@serifpersia/dango 3.9.0 → 3.9.1
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 +1 -1
- package/client/dist/assets/{AnimeCard-NynqB4iz.js → AnimeCard-CocG9qrm.js} +1 -1
- package/client/dist/assets/{AnimeInfo-B_VL5_wz.js → AnimeInfo-C-ZFMCrd.js} +1 -1
- package/client/dist/assets/AnimeInfoPage-DwL9Ax5L.js +2 -0
- package/client/dist/assets/{Asmr-DMspoMra.js → Asmr-D1HNwHq-.js} +1 -1
- package/client/dist/assets/{AsmrPopup-BRzUy94h.js → AsmrPopup-l0czpXly.js} +1 -1
- package/client/dist/assets/{AsmrResetProgressModal-s1eRMiAW.js → AsmrResetProgressModal-DYEslZfI.js} +1 -1
- package/client/dist/assets/{Home-B2BED0gb.js → Home-Ck5Pv2w-.js} +1 -1
- package/client/dist/assets/{Insights-I1lFAHGg.js → Insights-BNgHB1hx.js} +1 -1
- package/client/dist/assets/{LibraryListPage-DVFA51uJ.js → LibraryListPage-D27ISh6l.js} +1 -1
- package/client/dist/assets/{ListeningList-C3_v1Hfq.js → ListeningList-vXQfEFYE.js} +1 -1
- package/client/dist/assets/{Manga-Dwkuv9to.js → Manga-CeXla1mv.js} +1 -1
- package/client/dist/assets/{MangaInfoPage-Dbe96uTp.js → MangaInfoPage-B8IZSB-e.js} +1 -1
- package/client/dist/assets/{MangaReadPage-DMH36Bre.js → MangaReadPage-GpMss0tS.js} +1 -1
- package/client/dist/assets/{MangaResetProgressModal-61xx7JY3.js → MangaResetProgressModal-CSR-roX2.js} +1 -1
- package/client/dist/assets/{Mature-BcCct3VM.js → Mature-D64IntyP.js} +1 -1
- package/client/dist/assets/{MatureConsentModal-CkodsDv3.js → MatureConsentModal-BHtqyO00.js} +1 -1
- package/client/dist/assets/{MediaCard-qj_IAltC.js → MediaCard-9IiRZpbk.js} +1 -1
- package/client/dist/assets/{OptionListMenu-BfK_U2JZ.js → OptionListMenu-D4J4Q9gM.js} +1 -1
- package/client/dist/assets/Player-BsXkumtD.js +56 -0
- package/client/dist/assets/{PlayerProvider-DMiS49-n.js → PlayerProvider-BmMsmdYb.js} +1 -1
- package/client/dist/assets/{PlayerSettings-DnDE4FjN.js → PlayerSettings-BpQo55X9.js} +1 -1
- package/client/dist/assets/{QueueOptionsButton-ZPslb1vw.js → QueueOptionsButton-C__t6z-U.js} +1 -1
- package/client/dist/assets/{QueueRail-iewQtTf2.js → QueueRail-ByZnqlUT.js} +1 -1
- package/client/dist/assets/{ReadingList-DSn_7RPb.js → ReadingList-DgvW6qH1.js} +1 -1
- package/client/dist/assets/{ResetProgressModal-DkUfWl68.js → ResetProgressModal-DgzXKZJG.js} +1 -1
- package/client/dist/assets/{Search-DleGk52z.js → Search-DaH6qV3W.js} +1 -1
- package/client/dist/assets/Settings-DtwXOUlW.js +21 -0
- package/client/dist/assets/{SkeletonGrid-CDNxWb9m.js → SkeletonGrid-aY7UYKGV.js} +1 -1
- package/client/dist/assets/{Trackers-ChCE0FpJ.js → Trackers-B2tFpPHi.js} +1 -1
- package/client/dist/assets/{Tv-DT3m2nZs.css → Tv-Bbot3Klz.css} +1 -1
- package/client/dist/assets/Tv-VxFnu6cA.js +4 -0
- package/client/dist/assets/{TvInfo-CBDMmwKZ.js → TvInfo-DzdeVN1Y.js} +1 -1
- package/client/dist/assets/{TvPopup-CbjydYVj.js → TvPopup-BbrEhCCy.js} +1 -1
- package/client/dist/assets/{TvSearch-B46QqKRF.js → TvSearch-CLj4jth8.js} +1 -1
- package/client/dist/assets/{TvWatchlist-CKClWqAa.js → TvWatchlist-sq1VTglT.js} +1 -1
- package/client/dist/assets/{VirtualKeyboard-CO8IUNmo.js → VirtualKeyboard-CdG90MB4.js} +1 -1
- package/client/dist/assets/{WatchAlong-B3amSjXR.js → WatchAlong-CeIMQosP.js} +1 -1
- package/client/dist/assets/{WatchAlongPanel-CNXfPJV8.js → WatchAlongPanel-75S2BYQN.js} +1 -1
- package/client/dist/assets/{Watchlist-Dy02-vjm.js → Watchlist-BC20a1Yr.js} +1 -1
- package/client/dist/assets/index-Bi3wnovR.css +1 -0
- package/client/dist/assets/index-DAZg1_S9.js +178 -0
- package/client/dist/assets/{libraryInvalidation-2b2_7vwd.js → libraryInvalidation-ZMju1rNj.js} +1 -1
- package/client/dist/assets/playbackCompletion-Del9VqoH.js +1 -0
- package/client/dist/assets/{useAnimeInfoData-CdP9RtUB.js → useAnimeInfoData-Ba3HNec1.js} +1 -1
- package/client/dist/assets/{useMangaLibrary-BANnF0ot.js → useMangaLibrary-D_qIjbhI.js} +1 -1
- package/client/dist/assets/{useMangaPopup-BdNC1rr_.js → useMangaPopup-BpPyLnyj.js} +1 -1
- package/client/dist/assets/{useProviders-B0XQ7aY4.js → useProviders-Cy_Qpq6t.js} +1 -1
- package/client/dist/assets/{useTv-DM0uMYJ8.js → useTv-BDTl6Tsj.js} +1 -1
- package/client/dist/assets/{useTvLibrary-aGEImTh1.js → useTvLibrary-BcAQarFR.js} +1 -1
- package/client/dist/assets/useWatchAlongPlayer-CPj919ZS.js +10 -0
- package/client/dist/assets/useWatchAlongPlayer-DwQJwhql.css +1 -0
- package/client/dist/index.html +2 -2
- package/package.json +2 -2
- package/server/dist/server.js +136 -136
- package/server/package.json +1 -1
- package/client/dist/assets/AnimeInfoPage-DEHp6dbx.js +0 -2
- package/client/dist/assets/Player-CbaQmCP0.js +0 -56
- package/client/dist/assets/Settings-BL3wetIt.js +0 -21
- package/client/dist/assets/Tv-CnpSDbBA.js +0 -4
- package/client/dist/assets/index-D1FwY1a_.js +0 -178
- package/client/dist/assets/index-RwPVmyxh.css +0 -1
- package/client/dist/assets/playbackCompletion-OZmyMjQt.js +0 -1
- package/client/dist/assets/useWatchAlongPlayer-BkMVbNsw.js +0 -10
- package/client/dist/assets/useWatchAlongPlayer-CkSxIqXL.css +0 -1
package/server/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/AnimeInfo-B_VL5_wz.js","assets/vendor-core-DfaOB3Rn.js","assets/vendor-icons-DrybRNxP.js","assets/index-D1FwY1a_.js","assets/vendor-query-BBT5_sHx.js","assets/index-RwPVmyxh.css","assets/useAnimeInfoData-CdP9RtUB.js","assets/QueueOptionsButton-ZPslb1vw.js","assets/vendor-ui-3qrARCPr.js","assets/QueueOptionsButton-CM15uQn8.css","assets/AnimeMetaDetails-B3-A7O5H.js","assets/AnimeMetaDetails-BwNQnRCd.css","assets/SynopsisText-B3Sa5pRv.js","assets/useIsMobile-Dvx1uJ82.js","assets/SynopsisText-CYv2W3yR.css","assets/AnimeInfo-BivVqWcB.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{aq as r,a2 as t}from"./index-D1FwY1a_.js";import{u as o,P as a,z as e}from"./vendor-core-DfaOB3Rn.js";import"./vendor-query-BBT5_sHx.js";import"./vendor-icons-DrybRNxP.js";const i=e(()=>t(()=>import("./AnimeInfo-B_VL5_wz.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])));function _(){return o(a,{fallback:o(r,{}),children:o(i,{})})}export{_ as default};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/PlayerSettings-DnDE4FjN.js","assets/vendor-core-DfaOB3Rn.js","assets/index-D1FwY1a_.js","assets/vendor-query-BBT5_sHx.js","assets/vendor-icons-DrybRNxP.js","assets/index-RwPVmyxh.css","assets/OptionListMenu-BfK_U2JZ.js","assets/useWatchAlongPlayer-BkMVbNsw.js","assets/PlayerProvider-DMiS49-n.js","assets/PlayerProvider-ZeplRma-.css","assets/playbackCompletion-OZmyMjQt.js","assets/useWatchAlongPlayer-CkSxIqXL.css","assets/PlayerSettings-CbGkvNJq.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{u as t,g as pt,h as O,P as lr,z as cr,d as ae,A as N,q as Q,y as ur,T as Me,o as dr,a as mr,c as pr,_ as hr,S as Ze}from"./vendor-core-DfaOB3Rn.js";import{p as Y,a2 as Dt,a3 as et,o as fr,q as de,t as be,J as _e,a4 as vr,a5 as qe,Q as ht,a6 as gr,e as br,x as yr,y as Sr,z as Er,A as kr,d as wr,u as Tr,B as Ge,a7 as Cr,a8 as Mr,f as Rr}from"./index-D1FwY1a_.js";import{P as Nr,a as Pr,b as _r,F as Ar,s as xr,c as Lr}from"./PlayerProvider-DMiS49-n.js";import{u as $t,b as xt,a as Et}from"./vendor-query-BBT5_sHx.js";import{p as wt,s as Br,C as Dr,a as $r,P as Ir,b as Ue,c as Lt,f as It,d as Fr,e as Or,g as Wr,r as Ur,u as Vr,h as Qr,i as Kr,j as qr,k as Gr,l as zr,m as Hr,n as jr,o as Ce,A as Yr,q as Xr,R as Jr,E as Zr,t as en,v as S,w as tn,x as rn,y as nn}from"./useWatchAlongPlayer-BkMVbNsw.js";import{I as ge}from"./vendor-icons-DrybRNxP.js";import{l as sn,i as rt,s as on}from"./playbackCompletion-OZmyMjQt.js";import{M as an}from"./MatureConsentModal-CkodsDv3.js";import{u as ln}from"./useIsMobile-Dvx1uJ82.js";import{s as Pe,Q as cn}from"./QueueRail-iewQtTf2.js";import{u as un,Q as dn}from"./QueueOptionsButton-ZPslb1vw.js";import{u as Ft}from"./useProviders-B0XQ7aY4.js";import{A as mn}from"./AnimeMetaDetails-B3-A7O5H.js";import{S as pn}from"./SynopsisText-B3Sa5pRv.js";import{W as hn}from"./WatchAlongPanel-CNXfPJV8.js";import"./vendor-ui-3qrARCPr.js";const fn="_controlsOverlay_6uapd_1",vn="_hidden_6uapd_21",gn="_topControls_6uapd_27",bn="_backBtn_6uapd_47",yn="_videoTitleInfo_6uapd_67",Sn="_animeTitle_6uapd_73",En="_episodeNumber_6uapd_83",kn="_bottomControls_6uapd_91",wn="_progressBarContainer_6uapd_110",Tn="_progressBar_6uapd_110",Cn="_thumb_6uapd_129",Mn="_scrubbing_6uapd_144",Rn="_watchedBar_6uapd_148",Nn="_bufferedBar_6uapd_149",Pn="_timeBubble_6uapd_191",_n="_skipSegment_6uapd_225",An="_op_6uapd_235",xn="_mixed_op_6uapd_236",Ln="_ed_6uapd_240",Bn="_mixed_ed_6uapd_241",Dn="_recap_6uapd_245",$n="_mixed_recap_6uapd_246",In="_bottomControlsRow_6uapd_250",Fn="_leftControls_6uapd_258",On="_rightControls_6uapd_259",Wn="_controlBtn_6uapd_266",Un="_theaterBtn_6uapd_307",Vn="_nextEpisodeBtn_6uapd_311",Qn="_active_6uapd_332",Kn="_timeDisplay_6uapd_336",qn="_skipControls_6uapd_344",B={controlsOverlay:fn,hidden:vn,topControls:gn,backBtn:bn,videoTitleInfo:yn,animeTitle:Sn,episodeNumber:En,bottomControls:kn,progressBarContainer:wn,progressBar:Tn,thumb:Cn,scrubbing:Mn,watchedBar:Rn,bufferedBar:Nn,timeBubble:Pn,skipSegment:_n,op:An,mixed_op:xn,ed:Ln,mixed_ed:Bn,recap:Dn,mixed_recap:$n,bottomControlsRow:In,leftControls:Fn,rightControls:On,controlBtn:Wn,theaterBtn:Un,nextEpisodeBtn:Vn,active:Qn,timeDisplay:Kn,skipControls:qn},Gn=({player:r,handlers:o,visible:d,skipIntervals:m,showNextEpisodeButton:w,onNextEpisode:a,isTheaterMode:s,onTheaterModeToggle:n,settingsBtnRef:i,timeDisplayRef:b})=>{const{state:p,actions:f}=r,{showSettings:E}=p;return t("div",{className:`${B.controlsOverlay} ${d?"":B.hidden} `,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none",justifyContent:"flex-end"},children:t("div",{className:B.bottomControls,"data-speed-boost-ignore":"true",onClick:M=>M.stopPropagation(),children:[t(Nr,{classes:{container:B.progressBarContainer,scrubbing:B.scrubbing,timeBubble:B.timeBubble,bar:B.progressBar,buffered:B.bufferedBar,watched:B.watchedBar,thumb:B.thumb},timeLabelRef:b,children:[p.duration>0&&r.state.currentSkipInterval&&t("div",{className:`${B.skipSegment} ${B[r.state.currentSkipInterval.skip_type]} `,style:{left:`${r.state.currentSkipInterval.start_time/p.duration*100}% `,width:`${(r.state.currentSkipInterval.end_time-r.state.currentSkipInterval.start_time)/p.duration*100}% `}}),m.map(M=>{const e=M.start_time/p.duration*100,g=(M.end_time-M.start_time)/p.duration*100;return t("div",{className:`${B.skipSegment} ${B[M.skip_type]} `,style:{left:`${e}% `,width:`${g}% `},title:M.skip_type.toUpperCase()},M.skip_id)})]}),t("div",{className:B.bottomControlsRow,children:[t("div",{className:B.leftControls,children:[t(Pr,{className:B.controlBtn}),t(_r,{buttonClassName:B.controlBtn,onExpandedChange:f.setShowVolumeSlider}),t("span",{className:B.timeDisplay,ref:b,children:[f.formatTime(0)," / ",f.formatTime(p.duration)]}),p.currentSkipInterval&&!p.isAutoSkipEnabled&&!p.playbackLocked&&t("button",{className:B.controlBtn,onClick:()=>{p.currentSkipInterval&&(r.engine.seek(p.currentSkipInterval.end_time),f.setCurrentSkipInterval(null))},children:["Skip ",p.currentSkipInterval.skip_type==="op"?"Opening":"Ending"]})]}),t("div",{className:B.rightControls,children:[t("div",{className:B.skipControls,children:w&&t("button",{className:B.nextEpisodeBtn,onClick:a,title:"Play next episode",children:"Next EP"})}),t("button",{className:`${B.controlBtn} ${o.isSubtitleActive?B.active:""}`,onClick:o.handleCCToggle,title:o.isSubtitleActive?"Disable Subtitles":"Enable Subtitles","aria-label":"Toggle Subtitles",children:t(ge,{name:"closed-captioning",size:22})}),t("button",{ref:i,className:`${B.controlBtn} ${E?B.active:""} `,onClick:()=>f.setShowSettings(!E),"aria-label":"Settings",children:t(ge,{name:"cog"})}),t("button",{className:`${B.controlBtn} ${B.theaterBtn} ${s?B.active:""} `,onClick:M=>{M.stopPropagation(),n()},title:s?"Exit Theater Mode":"Theater Mode","aria-label":s?"Exit Theater Mode":"Theater Mode",children:t(ge,{name:"tv"})}),t(Ar,{className:B.controlBtn})]})]})]})})};function zn(r){const{state:o,refs:d,actions:m}=r,w=n=>{if(!d.videoRef.current)return;m.setActiveSubtitleTrack(n);try{if(n===null||n==="off")Y.setItem("playerSubtitlesEnabled","false");else{Y.setItem("playerSubtitlesEnabled","true");const b=o.availableSubtitles.find(p=>p.label===n||p.lang===n);b?Y.setItem("playerLastSubtitle",Br(b)):Y.setItem("playerLastSubtitle",n)}}catch{}let i=!1;Array.from(d.videoRef.current.textTracks).forEach(b=>{const f=n!==null&&n!=="off"&&(b.language===n||b.label===n)&&!i;b.mode=f?"showing":"hidden",f&&(i=!0)})},a=o.activeSubtitleTrack!==null&&o.activeSubtitleTrack!=="off";return{handleSubtitleSelection:w,isSubtitleActive:a,handleCCToggle:()=>{if(!d.videoRef.current)return;if(a){w("off");return}if(o.availableSubtitles.length===0)return;let n=null;try{n=Y.getItem("playerLastSubtitle")}catch{}const i=wt(o.availableSubtitles,{lastKey:n,enabled:!0});if(i<0)return;const b=o.availableSubtitles[i];w(b.label||b.lang)}}}const Hn=cr(()=>Dt(()=>import("./PlayerSettings-DnDE4FjN.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12]))),jn=({player:r,isAutoplayEnabled:o,onAutoplayChange:d,showNextEpisodeButton:m,onNextEpisode:w,videoSources:a,selectedSource:s,selectedLink:n,onSourceChange:i,loadingVideo:b,skipIntervals:p,animeTitle:f,episodeNumber:E,mode:M,isTheaterMode:e,onTheaterModeToggle:g,anime4kEnabled:T,onAnime4kToggle:_,anime4kSupported:x,anime4kProfile:y,onAnime4kProfileChange:c,anime4kInitializing:P,anime4kError:D,videoDelayEnabled:$,onVideoDelayToggle:U,videoDelayMs:h,onVideoDelayChange:v,onCalibrateAvSync:K,fallbackChoice:V,onFallbackChoiceChange:G,ambientSettings:Z,onAmbientChange:W,children:L,overlays:J,isInteractingExtra:A=!1,className:q,hideChrome:ee=!1})=>{const{state:l,actions:R}=r,{showSettings:k}=l,{setShowSettings:C}=R,I=zn(r),H=pt.useRef(null),Re=pt.useRef(null),Ae=pt.useRef(null);O(()=>{const ce=Oe=>{H.current&&!H.current.contains(Oe.target)&&Re.current&&!Re.current.contains(Oe.target)&&k&&C(!1)};return k&&document.addEventListener("mousedown",ce),()=>{document.removeEventListener("mousedown",ce)}},[k,C]);const ie=l.showControls||k||l.isScrubbing,j=l.activeSubtitleTrack!=="off"?l.availableSubtitles.find(ce=>ce.lang===l.activeSubtitleTrack||ce.label===l.activeSubtitleTrack):void 0,xe=t(Dr,{visible:ie,title:f,episode:E?`Episode ${E}`:void 0,mode:M,server:b?void 0:s?.sourceName,subtitles:b?void 0:j?.label||j?.lang,onBack:()=>window.history.back(),classes:{overlay:B.controlsOverlay,hidden:B.hidden,top:B.topControls,backBtn:B.backBtn,titleInfo:B.videoTitleInfo,title:B.animeTitle,episode:B.episodeNumber}}),Fe=!b&&!l.isBuffering&&l.duration>0?t($r,{}):null,le=t(Gn,{player:r,handlers:I,visible:ie,skipIntervals:p,showNextEpisodeButton:m,onNextEpisode:w,isTheaterMode:e,onTheaterModeToggle:g,settingsBtnRef:Re,timeDisplayRef:Ae}),ne=t(lr,{fallback:null,children:t(Hn,{ref:H,isOpen:k,onClose:()=>C(!1),videoSources:a,currentSource:s,currentLink:n,onSourceChange:i,subtitles:l.availableSubtitles,activeSubtitleTrack:l.activeSubtitleTrack,onSubtitleChange:I.handleSubtitleSelection,subtitleSettings:{fontSize:l.subtitleFontSize,position:l.subtitlePosition,bgOpacity:l.subtitleBgOpacity,bgColor:l.subtitleBgColor,textColor:l.subtitleTextColor,edge:l.subtitleEdge,bold:l.subtitleBold},onSubtitleSettingsChange:R.setSubtitleStyle,useNativeControls:!l.playbackLocked&&l.useNativeControls,onNativeControlsToggle:R.setUseNativeControls,anime4kEnabled:T,onAnime4kToggle:_,anime4kSupported:x,anime4kProfile:y,onAnime4kProfileChange:c,anime4kInitializing:P,anime4kError:D,videoDelayEnabled:$,onVideoDelayToggle:U,videoDelayMs:h,onVideoDelayChange:v,onCalibrateAvSync:K,isAutoSkipEnabled:l.isAutoSkipEnabled,onAutoSkipChange:ce=>{R.setIsAutoSkipEnabled(ce);try{Y.setItem("autoSkipEnabled",ce.toString())}catch{}},isAutoplayEnabled:o,onAutoplayChange:d,fallbackChoice:V,onFallbackChoiceChange:G,isTheaterMode:e,ambientSettings:Z,onAmbientChange:W})}),Ne=k?t("div",{"data-speed-boost-ignore":"true",onClick:ce=>ce.stopPropagation(),children:ne}):null;return t(Ir,{engine:r.engine,topBar:xe,centerControls:Fe,bottomBar:!b&&l.duration>0?le:null,settingsPanel:Ne,overlays:J,isInteracting:A||l.showSettings||l.showVolumeSlider,nativeControls:!l.playbackLocked&&l.useNativeControls,className:q,chromeDisabled:ee,children:L})},Yn=({count:r=3})=>t("section",{className:Pe.section,children:[t("div",{className:Pe.header,children:t("button",{className:Pe.headerToggle,disabled:!0,children:[t("span",{className:Pe.title,children:t(et,{width:"60px",height:"1.2rem",variant:"text"})}),t(ge,{name:"chevron-down",style:{opacity:.3}})]})}),t("div",{className:Pe.list,children:Array.from({length:r}).map((o,d)=>t("div",{className:Pe.item,style:{pointerEvents:"none"},children:[t("div",{className:Pe.dragHandle,style:{opacity:.2},children:t(et,{width:"16px",height:"16px",variant:"rectangular"})}),t("div",{className:Pe.thumbnail,style:{overflow:"hidden",background:"transparent"},children:t(et,{width:"100%",height:"100%",variant:"rectangular"})}),t("div",{className:Pe.meta,children:[t(et,{width:"80%",height:"1.2rem",variant:"text",className:Pe.metaGap}),t(et,{width:"40%",height:"0.8rem",variant:"rectangular",style:{borderRadius:"var(--radius-sm)"}})]})]},d))})]}),Xn={soft:"Softsub",hard:"Hardsub",mixed:"Mixed"},Jn={direct:"Direct",embed:"Embed",cookie:"Needs cookie"},Zn=["direct","cookie","embed"],es=({selectedProvider:r,onProviderChange:o,isAdult:d,options:m})=>{const a=(m&&m.length>0?m:[]).filter(s=>s.mature===(d===!0));return t("div",{className:Ue.providerSelectContainer,children:[t("h4",{children:"Provider"}),t("select",{className:Ue.providerSelect,value:r,onChange:s=>o(s.currentTarget.value),children:Zn.map(s=>{const n=a.filter(i=>(i.tier??"direct")===s);return n.length===0?null:t("optgroup",{label:Jn[s],children:n.map(i=>t("option",{value:i.id,children:i.sub?`${i.label} (${Xn[i.sub]})`:i.label},i.id))},s)})})]})},ts=({videoSources:r,selectedSource:o,selectedLink:d,onSourceChange:m,onLinkChange:w})=>{const a=Array.isArray(r)?r:[];if(a.length===0)return null;const s=o?.type==="iframe"&&(o.links?.length??0)>1;return t("div",{className:Ue.sourceSelectionContainer,children:[t("h4",{children:"Source"}),t("div",{className:Ue.sourceButtons,children:a.map((n,i)=>t("button",{className:`${Ue.sourceButton} ${o?.sourceName===n.sourceName?Ue.active:""} `,onClick:()=>m(n),children:n.sourceName},`${n.sourceName}-${i}`))}),s&&t("select",{className:Ue.sourceSelect,"aria-label":"Fallback embed quality",value:d?.link??o.links[0]?.link??"",onChange:n=>{const i=o.links.find(b=>b.link===n.currentTarget.value);i&&w(i)},children:o.links.map(n=>t("option",{value:n.link,children:n.resolutionStr},n.link))})]})},rs=pt.memo(ts,(r,o)=>r.selectedSource?.sourceName===o.selectedSource?.sourceName&&r.selectedLink?.link===o.selectedLink?.link&&r.videoSources===o.videoSources),ns={low:{sd:1.5,hd:1.3,fhd:1.25},balanced:{sd:2,hd:1.5,fhd:1.25},high:{sd:2.5,hd:2,fhd:1.5},denoise:{sd:1.5,hd:1.5,fhd:1.5}},ss={low:"ModeB",balanced:"ModeA",high:"ModeAA",denoise:"ModeC"},os=5,as=15e3,is=`
|
|
3
|
-
@group(0) @binding(0) var extTex: texture_external;
|
|
4
|
-
@group(0) @binding(1) var extSamp: sampler;
|
|
5
|
-
struct VSOut {
|
|
6
|
-
@builtin(position) pos: vec4f,
|
|
7
|
-
@location(0) uv: vec2f,
|
|
8
|
-
};
|
|
9
|
-
@vertex
|
|
10
|
-
fn vs(@builtin(vertex_index) idx: u32) -> VSOut {
|
|
11
|
-
var positions = array<vec2f, 6>(
|
|
12
|
-
vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(-1.0, 1.0),
|
|
13
|
-
vec2f(-1.0, 1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0)
|
|
14
|
-
);
|
|
15
|
-
var uvs = array<vec2f, 6>(
|
|
16
|
-
vec2f(0.0, 1.0), vec2f(1.0, 1.0), vec2f(0.0, 0.0),
|
|
17
|
-
vec2f(0.0, 0.0), vec2f(1.0, 1.0), vec2f(1.0, 0.0)
|
|
18
|
-
);
|
|
19
|
-
var out: VSOut;
|
|
20
|
-
out.pos = vec4f(positions[idx], 0.0, 1.0);
|
|
21
|
-
out.uv = uvs[idx];
|
|
22
|
-
return out;
|
|
23
|
-
}
|
|
24
|
-
@fragment
|
|
25
|
-
fn fs(@location(0) uv: vec2f) -> @location(0) vec4f {
|
|
26
|
-
return textureSampleBaseClampToEdge(extTex, extSamp, uv);
|
|
27
|
-
}
|
|
28
|
-
`;function ls({videoRef:r,canvasRef:o,profile:d="balanced",delayMs:m=0}){const[w,a]=ae(!1),[s,n]=ae(()=>{try{return Y.getItem("anime4kEnabled")==="true"}catch{return!1}}),[i,b]=ae(!1),[p,f]=ae(null),[E,M]=ae(0),e=N(0),g=N(null),T=N(null),_=N(null),x=N(null),y=N(null),c=N(null),P=N(null),D=N(null),$=N(null),U=N(!1),h=N(-1),v=N(0),K=N(m);K.current=m;const V=N([]),G=N(!1),Z=N(!1),W=N(!1),L=N(null),J=N(-1),A=N(-1),q=N(!1),ee=N(0);O(()=>{async function k(){if(typeof navigator>"u"||!navigator.gpu){a(!1);return}try{const C=await navigator.gpu.requestAdapter();a(!!C)}catch{a(!1)}}k()},[]),O(()=>{if(!s||!w)return;let k=!1;const C=++e.current,I=j=>{if(j)try{j.close()}catch{}},H=()=>{for(const j of V.current)I(j.bitmap);V.current=[]},Re=j=>Math.max(8,Math.min(40,Math.ceil(j/16.7)+4));function Ae(){$.current!==null&&(cancelAnimationFrame($.current),$.current=null)}async function ie(){let j=r.current;const xe=o.current;if(!j||!xe||e.current!==C)return;const Fe=performance.now()+as;for(;(!j||j.videoWidth===0)&&performance.now()<Fe;){if(await new Promise(se=>requestAnimationFrame(se)),k||e.current!==C)return;j=r.current}if(!j||j.videoWidth===0){!k&&e.current===C&&(f("Timed out waiting for video metadata"),b(!1),n(!1));return}const le=j.videoWidth,ne=j.videoHeight,Ne=Math.max(le,ne),ce=window.innerWidth,Oe=window.innerHeight,nt=Math.max(ce,Oe),ft=Ne<nt?nt/Ne:1,Le=ns[d],vt=Ne<=480?Le.sd:Ne<=720?Le.hd:Ne<=1080?Le.fhd:1,te=Math.min(vt,ft);xe.width=Math.round(le*te),xe.height=Math.round(ne*te),b(!0),f(null),v.current=0,h.current=-1,J.current=-1,A.current=-1,q.current=!1,ee.current=0,H(),U.current=!1;try{let se=function(){k||e.current!==C||(Ae(),$.current=requestAnimationFrame(()=>{ut()}))};const{ModeA:st,ModeB:ze,ModeC:ot,ModeAA:He}=await Dt(async()=>{const{ModeA:z,ModeB:oe,ModeC:ke,ModeAA:pe}=await import("./index-BOKlZEHq.js").then(fe=>fe.i);return{ModeA:z,ModeB:oe,ModeC:ke,ModeAA:pe}},[]);if(k||e.current!==C)return;if(!navigator.gpu)throw new Error("WebGPU not available");const je=await navigator.gpu.requestAdapter();if(k||e.current!==C)return;if(!je)throw new Error("No GPU adapter found");const F=await je.requestDevice();if(!F)throw new Error("Failed to get GPU device");if(k||e.current!==C){F.destroy();return}g.current=F;const Se=xe.getContext("webgpu");if(!Se)throw new Error("Failed to get WebGPU context");T.current=Se;const at=navigator.gpu.getPreferredCanvasFormat();Se.configure({device:F,format:at,alphaMode:"premultiplied"});const ye=F.createTexture({size:[le,ne],format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),gt=ss[d],Ve=Math.round(le*te),me=Math.round(ne*te),Qe=(()=>{switch(gt){case"ModeB":return new ze({device:F,inputTexture:ye,nativeDimensions:{width:le,height:ne},targetDimensions:{width:Ve,height:me}});case"ModeC":return new ot({device:F,inputTexture:ye,nativeDimensions:{width:le,height:ne},targetDimensions:{width:Ve,height:me}});case"ModeAA":return new He({device:F,inputTexture:ye,nativeDimensions:{width:le,height:ne},targetDimensions:{width:Ve,height:me}});default:return new st({device:F,inputTexture:ye,nativeDimensions:{width:le,height:ne},targetDimensions:{width:Ve,height:me}})}})(),it=Qe.getOutputTexture(),Ee=F.createSampler({magFilter:"linear",minFilter:"linear"}),Ye=F.createShaderModule({code:`
|
|
29
|
-
@group(0) @binding(0) var tex: texture_2d<f32>;
|
|
30
|
-
@group(0) @binding(1) var samp: sampler;
|
|
31
|
-
struct VertexOutput {
|
|
32
|
-
@builtin(position) pos: vec4f,
|
|
33
|
-
@location(0) uv: vec2f,
|
|
34
|
-
}
|
|
35
|
-
@vertex
|
|
36
|
-
fn vs(@builtin(vertex_index) idx: u32) -> VertexOutput {
|
|
37
|
-
var positions = array<vec2f, 6>(
|
|
38
|
-
vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(-1.0, 1.0),
|
|
39
|
-
vec2f(-1.0, 1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0)
|
|
40
|
-
);
|
|
41
|
-
var uvs = array<vec2f, 6>(
|
|
42
|
-
vec2f(0.0, 1.0), vec2f(1.0, 1.0), vec2f(0.0, 0.0),
|
|
43
|
-
vec2f(0.0, 0.0), vec2f(1.0, 1.0), vec2f(1.0, 0.0)
|
|
44
|
-
);
|
|
45
|
-
var out: VertexOutput;
|
|
46
|
-
out.pos = vec4f(positions[idx], 0.0, 1.0);
|
|
47
|
-
out.uv = uvs[idx];
|
|
48
|
-
return out;
|
|
49
|
-
}
|
|
50
|
-
@fragment
|
|
51
|
-
fn fs(@location(0) uv: vec2f) -> @location(0) vec4f {
|
|
52
|
-
return textureSample(tex, samp, uv);
|
|
53
|
-
}
|
|
54
|
-
`}),Be=F.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}}]}),lt=F.createRenderPipeline({layout:F.createPipelineLayout({bindGroupLayouts:[Be]}),vertex:{module:Ye,entryPoint:"vs"},fragment:{module:Ye,entryPoint:"fs",targets:[{format:at}]},primitive:{topology:"triangle-list"}}),bt=F.createBindGroup({layout:Be,entries:[{binding:0,resource:it.createView()},{binding:1,resource:Ee}]});try{const z=F.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,externalTexture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}}]}),oe=F.createShaderModule({code:is}),ke=F.createRenderPipeline({layout:F.createPipelineLayout({bindGroupLayouts:[z]}),vertex:{module:oe,entryPoint:"vs"},fragment:{module:oe,entryPoint:"fs",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list"}});L.current={pipeline:ke,layout:z,inputView:ye.createView()}}catch{L.current=null}_.current=Qe,x.current=ye,y.current=it,c.current=lt,P.current=Ee,D.current=Be,Z.current=!1,W.current=!1;async function ct(){const z=L.current;if(!z||Z.current)return!1;const oe=r.current;if(!oe)return!1;const ke=!W.current;ke&&F.pushErrorScope("validation");try{const pe=F.importExternalTexture({source:oe}),fe=F.createBindGroup({layout:z.layout,entries:[{binding:0,resource:pe},{binding:1,resource:Ee}]}),he=F.createCommandEncoder(),we=he.beginRenderPass({colorAttachments:[{view:z.inputView,loadOp:"load",storeOp:"store"}]});we.setPipeline(z.pipeline),we.setBindGroup(0,fe),we.draw(6),we.end(),F.queue.submit([he.finish()])}catch{return Z.current=!0,L.current=null,!1}if(ke){const pe=await F.popErrorScope().catch(()=>null);if(pe)return console.warn("[anime4k] blit probe failed:",pe.message),Z.current=!0,L.current=null,!1;W.current=!0}return!0}b(!1);async function ut(){if(k||e.current!==C||!Se)return;const z=r.current;if(!z||z.videoWidth===0){se();return}if(z!==j||z.videoWidth!==le||z.videoHeight!==ne){M(fe=>fe+1);return}if(z.paused||z.ended||document.hidden||z.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){se();return}const oe=z.getVideoPlaybackQuality().totalVideoFrames;if(oe===A.current){se();return}if(U.current){se();return}const ke=z.currentTime;(z.seeking||J.current>=0&&Math.abs(ke-J.current)>.5)&&(H(),q.current=!1,ee.current=0,A.current=-1),J.current=ke;const pe=Math.max(0,K.current||0);pe>ee.current&&(q.current=!1),U.current=!0;try{const fe=performance.now();let he=null,we=!1;if(pe<=0){V.current.length>0&&H(),q.current=!1,ee.current=0;let ve=!1;if(!G.current)try{F.queue.copyExternalImageToTexture({source:z},{texture:ye},[le,ne]),A.current=oe,ve=!0}catch(ue){if(ue instanceof TypeError)G.current=!0;else throw ue}if(!ve&&!Z.current&&L.current&&await ct()&&(A.current=oe,ve=!0),!ve){const ue=await createImageBitmap(z);A.current=oe,F.queue.copyExternalImageToTexture({source:ue},{texture:ye},[le,ne]),I(ue)}}else{const ve=await createImageBitmap(z);A.current=oe;const ue=V.current;ue.push({bitmap:ve,capture:fe});const dt=Re(pe);for(;ue.length>dt;)I(ue.shift()?.bitmap);let Ke=-1;for(let re=ue.length-1;re>=0;re--)if(fe-ue[re].capture>=pe){Ke=re;break}if(Ke!==-1){for(let Je=0;Je<Ke;Je++)I(ue.shift()?.bitmap);const re=ue.shift();re?(he=re.bitmap,q.current=!0,ee.current=pe):(he=ve,we=!0)}else if(!q.current)he=ve,we=!0;else{const re=ue.shift();he=re?re.bitmap:ve,re||(we=!0)}if(!he){U.current=!1,se();return}F.queue.copyExternalImageToTexture({source:he},{texture:ye},[le,ne]),we||I(he)}const Xe=F.createCommandEncoder();await Qe.pass(Xe);const De=Xe.beginRenderPass({colorAttachments:[{view:Se.getCurrentTexture().createView(),clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]});De.setPipeline(lt),De.setBindGroup(0,bt),De.draw(6),De.end(),F.queue.submit([Xe.finish()]),h.current=oe,v.current=0,F.queue.onSubmittedWorkDone().then(()=>{e.current===C&&(U.current=!1)})}catch(fe){if(U.current=!1,v.current+=1,v.current>=os&&!k&&e.current===C){console.error(fe),f(fe instanceof Error?fe.message:"Render error"),n(!1);return}}se()}se()}catch(se){!k&&e.current===C&&(T.current?.unconfigure(),g.current?.destroy(),g.current=null,T.current=null,f(se instanceof Error?se.message:"Failed to initialize upscaler"),b(!1),n(!1))}}return ie(),()=>{k=!0,e.current+=1,Ae(),H(),T.current?.unconfigure(),x.current&&(x.current.destroy(),x.current=null),y.current&&(y.current.destroy(),y.current=null),g.current&&(g.current.destroy(),g.current=null),_.current=null,c.current=null,P.current=null,D.current=null,L.current=null,T.current=null,U.current=!1}},[s,w,r,o,d,E]);const l=Q(k=>{n(k);try{Y.setItem("anime4kEnabled",String(k))}catch{}},[]),R=Q(()=>{n(k=>{const C=!k;try{Y.setItem("anime4kEnabled",String(C))}catch{}return C})},[]);return{isWebGPUSupported:w,isEnabled:s,isInitializing:i,error:p,toggle:R,setEnabled:l}}function cs({videoRef:r,episodeKey:o,isEnabled:d,isSupported:m,mediaReady:w,isIframeSource:a,setEnabled:s}){const n=N(null),i=N(!1),b=N(!1),p=N(s);p.current=s,O(()=>{const f=n.current;n.current=o,!(f===null||f===o)&&(!d||!m||(i.current=!0,b.current=!1,p.current(!1)))},[o,d,m]),O(()=>{if(!i.current)return;if(d){b.current&&(i.current=!1);return}if(b.current=!0,!w)return;if(a){i.current=!1,p.current(!0);return}const f=r.current;if(!f)return;let E,M=!1;const e=()=>{M||(M=!0,i.current=!1,p.current(!0))};if(f.readyState>=2)return E=window.setTimeout(e,500),()=>window.clearTimeout(E);const g=()=>{window.setTimeout(e,500)};return f.addEventListener("canplay",g,{once:!0}),f.addEventListener("playing",g,{once:!0}),E=window.setTimeout(e,5e3),()=>{window.clearTimeout(E),f.removeEventListener("canplay",g),f.removeEventListener("playing",g)}},[d,w,a,r])}const us=()=>Y.getItem("preferredMode")==="dub"?"dub":"sub",ds=/^[a-z0-9-]+$/i,Ot=r=>r?"preferredProviderMature":"preferredProvider",Wt=r=>{const o=Y.getItem(Ot(r));return o&&ds.test(o)?o:null},Ut=(r,o)=>{Y.setItem(Ot(o),r)},ms=()=>Wt(!1)??"megaplay",ps=()=>({showMeta:{},episodes:[],watchedEpisodes:[],watchlistStatus:null,showCombinedDetails:!1,currentMode:us(),inWatchlist:!1,videoSources:[],selectedSource:null,selectedLink:null,isAutoplayEnabled:sn(),showResumeModal:!0,resumeProgressPending:!0,resumeTime:0,resumeDuration:0,skipIntervals:[],selectedProvider:ms(),loadingShowData:!0,loadingVideo:!1,error:null,showCookieModal:!1,cookieProvider:null});function hs(r,o){switch(o.type){case"SET_STATE":return{...r,...o.payload};case"SET_MODE":return{...r,currentMode:o.payload,videoSources:[],selectedSource:null,selectedLink:null};case"SET_PROVIDER":return{...r,selectedProvider:o.payload};default:return r}}async function Bt(r,o,d,m,w=!1){if(!r||!o)throw new Error("Missing params");try{const[a,s,n,i]=await Promise.all([be.data.video.query({showId:r,episodeNumber:o,mode:d.currentMode,provider:d.selectedProvider}).catch(y=>{const c=y.data?.cause;return y.message==="AUTH_REQUIRED"&&c?.provider==="mkissa"&&m({type:"SET_STATE",payload:{showCookieModal:!0,cookieProvider:"mkissa"}}),null}),be.progress.getEpisode.query({showId:r,episodeNumber:o}).catch(()=>null),be.settings.getByKey.query({key:"preferredSource"}).catch(()=>null),be.data.skipTimes.query({showId:r,episodeNumber:o}).catch(()=>[])]),b=n?.value,p=a?.filter(y=>{const c=y.sourceName.toLowerCase();return d.currentMode==="dub"?c.includes("eng")||c.includes("dub"):c.includes("jpn")||c.includes("sub")||!c.includes("eng")&&!c.includes("dub")})??[],f=p.length>0?p:a??[];let E=f.length>0?f[0]:null;if(b){const y=f.find(c=>c.sourceName===b);y&&(E=y)}const M=E&&E.links.length>0?[...E.links].sort((y,c)=>(parseInt(c.resolutionStr)||0)-(parseInt(y.resolutionStr)||0))[0]:null,e=s?.currentTime||0,g=s?.duration||0,T=e,x=(Array.isArray(i)?i:i?.results||[]).map(y=>({skip_id:y.skip_id||"",skip_type:y.skip_type||"",start_time:y.interval?.start_time??y.start_time??0,end_time:y.interval?.end_time??y.end_time??0})).filter(y=>y.end_time>0);return(!a||a.length===0)&&(w||_e.error(`No video sources found for ${d.selectedProvider}`)),{videoSources:a,selectedSource:E,selectedLink:M,resumeTime:T,resumeDuration:g,showResumeModal:T>5&&!rt(T,g)&&E?.type!=="iframe",skipIntervals:x,fetchedEpisodeNumber:o}}catch(a){const s=a;if(s.message==="AUTH_REQUIRED")return m({type:"SET_STATE",payload:{showCookieModal:!0,cookieProvider:s.provider}}),{videoSources:[],selectedSource:null,selectedLink:null,resumeTime:0,resumeDuration:0,showResumeModal:!1,skipIntervals:[],fetchedEpisodeNumber:o};throw a}}const fs=(r,o,d,m)=>{const[w,a]=ur(hs,d,l=>({...ps(),showMeta:l?.name?{name:l.name,thumbnail:l.thumbnail,nativeName:l.nativeName,englishName:l.englishName,names:{romaji:l.name||l.englishName,english:l.englishName||l.name,native:l.nativeName}}:{}})),s=m?.watchSelection,n=Me(()=>s?{...w,selectedProvider:s.provider,currentMode:s.mode}:w,[w,s]),i=$t(),b=fr(),p=N(null),f=N(null),{options:E}=Ft(),M=Me(()=>E.filter(l=>(l.kind??"anime")==="anime"),[E]),e=o||n.initialEpisode,g=`${r}:${e}`,T=N(g);O(()=>{T.current!==g&&(T.current=g,a({type:"SET_STATE",payload:{selectedSource:null,selectedLink:null}}))},[g,a]),O(()=>{!s&&r&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)&&n.selectedProvider!=="animepahe"&&p.current!==r&&(p.current=r,a({type:"SET_PROVIDER",payload:"animepahe"}))},[r,n.selectedProvider,s]);const{data:_,isLoading:x,error:y}=un(r),{data:c}=xt({queryKey:[de.playerData,r,n.currentMode,n.selectedProvider],queryFn:async()=>{if(!r)throw new Error("No showId");const l=async()=>{try{const H=await be.data.episodes.query({showId:r,mode:n.currentMode,provider:n.selectedProvider}).catch(()=>null);if(H?.episodes?.length)return H}catch{}return null},[R,k,C]=await Promise.all([l(),be.watchlist.check.query({showId:r}).catch(()=>({inWatchlist:!1,status:null})),be.progress.getWatchedEpisodes.query({showId:r}).catch(()=>[])]),I=R?.episodes?R.episodes.sort((H,Re)=>parseFloat(H)-parseFloat(Re)):[];return{description:R?.description||"",episodes:I,inWatchlist:k.inWatchlist,watchlistStatus:k.status??null,watchedEpisodes:C}},enabled:!!r});O(()=>{!o&&c?.episodes&&c.episodes.length>0&&!o&&a({type:"SET_STATE",payload:{initialEpisode:c.episodes[0]}})},[c,o]),O(()=>{if(s||_?.isAdult===void 0||f.current===r)return;const l=_.isAdult===!0,R=M.filter(C=>C.mature===l);if(R.length===0||M.find(C=>C.id===n.selectedProvider)?.mature===l)return;const k=Wt(l);f.current=r??null,a({type:"SET_PROVIDER",payload:R.find(C=>C.id===k)?.id??R[0].id})},[_?.isAdult,n.selectedProvider,r,M,s]),O(()=>{if(s||!r||!/^dango-mt-\d+$/.test(r)||f.current===`temp:${r}`)return;const l=_?.provider;l&&(f.current=`temp:${r}`,l!==n.selectedProvider&&a({type:"SET_PROVIDER",payload:l}))},[r,_,n.selectedProvider,s]);const{data:P,isLoading:D,isFetching:$,error:U}=xt({queryKey:[de.videoSources,r,e,n.selectedProvider,n.currentMode],queryFn:()=>Bt(r,e,n,a),enabled:!!r&&!!e&&!(n.showMeta?.isAdult===!0&&!m?.hasMatureConsent)}),{mutateAsync:h}=Et({mutationFn:async({wasIn:l,showMeta:R})=>{if(!r)throw new Error("Missing showId");if(l)await be.watchlist.remove.mutate({id:r});else{const k=R.name||R.names?.romaji;if(!k)throw new Error("Missing show name");await be.watchlist.add.mutate({id:r,name:k,thumbnail:R.thumbnail,nativeName:R.names?.native,englishName:R.names?.english,type:R.type,isAdult:R.isAdult})}return!l},onSuccess:l=>{_e.success(l?"Added to watchlist":"Removed from watchlist"),i.invalidateQueries({queryKey:[de.playerData,r]}),i.invalidateQueries({queryKey:[de.showData,r]}),i.invalidateQueries({queryKey:[de.watchlist]})},onError:l=>_e.error(l instanceof Error?l.message:"Failed to update watchlist")}),v=Q(async()=>{!r||!_||await h({wasIn:!!c?.inWatchlist,showMeta:_})},[r,_,c?.inWatchlist,h]),K=Q(async l=>{try{await be.settings.set.mutate({key:"preferredSource",value:l})}catch(R){console.error(R)}},[]),{mutateAsync:V,isPending:G}=Et({mutationFn:async({status:l})=>{if(!r)throw new Error("Missing showId");if(c?.inWatchlist)return await be.watchlist.setStatus.mutate({id:r,status:l}),l;const R=_,k=R?.name||R?.names?.romaji;if(!R||!k)throw new Error("Missing show name");return await be.watchlist.add.mutate({id:r,name:k,thumbnail:R.thumbnail,nativeName:R.names?.native,englishName:R.names?.english,type:R.type,isAdult:R.isAdult,status:l}),l},onSuccess:l=>{a({type:"SET_STATE",payload:{inWatchlist:!0,watchlistStatus:l}}),_e.success(`Moved to ${l}`),i.invalidateQueries({queryKey:[de.showData,r]}),i.invalidateQueries({queryKey:[de.watchlist]}),i.invalidateQueries({queryKey:[de.continueWatching]})},onError:()=>_e.error("Failed to update watchlist status")}),Z=Q(async()=>{await V({status:"Completed"})},[V]),{mutateAsync:W,isPending:L}=Et({mutationFn:async({episodeNumber:l,duration:R,showMeta:k,episodes:C})=>{await be.progress.updateProgress.mutate({showId:r??"",episodeNumber:l,currentTime:R,duration:R,showName:k.name,showThumbnail:k.thumbnail,nativeName:k.names?.native,englishName:k.names?.english,genres:k.genres?.map(I=>I.name),popularityScore:vr(k.score)??void 0,type:k.type,status:k.status,episodeCount:C.length,isAdult:k.isAdult})},onSuccess:(l,R)=>{_e.success(`Episode ${R.episodeNumber} marked as watched`),i.invalidateQueries({queryKey:[de.playerData,r]}),i.invalidateQueries({queryKey:[de.showMeta,r]}),i.invalidateQueries({queryKey:[de.videoSources,r,R.episodeNumber]}),i.invalidateQueries({queryKey:[de.continueWatching]}),i.invalidateQueries({queryKey:[de.thisWeekSchedule]}),i.invalidateQueries(b.continueWatching.pathFilter())},onError:()=>_e.error("Failed to mark episode as watched")}),J=Q(async(l,R)=>{!r||!_||await W({episodeNumber:l,duration:R,showMeta:_,episodes:c?.episodes||[]})},[r,_,c?.episodes,W]),A=Q(async()=>{a({type:"SET_STATE",payload:{showCombinedDetails:!n.showCombinedDetails}})},[n.showCombinedDetails]),q=Me(()=>{const l=y||U,R=l?l.message:null,k=R==="AUTH_REQUIRED"?null:R,C=P&&P.fetchedEpisodeNumber===e?P:null,I=!!P&&!C,H=s?C?.videoSources?.find(ie=>ie.sourceName===s.source&&ie.type!=="iframe"&&ie.links.some(j=>j.hls))??null:null,Ae=(n.selectedSource?.sourceName===H?.sourceName?H?.links.find(ie=>ie.hls&&ie.link===n.selectedLink?.link):null)??H?.links.filter(ie=>ie.hls).slice().sort((ie,j)=>(parseInt(j.resolutionStr)||0)-(parseInt(ie.resolutionStr)||0))[0]??null;return{...n,currentEpisode:e,showMeta:{...n.showMeta||{},..._||{}},episodes:c?.episodes||[],watchedEpisodes:c?.watchedEpisodes||[],inWatchlist:!!c?.inWatchlist,watchlistStatus:c?.watchlistStatus??n.watchlistStatus??null,videoSources:C?.videoSources||[],selectedSource:s?H:n.selectedSource||C?.selectedSource||null,selectedLink:s?Ae:n.selectedLink||C?.selectedLink||null,resumeTime:s?0:C?.resumeTime||0,resumeDuration:C?.resumeDuration||0,resumeProgressPending:$,showResumeModal:!s&&n.showResumeModal&&(C?.showResumeModal??!1),skipIntervals:C?.skipIntervals||[],loadingShowData:x,loadingVideo:D||I,error:k,fetchedEpisodeNumber:C?.fetchedEpisodeNumber}},[n,_,c,P,x,D,$,y,U,e,s]),ee=Q((l,R)=>{const k=R||r;if(!k||!l||k===r&&l===e)return;const I=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(k)&&n.selectedProvider!=="animepahe"?"animepahe":n.selectedProvider,H=["video-sources",k,l,I,n.currentMode];i.getQueryState(H)?.status!=="success"&&i.prefetchQuery({queryKey:H,queryFn:()=>Bt(k,l,{selectedProvider:I,currentMode:n.currentMode},a,!0),staleTime:300*1e3,gcTime:1800*1e3})},[r,e,i,n,a]);return{state:q,dispatch:a,toggleWatchlist:v,moveToCompleted:Z,setPreferredSource:K,handleToggleDetails:A,markEpisodeWatched:J,prefetchEpisodeSources:ee,isMarkingWatched:L,isUpdatingWatchlistStatus:G}};function vs({onPrevious:r,onNext:o,onToggleTheater:d,flashControls:m}){O(()=>{const w=a=>{a.defaultPrevented||a.ctrlKey||a.metaKey||a.altKey||a.repeat||a.target.closest('input, textarea, button, select, a, [role="button"], [role="slider"], [contenteditable="true"]')||(["arrowup","arrowdown","arrowleft","arrowright"].includes(a.key.toLowerCase())&&m(),a.key.toLowerCase()==="n"&&o(),a.key.toLowerCase()==="p"&&r(),a.key.toLowerCase()==="t"&&d())};return document.addEventListener("keydown",w),()=>{document.removeEventListener("keydown",w)}},[m,o,r,d])}const tt=(r,o,d)=>r.showId===o||!!d&&r.showId===d;function gs({testClipActive:r,selectedSourceType:o,onEnded:d,queue:m,removeFromQueue:w,showId:a,showMetaId:s,showStatus:n,currentEpisode:i,isAutoplayEnabled:b,nextEpisode:p,previousEpisode:f,navigate:E,invalidateContinueWatching:M,dispatch:e}){const[g,T]=ae(!1),[_,x]=ae(null),[y,c]=ae(null),P=N(w);P.current=w;const D=N(!1),$=n?.toUpperCase()==="FINISHED";O(()=>{D.current=!1,T(!1)},[a,i]);const U=Q(()=>{if(r||D.current)return;D.current=!0,d();const W=m.find(L=>tt(L,a,s)&&L.episodeNumber===i);if(m.length>0){const L=m.findIndex(A=>tt(A,a,s)&&A.episodeNumber===i),J=L>=0?m[L+1]||null:m[0];c({nextItem:J,playedItem:W||null}),x(2);return}if(W&&P.current({showId:W.showId,episodeNumber:W.episodeNumber}),b&&p){M(),E(`/watch/${a}/${p}`);return}!p&&$&&T(!0)},[d,E,m,a,s,i,p,b,M,r,$]),h=Q(()=>{if(m.length===0)return;d();const W=m.find(A=>tt(A,a,s)&&A.episodeNumber===i),L=m.findIndex(A=>tt(A,a,s)&&A.episodeNumber===i),J=L>=0?m[L+1]||null:m[0];W&&w({showId:W.showId,episodeNumber:W.episodeNumber}),J?E(`/watch/${J.showId}/${J.episodeNumber}`):!p&&$&&T(!0)},[d,E,m,w,a,s,i,p,$]),v=Q(()=>{p&&(M(),E(`/watch/${a}/${p}`)),T(!1),e({type:"SET_STATE",payload:{showResumeModal:!1}})},[p,E,a,e,M]),K=Q(()=>{m.length>0?h():p?v():_e.error("No next episode available")},[m.length,h,v,p]),V=Q(()=>T(!1),[]),G=Q(()=>{c(null),x(null)},[]),Z=Q(()=>{f&&E(`/watch/${a}/${f}`)},[f,E,a]);return O(()=>{const W=L=>{L.origin===window.location.origin&&o==="iframe"&&L.data?.type==="ANI_WEB_MEDIA_ENDED"&&U()};return window.addEventListener("message",W),()=>window.removeEventListener("message",W)},[U,o]),O(()=>{if(!y||_===null)return;if(_<=0){const{nextItem:L,playedItem:J}=y;c(null),x(null),J&&P.current({showId:J.showId,episodeNumber:J.episodeNumber}),L?E(`/watch/${L.showId}/${L.episodeNumber}`):!p&&$&&T(!0);return}const W=window.setTimeout(()=>{x(L=>L===null?null:L-1)},1e3);return()=>window.clearTimeout(W)},[y,_,E,p,$]),{showCompleteModal:g,queueCountdown:_,pendingQueueTransition:y,handleQueueTransition:h,handleNextEpisode:v,handleNShortcut:K,handlePreviousEpisode:Z,handlePlaybackFinished:U,closeCompleteModal:V,cancelQueueTransition:G}}function bs({videoRef:r,queue:o,showId:d,showMetaId:m,currentEpisode:w,selectedSource:a,hasNextEpisode:s,nextEpisode:n,prefetchEpisodeSources:i,matchesQueueItem:b}){const[p,f]=ae(!1),E=N(i);E.current=i;const M=N("");O(()=>{f(!1)},[w]);const e=Q(()=>{const g=r.current;if(!g||a?.type==="iframe")return;const T=g.duration,_=g.currentTime;if(!T||Number.isNaN(T)){f(!1);return}if(T-_<=60){const x=o.findIndex(P=>b(P,d,m)&&P.episodeNumber===w),y=o.length>0?x>=0?o[x+1]||null:o[0]:null,c=y?`${y.showId}:${y.episodeNumber}`:s?`${d}:${n}`:"";c&&M.current!==c&&(M.current=c,y?E.current(y.episodeNumber,y.showId):E.current(n??""))}f(s&&rt(_,T))},[r,a,o,d,m,w,s,n,b]);return{showNextEpisodePrompt:p,handleThresholds:e}}const kt="fallbackChoice";function ys(){try{const r=Y.getItem(kt);return r==="iframe"||r==="retry"?r:null}catch{return null}}function Ss(r){try{r===null?Y.removeItem(kt):Y.setItem(kt,r)}catch{}}function Es({showId:r,episodeNumber:o,currentMode:d,selectedProvider:m,selectedSourceType:w,videoSources:a,isAdult:s,providerOrder:n,matureProviders:i,setPreferredSource:b,dispatch:p,showControls:f}){const E=N(!1),M=N([]),e=N(!1),[g,T]=ae(null),[_,x]=ae(!1),[y,c]=ae(!1),[P,D]=ae(()=>ys()??"ask"),$=Q(A=>{D(A),Ss(A==="ask"?null:A)},[]),U=N(P);O(()=>{U.current=P},[P]);const h=N(a);h.current=a;const v=Q(()=>{E.current=!1,M.current=[],e.current=!1,T(null),x(!1)},[]);O(()=>{v()},[v,r,o]);const K=Q(A=>{if(E.current)return;E.current=!0;const q=A.links[0];b(A.sourceName),p({type:"SET_STATE",payload:{selectedSource:A,selectedLink:q}}),T(null)},[p,b]),V=Q(()=>{const q=h.current.find(ee=>ee.type==="iframe");return q?.links?.length?q:null},[]),G=Q(async()=>{const A=n.filter(q=>{if(M.current.includes(q))return!1;const ee=i.has(q);return s===void 0?!0:ee===s});x(!0);try{for(const q of A){M.current.push(q);let ee=null;try{ee=await be.data.video.query({showId:r,episodeNumber:o,mode:d,provider:q})}catch{continue}const l=(ee??[]).filter(C=>{const I=C.sourceName.toLowerCase();return d==="dub"?I.includes("eng")||I.includes("dub"):I.includes("jpn")||I.includes("sub")||!I.includes("eng")&&!I.includes("dub")});if((l.length>0?l:ee??[]).find(C=>C.type!=="iframe"&&C.links?.length)){M.current=[m],e.current=!1,p({type:"SET_STATE",payload:{selectedProvider:q,videoSources:[],selectedSource:null,selectedLink:null,loadingVideo:!0}}),Ut(q,s===!0),T(null),_e.success(`Switched to ${q} (direct stream)`);return}}T({retryFailed:!0}),_e.error("No working direct stream found on other providers")}finally{x(!1)}},[r,o,d,s,m,p,n,i]),Z=Q(()=>{if(E.current||e.current||w!=="player")return;const A=V();if(!A)return;M.current.includes(m)||M.current.push(m);const q=U.current;if(q==="iframe"){K(A);return}if(q==="retry"){G();return}f(!0),T({retryFailed:!1})},[w,m,V,K,G,f]),W=Q(()=>{e.current=!0,T(null),c(!1)},[]),L=Q(()=>{y&&$("iframe");const A=V();A?K(A):T(null)},[y,$,V,K]),J=Q(()=>{y&&$("retry"),G()},[y,$,G]);return{fallbackPrompt:g,isRetryingProvider:_,rememberFallbackChoice:y,setRememberFallbackChoice:c,fallbackChoice:P,updateFallbackChoice:$,dismissFallbackPrompt:W,chooseIframeFallback:L,chooseProviderRetry:J,handleVideoSourceError:Z,resetFallback:v}}function ks({engine:r,videoRef:o,selectedSource:d,selectedLink:m,loadingVideo:w,testClipActive:a,resumeTime:s,resumeDuration:n=0,showResumeModal:i,disabled:b=!1,startOver:p=!1,calibReturnRef:f,setAvailableSubtitles:E,setActiveSubtitleTrack:M,onFatalError:e}){const g=N(null),T=N(s),_=N(n),x=N(i),y=N(e);return y.current=e,O(()=>{T.current=s,_.current=n,x.current=i},[s,n,i]),O(()=>{if(b){r.unload();return}const c=o.current;if(!c)return;for(;c.firstChild;)c.removeChild(c.firstChild);if(a)return r.loadSource({url:"/av-sync-test.mp4"},{autoPlay:!0});if(w||!d||!m||d.type==="iframe"){r.unload();return}p?g.current=0:f.current!=null?(g.current=f.current,f.current=null):g.current===null&&T.current>5&&!x.current&&!rt(T.current,_.current)?g.current=T.current:g.current===null&&x.current&&(g.current=0);let P=m.link;if(P.startsWith("/api/proxy")||(P=`/api/proxy?url=${encodeURIComponent(P)}`,m.headers?.Referer&&(P+=`&referer=${encodeURIComponent(m.headers.Referer)}`)),d.subtitles){const U=Y.getItem("playerSubtitlesEnabled")!=="false";let h=null;try{h=Y.getItem("playerLastSubtitle")}catch{}const v=wt(d.subtitles,{lastKey:h,enabled:U}),K=v>=0?d.subtitles[v]:null;d.subtitles.forEach(V=>{const G=document.createElement("track");G.kind="subtitles",G.label=V.label,G.srclang=V.lang;const Z=V.src??V.url;if(Z){let W=`/api/subtitle-proxy?url=${encodeURIComponent(Z)}`;const L=m.headers?.Referer;L&&(W+=`&referer=${encodeURIComponent(L)}`),G.src=W}K&&V.label===K.label&&V.lang===K.lang&&(G.default=!0),c.appendChild(G)}),U||M("off"),E(d.subtitles)}const D=g.current??0;g.current=null;const $=document.body.classList.contains("low-end");return r.loadSource({url:P,hls:m.hls},{initialTime:D,autoPlay:p||!(x.current&&T.current>5)&&!rt(T.current,_.current),hlsConfig:{maxBufferLength:$?15:30,maxMaxBufferLength:$?30:60,maxBufferSize:($?25:60)*1e3*1e3,startLevel:-1},onHls:(U,h)=>{if(!d.subtitles?.length)return;const v=()=>{U.subtitleTrack!==-1&&(U.subtitleTrack=-1)};U.on(h.Events.SUBTITLE_TRACK_SWITCH,v),v()},onError:()=>y.current()})},[r,d,m,o,f,w,a,b,p,M,E]),{seekToTimeRef:g}}function ws({videoRef:r,availableSubtitles:o,activeSubtitleTrack:d,setAvailableSubtitles:m,setActiveSubtitleTrack:w}){O(()=>{const a=r.current;if(!a)return;const s=()=>{const n=Array.from(a.textTracks).map(i=>({label:i.label,lang:i.language,src:void 0,mode:i.mode}));m(n)};return a.textTracks.addEventListener("addtrack",s),a.textTracks.addEventListener("removetrack",s),s(),()=>{a.textTracks.removeEventListener("addtrack",s),a.textTracks.removeEventListener("removetrack",s)}},[r,m]),O(()=>{if(d===null&&o.length>0&&Y.getItem("playerSubtitlesEnabled")!=="false"){let a=null;try{a=Y.getItem("playerLastSubtitle")}catch{}const s=wt(o,{lastKey:a,enabled:!0});if(s<0){w("off");return}const n=o[s];w(n.lang||n.label)}},[d,o,w]),O(()=>{const a=r.current;if(!a||o.length===0)return;const s=d;if(!(Y.getItem("playerSubtitlesEnabled")!=="false")||s==="off"||s===null){Array.from(a.textTracks).forEach(b=>{b.mode="hidden"});return}let i=!1;if(Array.from(a.textTracks).forEach(b=>{const f=(b.language===s||b.label===s)&&!i;b.mode=f?"showing":"hidden",f&&(i=!0)}),!i&&a.textTracks.length>0){const b=Array.from(a.textTracks).find(p=>p.language==="en"||p.label==="English")||a.textTracks[0];b&&(b.mode="showing")}},[d,o,r])}function Ts({videoRef:r,videoBoxH:o,style:d,sourceKey:m,activeSubtitleTrack:w,availableSubtitles:a}){O(()=>{const s="dynamic-subtitle-styles";let n=document.getElementById(s);n||(n=document.createElement("style"),n.id=s,document.head.appendChild(n)),n.textContent=Lt(d);const i=r.current;if(!i)return;const b=It(d.fontSize,o||i.clientHeight||720);n.textContent=Lt({...d,fontSize:b});const p=()=>{const c=Number(d.position),P=isNaN(c)?0:Math.max(0,Math.min(100,c));return Math.max(0,Math.min(100,100-P))},f=(c,P)=>{try{const D=c;D.snapToLines=!1,D.line=P}catch{}},E=()=>{const c=b*16,P=i.videoHeight||i.clientHeight||720,D=i.videoWidth||i.clientWidth||1280;return{step:c*1.3/P*100,chars:Math.max(20,Math.floor(D/(c*.55)))}},M=c=>{const P=p(),D=Array.from(c.activeCues??[]);if(D.length<=1){D.forEach(v=>f(v,P));return}const{step:$,chars:U}=E();let h=P;for(let v=D.length-1;v>=0;v--){const V=String(D[v].text??"").replace(/<[^>]*>/g,"").split(`
|
|
55
|
-
`).reduce((Z,W)=>Z+Math.max(1,Math.ceil(W.length/U)),0),G=h-V*$;f(D[v],Math.max(0,G)),h=G-$*.4}},e=c=>{if(!c.cues)return;const P=p();Array.from(c.cues).forEach(D=>f(D,P)),c.mode==="showing"&&M(c)},g=()=>{Array.from(i.textTracks).forEach(e)};g();const T=c=>{const P=c.target;P.mode==="showing"&&M(P)};Array.from(i.textTracks).forEach(c=>{c.addEventListener("cuechange",T)});const _=()=>{Array.from(i.textTracks).forEach(c=>{c.removeEventListener("cuechange",T),c.addEventListener("cuechange",T)}),g()};i.textTracks.addEventListener("addtrack",_),i.textTracks.addEventListener("removetrack",_);const x=Array.from(i.querySelectorAll("track")),y=()=>{g()};return x.forEach(c=>{c.addEventListener("load",y)}),()=>{Array.from(i.textTracks).forEach(c=>{c.removeEventListener("cuechange",T)}),i.textTracks.removeEventListener("addtrack",_),i.textTracks.removeEventListener("removetrack",_),x.forEach(c=>{c.removeEventListener("load",y)})}},[d,o,r,m,w,a])}function Cs({videoRef:r,overlayRef:o,style:d,activeSubtitleTrack:m,delayMs:w,enabled:a}){O(()=>{if(!a)return;const s=r.current,n=o.current;if(!s||!n)return;const i=Y.getItem("playerSubtitlesEnabled")!=="false",b=()=>{if(n.innerHTML="",!i||m==="off"||m===null)return;const E=Array.from(s.textTracks).find(y=>y.language===m||y.label===m);if(!E||E.mode!=="showing")return;const M=w/1e3;let e;if(M>0&&E.cues){const y=s.currentTime-M;e=Array.from(E.cues).filter(c=>c.startTime<=y&&y<=c.endTime)}else e=Array.from(E.activeCues??[]);if(e.length===0)return;const g={...d,fontSize:It(d.fontSize,s.clientHeight||0)},T=Fr(g),_=Or(s,g.position),x=Array.from(e);x.forEach((y,c)=>{const P=String(y.text??"");if(!Wr(P).trim())return;const D=document.createElement("div"),$=(x.length-1-c)*1.7;D.style.cssText=`${T}
|
|
56
|
-
bottom: calc(${_}px + ${$}em);`,D.innerHTML=Ur(P),n.appendChild(D)})},p=()=>b(),f=()=>b();return Array.from(s.textTracks).forEach(E=>{E.addEventListener("cuechange",p)}),s.addEventListener("timeupdate",f),b(),()=>{Array.from(s.textTracks).forEach(E=>{E.removeEventListener("cuechange",p)}),s.removeEventListener("timeupdate",f),n.innerHTML=""}},[m,w,a,o,d,r])}const Ms=({isOpen:r,onClose:o,onSuccess:d})=>{const m=()=>{d?.(),o()};return t(ht,{isOpen:r,onClose:o,title:"MKissa Browser Verification",children:t("div",{className:qe.container,children:[t("p",{children:"Open MKissa in this browser, play an anime episode, and complete any Cloudflare verification it shows. Once playback works there, return to Dango and click Refresh."}),t("div",{className:qe.actions,children:t("a",{className:qe.link,href:"https://mkissa.to/anime",target:"_blank",rel:"noreferrer",children:"Open MKissa anime"})}),t("div",{className:qe.actions,children:[t("button",{className:qe.secondaryButton,onClick:o,children:"Cancel"}),t("button",{className:qe.button,onClick:m,children:"Refresh Dango"})]})]})})},Ks=()=>{const{id:r,episodeNumber:o}=dr(),d=mr(),m=$t(),w=pr(),a=gr(),s=!!a.session,n=s&&!a.session?.host,{hasConsent:i,grant:b}=br(),{options:p}=Ft(),f=Me(()=>p.filter(u=>(u.kind??"anime")==="anime"),[p]),E=Me(()=>f.map(u=>u.id),[f]),M=Me(()=>new Set(f.filter(u=>u.mature).map(u=>u.id)),[f]),{state:e,dispatch:g,toggleWatchlist:T,moveToCompleted:_,setPreferredSource:x,handleToggleDetails:y,markEpisodeWatched:c,prefetchEpisodeSources:P,isMarkingWatched:D,isUpdatingWatchlistStatus:$}=fs(r,o,w.state||null,{hasMatureConsent:i,watchSelection:n?a.room?.selection:null});O(()=>{if(r&&e.showMeta?.id&&e.showMeta.id!==r){const u=o?`/watch/${e.showMeta.id}/${o}${window.location.search}`:`/watch/${e.showMeta.id}${window.location.search}`;d(u,{replace:!0})}},[r,e.showMeta?.id,o,d]);const U=Me(()=>{if(e.showMeta.name)return{name:e.showMeta.name,thumbnail:e.showMeta.thumbnail,names:e.showMeta.names,genres:e.showMeta.genres,score:e.showMeta.score,isAdult:e.showMeta.isAdult}},[e.showMeta.name,e.showMeta.thumbnail,e.showMeta.names,e.showMeta.genres,e.showMeta.score,e.showMeta.isAdult]),h=Vr({skipIntervals:e.skipIntervals,showId:r,episodeNumber:e.currentEpisode?.toString(),episodeCount:e.episodes.length||void 0,sourceType:e.selectedSource?.type,showMeta:U}),{refs:v,actions:K}=h,V=Me(()=>!r||r.startsWith("dango-mt-")||!e.currentEpisode||e.selectedSource?.type==="iframe"||!e.selectedLink?.hls||!e.selectedSource?null:{showId:r,episode:e.currentEpisode,provider:e.selectedProvider,mode:e.currentMode,source:e.selectedSource.sourceName,title:e.showMeta.name||r},[r,e.currentEpisode,e.selectedProvider,e.currentMode,e.selectedSource,e.selectedLink,e.showMeta.name]),G=Qr(h.engine,V,e.loadingVideo||e.loadingShowData),Z=ln(),W=N(null),L=N(null),J=N(null),[A,q]=ae(()=>{try{const u=Y.getItem("anime4kProfile");return["low","balanced","high","denoise"].includes(u)?u:"balanced"}catch{return"balanced"}}),{videoDelayMs:ee,videoDelayEnabled:l,setDelayEnabled:R,handleVideoDelayChange:k,isCalibrating:C,testClipActive:I,stopCalibration:H,openAvSyncCalibrator:Re,cancelAvSyncCalibrator:Ae,applyAvSyncCalibrator:ie,toggleTestClip:j,calibReturnRef:xe,effectiveVideoDelayMs:Fe}=Kr(v.videoRef,()=>K.setShowSettings(!1)),le=N(null),[ne,Ne]=ae(!1);O(()=>{Ne(!1)},[r,e.currentEpisode]);const ce=`${r??""}:${e.currentEpisode??""}`,[Oe,nt]=ae(null);O(()=>{e.loadingVideo||e.videoSources.length===0||nt(u=>u?.key===ce?u:{key:ce,watched:rt(e.resumeTime,e.resumeDuration)})},[ce,e.loadingVideo,e.videoSources.length,e.resumeTime,e.resumeDuration]);const ft=Oe?.key===ce&&Oe.watched,Le=!s&&!I&&ft&&e.videoSources.length>0&&!ne,vt=Q(()=>Ne(!0),[]),te=ls({videoRef:v.videoRef,canvasRef:L,profile:A,delayMs:Fe}),se=te.isEnabled&&te.isWebGPUSupported;cs({videoRef:v.videoRef,episodeKey:`${r??""}:${e.currentEpisode??""}`,isEnabled:te.isEnabled,isSupported:te.isWebGPUSupported,mediaReady:!e.loadingVideo&&!!e.selectedLink,isIframeSource:e.selectedSource?.type==="iframe",setEnabled:te.setEnabled}),qr({videoRef:v.videoRef,canvasRef:le,delayMs:Fe,enabled:l&&!se});const st=l&&!se,ze=se||st,[ot,He]=ae(!1),je=N(o);O(()=>{je.current!==o&&(je.current=o,H())},[o,H]);const F=Q(()=>{m.invalidateQueries({queryKey:[de.continueWatching]})},[m]),{data:Se=[],isLoading:at}=yr(),ye=Sr(),gt=Er(),Ve=kr(),{isTheaterMode:me,toggleTheaterMode:Qe,handleLayoutClick:it}=Gr();hr(()=>{if(h.state.isFullscreen||me)return;const u=v.playerContainerRef.current,X=W.current;if(!u||!X)return;const We=()=>{const St=u.getBoundingClientRect().height;X.style.height=`${St}px`};We();const Ie=new ResizeObserver(We);return Ie.observe(u),()=>Ie.disconnect()},[h.state.isFullscreen,me,v.playerContainerRef]);const Ee=Me(()=>e.episodes.findIndex(u=>u===e.currentEpisode),[e.episodes,e.currentEpisode]),Ye=Ee>0?e.episodes[Ee-1]:null,Be=Ee>=0&&Ee<e.episodes.length-1?e.episodes[Ee+1]:null,lt=Ee>-1&&Ee<e.episodes.length-1,{showCompleteModal:bt,queueCountdown:ct,pendingQueueTransition:ut,handleQueueTransition:z,handleNextEpisode:oe,handleNShortcut:ke,handlePreviousEpisode:pe,handlePlaybackFinished:fe,closeCompleteModal:he,cancelQueueTransition:we}=gs({testClipActive:I,selectedSourceType:e.selectedSource?.type,onEnded:K.onEnded,queue:Se,removeFromQueue:ye.mutate,showId:r,showMetaId:e.showMeta?.id,showStatus:e.showMeta?.status,currentEpisode:e.currentEpisode,isAutoplayEnabled:!n&&e.isAutoplayEnabled,nextEpisode:Be,previousEpisode:Ye,navigate:d,invalidateContinueWatching:F,dispatch:g}),{showNextEpisodePrompt:Xe,handleThresholds:De}=bs({videoRef:v.videoRef,queue:Se,showId:r,showMetaId:e.showMeta?.id,currentEpisode:e.currentEpisode,selectedSource:e.selectedSource,hasNextEpisode:lt,nextEpisode:Be,prefetchEpisodeSources:P,matchesQueueItem:tt}),{checkEnd:ve,logDuration:ue}=zr({videoRef:v.videoRef,sourceType:e.selectedSource?.type,resetKey:`${r}:${e.currentEpisode}:${ne}`,onEnd:n?K.onEnded:fe}),dt=!s&&e.showResumeModal&&!e.resumeProgressPending,Ke=bt,re=dt||Ke;Hr(h,!!e.selectedLink&&!me&&!re&&!Le);const{fallbackPrompt:Je,isRetryingProvider:Tt,rememberFallbackChoice:Vt,setRememberFallbackChoice:Qt,fallbackChoice:Kt,updateFallbackChoice:qt,dismissFallbackPrompt:Gt,chooseIframeFallback:zt,chooseProviderRetry:Ht,handleVideoSourceError:Ct,resetFallback:Mt}=Es({showId:r,episodeNumber:e.currentEpisode??void 0,currentMode:e.currentMode,selectedProvider:e.selectedProvider,selectedSourceType:e.selectedSource?.type,videoSources:e.videoSources,isAdult:e.showMeta?.isAdult,providerOrder:E,matureProviders:M,setPreferredSource:x,showControls:K.setShowControls,dispatch:g}),{seekToTimeRef:Rt}=ks({engine:h.engine,videoRef:v.videoRef,selectedSource:e.selectedSource,selectedLink:e.selectedLink,loadingVideo:e.loadingVideo,testClipActive:!s&&I,resumeTime:s?0:e.resumeTime,resumeDuration:e.resumeDuration,showResumeModal:!s&&e.showResumeModal,disabled:Le,startOver:ne,calibReturnRef:xe,setAvailableSubtitles:K.setAvailableSubtitles,setActiveSubtitleTrack:K.setActiveSubtitleTrack,onFatalError:s?()=>{}:Ct});O(()=>{re&&h.state.isFullscreen&&h.actions.toggleFullscreen()},[re,h.state.isFullscreen,h.actions]),O(()=>{re&&v.videoRef.current&&v.videoRef.current.pause()},[re,v.videoRef]);const{titlePreference:mt}=wr(),{lowEndMode:Nt}=Tr(),{settings:yt,update:jt}=jr(),Yt=me&&yt.enabled&&!Nt&&e.selectedSource?.type!=="iframe"&&!!e.selectedLink,$e=Me(()=>{if(!e.showMeta||e.loadingShowData)return"Loading...";const{name:u,names:X}=e.showMeta;return mt==="name"?u||"Loading...":mt==="nativeName"?X?.native||u||"Loading...":mt==="englishName"?X?.english||u||"Loading...":u||"Loading..."},[e.showMeta,mt,e.loadingShowData]);O(()=>{$e&&$e!=="Loading..."&&e.currentEpisode&&(document.title=`► ${$e} Episode ${e.currentEpisode} - dango`)},[$e,e.currentEpisode]),vs({onPrevious:n?()=>{}:pe,onNext:n?()=>{}:ke,onToggleTheater:Qe,flashControls:h.actions.flashControls});const{setAvailableSubtitles:Xt,setActiveSubtitleTrack:Jt}=K,Pt=Me(()=>({fontSize:h.state.subtitleFontSize,position:h.state.subtitlePosition,bgOpacity:h.state.subtitleBgOpacity,bgColor:h.state.subtitleBgColor,textColor:h.state.subtitleTextColor,edge:h.state.subtitleEdge,bold:h.state.subtitleBold}),[h.state.subtitleFontSize,h.state.subtitlePosition,h.state.subtitleBgOpacity,h.state.subtitleBgColor,h.state.subtitleTextColor,h.state.subtitleEdge,h.state.subtitleBold]);ws({videoRef:v.videoRef,availableSubtitles:h.state.availableSubtitles,activeSubtitleTrack:h.state.activeSubtitleTrack,setAvailableSubtitles:Xt,setActiveSubtitleTrack:Jt});const[Zt,er]=ae(0);O(()=>{const u=v.videoRef.current;if(!u)return;const X=()=>er(u.clientHeight||0);X();const We=new ResizeObserver(X);return We.observe(u),()=>We.disconnect()},[v.videoRef,e.selectedSource,e.selectedLink]),Ts({videoRef:v.videoRef,videoBoxH:Zt,style:Pt,sourceKey:`${e.selectedSource?.sourceName??""}:${e.selectedLink?.link??""}`,activeSubtitleTrack:h.state.activeSubtitleTrack,availableSubtitles:h.state.availableSubtitles}),Cs({videoRef:v.videoRef,overlayRef:J,style:Pt,activeSubtitleTrack:h.state.activeSubtitleTrack,delayMs:Fe,enabled:ze}),O(()=>{try{Y.setItem("anime4kProfile",A)}catch{}},[A]);const tr=()=>{v.videoRef.current&&(v.videoRef.current.currentTime=e.resumeTime,v.videoRef.current.play()),g({type:"SET_STATE",payload:{showResumeModal:!1}})},rr=()=>{v.videoRef.current&&(v.videoRef.current.currentTime=0,v.videoRef.current.play()),g({type:"SET_STATE",payload:{showResumeModal:!1}})},nr=Q(()=>{g({type:"SET_STATE",payload:{showResumeModal:!1}})},[g]),sr=Q(async()=>{try{await _(),he(),g({type:"SET_STATE",payload:{showResumeModal:!1}}),d("/")}catch{}},[_,he,g,d]),_t=(u,X)=>t("div",{className:u,children:[t("button",{className:`${S.episodeNavBtn} ${S.secondary}`,onClick:pe,disabled:n||!Ye,type:"button",children:[t(ge,{name:"chevron-left",size:12}),"Prev EP"]}),t("button",{className:`${S.episodeNavBtn} ${S.primary}`,onClick:oe,disabled:n||!Be,type:"button",children:["Next EP",t(ge,{name:"chevron-right",size:12})]}),X==="mobile"&&Z&&t("button",{className:`${S.episodeNavBtn} ${S.episodePickerBtn}`,onClick:()=>He(!0),type:"button",children:[t(ge,{name:"list-ul",size:12}),"Episodes"]})]}),or=u=>{g({type:"SET_STATE",payload:{isAutoplayEnabled:u}}),on(u)},At=!!(e.currentEpisode&&e.watchedEpisodes.includes(e.currentEpisode)),ar=e.selectedProvider!=="megaplay"||e.selectedSource?.type==="iframe",ir=Q(async()=>{if(!r||!e.currentEpisode||!e.showMeta.name||D)return;const u=v.videoRef.current?.duration,X=Math.max(u||0,e.resumeDuration||0,Number(e.showMeta.episodeDuration||0)*60,1);await c(e.currentEpisode,X)},[r,e.currentEpisode,e.showMeta,e.resumeDuration,c,D,v.videoRef]);if(e.error&&!e.showMeta.name&&e.videoSources.length===0&&e.episodes.length===0)return t("p",{className:"error-message",children:["Error: ",e.error]});const Te=e.loadingShowData||e.loadingVideo;return e.showMeta?.isAdult===!0&&!i?t("div",{className:Ce.playerPageLayout,children:t(an,{isOpen:!0,onClose:()=>d("/home"),onGrant:b})}):t("div",{className:`${Ce.playerPageLayout} ${me?Ce.theaterMode:""}`,onClick:it,children:[me&&t(Yr,{videoRef:v.videoRef,active:Yt,settings:yt}),t(Xr,{isOpen:Ke,onClose:he,title:"Show Completed!",heading:$e,message:"Congratulations! You finished all available episodes.",children:[t(Ge,{variant:"secondary",onClick:he,children:"Close"}),t(Ge,{onClick:sr,disabled:$,children:$?"Saving...":"Move to Completed"})]}),t(Jr,{isOpen:dt,onClose:nr,title:"Resume Playback?",message:t(Ze,{children:["You were watching at ",t("strong",{children:h.actions.formatTime(e.resumeTime)}),". Would you like to continue?"]}),onResume:tr,onRestart:rr}),t(ht,{isOpen:!!Je,onClose:Gt,title:"Direct stream failed",width:"sm",children:[t(ht.Body,{children:[t("p",{children:[t("strong",{children:e.selectedProvider}),"'s direct stream failed for this episode."]}),Je?.retryFailed&&t("p",{children:"No working direct stream was found on the other providers either."}),t("p",{children:["You can continue with the embedded (iframe) player, but embedded players may show"," ",t("strong",{children:"ads and pop-ups"}),"."]}),t("label",{style:{display:"flex",alignItems:"center",gap:"8px",marginTop:"0.75rem",cursor:"pointer"},children:[t("input",{type:"checkbox",checked:Vt,onChange:u=>Qt(u.currentTarget.checked)}),"Remember my choice"]})]}),t(ht.Actions,{children:[t(Ge,{variant:"secondary",onClick:zt,children:"Continue with iframe"}),t(Ge,{onClick:Ht,disabled:Tt,children:Tt?"Searching…":"Try another provider"})]})]}),t(Cr,{isOpen:!!e.showCookieModal&&e.cookieProvider!=="mkissa",onClose:()=>g({type:"SET_STATE",payload:{showCookieModal:!1}}),onSuccess:()=>{m.invalidateQueries({queryKey:[de.videoSources,r,e.currentEpisode,e.selectedProvider,e.currentMode]})}}),t(Ms,{isOpen:!!e.showCookieModal&&e.cookieProvider==="mkissa",onClose:()=>g({type:"SET_STATE",payload:{showCookieModal:!1}}),onSuccess:()=>{m.invalidateQueries({queryKey:[de.videoSources,r,e.currentEpisode,e.selectedProvider,e.currentMode]})}}),!me&&t("aside",{ref:W,className:Ce.episodeSidebar,children:e.loadingShowData?t(Zr,{variant:"sidebar"}):t(en,{episodes:e.episodes,currentEpisode:e.currentEpisode??void 0,watchedEpisodes:e.watchedEpisodes,onEpisodeClick:u=>{n||d(`/watch/${r}/${u}`)}})}),t("div",{className:Ce.playerMain,children:[t("div",{className:`${S.videoContainer} ${h.state.isFullscreen?"":Ce.videoPlayerWrapper} ${h.state.isFullscreen?S.fullscreenActive:""}`,style:{...re?{visibility:"hidden"}:{}},onContextMenu:u=>u.preventDefault(),children:t(jn,{player:h,isAutoplayEnabled:e.isAutoplayEnabled,onAutoplayChange:or,fallbackChoice:Kt,onFallbackChoiceChange:qt,ambientSettings:yt,onAmbientChange:jt,showNextEpisodeButton:!n&&!re&&Xe&&Se.length===0,onNextEpisode:oe,videoSources:n?[]:s?e.videoSources.filter(u=>u.type!=="iframe"&&u.links.some(X=>X.hls)):e.videoSources,selectedSource:e.selectedSource,selectedLink:e.selectedLink,onSourceChange:(u,X)=>{n&&u.sourceName!==a.room?.selection.source||s&&(u.type==="iframe"||!X.hls)||(v.videoRef.current&&!isNaN(v.videoRef.current.currentTime)&&(Rt.current=v.videoRef.current.currentTime),x(u.sourceName),g({type:"SET_STATE",payload:{selectedSource:u,selectedLink:X,showResumeModal:e.showResumeModal&&u.type!=="iframe"}}))},loadingVideo:Te,skipIntervals:e.skipIntervals,animeTitle:$e,episodeNumber:e.currentEpisode??void 0,mode:e.currentMode,isTheaterMode:me,onTheaterModeToggle:Qe,anime4kEnabled:te.isEnabled,onAnime4kToggle:te.toggle,anime4kSupported:te.isWebGPUSupported,anime4kProfile:A,onAnime4kProfileChange:q,anime4kInitializing:te.isInitializing,anime4kError:te.error,videoDelayEnabled:l,onVideoDelayToggle:R,videoDelayMs:ee,onVideoDelayChange:k,onCalibrateAvSync:s?()=>{}:Re,isInteractingExtra:ot||C,className:xr.shellFill,hideChrome:Le||e.selectedSource?.type==="iframe",overlays:t(Ze,{children:[h.state.isSpeedBoostActive&&t("div",{className:S.speedBoostBadge,"aria-hidden":"true",children:[t("span",{children:"2x"}),t(ge,{name:"forward",size:12})]}),ct!==null&&ut?.nextItem&&t("div",{className:S.queueCountdown,children:["Queue next in ",ct,"s"]})]}),children:t(Ze,{children:[Te&&t("div",{className:S.loadingOverlay,children:t("div",{className:S.loadingDots,children:[t("div",{className:S.dot}),t("div",{className:S.dot}),t("div",{className:S.dot})]})}),h.state.isBuffering&&!Te&&e.selectedSource?.type!=="iframe"&&t("div",{className:S.bufferingOverlay,children:t("div",{className:S.bufferingSpinner})}),e.selectedSource?.type==="iframe"&&!s?!Te&&t("iframe",{src:e.selectedLink?.link,className:S.videoIframe,allow:"autoplay; fullscreen; picture-in-picture",allowFullScreen:!0,sandbox:e.selectedSource.sandbox?`${e.selectedSource.sandbox} allow-fullscreen allow-popups allow-popups-to-escape-sandbox`:void 0}):t(Ze,{children:[!Te&&e.videoSources.length===0&&t("div",{className:S.errorOverlay,children:[t("p",{children:["No sources found for this episode with ",e.selectedProvider,"."]}),t("p",{className:S.errorSubtext,children:"Please try selecting a different provider below."}),t("button",{className:S.retryButton,onClick:()=>window.location.reload(),"data-speed-boost-ignore":"true",style:{marginTop:8},children:"Retry"})]}),!Te&&e.videoSources.length>0&&t(Lr,{controls:!h.state.playbackLocked&&h.state.useNativeControls,playsInline:!0,"webkit-playsinline":"true",disablePictureInPicture:!0,disableRemotePlayback:!0,onPlay:K.onPlay,onPause:K.onPause,onEnded:()=>{I||ve(!0)},onDurationChange:()=>{ue()},onSeeked:()=>{I||(De(),ve())},onLoadedMetadata:()=>{De(),ue(),I||ve()},onTimeUpdate:()=>{I||(K.onTimeUpdate(),De(),ve(),ut&&v.videoRef.current&&v.videoRef.current.currentTime<v.videoRef.current.duration-1&&we())},onError:s?void 0:Ct,onContextMenu:u=>u.preventDefault(),className:ze?S.videoElementHidden:""}),te.isWebGPUSupported&&!Te&&e.videoSources.length>0&&t("canvas",{ref:L,className:`${S.upscalerCanvas} ${se?S.upscalerActive:""}`}),!se&&!Te&&e.videoSources.length>0&&t("canvas",{ref:le,className:`${S.upscalerCanvas} ${st?S.upscalerActive:""}`}),te.isEnabled&&te.isWebGPUSupported&&te.isInitializing&&t("div",{className:S.upscalerStatusBadge,children:"Preparing upscaler…"}),ze&&t("div",{ref:J,className:S.subtitleOverlay}),t(tn,{isOpen:C,ms:ee,onChange:k,onApply:ie,onClose:Ae,testClipActive:I,onTestClip:j})]}),Le&&t("div",{className:S.watchedOverlay,children:[t(ge,{name:"check-circle",size:48,style:{color:"var(--accent-lighter)"}}),t("p",{className:S.watchedTitle,children:e.currentEpisode?`Episode ${e.currentEpisode} watched`:"Watched"}),t("p",{className:S.watchedSubtext,children:"Replay from the beginning or continue with the next episode."}),t("div",{className:S.watchedActions,children:[t(Ge,{onClick:vt,children:"Replay"}),Be&&t(Ge,{variant:"secondary",onClick:oe,children:"Next Episode"})]})]})]})})}),t(hn,{playback:V&&!Te?{selection:V,position:v.videoRef.current?.currentTime||0,playing:!1,rate:h.engine.getState().playbackRate}:null,onCreate:()=>{H(),h.engine.pause()},needsPlayback:G.needsPlayback,onEnablePlayback:G.enablePlayback}),s&&!Te&&!V&&t("p",{role:"alert",children:"This room requires the host's direct HLS source. It is unavailable here. Retry the episode or leave the room to use another source."}),!me&&t(rn,{}),!me&&t(Ze,{children:[at&&Se.length===0?t(Yn,{count:3}):t(cn,{title:"Queue",items:Se,currentShowId:r,currentEpisode:e.currentEpisode??void 0,onNextQueue:n?()=>{}:z,onRemove:u=>ye.mutate({showId:u.showId,episodeNumber:u.episodeNumber}),onClear:()=>gt.mutate(),showClearAll:!0,onReorder:u=>Ve.mutate(u.map(X=>({id:X.id,showId:X.showId,episodeNumber:X.episodeNumber})))}),t("div",{className:S.streamPanel,children:[!n&&t(es,{selectedProvider:e.selectedProvider,isAdult:e.showMeta?.isAdult,options:f,onProviderChange:u=>{Mt(),g({type:"SET_STATE",payload:{selectedProvider:u,videoSources:[],selectedSource:null,selectedLink:null,loadingVideo:!0}}),Ut(u,e.showMeta?.isAdult===!0)}}),_t(`${S.episodeActions} ${S.desktopEpisodeActions}`,"desktop"),Te?t("div",{className:S.sourceLoader,children:t("div",{className:S.spinner})}):n?t("p",{children:["Provider: ",e.selectedProvider," · Source: ",a.room?.selection.source," ·"," ",e.currentMode]}):t(rs,{videoSources:s?e.videoSources.filter(u=>u.type!=="iframe"&&u.links.some(X=>X.hls)):e.videoSources,selectedSource:e.selectedSource,selectedLink:e.selectedLink,onSourceChange:u=>{if(s&&(u.type==="iframe"||!u.links.some(Ie=>Ie.hls)))return;v.videoRef.current&&!isNaN(v.videoRef.current.currentTime)&&(Rt.current=v.videoRef.current.currentTime);const We=(s?u.links.filter(Ie=>Ie.hls):u.links||[]).sort((Ie,St)=>(parseInt(St.resolutionStr)||0)-(parseInt(Ie.resolutionStr)||0))[0]||null;x(u.sourceName),g({type:"SET_STATE",payload:{selectedSource:u,selectedLink:We,showResumeModal:e.showResumeModal&&u.type!=="iframe"}})},onLinkChange:u=>{e.selectedSource&&(x(e.selectedSource.sourceName),g({type:"SET_STATE",payload:{selectedLink:u}}))}})]}),t("div",{className:Ce.playerInfoContainer,children:[t("div",{className:Ce.playerInfoHeader,children:[t("div",{className:Ce.playerAnimeCard,children:t(Mr,{src:Rr(e.showMeta.thumbnail||""),alt:$e,loading:"lazy",decoding:"async",onError:u=>{u.target.src="/placeholder.svg"}})}),t("div",{className:Ce.videoTitleSection,children:[t("div",{className:S.titleContainer,children:[t("h1",{children:$e}),t("div",{className:S.scheduleInfo,children:[e.showMeta.status&&t("span",{className:S.status,children:e.showMeta.status}),e.showMeta.nextEpisodeAirDate&&t("span",{className:S.nextEpisode,children:["Next episode: ",e.showMeta.nextEpisodeAirDate]})]})]}),t("div",{className:S.controls,children:[t("button",{className:`${S.watchlistBtn} ${e.inWatchlist?S.inList:""}`,onClick:T,children:[e.inWatchlist?t(ge,{name:"check",size:14}):t(ge,{name:"plus",size:14}),e.inWatchlist?"In Watchlist":"Add to Watchlist"]}),t(dn,{showId:r,showName:e.showMeta.name||e.showMeta.names?.romaji,showThumbnail:e.showMeta.thumbnail,nativeName:e.showMeta.names?.native,englishName:e.showMeta.names?.english,showType:e.showMeta.type,className:`${S.watchlistBtn} ${S.queueBtn}`,activeClassName:S.queueActive}),ar&&t("button",{className:`${S.watchlistBtn} ${S.markWatchedBtn} ${At?S.markWatchedDone:""}`,onClick:ir,disabled:D||!e.currentEpisode,children:[t(ge,{name:"check",size:14}),D?"Saving...":At?"Watched":"Mark Watched"]}),t("button",{className:`${S.watchlistBtn} ${S.modeToggleBtn} ${e.currentMode==="dub"?S.modeToggleActive:""}`,disabled:n,onClick:()=>{const u=e.currentMode==="dub"?"sub":"dub";Mt(),g({type:"SET_MODE",payload:u}),Y.setItem("preferredMode",u)},type:"button","aria-pressed":e.currentMode==="dub",children:e.currentMode==="dub"?"DUB":"SUB"}),Nt&&t("button",{disabled:n,className:`${S.watchlistBtn} ${S.modeToggleBtn} ${h.state.useNativeControls?S.modeToggleActive:""}`,onClick:()=>{const u=!h.state.useNativeControls;h.actions.setUseNativeControls(u),Y.setItem("playerUseNativeControls",u.toString())},type:"button",children:h.state.useNativeControls?"NATIVE: ON":"NATIVE: OFF"})]})]})]}),_t(`${S.episodeActions} ${S.mobileEpisodeActions}`,"mobile"),t("div",{className:Ce.infoColumns,children:[t("div",{className:`${S.descriptionSection} ${S.synopsisFlat}`,children:[t("h3",{children:"Synopsis"}),t(pn,{text:e.showMeta.description?e.showMeta.description.replace(/<[^>]*>?/gm,""):"",emptyText:"No description available."}),t("button",{className:S.detailsToggleBtn,onClick:y,children:[e.showCombinedDetails?t(ge,{name:"chevron-up"}):t(ge,{name:"chevron-down"}),e.showCombinedDetails?"Hide Details":"Show Details"]})]}),e.showCombinedDetails&&t(mn,{showMeta:e.showMeta,styles:S})]})]})]})]}),t(nn,{isOpen:ot,onClose:()=>He(!1),episodes:e.episodes,currentEpisode:e.currentEpisode??void 0,watchedEpisodes:e.watchedEpisodes,onEpisodeClick:u=>{He(!1),d(`/watch/${r}/${u}`)}})]})};export{Ks as default};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import{d as s,u as e,S as ge,A as Z,h as M,q as me,T as Me,p as qe,g as we,_ as ze}from"./vendor-core-DfaOB3Rn.js";import{b as pe,u as te}from"./vendor-query-BBT5_sHx.js";import{R as ee,S as J,U,V as be,B as S,W as Ke,Q as E,d as Ue,L as _e,t as b,v as Te,o as Ee,J as Ce,X,q as H,Y as ke,Z as Fe,_ as $e,u as He,e as We,$ as Be,K as le,p as je,a0 as Qe,a1 as Ve}from"./index-D1FwY1a_.js";import{I as B}from"./vendor-icons-DrybRNxP.js";import{T as $}from"./ToggleSwitch-CN_ppEc9.js";import{M as Ye}from"./MatureConsentModal-CkodsDv3.js";const Je="_sectionCard_1vuib_1",Xe="_dangerCard_1vuib_20",Ze="_settingRow_1vuib_31",T={sectionCard:Je,dangerCard:Xe,settingRow:Ze};function et(){const{data:t}=pe(ee),{data:i}=pe({queryKey:["profiles"],queryFn:()=>J("/api/profiles/status"),enabled:!!t?.owner}),l=te(),[g,f]=s(null),[d,C]=s(""),[m,o]=s(""),[a,p]=s(""),[y,u]=s(""),[L,c]=s(""),[v,_]=s(!1),[I,O]=s(null),P=async n=>{_(!0),c("");try{await J("/api/profiles/update",{method:"POST",body:JSON.stringify(n)}),await l.invalidateQueries({queryKey:ee.queryKey}),C(""),o(""),c("Profile saved")}catch(N){c(N.message)}finally{_(!1)}};return t?e("section",{className:T.sectionCard,children:[e("h3",{children:"Your profile"}),e("p",{children:"Keep using this profile, rename it, or add another person with their own library and connections."}),e("div",{className:U.avatarRow,children:[e(be,{image:t.image,name:t.name}),e("label",{className:U.uploadButton,children:[e(B,{name:"upload"}),e("span",{children:"Upload image"}),e("input",{className:U.fileInput,type:"file",accept:"image/png,image/jpeg,image/webp,image/gif",disabled:v,onChange:async n=>{const N=n.currentTarget.files?.[0];if(n.currentTarget.value="",!N)return;if(N.size>2*1024*1024){c("Image must be smaller than 2 MB");return}const R=new FileReader;R.onerror=()=>c("Could not read image"),R.onload=()=>{P({avatar:R.result})},R.readAsDataURL(N)}})]}),t.avatar&&e(S,{variant:"secondary",disabled:v,onClick:()=>P({avatar:null}),children:"Clear uploaded image"})]}),e("p",{children:"Your uploaded image takes priority, followed by your active cloud account image, then the default user icon."}),e("form",{className:U.form,onSubmit:n=>{n.preventDefault(),P({name:g??t.name})},children:[e("label",{className:U.field,children:["Profile name",e("input",{value:g??t.name,maxLength:60,required:!0,onChange:n=>f(n.currentTarget.value)})]}),e(S,{type:"submit",disabled:v,children:"Save name"})]}),e("form",{className:U.form,onSubmit:n=>{n.preventDefault(),P({password:d,currentPassword:m})},children:[t.protected&&e("label",{className:U.field,children:["Current password",e("input",{type:"password",autoComplete:"current-password",value:m,required:!0,maxLength:256,onChange:n=>o(n.currentTarget.value)})]}),e("label",{className:U.field,children:[t.protected?"New password (empty removes protection)":"Protect this profile",e("input",{type:"password",autoComplete:"new-password",value:d,minLength:8,maxLength:256,onChange:n=>C(n.currentTarget.value)})]}),e(S,{type:"submit",disabled:v,children:"Save password"})]}),e(S,{variant:"secondary",disabled:v,onClick:async()=>{_(!0);try{await J("/api/profiles/logout",{method:"POST"}),Ke()}catch(n){c(n.message),_(!1)}},children:"Switch profile / sign out"}),t.owner&&e("form",{className:U.form,onSubmit:async n=>{n.preventDefault(),_(!0),c("");try{await J("/api/profiles/create",{method:"POST",body:JSON.stringify({name:a,password:y})}),p(""),u(""),await l.invalidateQueries({queryKey:["profiles"]}),c("Profile created. Sign out to switch to it.")}catch(N){c(N.message)}finally{_(!1)}},children:[e("h3",{children:"Add another profile"}),e("p",{children:"Protect your owner profile first. New profiles start empty and do not inherit your accounts. A profile without a password is accessible to anyone who passes the LAN lock."}),e("label",{className:U.field,children:["Name",e("input",{required:!0,maxLength:60,value:a,onChange:n=>p(n.currentTarget.value)})]}),e("label",{className:U.field,children:["Password (optional)",e("input",{type:"password",autoComplete:"new-password",minLength:8,maxLength:256,value:y,onChange:n=>u(n.currentTarget.value)})]}),e(S,{type:"submit",disabled:v||!t.protected,children:"Create profile"})]}),t.owner&&i?.profiles.some(n=>!n.owner)&&e(ge,{children:[e("h3",{children:"Other profiles"}),e("ul",{className:U.profileList,children:i.profiles.filter(n=>!n.owner).map(n=>e("li",{children:[e("span",{className:U.smallAvatar,children:e(be,{image:n.avatar??n.cloudAvatar,name:n.name})}),e("span",{className:U.profileName,children:n.name}),e(S,{variant:"danger",size:"sm",disabled:v,onClick:()=>{c(""),O(n)},children:"Delete"})]},n.id))})]}),e(E,{isOpen:!!I,onClose:v?void 0:()=>O(null),title:"Delete profile?",width:"sm",footer:e(ge,{children:[e(S,{variant:"secondary",disabled:v,onClick:()=>O(null),children:"Cancel"}),e(S,{variant:"danger",loading:v,onClick:async()=>{if(I){_(!0);try{await J("/api/profiles/delete",{method:"POST",body:JSON.stringify({id:I.id,confirm:!0})}),await l.invalidateQueries({queryKey:["profiles"]}),O(null),c("Profile deleted. Local files will be removed when Dango restarts.")}catch(n){c(n.message),O(null)}finally{_(!1)}}},children:"Delete profile"})]}),children:[e("p",{children:["Delete ",e("strong",{children:I?.name}),"? This signs them out immediately. Their local libraries, settings and connections will be removed when Dango next restarts."]}),e("p",{children:"Cloud backups and tracker lists will stay intact. Export any library you want to keep before deleting."})]}),L&&e("p",{role:"status",children:L})]}):null}const ce={"title-preference-container":"_title-preference-container_sdqgs_1","toggle-button":"_toggle-button_sdqgs_21","toggle-label":"_toggle-label_sdqgs_51"},de=["name","nativeName","englishName"],ue={name:"Default (Romaji)",nativeName:"Native",englishName:"English"},tt=()=>{const{titlePreference:t,setTitlePreference:i,loading:l}=Ue(),g=_e(),[f,d]=s(ue[t]),[C,m]=s(!1),o=Z(null);M(()=>{l||d(ue[t])},[t,l]);const a=async()=>{if(C)return;m(!0);const y=(de.indexOf(t)+1)%de.length,u=de[y],L=ue[u];o.current&&(o.current.style.transform="translateX(-100%)",o.current.style.opacity="0"),setTimeout(async()=>{d(L),i(u),o.current&&(o.current.style.transition="none",o.current.style.transform="translateX(100%)",o.current.style.opacity="0",o.current.offsetWidth,o.current.style.transition="transform 0.3s ease-out, opacity 0.3s ease-out",o.current.style.transform="translateX(0)",o.current.style.opacity="1");try{await g.mutateAsync({key:"titlePreference",value:u})}catch(c){console.error("Error saving title preference:",c)}finally{m(!1)}},300)};return l?e("p",{children:"Loading title preference..."}):e("div",{className:ce["title-preference-container"],children:[e("h4",{children:"Anime Title Display Preference"}),e("button",{onClick:a,className:ce["toggle-button"],disabled:C,children:e("span",{ref:o,className:ce["toggle-label"],children:f})})]})},at="_settingsHeader_gfwoa_1",nt="_pageTitle_gfwoa_6",rt="_pageSubtitle_gfwoa_14",st="_settingsLayout_gfwoa_20",it="_sidebar_gfwoa_27",ot="_sidebarIndicator_gfwoa_35",lt="_sidebarItem_gfwoa_50",ct="_active_gfwoa_72",dt="_mainContent_gfwoa_80",ut="_tabContent_gfwoa_85",ht="_settingItem_gfwoa_103",gt="_shortcutContainer_gfwoa_108",mt="_shortcutGroup_gfwoa_115",pt="_shortcutGroupTitle_gfwoa_121",ft="_shortcutGrid_gfwoa_130",yt="_shortcutCard_gfwoa_136",vt="_controls_gfwoa_170",wt="_status_gfwoa_176",h={settingsHeader:at,pageTitle:nt,pageSubtitle:rt,settingsLayout:st,sidebar:it,sidebarIndicator:ot,sidebarItem:lt,active:ct,mainContent:dt,tabContent:ut,settingItem:ht,shortcutContainer:gt,shortcutGroup:mt,shortcutGroupTitle:pt,shortcutGrid:ft,shortcutCard:yt,controls:vt,status:wt},bt="_title_tm30b_11",Ct="_signIn_tm30b_18",kt="_userInfo_tm30b_25",St="_warning_tm30b_47",Nt="_formGroup_tm30b_54",_t="_label_tm30b_58",Tt="_inputWrapper_tm30b_68",It="_input_tm30b_68",Lt="_select_tm30b_92",Pt="_actions_tm30b_109",xt="_hr_tm30b_117",w={title:bt,signIn:Ct,userInfo:kt,warning:St,formGroup:Nt,label:_t,inputWrapper:Tt,input:It,select:Lt,actions:Pt,hr:xt},Rt=()=>{const t=te(),[i,l]=s(!0),[g,f]=s(!1),[d,C]=s(!1),[m,o]=s(null),[a,p]=s({status:"idle"}),[y,u]=s(!1),[L,c]=s(""),[v,_]=s(!1),I=Z(null),[O,P]=s({show:!1,message:"",type:"info"}),n=()=>{I.current&&(window.clearInterval(I.current),I.current=null)},N=me(k=>{C(k.authenticated),o(k.user||k.device.user||null),p(k.device),u(!!k.hasCustomClientId)},[]),R=me(async()=>{const k=await b.auth.githubStatus.query();N(k)},[N]),z=async()=>{try{const k=await b.auth.githubPoll.query();p(k),k.status==="success"?(n(),await t.invalidateQueries({queryKey:ee.queryKey}),await R(),P({show:!0,message:"GitHub authentication complete. Sync has been initialized.",type:"success"})):k.status==="error"&&(n(),P({show:!0,message:k.error||"GitHub authentication failed.",type:"error"}))}catch{n(),P({show:!0,message:"Failed to poll GitHub authentication status.",type:"error"})}},x=(k=5)=>{n(),I.current=window.setInterval(z,Math.max(k,5)*1e3)};M(()=>(R().catch(()=>{P({show:!0,message:"Failed to load GitHub sync status.",type:"error"})}).finally(()=>l(!1)),n),[R]);const A=async()=>{f(!0);try{const k=await b.auth.githubStart.mutate();p(k),x(k.verification?.interval)}catch(k){P({show:!0,message:k instanceof Error?k.message:"Failed to start GitHub authentication.",type:"error"})}finally{f(!1)}},q=async()=>{try{await b.auth.githubLogout.mutate(),await t.invalidateQueries({queryKey:ee.queryKey}),C(!1),o(null),p({status:"idle"}),P({show:!0,message:"Signed out of GitHub sync.",type:"success"})}catch{P({show:!0,message:"Failed to sign out of GitHub.",type:"error"})}},j=async()=>{_(!0);try{await b.auth.saveGithubAuth.mutate({clientId:L}),c(""),await R(),P({show:!0,message:"Custom GitHub auth saved.",type:"success"})}catch{P({show:!0,message:"Failed to save override.",type:"error"})}finally{_(!1)}},Q=async()=>{_(!0);try{await b.auth.saveGithubAuth.mutate({clientId:""}),c(""),await R(),P({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{P({show:!0,message:"Failed to clear override.",type:"error"})}finally{_(!1)}};return i?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:T.sectionCard,children:[e("h3",{className:w.title,children:"GitHub Cloud Sync"}),e("p",{className:w.signIn,children:"Sync local data through a private GitHub repository named dango-sync-data."}),d&&m?e("div",{className:w.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:m.name||m.login})]}),e(S,{variant:"danger",onClick:q,children:"Sign Out"})]}):e("div",{className:w.signIn,children:e(S,{onClick:A,disabled:g||a.status==="pending",children:g||a.status==="pending"?"Waiting for GitHub...":"Sign in with GitHub"})}),a.status==="pending"&&a.verification&&e(ge,{children:[e("hr",{className:w.hr}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Verification URL"}),e("div",{className:w.inputWrapper,children:[e("input",{className:w.input,value:a.verification.verification_uri,readOnly:!0}),e(S,{onClick:()=>{const k=a.verification?.verification_uri;k&&/^https?:\/\//i.test(k)&&window.open(k,"_blank","noopener,noreferrer")},children:"Open"})]})]}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Device Code"}),e("input",{className:w.input,value:a.verification.user_code,readOnly:!0})]})]}),a.status==="error"&&e("p",{className:w.warning,children:a.error}),e("details",{style:{marginTop:"1rem",fontSize:"var(--font-size-sm)"},children:[e("summary",{style:{cursor:"pointer",color:"var(--text-secondary)"},children:["Advanced: use your own auth ",y?"(override active)":""]}),e("div",{className:w.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:w.label,children:"Client ID (optional)"}),e("input",{className:w.input,value:L,onChange:k=>c(k.currentTarget.value),placeholder:"Your GitHub OAuth app ID"})]}),e("div",{className:w.actions,children:[e(S,{onClick:j,disabled:v,children:"Save override"}),e(S,{variant:"secondary",onClick:Q,disabled:v,children:"Use dango defaults"})]})]}),e(E,{isOpen:O.show,onClose:()=>P(k=>({...k,show:!1})),width:"sm",children:[e(E.Body,{children:e("p",{children:O.message})}),e(E.Actions,{children:e(S,{onClick:()=>P(k=>({...k,show:!1})),children:"OK"})})]})]})},Dt=()=>{const[t,i]=s(!0),[l,g]=s(null),[f,d]=s(!1),[C,m]=s(!1),[o,a]=s(""),[p,y]=s(""),[u,L]=s(""),[c,v]=s(!1),[_,I]=s({show:!1,message:"",type:"info"}),O=async()=>{try{const A=await b.auth.user.query();g(A?.email?A:null)}catch{g(null)}},P=async()=>{try{const[x,A]=await Promise.all([b.auth.configStatus.query(),b.auth.googleAuth.query()]);d(!!x.hasConfig),m(!!(A.hasCustomWorkerUrl||A.hasCustomClientId||A.hasClientSecret))}catch(x){console.error("Failed to fetch config status",x)}};M(()=>{(async()=>{i(!0),await Promise.all([O(),P()]);try{new URLSearchParams(window.location.search).get("google_auth")==="success"&&(await O(),window.history.replaceState(null,"",window.location.pathname))}catch{}i(!1)})();const A=q=>{q.origin===window.location.origin&&typeof q.data=="object"&&q.data!==null&&q.data.type==="GOOGLE_AUTH_SUCCESS"&&(g(q.data.user),window.location.reload())};return window.addEventListener("message",A),()=>window.removeEventListener("message",A)},[]);const n=async()=>{try{const x=await b.auth.googleLogin.mutate();if(x.authenticated){window.location.reload();return}if(x.url){if(typeof window.DangoBridge<"u"){window.location.href=x.url;return}const q=600,j=700,Q=window.innerWidth/2-q/2,k=window.innerHeight/2-j/2;window.open(x.url,"GoogleAuth",`width=${q},height=${j},top=${k},left=${Q}`)}else throw new Error("Auth URL not available")}catch{I({show:!0,message:"Authentication failed. Ensure server is configured correctly.",type:"error"})}},N=async()=>{try{await b.auth.logout.mutate(),g(null),I({show:!0,message:"Successfully signed out.",type:"success"}),window.location.reload()}catch(x){console.error("Sign out failed",x),I({show:!0,message:"Failed to sign out.",type:"error"})}},R=async()=>{v(!0);try{await b.auth.saveGoogleAuth.mutate({workerUrl:o,clientId:p,clientSecret:u}),a(""),y(""),L(""),await P(),I({show:!0,message:"Custom auth saved. Restart may be required.",type:"success"})}catch{I({show:!0,message:"Failed to save override.",type:"error"})}finally{v(!1)}},z=async()=>{v(!0);try{await b.auth.saveGoogleAuth.mutate({workerUrl:"",clientId:"",clientSecret:""}),a(""),y(""),L(""),await P(),I({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{I({show:!0,message:"Failed to clear override.",type:"error"})}finally{v(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:T.sectionCard,children:[e("h3",{className:w.title,children:"Google Drive Sync"}),l?e("div",{className:w.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:l.name})," (",l.email,")"]}),e(S,{variant:"danger",onClick:N,children:"Sign Out"})]}):e("div",{className:w.signIn,children:[e("p",{children:"Sign in with your Google account to enable synchronization features."}),e(S,{onClick:n,disabled:!f,children:"Sign in with Google"}),!f&&e("p",{className:w.warning,children:"Google sync is not configured on the server."})]}),e("details",{style:{marginTop:"1rem",fontSize:"var(--font-size-sm)"},children:[e("summary",{style:{cursor:"pointer",color:"var(--text-secondary)"},children:["Advanced: use your own auth ",C?"(override active)":""]}),e("div",{className:w.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:w.label,children:"Worker URL (optional)"}),e("input",{className:w.input,value:o,onChange:x=>a(x.currentTarget.value),placeholder:"https://your-worker.workers.dev"})]}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Client ID (optional)"}),e("input",{className:w.input,value:p,onChange:x=>y(x.currentTarget.value),placeholder:"Your Google OAuth client ID"})]}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Client Secret (optional)"}),e("input",{type:"password",className:w.input,value:u,onChange:x=>L(x.currentTarget.value),placeholder:"Your Google OAuth secret"})]}),e("div",{className:w.actions,children:[e(S,{onClick:R,disabled:c,children:"Save override"}),e(S,{variant:"secondary",onClick:z,disabled:c,children:"Use dango defaults"})]})]}),e(E,{isOpen:_.show,onClose:()=>I(x=>({...x,show:!1})),width:"sm",children:[e(E.Body,{children:e("p",{children:_.message})}),e(E.Actions,{children:e(S,{onClick:()=>I(x=>({...x,show:!1})),children:"OK"})})]})]})},At="_settingItem_3qq0n_1",Ot="_modalOverlay_3qq0n_6",Gt="_modal_3qq0n_6",Mt="_modalActions_3qq0n_41",qt="_modalSecondary_3qq0n_47",zt="_modalPrimary_3qq0n_57",W={settingItem:At,modalOverlay:Ot,modal:Gt,modalActions:Mt,modalSecondary:qt,modalPrimary:zt},Kt={anime:{heading:"Watchlist Preferences",blurb:"Customize your experience when managing your watchlist and series entries.",skipKey:"skipRemoveConfirmation",ignoreKey:"ignoreAdultContent",listOnlyKey:"cwWatchlistOnly",skipLabel:"Skip confirmation when removing from watchlist",ignoreLabel:"Hide adult content from continue watching",listOnlyLabel:"Only show continue watching for shows in watchlist",listNoun:"watchlist",continueNoun:"continue watching",adultCountUrl:"/api/continue-watching/adult-count",purgeUrl:"/api/continue-watching/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue watching`,invalidateKeys:[["allContinueWatching"]]},manga:{heading:"Reading List Preferences",blurb:"Customize your experience when managing your reading list and manga entries.",skipKey:"mangaSkipRemoveConfirmation",ignoreKey:"mangaIgnoreAdultContent",listOnlyKey:"mangaCwWatchlistOnly",skipLabel:"Skip confirmation when removing from reading list",ignoreLabel:"Hide adult content from continue reading",listOnlyLabel:"Only show continue reading for manga in reading list",listNoun:"reading list",continueNoun:"continue reading",adultCountUrl:"/api/manga/continue-reading/adult-count",purgeUrl:"/api/manga/continue-reading/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue reading`,invalidateKeys:[["manga-continue-reading"]]},tv:{heading:"TV Watchlist Preferences",blurb:"Customize your experience when managing your TV watchlist and series entries.",skipKey:"tvSkipRemoveConfirmation",ignoreKey:"tvIgnoreAdultContent",listOnlyKey:"tvCwWatchlistOnly",skipLabel:"Skip confirmation when removing from TV watchlist",ignoreLabel:"Hide adult content from continue watching",listOnlyLabel:"Only show continue watching for shows in TV watchlist",listNoun:"TV watchlist",continueNoun:"continue watching",adultCountUrl:"/api/tv/continue-watching/adult-count",purgeUrl:"/api/tv/continue-watching/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue watching`,invalidateKeys:[["tv-continue-watching"]]},asmr:{heading:"Listening List Preferences",blurb:"Customize your experience when managing your listening list and work entries.",skipKey:"asmrSkipRemoveConfirmation",ignoreKey:"asmrIgnoreAdultContent",listOnlyKey:"asmrCwWatchlistOnly",skipLabel:"Skip confirmation when removing from listening list",ignoreLabel:"Hide adult content from continue listening",listOnlyLabel:"Only show continue listening for works in listening list",listNoun:"listening list",continueNoun:"continue listening",adultCountUrl:"/api/asmr/continue-listening/adult-count",purgeUrl:"/api/asmr/continue-listening/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue listening`,invalidateKeys:[["asmr-continue-listening"]]}},Ut=(t,i)=>{if(t==null)return i;const l=String(t);return l==="true"||l==="1"?!0:l==="false"||l==="0"?!1:i},Se=(t,i,l)=>{const[g,f]=s(i),[d,C]=s(!1),m=te();return M(()=>{(async()=>{try{const p=await b.settings.getByKey.query({key:t});f(Ut(p.value,i))}catch(p){console.error("Failed to fetch setting",p)}})()},[t,i]),{value:g,setValue:f,isUpdating:d,toggle:async()=>{if(d)return;C(!0);const a=!g;f(a);try{await b.settings.set.mutate({key:t,value:a});for(const p of l)m.invalidateQueries({queryKey:p})}catch(p){console.error("Error saving setting:",p),f(!a)}finally{C(!1)}}}},Et=()=>{const{contentType:t}=Te(),i=Kt[t],[l,g]=s(!1),[f,d]=s(!0),[C,m]=s(!1),o=Se(i.ignoreKey,!0,i.invalidateKeys),a=Se(i.listOnlyKey,!1,i.invalidateKeys),[p,y]=s(null),[u,L]=s(!1),c=te(),v=Ee();M(()=>{d(!0),(async()=>{try{const N=await b.settings.getByKey.query({key:i.skipKey});String(N.value)==="true"||String(N.value)==="1"?g(!0):g(!1)}catch(N){console.error("Failed to fetch setting",N)}finally{d(!1)}})()},[i.skipKey]);const _=async()=>{if(C)return;m(!0);const n=!l;g(n);try{await b.settings.set.mutate({key:i.skipKey,value:n})}catch(N){console.error("Error saving setting:",N),g(!n)}finally{m(!1)}},I=async()=>{if(!o.isUpdating){if(o.value)try{let n;if(t==="anime"?n=(await b.continueWatching.adultCount.query()).count:t==="manga"?n=(await b.mangaProgress.adultCount.query()).count:t==="asmr"?n=(await b.asmrProgress.adultCount.query()).count:n=(await b.tvProgress.adultCount.query()).count,typeof n=="number"&&n>0){y(n);return}}catch(n){console.error("Failed to fetch adult count",n)}o.toggle()}},O=()=>{y(null),o.toggle()},P=async()=>{if(!u){L(!0);try{let n;t==="anime"?n=(await b.continueWatching.purgeAdult.mutate()).removed:t==="manga"?n=(await b.mangaProgress.purgeAdult.mutate()).removed:t==="asmr"?n=(await b.asmrProgress.purgeAdult.mutate()).removed:n=(await b.tvProgress.purgeAdult.mutate()).removed,Ce.success(i.purgeDoneText(n??0));for(const N of i.invalidateKeys)c.invalidateQueries({queryKey:N});t==="anime"&&c.invalidateQueries(v.continueWatching.pathFilter()),t==="manga"&&c.invalidateQueries(v.mangaProgress.pathFilter()),t==="asmr"&&c.invalidateQueries(v.asmrProgress.pathFilter()),t==="tv"&&c.invalidateQueries(v.tvProgress.pathFilter())}catch(n){console.error("Failed to purge adult entries",n),Ce.error("Failed to remove adult entries")}finally{L(!1),y(null)}o.toggle()}};return f?e("div",{children:"Loading settings..."}):e("div",{className:T.sectionCard,children:[e("h3",{children:i.heading}),e("p",{children:i.blurb}),e("div",{className:W.settingItem,children:e("div",{className:T.settingRow,children:[e("label",{htmlFor:"skip-confirmation-toggle",children:i.skipLabel}),e($,{isChecked:l,onChange:_,id:"skip-confirmation-toggle",disabled:C})]})}),e("div",{className:W.settingItem,children:e("div",{className:T.settingRow,children:[e("label",{htmlFor:"ignore-adult-toggle",children:i.ignoreLabel}),e($,{isChecked:o.value,onChange:I,id:"ignore-adult-toggle",disabled:o.isUpdating})]})}),e("div",{className:W.settingItem,children:e("div",{className:T.settingRow,children:[e("label",{htmlFor:"cw-watchlist-only-toggle",children:i.listOnlyLabel}),e($,{isChecked:a.value,onChange:a.toggle,id:"cw-watchlist-only-toggle",disabled:a.isUpdating})]})}),p!==null&&e("div",{className:W.modalOverlay,onClick:()=>y(null),children:e("div",{className:W.modal,onClick:n=>n.stopPropagation(),children:[e("h4",{children:"Show adult entries?"}),e("p",{children:[p," adult ",p===1?"entry":"entries"," not in your"," ",i.listNoun," ",p===1?"is":"are"," currently hidden from"," ",i.continueNoun,". You can purge ",p===1?"it":"them"," from the database instead of showing ",p===1?"it":"them","."]}),e("div",{className:W.modalActions,children:[e("button",{type:"button",className:W.modalSecondary,onClick:O,disabled:u,children:"Show them"}),e("button",{type:"button",className:W.modalPrimary,onClick:P,disabled:u,children:u?"Purging...":`Purge ${p}`})]})]})})]})},Ft="_statsGrid_o4nf0_1",$t="_statCard_o4nf0_8",Ht="_statLabel_o4nf0_18",Wt="_statValue_o4nf0_26",Bt="_statMeta_o4nf0_32",jt="_statusBanner_o4nf0_38",Qt="_statusSuccess_o4nf0_49",Vt="_statusUpdating_o4nf0_55",Yt="_statusError_o4nf0_61",Jt="_sha_o4nf0_67",Xt="_settingItem_o4nf0_74",Zt="_settingTitle_o4nf0_79",ea="_settingSubtitle_o4nf0_85",ta="_actionsRow_o4nf0_92",D={statsGrid:Ft,statCard:$t,statLabel:Ht,statValue:Wt,statMeta:Bt,statusBanner:jt,statusSuccess:Qt,statusUpdating:Vt,statusError:Yt,sha:Jt,settingItem:Xt,settingTitle:Zt,settingSubtitle:ea,actionsRow:ta},aa=()=>{const[t,i]=s(null),[l,g]=s(!0),[f,d]=s(!1),[C,m]=s(!1),o=Z(null),a=async()=>{try{const c=await b.settings.offlineDbInfo.query();return i(c),c}catch(c){console.error("Failed to fetch offline DB info:",c)}finally{g(!1)}return null};M(()=>(a(),()=>{o.current&&window.clearInterval(o.current)}),[]),M(()=>{t?.isRefreshing?o.current||(o.current=window.setInterval(async()=>{const c=await a();c&&!c.isRefreshing&&o.current&&(window.clearInterval(o.current),o.current=null)},2e3)):o.current&&(window.clearInterval(o.current),o.current=null)},[t?.isRefreshing]);const p=async()=>{if(!t||f)return;const c=!t.autoUpdateEnabled;d(!0),i({...t,autoUpdateEnabled:c});try{await b.settings.setOfflineDbAutoUpdate.mutate({enabled:c})}catch(v){console.error("Failed to update auto update setting:",v),i({...t,autoUpdateEnabled:!c})}finally{d(!1)}},y=async()=>{if(!(t?.isRefreshing||C)){m(!0);try{await b.settings.triggerOfflineDbUpdate.mutate(),i(c=>c?{...c,isRefreshing:!0,lastStatus:"updating",lastMessage:"Downloading database..."}:null)}catch(c){console.error("Failed to trigger offline DB update:",c)}finally{m(!1)}}},u=c=>{if(!c)return"Never";try{return new Date(c).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"})}catch{return c}},L=t?.isRefreshing||C;return e("div",{className:T.sectionCard,children:[e("h3",{children:"Offline Metadata Database"}),e("p",{children:"Local MAL to AniList ID map used for instant imports and metadata enrichment without hitting rate-limited APIs. Updates automatically every Saturday in the background."}),e("div",{className:D.statsGrid,children:[e("div",{className:D.statCard,children:[e("span",{className:D.statLabel,children:"MAL Mapped"}),e("span",{className:D.statValue,children:l?"-":(t?.totalMalMapped??0).toLocaleString()})]}),e("div",{className:D.statCard,children:[e("span",{className:D.statLabel,children:"Release"}),e("span",{className:D.statMeta,children:l?"-":t?.releaseTag??"Never"})]}),e("div",{className:D.statCard,children:[e("span",{className:D.statLabel,children:"Last Checked"}),e("span",{className:D.statMeta,children:l?"-":u(t?.lastCheckedAt??null)})]}),e("div",{className:D.statCard,children:[e("span",{className:D.statLabel,children:"Last Updated"}),e("span",{className:D.statMeta,children:l?"-":u(t?.lastUpdatedAt??null)})]})]}),t?.lastMessage&&e("div",{className:`${D.statusBanner} ${t.lastStatus==="failed"?D.statusError:t.lastStatus==="updating"?D.statusUpdating:D.statusSuccess}`,children:[e("span",{children:t.lastMessage}),t.contentSha256&&e("span",{className:D.sha,children:["sha:",t.contentSha256.slice(0,12)]})]}),e("div",{className:D.settingItem,children:e("div",{className:T.settingRow,children:[e("div",{children:[e("span",{className:D.settingTitle,children:"Weekly Automatic Updates (Saturdays)"}),e("div",{className:D.settingSubtitle,children:"Download and index new database releases in the background. Catches up on startup if the server was offline."})]}),e($,{id:"offline-db-auto-update-toggle",isChecked:t?t.autoUpdateEnabled:!0,onChange:p,disabled:l||f})]})}),e("div",{className:D.actionsRow,children:e(S,{onClick:y,disabled:l||L,children:L?"Updating Database...":"Update Offline Database Now"})})]})},na="_status_1wbo0_1",ra="_warningText_1wbo0_7",sa="_ackLabel_1wbo0_11",he={status:na,warningText:ra,ackLabel:sa},ia=()=>{const t=te(),[i,l]=s(!1),[g,f]=s(!1),[d,C]=s(!1),[m,o]=s(""),a=()=>{f(!1),o(""),l(!0)},p=()=>{d||(l(!1),f(!1))},y=async()=>{if(!(!g||d)){C(!0),o("");try{const u=await X("/api/database/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({confirm:!0})}),L=await u.json();if(!u.ok)throw new Error(L.error||"Failed to clear database");const c=L.deleted,v=L.deletedManga,_=L.deletedTv,I=L.deletedAsmr,O=Object.values(c).reduce((R,z)=>R+(z||0),0)+Object.values(v??{}).reduce((R,z)=>R+(z||0),0)+Object.values(_??{}).reduce((R,z)=>R+(z||0),0)+Object.values(I??{}).reduce((R,z)=>R+(z||0),0),P=(v?.manga_library??0)+(v?.manga_progress??0),n=(_?.tv_library??0)+(_?.tv_progress??0),N=(I?.asmr_library??0)+(I?.asmr_progress??0);o(`Library cleared - ${c.watchlist??0} watchlist entries, ${P} manga rows, ${n} TV rows, ${N} ASMR rows and ${O} total rows removed.`),t.invalidateQueries({queryKey:[H.watchlist]}),t.invalidateQueries({queryKey:[H.continueWatching]}),t.invalidateQueries({queryKey:[H.mangaLibrary]}),t.invalidateQueries({queryKey:[H.mangaContinueReading]}),t.invalidateQueries({queryKey:[H.tvLibrary]}),t.invalidateQueries({queryKey:[H.tvContinueWatching]}),t.invalidateQueries({queryKey:[H.asmrLibrary]}),t.invalidateQueries({queryKey:[H.asmrContinueListening]}),l(!1)}catch(u){o(u.message)}finally{C(!1),f(!1)}}};return e("div",{className:`${T.sectionCard} ${T.dangerCard}`,children:[e("h3",{children:"Danger Zone"}),e("p",{children:"Permanently delete your library (watchlist, watched episodes, queue, cached show metadata, manga reading list and reading progress, TV watchlist and watch progress, ASMR listening list and listening progress) to start fresh. Your settings, sync state and the offline metadata cache are preserved."}),e(S,{variant:"danger",onClick:a,children:"Clear Library Data"}),m&&e("p",{className:he.status,children:m}),e(E,{isOpen:i,onClose:p,title:"Clear library data?",width:"sm",children:[e(E.Body,{children:[e("p",{className:he.warningText,children:"This permanently deletes everything in your library. It acts on the active database (dev or prod, per server config) and cannot be undone. Settings, sync state and the offline metadata cache are kept."}),e("label",{className:he.ackLabel,children:[e("input",{type:"checkbox",checked:g,onChange:u=>f(u.currentTarget.checked),disabled:d}),e("span",{children:"I understand this permanently deletes my library"})]})]}),e(E.Actions,{children:[e(S,{variant:"secondary",onClick:p,disabled:d,children:"Cancel"}),e(S,{variant:"danger",onClick:y,disabled:!g||d,children:d?"Clearing...":"Yes, delete everything"})]})]})]})},oa=()=>{const[t,i]=s(""),[l,g]=s([]),[f,d]=s(null),[C,m]=s(!0),[o,a]=s({show:!1,message:"",type:"info"}),p=async()=>{try{m(!0);const u=await b.auth.rcloneSettings.query();i(u.remote||""),g(u.availableRemotes||[]),d(u.activeRemote||null)}catch(u){console.error("Failed to fetch Rclone settings",u)}finally{m(!1)}};M(()=>{p()},[]);const y=async()=>{try{await b.auth.saveRclone.mutate({remote:t}),a({show:!0,message:"Rclone configuration saved successfully. You must restart the server for these changes to take effect.",type:"success"}),p()}catch{a({show:!0,message:"Failed to save Rclone configuration.",type:"error"})}};return C?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:T.sectionCard,children:[e("h3",{className:w.title,children:"Rclone Cloud Sync"}),e("p",{className:w.signIn,children:"Configure which Rclone remote to use for database synchronization."}),f?e("div",{className:w.userInfo,children:e("p",{children:["Current Active Remote: ",e("strong",{children:f})]})}):e("p",{className:w.warning,style:{marginBottom:"1.5rem"},children:"Rclone sync is not currently active. Ensure rclone is installed and a remote is configured."}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Remote Name"}),e("div",{className:w.inputWrapper,children:e("select",{className:w.select,value:t,onChange:u=>i(u.currentTarget.value),children:[e("option",{value:"",children:"(Disabled / None)"}),l.map(u=>e("option",{value:u,children:u},u)),t&&!l.includes(t)&&e("option",{value:t,children:[t," (Manual)"]})]})}),e("p",{className:w.warning,style:{marginTop:"12px"},children:[e("strong",{children:"Note:"})," You can choose which provider is active using the selector at the top of the page."]})]}),e("div",{className:w.actions,children:e(S,{onClick:y,children:"Save Rclone Settings"})}),e(E,{isOpen:o.show,onClose:()=>a(u=>({...u,show:!1})),width:"sm",children:[e(E.Body,{children:e("p",{children:o.message})}),e(E.Actions,{children:e(S,{onClick:()=>a(u=>({...u,show:!1})),children:"OK"})})]})]})},la=()=>{const t=te(),[i,l]=s(null),[g,f]=s(!0),d=async()=>{try{const a=await b.auth.syncSettings.query();l(a)}catch(a){console.error("Failed to fetch sync settings",a)}finally{f(!1)}};M(()=>{d()},[]);const C=async a=>{const p=a.currentTarget.value;try{const y=await b.auth.saveSyncProvider.mutate({provider:p});l(u=>u?{...u,activeProvider:y.activeProvider}:null),await d(),await t.invalidateQueries({queryKey:ee.queryKey}),ke.success(`Sync provider updated to ${p==="default"?"Default Order":p}`)}catch{ke.error("Failed to update sync provider")}};if(g||!i)return null;const m=[{value:"default",label:"Default (Priority Based)"}];i.authenticatedProviders.github&&m.push({value:"github",label:"GitHub"}),i.authenticatedProviders.google&&m.push({value:"google",label:"Google Drive"}),i.authenticatedProviders.rclone&&m.push({value:"rclone",label:"Rclone"}),m.push({value:"none",label:"None (Local Only)"});const o=a=>a==="none"?"Local Only (No Sync)":a==="google"?"Google Drive":a==="github"?"GitHub":a==="rclone"?"Rclone":a;return e("div",{className:T.sectionCard,children:[e("h3",{children:"Active Sync Provider"}),e("p",{children:'Choose which provider to use for synchronization. "Default" uses the first available provider you are logged into.'}),e("div",{style:{marginBottom:"1.5rem",padding:"0.75rem",background:"rgba(255, 255, 255, 0.03)",borderRadius:"var(--radius-md)",borderLeft:"4px solid var(--accent)",fontSize:"var(--font-size-sm)"},children:["Current Status:"," ",e("strong",{style:{color:"var(--accent-light)",textTransform:"capitalize"},children:o(i.actualActiveProvider)})]}),e("div",{className:T.settingRow,children:[e("label",{htmlFor:"sync-provider-select",children:"Selected Preference"}),e("select",{id:"sync-provider-select",value:i.activeProvider,onChange:C,style:{padding:"0.5rem",borderRadius:"var(--radius-md)",background:"rgba(255, 255, 255, 0.05)",color:"var(--text-primary)",border:"1px solid var(--glass-border)",fontSize:"var(--font-size-sm)",minWidth:"220px",outline:"none",cursor:"pointer"},children:m.map(a=>e("option",{value:a.value,children:a.label},a.value))})]})]})};function ca(){return"javascript:"+encodeURIComponent(`(function(){
|
|
2
|
-
if(!/(^|\\.)discord\\.com$/.test(location.hostname)){alert('Dango: use this bookmarklet while on discord.com');return}
|
|
3
|
-
var t=null;
|
|
4
|
-
try{
|
|
5
|
-
window.webpackChunkdiscord_app.push([[Symbol()],{},function(req){
|
|
6
|
-
if(!req.c)return;
|
|
7
|
-
var ms=Object.values(req.c);
|
|
8
|
-
for(var i=0;i<ms.length;i++){var m=ms[i];
|
|
9
|
-
try{
|
|
10
|
-
if(!m.exports||m.exports===window)continue;
|
|
11
|
-
if(typeof m.exports.getToken==='function'){var x=m.exports.getToken();if(x){t=x;return}}
|
|
12
|
-
for(var k in m.exports){try{var ex=m.exports[k];if(ex&&typeof ex.getToken==='function'&&ex[Symbol.toStringTag]!=='IntlMessagesProxy'){var y=ex.getToken();if(y){t=y;return}}}catch(e1){}}
|
|
13
|
-
}catch(e2){}}
|
|
14
|
-
}]);
|
|
15
|
-
window.webpackChunkdiscord_app.pop();
|
|
16
|
-
}catch(e3){}
|
|
17
|
-
if(!t){alert('Dango: could not grab your token. Make sure you are logged in to Discord in this tab, then run the bookmarklet again.');return}
|
|
18
|
-
function copyFallback(){var a=document.createElement('textarea');a.value=t;a.style.position='fixed';a.style.opacity='0';document.body.appendChild(a);a.select();try{document.execCommand('copy')}catch(e4){}document.body.removeChild(a)}
|
|
19
|
-
var done=function(){window.close();setTimeout(function(){if(!window.closed){alert('Dango: token copied to clipboard! Could not close this tab, so just close it, go back to Dango Settings, paste the token and press Save.')}},250)};
|
|
20
|
-
if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(t).then(done,function(){copyFallback();done()})}else{copyFallback();done()}
|
|
21
|
-
})()`)}const da=()=>{const t=Me(ca,[]);return e("div",{style:{marginTop:"0.9rem",paddingTop:"0.9rem",borderTop:"1px dashed var(--border-color)"},children:[e("h4",{style:{margin:"0 0 0.35rem",fontSize:"0.95rem"},children:"Grab the token automatically (bookmarklet)"}),e("p",{style:{margin:"0 0 0.6rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Set this up once and you never have to dig through DevTools: the bookmarklet copies your Discord token to the clipboard and closes the Discord tab - then you just paste it above and press Save."}),e("ol",{style:{margin:"0 0 0.75rem",paddingLeft:"1.25rem",fontSize:"0.85rem",color:"var(--text-secondary)",display:"grid",gap:"0.3rem"},children:[e("li",{children:["Drag the ",e("strong",{style:{color:"var(--text-primary)"},children:"Dango Token Grabber"})," ","button below onto your bookmarks bar (press ",e("kbd",{children:"Ctrl"}),"+",e("kbd",{children:"Shift"}),"+",e("kbd",{children:"B"})," ","first if the bar is hidden)."]}),e("li",{children:["Click ",e("strong",{style:{color:"var(--text-primary)"},children:"Open Discord"})," and log in (skip this if you are already logged in)."]}),e("li",{children:["On the Discord tab, click the"," ",e("strong",{style:{color:"var(--text-primary)"},children:"Dango Token Grabber"})," bookmark. The token lands in your clipboard and the tab closes on its own - come back here, paste it above and press ",e("strong",{children:"Save"}),"."]})]}),e("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center",flexWrap:"wrap"},children:[e("a",{href:t,onClick:g=>{g.preventDefault(),alert("Drag this button onto your bookmarks bar instead of clicking it, then click it while you are on discord.com.")},title:"Drag me to your bookmarks bar",draggable:!0,style:{display:"inline-flex",alignItems:"center",padding:"0.4rem 0.8rem",borderRadius:"999px",border:"1px dashed var(--accent)",background:"var(--bg-secondary)",color:"var(--text-primary)",fontSize:"0.85rem",textDecoration:"none",cursor:"grab",userSelect:"none"},children:[e(B,{name:"bookmark",style:{marginRight:"0.45rem",color:"var(--accent)"}}),"Dango Token Grabber"]}),e("a",{className:"btn btn-secondary btn-sm",href:"https://discord.com/channels/@me",target:"_blank",rel:"noopener noreferrer",children:"Open Discord"}),e(S,{variant:"ghost",size:"sm",onClick:async()=>{try{await navigator.clipboard.writeText(t),alert('Bookmarklet code copied. Create a new bookmark on your bookmarks bar, name it "Dango Token" and paste the code as its URL.')}catch{alert(`Could not copy automatically. Right-click the "Dango Token Grabber" button and choose "Copy link address" instead, then paste that into a new bookmark's URL.`)}},children:"Copy code"})]}),e("p",{style:{margin:"0.5rem 0 0",fontSize:"0.75rem",color:"var(--text-tertiary)"},children:`"Copy code" is a fallback for browsers that won't drag bookmarklets: create any bookmark, then paste the copied code as its URL.`})]})},ua="_settingItem_68mz3_1",ha="_field_68mz3_6",ga="_input_68mz3_19",ma="_actions_68mz3_39",pa="_status_68mz3_45",G={settingItem:ua,field:ha,input:ga,actions:ma,status:pa},fa=()=>{const[t,i]=s(!1),[l,g]=s(""),[f,d]=s(""),[C,m]=s(!0),[o,a]=s(!1),[p,y]=s("");M(()=>{(async()=>{try{const I=await(await X("/api/auth/app-status")).json();i(I.hasPassword)}catch{console.error("Failed to fetch LAN auth status")}finally{m(!1)}})()},[]);const u=async()=>{if(y(""),l!==f){y("Passwords do not match");return}if(l.length<4){y("Password must be at least 4 characters");return}a(!0);try{const v=await X("/api/auth/app-setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:l})}),_=await v.json();if(!v.ok){y(_.error||"Failed to update password");return}i(_.hasPassword),g(""),d(""),y(_.hasPassword?"Password set successfully":"Password removed")}catch{y("Network error")}finally{a(!1)}},L=async()=>{a(!0);try{const v=await X("/api/auth/app-setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:""})}),_=await v.json();if(!v.ok){y(_.error||"Failed to remove password");return}i(!1),g(""),d(""),y("Password removed")}catch{y("Network error")}finally{a(!1)}},c=async()=>{a(!0);try{await X("/api/auth/app-logout",{method:"POST"}),y("Logged out"),window.location.reload()}catch{y("Logout failed")}finally{a(!1)}};return C?e("div",{className:T.sectionCard,children:e("p",{children:"Loading..."})}):e("div",{className:T.sectionCard,children:[e("h3",{children:"LAN Lock"}),e("p",{children:"Require a password to access this instance from any device, including this one. Sessions persist across server restarts until logout or password change."}),e("div",{className:G.settingItem,children:[e("div",{className:G.field,children:[e("label",{htmlFor:"lan-password",children:"New Password"}),e("input",{id:"lan-password",type:"password",value:l,onChange:v=>g(v.currentTarget.value),placeholder:t?"Leave empty to keep current password":"Enter a password...",className:G.input})]}),e("div",{className:G.field,children:[e("label",{htmlFor:"lan-confirm-password",children:"Confirm Password"}),e("input",{id:"lan-confirm-password",type:"password",value:f,onChange:v=>d(v.currentTarget.value),placeholder:"Confirm password...",className:G.input})]}),e("div",{className:G.actions,children:[e(S,{variant:"primary",onClick:u,loading:o,disabled:o,children:t?"Update Password":"Set Password"}),t&&e(S,{variant:"danger",onClick:c,loading:o,disabled:o,children:"Logout"}),t&&e(S,{variant:"secondary",onClick:L,loading:o,disabled:o,children:"Remove Password"})]}),p&&e("p",{className:G.status,children:p})]})]})},ya=()=>{const[t,i]=s(""),[l,g]=s(!0),[f,d]=s(!1),[C,m]=s("");M(()=>{J("/api/auth/app-status").then(a=>i(String(a.port??3e3))).catch(()=>m("Failed to load current port")).finally(()=>g(!1))},[]);const o=async()=>{const a=Number(t);if(!Number.isInteger(a)||a<1||a>65535){m("Enter a port between 1 and 65535");return}d(!0),m("");try{await b.auth.setServerPort.mutate({port:a}),m(`Saved. Restart dango, then open http://localhost:${a} - this overrides the PORT environment variable.`)}catch(p){m(p.message)}finally{d(!1)}};return l?e("div",{className:T.sectionCard,children:e("p",{children:"Loading..."})}):e("div",{className:T.sectionCard,children:[e("h3",{children:"Server Port"}),e("p",{children:"Port the backend listens on. Takes effect after a restart. Google and AniList sign-in need the matching redirect URI registered with the provider."}),e("div",{className:G.settingItem,children:[e("div",{className:G.field,children:[e("label",{htmlFor:"server-port",children:"Port"}),e("input",{id:"server-port",type:"number",min:1,max:65535,value:t,onChange:a=>i(a.currentTarget.value),className:G.input})]}),e("div",{className:G.actions,children:e(S,{variant:"primary",onClick:o,loading:f,disabled:f,children:"Save Port"})}),C&&e("p",{className:G.status,children:C})]})]})},va=()=>{const[t,i]=s(""),[l,g]=s(!0),[f,d]=s(!1),[C,m]=s("");M(()=>{b.auth.allowedOrigins.query().then(a=>i(a.origins.join(", "))).catch(()=>m("Failed to load allowed origins")).finally(()=>g(!1))},[]);const o=async()=>{d(!0),m("");try{const a=await b.auth.setAllowedOrigins.mutate({origins:t});i(a.origins.join(", ")),m("Saved.")}catch(a){m(a.message)}finally{d(!1)}};return l?e("div",{className:T.sectionCard,children:e("p",{children:"Loading..."})}):e("div",{className:T.sectionCard,children:[e("h3",{children:"Allowed Origins"}),e("p",{children:["Extra browser origins allowed to call the API, comma-separated. Include the scheme (e.g."," ",e("code",{children:"https://example.com"}),"). Same-origin access and reverse proxies that forward X-Forwarded-Host/X-Forwarded-Proto work automatically."]}),e("div",{className:G.settingItem,children:[e("div",{className:G.field,children:[e("label",{htmlFor:"allowed-origins",children:"Origins"}),e("input",{id:"allowed-origins",value:t,onChange:a=>i(a.currentTarget.value),className:G.input,placeholder:"https://example.com"})]}),e("div",{className:G.actions,children:e(S,{variant:"primary",onClick:o,loading:f,disabled:f,children:"Save Origins"})}),C&&e("p",{className:G.status,children:C})]})]})},wa=()=>{const{theme:t,setTheme:i,loading:l}=Fe();return e("div",{children:[e("h4",{style:{margin:"0 0 0.25rem",fontSize:"1rem"},children:"Palette"}),e("p",{style:{margin:"0 0 0.75rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Taro is the default. Pick a palette that suits you."}),e("div",{role:"radiogroup","aria-label":"Palette",style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(150px, 1fr))",gap:"0.6rem"},children:$e.map(g=>{const f=t===g.id;return e("button",{role:"radio","aria-checked":f,disabled:l,onClick:()=>i(g.id),style:{display:"flex",gap:"0.6rem",alignItems:"center",textAlign:"left",padding:"0.65rem 0.75rem",borderRadius:"10px",cursor:"pointer",background:f?"var(--accent-subtle)":"var(--bg-tertiary)",border:f?"1px solid var(--accent)":"1px solid var(--border-primary)",color:"var(--text-primary)"},children:[e("span",{"aria-hidden":!0,style:{width:26,height:26,borderRadius:"50%",flex:"none",background:g.swatch,border:"1px solid rgba(0,0,0,0.35)"}}),e("span",{style:{minWidth:0},children:[e("span",{style:{display:"block",fontSize:"0.85rem",fontWeight:700},children:g.label}),e("span",{style:{display:"block",fontSize:"0.75rem",color:"var(--text-secondary)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:g.blurb})]})]},g.id)})})]})};function ba({variant:t="info",children:i,className:l=""}){return e("div",{className:`alert alert-${t} ${l}`,children:i})}const Ca={anime:"Watchlist",manga:"Reading List",tv:"TV Watchlist",asmr:"Listening List"},Ne=["general","presence","server","sync","watchlist","database"],La=()=>{const{data:t}=pe(ee),[i,l]=qe(),{contentType:g}=Te(),f=i.get("tab"),[d,C]=s(f&&Ne.includes(f)?f:"general"),[m,o]=s(""),a=Z(null),p=Z(null),y=Z(new Map),[u,L]=s({top:0,height:0,left:0,width:0}),{lowEndMode:c,setLowEndMode:v}=He(),{hasConsent:_,grant:I,revoke:O}=We(),[P,n]=s(!1),[N,R]=s(Be),[z,x]=s(!0),{data:A}=le("discordRPCEnabled"),q=_e(),[j,Q]=s(!0),{data:k}=le("dangoGaze"),[Ie,fe]=s(!0),{data:ae}=le("discordRPCHideMature"),[ye,ie]=s(""),[ne,oe]=s(null);M(()=>{t?.owner&&b.discord.gatewayStatus.query().then(r=>{oe(r),r.masked&&r.masked!=="none"&&ie(r.masked)}).catch(()=>{})},[t?.owner]),M(()=>{A!==void 0&&x(A==="true"||A===!0||A===null)},[A]),M(()=>{ae!==void 0&&fe(ae==="true"||ae===!0||ae===null)},[ae]);const Le=r=>{x(r),q.mutate({key:"discordRPCEnabled",value:String(r)})};M(()=>{k!==void 0&&Q(k!=="false"&&k!==!1)},[k]);const Pe=r=>{Q(r),q.mutate({key:"dangoGaze",value:String(r)})},xe=r=>{fe(r),q.mutate({key:"discordRPCHideMature",value:String(r)})},Re=r=>{R(r),je.setItem(Qe,String(r)),window.dispatchEvent(new CustomEvent(Ve))};we.useEffect(()=>{document.title="Settings - dango"},[]),we.useEffect(()=>{const r=i.get("tab");r&&Ne.includes(r)&&C(r)},[i]);const V=r=>{C(r),l(r==="general"?{}:{tab:r})},re=me(()=>{const r=y.current.get(d),K=p.current;if(r&&K){const Y=K.getBoundingClientRect(),F=r.getBoundingClientRect(),se=window.matchMedia("(max-width: 900px)").matches;L(se?{top:F.top-Y.top,height:F.height,left:F.left-Y.left,width:F.width}:{top:F.top-Y.top,height:F.height,left:0,width:0})}},[d]);ze(()=>{re()},[d,re]),M(()=>{const r=()=>re();window.addEventListener("resize",r);let K=!1;return document.fonts?.ready&&document.fonts.ready.then(()=>{K||re()}),()=>{K=!0,window.removeEventListener("resize",r)}},[d,re]);const De=()=>{o("Exporting databases...");const r=window.DangoBridge;if(r?.downloadFile){r.downloadFile("/api/backup-db","dango-backup.json"),setTimeout(()=>{o("Databases exported successfully!")},1500);return}const K=document.createElement("a");K.href="/api/backup-db",K.download="dango-backup.json",document.body.appendChild(K),K.click(),K.remove(),setTimeout(()=>{o("Databases exported successfully!")},1500)},Ae=async r=>{const K=r.currentTarget.files?.[0];if(!K)return;o("Importing databases...");const Y=new FormData;Y.append("dbfile",K);try{const F=await X("/api/restore-db",{method:"POST",body:Y}),se=await F.json();if(F.ok){const ve=Array.isArray(se.restored)?se.restored.join(", "):null;o(ve?`Databases imported successfully (${ve})!`:"Database imported successfully!"),setTimeout(()=>window.location.reload(),2e3)}else o(`Import failed: ${se.error}`)}catch{o("Import failed: An unexpected error occurred.")}finally{r.currentTarget.value=""}},Oe=()=>{a.current?.click()},Ge=()=>{switch(d){case"general":return e("div",{className:h.tabContent,children:[e(et,{}),e("div",{className:T.sectionCard,children:[e("h3",{children:"Appearance & Preferences"}),e("p",{children:"Configure how titles are displayed and other general preferences."}),e("div",{className:h.settingItem,children:e(tt,{})}),e("div",{className:h.settingItem,style:{marginTop:"1.5rem"},children:e(wa,{})}),e("div",{className:h.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:T.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Low End Mode"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Disables animations and heavy visual effects for better performance on older hardware."})]}),e($,{isChecked:c,onChange:r=>v(r.currentTarget.checked),id:"low-end-mode"})]})}),e("div",{className:h.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:T.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Dango Animations"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Lets the dango logo look around, blink and react when you pet it. Always off in Low End Mode."})]}),e($,{isChecked:j,onChange:r=>Pe(r.currentTarget.checked),id:"dango-gaze"})]})}),e("div",{className:h.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:T.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Virtual Keyboard"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Shows an on-screen keyboard when text search fields are focused."})]}),e($,{isChecked:N,onChange:r=>Re(r.currentTarget.checked),id:"virtual-keyboard-enabled"})]})})]}),e("section",{className:T.sectionCard,children:[e("h3",{children:"Keyboard Shortcuts"}),e("p",{children:"Use S or Ctrl+K to focus search anywhere, or use player keys while watching."}),e("div",{className:h.shortcutContainer,children:[e("div",{className:h.shortcutGroup,children:[e("h4",{className:h.shortcutGroupTitle,children:"Search"}),e("div",{className:h.shortcutGrid,children:[e("div",{className:h.shortcutCard,children:[e("kbd",{children:"S"}),e("span",{children:"Focus search"})]}),e("div",{className:h.shortcutCard,children:[e("kbd",{children:"Ctrl + K / ⌘ + K"}),e("span",{children:"Focus search"})]})]})]}),e("div",{className:h.shortcutGroup,children:[e("h4",{className:h.shortcutGroupTitle,children:"Player"}),e("div",{className:h.shortcutGrid,children:[e("div",{className:h.shortcutCard,children:[e("kbd",{children:"Space / K"}),e("span",{children:"Play / pause"})]}),e("div",{className:h.shortcutCard,children:[e("kbd",{children:"J / L · ← / →"}),e("span",{children:"Seek back / fwd"})]}),e("div",{className:h.shortcutCard,children:[e("kbd",{children:"↑ / ↓"}),e("span",{children:"Adjust volume"})]}),e("div",{className:h.shortcutCard,children:[e("kbd",{children:"M / F"}),e("span",{children:"Mute / fullscreen"})]}),e("div",{className:h.shortcutCard,children:[e("kbd",{children:"N / P"}),e("span",{children:"Next / prev episode"})]}),e("div",{className:h.shortcutCard,children:[e("kbd",{children:"T"}),e("span",{children:"Theater mode"})]})]})]})]})]})]});case"presence":return e("div",{className:h.tabContent,children:e("div",{className:T.sectionCard,children:[e("h3",{children:"Presence & Content"}),e("p",{children:"Control what Dango shares on Discord and your mature-content preference."}),t?.owner&&e("div",{className:h.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:T.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Discord Rich Presence"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Show your current anime and watch progress on your Discord profile status."})]}),e($,{isChecked:z,onChange:r=>Le(r.currentTarget.checked),id:"discord-rpc-enabled"})]})}),t?.owner&&z&&e("div",{className:h.settingItem,style:{marginTop:"1rem"},children:e("div",{className:T.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Hide Mature Content"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Hide mature content (18+) from Discord Rich Presence."})]}),e($,{isChecked:Ie,onChange:r=>xe(r.currentTarget.checked),id:"discord-hide-mature"})]})}),t?.owner&&e("div",{className:h.settingItem,style:{marginTop:"1.5rem",background:"var(--bg-tertiary)",padding:"1rem",borderRadius:"8px",border:"1px solid var(--border-color)"},children:[e("div",{className:T.settingRow,children:e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Discord Mobile Presence (Gateway)"}),e("p",{style:{margin:"0.25rem 0 0.75rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Paste your Discord authentication token to enable presence on mobile devices. If no token is saved, the default desktop Rich Presence is used. The token is stored locally in your configuration and never shared."})]})}),e(ba,{variant:"warning",style:{marginTop:"1.25rem",paddingTop:"1.25rem"},children:[e("strong",{children:"Use at your own risk."})," This feature uses the Discord Gateway API with your user token, which violates Discord's Terms of Service. Discord may detect this usage and take action against your account, including phone number locks, temporary suspensions, or permanent bans. While the risk is generally low, it is not zero. Only use this if you understand and accept the risks."]}),e("div",{style:{marginTop:"0.75rem",display:"flex",gap:"0.5rem",alignItems:"center",flexWrap:"wrap"},children:[e("input",{type:"password",value:ye,onChange:r=>ie(r.currentTarget.value),placeholder:"Paste Discord token here...",style:{flex:"1 1 200px",padding:"0.5rem",borderRadius:"4px",border:"1px solid var(--border-color)",background:"var(--bg-primary)",color:"var(--text-primary)",fontFamily:"monospace",minWidth:0}}),e(S,{variant:"primary",size:"sm",onClick:async()=>{try{const r=await b.discord.gatewaySave.mutate({token:ye});oe({hasToken:!0,masked:r.masked,enabled:!0}),ie(r.masked)}catch(r){alert(r instanceof Error?r.message:"Failed to save token")}},children:"Save"}),e(S,{variant:"secondary",size:"sm",onClick:async()=>{await b.discord.gatewayRemove.mutate().catch(()=>{}),ie(""),oe({hasToken:!1,masked:null,enabled:!1})},children:"Remove"})]}),ne&&e("p",{style:{marginTop:"0.5rem",fontSize:"0.8rem",color:ne.hasToken?"green":"var(--text-secondary)"},children:["Status:"," ",ne.hasToken?`Token saved (${ne.masked})`:"No token saved",ne.enabled?" - Gateway active":""]}),t?.owner&&e(da,{})]}),e("div",{className:h.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:T.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Mature Content"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Allow mature content intended for adults 18 and older. Turning this off restores filtering and blur gates."})]}),e($,{isChecked:_,onChange:r=>{r.currentTarget.checked?n(!0):(O(),window.location.reload())},id:"mature-content-enabled"})]})})]})});case"server":return e("div",{className:h.tabContent,children:[t?.owner&&e(fa,{}),t?.owner&&e(ya,{}),t?.owner&&e(va,{})]});case"sync":return e("div",{className:h.tabContent,children:[e(la,{}),e(Rt,{}),e(Dt,{}),t?.owner&&e(oa,{})]});case"watchlist":return e("div",{className:h.tabContent,children:e(Et,{})});case"database":return e("div",{className:h.tabContent,children:[e("div",{className:T.sectionCard,children:[e("h3",{children:"Database Management"}),e("p",{children:"Download a backup of all databases (anime, manga, TV and ASMR) or restore from a backup file. Legacy single-file anime (.db) backups can still be restored."}),e("div",{className:h.controls,children:[e(S,{onClick:De,children:"Backup Database"}),e(S,{variant:"secondary",onClick:Oe,children:"Restore Database"})]}),e("input",{type:"file",ref:a,onChange:Ae,style:{position:"absolute",width:1,height:1,opacity:0,overflow:"hidden"},accept:".json,.db,application/octet-stream"}),m&&e("p",{className:h.status,children:m})]}),t?.owner&&e(aa,{}),e(ia,{})]});default:return null}};return e("div",{className:"page-container",children:[e("div",{className:h.settingsHeader,children:[e("h1",{className:h.pageTitle,children:"Settings"}),e("p",{className:h.pageSubtitle,children:"Manage your preferences and data synchronization"})]}),e("div",{className:h.settingsLayout,children:[e("aside",{className:h.sidebar,ref:p,children:[e("div",{className:h.sidebarIndicator,style:{top:u.top,height:u.height,left:u.left,...u.width?{width:u.width}:{}}}),e("button",{ref:r=>{r&&y.current.set("general",r)},className:`${h.sidebarItem} ${d==="general"?h.active:""}`,onClick:()=>V("general"),children:[e(B,{name:"cog"})," ",e("span",{children:"General"})]}),e("button",{ref:r=>{r&&y.current.set("presence",r)},className:`${h.sidebarItem} ${d==="presence"?h.active:""}`,onClick:()=>V("presence"),children:[e(B,{name:"discord"})," ",e("span",{children:"Presence"})]}),e("button",{ref:r=>{r&&y.current.set("server",r)},className:`${h.sidebarItem} ${d==="server"?h.active:""}`,onClick:()=>V("server"),children:[e(B,{name:"server"})," ",e("span",{children:"Server"})]}),e("button",{ref:r=>{r&&y.current.set("sync",r)},className:`${h.sidebarItem} ${d==="sync"?h.active:""}`,onClick:()=>V("sync"),children:[e(B,{name:"cloud"})," ",e("span",{children:"Synchronization"})]}),e("button",{ref:r=>{r&&y.current.set("watchlist",r)},className:`${h.sidebarItem} ${d==="watchlist"?h.active:""}`,onClick:()=>V("watchlist"),children:[e(B,{name:"list"})," ",e("span",{children:Ca[g]})]}),e("button",{ref:r=>{r&&y.current.set("database",r)},className:`${h.sidebarItem} ${d==="database"?h.active:""}`,onClick:()=>V("database"),children:[e(B,{name:"database"})," ",e("span",{children:"Database"})]})]}),e("main",{className:h.mainContent,children:e("div",{className:h.tabContent,children:Ge()},d)})]}),e(Ye,{isOpen:P,onClose:()=>n(!1),onGrant:()=>{I(),n(!1)},scope:"section"})]})};export{La as default};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{u as t,d as g,A as F,h as y,S as qe,g as ms,q as C,o as hs,p as bs,a as fs,T as Se}from"./vendor-core-DfaOB3Rn.js";import{h as Yn,p as R,t as gt,ac as vs,a6 as ps,S as Hn,e as gs,ak as ys,J as Tr,B as at,a8 as Ss}from"./index-D1FwY1a_.js";import{P as _s,a as Ts,b as Cs,F as ks,f as Es,c as Ns}from"./PlayerProvider-DMiS49-n.js";import{u as ws}from"./vendor-query-BBT5_sHx.js";import{I as le}from"./vendor-icons-DrybRNxP.js";import{p as jn,M as Is,z as Nr,f as Gn,c as xs,C as As,a as Ls,P as Bs,b as vn,u as Ps,i as Ms,j as Rs,n as $s,h as Ds,k as Os,m as zs,l as qs,s as Wn,d as Vs,e as Fs,g as Us,r as Hs,o as xe,A as Ws,t as Ks,E as Qs,w as Ys,x as js,v as ie,y as Gs,R as Xs,q as Js}from"./useWatchAlongPlayer-BkMVbNsw.js";import{S as Zs,O as Kn,a as ea,A as ta,b as na}from"./OptionListMenu-BfK_U2JZ.js";import{M as ra}from"./MatureConsentModal-CkodsDv3.js";import{u as sa}from"./useProviders-B0XQ7aY4.js";import{e as aa,f as oa,g as ia,d as la,c as ca,h as da,i as ua}from"./useTvLibrary-aGEImTh1.js";import{i as Vt,l as ma,s as ha,h as Cr}from"./playbackCompletion-OZmyMjQt.js";import{u as ba}from"./useIsMobile-Dvx1uJ82.js";import{S as fa}from"./SynopsisText-B3Sa5pRv.js";import{W as va}from"./WatchAlongPanel-CNXfPJV8.js";import"./libraryInvalidation-2b2_7vwd.js";const pa="_fullscreenFlat_10bzs_1",ga="_timeDisplay_10bzs_12",ya="_bottomControls_10bzs_16",Sa="_leftControls_10bzs_20",_a="_rightControls_10bzs_21",Ta="_controlBtn_10bzs_25",Ca="_controlsOverlay_10bzs_32",ka="_hidden_10bzs_52",Ea="_topControls_10bzs_58",Na="_backBtn_10bzs_78",wa="_videoTitleInfo_10bzs_98",Ia="_animeTitle_10bzs_104",xa="_episodeLabel_10bzs_112",Aa="_speedBoostBadge_10bzs_119",La="_progressBarContainer_10bzs_165",Ba="_progressBar_10bzs_165",Pa="_thumb_10bzs_184",Ma="_bufferedBar_10bzs_202",Ra="_watchedBar_10bzs_212",$a="_scrubbing_10bzs_237",Da="_timeBubble_10bzs_241",Oa="_bottomControlsRow_10bzs_255",za="_nextEpisodeBtn_10bzs_278",qa="_active_10bzs_340",Va="_settingsPanel_10bzs_352",Fa="_settingsHeader_10bzs_371",Ua="_settingsBackBtn_10bzs_379",Ha="_settingsTitle_10bzs_397",Wa="_settingsContent_10bzs_408",Ka="_currentValue_10bzs_417",Qa="_menuItem_10bzs_423",Ya="_menuNote_10bzs_456",ja="_loadingOverlay_10bzs_465",Ga="_loadingDots_10bzs_476",Xa="_dot_10bzs_481",Ja="_bufferingOverlay_10bzs_510",Za="_bufferingSpinner_10bzs_519",a={fullscreenFlat:pa,timeDisplay:ga,bottomControls:ya,leftControls:Sa,rightControls:_a,controlBtn:Ta,controlsOverlay:Ca,hidden:ka,topControls:Ea,backBtn:Na,videoTitleInfo:wa,animeTitle:Ia,episodeLabel:xa,speedBoostBadge:Aa,progressBarContainer:La,progressBar:Ba,thumb:Pa,bufferedBar:Ma,watchedBar:Ra,scrubbing:$a,timeBubble:Da,bottomControlsRow:Oa,nextEpisodeBtn:za,active:qa,settingsPanel:Va,settingsHeader:Fa,settingsBackBtn:Ua,settingsTitle:Ha,settingsContent:Wa,currentValue:Ka,menuItem:Qa,menuNote:Ya,loadingOverlay:ja,loadingDots:Ga,dot:Xa,bufferingOverlay:Ja,bufferingSpinner:Za},eo=({player:s,visible:b,settingsOpen:O,onOpenSettings:A,onCloseSettings:M,hasSubtitles:k,isSubtitleActive:w,subtitles:u,onSubtitleChange:l,showNextEpisodeButton:_,onNextEpisode:r,isTheaterMode:L,onTheaterModeToggle:fe,timeLabelRef:Z})=>{const{state:m,actions:ke}=s,Ae=()=>{if(w){l(-1);return}let ve=null;try{ve=R.getItem("tvLastSubtitle")}catch{}l(jn(u,{lastKey:ve,enabled:!0}))};return t("div",{className:`${a.controlsOverlay} ${b?"":a.hidden}`,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none",justifyContent:"flex-end"},children:t("div",{className:a.bottomControls,onClick:ve=>ve.stopPropagation(),children:[t(_s,{classes:{container:a.progressBarContainer,scrubbing:a.scrubbing,timeBubble:a.timeBubble,bar:a.progressBar,buffered:a.bufferedBar,watched:a.watchedBar,thumb:a.thumb},timeLabelRef:Z}),t("div",{className:a.bottomControlsRow,children:[t("div",{className:a.leftControls,children:[t(Ts,{className:a.controlBtn}),t(Cs,{buttonClassName:a.controlBtn,onExpandedChange:ke.setShowVolumeSlider}),t("span",{className:a.timeDisplay,ref:Z,children:[Yn(0)," / ",Yn(m.duration)]})]}),t("div",{className:a.rightControls,children:[_&&t("button",{className:a.nextEpisodeBtn,onClick:r,title:"Play next episode",children:"Next EP"}),k&&t("button",{className:`${a.controlBtn} ${w?a.active:""}`,onClick:Ae,"aria-label":w?"Turn subtitles off":"Turn subtitles on",children:t(le,{name:"closed-captioning"})}),t("button",{className:`${a.controlBtn} ${O?a.active:""}`,onClick:()=>O?M():A(),"aria-label":"Settings",children:t(le,{name:"cog"})}),t("button",{className:`${a.controlBtn} ${L?a.active:""}`,onClick:ve=>{ve.stopPropagation(),fe()},title:L?"Exit Theater Mode":"Theater Mode","aria-label":L?"Exit Theater Mode":"Theater Mode",children:t(le,{name:"tv"})}),t(ks,{className:a.controlBtn})]})]})]})})},pn=-6e4,Qn=6e4,kr=500,to=({classes:s,delayMs:b,onDelayChange:O})=>{const[A,M]=g(null),k=A??b,w=F(O);w.current=O;const u=F(b);u.current=b;const l=F(null);l.current=A,y(()=>{M(null)},[b]),y(()=>()=>{const L=l.current;L!==null&&L!==u.current&&w.current(L)},[]);const _=L=>{u.current=L,l.current=null,w.current(L),M(null)},r=L=>{const fe=l.current??u.current,Z=Math.max(pn,Math.min(Qn,fe+L));_(Z)};return t(qe,{children:[t("div",{style:{display:"flex",gap:6,padding:"0.5rem 0.75rem 0.25rem"},children:[t("button",{type:"button",className:s.item,onClick:()=>r(-kr),"aria-label":"Show subtitles 0.5 seconds earlier",style:{flex:1,justifyContent:"center"},children:t("span",{children:"-0.5s"})}),t("button",{type:"button",className:s.item,onClick:()=>r(kr),"aria-label":"Show subtitles 0.5 seconds later",style:{flex:1,justifyContent:"center"},children:t("span",{children:"+0.5s"})}),t("button",{type:"button",className:s.item,onClick:()=>_(0),disabled:k===0,"aria-label":"Reset subtitle timing",style:{flex:1,justifyContent:"center"},children:t("span",{children:"Reset"})})]}),t(Is,{label:"Subtitle timing",display:Nr(k),min:pn,max:Qn,step:100,value:k,percent:(k-pn)/(Qn-pn)*100,onChange:L=>{const fe=Math.round(L);l.current=fe,M(fe)},onCommit:()=>{const L=l.current;L!==null&&_(L)}}),t("div",{className:s.note,children:"Positive delays subtitles (show later). Negative shows them earlier. 0.0s is default."})]})},no=({view:s,onSelectView:b,onClose:O,player:A,onSubtitleStyleChange:M,streams:k,resolutionIdx:w,onResolutionChange:u,hasSubtitles:l,subtitles:_,selectedSubtitle:r,isSubtitleActive:L,onSubtitleChange:fe,audioTracks:Z,selectedAudioTrack:m,onAudioTrackChange:ke,videoDelayEnabled:Ae,onVideoDelayToggle:ve,videoDelayMs:pe,onVideoDelayChange:S,onCalibrate:yt,subtitleDelayMs:Ge,onSubtitleDelayChange:E,ambientSettings:U,onAmbientChange:Q})=>{const{state:ce}=A,St=()=>t(qe,{children:[k.length>1&&t("button",{className:a.menuItem,onClick:()=>b("resolution"),children:[t("span",{children:"Resolution"}),t("span",{className:a.currentValue,children:k[w]?.quality||"Auto"})]}),l&&t("button",{className:a.menuItem,onClick:()=>b("subtitles"),children:[t("span",{children:"Subtitles"}),t("span",{className:a.currentValue,children:L?_[r]?.label||_[r]?.language:"Off"})]}),l&&t("button",{className:a.menuItem,onClick:()=>b("subtitle-style"),children:[t("span",{children:"Subtitle Style"}),t("span",{className:a.currentValue,children:[ce.subtitleFontSize.toFixed(1),"x · ",ce.subtitlePosition]})]}),l&&t("button",{className:a.menuItem,onClick:()=>b("subtitle-timing"),children:[t("span",{children:"Subtitle Timing"}),t("span",{className:a.currentValue,children:Nr(Ge)})]}),Z.length>0&&t("button",{className:a.menuItem,onClick:()=>b("audio"),children:[t("span",{children:"Audio Track"}),t("span",{className:a.currentValue,children:Z[m]?.label||Z[m]?.language})]}),t("button",{className:a.menuItem,onClick:()=>b("av-sync"),children:[t("span",{children:"A/V Sync"}),t("span",{className:a.currentValue,children:Ae?`${pe}ms`:"Off"})]}),U&&Q&&t("button",{className:a.menuItem,onClick:()=>b("ambient"),children:[t("span",{children:"Ambient Light"}),t("span",{className:a.currentValue,children:U.enabled?"On":"Off"})]})]}),Le=()=>t(Kn,{classes:{item:a.menuItem,active:a.active},options:k.map((I,te)=>({key:String(te),label:I.quality,selected:te===w})),onSelect:I=>u(Number(I))}),Xe=()=>t(Kn,{classes:{item:a.menuItem,active:a.active},options:[{key:"off",label:"Off",selected:!L},..._.map((I,te)=>({key:String(te),label:I.label||I.language,selected:te===r}))],onSelect:I=>fe(I==="off"?-1:Number(I))}),ot=()=>t(ea,{classes:{item:a.menuItem,active:a.active},values:{fontSize:ce.subtitleFontSize,position:ce.subtitlePosition,bgOpacity:ce.subtitleBgOpacity,bgColor:ce.subtitleBgColor,textColor:ce.subtitleTextColor,edge:ce.subtitleEdge,bold:ce.subtitleBold},onChange:M}),ae=()=>t(to,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},delayMs:Ge,onDelayChange:I=>E?.(I)}),_t=()=>t(Kn,{classes:{item:a.menuItem,active:a.active},options:Z.map((I,te)=>({key:String(te),label:I.label||I.language,selected:te===m})),onSelect:I=>ke(Number(I))}),Je=()=>t(ta,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},enabled:Ae,delayMs:pe,onToggle:I=>ve?.(I),onDelayChange:I=>S?.(I),onCalibrate:yt}),Y=()=>U&&Q?t(na,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},values:U,onChange:Q}):null;return t("div",{"data-speed-boost-ignore":"true",onClick:I=>I.stopPropagation(),children:t(Zs,{classes:{panel:a.settingsPanel,header:a.settingsHeader,backBtn:a.settingsBackBtn,title:a.settingsTitle,content:a.settingsContent},title:s==="main"?"Settings":s==="subtitle-style"?"Subtitle Style":s==="subtitle-timing"?"Subtitle Timing":s==="audio"?"Audio Track":s==="resolution"?"Resolution":s==="av-sync"?"A/V Sync":s==="ambient"?"Ambient Light":s.charAt(0).toUpperCase()+s.slice(1),onBack:()=>s==="main"?O():b("main"),children:[s==="main"&&St(),s==="resolution"&&Le(),s==="subtitles"&&Xe(),s==="subtitle-style"&&ot(),s==="subtitle-timing"&&ae(),s==="audio"&&_t(),s==="av-sync"&&Je(),s==="ambient"&&Y()]})})},ro=({player:s,title:b,episodeLabel:O,server:A,audioTracks:M,selectedAudioTrack:k,onAudioTrackChange:w,subtitles:u,selectedSubtitle:l,onSubtitleChange:_,streams:r,resolutionIdx:L,onResolutionChange:fe,onBack:Z,children:m,videoDelayEnabled:ke=!1,onVideoDelayToggle:Ae,videoDelayMs:ve=0,onVideoDelayChange:pe,onCalibrateAvSync:S,subtitleDelayMs:yt=0,onSubtitleDelayChange:Ge,showNextEpisodeButton:E=!1,onNextEpisode:U,isLoading:Q=!1,isTheaterMode:ce,onTheaterModeToggle:St,ambientSettings:Le,onAmbientChange:Xe,hideChrome:ot=!1})=>{const{state:ae,refs:_t,actions:Je}=s,Y=_t.videoRef,{subtitleFontSize:I,subtitlePosition:te,subtitleBgOpacity:de,subtitleBgColor:Be,subtitleTextColor:Pe,subtitleEdge:ne,subtitleBold:Tt}=ae,[Ve,_e]=g(null),Ct=F(null),[Te,kt]=g(0);y(()=>{const me=Y.current;if(!me)return;const ee=()=>kt(me.clientHeight||0);ee();const et=new ResizeObserver(ee);return et.observe(me),()=>et.disconnect()},[Y]);const ue=Je.setSubtitleStyle;y(()=>{const me="tv-player-subtitle-style";let ee=document.getElementById(me);ee||(ee=document.createElement("style"),ee.id=me,document.head.appendChild(ee));const et={fontSize:I,position:te,bgOpacity:de,bgColor:Be,textColor:Pe,edge:ne,bold:Tt},re=Y.current,ct=Gn(I,Te||re?.clientHeight||720);if(ee.textContent=xs({...et,fontSize:ct}),re){const wt=()=>{const i=Number(te);return isNaN(i)?0:Math.max(0,Math.min(100,i))},tt=(i,c)=>{try{const z=i;z.snapToLines=!1,z.line=c}catch{}},ge=()=>{const i=ct*16,c=re.videoHeight||re.clientHeight||720,z=re.videoWidth||re.clientWidth||1280;return{step:i*1.3/c*100,chars:Math.max(20,Math.floor(z/(i*.55)))}},Ht=i=>{const c=Math.max(0,Math.min(100,100-wt())),z=Array.from(i.activeCues??[]);if(z.length<=1){z.forEach(Re=>tt(Re,c));return}const{step:oe,chars:Wt}=ge();let At=c;for(let Re=z.length-1;Re>=0;Re--){const gn=String(z[Re].text??"").replace(/<[^>]*>/g,"").split(`
|
|
2
|
-
`).reduce((yn,he)=>yn+Math.max(1,Math.ceil(he.length/Wt)),0),Lt=At-gn*oe;tt(z[Re],Math.max(0,Lt)),At=Lt-oe*.4}},Ne=()=>{const i=Math.max(0,Math.min(100,100-wt()));Array.from(re.textTracks).forEach(c=>{c.cues&&(Array.from(c.cues).forEach(z=>tt(z,i)),c.mode==="showing"&&Ht(c))})};Ne();const nt=i=>{const c=i.target;c.mode==="showing"&&Ht(c)},It=()=>{Array.from(re.textTracks).forEach(i=>{i.removeEventListener("cuechange",nt),i.addEventListener("cuechange",nt)}),Ne()};Array.from(re.textTracks).forEach(i=>{i.addEventListener("cuechange",nt)}),re.textTracks.addEventListener("addtrack",It);const xt=Array.from(re.querySelectorAll("track")),dt=()=>Ne();return xt.forEach(i=>i.addEventListener("load",dt)),()=>{Array.from(re.textTracks).forEach(i=>{i.removeEventListener("cuechange",nt)}),re.textTracks.removeEventListener("addtrack",It),xt.forEach(i=>i.removeEventListener("load",dt))}}},[I,te,de,Be,Pe,ne,Tt,l,u,Y,Te]);const Me=u.length>0,Ee=l>=0,it=()=>{_e("main"),Je.setShowControls(!0)},Fe=()=>{_e(null)},Ft=ae.showControls||!!Ve,Ze=Es(s.engine),Ue=Ze.audioTracks.find(me=>me.id===Ze.activeAudioTrack)??M[k],Ut=l>=0?u[l]??Ze.subtitleTracks.find(me=>me.id===l):void 0,Et=t(As,{visible:Ft,title:b,episode:O,server:Q?void 0:A,audio:Q?void 0:Ue?.label||Ue?.language,subtitles:Q?void 0:Ut?.label||Ut?.language,onBack:Z,classes:{overlay:a.controlsOverlay,hidden:a.hidden,top:a.topControls,backBtn:a.backBtn,titleInfo:a.videoTitleInfo,title:a.animeTitle,episode:a.episodeLabel}}),K=!Q&&!ae.isBuffering&&ae.duration>0?t(Ls,{}):null,lt=t(eo,{player:s,visible:Ft,settingsOpen:!!Ve,onOpenSettings:it,onCloseSettings:Fe,hasSubtitles:Me,isSubtitleActive:Ee,subtitles:u,onSubtitleChange:_,showNextEpisodeButton:E,onNextEpisode:U,isTheaterMode:ce,onTheaterModeToggle:St,timeLabelRef:Ct}),x=Ve?t(no,{view:Ve,onSelectView:_e,onClose:Fe,player:s,onSubtitleStyleChange:ue,streams:r,resolutionIdx:L,onResolutionChange:fe,hasSubtitles:Me,subtitles:u,selectedSubtitle:l,isSubtitleActive:Ee,onSubtitleChange:_,audioTracks:M,selectedAudioTrack:k,onAudioTrackChange:w,videoDelayEnabled:ke,onVideoDelayToggle:Ae,videoDelayMs:ve,onVideoDelayChange:pe,onCalibrate:()=>{_e(null),S?.()},subtitleDelayMs:yt,onSubtitleDelayChange:Ge,ambientSettings:Le,onAmbientChange:Xe}):null,Nt=t(qe,{children:[Q&&t("div",{className:a.loadingOverlay,"aria-hidden":"true",children:t("div",{className:a.loadingDots,children:[t("div",{className:a.dot}),t("div",{className:a.dot}),t("div",{className:a.dot})]})}),ae.isBuffering&&!Q&&t("div",{className:a.bufferingOverlay,"aria-hidden":"true",children:t("div",{className:a.bufferingSpinner})}),ae.isSpeedBoostActive&&t("div",{className:a.speedBoostBadge,"aria-hidden":"true",children:[t("span",{children:"2x"}),t(le,{name:"forward",size:12})]})]});return t(Bs,{engine:s.engine,topBar:Et,centerControls:K,bottomBar:!Q&&ae.duration>0?lt:null,settingsPanel:x,overlays:Nt,isInteracting:!!Ve||ae.showVolumeSlider,nativeControls:ae.useNativeControls,onStageClick:Fe,className:ae.isFullscreen?a.fullscreenFlat:"",chromeDisabled:ot,children:m})},so=({servers:s,selectedServer:b,onServerSelect:O})=>s.length===0?null:t("div",{className:vn.sourceSelectionContainer,children:[t("h4",{children:"Source"}),t("div",{className:vn.sourceButtons,children:s.map(A=>t("button",{className:`${vn.sourceButton} ${b===A?vn.active:""}`,onClick:()=>O(A),children:A},A))})]}),ao=ms.memo(so);function oo({details:s,isMovie:b,season:O,episode:A,videoRef:M,active:k}){const w=F("");w.current||(w.current=`tv-${Date.now()}-${Math.random().toString(36).slice(2)}`);const u=C(()=>{if(!s)return;const l=M.current,_=b?"":`S${String(O).padStart(2,"0")}E${String(A).padStart(2,"0")}`;gt.discord.tvPresence.mutate({title:s.title,episodeLabel:_,isPlaying:l?!l.paused&&!l.ended:!0,thumbnail:s.poster,currentTime:l?l.currentTime:0,duration:l&&l.duration||0,isAdult:s.adult===!0,sessionId:w.current}).catch(()=>{}),gt.discord.heartbeat.mutate({sessionId:w.current}).catch(()=>{})},[s,b,O,A,M]);return y(()=>{if(!s)return;u();const l=window.setInterval(()=>{const _=M.current;(!_||!_.paused)&&u()},15e3);return()=>window.clearInterval(l)},[u,s,M]),y(()=>{if(!s||!k)return;const l=M.current;if(!l)return;const _=()=>u();return l.addEventListener("play",_),l.addEventListener("pause",_),l.addEventListener("seeked",_),()=>{l.removeEventListener("play",_),l.removeEventListener("pause",_),l.removeEventListener("seeked",_)}},[s,k,u,M]),y(()=>{const l=w.current,_=()=>vs(l),r=()=>_();return window.addEventListener("pagehide",r),window.addEventListener("beforeunload",r),()=>{window.removeEventListener("pagehide",r),window.removeEventListener("beforeunload",r),_()}},[]),{sendPresence:u}}function io(s,b,O){const A=()=>{const k=Array.isArray(s.audioTracks)?s.audioTracks.length:0,w=O.getWant(),u=k>0?Math.min(Math.max(0,w),k-1):w;s.audioTrack=u,u!==w&&O.onResolve(u)},M=(k,w)=>{const u=O.getWant(),l=Array.isArray(s.audioTracks)?s.audioTracks.length:0;if(w.id!==u&&u>=0&&u<l){s.audioTrack!==u&&(s.audioTrack=u);return}O.onResolve(w.id)};return s.on(b.MANIFEST_PARSED,A),s.on(b.AUDIO_TRACK_SWITCHED,M),()=>{s.off(b.MANIFEST_PARSED,A),s.off(b.AUDIO_TRACK_SWITCHED,M)}}const lo=/\b(SmartTV|SMART-TV|Tizen|Web0S|webOS|NetCast|HbbTV|AppleTV|CrKey|BRAVIA|AFT[A-Za-z]|Fire\s?TV|GoogleTV|Roku|VIDAA|DTV|PlayStation|Xbox|Opera TV|POV_TV)\b/i;function co(){try{if(lo.test(navigator.userAgent||""))return!0;const s=navigator.deviceMemory;if(typeof s=="number"&&s>0&&s<2)return!0}catch{}return!1}const uo="_statusMsg_4sq8d_1",mo="_error_4sq8d_7",ho="_spinner_4sq8d_11",bo="_spin_4sq8d_11",fo="_sourceLoader_4sq8d_16",vo="_ringSpinner_4sq8d_22",po="_meta_4sq8d_40",go="_year_4sq8d_48",yo="_rating_4sq8d_53",So="_typeBadge_4sq8d_62",_o="_tv_4sq8d_70",To="_movie_4sq8d_75",Co="_controlLabel_4sq8d_80",ko="_select_4sq8d_90",Eo="_playerSection_4sq8d_102",No="_video_4sq8d_106",wo="_videoHidden_4sq8d_128",Io="_delayCanvas_4sq8d_133",xo="_delayCanvasActive_4sq8d_146",Ao="_subtitleOverlay_4sq8d_150",Lo="_videoIframe_4sq8d_169",Bo="_retryButton_4sq8d_177",Po="_sidebarSeason_4sq8d_192",Mo="_mobileSeasonRow_4sq8d_208",Ro="_providerSelectWrap_4sq8d_222",$o="_genreRow_4sq8d_230",Do="_genreChip_4sq8d_237",Oo="_metaRow_4sq8d_247",zo="_detailGrid_4sq8d_256",qo="_detailItem_4sq8d_264",Vo="_imdbLink_4sq8d_286",Fo="_watchedOverlay_4sq8d_296",Uo="_watchedTitle_4sq8d_318",Ho="_watchedSubtext_4sq8d_324",Wo="_watchedActions_4sq8d_330",f={statusMsg:uo,error:mo,spinner:ho,spin:bo,sourceLoader:fo,ringSpinner:vo,meta:po,year:go,rating:yo,typeBadge:So,tv:_o,movie:To,controlLabel:Co,select:ko,playerSection:Eo,video:No,videoHidden:wo,delayCanvas:Io,delayCanvasActive:xo,subtitleOverlay:Ao,videoIframe:Lo,retryButton:Bo,sidebarSeason:Po,mobileSeasonRow:Mo,providerSelectWrap:Ro,genreRow:$o,genreChip:Do,metaRow:Oo,detailGrid:zo,detailItem:qo,imdbLink:Vo,watchedOverlay:Fo,watchedTitle:Uo,watchedSubtext:Ho,watchedActions:Wo},Ko=[],Qo=[];function Er({error:s,onRetry:b}){return t("div",{className:`${f.statusMsg} ${f.error}`,style:{flexDirection:"column",alignItems:"stretch",gap:8},children:t("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[t("span",{style:{flex:1},children:s}),t("button",{className:f.retryButton,onClick:b,children:"Retry"})]})})}const ci=()=>{const{id:s}=hs(),[b]=bs(),O=F(b);O.current=b;const A=fs(),M=ws(),k=b.get("type"),w=ps(),u=!!w.session,l=u&&!w.session?.host,_=l&&["tv","movie"].includes(w.room?.selection.kind||"")?w.room?.selection:null,[r,L]=g(null),[fe,Z]=g(()=>parseInt(b.get("s")||"1",10)||1),m=_?.season??fe,[ke,Ae]=g([]),[ve,pe]=g(()=>parseInt(b.get("e")||"1",10)||1),S=_?Number(_.episode):ve,[yt,Ge]=g(()=>{try{return R.getItem("tvProvider")||""}catch{return""}}),E=_?.provider??yt,[U,Q]=g([]),[ce,St]=g(""),[Le,Xe]=g(""),{options:ot,isFallback:ae,isLoading:_t}=sa(),Je=Se(()=>ot.filter(e=>(e.kind??"tv")==="tv").map(e=>({id:e.id,label:e.label,tier:e.tier==="embed"?"embed":"direct",servers:e.servers})),[ot]),Y=ae||Je.length===0?Ko:Je,I=Y.filter(e=>e.tier==="direct"),te=Y.filter(e=>e.tier==="embed"),[de,Be]=g(!1),[Pe,ne]=g(""),[Tt,Ve]=g([]),[_e,Ct]=g(0),[Te,kt]=g([]),[ue,Me]=g(-1),[Ee,it]=g(0),[Fe,Ft]=g(""),[Ze,Ue]=g(""),[Ut,Et]=g(()=>{try{return R.getItem("tvServer")||""}catch{return""}}),K=_?.source??Ut,lt=Se(()=>Y.find(e=>e.id===E),[Y,E]),x=lt?.tier==="embed",[Nt,me]=g([]),[ee,et]=g(""),[re,ct]=g(""),[wt,tt]=g(!1),ge=Se(()=>Nt.length>0?Nt:lt?.servers??[],[Nt,lt]),Ht=Se(()=>ee&&!u?["Embed",...ge]:ge,[ge,ee,u]),Ne=wt&&!!ee,nt=Ne?re||ee:"";y(()=>{if(!ee){ct("");return}let e=!1;return Hn(`/api/resolve?url=${encodeURIComponent(ee)}`).then(n=>{!e&&n.finalUrl&&ct(n.finalUrl)}).catch(()=>{}),()=>{e=!0}},[ee]);const It=F([]);y(()=>{It.current=U},[U]);const xt=F(_e);y(()=>{xt.current=_e},[_e]);const dt=F(ue);y(()=>{dt.current=ue},[ue]);const i=Ps({skipIntervals:Qo}),c=i.refs.videoRef,z=F(null),oe=F([]),Wt=F(null),At=F(null),{videoDelayMs:Re,videoDelayEnabled:Kt,setDelayEnabled:gn,handleVideoDelayChange:Lt,isCalibrating:yn,testClipActive:he,stopCalibration:Sn,openAvSyncCalibrator:wr,cancelAvSyncCalibrator:Ir,applyAvSyncCalibrator:xr,toggleTestClip:Ar,calibReturnRef:Qt,effectiveVideoDelayMs:_n}=Ms(c),[ut,Lr]=g(()=>{try{const e=Number(R.getItem("tvSubtitleDelayMs"));if(Number.isFinite(e)&&e>=-6e4&&e<=6e4)return Math.round(e)}catch{}return 0}),Tn=F(ut);Tn.current=ut;const Br=C(e=>{const n=Math.max(-6e4,Math.min(6e4,Math.round(e)));if(Tn.current!==n){Tn.current=n,Lr(n);try{R.setItem("tvSubtitleDelayMs",String(n))}catch{}}},[]);Rs({videoRef:c,canvasRef:Wt,delayMs:_n,enabled:Kt});const Cn=Kt,ye=Cn||ut!==0,{settings:kn,update:Pr}=$s(),En=F(ye);En.current=ye;const Nn=C(()=>{if(!En.current)return;const e=c.current;e&&Array.from(e.textTracks).forEach(n=>{n.mode!=="hidden"&&(n.mode="hidden")})},[c]),{hasConsent:Bt,grant:Mr}=gs(),v=k==="movie";oo({details:r,isMovie:v,season:m,episode:S,videoRef:c,active:!x&&!de&&!Pe&&U.length>0});const Yt=s?ys(k||"tv",s):"",G=Yt,$e=`${G}:${m}:${S}:${E}:${K}`,jt=Se(()=>!s||!r||x||Ne||de||Le!==$e||U[Ee]?.type!=="hls"?null:{kind:v?"movie":"tv",...v?{}:{season:m},showId:s,episode:String(v?1:S),provider:E,source:K,mode:"sub",title:r.title},[s,r,x,Ne,de,Le,$e,U,Ee,v,m,S,E,K]),Xn=Ds(i.engine,jt,de||!r),Jn=aa(),Gt=oa(),Xt=ia(),{toggle:Zn,bookmarkedIds:Rr,pending:$r}=la(),{data:er}=ca(r?Yt:void 0),Pt=er?!!er.inLibrary:Yt?Rr.has(Yt):!1,Dr=C(()=>{!r||!s||Zn({tmdbId:Number(s),mediaType:k||"tv",title:r.title,poster:r.poster,year:r.year,adult:r.adult})},[r,s,k,Zn]),{data:He,isFetched:Mt,isFetching:wn}=da(G||void 0,m,S),Jt=Se(()=>ke.map(e=>e.episode_number).sort((e,n)=>e-n),[ke]),Rt=Jt.indexOf(S),In=Rt>0?Jt[Rt-1]:null,q=Rt>=0&&Rt<Jt.length-1?Jt[Rt+1]:null,Zt=Se(()=>(r?.seasons??[]).map(e=>e.season_number).filter(e=>Number.isFinite(e)).sort((e,n)=>e-n),[r]),De=Se(()=>{if(v||q!=null)return null;const e=Zt.indexOf(m);return e>=0&&e<Zt.length-1?Zt[e+1]:(r?.number_of_seasons??0)>m?m+1:null},[v,q,Zt,m,r?.number_of_seasons]),en=He?.currentTime??0,tn=F(null),[We,nn]=g(!1),[mt,tr]=g(0),[$t,nr]=g(!1),[ht,bt]=g(!1),[Or,xn]=g(!1),[zr,qr]=g(""),[rn,Vr]=g(!1),[Fr,An]=g(!1),[Ln,rr]=g(!1),{isTheaterMode:Oe,toggleTheaterMode:Bn,handleLayoutClick:Ur}=Os(),sr=He?.duration??0,ar=He?.completed===1,sn=`${G}:${m}:${S}`,[or,Hr]=g(null);y(()=>{Mt&&Hr(e=>e?.key===sn?e:{key:sn,watched:ar||Vt(en,sr)})},[Mt,sn,ar,en,sr]);const Wr=Mt&&or?.key===sn&&or.watched,ft=!u&&!he&&Wr&&!Ln,Kr=C(()=>rr(!0),[]);y(()=>{const e=n=>{n.defaultPrevented||n.ctrlKey||n.metaKey||n.altKey||n.repeat||n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="t"&&Bn()};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[Bn]),zs(i,(U.length>0||Ze!=="")&&!Oe&&!We&&!ht&&!ft);const Qr=ba(),[vt,Yr]=g(ma),jr=C(e=>{Yr(e),ha(e)},[]),Ke=F(!1),ze=F(null),Pn=F(0),X=F(null),an=F(""),Gr=Cr(en),Dt=!u&&!Ke.current&&!Ln&&(We||ht||Gr||ft),on=F(Dt);on.current=Dt;const ln=F(!1);y(()=>{ln.current=$t},[$t]);const Qe=C((e,n)=>{if(!G||!n||n<30)return;const o=Vt(e,n);Math.abs(e-Pn.current)<10&&!o||(Pn.current=e,Jn.mutate({mediaId:G,season:m,episode:S,currentTime:Math.floor(e),duration:Math.floor(n),completed:o,title:r?.title??null,poster:r?.poster??null,backdrop:r?.backdrop??null,year:r?.year??null,overview:r?.overview??null,tmdbId:r?.id??null,mediaType:k||"tv",adult:r?.adult?1:0}))},[G,m,S,Jn,r,k]),we=C((e,n)=>{Sn();const o=new URLSearchParams(b);o.set("type",b.get("type")||"tv"),o.set("s",String(e)),o.set("e",String(n)),A(`${window.location.pathname}?${o.toString()}`)},[b,A,Sn]),Ot=C(()=>{const e=c.current;if(!e||v||q==null){xn(!1);return}const n=e.duration||0,o=e.currentTime||0;xn(n>0&&o/n>=.8)},[v,q,c]),cn=C((e,n)=>["tv-sources",E,v?"movie":"tv",s,e,n,K],[E,v,s,K]),dn=C(async(e,n)=>{if(!r||!s||!E)return{valid:!1,sources:[]};const o=v?"movie":"tv",d=await gt.tv.sources.query({provider:E,type:o,tmdbId:String(s),season:e,episode:n,title:r.title||"",year:r.year||"",totalSeasons:String(r.number_of_seasons||1),imdbId:r.imdb_id||"",...K?{server:K}:{}});return{valid:"valid"in d?d.valid:!1,error:"error"in d?d.error:void 0,sources:d.sources,referer:"referer"in d?d.referer:void 0,audioTracks:d.audioTracks,subtitles:"subtitles"in d?d.subtitles:void 0,servers:"servers"in d?d.servers:void 0,server:"server"in d?d.server:void 0,embedUrl:"embedUrl"in d?d.embedUrl:void 0}},[r,s,E,v,K]),ir=C(()=>{if(v||!r||!s||!E||x||q==null)return;const e=cn(m,q);M.getQueryState(e)?.status!=="success"&&M.prefetchQuery({queryKey:e,queryFn:()=>dn(m,q),staleTime:300*1e3,gcTime:1800*1e3})},[v,r,s,E,x,q,m,M,cn,dn]),Xr=C(()=>{if(he)return;Ot();const e=c.current;!e||e.paused||e.ended||(e.duration>0&&e.duration-e.currentTime<=60&&ir(),!ze.current&&(ze.current=setTimeout(()=>{ze.current=null,Qe(e.currentTime,e.duration||0)},5e3)))},[Qe,c,he,Ot,ir]),Jr=C(()=>{const e=c.current;if(!(!e||!r)&&(ze.current&&clearTimeout(ze.current),ze.current=null,Qe(e.currentTime,e.duration||0),!l)){if(q!=null){vt&&(pe(q),we(m,q));return}qr(v?r.title:`${r.title} - Season ${m}`),bt(!0),Ke.current=!0}},[v,r,m,q,vt,Qe,we,c,l]),{checkEnd:un,logDuration:lr}=qs({videoRef:c,sourceType:x?"iframe":void 0,resetKey:`${G}:${m}:${S}:${Ln}`,onEnd:Jr}),Zr=C(()=>{i.actions.onPlay()},[i.actions]),es=C(()=>{i.actions.onPause();const e=c.current;e&&!e.ended&&Qe(e.currentTime,e.duration||0)},[i.actions,Qe,c]),ts=C(()=>{const e=c.current;if(e){try{const n=parseFloat(R.getItem("playerVolume")||"");isNaN(n)||(e.volume=Math.max(0,Math.min(1,n))),e.muted=R.getItem("playerMuted")==="true"}catch{}if(X.current!=null&&X.current>0){try{e.currentTime=X.current}catch{}X.current=null}Ot()}},[c,Ot]),Mn=C(()=>{const e=c.current;if(e&&X.current!=null&&X.current>0){try{e.currentTime=X.current}catch{}X.current=null}},[c]),ns=C(()=>{mt>0&&(X.current=mt);const e=c.current;if(e&&mt>0){try{e.currentTime=mt,X.current=null}catch{}e.play().catch(()=>{})}nn(!1),Ke.current=!0},[mt,c]),cr=C(()=>{X.current=null;const e=c.current;e&&(e.currentTime=0,e.play().catch(()=>{})),nn(!1),Ke.current=!0},[c]),dr=C(()=>{q!=null&&(Ke.current=!0,pe(q),we(m,q))},[q,m,we]),ur=C(()=>{De!=null&&(bt(!1),Ke.current=!0,Z(De),pe(1),we(De,1))},[De,we]),rs=C(async()=>{if(G)try{Pt?await Gt.mutateAsync({id:G,status:"Completed"}):r&&s&&(await Xt.mutateAsync({tmdbId:Number(s),mediaType:k||"tv",title:r.title,poster:r.poster,backdrop:r.backdrop,year:r.year,overview:r.overview,adult:r.adult,status:"Completed",silent:!0}),Tr.success("Moved to Completed")),bt(!1),A("/")}catch{}},[G,Pt,Gt,Xt,r,s,k,A]);y(()=>{Ke.current=!1,tn.current=null,nn(!1),xn(!1),tr(0),nr(!1),rr(!1),ln.current=!1,X.current=null,Pn.current=0},[G,m,S]),y(()=>{an.current=$e},[$e]),y(()=>{Mt&&(nr(!0),ln.current=!0)},[Mt,G,m,S]),y(()=>{if(u||wn||!He||Ke.current)return;const e=`${G}:${m}:${S}`;if(tn.current===e)return;tn.current=e;const n=He,o=n.currentTime??0;Cr(o)&&n.completed!==1&&!Vt(o,n.duration??0)&&(tr(o),nn(!0))},[He,wn,G,m,S,u]),y(()=>{!u&&We&&c.current&&c.current.pause()},[We,c,u]),y(()=>{const e=c.current;return()=>{ze.current&&clearTimeout(ze.current),ze.current=null,!e?.ended&&i.engine.getState().duration>0&&Qe(i.engine.getTimeline().currentTime,i.engine.getState().duration)}},[i.engine,Qe,c]);const Rn=C(e=>{let n=null,o=!0;try{n=R.getItem("tvLastSubtitle"),o=R.getItem("tvSubtitlesEnabled")!=="false"}catch{}return jn(e,{lastKey:n,enabled:o})},[]),$n=C(e=>{if(!(e<0))try{R.setItem("tvSubtitlesEnabled","true"),R.setItem("tvSelectedSubtitle",String(e))}catch{}},[]),mr=C(e=>{if(e.length===0)return 0;let n=null;try{n=R.getItem("tvLastAudio")}catch{}if(n){const o=e.findIndex(B=>Wn(B)===n);if(o>=0)return o;const d=n.indexOf("|||"),h=d>=0?n.slice(0,d):n,T=d>=0?n.slice(d+3):n,$=e.findIndex(B=>B.language===h||B.label===T);if($>=0)return $}return jn(e,{lastKey:null,enabled:!0})},[]),hr=C(e=>{let n=null;try{n=R.getItem("tvLastQuality")}catch{}if(!n||e.length===0)return 0;const o=e.findIndex(B=>(B.quality||"")===n);if(o>=0)return o;const d=B=>{const J=/(\d{3,4})/.exec(B||"");return J?parseInt(J[1],10):0},h=d(n);if(!h)return 0;let T=0,$=1/0;return e.forEach((B,J)=>{const p=d(B.quality),H=Math.abs(p-h);p>0&&H<$&&($=H,T=J)}),T},[]),{data:br}=ua(G||void 0),fr=Se(()=>(br?.progress??[]).filter(n=>n.season===m&&(n.completed===1||Vt(n.currentTime,n.duration))).map(n=>String(n.episode)),[br,m]),vr=Se(()=>ke.map(e=>({id:String(e.episode_number),label:`Episode ${e.episode_number}`,sublabel:e.name||void 0,thumbnail:e.still_path?`https://image.tmdb.org/t/p/w185${e.still_path}`:void 0})),[ke]),pr=Se(()=>(r?.genres??[]).map(e=>e.name).slice(0,5),[r]),Dn=Se(()=>[r?.year,r?.status,r?.number_of_seasons?`${r.number_of_seasons} Season${r.number_of_seasons>1?"s":""}`:null,r?.number_of_episodes?`${r.number_of_episodes} Episodes`:null].filter(Boolean),[r]);y(()=>{if(!l&&Y.length!==0&&!Y.some(e=>e.id===E)){const e=Y.find(n=>n.tier==="direct")?.id??Y[0].id;Ge(e);try{R.setItem("tvProvider",e)}catch{}}},[Y,E,l]),y(()=>{me([]),et(""),ct(""),tt(!1)},[E]),y(()=>{if(!l&&ge.length!==0&&!ge.includes(K)){Et(ge[0]);try{R.setItem("tvServer",ge[0])}catch{}}},[ge,K,l]),y(()=>{if(!s){L(null),Q([]),Xe(""),ne(""),Ue("");return}const e=Number(s),n=k||"tv";L(null),Q([]),Xe(""),ne(""),Ue("");const o=parseInt(O.current.get("s")||"",10),d=parseInt(O.current.get("e")||"",10);Z(isNaN(o)?1:o),pe(isNaN(d)?1:d),it(0),gt.tv.details.query({type:n,id:String(e)}).then(h=>{const T={id:h.id,title:h.title||"",overview:h.overview||"",vote_average:h.vote_average,year:h.year,poster:h.poster,backdrop:h.backdrop,imdb_id:h.imdb_id||void 0,adult:h.adult,seasons:h.seasons,number_of_seasons:h.number_of_seasons};L(T),T.seasons&&T.seasons.length>0&&isNaN(o)&&Z(T.seasons[0].season_number)}).catch(()=>{})},[s,k]),y(()=>{if(!r||!s)return;if(!(r.seasons!==void 0||r.number_of_seasons!==void 0)){Ae([]);return}const n=parseInt(b.get("e")||"",10);gt.tv.episodes.query({id:String(s),season:String(m)}).then(o=>{const d=(o.episodes||[]).map(h=>({episode_number:h.episode_number,name:h.name||"",vote_average:h.vote_average,overview:h.overview||"",still_path:h.still_path||""}));Ae(d),d.length!==0&&pe(h=>!isNaN(n)&&d.some(T=>T.episode_number===n)?n:d.some(T=>T.episode_number===h)?h:d[0].episode_number)}).catch(()=>{})},[r,s,m,b]),y(()=>{if(!x||!r||!s)return;Hn(`/api/tv/embed/${E}/${v?"movie":"tv"}/${s}?season=${m}&episode=${S}`).then(n=>{if(n.url)return Ue(n.url),Hn(`/api/resolve?url=${encodeURIComponent(n.url)}`).then(o=>{o.finalUrl&&Ue(o.finalUrl)})}).catch(()=>{})},[E,r,s,m,S,v,x]);const mn=C(async()=>{if(!r||!s||!E||x||r.adult&&!Bt)return;const e=$e;Be(!0),ne(""),It.current.length===0&&(Q([]),it(0),Ve([]),kt([]));try{const n=await M.fetchQuery({queryKey:cn(m,S),queryFn:()=>dn(m,S),staleTime:3e5,gcTime:18e5});if(an.current!==e)return;if(Be(!1),!n.valid||!n.sources?.length){ne(n.error?`${n.error}`:ge.length>0?`No streams from ${K}. Try another server.`:"No streams available.");return}if(u&&K&&n.server&&n.server!==K){Q([]),ne("The host's selected server is unavailable. Automatic source switching is disabled in watch-along rooms.");return}!l&&!K&&n.server&&Et(n.server);const o=u?n.sources.filter(B=>B.type==="hls"):n.sources;if(u&&o.length===0){Q([]),ne("The room requires a direct HLS source. No compatible stream is available here.");return}Q(o),St(n.server||K),Xe(e),n.servers?.length&&me(n.servers),n.embedUrl&&et(n.embedUrl),it(hr(o)),n.referer&&Ft(n.referer);const d=n.audioTracks||[];Ve(d),Ct(d.length>0?mr(d):0);const h=n.subtitles||[];if(kt(h),h.length>0){const B=Rn(h);Me(B),$n(B)}else Me(-1);const T=v?"movie":"tv",$=s;gt.tv.subtitles.query({type:T,tmdbId:String($),season:String(m),episode:String(S)}).then(B=>{if(an.current!==e)return;const J=Array.isArray(B.subtitles)?B.subtitles:[];J.length!==0&&kt(p=>{const H=[...p,...J.filter(j=>!p.some(V=>V.url===j.url))];if(p.length===0){const j=Rn(H);Me(j),$n(j)}return H})}).catch(()=>{}),ne("")}catch(n){if(an.current!==e)return;Be(!1),ne(n instanceof Error?n.message:"Failed to load streams.")}},[r,s,E,m,S,v,x,Bt,ge,K,Rn,$n,mr,hr,M,cn,dn,$e,u,l]),On=C(()=>{const e=c.current;e&&!isNaN(e.currentTime)&&(X.current=e.currentTime)},[c]),ss=C(e=>{if(!(l||u&&e==="Embed")){if(e==="Embed"){tt(!0);return}On(),tt(!1),Et(e);try{R.setItem("tvServer",e)}catch{}ne("")}},[On,l,u]),as=C(e=>{Ge(e);try{R.setItem("tvProvider",e)}catch{}},[]);y(()=>{E&&r&&!x&&mn()},[E,r,mn,x]),y(()=>{if(ft){i.engine.unload();return}if(!c.current)return;if(z.current=null,x||Ne||u&&U[Ee]?.type!=="hls"){i.engine.unload();return}if(he&&!u)return i.engine.loadSource({url:"/av-sync-test.mp4"},{autoPlay:!on.current});if(Qt.current!=null&&(X.current=Qt.current,Qt.current=null),Le===$e&&X.current==null&&!on.current)try{const p=c.current;p&&!p.ended&&p.currentTime>1&&(X.current=p.currentTime)}catch{}const n=X.current??0,o=!de&&Le===$e?Ne?"":U[Ee]?.url||"":"";if(!o){try{c.current?.pause(),c.current?.removeAttribute("src"),c.current?.load()}catch{}return}const d=c.current;d.pause(),d.removeAttribute("src"),d.load(),i.actions.resetMediaState();const h=`/api/tv/stream-proxy?url=${encodeURIComponent(o)}&referer=${encodeURIComponent(Fe)}&provider=${encodeURIComponent(E)}`,T=co()||document.body.classList.contains("low-end"),$=T?60:180,B=i.engine.loadSource({url:h,hls:U[Ee]?.type==="hls"},{hlsConfig:{enableWorker:!0,lowLatencyMode:!1,startPosition:n>0?n:-1,maxBufferLength:$,maxMaxBufferLength:$+(T?30:60),backBufferLength:T?30:60,maxBufferSize:(T?120:360)*1e3*1e3,fragLoadPolicy:{default:{maxTimeToFirstByteMs:15e3,maxLoadTimeMs:45e3,timeoutRetry:{maxNumRetry:2,retryDelayMs:0,maxRetryDelayMs:0},errorRetry:{maxNumRetry:3,retryDelayMs:800,maxRetryDelayMs:6e3}}},manifestLoadPolicy:{default:{maxTimeToFirstByteMs:1e4,maxLoadTimeMs:25e3,timeoutRetry:{maxNumRetry:1,retryDelayMs:500,maxRetryDelayMs:2e3},errorRetry:{maxNumRetry:2,retryDelayMs:800,maxRetryDelayMs:4e3}}}},onHls:(p,H)=>{z.current=p;const j=()=>{let D=!1,P=0;try{D=R.getItem("tvSubtitlesEnabled")==="true";const N=parseInt(R.getItem("tvSelectedSubtitle")||"0",10);!isNaN(N)&&N>=0&&(P=N)}catch{}return{enabled:D,index:P}},V=()=>{if(typeof p.subtitleTrack!="number")return;if(oe.current.length>0){p.subtitleTrack=-1;return}const D=Array.isArray(p.subtitleTracks)?p.subtitleTracks:[];if(D.length===0){p.subtitleTrack=-1;return}const P=j();if(P.enabled){const N=P.index<D.length?P.index:0;p.subtitleTrack=N,Me(N),Nn()}else p.subtitleTrack=-1};io(p,H.Events,{getWant:()=>xt.current,onResolve:D=>Ct(D)}),p.on(H.Events.MANIFEST_PARSED,V),p.on(H.Events.SUBTITLE_TRACKS_UPDATED,()=>{V()}),p.on(H.Events.SUBTITLE_TRACK_SWITCH,(D,P)=>{if(oe.current.length>0){if(P.id!==-1)try{p.subtitleTrack=-1}catch{}return}const N=Array.isArray(p.subtitleTracks)?p.subtitleTracks:[];if(N.length!==0){if(P.id===-1){const Ce=j();if(Ce.enabled){const se=Ce.index<N.length?Ce.index:0;p.subtitleTrack=se;return}}Me(P.id),Nn()}})},onReady:()=>{(n>0||!on.current&&ln.current)&&i.engine.play()},onError:p=>{ne(p.message),Be(!1),z.current=null}}),J=()=>{const j=d.error?.code===4?"Video source not supported or not found":"Failed to load video stream";ne(`${j}. The source may be invalid or expired. Try switching source or reloading.`),Be(!1)};return d.addEventListener("error",J),()=>{B(),z.current=null,d.removeEventListener("error",J)}},[U,Le,de,Ee,E,Fe,x,Ne,c,Qt,he,G,m,S,Mn,Nn,i.actions,i.engine,$e,u,ft]),y(()=>{if(l||!$t||We||ht||Dt||x||he)return;const e=c.current;!e||!e.paused||e.ended||e.readyState<1||(Mn(),i.engine.play())},[$t,We,ht,Dt,x,he,Mn,c,l,i.engine]),y(()=>{const e=z.current;!e||typeof e.audioTrack!="number"||(e.audioTrack=_e)},[_e]),y(()=>{const e=z.current;!e||typeof e.subtitleTrack!="number"||!Array.isArray(e.subtitleTracks)||e.subtitleTracks.length===0||oe.current.length>0||(ue>=0?e.subtitleTrack=ue:e.subtitleTrack=-1)},[ue]),y(()=>{const e=c.current;if(!(!e||x)&&(e.querySelectorAll("track").forEach(n=>n.remove()),oe.current=[],Te.length!==0&&(Te.forEach(n=>{const o=document.createElement("track");o.kind="subtitles",o.label=n.label||n.language||"Unknown",o.srclang=n.language||n.label||"en";const d=`/api/subtitle-proxy?url=${encodeURIComponent(n.url)}&referer=${encodeURIComponent(Fe)}`;o.src=d,o.addEventListener("load",()=>{const h=oe.current.indexOf(o),T=o.track;if(T&&h>=0){const $=h===dt.current;T.mode=$&&!En.current?"showing":"hidden"}}),e.appendChild(o),oe.current.push(o)}),Te.length>0)))try{const n=z.current;n&&typeof n.subtitleTrack=="number"&&n.subtitleTrack!==-1&&(n.subtitleTrack=-1)}catch{}},[Te,Fe,x,E,K,c]),y(()=>{const e=c.current;if(!e||x)return;const n=z.current;oe.current.length>0&&n&&typeof n.subtitleTrack=="number"&&Array.isArray(n.subtitleTracks)&&n.subtitleTracks.length>0&&(n.subtitleTrack=-1);const o=()=>{const T=Gn(i.state.subtitleFontSize,e.clientHeight||720),$=Math.max(0,Math.min(100,100-i.state.subtitlePosition)),B=()=>{const V=T*16,D=e.videoHeight||e.clientHeight||720,P=e.videoWidth||e.clientWidth||1280;return{step:V*1.3/D*100,chars:Math.max(20,Math.floor(P/(V*.55)))}},J=(V,D)=>{const P=V;P.snapToLines=!1,P.line=D},p=V=>{if(!V.cues)return;Array.from(V.cues).forEach(se=>J(se,$));const D=Array.from(V.activeCues??[]);if(D.length<=1){D.forEach(se=>J(se,$));return}const{step:P,chars:N}=B();let Ce=$;for(let se=D.length-1;se>=0;se--){const Ye=String(D[se].text??"").replace(/<[^>]*>/g,"").split(`
|
|
3
|
-
`).reduce((bn,zt)=>bn+Math.max(1,Math.ceil(zt.length/N)),0);Ce=Math.max(0,Ce-Ye*P),J(D[se],Ce),Ce-=P*.4}},H=oe.current;if(H.length>0){H.forEach((V,D)=>{const P=V.track;if(!P)return;const N=D===ue;P.mode=N&&!ye?"showing":"hidden",N&&!ye&&p(P)});return}const j=Array.from(e.textTracks);j.length!==0&&j.forEach((V,D)=>{const P=D===ue;V.mode=P&&!ye?"showing":"hidden",P&&!ye&&p(V)})};o();const d=()=>o();e.textTracks.addEventListener("addtrack",d),e.addEventListener("loadedmetadata",o,{once:!0});const h=window.setTimeout(o,600);return()=>{e.textTracks.removeEventListener("addtrack",d),e.removeEventListener("loadedmetadata",o),window.clearTimeout(h)}},[ue,Te,x,E,c,ye,i.state.subtitleFontSize,i.state.subtitlePosition]),y(()=>{if(!ye)return;const e=c.current,n=At.current;if(!e||!n)return;const o=ut/1e3,d=_n/1e3,h=new Set;let T=[],$=-1,B=-1,J=-1,p=-1,H=0,j=0,V=!1;const D=()=>{const W=dt.current;if(W<0)return null;const je=oe.current;return je.length>0?je[W]?.track??null:Array.from(e.textTracks)[W]??null},P=(W,je)=>{const be=W.cues;if(!be||be.length===0)return Array.from(W.activeCues??[]);let rt=0,st=be.length;for(;rt<st;){const Ie=rt+st>>>1;be[Ie].endTime+o<je?rt=Ie+1:st=Ie}const qt=[];for(let Ie=rt;Ie<be.length;Ie++){const fn=be[Ie];if(fn.startTime+o>je)break;fn.endTime+o>=je&&qt.push(fn)}return qt},N=()=>{const W=D(),je=e.currentTime-d,be=W?P(W,je):[],rt=e.clientWidth,st=e.clientHeight,qt=e.videoWidth,Ie=e.videoHeight;if(be.length===T.length&&be.every((Vn,Fn)=>Vn===T[Fn])&&rt===$&&st===B&&qt===J&&Ie===p||(T=be,$=rt,B=st,J=qt,p=Ie,n.textContent="",be.length===0))return;const Sr={fontSize:Gn(i.state.subtitleFontSize,st),position:i.state.subtitlePosition,bgOpacity:i.state.subtitleBgOpacity,bgColor:i.state.subtitleBgColor,textColor:i.state.subtitleTextColor,edge:i.state.subtitleEdge,bold:i.state.subtitleBold},cs=Vs(Sr),ds=Fs(e,Sr.position);be.forEach((Vn,Fn)=>{const _r=String(Vn.text??"");if(!Us(_r).trim())return;const Un=document.createElement("div"),us=(be.length-1-Fn)*1.7;Un.style.cssText=`${cs}
|
|
4
|
-
bottom: calc(${ds}px + ${us}em);`,Un.innerHTML=Hs(_r),n.appendChild(Un)})},Ce=()=>{Array.from(e.textTracks).forEach(W=>{h.has(W)||(h.add(W),W.addEventListener("cuechange",N))})},se=()=>{Ce(),N()},qn=()=>{if(V||j)return;const W=()=>{j=0,!(V||e.paused||e.ended)&&(N(),qn())};j=window.requestAnimationFrame(W)},Ye=e,bn=()=>{H=0,N(),!V&&Ye.requestVideoFrameCallback&&(H=Ye.requestVideoFrameCallback(bn))},zt=()=>{N(),Ye.requestVideoFrameCallback?H||(H=Ye.requestVideoFrameCallback(bn)):qn()};Ce(),e.textTracks.addEventListener("addtrack",se),e.textTracks.addEventListener("removetrack",se),e.addEventListener("timeupdate",N),e.addEventListener("seeked",N),e.addEventListener("loadedmetadata",N),e.addEventListener("play",zt);const gr=Array.from(e.querySelectorAll("track"));gr.forEach(W=>W.addEventListener("load",N));const yr=typeof ResizeObserver>"u"?null:new ResizeObserver(()=>N());return yr?.observe(e),N(),zt(),()=>{V=!0,h.forEach(W=>W.removeEventListener("cuechange",N)),e.textTracks.removeEventListener("addtrack",se),e.textTracks.removeEventListener("removetrack",se),e.removeEventListener("timeupdate",N),e.removeEventListener("seeked",N),e.removeEventListener("loadedmetadata",N),e.removeEventListener("play",zt),gr.forEach(W=>W.removeEventListener("load",N)),yr?.disconnect(),j&&window.cancelAnimationFrame(j),H&&Ye.cancelVideoFrameCallback&&Ye.cancelVideoFrameCallback(H),n.textContent=""}},[ye,ut,ue,Te,_n,c,i.state.subtitleFontSize,i.state.subtitlePosition,i.state.subtitleBgOpacity,i.state.subtitleBgColor,i.state.subtitleTextColor,i.state.subtitleEdge,i.state.subtitleBold]);const zn=()=>{L(null),Q([]),Ue(""),A(-1)},os=C(e=>{l||(Z(e),pe(1),we(e,1))},[we,l]),hn=!v&&r?.seasons&&r.seasons.length>1?t("label",{className:f.sidebarSeason,children:[t("span",{children:"Season"}),t("select",{disabled:l,value:m,onChange:e=>os(parseInt(e.currentTarget.value,10)||1),className:f.select,children:r.seasons.map(e=>t("option",{value:e.season_number,children:["Season ",e.season_number," (",e.episode_count," ep)"]},e.season_number))})]}):null,pt=C(e=>{if(l)return;const n=parseInt(e,10);if(!isNaN(n)){try{c.current?.pause()}catch{}pe(n),we(m,n)}An(!1)},[m,we,c,l]);y(()=>{if(v)return;const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="n"&&(q!=null?pt(String(q)):Tr.error("No next episode available"))};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[v,q,pt]);const is=e=>{Ct(e);try{const o=Tt[e];o&&R.setItem("tvLastAudio",Wn(o))}catch{}const n=z.current;n&&n.audioTrack!==void 0&&(n.audioTrack=e)},ls=e=>{Me(e);try{if(e===-1)R.setItem("tvSubtitlesEnabled","false");else{R.setItem("tvSubtitlesEnabled","true"),R.setItem("tvSelectedSubtitle",String(e));const h=Te[e];h&&R.setItem("tvLastSubtitle",Wn(h))}}catch{}const n=c.current,o=z.current;if(o&&typeof o.subtitleTrack=="number"&&Array.isArray(o.subtitleTracks)&&o.subtitleTracks.length>0&&(o.subtitleTrack=oe.current.length>0||e<0?-1:e),!n)return;const d=oe.current;if(d.length>0){d.forEach((h,T)=>{const $=h.track;if(!$)return;const B=T===e;$.mode=B&&!ye?"showing":"hidden"});return}Array.from(n.textTracks).forEach((h,T)=>{const $=T===e;h.mode=$&&!ye?"showing":"hidden"})};return y(()=>{if(!r){document.title="TV & Movies - dango";return}document.title=v?`${r.title} - dango`:`${r.title} - Season ${m} Episode ${S} - dango`},[r,v,m,S]),y(()=>{if(!r||v)return;const e=new URLSearchParams(b),n=e.get("s"),o=e.get("e"),d=String(m),h=String(S);n===d&&o===h||(e.set("type",b.get("type")||"tv"),e.set("s",d),e.set("e",h),A(`${window.location.pathname}?${e.toString()}`,{replace:!0}))},[r,v,m,S,b,A]),t("div",{className:`${xe.playerPageLayout} ${Oe?xe.theaterMode:""} ${v?xe.noSidebar:""}`,onClick:Ur,children:[Oe&&t(Ws,{videoRef:c,active:kn.enabled&&!x&&U.length>0&&!Pe&&!(r?.adult&&!Bt),settings:kn}),!Oe&&!v&&t("aside",{className:xe.episodeSidebar,children:r?t(Ks,{episodes:vr,currentEpisode:String(S),watchedEpisodes:fr,onEpisodeClick:pt,header:hn}):t(Qs,{variant:"sidebar"})}),t("div",{className:xe.playerMain,children:[r&&t("div",{className:f.playerSection,onContextMenu:e=>e.preventDefault(),style:r.adult&&!Bt?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:x&&Ze&&!u?t("iframe",{src:Ze,className:f.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!x&&nt&&!u?t("iframe",{src:nt,className:f.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!x&&(U.length>0||de)?t(qe,{children:[Pe&&t(Er,{error:Pe,onRetry:mn}),t(ro,{player:i,title:r.title,episodeLabel:v?void 0:`S${m} E${S}`,server:ce||lt?.label||E,audioTracks:Tt,selectedAudioTrack:_e,onAudioTrackChange:is,subtitles:Te,selectedSubtitle:ue,onSubtitleChange:ls,streams:U,resolutionIdx:Ee,onResolutionChange:e=>{On(),it(e);try{const n=U[e]?.quality;n&&R.setItem("tvLastQuality",n)}catch{}},onBack:zn,videoDelayEnabled:Kt,onVideoDelayToggle:gn,videoDelayMs:Re,onVideoDelayChange:Lt,onCalibrateAvSync:u?void 0:wr,subtitleDelayMs:ut,onSubtitleDelayChange:Br,showNextEpisodeButton:!l&&Or&&!We&&!ht,onNextEpisode:dr,isLoading:de,isTheaterMode:Oe,onTheaterModeToggle:Bn,ambientSettings:kn,onAmbientChange:Pr,hideChrome:ft,children:t(qe,{children:[t(Ns,{autoPlay:!u&&$t&&!Dt,playsInline:!0,disablePictureInPicture:!0,className:`${f.video} ${Cn?f.videoHidden:""}`,onTimeUpdate:()=>{he||(Xr(),un())},onEnded:()=>{he||un(!0)},onPlay:Zr,onPause:es,onSeeked:()=>{he||(Ot(),un())},onLoadedMetadata:()=>{ts(),lr(),un()},onDurationChange:()=>{lr()},onContextMenu:e=>e.preventDefault(),onError:()=>{ne("Video failed to load. Try another server or reload."),Be(!1)}}),t("canvas",{ref:Wt,className:`${f.delayCanvas} ${Cn?f.delayCanvasActive:""}`}),ye&&t("div",{ref:At,className:f.subtitleOverlay}),t(Ys,{isOpen:yn,ms:Re,onChange:Lt,onApply:xr,onClose:Ir,testClipActive:he,onTestClip:Ar}),ft&&t("div",{className:f.watchedOverlay,children:[t(le,{name:"check-circle",size:48,style:{color:"var(--accent-lighter)"}}),t("p",{className:f.watchedTitle,children:v?"Movie watched":`S${m} E${S} watched`}),t("p",{className:f.watchedSubtext,children:"Replay from the beginning or continue with the next episode."}),t("div",{className:f.watchedActions,children:[t(at,{onClick:Kr,children:"Replay"}),q!=null?t(at,{variant:"secondary",onClick:dr,children:"Next Episode"}):De!=null?t(at,{variant:"secondary",onClick:ur,children:"Next Season"}):null]})]})]})})]}):Pe&&!x?t(Er,{error:Pe,onRetry:mn}):null}),t(va,{playback:jt?{selection:jt,position:c.current?.currentTime||0,playing:!1,rate:i.engine.getState().playbackRate}:null,onCreate:()=>{Sn(),i.engine.pause()},needsPlayback:Xn.needsPlayback,onEnablePlayback:Xn.enablePlayback}),u&&!de&&r&&!jt&&t("p",{role:"alert",children:"The host's direct HLS source is unavailable here. Retry or leave the room to use another source."}),!Oe&&r&&t(js,{}),!Oe&&hn&&t("div",{className:f.mobileSeasonRow,children:hn}),!Oe&&r&&t("div",{className:ie.streamPanel,children:[t("div",{className:f.providerSelectWrap,children:t("label",{className:f.controlLabel,children:["Provider",t("select",{value:E,onChange:e=>as(e.currentTarget.value),className:f.select,disabled:l||Y.length===0,children:_t?t("option",{value:"",children:"Loading..."}):Y.length===0?t("option",{value:"",children:"No providers available"}):t(qe,{children:[I.length>0&&t("optgroup",{label:"Direct HLS",children:I.map(e=>t("option",{value:e.id,children:e.label},e.id))}),te.length>0&&t("optgroup",{label:"Embeds",children:te.map(e=>t("option",{value:e.id,children:e.label},e.id))})]})})]})}),!l&&!x&&(de?t("div",{className:f.sourceLoader,children:t("div",{className:f.ringSpinner})}):t(ao,{servers:Ht,selectedServer:wt?"Embed":K,onServerSelect:ss}))]}),!Oe&&r&&t("div",{className:xe.playerInfoContainer,children:[t("div",{className:xe.playerInfoHeader,children:[t("div",{className:xe.playerAnimeCard,children:r.poster&&t(Ss,{src:`https://image.tmdb.org/t/p/w342${r.poster}`,alt:r.title,loading:"lazy",decoding:"async"})}),t("div",{className:xe.videoTitleSection,children:[t("div",{className:ie.titleContainer,children:[t("h1",{children:r.title}),t("div",{className:f.meta,children:[t("span",{className:f.year,children:r.year}),r.vote_average!=null&&r.vote_average>0&&t("span",{className:f.rating,children:[t(le,{name:"star",size:12}),Number(r.vote_average).toFixed(1)]}),t("span",{className:`${f.typeBadge} ${f[v?"movie":"tv"]}`,children:v?"Movie":"TV Show"})]}),pr.length>0&&t("div",{className:f.genreRow,children:pr.map(e=>t("span",{className:f.genreChip,children:e},e))}),Dn.length>0&&t("div",{className:f.metaRow,children:Dn.map((e,n)=>t("span",{children:[e,n<Dn.length-1?" · ":""]},`${e}-${n}`))})]}),t("div",{className:ie.controls,children:[t("button",{className:`${ie.watchlistBtn} ${Pt?ie.inList:""}`,onClick:Dr,disabled:$r,type:"button",children:[Pt?t(le,{name:"check",size:14}):t(le,{name:"plus",size:14}),Pt?"In Watchlist":"Add to Watchlist"]}),!v&&t(qe,{children:[t("button",{className:`${ie.watchlistBtn}`,onClick:()=>In!=null&&pt(String(In)),disabled:l||In==null,type:"button",children:[t(le,{name:"chevron-left",size:14}),"Prev EP"]}),t("button",{className:`${ie.watchlistBtn}`,onClick:()=>q!=null&&pt(String(q)),disabled:l||q==null,type:"button",children:["Next EP",t(le,{name:"chevron-right",size:14})]}),!v&&t("button",{className:`${ie.watchlistBtn} ${ie.modeToggleBtn} ${vt?ie.modeToggleActive:""}`,onClick:()=>jr(!vt),type:"button","aria-pressed":vt,children:vt?"AUTOPLAY: ON":"AUTOPLAY: OFF"}),Qr&&t("button",{className:`${ie.watchlistBtn}`,onClick:()=>An(!0),type:"button",children:[t(le,{name:"list-ul",size:14}),"Episodes"]})]})]})]})]}),t("div",{className:xe.infoColumns,children:[t("div",{className:`${ie.descriptionSection} ${ie.synopsisFlat}`,children:[t("h3",{children:"Synopsis"}),t(fa,{text:r.overview,emptyText:"No description available."}),t("button",{className:ie.detailsToggleBtn,onClick:()=>Vr(!rn),type:"button",children:[rn?t(le,{name:"chevron-up"}):t(le,{name:"chevron-down"}),rn?"Hide Details":"Show Details"]})]}),rn&&t("div",{className:f.detailGrid,children:[r.first_air_date&&t("div",{className:f.detailItem,children:[t("strong",{children:v?"Release Date":"First Air Date"}),t("span",{children:r.first_air_date})]}),r.last_air_date&&t("div",{className:f.detailItem,children:[t("strong",{children:"Last Air Date"}),t("span",{children:r.last_air_date})]}),r.networks&&r.networks.length>0&&t("div",{className:f.detailItem,children:[t("strong",{children:"Networks"}),t("span",{children:r.networks.map(e=>e.name).join(", ")})]}),r.created_by&&r.created_by.length>0&&t("div",{className:f.detailItem,children:[t("strong",{children:"Created By"}),t("span",{children:r.created_by.map(e=>e.name).join(", ")})]}),r.episode_run_time&&r.episode_run_time.length>0&&t("div",{className:f.detailItem,children:[t("strong",{children:"Episode Runtime"}),t("span",{children:[r.episode_run_time[0]," min"]})]}),r.imdb_id&&t("div",{className:f.detailItem,children:[t("strong",{children:"IMDb"}),t("a",{href:`https://www.imdb.com/title/${r.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:f.imdbLink,children:"View on IMDb"})]})]})]})]}),!v&&t(Gs,{isOpen:Fr,onClose:()=>An(!1),episodes:vr,currentEpisode:String(S),watchedEpisodes:fr,onEpisodeClick:pt,header:hn}),r?.adult&&!Bt&&t(ra,{isOpen:!0,onClose:zn,onGrant:Mr}),t(Xs,{isOpen:!u&&We&&!wn&&tn.current===`${G}:${m}:${S}`&&He?.completed!==1&&!Vt(en,He?.duration??0),onClose:cr,title:"Resume Watching",message:t(qe,{children:["You were at ",t("strong",{children:Yn(mt)})]}),restartLabel:"Start from Beginning",onResume:ns,onRestart:cr}),t(Js,{isOpen:ht,onClose:()=>bt(!1),title:v?"Movie Completed!":De!=null?"Season Complete!":"Show Completed!",heading:zr,message:v?"You finished this movie!":De!=null?`You finished Season ${m}.`:"Congratulations! You finished all available episodes.",children:[t(at,{variant:"secondary",onClick:()=>bt(!1),children:"Close"}),De!=null?t(at,{onClick:ur,children:["Start Season ",De]}):t(qe,{children:[t(at,{onClick:()=>{bt(!1),zn()},children:"Back to Details"}),t(at,{onClick:rs,disabled:Gt.isPending||Xt.isPending,children:Gt.isPending||Xt.isPending?"Saving...":"Move to Completed"})]})]}),!r&&t("div",{className:f.statusMsg,children:[t(le,{name:"spinner",className:f.spinner})," Loading..."]})]})]})};export{ci as default};
|