@serifpersia/dango 3.7.1 → 3.7.2
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 +2 -2
- package/client/dist/assets/ActiveFilterChips-QjkplDN2.css +1 -0
- package/client/dist/assets/ActiveFilterChips-olGfwxle.js +1 -0
- package/client/dist/assets/AnimeCard-CoPx634q.js +1 -0
- package/client/dist/assets/AnimeInfo-COVCRujg.js +1 -0
- package/client/dist/assets/AnimeInfoPage-BwlKpRXY.js +2 -0
- package/client/dist/assets/{AnimeMetaDetails-BogOi_bM.js → AnimeMetaDetails-D8WIiO4b.js} +1 -1
- package/client/dist/assets/Asmr-Dl1EZqaI.css +1 -0
- package/client/dist/assets/Asmr-nOUcDsWe.js +2 -0
- package/client/dist/assets/AsmrResetProgressModal-Mj1PYE2c.js +1 -0
- package/client/dist/assets/AvSyncCalibrator-BtUHM1mW.css +1 -0
- package/client/dist/assets/AvSyncCalibrator-C5GxpyPE.js +10 -0
- package/client/dist/assets/Home-C5eTe3jP.css +1 -0
- package/client/dist/assets/Home-wi0a_BDQ.js +1 -0
- package/client/dist/assets/Insights-D0qrep0K.css +1 -0
- package/client/dist/assets/Insights-MLCDyTnY.js +1 -0
- package/client/dist/assets/LibraryListPage-CRqv737t.js +1 -0
- package/client/dist/assets/LibraryListPage-DmdjNa2U.css +1 -0
- package/client/dist/assets/LibraryListPage.module-r6k9nyT9.js +1 -0
- package/client/dist/assets/ListeningList-8dzhiDeb.js +1 -0
- package/client/dist/assets/Manga-dkD-uWJk.js +1 -0
- package/client/dist/assets/MangaInfoPage-nCeWZNcO.js +1 -0
- package/client/dist/assets/MangaReadPage-NdDNCyLg.js +1 -0
- package/client/dist/assets/MangaResetProgressModal-C28AiLJl.js +1 -0
- package/client/dist/assets/Mature-D5WSkhIJ.js +1 -0
- package/client/dist/assets/MatureConsentModal-BsdpNeXA.js +1 -0
- package/client/dist/assets/MatureConsentModal-CqewXc0q.css +1 -0
- package/client/dist/assets/MediaCard-B0PJStxp.css +1 -0
- package/client/dist/assets/MediaCard-C1jNesfK.js +1 -0
- package/client/dist/assets/OptionListMenu-CIvW5WmO.js +1 -0
- package/client/dist/assets/Player-D-sQfjcx.css +1 -0
- package/client/dist/assets/Player-PGj8YYO8.js +56 -0
- package/client/dist/assets/{PlayerSettings-CqgKYfAN.js → PlayerSettings-CAYfF0sA.js} +1 -1
- package/client/dist/assets/QueueOptionsButton-DNzKPzPw.js +1 -0
- package/client/dist/assets/QueueRail-BWcDVSHd.js +1 -0
- package/client/dist/assets/{QueueRail-BUYEjdaq.css → QueueRail-Bkh4VZls.css} +1 -1
- package/client/dist/assets/ReadingList-zkFp3wpF.js +1 -0
- package/client/dist/assets/ResetProgressModal-BYNYqwwl.js +1 -0
- package/client/dist/assets/Search-DCKK3seW.css +1 -0
- package/client/dist/assets/Search-yDP_wGJ1.js +1 -0
- package/client/dist/assets/Search.module-C_qwCdHS.js +1 -0
- package/client/dist/assets/Settings-BEHII_8K.css +1 -0
- package/client/dist/assets/Settings-BpKwWesn.js +21 -0
- package/client/dist/assets/SkeletonGrid-BisPI38I.css +1 -0
- package/client/dist/assets/SkeletonGrid-CYJeh04P.js +1 -0
- package/client/dist/assets/Trackers-D2KUt71k.js +2 -0
- package/client/dist/assets/Tv-D3vXCsSC.css +1 -0
- package/client/dist/assets/Tv-Ul3jFq-x.js +4 -0
- package/client/dist/assets/TvInfo-D_4QdgV4.js +1 -0
- package/client/dist/assets/TvPopup-DHXB5ZSF.js +1 -0
- package/client/dist/assets/TvSearch-COwVoGru.js +1 -0
- package/client/dist/assets/TvWatchlist-CU3r-NO5.js +1 -0
- package/client/dist/assets/VirtualKeyboard-BaUll8Yv.css +1 -0
- package/client/dist/assets/VirtualKeyboard-DeP7fb3P.js +1 -0
- package/client/dist/assets/Watchlist-DHyuTLJG.js +1 -0
- package/client/dist/assets/Watchlist-DW7kUORr.css +1 -0
- package/client/dist/assets/{hls-CdJTQ6Lc.js → hls-DOAVt6Ry.js} +1 -1
- package/client/dist/assets/index-B7katXv0.css +1 -0
- package/client/dist/assets/index-BLh_CXtu.js +178 -0
- package/client/dist/assets/libraryInvalidation-AzFLnbjH.js +1 -0
- package/client/dist/assets/playbackCompletion-DuUs8u-8.js +1 -0
- package/client/dist/assets/useAnimeInfoData-MPNJXLaM.js +1 -0
- package/client/dist/assets/useAsmr-2dFEmQD_.js +1 -0
- package/client/dist/assets/useAsmrPopup-N2vUf3Pw.js +1 -0
- package/client/dist/assets/useMangaLibrary-B3Ni34a7.js +1 -0
- package/client/dist/assets/useMangaPopup-h8NHEPUk.js +1 -0
- package/client/dist/assets/useProviders-z8L8GKy0.js +1 -0
- package/client/dist/assets/useTv-D4zQ1BsQ.js +1 -0
- package/client/dist/assets/useTvLibrary-B4vcRzQc.js +1 -0
- package/client/dist/index.html +2 -2
- package/orchestrator.js +1 -1
- package/package.json +6 -4
- package/server/dist/server.js +344 -372
- package/server/package.json +2 -1
- package/client/dist/assets/AnimeCard-DSC8cos-.js +0 -1
- package/client/dist/assets/AnimeInfo-BHj_zyLA.js +0 -1
- package/client/dist/assets/AnimeInfoPage-QCfx0BSB.js +0 -2
- package/client/dist/assets/Asmr-DzdvD9rp.js +0 -2
- package/client/dist/assets/AsmrResetProgressModal-BMi8sNRK.js +0 -1
- package/client/dist/assets/AvSyncCalibrator-BI6-WMwv.js +0 -10
- package/client/dist/assets/AvSyncCalibrator-ZSpMgUid.css +0 -1
- package/client/dist/assets/Home-BTuHZIu5.js +0 -1
- package/client/dist/assets/Home-DeY8zvfI.css +0 -1
- package/client/dist/assets/Insights-Dc8xLmsr.css +0 -1
- package/client/dist/assets/Insights-DcENcCT3.js +0 -1
- package/client/dist/assets/LibraryListPage-CHJTM02k.js +0 -1
- package/client/dist/assets/ListeningList-BMCy3Xma.js +0 -1
- package/client/dist/assets/Manga-Bh8UBkW8.js +0 -1
- package/client/dist/assets/MangaInfoPage-Xf1v-kOS.js +0 -1
- package/client/dist/assets/MangaReadPage-BktwU4Z6.js +0 -1
- package/client/dist/assets/MangaResetProgressModal-D4AFduYZ.js +0 -1
- package/client/dist/assets/Mature-0t7mUuKs.js +0 -1
- package/client/dist/assets/MediaCard-Ck-VFldj.js +0 -1
- package/client/dist/assets/MediaCard-DB6Yjgky.css +0 -1
- package/client/dist/assets/OptionListMenu-6grp_X7Q.js +0 -1
- package/client/dist/assets/Player-BMsolf38.js +0 -56
- package/client/dist/assets/Player-DCB994_8.css +0 -1
- package/client/dist/assets/QueueOptionsButton-1BIDVRnc.js +0 -1
- package/client/dist/assets/QueueRail-Dtqs6-Cj.js +0 -1
- package/client/dist/assets/ReadingList-CFu3SJg6.js +0 -1
- package/client/dist/assets/ResetProgressModal-DDLhwvu_.js +0 -1
- package/client/dist/assets/Search-Cs45oAwI.css +0 -1
- package/client/dist/assets/Search-DH17j8Mu.js +0 -1
- package/client/dist/assets/Search.module-CMEai-B-.js +0 -1
- package/client/dist/assets/Settings-CS2RnS22.js +0 -21
- package/client/dist/assets/Settings-CwIWLSfY.css +0 -1
- package/client/dist/assets/SkeletonGrid-Bge3aRl2.css +0 -1
- package/client/dist/assets/SkeletonGrid-j41CQ_eq.js +0 -1
- package/client/dist/assets/Trackers-DiwSfbK5.js +0 -2
- package/client/dist/assets/Tv-Bdruknna.css +0 -1
- package/client/dist/assets/Tv-Ko75Tjxy.js +0 -4
- package/client/dist/assets/TvInfo-B5OSSyav.js +0 -1
- package/client/dist/assets/TvPopup-Lnu1Dmx3.js +0 -1
- package/client/dist/assets/TvSearch-BYknb0BD.js +0 -1
- package/client/dist/assets/TvWatchlist-Bb9EnbIC.js +0 -1
- package/client/dist/assets/VirtualKeyboard-BmqZPZXR.js +0 -1
- package/client/dist/assets/VirtualKeyboard-KIPc5ZGH.css +0 -1
- package/client/dist/assets/Watchlist-BiDEU0iV.css +0 -1
- package/client/dist/assets/Watchlist-BuRda78R.js +0 -1
- package/client/dist/assets/Watchlist.module-XGtVQr1d.js +0 -1
- package/client/dist/assets/index-C9FfV5Fg.js +0 -178
- package/client/dist/assets/index-D0Haw_Zl.css +0 -1
- package/client/dist/assets/useAnimeInfoData-8nSxobwT.js +0 -1
- package/client/dist/assets/useAsmr-Cwcgsq-Y.js +0 -1
- package/client/dist/assets/useAsmrPopup-D1KuQwQy.css +0 -1
- package/client/dist/assets/useAsmrPopup-pj0IVP6Q.js +0 -1
- package/client/dist/assets/useMangaLibrary-C8eMKmfr.js +0 -1
- package/client/dist/assets/useMangaPopup-BIQGwv4w.js +0 -1
- package/client/dist/assets/useProviders-DvEWO7KK.js +0 -1
- package/client/dist/assets/useTv-DZzw1cpP.js +0 -1
- package/client/dist/assets/useTvLibrary-DnAI4fMY.js +0 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import{d as s,A as j,h as O,u as e,q as le,S as Ne,T as Te,p as xe,g as ue,_ as Ie}from"./vendor-core-DfaOB3Rn.js";import{d as Le,D as pe,t as b,B as T,M as E,k as ye,i as Re,A as he,H as V,q as $,I as ge,J as Pe,K as De,T as Ae,u as Oe,e as Ge,L as qe,C as ne,V as Me,N as ze}from"./index-BLh_CXtu.js";import{u as ce}from"./vendor-query-BBT5_sHx.js";import{T as K}from"./ToggleSwitch-CN_ppEc9.js";import{I as X}from"./vendor-icons-DrybRNxP.js";const se={"title-preference-container":"_title-preference-container_sdqgs_1","toggle-button":"_toggle-button_sdqgs_21","toggle-label":"_toggle-label_sdqgs_51"},re=["name","nativeName","englishName"],ie={name:"Default (Romaji)",nativeName:"Native",englishName:"English"},Ue=()=>{const{titlePreference:t,setTitlePreference:r,loading:o}=Le(),c=pe(),[l,f]=s(ie[t]),[v,m]=s(!1),a=j(null);O(()=>{o||f(ie[t])},[t,o]);const i=async()=>{if(v)return;m(!0);const p=(re.indexOf(t)+1)%re.length,d=re[p],x=ie[d];a.current&&(a.current.style.transform="translateX(-100%)",a.current.style.opacity="0"),setTimeout(async()=>{f(x),r(d),a.current&&(a.current.style.transition="none",a.current.style.transform="translateX(100%)",a.current.style.opacity="0",a.current.offsetWidth,a.current.style.transition="transform 0.3s ease-out, opacity 0.3s ease-out",a.current.style.transform="translateX(0)",a.current.style.opacity="1");try{await c.mutateAsync({key:"titlePreference",value:d})}catch(h){console.error("Error saving title preference:",h)}finally{m(!1)}},300)};return o?e("p",{children:"Loading title preference..."}):e("div",{className:se["title-preference-container"],children:[e("h4",{children:"Anime Title Display Preference"}),e("button",{onClick:i,className:se["toggle-button"],disabled:v,children:e("span",{ref:a,className:se["toggle-label"],children:l})})]})},Ee="_settingsHeader_1p8qx_1",Fe="_pageTitle_1p8qx_6",Ke="_pageSubtitle_1p8qx_14",$e="_settingsLayout_1p8qx_20",He="_sidebar_1p8qx_27",We="_sidebarIndicator_1p8qx_35",Be="_sidebarItem_1p8qx_50",Ve="_active_1p8qx_72",je="_mainContent_1p8qx_80",Qe="_tabContent_1p8qx_85",Ye="_settingItem_1p8qx_95",Je="_controls_1p8qx_100",Xe="_status_1p8qx_106",S={settingsHeader:Ee,pageTitle:Fe,pageSubtitle:Ke,settingsLayout:$e,sidebar:He,sidebarIndicator:We,sidebarItem:Be,active:Ve,mainContent:je,tabContent:Qe,settingItem:Ye,controls:Je,status:Xe},Ze="_title_tm30b_11",et="_signIn_tm30b_18",tt="_userInfo_tm30b_25",at="_warning_tm30b_47",nt="_formGroup_tm30b_54",st="_label_tm30b_58",rt="_inputWrapper_tm30b_68",it="_input_tm30b_68",ot="_select_tm30b_92",lt="_actions_tm30b_109",ct="_hr_tm30b_117",g={title:Ze,signIn:et,userInfo:tt,warning:at,formGroup:nt,label:st,inputWrapper:rt,input:it,select:ot,actions:lt,hr:ct},dt="_sectionCard_1axuo_1",ut="_dangerCard_1axuo_23",ht="_settingRow_1axuo_31",N={sectionCard:dt,dangerCard:ut,settingRow:ht},gt=()=>{const[t,r]=s(!0),[o,c]=s(!1),[l,f]=s(!1),[v,m]=s(null),[a,i]=s({status:"idle"}),[u,p]=s(!1),[d,x]=s(""),[h,k]=s(!1),I=j(null),[L,R]=s({show:!1,message:"",type:"info"}),A=()=>{I.current&&(window.clearInterval(I.current),I.current=null)},w=le(y=>{f(y.authenticated),m(y.user||y.device.user||null),i(y.device),p(!!y.hasCustomClientId)},[]),C=le(async()=>{const y=await b.auth.githubStatus.query();w(y)},[w]),G=async()=>{try{const y=await b.auth.githubPoll.query();i(y),y.status==="success"?(A(),await C(),R({show:!0,message:"GitHub authentication complete. Sync has been initialized.",type:"success"})):y.status==="error"&&(A(),R({show:!0,message:y.error||"GitHub authentication failed.",type:"error"}))}catch{A(),R({show:!0,message:"Failed to poll GitHub authentication status.",type:"error"})}},M=(y=5)=>{A(),I.current=window.setInterval(G,Math.max(y,5)*1e3)};O(()=>(C().catch(()=>{R({show:!0,message:"Failed to load GitHub sync status.",type:"error"})}).finally(()=>r(!1)),A),[C]);const _=async()=>{c(!0);try{const y=await b.auth.githubStart.mutate();i(y),M(y.verification?.interval)}catch(y){R({show:!0,message:y instanceof Error?y.message:"Failed to start GitHub authentication.",type:"error"})}finally{c(!1)}},D=async()=>{try{await b.auth.githubLogout.mutate(),f(!1),m(null),i({status:"idle"}),R({show:!0,message:"Signed out of GitHub sync.",type:"success"})}catch{R({show:!0,message:"Failed to sign out of GitHub.",type:"error"})}},z=async()=>{k(!0);try{await b.auth.saveGithubAuth.mutate({clientId:d}),x(""),await C(),R({show:!0,message:"Custom GitHub auth saved.",type:"success"})}catch{R({show:!0,message:"Failed to save override.",type:"error"})}finally{k(!1)}},W=async()=>{k(!0);try{await b.auth.saveGithubAuth.mutate({clientId:""}),x(""),await C(),R({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{R({show:!0,message:"Failed to clear override.",type:"error"})}finally{k(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:N.sectionCard,children:[e("h3",{className:g.title,children:"GitHub Cloud Sync"}),e("p",{className:g.signIn,children:"Sync local data through a private GitHub repository named dango-sync-data."}),l&&v?e("div",{className:g.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:v.name||v.login})]}),e(T,{variant:"danger",onClick:D,children:"Sign Out"})]}):e("div",{className:g.signIn,children:e(T,{onClick:_,disabled:o||a.status==="pending",children:o||a.status==="pending"?"Waiting for GitHub...":"Sign in with GitHub"})}),a.status==="pending"&&a.verification&&e(Ne,{children:[e("hr",{className:g.hr}),e("div",{className:g.formGroup,children:[e("label",{className:g.label,children:"Verification URL"}),e("div",{className:g.inputWrapper,children:[e("input",{className:g.input,value:a.verification.verification_uri,readOnly:!0}),e(T,{onClick:()=>{const y=a.verification?.verification_uri;y&&/^https?:\/\//i.test(y)&&window.open(y,"_blank","noopener,noreferrer")},children:"Open"})]})]}),e("div",{className:g.formGroup,children:[e("label",{className:g.label,children:"Device Code"}),e("input",{className:g.input,value:a.verification.user_code,readOnly:!0})]})]}),a.status==="error"&&e("p",{className:g.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 ",u?"(override active)":""]}),e("div",{className:g.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:g.label,children:"Client ID (optional)"}),e("input",{className:g.input,value:d,onChange:y=>x(y.currentTarget.value),placeholder:"Your GitHub OAuth app ID"})]}),e("div",{className:g.actions,children:[e(T,{onClick:z,disabled:h,children:"Save override"}),e(T,{variant:"secondary",onClick:W,disabled:h,children:"Use dango defaults"})]})]}),e(E,{isOpen:L.show,onClose:()=>R(y=>({...y,show:!1})),width:"sm",children:[e(E.Body,{children:e("p",{children:L.message})}),e(E.Actions,{children:e(T,{onClick:()=>R(y=>({...y,show:!1})),children:"OK"})})]})]})},mt=()=>{const[t,r]=s(!0),[o,c]=s(null),[l,f]=s(!1),[v,m]=s(!1),[a,i]=s(""),[u,p]=s(""),[d,x]=s(""),[h,k]=s(!1),[I,L]=s({show:!1,message:"",type:"info"}),R=async()=>{try{const D=await b.auth.user.query();c(D?.email?D:null)}catch{c(null)}},A=async()=>{try{const[_,D]=await Promise.all([b.auth.configStatus.query(),b.auth.googleAuth.query()]);f(!!_.hasConfig),m(!!(D.hasCustomWorkerUrl||D.hasCustomClientId||D.hasClientSecret))}catch(_){console.error("Failed to fetch config status",_)}};O(()=>{(async()=>{r(!0),await Promise.all([R(),A()]);try{new URLSearchParams(window.location.search).get("google_auth")==="success"&&(await R(),window.history.replaceState(null,"",window.location.pathname))}catch{}r(!1)})();const D=z=>{z.origin===window.location.origin&&typeof z.data=="object"&&z.data!==null&&z.data.type==="GOOGLE_AUTH_SUCCESS"&&(c(z.data.user),window.location.reload())};return window.addEventListener("message",D),()=>window.removeEventListener("message",D)},[]);const w=async()=>{try{const _=await b.auth.googleLogin.mutate();if(_.authenticated){window.location.reload();return}if(_.url){if(typeof window.DangoBridge<"u"){window.location.href=_.url;return}const z=600,W=700,y=window.innerWidth/2-z/2,Z=window.innerHeight/2-W/2;window.open(_.url,"GoogleAuth",`width=${z},height=${W},top=${Z},left=${y}`)}else throw new Error("Auth URL not available")}catch{L({show:!0,message:"Authentication failed. Ensure server is configured correctly.",type:"error"})}},C=async()=>{try{await b.auth.logout.mutate(),c(null),L({show:!0,message:"Successfully signed out.",type:"success"}),window.location.reload()}catch(_){console.error("Sign out failed",_),L({show:!0,message:"Failed to sign out.",type:"error"})}},G=async()=>{k(!0);try{await b.auth.saveGoogleAuth.mutate({workerUrl:a,clientId:u,clientSecret:d}),i(""),p(""),x(""),await A(),L({show:!0,message:"Custom auth saved. Restart may be required.",type:"success"})}catch{L({show:!0,message:"Failed to save override.",type:"error"})}finally{k(!1)}},M=async()=>{k(!0);try{await b.auth.saveGoogleAuth.mutate({workerUrl:"",clientId:"",clientSecret:""}),i(""),p(""),x(""),await A(),L({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{L({show:!0,message:"Failed to clear override.",type:"error"})}finally{k(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:N.sectionCard,children:[e("h3",{className:g.title,children:"Google Drive Sync"}),o?e("div",{className:g.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:o.name})," (",o.email,")"]}),e(T,{variant:"danger",onClick:C,children:"Sign Out"})]}):e("div",{className:g.signIn,children:[e("p",{children:"Sign in with your Google account to enable synchronization features."}),e(T,{onClick:w,disabled:!l,children:"Sign in with Google"}),!l&&e("p",{className:g.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 ",v?"(override active)":""]}),e("div",{className:g.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:g.label,children:"Worker URL (optional)"}),e("input",{className:g.input,value:a,onChange:_=>i(_.currentTarget.value),placeholder:"https://your-worker.workers.dev"})]}),e("div",{className:g.formGroup,children:[e("label",{className:g.label,children:"Client ID (optional)"}),e("input",{className:g.input,value:u,onChange:_=>p(_.currentTarget.value),placeholder:"Your Google OAuth client ID"})]}),e("div",{className:g.formGroup,children:[e("label",{className:g.label,children:"Client Secret (optional)"}),e("input",{type:"password",className:g.input,value:d,onChange:_=>x(_.currentTarget.value),placeholder:"Your Google OAuth secret"})]}),e("div",{className:g.actions,children:[e(T,{onClick:G,disabled:h,children:"Save override"}),e(T,{variant:"secondary",onClick:M,disabled:h,children:"Use dango defaults"})]})]}),e(E,{isOpen:I.show,onClose:()=>L(_=>({..._,show:!1})),width:"sm",children:[e(E.Body,{children:e("p",{children:I.message})}),e(E.Actions,{children:e(T,{onClick:()=>L(_=>({..._,show:!1})),children:"OK"})})]})]})},pt="_settingItem_3qq0n_1",yt="_modalOverlay_3qq0n_6",ft="_modal_3qq0n_6",vt="_modalActions_3qq0n_41",bt="_modalSecondary_3qq0n_47",wt="_modalPrimary_3qq0n_57",H={settingItem:pt,modalOverlay:yt,modal:ft,modalActions:vt,modalSecondary:bt,modalPrimary:wt},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"]]}},Ct=(t,r)=>{if(t==null)return r;const o=String(t);return o==="true"||o==="1"?!0:o==="false"||o==="0"?!1:r},me=(t,r,o)=>{const[c,l]=s(r),[f,v]=s(!1),m=ce();return O(()=>{(async()=>{try{const u=await b.settings.getByKey.query({key:t});l(Ct(u.value,r))}catch(u){console.error("Failed to fetch setting",u)}})()},[t,r]),{value:c,setValue:l,isUpdating:f,toggle:async()=>{if(f)return;v(!0);const i=!c;l(i);try{await b.settings.set.mutate({key:t,value:i});for(const u of o)m.invalidateQueries({queryKey:u})}catch(u){console.error("Error saving setting:",u),l(!i)}finally{v(!1)}}}},St=()=>{const{contentType:t}=ye(),r=kt[t],[o,c]=s(!1),[l,f]=s(!0),[v,m]=s(!1),a=me(r.ignoreKey,!0,r.invalidateKeys),i=me(r.listOnlyKey,!1,r.invalidateKeys),[u,p]=s(null),[d,x]=s(!1),h=ce(),k=Re();O(()=>{f(!0),(async()=>{try{const C=await b.settings.getByKey.query({key:r.skipKey});String(C.value)==="true"||String(C.value)==="1"?c(!0):c(!1)}catch(C){console.error("Failed to fetch setting",C)}finally{f(!1)}})()},[r.skipKey]);const I=async()=>{if(v)return;m(!0);const w=!o;c(w);try{await b.settings.set.mutate({key:r.skipKey,value:w})}catch(C){console.error("Error saving setting:",C),c(!w)}finally{m(!1)}},L=async()=>{if(!a.isUpdating){if(a.value)try{let w;if(t==="anime"?w=(await b.continueWatching.adultCount.query()).count:t==="manga"?w=(await b.mangaProgress.adultCount.query()).count:t==="asmr"?w=(await b.asmrProgress.adultCount.query()).count:w=(await b.tvProgress.adultCount.query()).count,typeof w=="number"&&w>0){p(w);return}}catch(w){console.error("Failed to fetch adult count",w)}a.toggle()}},R=()=>{p(null),a.toggle()},A=async()=>{if(!d){x(!0);try{let w;t==="anime"?w=(await b.continueWatching.purgeAdult.mutate()).removed:t==="manga"?w=(await b.mangaProgress.purgeAdult.mutate()).removed:t==="asmr"?w=(await b.asmrProgress.purgeAdult.mutate()).removed:w=(await b.tvProgress.purgeAdult.mutate()).removed,he.success(r.purgeDoneText(w??0));for(const C of r.invalidateKeys)h.invalidateQueries({queryKey:C});t==="anime"&&h.invalidateQueries(k.continueWatching.pathFilter()),t==="manga"&&h.invalidateQueries(k.mangaProgress.pathFilter()),t==="asmr"&&h.invalidateQueries(k.asmrProgress.pathFilter()),t==="tv"&&h.invalidateQueries(k.tvProgress.pathFilter())}catch(w){console.error("Failed to purge adult entries",w),he.error("Failed to remove adult entries")}finally{x(!1),p(null)}a.toggle()}};return l?e("div",{children:"Loading settings..."}):e("div",{className:N.sectionCard,children:[e("h3",{children:r.heading}),e("p",{children:r.blurb}),e("div",{className:H.settingItem,children:e("div",{className:N.settingRow,children:[e("label",{htmlFor:"skip-confirmation-toggle",children:r.skipLabel}),e(K,{isChecked:o,onChange:I,id:"skip-confirmation-toggle",disabled:v})]})}),e("div",{className:H.settingItem,children:e("div",{className:N.settingRow,children:[e("label",{htmlFor:"ignore-adult-toggle",children:r.ignoreLabel}),e(K,{isChecked:a.value,onChange:L,id:"ignore-adult-toggle",disabled:a.isUpdating})]})}),e("div",{className:H.settingItem,children:e("div",{className:N.settingRow,children:[e("label",{htmlFor:"cw-watchlist-only-toggle",children:r.listOnlyLabel}),e(K,{isChecked:i.value,onChange:i.toggle,id:"cw-watchlist-only-toggle",disabled:i.isUpdating})]})}),u!==null&&e("div",{className:H.modalOverlay,onClick:()=>p(null),children:e("div",{className:H.modal,onClick:w=>w.stopPropagation(),children:[e("h4",{children:"Show adult entries?"}),e("p",{children:[u," adult ",u===1?"entry":"entries"," not in your"," ",r.listNoun," ",u===1?"is":"are"," currently hidden from"," ",r.continueNoun,". You can purge ",u===1?"it":"them"," from the database instead of showing ",u===1?"it":"them","."]}),e("div",{className:H.modalActions,children:[e("button",{type:"button",className:H.modalSecondary,onClick:R,disabled:d,children:"Show them"}),e("button",{type:"button",className:H.modalPrimary,onClick:A,disabled:d,children:d?"Purging...":`Purge ${u}`})]})]})})]})},_t="_statsGrid_o4nf0_1",Nt="_statCard_o4nf0_8",Tt="_statLabel_o4nf0_18",xt="_statValue_o4nf0_26",It="_statMeta_o4nf0_32",Lt="_statusBanner_o4nf0_38",Rt="_statusSuccess_o4nf0_49",Pt="_statusUpdating_o4nf0_55",Dt="_statusError_o4nf0_61",At="_sha_o4nf0_67",Ot="_settingItem_o4nf0_74",Gt="_settingTitle_o4nf0_79",qt="_settingSubtitle_o4nf0_85",Mt="_actionsRow_o4nf0_92",P={statsGrid:_t,statCard:Nt,statLabel:Tt,statValue:xt,statMeta:It,statusBanner:Lt,statusSuccess:Rt,statusUpdating:Pt,statusError:Dt,sha:At,settingItem:Ot,settingTitle:Gt,settingSubtitle:qt,actionsRow:Mt},zt=()=>{const[t,r]=s(null),[o,c]=s(!0),[l,f]=s(!1),[v,m]=s(!1),a=j(null),i=async()=>{try{const h=await b.settings.offlineDbInfo.query();return r(h),h}catch(h){console.error("Failed to fetch offline DB info:",h)}finally{c(!1)}return null};O(()=>(i(),()=>{a.current&&window.clearInterval(a.current)}),[]),O(()=>{t?.isRefreshing?a.current||(a.current=window.setInterval(async()=>{const h=await i();h&&!h.isRefreshing&&a.current&&(window.clearInterval(a.current),a.current=null)},2e3)):a.current&&(window.clearInterval(a.current),a.current=null)},[t?.isRefreshing]);const u=async()=>{if(!t||l)return;const h=!t.autoUpdateEnabled;f(!0),r({...t,autoUpdateEnabled:h});try{await b.settings.setOfflineDbAutoUpdate.mutate({enabled:h})}catch(k){console.error("Failed to update auto update setting:",k),r({...t,autoUpdateEnabled:!h})}finally{f(!1)}},p=async()=>{if(!(t?.isRefreshing||v)){m(!0);try{await b.settings.triggerOfflineDbUpdate.mutate(),r(h=>h?{...h,isRefreshing:!0,lastStatus:"updating",lastMessage:"Downloading database..."}:null)}catch(h){console.error("Failed to trigger offline DB update:",h)}finally{m(!1)}}},d=h=>{if(!h)return"Never";try{return new Date(h).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"})}catch{return h}},x=t?.isRefreshing||v;return e("div",{className:N.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:P.statsGrid,children:[e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"MAL Mapped"}),e("span",{className:P.statValue,children:o?"-":(t?.totalMalMapped??0).toLocaleString()})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Release"}),e("span",{className:P.statMeta,children:o?"-":t?.releaseTag??"Never"})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Last Checked"}),e("span",{className:P.statMeta,children:o?"-":d(t?.lastCheckedAt??null)})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Last Updated"}),e("span",{className:P.statMeta,children:o?"-":d(t?.lastUpdatedAt??null)})]})]}),t?.lastMessage&&e("div",{className:`${P.statusBanner} ${t.lastStatus==="failed"?P.statusError:t.lastStatus==="updating"?P.statusUpdating:P.statusSuccess}`,children:[e("span",{children:t.lastMessage}),t.contentSha256&&e("span",{className:P.sha,children:["sha:",t.contentSha256.slice(0,12)]})]}),e("div",{className:P.settingItem,children:e("div",{className:N.settingRow,children:[e("div",{children:[e("span",{className:P.settingTitle,children:"Weekly Automatic Updates (Saturdays)"}),e("div",{className:P.settingSubtitle,children:"Download and index new database releases in the background. Catches up on startup if the server was offline."})]}),e(K,{id:"offline-db-auto-update-toggle",isChecked:t?t.autoUpdateEnabled:!0,onChange:u,disabled:o||l})]})}),e("div",{className:P.actionsRow,children:e(T,{onClick:p,disabled:o||x,children:x?"Updating Database...":"Update Offline Database Now"})})]})},Ut="_status_1wbo0_1",Et="_warningText_1wbo0_7",Ft="_ackLabel_1wbo0_11",oe={status:Ut,warningText:Et,ackLabel:Ft},Kt=()=>{const t=ce(),[r,o]=s(!1),[c,l]=s(!1),[f,v]=s(!1),[m,a]=s(""),i=()=>{l(!1),a(""),o(!0)},u=()=>{f||(o(!1),l(!1))},p=async()=>{if(!(!c||f)){v(!0),a("");try{const d=await V("/api/database/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({confirm:!0})}),x=await d.json();if(!d.ok)throw new Error(x.error||"Failed to clear database");const h=x.deleted,k=x.deletedManga,I=x.deletedTv,L=x.deletedAsmr,R=Object.values(h).reduce((G,M)=>G+(M||0),0)+Object.values(k??{}).reduce((G,M)=>G+(M||0),0)+Object.values(I??{}).reduce((G,M)=>G+(M||0),0)+Object.values(L??{}).reduce((G,M)=>G+(M||0),0),A=(k?.manga_library??0)+(k?.manga_progress??0),w=(I?.tv_library??0)+(I?.tv_progress??0),C=(L?.asmr_library??0)+(L?.asmr_progress??0);a(`Library cleared - ${h.watchlist??0} watchlist entries, ${A} manga rows, ${w} TV rows, ${C} ASMR rows and ${R} total rows removed.`),t.invalidateQueries({queryKey:[$.watchlist]}),t.invalidateQueries({queryKey:[$.continueWatching]}),t.invalidateQueries({queryKey:[$.mangaLibrary]}),t.invalidateQueries({queryKey:[$.mangaContinueReading]}),t.invalidateQueries({queryKey:[$.tvLibrary]}),t.invalidateQueries({queryKey:[$.tvContinueWatching]}),t.invalidateQueries({queryKey:[$.asmrLibrary]}),t.invalidateQueries({queryKey:[$.asmrContinueListening]}),o(!1)}catch(d){a(d.message)}finally{v(!1),l(!1)}}};return e("div",{className:`${N.sectionCard} ${N.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(T,{variant:"danger",onClick:i,children:"Clear Library Data"}),m&&e("p",{className:oe.status,children:m}),e(E,{isOpen:r,onClose:u,title:"Clear library data?",width:"sm",children:[e(E.Body,{children:[e("p",{className:oe.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:oe.ackLabel,children:[e("input",{type:"checkbox",checked:c,onChange:d=>l(d.currentTarget.checked),disabled:f}),e("span",{children:"I understand this permanently deletes my library"})]})]}),e(E.Actions,{children:[e(T,{variant:"secondary",onClick:u,disabled:f,children:"Cancel"}),e(T,{variant:"danger",onClick:p,disabled:!c||f,children:f?"Clearing...":"Yes, delete everything"})]})]})]})},$t=()=>{const[t,r]=s(""),[o,c]=s([]),[l,f]=s(null),[v,m]=s(!0),[a,i]=s({show:!1,message:"",type:"info"}),u=async()=>{try{m(!0);const d=await b.auth.rcloneSettings.query();r(d.remote||""),c(d.availableRemotes||[]),f(d.activeRemote||null)}catch(d){console.error("Failed to fetch Rclone settings",d)}finally{m(!1)}};O(()=>{u()},[]);const p=async()=>{try{await b.auth.saveRclone.mutate({remote:t}),i({show:!0,message:"Rclone configuration saved successfully. You must restart the server for these changes to take effect.",type:"success"}),u()}catch{i({show:!0,message:"Failed to save Rclone configuration.",type:"error"})}};return v?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:N.sectionCard,children:[e("h3",{className:g.title,children:"Rclone Cloud Sync"}),e("p",{className:g.signIn,children:"Configure which Rclone remote to use for database synchronization."}),l?e("div",{className:g.userInfo,children:e("p",{children:["Current Active Remote: ",e("strong",{children:l})]})}):e("p",{className:g.warning,style:{marginBottom:"1.5rem"},children:"Rclone sync is not currently active. Ensure rclone is installed and a remote is configured."}),e("div",{className:g.formGroup,children:[e("label",{className:g.label,children:"Remote Name"}),e("div",{className:g.inputWrapper,children:e("select",{className:g.select,value:t,onChange:d=>r(d.currentTarget.value),children:[e("option",{value:"",children:"(Disabled / None)"}),o.map(d=>e("option",{value:d,children:d},d)),t&&!o.includes(t)&&e("option",{value:t,children:[t," (Manual)"]})]})}),e("p",{className:g.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:g.actions,children:e(T,{onClick:p,children:"Save Rclone Settings"})}),e(E,{isOpen:a.show,onClose:()=>i(d=>({...d,show:!1})),width:"sm",children:[e(E.Body,{children:e("p",{children:a.message})}),e(E.Actions,{children:e(T,{onClick:()=>i(d=>({...d,show:!1})),children:"OK"})})]})]})},Ht=()=>{const[t,r]=s(null),[o,c]=s(!0),l=async()=>{try{const a=await b.auth.syncSettings.query();r(a)}catch(a){console.error("Failed to fetch sync settings",a)}finally{c(!1)}};O(()=>{l()},[]);const f=async a=>{const i=a.currentTarget.value;try{const u=await b.auth.saveSyncProvider.mutate({provider:i});r(p=>p?{...p,activeProvider:u.activeProvider}:null),await l(),ge.success(`Sync provider updated to ${i==="default"?"Default Order":i}`)}catch{ge.error("Failed to update sync provider")}};if(o||!t)return null;const v=[{value:"default",label:"Default (Priority Based)"}];t.authenticatedProviders.github&&v.push({value:"github",label:"GitHub"}),t.authenticatedProviders.google&&v.push({value:"google",label:"Google Drive"}),t.authenticatedProviders.rclone&&v.push({value:"rclone",label:"Rclone"}),v.push({value:"none",label:"None (Local Only)"});const m=a=>a==="none"?"Local Only (No Sync)":a==="google"?"Google Drive":a==="github"?"GitHub":a==="rclone"?"Rclone":a;return e("div",{className:N.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:m(t.actualActiveProvider)})]}),e("div",{className:N.settingRow,children:[e("label",{htmlFor:"sync-provider-select",children:"Selected Preference"}),e("select",{id:"sync-provider-select",value:t.activeProvider,onChange:f,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:v.map(a=>e("option",{value:a.value,children:a.label},a.value))})]})]})};function Wt(){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 Bt=()=>{const t=Te(Wt,[]);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:c=>{c.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(X,{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(T,{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.`})]})},Vt="_settingItem_68mz3_1",jt="_field_68mz3_6",Qt="_input_68mz3_19",Yt="_actions_68mz3_39",Jt="_status_68mz3_45",U={settingItem:Vt,field:jt,input:Qt,actions:Yt,status:Jt},Xt=()=>{const[t,r]=s(!1),[o,c]=s(""),[l,f]=s(""),[v,m]=s(!0),[a,i]=s(!1),[u,p]=s("");O(()=>{(async()=>{try{const L=await(await V("/api/auth/app-status")).json();r(L.hasPassword)}catch{console.error("Failed to fetch LAN auth status")}finally{m(!1)}})()},[]);const d=async()=>{if(p(""),o!==l){p("Passwords do not match");return}if(o.length<4){p("Password must be at least 4 characters");return}i(!0);try{const k=await V("/api/auth/app-setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:o})}),I=await k.json();if(!k.ok){p(I.error||"Failed to update password");return}r(I.hasPassword),c(""),f(""),p(I.hasPassword?"Password set successfully":"Password removed")}catch{p("Network error")}finally{i(!1)}},x=async()=>{i(!0);try{const k=await V("/api/auth/app-setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:""})}),I=await k.json();if(!k.ok){p(I.error||"Failed to remove password");return}r(!1),c(""),f(""),p("Password removed")}catch{p("Network error")}finally{i(!1)}},h=async()=>{i(!0);try{await V("/api/auth/app-logout",{method:"POST"}),p("Logged out"),window.location.reload()}catch{p("Logout failed")}finally{i(!1)}};return v?e("div",{className:N.sectionCard,children:e("p",{children:"Loading..."})}):e("div",{className:N.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:U.settingItem,children:[e("div",{className:U.field,children:[e("label",{htmlFor:"lan-password",children:"New Password"}),e("input",{id:"lan-password",type:"password",value:o,onChange:k=>c(k.currentTarget.value),placeholder:t?"Leave empty to keep current password":"Enter a password...",className:U.input})]}),e("div",{className:U.field,children:[e("label",{htmlFor:"lan-confirm-password",children:"Confirm Password"}),e("input",{id:"lan-confirm-password",type:"password",value:l,onChange:k=>f(k.currentTarget.value),placeholder:"Confirm password...",className:U.input})]}),e("div",{className:U.actions,children:[e(T,{variant:"primary",onClick:d,loading:a,disabled:a,children:t?"Update Password":"Set Password"}),t&&e(T,{variant:"danger",onClick:h,loading:a,disabled:a,children:"Logout"}),t&&e(T,{variant:"secondary",onClick:x,loading:a,disabled:a,children:"Remove Password"})]}),u&&e("p",{className:U.status,children:u})]})]})},Zt=()=>{const[t,r]=s(""),[o,c]=s(!0),[l,f]=s(!1),[v,m]=s("");O(()=>{Pe("/api/auth/app-status").then(i=>r(String(i.port??3e3))).catch(()=>m("Failed to load current port")).finally(()=>c(!1))},[]);const a=async()=>{const i=Number(t);if(!Number.isInteger(i)||i<1||i>65535){m("Enter a port between 1 and 65535");return}f(!0),m("");try{await b.auth.setServerPort.mutate({port:i}),m(`Saved. Restart dango, then open http://localhost:${i} - this overrides the PORT environment variable.`)}catch(u){m(u.message)}finally{f(!1)}};return o?e("div",{className:N.sectionCard,children:e("p",{children:"Loading..."})}):e("div",{className:N.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:U.settingItem,children:[e("div",{className:U.field,children:[e("label",{htmlFor:"server-port",children:"Port"}),e("input",{id:"server-port",type:"number",min:1,max:65535,value:t,onChange:i=>r(i.currentTarget.value),className:U.input})]}),e("div",{className:U.actions,children:e(T,{variant:"primary",onClick:a,loading:l,disabled:l,children:"Save Port"})}),v&&e("p",{className:U.status,children:v})]})]})},ea=()=>{const{theme:t,setTheme:r,loading:o}=De();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:Ae.map(c=>{const l=t===c.id;return e("button",{role:"radio","aria-checked":l,disabled:o,onClick:()=>r(c.id),style:{display:"flex",gap:"0.6rem",alignItems:"center",textAlign:"left",padding:"0.65rem 0.75rem",borderRadius:"10px",cursor:"pointer",background:l?"var(--accent-subtle)":"var(--bg-tertiary)",border:l?"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:c.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:c.label}),e("span",{style:{display:"block",fontSize:"0.75rem",color:"var(--text-secondary)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:c.blurb})]})]},c.id)})})]})};function ta({variant:t="info",children:r,className:o=""}){return e("div",{className:`alert alert-${t} ${o}`,children:r})}const aa={anime:"Watchlist",manga:"Reading List",tv:"TV Watchlist",asmr:"Listening List"},la=()=>{const[t,r]=xe(),{contentType:o}=ye(),c=t.get("tab"),[l,f]=s(c&&["general","sync","watchlist","database"].includes(c)?c:"general"),[v,m]=s(""),a=j(null),i=j(null),u=j(new Map),[p,d]=s({top:0,height:0,left:0,width:0}),{lowEndMode:x,setLowEndMode:h}=Oe(),{hasConsent:k,revoke:I}=Ge(),[L,R]=s(qe),[A,w]=s(!0),{data:C}=ne("discordRPCEnabled"),G=pe(),[M,_]=s(!0),{data:D}=ne("dangoGaze"),[z,W]=s(!0),{data:y}=ne("discordRPCHideMature"),[Z,ee]=s(""),[Q,ae]=s(null);O(()=>{b.discord.gatewayStatus.query().then(n=>{ae(n),n.masked&&n.masked!=="none"&&ee(n.masked)}).catch(()=>{})},[]),O(()=>{C!==void 0&&w(C==="true"||C===!0||C===null)},[C]),O(()=>{y!==void 0&&W(y==="true"||y===!0||y===null)},[y]);const fe=n=>{w(n),G.mutate({key:"discordRPCEnabled",value:String(n)})};O(()=>{D!==void 0&&_(D!=="false"&&D!==!1)},[D]);const ve=n=>{_(n),G.mutate({key:"dangoGaze",value:String(n)})},be=n=>{W(n),G.mutate({key:"discordRPCHideMature",value:String(n)})},we=n=>{R(n),localStorage.setItem(Me,String(n)),window.dispatchEvent(new CustomEvent(ze))};ue.useEffect(()=>{document.title="Settings - dango"},[]),ue.useEffect(()=>{const n=t.get("tab");n&&["general","sync","watchlist","database"].includes(n)&&f(n)},[t]);const te=n=>{f(n),r(n==="general"?{}:{tab:n})},Y=le(()=>{const n=u.current.get(l),q=i.current;if(n&&q){const B=q.getBoundingClientRect(),F=n.getBoundingClientRect(),J=window.matchMedia("(max-width: 900px)").matches;d(J?{top:F.top-B.top,height:F.height,left:F.left-B.left,width:F.width}:{top:F.top-B.top,height:F.height,left:0,width:0})}},[l]);Ie(()=>{Y()},[l,Y]),O(()=>{const n=()=>Y();window.addEventListener("resize",n);let q=!1;return document.fonts?.ready&&document.fonts.ready.then(()=>{q||Y()}),()=>{q=!0,window.removeEventListener("resize",n)}},[l,Y]);const ke=()=>{m("Exporting databases...");const n=window.DangoBridge;if(n?.downloadFile){n.downloadFile("/api/backup-db","dango-backup.json"),setTimeout(()=>{m("Databases exported successfully!")},1500);return}const q=document.createElement("a");q.href="/api/backup-db",q.download="dango-backup.json",document.body.appendChild(q),q.click(),q.remove(),setTimeout(()=>{m("Databases exported successfully!")},1500)},Ce=async n=>{const q=n.currentTarget.files?.[0];if(!q)return;m("Importing databases...");const B=new FormData;B.append("dbfile",q);try{const F=await V("/api/restore-db",{method:"POST",body:B}),J=await F.json();if(F.ok){const de=Array.isArray(J.restored)?J.restored.join(", "):null;m(de?`Databases imported successfully (${de})!`:"Database imported successfully!"),setTimeout(()=>window.location.reload(),2e3)}else m(`Import failed: ${J.error}`)}catch{m("Import failed: An unexpected error occurred.")}finally{n.currentTarget.value=""}},Se=()=>{a.current?.click()},_e=()=>{switch(l){case"general":return e("div",{className:S.tabContent,children:e("div",{className:N.sectionCard,children:[e("h3",{children:"Appearance & Preferences"}),e("p",{children:"Configure how titles are displayed and other general preferences."}),e("div",{className:S.settingItem,children:e(Ue,{})}),e("div",{className:S.settingItem,style:{marginTop:"1.5rem"},children:e(ea,{})}),e("div",{className:S.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:N.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(K,{isChecked:x,onChange:n=>h(n.currentTarget.checked),id:"low-end-mode"})]})}),e("div",{className:S.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:N.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(K,{isChecked:M,onChange:n=>ve(n.currentTarget.checked),id:"dango-gaze"})]})}),e("div",{className:S.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:N.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(K,{isChecked:L,onChange:n=>we(n.currentTarget.checked),id:"virtual-keyboard-enabled"})]})}),e("div",{className:S.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:N.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(K,{isChecked:A,onChange:n=>fe(n.currentTarget.checked),id:"discord-rpc-enabled"})]})}),e("div",{style:{marginTop:"2rem"},children:e(Xt,{})}),e("div",{style:{marginTop:"2rem"},children:e(Zt,{})}),A&&e("div",{className:S.settingItem,style:{marginTop:"1rem"},children:e("div",{className:N.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(K,{isChecked:z,onChange:n=>be(n.currentTarget.checked),id:"discord-hide-mature"})]})}),e("div",{className:S.settingItem,style:{marginTop:"1.5rem",background:"var(--bg-tertiary)",padding:"1rem",borderRadius:"8px",border:"1px solid var(--border-color)"},children:[e("div",{className:N.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(ta,{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:Z,onChange:n=>ee(n.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(T,{variant:"primary",size:"sm",onClick:async()=>{try{const n=await b.discord.gatewaySave.mutate({token:Z});ae({hasToken:!0,masked:n.masked,enabled:!0}),ee(n.masked)}catch(n){alert(n instanceof Error?n.message:"Failed to save token")}},children:"Save"}),e(T,{variant:"secondary",size:"sm",onClick:async()=>{await b.discord.gatewayRemove.mutate().catch(()=>{}),ee(""),ae({hasToken:!1,masked:null,enabled:!1})},children:"Remove"})]}),Q&&e("p",{style:{marginTop:"0.5rem",fontSize:"0.8rem",color:Q.hasToken?"green":"var(--text-secondary)"},children:["Status:"," ",Q.hasToken?`Token saved (${Q.masked})`:"No token saved",Q.enabled?" - Gateway active":""]}),e(Bt,{})]}),k&&e("div",{className:S.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:N.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:"You have previously agreed to view 18+ content. Toggle this off to re-enable the blur gate and filtering."})]}),e(K,{isChecked:!0,onChange:n=>{n.currentTarget.checked||(I(),window.location.reload())},id:"mature-content-enabled"})]})})]})});case"sync":return e("div",{className:S.tabContent,children:[e(Ht,{}),e(gt,{}),e(mt,{}),e($t,{})]});case"watchlist":return e("div",{className:S.tabContent,children:e(St,{})});case"database":return e("div",{className:S.tabContent,children:[e("div",{className:N.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:S.controls,children:[e(T,{onClick:ke,children:"Backup Database"}),e(T,{variant:"secondary",onClick:Se,children:"Restore Database"})]}),e("input",{type:"file",ref:a,onChange:Ce,style:{position:"absolute",width:1,height:1,opacity:0,overflow:"hidden"},accept:".json,.db,application/octet-stream"}),v&&e("p",{className:S.status,children:v})]}),e(zt,{}),e(Kt,{})]});default:return null}};return e("div",{className:"page-container",children:[e("div",{className:S.settingsHeader,children:[e("h1",{className:S.pageTitle,children:"Settings"}),e("p",{className:S.pageSubtitle,children:"Manage your preferences and data synchronization"})]}),e("div",{className:S.settingsLayout,children:[e("aside",{className:S.sidebar,ref:i,children:[e("div",{className:S.sidebarIndicator,style:{top:p.top,height:p.height,left:p.left,...p.width?{width:p.width}:{}}}),e("button",{ref:n=>{n&&u.current.set("general",n)},className:`${S.sidebarItem} ${l==="general"?S.active:""}`,onClick:()=>te("general"),children:[e(X,{name:"cog"})," ",e("span",{children:"General"})]}),e("button",{ref:n=>{n&&u.current.set("sync",n)},className:`${S.sidebarItem} ${l==="sync"?S.active:""}`,onClick:()=>te("sync"),children:[e(X,{name:"cloud"})," ",e("span",{children:"Synchronization"})]}),e("button",{ref:n=>{n&&u.current.set("watchlist",n)},className:`${S.sidebarItem} ${l==="watchlist"?S.active:""}`,onClick:()=>te("watchlist"),children:[e(X,{name:"list"})," ",e("span",{children:aa[o]})]}),e("button",{ref:n=>{n&&u.current.set("database",n)},className:`${S.sidebarItem} ${l==="database"?S.active:""}`,onClick:()=>te("database"),children:[e(X,{name:"database"})," ",e("span",{children:"Database"})]})]}),e("main",{className:S.mainContent,children:e("div",{className:S.tabContent,children:_e()},l)})]})]})};export{la as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._skeletonCard_qtypb_1{display:flex;flex-direction:column;background-color:var(--bg-secondary);border-radius:var(--radius-md);overflow:hidden;height:100%;border:1px solid var(--border-secondary)}._poster_qtypb_11{width:100%;aspect-ratio:3 / 4;background-color:var(--bg-tertiary);position:relative;overflow:hidden}._poster_qtypb_11:after,._line_qtypb_20:after{content:"";position:absolute;inset:0;transform:translate(-100%);background-image:linear-gradient(90deg,#fff0 0,#ffffff0d 20%,#ffffff1f 60%,#fff0);animation:_skeleton-wave_qtypb_1 1.8s infinite ease-in-out}._info_qtypb_38{padding:var(--space-3);display:flex;flex-direction:column;gap:var(--space-2);flex-grow:1}._line_qtypb_20{position:relative;overflow:hidden;height:18px;border-radius:var(--radius-sm);background-color:var(--bg-tertiary)}._line_qtypb_20._short_qtypb_54{width:60%;height:14px}@media(max-width:768px){._line_qtypb_20{height:16px}._line_qtypb_20._short_qtypb_54{height:12px}}._skeletonCard_qtypb_1._lowEnd_qtypb_69{min-height:0}._skeletonCard_qtypb_1._lowEnd_qtypb_69 ._poster_qtypb_11:after,._skeletonCard_qtypb_1._lowEnd_qtypb_69 ._line_qtypb_20:after{animation:none}._skeletonCard_qtypb_1._lowEnd_qtypb_69 ._line_qtypb_20{opacity:.6}._skeletonCard_qtypb_1._lowEnd_qtypb_69 ._info_qtypb_38{padding:var(--space-3)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{u as o,g as r}from"./vendor-core-DfaOB3Rn.js";import{u as l}from"./index-BLh_CXtu.js";const a="_skeletonCard_qtypb_1",i="_poster_qtypb_11",d="_line_qtypb_20",c="_info_qtypb_38",_="_short_qtypb_54",m="_lowEnd_qtypb_69",e={skeletonCard:a,poster:i,line:d,"skeleton-wave":"_skeleton-wave_qtypb_1",info:c,short:_,lowEnd:m},p=({layout:n="vertical"})=>{const{lowEndMode:t}=l();return o("div",{className:`${e.skeletonCard} ${e[n]} ${t?e.lowEnd:""}`,children:[o("div",{className:e.poster}),o("div",{className:e.info,children:[o("div",{className:e.line}),o("div",{className:`${e.line} ${e.short}`})]})]})},v=({count:n=14,layout:t="vertical"})=>o("div",{className:"grid-container",children:Array.from({length:n}).map((k,s)=>o(p,{layout:t},s))}),w=r.memo(v);export{p as A,w as S};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{d as t,h as Ke,g as De,A as Fe,q as $e,u as e,S as m}from"./vendor-core-DfaOB3Rn.js";import{u as Oe,b as Re,a as x}from"./vendor-query-BBT5_sHx.js";import{A as i,q as r,t as h,Z as tn,k as sn,H as Ue,B as ce}from"./index-BLh_CXtu.js";import{I as c}from"./vendor-icons-DrybRNxP.js";function rn(){const O=Oe(),[Z,v]=t(!1);return Ke(()=>{const s=new URLSearchParams(window.location.search),_=s.get("anilist");if(_){const p=s.get("user"),f=s.get("reason");window.history.replaceState(null,"",window.location.pathname),_==="success"?(i.success(p?`Connected to AniList as ${decodeURIComponent(p)}`:"Connected to AniList"),O.invalidateQueries({queryKey:[r.trackerStatus]})):i.error(f?decodeURIComponent(f):"AniList authentication failed");return}const P=new URLSearchParams(window.location.hash.substring(1)),b=P.get("access_token"),L=s.get("code");if(!b&&!L){const p=P.get("error");p&&(i.error(`AniList error: ${p}`),window.history.replaceState(null,"",window.location.pathname));return}const y=window.location.origin+window.location.pathname;window.history.replaceState(null,"",window.location.pathname),v(!0),i("Connecting to AniList..."),h.tracker.anilistAuth.mutate(b?{token:b}:{code:L,redirectUri:y}).then(async p=>{const f=p.user;i.success(`Connected to AniList as ${f?.name??"AniList user"}`),O.invalidateQueries({queryKey:[r.trackerStatus]})}).catch(p=>{i.error(p instanceof Error?p.message:"Failed to authenticate with AniList")}).finally(()=>{v(!1)})},[O]),Z}const ln="_header_j1lbh_1",cn="_fadeIn_j1lbh_1",on="_pageTitle_j1lbh_6",dn="_pageSubtitle_j1lbh_14",mn="_importCard_j1lbh_20",pn="_slideUpIn_j1lbh_1",un="_cardHeader_j1lbh_37",hn="_uploadArea_j1lbh_55",gn="_fileInputWrapper_j1lbh_59",yn="_fileInput_j1lbh_59",bn="_fileDisplay_j1lbh_87",_n="_fileIcon_j1lbh_95",fn="_fileName_j1lbh_100",Nn="_browseButton_j1lbh_109",kn="_optionsArea_j1lbh_120",vn="_checkboxLabel_j1lbh_128",wn="_checkbox_j1lbh_128",In="_checkboxCustom_j1lbh_141",xn="_optionText_j1lbh_169",Ln="_optionTitle_j1lbh_175",Cn="_optionDesc_j1lbh_181",Mn="_actions_j1lbh_187",Sn="_importBtn_j1lbh_195",Tn="_cancelBtn_j1lbh_201",An="_statusMessage_j1lbh_215",jn="_success_j1lbh_225",Pn="_error_j1lbh_231",En="_progressSection_j1lbh_237",Bn="_progressBar_j1lbh_242",Dn="_progressFill_j1lbh_250",Fn="_progressInfo_j1lbh_257",$n="_progressCount_j1lbh_264",Rn="_progressTitle_j1lbh_271",Un="_sourceBadge_j1lbh_289",qn="_anilist_j1lbh_301",Kn="_kitsu_j1lbh_307",On="_offline_j1lbh_313",Qn="_skipped_j1lbh_319",Gn="_cardTitleRow_j1lbh_324",Hn="_anilistIcon_j1lbh_334",Wn="_malIcon_j1lbh_340",Xn="_badgeOnline_j1lbh_346",zn="_badgeOffline_j1lbh_358",Jn="_connectedProfile_j1lbh_370",Yn="_avatar_j1lbh_379",Zn="_connectedInfo_j1lbh_386",Vn="_connectedName_j1lbh_394",ea="_connectedHint_j1lbh_400",na="_loginPrompt_j1lbh_405",aa="_loginSection_j1lbh_413",ta="_fieldLabel_j1lbh_419",sa="_helpText_j1lbh_438",ia="_loginText_j1lbh_455",ra="_primaryBtn_j1lbh_464",la="_secondaryBtn_j1lbh_465",ca="_syncBtn_j1lbh_466",oa="_divider_j1lbh_518",da="_actionSection_j1lbh_524",ma="_inputGroup_j1lbh_538",pa="_input_j1lbh_538",ua="_syncSummary_j1lbh_559",ha="_syncErrors_j1lbh_565",ga="_spin_j1lbh_569",ya="_radioGroup_j1lbh_598",ba="_radioLabel_j1lbh_604",_a="_syncHint_j1lbh_642",fa="_importLoading_j1lbh_649",n={header:ln,fadeIn:cn,pageTitle:on,pageSubtitle:dn,importCard:mn,slideUpIn:pn,cardHeader:un,uploadArea:hn,fileInputWrapper:gn,fileInput:yn,fileDisplay:bn,fileIcon:_n,fileName:fn,browseButton:Nn,optionsArea:kn,checkboxLabel:vn,checkbox:wn,checkboxCustom:In,optionText:xn,optionTitle:Ln,optionDesc:Cn,actions:Mn,importBtn:Sn,cancelBtn:Tn,statusMessage:An,success:jn,error:Pn,progressSection:En,progressBar:Bn,progressFill:Dn,progressInfo:Fn,progressCount:$n,progressTitle:Rn,sourceBadge:Un,anilist:qn,kitsu:Kn,offline:On,skipped:Qn,cardTitleRow:Gn,anilistIcon:Hn,malIcon:Wn,badgeOnline:Xn,badgeOffline:zn,connectedProfile:Jn,avatar:Yn,connectedInfo:Zn,connectedName:Vn,connectedHint:ea,loginPrompt:na,loginSection:aa,fieldLabel:ta,helpText:sa,loginText:ia,primaryBtn:ra,secondaryBtn:la,syncBtn:ca,divider:oa,actionSection:da,inputGroup:ma,input:pa,syncSummary:ua,syncErrors:ha,spin:ga,radioGroup:ya,radioLabel:ba,syncHint:_a,importLoading:fa},oe="tracker_anilist_client_id",qe="49887".trim(),Ia=()=>{const{setIsOpen:O}=tn(),{contentType:Z}=sn(),v=Z==="manga",s=Oe();De.useEffect(()=>{document.title="Trackers - dango"},[]);const[_,P]=t(""),[b,L]=t("username"),[y,p]=t(null),[f,de]=t(""),[C,me]=t(!1),Qe=rn(),{data:pe,isLoading:ue}=Re({queryKey:[r.trackerStatus],queryFn:async()=>await h.tracker.status.query()}),{data:M}=Re({queryKey:[r.anilistClientId],queryFn:async()=>(await h.settings.getByKey.query({key:oe})).value||""}),he=Fe(!1);De.useEffect(()=>{he.current||M!==void 0&&(M&&de(M),he.current=!0)},[M]);const w=pe?.anilist?.connected??!1;Ke(()=>{w&&L("sync")},[w]);const Q=pe?.anilist?.user??null,V=!!qe,Ge=(M||"").trim(),He=async()=>{const a=f.trim(),l=a||qe;if(!l){i.error("Enter your AniList client ID first");return}const k=async(j,ie)=>{await h.settings.set.mutate({key:j,value:ie})};try{a?a!==M&&await k(oe,a):V&&Ge&&await k(oe,""),s.invalidateQueries({queryKey:[r.anilistClientId]})}catch(j){i.error(j.message);return}const o=window.location.origin+window.location.pathname,U=encodeURIComponent(o);window.location.href=`https://anilist.co/api/v2/oauth/authorize?client_id=${encodeURIComponent(l)}&response_type=token&state=${U}`},ge=x({mutationFn:async()=>h.tracker.anilistDisconnect.mutate(),onSuccess:()=>{s.invalidateQueries({queryKey:[r.trackerStatus]}),i.success("Disconnected from AniList")},onError:a=>i.error(a.message)}),G=x({mutationFn:async()=>(await h.tracker.sync.mutate({provider:"anilist"})).summary,onSuccess:a=>{s.invalidateQueries({queryKey:[r.watchlist]}),s.invalidateQueries({queryKey:[r.continueWatching]}),p(a),i.success(`Sync complete - pushed ${a.pushed}, pulled ${a.pulled}, merged ${a.merged}, unchanged ${a.unchanged}`,{duration:6e3})},onError:a=>i.error(a.message)}),[E,ye]=t(""),[H,be]=t("sync"),[ee,_e]=t("two-way"),[d,We]=t(null),W=x({mutationFn:async()=>(await h.tracker.mangaSync.mutate({direction:ee})).summary,onSuccess:a=>{s.invalidateQueries({queryKey:[r.mangaLibrary]}),s.invalidateQueries({queryKey:[r.mangaContinueReading]}),We(a);const l=(a.warnings?.length??0)>0?`, ${a.warnings.length} warning(s)`:"";i.success(`Manga sync complete - pushed ${a.pushed}, pulled ${a.pulled}, merged ${a.merged}, unchanged ${a.unchanged}${l}`,{duration:6e3})},onError:a=>i.error(a.message)}),S=x({mutationFn:async()=>{if(!E.trim())throw new Error("Please enter a username");return(await h.tracker.mangaImport.mutate({username:E.trim(),erase:C})).count},onSuccess:a=>{s.invalidateQueries({queryKey:[r.mangaLibrary]}),s.invalidateQueries({queryKey:[r.mangaContinueReading]}),i.success(`Imported ${a} manga entries from AniList`),ye("")},onError:a=>i.error(a.message)}),[B,fe]=t(""),[X,Ne]=t("username"),[ne,ke]=t(null),[z,ve]=t(!1),[we,ae]=t(""),[Ie,Xe]=t(""),N=x({mutationFn:async()=>{if(!B.trim())throw new Error("Please enter a MAL username");const a=await h.tracker.mangaMalImport.mutate({username:B.trim(),erase:C});return{imported:a.imported??0,skipped:a.skipped??0}},onSuccess:({imported:a,skipped:l})=>{s.invalidateQueries({queryKey:[r.mangaLibrary]}),s.invalidateQueries({queryKey:[r.mangaContinueReading]}),i.success(`Imported ${a} manga entries from MAL${l>0?`, skipped ${l}`:""}`),fe("")},onError:a=>i.error(a.message)}),ze=$e(async()=>{const a=document.getElementById("malMangaFile");if(!a.files||a.files.length===0){ae("Please select a file first.");return}ve(!0),ae(""),ke(null);try{const l=new FormData;l.append("xmlfile",a.files[0]),l.append("erase",String(C));const k=await Ue("/api/import/mal-xml-manga",{method:"POST",body:l}),o=await k.json().catch(()=>({}));if(!k.ok)throw new Error(o.error||"Import failed");ke({imported:o.imported??0,skipped:o.skipped??0}),s.invalidateQueries({queryKey:[r.mangaLibrary]}),s.invalidateQueries({queryKey:[r.mangaContinueReading]})}catch(l){ae(l.message)}finally{ve(!1)}},[C,s]),T=x({mutationFn:async()=>{if(!_.trim())throw new Error("Please enter a username");return(await h.tracker.anilistImport.mutate({username:_.trim(),erase:I})).count},onSuccess:a=>{s.invalidateQueries({queryKey:[r.watchlist]}),s.invalidateQueries({queryKey:[r.continueWatching]}),i.success(`Imported ${a} anime entries from AniList`),P("")},onError:a=>i.error(a.message)}),[D,xe]=t(""),g=x({mutationFn:async a=>{if(!D.trim())throw new Error("Please enter a MAL username");return(await h.tracker.malImport.mutate({username:D.trim(),erase:a.erase,useOfflineDb:a.useOfflineDb,skipFallback:a.skipFallback})).count},onSuccess:a=>{s.invalidateQueries({queryKey:[r.watchlist]}),s.invalidateQueries({queryKey:[r.continueWatching]}),i.success(`Imported ${a} anime entries from MAL`),xe("")},onError:a=>i.error(a.message)}),[I,Le]=t(!1),[F,Je]=t(!0),[$,Ye]=t(!1),[Ce,Me]=t(""),[A,Se]=t(!1),[u,Te]=t(null),[te,Ae]=t(null),[je,J]=t(""),se=Fe(null),Ze=a=>{a.currentTarget.files&&a.currentTarget.files.length>0?Me(a.currentTarget.files[0].name):Me("")},Ve=$e(async()=>{const a=document.getElementById("malFile");if(!a.files||a.files.length===0){J("Please select a file first.");return}const l=a.files[0];Se(!0),Te(null),Ae(null),J("");const k=new AbortController;se.current=k;try{const o=new FormData;o.append("xmlfile",l),o.append("erase",String(I)),o.append("useOfflineDb",String(F)),o.append("skipFallback",String($));const U=await Ue("/api/import/mal-xml",{method:"POST",body:o,signal:k.signal});if(!U.ok){const le=await U.text();let q="Failed to import";try{q=JSON.parse(le).error||q}catch{}throw new Error(q)}const j=U.body?.getReader();if(!j)throw new Error("No response stream");const ie=new TextDecoder;let re="",Y="";for(;;){const{done:le,value:q}=await j.read();if(le)break;re+=ie.decode(q,{stream:!0});const Ee=re.split(`
|
|
2
|
+
`);re=Ee.pop()||"";for(const K of Ee)if(K.startsWith("event: "))Y=K.slice(7).trim();else if(K.startsWith("data: ")){const an=K.slice(6);try{const Be=JSON.parse(an);Y==="progress"?Te(Be):Y==="complete"&&Ae(Be)}catch{}}else K===""&&(Y="")}s.invalidateQueries({queryKey:[r.watchlist]})}catch(o){o instanceof DOMException&&o.name==="AbortError"?J("Import cancelled."):J(o.message)}finally{Se(!1),se.current=null}},[I,F,$,s]),en=()=>{se.current?.abort(),h.settings.malImportCancel.mutate().catch(()=>{})},nn=u?Math.round(u.current/u.total*100):0,[R,Pe]=t("username");return e("div",{className:"page-container",children:[e("div",{className:n.header,children:[e("h1",{className:n.pageTitle,children:"Trackers"}),e("p",{className:n.pageSubtitle,children:"Import & sync your anime watchlists and manga reading lists with tracking services"})]}),e("div",{style:{marginBottom:"16px",padding:"10px 14px",borderRadius:"8px",fontSize:"0.85rem",background:"color-mix(in srgb, var(--color-warning) 8%, transparent)",border:"1px solid color-mix(in srgb, var(--color-warning) 25%, transparent)",color:"var(--text-secondary)"},children:"⚠ Syncing writes directly to your AniList entries, and dango may not always handle anime/manga lists correctly - always keep a backup of your lists before syncing."}),!v&&e(m,{children:e("div",{className:n.importCard,children:[e("div",{className:n.cardHeader,children:e("div",{className:n.cardTitleRow,children:[e(c,{name:"anilist",className:n.anilistIcon}),e("h3",{children:"AniList"}),ue?null:w?e("span",{className:n.badgeOnline,children:"Connected"}):e("span",{className:n.badgeOffline,children:"Not connected"})]})}),w&&Q?e("div",{className:n.connectedProfile,children:[Q.avatar&&e("img",{src:Q.avatar,alt:"Avatar",className:n.avatar,loading:"lazy",decoding:"async"}),e("div",{className:n.connectedInfo,children:[e("span",{className:n.connectedName,children:Q.name}),e("span",{className:n.connectedHint,children:"2-way sync is ready"})]}),e("button",{className:n.secondaryBtn,onClick:()=>ge.mutate(),disabled:ge.isPending,children:[e(c,{name:"sign-out-alt"})," Disconnect"]})]}):e("div",{className:n.loginSection,children:[e("p",{className:n.loginText,children:["Log in with AniList to enable bidirectional progress & status synchronization.",Qe&&e("span",{style:{marginLeft:8,color:"var(--accent)"},children:"Finishing login…"})]}),e("div",{className:n.fieldLabel,children:["AniList client ID - defaults to Dango's app"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:["create your own app ",e(c,{name:"external-link-alt",size:9})]})]}),e("div",{className:n.inputGroup,children:[e("input",{type:"text",placeholder:"Client ID",value:f,onChange:a=>de(a.currentTarget.value),className:n.input}),e("button",{className:n.primaryBtn,onClick:He,disabled:!(f.trim()||V),children:[e(c,{name:"external-link-alt"})," Connect"]})]}),e("p",{className:n.helpText,children:V?e(m,{children:["By default uses Dango's client. To use your own AniList app: create it at"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:"anilist.co/settings/developer"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste only the ",e("strong",{children:"Client ID"})," above (leave empty to use Dango's)."]}):e(m,{children:["No shipped client in this build - create your own app at"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:"anilist.co/settings/developer"}),", set ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste the ",e("strong",{children:"Client ID"})," above."]})})]}),w&&e(m,{children:[e("hr",{className:n.divider}),e("div",{className:n.radioGroup,children:[e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"anilistMode",value:"username",checked:b==="username",onChange:()=>L("username")}),e("span",{children:"Quick Import"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"anilistMode",value:"sync",checked:b==="sync",onChange:()=>L("sync")}),e("span",{children:"Two-way Sync"})]})]}),b==="username"?e("div",{className:n.inputGroup,children:e("input",{type:"text",placeholder:"Enter AniList username",value:_,onChange:a=>P(a.currentTarget.value),className:n.input,disabled:T.isPending,onKeyDown:a=>{a.key==="Enter"&&_.trim()&&T.mutate()}})}):e("p",{className:n.syncHint,children:"Merges progress non-destructively: pushes shows and episodes you watched on dango to AniList, and pulls anything you updated on AniList into dango."}),b==="username"&&e("div",{className:n.optionsArea,children:e("label",{className:n.checkboxLabel,children:[e("input",{type:"checkbox",checked:I,onChange:a=>Le(a.currentTarget.checked),className:n.checkbox,disabled:T.isPending}),e("span",{className:n.checkboxCustom}),e("div",{className:n.optionText,children:[e("span",{className:n.optionTitle,children:"Erase current watchlist"}),e("span",{className:n.optionDesc,children:"Delete existing watchlist before importing."})]})]})}),b==="username"?e("button",{className:n.syncBtn,onClick:()=>T.mutate(),disabled:!_.trim()||T.isPending,children:[e(c,{name:"download"}),T.isPending?"Importing...":"Start Import"]}):e(m,{children:[e("button",{className:n.syncBtn,onClick:()=>G.mutate(),disabled:G.isPending,children:[e(c,{name:"sync-alt",className:G.isPending?n.spin:""}),G.isPending?"Syncing...":"Start Sync"]}),y&&e("div",{className:n.syncSummary,children:["Pushed: ",y.pushed," · Pulled: ",y.pulled," · Merged:"," ",y.merged," · Unchanged: ",y.unchanged,y.errors.length>0&&e("span",{className:n.syncErrors,children:[" ","· ",y.errors.length," error",y.errors.length>1?"s":""]})]})]}),e("p",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)",marginTop:"8px"},children:["AniList ",e("code",{children:"Rewatching (REPEATING)"})," is not tracked - entries with this status are ignored."]})]})]})}),v&&e(m,{children:e("div",{className:n.importCard,children:[e("div",{className:n.cardHeader,children:e("div",{className:n.cardTitleRow,children:[e(c,{name:"anilist",className:n.anilistIcon}),e("h3",{children:"AniList Manga"}),ue?null:w?e("span",{className:n.badgeOnline,children:"Connected"}):e("span",{className:n.badgeOffline,children:"Not connected"})]})}),w?e(m,{children:[e("div",{className:n.radioGroup,children:[e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"mangaMode",value:"username",checked:H==="username",onChange:()=>be("username")}),e("span",{children:"Quick Import"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"mangaMode",value:"sync",checked:H==="sync",onChange:()=>be("sync")}),e("span",{children:"Two-way Sync"})]})]}),H==="username"?e(m,{children:[e("div",{className:n.inputGroup,children:e("input",{type:"text",placeholder:"Enter AniList username",value:E,onChange:a=>ye(a.currentTarget.value),className:n.input,disabled:S.isPending,onKeyDown:a=>{a.key==="Enter"&&E.trim()&&S.mutate()}})}),e("div",{className:n.optionsArea,children:e("label",{className:n.checkboxLabel,children:[e("input",{type:"checkbox",checked:C,onChange:a=>me(a.currentTarget.checked),className:n.checkbox,disabled:S.isPending}),e("span",{className:n.checkboxCustom}),e("div",{className:n.optionText,children:[e("span",{className:n.optionTitle,children:"Replace AniList-linked manga"}),e("span",{className:n.optionDesc,children:"Clears previously imported (anilist:) entries before importing. Your provider bookmarks are never touched."})]})]})})]}):e(m,{children:[e("p",{className:n.syncHint,children:"Merges chapter progress non-destructively: pushes manga and chapters you read on dango to AniList, and pulls anything you updated on AniList into dango. Local titles are linked only on exact title matches, and bookmarks with no chapters read are never pushed."}),e("div",{className:n.radioGroup,children:[e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"mangaDirection",value:"two-way",checked:ee==="two-way",onChange:()=>_e("two-way")}),e("span",{children:"Two-way"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"mangaDirection",value:"pull-only",checked:ee==="pull-only",onChange:()=>_e("pull-only")}),e("span",{children:"Pull only (never writes to AniList)"})]})]})]}),H==="username"?e("button",{className:n.syncBtn,onClick:()=>S.mutate(),disabled:!E.trim()||S.isPending,children:[e(c,{name:"download"}),S.isPending?"Importing...":"Start Import"]}):e(m,{children:[e("button",{className:n.syncBtn,onClick:()=>W.mutate(),disabled:W.isPending,children:[e(c,{name:"sync-alt",className:W.isPending?n.spin:""}),W.isPending?"Syncing...":"Start Manga Sync"]}),d&&e(m,{children:[e("div",{className:n.syncSummary,children:["Pushed: ",d.pushed," · Pulled: ",d.pulled," · Merged: ",d.merged," · Unchanged:"," ",d.unchanged,(d.skipped??0)>0&&e("span",{children:[" · Skipped: ",d.skipped]}),d.errors.length>0&&e("span",{className:n.syncErrors,children:[" ","· ",d.errors.length," error",d.errors.length>1?"s":""]})]}),(d.warnings?.length??0)>0&&e("div",{className:n.syncErrors,style:{marginTop:"8px"},children:[(d.warnings??[]).slice(0,5).map((a,l)=>e("div",{children:["⚠ ",a]},l)),(d.warnings?.length??0)>5&&e("div",{children:["+",(d.warnings?.length??0)-5," more warning(s)"]})]})]})]}),e("p",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)",marginTop:"8px"},children:["AniList ",e("code",{children:"Rereading (REPEATING)"})," is not tracked - entries with this status are ignored."]})]}):e("p",{className:n.loginText,children:"Connect your AniList account above to sync your manga reading list."})]})}),!v&&e(m,{children:e("div",{className:n.importCard,children:[e("div",{className:n.cardHeader,children:e("div",{className:n.cardTitleRow,children:[e(c,{name:"myanimelist",className:n.malIcon}),e("h3",{children:"MyAnimeList"})]})}),e("div",{className:n.radioGroup,children:[e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"malMode",value:"username",checked:R==="username",onChange:()=>Pe("username")}),e("span",{children:"Username"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"malMode",value:"xml",checked:R==="xml",onChange:()=>Pe("xml")}),e("span",{children:"XML File"})]})]}),R==="username"?e(m,{children:[e("div",{className:n.inputGroup,children:e("input",{type:"text",placeholder:"Enter MAL username",value:D,onChange:a=>xe(a.currentTarget.value),className:n.input,disabled:g.isPending,onKeyDown:a=>{a.key==="Enter"&&D.trim()&&g.mutate({erase:I,useOfflineDb:F,skipFallback:$})}})}),g.isPending&&e("div",{className:n.importLoading,children:[e(c,{name:"sync-alt",className:n.spin}),e("span",{children:"Importing from MAL..."})]})]}):e("div",{className:n.uploadArea,children:e("div",{className:n.fileInputWrapper,children:[e("input",{type:"file",id:"malFile",accept:".xml,application/xml",className:n.fileInput,onChange:Ze,disabled:A}),e("div",{className:n.fileDisplay,children:[e(c,{name:"file-alt",className:n.fileIcon}),e("span",{className:n.fileName,children:Ce||"Choose XML file..."})]}),e("label",{htmlFor:"malFile",className:n.browseButton,children:"Browse"})]})}),e("div",{className:n.optionsArea,children:[e("label",{className:n.checkboxLabel,children:[e("input",{type:"checkbox",checked:I,onChange:a=>Le(a.currentTarget.checked),className:n.checkbox,disabled:A||g.isPending}),e("span",{className:n.checkboxCustom}),e("div",{className:n.optionText,children:[e("span",{className:n.optionTitle,children:"Erase current watchlist"}),e("span",{className:n.optionDesc,children:"Delete existing watchlist before importing."})]})]}),e("label",{className:n.checkboxLabel,children:[e("input",{type:"checkbox",checked:F,onChange:a=>Je(a.currentTarget.checked),className:n.checkbox,disabled:A||g.isPending}),e("span",{className:n.checkboxCustom}),e("div",{className:n.optionText,children:[e("span",{className:n.optionTitle,children:"Use offline database (fast)"}),e("span",{className:n.optionDesc,children:"Match by MAL ID locally first - instant and avoids AniList rate limits."})]})]}),e("label",{className:n.checkboxLabel,children:[e("input",{type:"checkbox",checked:$,onChange:a=>Ye(a.currentTarget.checked),className:n.checkbox,disabled:A||g.isPending}),e("span",{className:n.checkboxCustom}),e("div",{className:n.optionText,children:[e("span",{className:n.optionTitle,children:"Skip online fallback"}),e("span",{className:n.optionDesc,children:"Only import offline matches. Unmatched titles are skipped without API calls."})]})]})]}),R==="username"?e("button",{className:n.syncBtn,onClick:()=>g.mutate({erase:I,useOfflineDb:F,skipFallback:$}),disabled:!D.trim()||g.isPending,children:[e(c,{name:"download"}),g.isPending?"Importing...":"Start Import"]}):e("div",{className:n.actions,children:A?e(ce,{onClick:en,className:n.cancelBtn,children:"Cancel Import"}):e(ce,{onClick:Ve,className:n.importBtn,disabled:!Ce,children:[e(c,{name:"upload"})," Start Import"]})}),R==="username"&&g.isError&&e("div",{className:`${n.statusMessage} ${n.error}`,children:g.error.message}),A&&u&&e("div",{className:n.progressSection,children:[e("div",{className:n.progressBar,children:e("div",{className:n.progressFill,style:{width:`${nn}%`}})}),e("div",{className:n.progressInfo,children:[e("span",{className:n.progressCount,children:[u.current," / ",u.total]}),e("span",{className:n.progressTitle,children:u.found?e(m,{children:[u.matchedTitle,e("span",{className:`${n.sourceBadge} ${n[u.source||"anilist"]}`,children:u.source==="kitsu"?"Kitsu":u.source==="offline"?"Offline DB":"AniList"})]}):e("span",{className:n.skipped,children:["Skipped: ",u.title]})})]})]}),te&&e("div",{className:`${n.statusMessage} ${n.success}`,children:["Import complete! Imported: ",te.imported,", Skipped: ",te.skipped,"."]}),je&&e("div",{className:`${n.statusMessage} ${n.error}`,children:je})]})}),v&&e("div",{className:n.importCard,children:[e("div",{className:n.cardHeader,children:e("div",{className:n.cardTitleRow,children:[e(c,{name:"myanimelist",className:n.malIcon}),e("h3",{children:"MyAnimeList Manga"})]})}),e("div",{className:n.radioGroup,children:[e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"malMangaMode",value:"username",checked:X==="username",onChange:()=>Ne("username")}),e("span",{children:"Username"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"malMangaMode",value:"xml",checked:X==="xml",onChange:()=>Ne("xml")}),e("span",{children:"XML File"})]})]}),X==="username"?e("div",{className:n.inputGroup,children:e("input",{type:"text",placeholder:"Enter MAL username",value:B,onChange:a=>fe(a.currentTarget.value),className:n.input,disabled:N.isPending,onKeyDown:a=>{a.key==="Enter"&&B.trim()&&N.mutate()}})}):e("div",{className:n.uploadArea,children:e("div",{className:n.fileInputWrapper,children:[e("input",{type:"file",id:"malMangaFile",accept:".xml,application/xml",className:n.fileInput,onChange:a=>Xe(a.currentTarget.files?.[0]?.name??""),disabled:z}),e("div",{className:n.fileDisplay,children:[e(c,{name:"file-alt",className:n.fileIcon}),e("span",{className:n.fileName,children:Ie||"Choose XML file..."})]}),e("label",{htmlFor:"malMangaFile",className:n.browseButton,children:"Browse"})]})}),e("div",{className:n.optionsArea,children:e("label",{className:n.checkboxLabel,children:[e("input",{type:"checkbox",checked:C,onChange:a=>me(a.currentTarget.checked),className:n.checkbox,disabled:N.isPending||z}),e("span",{className:n.checkboxCustom}),e("div",{className:n.optionText,children:[e("span",{className:n.optionTitle,children:"Replace AniList-linked manga"}),e("span",{className:n.optionDesc,children:"Clears previously imported (anilist:) entries before importing. Your provider bookmarks are never touched."})]})]})}),X==="username"?e("button",{className:n.syncBtn,onClick:()=>N.mutate(),disabled:!B.trim()||N.isPending,children:[e(c,{name:"download"}),N.isPending?"Importing...":"Start Import"]}):e("div",{className:n.actions,children:e(ce,{onClick:ze,className:n.importBtn,disabled:z||!Ie,children:[e(c,{name:"upload"})," ",z?"Importing...":"Start Import"]})}),N.isError&&e("div",{className:`${n.statusMessage} ${n.error}`,children:N.error.message}),we&&e("div",{className:`${n.statusMessage} ${n.error}`,children:we}),ne&&e("div",{className:`${n.statusMessage} ${n.success}`,children:["Import complete! Imported: ",ne.imported,", Skipped:"," ",ne.skipped,"."]}),e("p",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)",marginTop:"8px"},children:"MAL manga is matched to AniList by MAL ID with a title fallback. Unmatched titles are skipped. Imports land as AniList-linked entries alongside your provider bookmarks."})]})]})};export{Ia as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._fullscreenFlat_10bzs_1{border-radius:0}@media(max-width:900px)and (orientation:landscape){._fullscreenFlat_10bzs_1{border-radius:0}}@container (max-width: 26rem){._timeDisplay_10bzs_12{display:none}._bottomControls_10bzs_16{padding:0 .75rem .75rem}._leftControls_10bzs_20,._rightControls_10bzs_21{gap:.2rem}._controlBtn_10bzs_25{padding:5px;min-width:2.125rem;min-height:2.125rem}}._controlsOverlay_10bzs_32{position:absolute;inset:0;opacity:1;transition:opacity .4s cubic-bezier(.4,0,.2,1);z-index:50;pointer-events:none;display:flex;flex-direction:column;justify-content:space-between;background:radial-gradient(circle,transparent 20%,rgba(0,0,0,.4) 100%)}._controlsOverlay_10bzs_32>*{pointer-events:auto}._controlsOverlay_10bzs_32._hidden_10bzs_52{opacity:0;pointer-events:none;cursor:none}._topControls_10bzs_58{position:absolute;top:0;left:0;right:0;display:flex;align-items:center;gap:var(--space-6);background:linear-gradient(to bottom,rgba(0,0,0,.85) 0%,rgba(0,0,0,.45) 60%,transparent 100%);padding:var(--space-8) var(--space-10);transition:transform .4s cubic-bezier(.2,.8,.2,1);z-index:10;pointer-events:auto}._backBtn_10bzs_78{background:transparent;border:none;color:#ffffffd9;font-size:1.6rem;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--transition-fast);padding:8px;border-radius:50%}._backBtn_10bzs_78:hover{background:#0f0f1199;color:#fff;transform:scale(1.1)}._videoTitleInfo_10bzs_98{display:flex;flex-direction:column;gap:.25rem}._animeTitle_10bzs_104{font-size:1.4rem;font-weight:800;color:#fff;letter-spacing:-.01em;text-shadow:0 2px 4px rgba(0,0,0,.5)}._episodeLabel_10bzs_112{font-size:.85rem;font-weight:600;color:#ffffffbf;text-shadow:0 2px 4px rgba(0,0,0,.5)}._speedBoostBadge_10bzs_119{position:absolute;top:1.5rem;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.7rem;padding:.65rem 1rem;border:1px solid color-mix(in srgb,var(--accent) 45%,transparent);border-radius:var(--radius-md);background:#121216eb;color:#f5f3ff;font-size:.85rem;font-weight:800;letter-spacing:.06em;z-index:11;pointer-events:none}._speedBoostBadge_10bzs_119 span{line-height:1}._speedBoostBadge_10bzs_119 svg{display:block;flex-shrink:0}._bottomControls_10bzs_16{position:absolute;bottom:0;left:0;right:0;background:linear-gradient(to top,rgba(0,0,0,.85) 0%,rgba(0,0,0,.45) 60%,transparent 100%);padding:0 clamp(.5rem,1.5cqw,.75rem) clamp(.75rem,2.5cqw,1.5rem);z-index:10;pointer-events:auto;transition:transform .4s cubic-bezier(.2,.8,.2,1)}._progressBarContainer_10bzs_165{width:100%;height:20px;display:flex;align-items:center;cursor:pointer;position:relative;touch-action:none}@media(pointer:coarse){._progressBarContainer_10bzs_165{height:28px}._progressBarContainer_10bzs_165 ._progressBar_10bzs_165{height:6px}._progressBarContainer_10bzs_165 ._thumb_10bzs_184{opacity:1}}._progressBar_10bzs_165{width:100%;height:4px;background:#fff3;border-radius:2px;position:relative;transition:height .15s ease}._progressBarContainer_10bzs_165:hover ._progressBar_10bzs_165{height:6px}._bufferedBar_10bzs_202{position:absolute;top:0;left:0;height:100%;background:#ffffff4d;border-radius:2px;pointer-events:none}._watchedBar_10bzs_212{position:absolute;top:0;left:0;height:100%;background:var(--accent);border-radius:2px;pointer-events:none}._thumb_10bzs_184{position:absolute;top:50%;width:12px;height:12px;background:#fff;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 4px #0006;pointer-events:none;opacity:0;transition:opacity .15s ease}._progressBarContainer_10bzs_165:hover ._thumb_10bzs_184,._progressBarContainer_10bzs_165._scrubbing_10bzs_237 ._thumb_10bzs_184{opacity:1}._timeBubble_10bzs_241{position:absolute;bottom:24px;background:#000000d9;color:#fff;padding:4px 8px;border-radius:4px;font-size:.8rem;font-weight:500;transform:translate(-50%);pointer-events:none;white-space:nowrap}._bottomControlsRow_10bzs_255{display:flex;align-items:center;justify-content:space-between;gap:.75rem;margin-top:8px}._leftControls_10bzs_20{display:flex;align-items:center;gap:1rem;gap:clamp(.5rem,2.5cqw,1rem);min-width:0}._rightControls_10bzs_21{display:flex;align-items:center;gap:.75rem;gap:clamp(.5rem,2cqw,.75rem)}._nextEpisodeBtn_10bzs_278{background:#ffffff0f;border:1px solid rgba(255,255,255,.12);border-radius:var(--radius-md);padding:.45rem .8rem;color:#fffc;font-weight:600;font-size:.9rem;display:inline-flex;align-items:center;gap:.5rem;cursor:pointer;transition:all var(--transition-fast);white-space:nowrap}._nextEpisodeBtn_10bzs_278:hover{background:#ffffff1a;color:#fff;transform:translateY(-1px);border-color:#fff3}._controlBtn_10bzs_25{background:transparent;border:none;color:#ffffffd9;font-size:1.1rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:8px;border-radius:4px;transition:all var(--transition-fast);min-width:2.125rem;min-height:2.125rem;flex:0 0 auto}@media(pointer:coarse){._controlBtn_10bzs_25{padding:10px;min-width:2.75rem;min-height:2.75rem}}._controlBtn_10bzs_25:hover{color:#fff;background:#ffffff1a}._controlBtn_10bzs_25:focus{outline:none}._controlBtn_10bzs_25:focus-visible{outline:2px solid var(--accent-light);outline-offset:2px}._controlBtn_10bzs_25._active_10bzs_340{color:var(--accent)}._timeDisplay_10bzs_12{color:#fffc;font-size:.85rem;font-weight:500;font-variant-numeric:tabular-nums;min-width:100px}._settingsPanel_10bzs_352{position:absolute;bottom:clamp(6rem,15vh,8rem);right:clamp(1rem,3vw,2rem);background:#141418f2;border:1px solid var(--border-secondary);border-radius:var(--radius-md);width:max-content;min-width:12rem;max-width:min(19rem,calc(100vw - 1.5rem));font-size:.85rem;z-index:60;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 8px 32px #00000080;display:flex;flex-direction:column;overflow:hidden}._settingsHeader_10bzs_371{display:flex;align-items:center;padding:.55rem .75rem;border-bottom:1px solid var(--border-secondary);gap:.625rem}._settingsBackBtn_10bzs_379{background:transparent;border:none;color:#ffffffd9;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:4px;border-radius:4px;transition:all var(--transition-fast)}._settingsBackBtn_10bzs_379:hover{background:#ffffff1a;color:#fff}._settingsTitle_10bzs_397{font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._settingsContent_10bzs_408{overflow-y:auto;padding:.375rem;display:flex;flex-direction:column;gap:.125rem;max-height:min(56vh,22rem)}._currentValue_10bzs_417{color:var(--text-tertiary);font-size:.8rem;font-weight:500}._menuItem_10bzs_423{display:flex;align-items:center;justify-content:space-between;gap:.75rem;width:100%;min-height:2rem;padding:.5rem .75rem;background:transparent;border:none;color:var(--text-primary);font-size:.85rem;cursor:pointer;border-radius:var(--radius-sm);transition:background-color var(--transition-fast);text-align:left;white-space:nowrap}._menuItem_10bzs_423:hover{background:var(--bg-tertiary)}._menuItem_10bzs_423._active_10bzs_340{background:color-mix(in srgb,var(--accent) 18%,transparent);color:var(--accent-lighter)}._currentValue_10bzs_417{color:var(--text-secondary);font-size:.85rem}._menuNote_10bzs_456{padding:.5rem .75rem;font-size:.7rem;line-height:1.5;color:var(--text-tertiary);white-space:normal;overflow-wrap:break-word}._loadingOverlay_10bzs_465{position:absolute;inset:0;display:flex;justify-content:center;align-items:center;z-index:10;background:#00000080;border-radius:inherit}._loadingDots_10bzs_476{display:flex;gap:10px}._dot_10bzs_481{width:12px;height:12px;border-radius:50%;background-color:var(--accent);animation:_bounce_10bzs_1 1.4s infinite ease-in-out both;box-shadow:0 0 10px var(--accent-glow)}._dot_10bzs_481:nth-child(1){animation-delay:-.32s}._dot_10bzs_481:nth-child(2){animation-delay:-.16s}@keyframes _bounce_10bzs_1{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}._bufferingOverlay_10bzs_510{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);pointer-events:none;z-index:20}._bufferingSpinner_10bzs_519{width:50px;height:50px;border:4px solid rgba(255,255,255,.3);border-radius:50%;border-top-color:var(--accent);animation:_spin_10bzs_1 1s ease-in-out infinite}@keyframes _spin_10bzs_1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media(pointer:coarse){._settingsPanel_10bzs_352{font-size:.9rem;bottom:calc(env(safe-area-inset-bottom,0px) + 7rem);right:max(.75rem,env(safe-area-inset-right,0px))}._menuItem_10bzs_423{min-height:2.75rem}._settingsContent_10bzs_408{max-height:52vh}}@media(max-width:480px){._settingsPanel_10bzs_352{min-width:9rem;max-width:calc(100vw - 2rem);font-size:.75rem;bottom:calc(env(safe-area-inset-bottom,0px) + 6rem)}._settingsHeader_10bzs_371{padding:.4rem .625rem}._settingsTitle_10bzs_397{font-size:.64rem}._menuItem_10bzs_423{min-height:2.25rem;padding:.45rem .625rem;font-size:.75rem;gap:.5rem}._settingsContent_10bzs_408{max-height:min(40vh,15rem)}}@media(max-height:500px)and (orientation:landscape){._settingsPanel_10bzs_352{bottom:7.25rem;right:2rem;min-width:10rem;max-width:min(15rem,calc(100vw - 1.5rem));font-size:.8rem}._menuItem_10bzs_423{min-height:2.5rem;font-size:.8rem}._settingsContent_10bzs_408{max-height:50vh;overflow-y:auto}}._statusMsg_zqb8u_1{padding:1rem;text-align:center;color:var(--text-secondary)}._statusMsg_zqb8u_1._error_zqb8u_7{color:#f87171}._spinner_zqb8u_11{animation:_spin_zqb8u_11 1s linear infinite;margin-right:.5rem}._sourceLoader_zqb8u_16{padding:.75rem;display:flex;justify-content:center}._ringSpinner_zqb8u_22{width:40px;height:40px;border:4px solid rgba(255,255,255,.1);border-left-color:var(--accent);border-radius:50%;animation:_spin_zqb8u_11 1s linear infinite}@keyframes _spin_zqb8u_11{0%{transform:rotate(0)}to{transform:rotate(360deg)}}._meta_zqb8u_40{display:flex;align-items:center;gap:.75rem;margin:.5rem 0;flex-wrap:wrap}._year_zqb8u_48{color:var(--text-secondary);font-size:.9rem}._rating_zqb8u_53{display:inline-flex;align-items:center;gap:4px;color:var(--accent-lighter);font-weight:600;font-size:.9rem}._typeBadge_zqb8u_62{padding:2px 10px;border-radius:4px;font-size:.75rem;font-weight:600;text-transform:uppercase}._typeBadge_zqb8u_62._tv_zqb8u_70{background:color-mix(in srgb,var(--accent) 20%,transparent);color:var(--accent)}._typeBadge_zqb8u_62._movie_zqb8u_75{background:color-mix(in srgb,var(--accent-lighter) 20%,transparent);color:var(--accent-lighter)}._controlLabel_zqb8u_80{display:flex;flex-direction:column;gap:.3rem;font-size:.8rem;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em}._select_zqb8u_90{height:42px;padding:0 1rem;border-radius:var(--radius-md);border:1px solid var(--border-primary);background:var(--bg-elevated);color:var(--text-primary);font-size:.9rem;cursor:pointer;min-width:160px}._playerSection_zqb8u_102{margin:0;border-radius:0;overflow:hidden;overflow:clip;isolation:isolate;background:#000;position:relative}._video_zqb8u_106{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:contain;display:block;background:#000;border:none;border-radius:inherit}._videoHidden_zqb8u_128{opacity:0;pointer-events:none}._delayCanvas_zqb8u_133{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:contain;opacity:0;pointer-events:none;z-index:2;border-radius:inherit}._delayCanvasActive_zqb8u_146{opacity:1}._subtitleOverlay_zqb8u_150{position:absolute;top:0;left:0;width:100%;height:100%;z-index:3;pointer-events:none;overflow:hidden;border-radius:inherit}@media(max-width:900px)and (orientation:landscape){._playerSection_zqb8u_102{margin:0;border-radius:0}}._videoIframe_zqb8u_169{width:100%;aspect-ratio:16 / 9;min-height:400px;border:none;background:#000}._retryButton_zqb8u_177{margin-left:8px;padding:4px 10px;border-radius:4px;border:1px solid var(--border-primary);background:var(--bg-elevated);color:var(--text-primary);cursor:pointer;font-size:.8rem}._retryButton_zqb8u_177:hover{border-color:var(--accent)}._sidebarSeason_zqb8u_192{display:flex;flex-direction:column;gap:.4rem;font-size:.75rem;font-weight:700;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.1em;margin-bottom:var(--space-4)}._sidebarSeason_zqb8u_192 ._select_zqb8u_90{width:100%}._mobileSeasonRow_zqb8u_208{display:none}@media(max-width:768px){._mobileSeasonRow_zqb8u_208{display:block}._mobileSeasonRow_zqb8u_208 ._sidebarSeason_zqb8u_192{margin-bottom:0}}._providerSelectWrap_zqb8u_222{display:flex;align-items:flex-end;gap:1rem;flex-wrap:wrap;min-width:0}._genreRow_zqb8u_230{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.6rem}._genreChip_zqb8u_237{padding:.2rem .7rem;border-radius:20px;border:1px solid var(--glass-border);background:#ffffff0d;color:var(--text-secondary);font-size:.78rem;font-weight:600}._metaRow_zqb8u_247{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.6rem;color:var(--text-secondary);font-size:.9rem}._detailGrid_zqb8u_256{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:1.1rem 1.25rem;align-content:start;min-width:0}._detailItem_zqb8u_264{display:flex;flex-direction:column;gap:.2rem;padding:0;border-radius:0;border:0;background:none}._detailItem_zqb8u_264 strong{font-size:.75rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-tertiary)}._detailItem_zqb8u_264 span{color:var(--text-primary);font-size:.9rem}._imdbLink_zqb8u_286{color:var(--accent-light);font-size:.9rem;text-decoration:none}._imdbLink_zqb8u_286:hover{text-decoration:underline}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{u as t,d as S,A as P,h as v,S as Le,g as jr,q as T,o as Gr,p as Qr,a as Xr,T as Te}from"./vendor-core-DfaOB3Rn.js";import{u as Jr}from"./vendor-query-BBT5_sHx.js";import{g as nn,t as vt,W as Zr,J as Ln,e as es,A as ts,M as ur,B as ot}from"./index-BLh_CXtu.js";import{I as H}from"./vendor-icons-DrybRNxP.js";import{S as ns,U as rs,p as $n,M as ss,x as br,f as Dn,d as as,C as os,a as is,b as ls,c as en,u as cs,i as us,j as ds,m as ms,k as hs,l as bs,s as Bn,e as fs,g as ps,h as gs,r as vs,n as Me,A as ys,o as Ss,E as _s,v as Ts,P as Cs,q as de,w as ks,R as Es}from"./AvSyncCalibrator-C5GxpyPE.js";import{S as Ns,O as Pn,a as xs,A as Is,b as As}from"./OptionListMenu-CIvW5WmO.js";import{M as ws}from"./MatureConsentModal-BsdpNeXA.js";import{u as Ms}from"./useProviders-z8L8GKy0.js";import{d as Ls,g as Bs,h as Ps,f as Rs,e as zs,j as $s,k as Ds}from"./useTvLibrary-B4vcRzQc.js";import{l as Os,s as Vs,a as Rn,d as Fs,S as qs,h as dr}from"./playbackCompletion-DuUs8u-8.js";import{l as Us,c as Ws}from"./hls-DOAVt6Ry.js";import{u as Hs}from"./useIsMobile-Dvx1uJ82.js";import{S as Ks}from"./SynopsisText-B3Sa5pRv.js";import"./libraryInvalidation-AzFLnbjH.js";const Ys="_fullscreenFlat_10bzs_1",js="_timeDisplay_10bzs_12",Gs="_bottomControls_10bzs_16",Qs="_leftControls_10bzs_20",Xs="_rightControls_10bzs_21",Js="_controlBtn_10bzs_25",Zs="_controlsOverlay_10bzs_32",ea="_hidden_10bzs_52",ta="_topControls_10bzs_58",na="_backBtn_10bzs_78",ra="_videoTitleInfo_10bzs_98",sa="_animeTitle_10bzs_104",aa="_episodeLabel_10bzs_112",oa="_speedBoostBadge_10bzs_119",ia="_progressBarContainer_10bzs_165",la="_progressBar_10bzs_165",ca="_thumb_10bzs_184",ua="_bufferedBar_10bzs_202",da="_watchedBar_10bzs_212",ma="_scrubbing_10bzs_237",ha="_timeBubble_10bzs_241",ba="_bottomControlsRow_10bzs_255",fa="_nextEpisodeBtn_10bzs_278",pa="_active_10bzs_340",ga="_settingsPanel_10bzs_352",va="_settingsHeader_10bzs_371",ya="_settingsBackBtn_10bzs_379",Sa="_settingsTitle_10bzs_397",_a="_settingsContent_10bzs_408",Ta="_currentValue_10bzs_417",Ca="_menuItem_10bzs_423",ka="_menuNote_10bzs_456",Ea="_loadingOverlay_10bzs_465",Na="_loadingDots_10bzs_476",xa="_dot_10bzs_481",Ia="_bufferingOverlay_10bzs_510",Aa="_bufferingSpinner_10bzs_519",o={fullscreenFlat:Ys,timeDisplay:js,bottomControls:Gs,leftControls:Qs,rightControls:Xs,controlBtn:Js,controlsOverlay:Zs,hidden:ea,topControls:ta,backBtn:na,videoTitleInfo:ra,animeTitle:sa,episodeLabel:aa,speedBoostBadge:oa,progressBarContainer:ia,progressBar:la,thumb:ca,bufferedBar:ua,watchedBar:da,scrubbing:ma,timeBubble:ha,bottomControlsRow:ba,nextEpisodeBtn:fa,active:pa,settingsPanel:ga,settingsHeader:va,settingsBackBtn:ya,settingsTitle:Sa,settingsContent:_a,currentValue:Ta,menuItem:Ca,menuNote:ka,loadingOverlay:Ea,loadingDots:Na,dot:xa,bufferingOverlay:Ia,bufferingSpinner:Aa},wa=({player:a,visible:m,settingsOpen:V,onOpenSettings:M,onCloseSettings:R,hasSubtitles:A,isSubtitleActive:r,subtitles:_,onSubtitleChange:s,showNextEpisodeButton:C,onNextEpisode:F,isTheaterMode:z,onTheaterModeToggle:h,timeLabelRef:j})=>{const{state:d,refs:qe,actions:O}=a,X=qe.videoRef,Be=E=>{const te=X.current;!te||isNaN(d.duration)||d.duration===0||(te.currentTime=E*d.duration)},Pe=()=>{X.current&&(O.setIsScrubbing(!0),O.wasPlayingBeforeScrub.current=!X.current.paused,X.current.pause())},Ue=E=>{const te=X.current;te&&d.duration&&(te.currentTime=E*d.duration)},We=()=>{O.setIsScrubbing(!1),O.wasPlayingBeforeScrub.current&&X.current?.play().catch(()=>{})},Qe=E=>{const te=X.current;te&&(te.volume=E,te.muted=E===0)},ie=()=>{if(r){s(-1);return}let E=null;try{E=localStorage.getItem("tvLastSubtitle")}catch{}s($n(_,{lastKey:E,enabled:!0}))},G=d.isMuted?t(H,{name:"volume-mute"}):d.volume<.5?t(H,{name:"volume-down"}):t(H,{name:"volume-up"});return t("div",{className:`${o.controlsOverlay} ${m?"":o.hidden}`,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none",justifyContent:"flex-end"},children:t("div",{className:o.bottomControls,onClick:E=>E.stopPropagation(),children:[t(ns,{classes:{container:o.progressBarContainer,scrubbing:o.scrubbing,timeBubble:o.timeBubble,bar:o.progressBar,buffered:o.bufferedBar,watched:o.watchedBar,thumb:o.thumb},videoRef:X,duration:d.duration,formatTime:nn,isScrubbing:d.isScrubbing,buffered:"full",onSeek:Be,onScrubStart:Pe,onScrubMove:Ue,onScrubEnd:We,timeLabelRef:j}),t("div",{className:o.bottomControlsRow,children:[t("div",{className:o.leftControls,children:[t("button",{className:o.controlBtn,onClick:O.togglePlay,"aria-label":d.isPlaying?"Pause":"Play",children:d.isPlaying?t(H,{name:"pause"}):t(H,{name:"play"})}),t(rs,{muted:d.isMuted,volume:d.volume,volumeIcon:G,buttonClassName:o.controlBtn,onToggleMute:O.toggleMute,onVolumeChange:Qe,onExpandedChange:E=>O.setShowVolumeSlider(E)}),t("span",{className:o.timeDisplay,ref:j,children:[nn(0)," / ",nn(d.duration)]})]}),t("div",{className:o.rightControls,children:[C&&t("button",{className:o.nextEpisodeBtn,onClick:F,title:"Play next episode",children:"Next EP"}),A&&t("button",{className:`${o.controlBtn} ${r?o.active:""}`,onClick:ie,"aria-label":r?"Turn subtitles off":"Turn subtitles on",children:t(H,{name:"closed-captioning"})}),t("button",{className:`${o.controlBtn} ${V?o.active:""}`,onClick:()=>V?R():M(),"aria-label":"Settings",children:t(H,{name:"cog"})}),t("button",{className:`${o.controlBtn} ${z?o.active:""}`,onClick:E=>{E.stopPropagation(),h()},title:z?"Exit Theater Mode":"Theater Mode","aria-label":z?"Exit Theater Mode":"Theater Mode",children:t(H,{name:"tv"})}),t("button",{className:o.controlBtn,onClick:O.toggleFullscreen,"aria-label":d.isFullscreen?"Exit Fullscreen":"Fullscreen",children:d.isFullscreen?t(H,{name:"compress"}):t(H,{name:"expand"})})]})]})]})})},tn=-6e4,zn=6e4,mr=500,Ma=({classes:a,delayMs:m,onDelayChange:V})=>{const[M,R]=S(null),A=M??m,r=P(V);r.current=V;const _=P(m);_.current=m;const s=P(null);s.current=M,v(()=>{R(null)},[m]),v(()=>()=>{const z=s.current;z!==null&&z!==_.current&&r.current(z)},[]);const C=z=>{_.current=z,s.current=null,r.current(z),R(null)},F=z=>{const h=s.current??_.current,j=Math.max(tn,Math.min(zn,h+z));C(j)};return t(Le,{children:[t("div",{style:{display:"flex",gap:6,padding:"0.5rem 0.75rem 0.25rem"},children:[t("button",{type:"button",className:a.item,onClick:()=>F(-mr),"aria-label":"Show subtitles 0.5 seconds earlier",style:{flex:1,justifyContent:"center"},children:t("span",{children:"-0.5s"})}),t("button",{type:"button",className:a.item,onClick:()=>F(mr),"aria-label":"Show subtitles 0.5 seconds later",style:{flex:1,justifyContent:"center"},children:t("span",{children:"+0.5s"})}),t("button",{type:"button",className:a.item,onClick:()=>C(0),disabled:A===0,"aria-label":"Reset subtitle timing",style:{flex:1,justifyContent:"center"},children:t("span",{children:"Reset"})})]}),t(ss,{label:"Subtitle timing",display:br(A),min:tn,max:zn,step:100,value:A,percent:(A-tn)/(zn-tn)*100,onChange:z=>{const h=Math.round(z);s.current=h,R(h)},onCommit:()=>{const z=s.current;z!==null&&C(z)}}),t("div",{className:a.note,children:"Positive delays subtitles (show later). Negative shows them earlier. 0.0s is default."})]})},La=({view:a,onSelectView:m,onClose:V,player:M,onSubtitleStyleChange:R,streams:A,resolutionIdx:r,onResolutionChange:_,hasSubtitles:s,subtitles:C,selectedSubtitle:F,isSubtitleActive:z,onSubtitleChange:h,audioTracks:j,selectedAudioTrack:d,onAudioTrackChange:qe,videoDelayEnabled:O,onVideoDelayToggle:X,videoDelayMs:Be,onVideoDelayChange:Pe,onCalibrate:Ue,subtitleDelayMs:We,onSubtitleDelayChange:Qe,ambientSettings:ie,onAmbientChange:G})=>{const{state:E}=M,te=()=>t(Le,{children:[A.length>1&&t("button",{className:o.menuItem,onClick:()=>m("resolution"),children:[t("span",{children:"Resolution"}),t("span",{className:o.currentValue,children:A[r]?.quality||"Auto"})]}),s&&t("button",{className:o.menuItem,onClick:()=>m("subtitles"),children:[t("span",{children:"Subtitles"}),t("span",{className:o.currentValue,children:z?C[F]?.label||C[F]?.language:"Off"})]}),s&&t("button",{className:o.menuItem,onClick:()=>m("subtitle-style"),children:[t("span",{children:"Subtitle Style"}),t("span",{className:o.currentValue,children:[E.subtitleFontSize.toFixed(1),"x · ",E.subtitlePosition]})]}),s&&t("button",{className:o.menuItem,onClick:()=>m("subtitle-timing"),children:[t("span",{children:"Subtitle Timing"}),t("span",{className:o.currentValue,children:br(We)})]}),j.length>0&&t("button",{className:o.menuItem,onClick:()=>m("audio"),children:[t("span",{children:"Audio Track"}),t("span",{className:o.currentValue,children:j[d]?.label||j[d]?.language})]}),t("button",{className:o.menuItem,onClick:()=>m("av-sync"),children:[t("span",{children:"A/V Sync"}),t("span",{className:o.currentValue,children:O?`${Be}ms`:"Off"})]}),ie&&G&&t("button",{className:o.menuItem,onClick:()=>m("ambient"),children:[t("span",{children:"Ambient Light"}),t("span",{className:o.currentValue,children:ie.enabled?"On":"Off"})]})]}),Ce=()=>t(Pn,{classes:{item:o.menuItem,active:o.active},options:A.map((x,Y)=>({key:String(Y),label:x.quality,selected:Y===r})),onSelect:x=>_(Number(x))}),Q=()=>t(Pn,{classes:{item:o.menuItem,active:o.active},options:[{key:"off",label:"Off",selected:!z},...C.map((x,Y)=>({key:String(Y),label:x.label||x.language,selected:Y===F}))],onSelect:x=>h(x==="off"?-1:Number(x))}),ke=()=>t(xs,{classes:{item:o.menuItem,active:o.active},values:{fontSize:E.subtitleFontSize,position:E.subtitlePosition,bgOpacity:E.subtitleBgOpacity,bgColor:E.subtitleBgColor,textColor:E.subtitleTextColor,edge:E.subtitleEdge,bold:E.subtitleBold},onChange:R}),K=()=>t(Ma,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},delayMs:We,onDelayChange:x=>Qe?.(x)}),Re=()=>t(Pn,{classes:{item:o.menuItem,active:o.active},options:j.map((x,Y)=>({key:String(Y),label:x.label||x.language,selected:Y===d})),onSelect:x=>qe(Number(x))}),He=()=>t(Is,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},enabled:O,delayMs:Be,onToggle:x=>X?.(x),onDelayChange:x=>Pe?.(x),onCalibrate:Ue}),ge=()=>ie&&G?t(As,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},values:ie,onChange:G}):null;return t("div",{"data-speed-boost-ignore":"true",onClick:x=>x.stopPropagation(),children:t(Ns,{classes:{panel:o.settingsPanel,header:o.settingsHeader,backBtn:o.settingsBackBtn,title:o.settingsTitle,content:o.settingsContent},title:a==="main"?"Settings":a==="subtitle-style"?"Subtitle Style":a==="subtitle-timing"?"Subtitle Timing":a==="audio"?"Audio Track":a==="resolution"?"Resolution":a==="av-sync"?"A/V Sync":a==="ambient"?"Ambient Light":a.charAt(0).toUpperCase()+a.slice(1),onBack:()=>a==="main"?V():m("main"),children:[a==="main"&&te(),a==="resolution"&&Ce(),a==="subtitles"&&Q(),a==="subtitle-style"&&ke(),a==="subtitle-timing"&&K(),a==="audio"&&Re(),a==="av-sync"&&He(),a==="ambient"&&ge()]})})},Ba=({player:a,title:m,episodeLabel:V,audioTracks:M,selectedAudioTrack:R,onAudioTrackChange:A,subtitles:r,selectedSubtitle:_,onSubtitleChange:s,streams:C,resolutionIdx:F,onResolutionChange:z,onBack:h,children:j,videoDelayEnabled:d=!1,onVideoDelayToggle:qe,videoDelayMs:O=0,onVideoDelayChange:X,onCalibrateAvSync:Be,subtitleDelayMs:Pe=0,onSubtitleDelayChange:Ue,showNextEpisodeButton:We=!1,onNextEpisode:Qe,isLoading:ie=!1,isTheaterMode:G,onTheaterModeToggle:E,ambientSettings:te,onAmbientChange:Ce})=>{const{state:Q,refs:ke,actions:K}=a,Re=ke.videoRef,{subtitleFontSize:He,subtitlePosition:ge,subtitleBgOpacity:x,subtitleBgColor:Y,subtitleTextColor:it,subtitleEdge:le,subtitleBold:ze}=Q,[Ee,$e]=S(null),lt=P(null),[Lt,yt]=S(0);v(()=>{const Oe=Re.current;if(!Oe)return;const ve=()=>yt(Oe.clientHeight||0);ve();const Z=new ResizeObserver(ve);return Z.observe(Oe),()=>Z.disconnect()},[Re]);const Xe=K.setSubtitleStyle;v(()=>{const Oe="tv-player-subtitle-style";let ve=document.getElementById(Oe);ve||(ve=document.createElement("style"),ve.id=Oe,document.head.appendChild(ve));const Z={fontSize:He,position:ge,bgOpacity:x,bgColor:Y,textColor:it,edge:le,bold:ze},se=Re.current,Je=Dn(He,Lt||se?.clientHeight||720);if(ve.textContent=as({...Z,fontSize:Je}),se){const Ct=()=>{const B=Number(ge);return isNaN(B)?0:Math.max(0,Math.min(100,B))},ut=(B,ee)=>{try{const ne=B;ne.snapToLines=!1,ne.line=ee}catch{}},Rt=()=>{const B=Je*16,ee=se.videoHeight||se.clientHeight||720,ne=se.videoWidth||se.clientWidth||1280;return{step:B*1.3/ee*100,chars:Math.max(20,Math.floor(ne/(B*.55)))}},dt=B=>{const ee=Math.max(0,Math.min(100,100-Ct())),ne=Array.from(B.activeCues??[]);if(ne.length<=1){ne.forEach(ae=>ut(ae,ee));return}const{step:zt,chars:$t}=Rt();let Dt=ee;for(let ae=ne.length-1;ae>=0;ae--){const an=String(ne[ae].text??"").replace(/<[^>]*>/g,"").split(`
|
|
2
|
+
`).reduce((on,ln)=>on+Math.max(1,Math.ceil(ln.length/$t)),0),Ot=Dt-an*zt;ut(ne[ae],Math.max(0,Ot)),Dt=Ot-zt*.4}},p=()=>{const B=Math.max(0,Math.min(100,100-Ct()));Array.from(se.textTracks).forEach(ee=>{ee.cues&&(Array.from(ee.cues).forEach(ne=>ut(ne,B)),ee.mode==="showing"&&dt(ee))})};p();const l=B=>{const ee=B.target;ee.mode==="showing"&&dt(ee)},ce=()=>{Array.from(se.textTracks).forEach(B=>{B.removeEventListener("cuechange",l),B.addEventListener("cuechange",l)}),p()};Array.from(se.textTracks).forEach(B=>{B.addEventListener("cuechange",l)}),se.textTracks.addEventListener("addtrack",ce);const ue=Array.from(se.querySelectorAll("track")),kt=()=>p();return ue.forEach(B=>B.addEventListener("load",kt)),()=>{Array.from(se.textTracks).forEach(B=>{B.removeEventListener("cuechange",l)}),se.textTracks.removeEventListener("addtrack",ce),ue.forEach(B=>B.removeEventListener("load",kt))}}},[He,ge,x,Y,it,le,ze,_,r,Re,Lt]);const me=r.length>0,St=_>=0,_t=()=>{$e("main"),K.setShowControls(!0)},L=()=>{$e(null)},ct=Q.showControls||!!Ee,Bt=t(ls,{visible:ct,title:m,episode:V,onBack:h,classes:{overlay:o.controlsOverlay,hidden:o.hidden,top:o.topControls,backBtn:o.backBtn,titleInfo:o.videoTitleInfo,title:o.animeTitle,episode:o.episodeLabel}}),De=!ie&&!Q.isBuffering&&Q.duration>0?t(os,{isPlaying:Q.isPlaying,onTogglePlay:K.togglePlay,onSkipBack:()=>K.seek(-10),onSkipForward:()=>K.seek(10)}):null,Pt=t(wa,{player:a,visible:ct,settingsOpen:!!Ee,onOpenSettings:_t,onCloseSettings:L,hasSubtitles:me,isSubtitleActive:St,subtitles:r,onSubtitleChange:s,showNextEpisodeButton:We,onNextEpisode:Qe,isTheaterMode:G,onTheaterModeToggle:E,timeLabelRef:lt}),rn=Ee?t(La,{view:Ee,onSelectView:$e,onClose:L,player:a,onSubtitleStyleChange:Xe,streams:C,resolutionIdx:F,onResolutionChange:z,hasSubtitles:me,subtitles:r,selectedSubtitle:_,isSubtitleActive:St,onSubtitleChange:s,audioTracks:M,selectedAudioTrack:R,onAudioTrackChange:A,videoDelayEnabled:d,onVideoDelayToggle:qe,videoDelayMs:O,onVideoDelayChange:X,onCalibrate:()=>{$e(null),Be?.()},subtitleDelayMs:Pe,onSubtitleDelayChange:Ue,ambientSettings:te,onAmbientChange:Ce}):null,Tt=t(Le,{children:[ie&&t("div",{className:o.loadingOverlay,"aria-hidden":"true",children:t("div",{className:o.loadingDots,children:[t("div",{className:o.dot}),t("div",{className:o.dot}),t("div",{className:o.dot})]})}),Q.isBuffering&&!ie&&t("div",{className:o.bufferingOverlay,"aria-hidden":"true",children:t("div",{className:o.bufferingSpinner})}),Q.isSpeedBoostActive&&t("div",{className:o.speedBoostBadge,"aria-hidden":"true",children:[t("span",{children:"2x"}),t(H,{name:"forward",size:12})]})]});return t(is,{player:a,topBar:Bt,centerControls:De,bottomBar:!ie&&Q.duration>0?Pt:null,settingsPanel:rn,overlays:Tt,isInteracting:!!Ee,onStageClick:L,className:Q.isFullscreen?o.fullscreenFlat:"",children:j})},Pa=({servers:a,selectedServer:m,onServerSelect:V})=>a.length===0?null:t("div",{className:en.sourceSelectionContainer,children:[t("h4",{children:"Source"}),t("div",{className:en.sourceButtons,children:a.map(M=>t("button",{className:`${en.sourceButton} ${m===M?en.active:""}`,onClick:()=>V(M),children:M},M))})]}),Ra=jr.memo(Pa);function za({details:a,isMovie:m,season:V,episode:M,videoRef:R,active:A}){const r=P("");r.current||(r.current=`tv-${Date.now()}-${Math.random().toString(36).slice(2)}`);const _=T(()=>{if(!a)return;const s=R.current,C=m?"":`S${String(V).padStart(2,"0")}E${String(M).padStart(2,"0")}`;vt.discord.tvPresence.mutate({title:a.title,episodeLabel:C,isPlaying:s?!s.paused&&!s.ended:!0,thumbnail:a.poster,currentTime:s?s.currentTime:0,duration:s&&s.duration||0,isAdult:a.adult===!0,sessionId:r.current}).catch(()=>{}),vt.discord.heartbeat.mutate({sessionId:r.current}).catch(()=>{})},[a,m,V,M,R]);return v(()=>{if(!a)return;_();const s=window.setInterval(()=>{const C=R.current;(!C||!C.paused)&&_()},15e3);return()=>window.clearInterval(s)},[_,a,R]),v(()=>{if(!a||!A)return;const s=R.current;if(!s)return;const C=()=>_();return s.addEventListener("play",C),s.addEventListener("pause",C),s.addEventListener("seeked",C),()=>{s.removeEventListener("play",C),s.removeEventListener("pause",C),s.removeEventListener("seeked",C)}},[a,A,_,R]),v(()=>{const s=r.current,C=()=>Zr(s),F=()=>C();return window.addEventListener("pagehide",F),window.addEventListener("beforeunload",F),()=>{window.removeEventListener("pagehide",F),window.removeEventListener("beforeunload",F),C()}},[]),{sendPresence:_}}function $a(a,m,V){const M=()=>{const A=Array.isArray(a.audioTracks)?a.audioTracks.length:0,r=V.getWant(),_=A>0?Math.min(Math.max(0,r),A-1):r;a.audioTrack=_,_!==r&&V.onResolve(_)},R=(A,r)=>{const _=V.getWant(),s=Array.isArray(a.audioTracks)?a.audioTracks.length:0;if(r.id!==_&&_>=0&&_<s){a.audioTrack!==_&&(a.audioTrack=_);return}V.onResolve(r.id)};return a.on(m.MANIFEST_PARSED,M),a.on(m.AUDIO_TRACK_SWITCHED,R),()=>{a.off(m.MANIFEST_PARSED,M),a.off(m.AUDIO_TRACK_SWITCHED,R)}}const Da=/\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 Oa(){try{if(Da.test(navigator.userAgent||""))return!0;const a=navigator.deviceMemory;if(typeof a=="number"&&a>0&&a<2)return!0}catch{}return!1}const Va="_statusMsg_zqb8u_1",Fa="_error_zqb8u_7",qa="_spinner_zqb8u_11",Ua="_spin_zqb8u_11",Wa="_sourceLoader_zqb8u_16",Ha="_ringSpinner_zqb8u_22",Ka="_meta_zqb8u_40",Ya="_year_zqb8u_48",ja="_rating_zqb8u_53",Ga="_typeBadge_zqb8u_62",Qa="_tv_zqb8u_70",Xa="_movie_zqb8u_75",Ja="_controlLabel_zqb8u_80",Za="_select_zqb8u_90",eo="_playerSection_zqb8u_102",to="_video_zqb8u_106",no="_videoHidden_zqb8u_128",ro="_delayCanvas_zqb8u_133",so="_delayCanvasActive_zqb8u_146",ao="_subtitleOverlay_zqb8u_150",oo="_videoIframe_zqb8u_169",io="_retryButton_zqb8u_177",lo="_sidebarSeason_zqb8u_192",co="_mobileSeasonRow_zqb8u_208",uo="_providerSelectWrap_zqb8u_222",mo="_genreRow_zqb8u_230",ho="_genreChip_zqb8u_237",bo="_metaRow_zqb8u_247",fo="_detailGrid_zqb8u_256",po="_detailItem_zqb8u_264",go="_imdbLink_zqb8u_286",g={statusMsg:Va,error:Fa,spinner:qa,spin:Ua,sourceLoader:Wa,ringSpinner:Ha,meta:Ka,year:Ya,rating:ja,typeBadge:Ga,tv:Qa,movie:Xa,controlLabel:Ja,select:Za,playerSection:eo,video:to,videoHidden:no,delayCanvas:ro,delayCanvasActive:so,subtitleOverlay:ao,videoIframe:oo,retryButton:io,sidebarSeason:lo,mobileSeasonRow:co,providerSelectWrap:uo,genreRow:mo,genreChip:ho,metaRow:bo,detailGrid:fo,detailItem:po,imdbLink:go},vo=[],yo=[];function hr({error:a,onRetry:m}){return t("div",{className:`${g.statusMsg} ${g.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:a}),t("button",{className:g.retryButton,onClick:m,children:"Retry"})]})})}const Ro=()=>{const{id:a}=Gr(),[m]=Qr(),V=P(m);V.current=m;const M=Xr(),R=Jr(),A=m.get("type"),[r,_]=S(null),[s,C]=S(()=>parseInt(m.get("s")||"1",10)||1),[F,z]=S([]),[h,j]=S(()=>parseInt(m.get("e")||"1",10)||1),[d,qe]=S(()=>{try{return localStorage.getItem("tvProvider")||""}catch{return""}}),[O,X]=S([]),[Be,Pe]=S(""),{options:Ue,isFallback:We,isLoading:Qe}=Ms(),ie=Te(()=>Ue.filter(e=>(e.kind??"tv")==="tv").map(e=>({id:e.id,label:e.label,tier:e.tier==="embed"?"embed":"direct",servers:e.servers})),[Ue]),G=We||ie.length===0?vo:ie,E=G.filter(e=>e.tier==="direct"),te=G.filter(e=>e.tier==="embed"),[Ce,Q]=S(!1),[ke,K]=S(""),[Re,He]=S([]),[ge,x]=S(0),[Y,it]=S([]),[le,ze]=S(-1),[Ee,$e]=S(0),[lt,Lt]=S(""),[yt,Xe]=S(""),[me,St]=S(()=>{try{return localStorage.getItem("tvServer")||""}catch{return""}}),_t=Te(()=>G.find(e=>e.id===d),[G,d]),L=_t?.tier==="embed",[ct,Bt]=S([]),[De,Pt]=S(""),[rn,Tt]=S(""),[Oe,ve]=S(!1),Z=Te(()=>ct.length>0?ct:_t?.servers??[],[ct,_t]),se=Te(()=>De?["Embed",...Z]:Z,[Z,De]),Je=Oe&&!!De,Ct=Je?rn||De:"";v(()=>{if(!De){Tt("");return}let e=!1;return Ln(`/api/resolve?url=${encodeURIComponent(De)}`).then(n=>{!e&&n.finalUrl&&Tt(n.finalUrl)}).catch(()=>{}),()=>{e=!0}},[De]);const ut=P([]);v(()=>{ut.current=O},[O]);const Rt=P(ge);v(()=>{Rt.current=ge},[ge]);const dt=P(le);v(()=>{dt.current=le},[le]);const p=cs({skipIntervals:yo}),l=p.refs.videoRef,ce=P(null),ue=P([]),kt=P(null),B=P(null),{videoDelayMs:ee,videoDelayEnabled:ne,setDelayEnabled:zt,handleVideoDelayChange:$t,isCalibrating:Dt,testClipActive:ae,stopCalibration:sn,openAvSyncCalibrator:an,cancelAvSyncCalibrator:Ot,applyAvSyncCalibrator:on,toggleTestClip:ln,calibReturnRef:Vt,effectiveVideoDelayMs:cn}=us(l),[mt,fr]=S(()=>{try{const e=Number(localStorage.getItem("tvSubtitleDelayMs"));if(Number.isFinite(e)&&e>=-6e4&&e<=6e4)return Math.round(e)}catch{}return 0}),un=P(mt);un.current=mt;const pr=T(e=>{const n=Math.max(-6e4,Math.min(6e4,Math.round(e)));if(un.current!==n){un.current=n,fr(n);try{localStorage.setItem("tvSubtitleDelayMs",String(n))}catch{}}},[]);ds({videoRef:l,canvasRef:kt,delayMs:cn,enabled:ne});const dn=ne,ye=dn||mt!==0,{settings:mn,update:gr}=ms(),hn=P(ye);hn.current=ye;const bn=T(()=>{if(!hn.current)return;const e=l.current;e&&Array.from(e.textTracks).forEach(n=>{n.mode!=="hidden"&&(n.mode="hidden")})},[l]),{hasConsent:Et,grant:vr}=es(),b=A==="movie";za({details:r,isMovie:b,season:s,episode:h,videoRef:l,active:!L&&!Ce&&!ke&&O.length>0});const Ft=a?Ls(A||"tv",a):"",q=Ft,On=Bs(),qt=Ps(),{toggle:Vn,bookmarkedIds:yr,pending:Sr}=Rs(),{data:Fn}=zs(r?Ft:void 0),Ut=Fn?!!Fn.inLibrary:Ft?yr.has(Ft):!1,_r=T(()=>{!r||!a||Vn({tmdbId:Number(a),mediaType:A||"tv",title:r.title,poster:r.poster,year:r.year,adult:r.adult})},[r,a,A,Vn]),{data:Ze,isFetched:qn,isPending:Un}=$s(q||void 0,s,h),Wt=Te(()=>F.map(e=>e.episode_number).sort((e,n)=>e-n),[F]),et=Wt.indexOf(h),fn=et>0?Wt[et-1]:null,w=et>=0&&et<Wt.length-1?Wt[et+1]:null,Ht=Te(()=>(r?.seasons??[]).map(e=>e.season_number).filter(e=>Number.isFinite(e)).sort((e,n)=>e-n),[r]),Se=Te(()=>{if(b||w!=null)return null;const e=Ht.indexOf(s);return e>=0&&e<Ht.length-1?Ht[e+1]:(r?.number_of_seasons??0)>s?s+1:null},[b,w,Ht,s,r?.number_of_seasons]),Wn=Ze?.currentTime??0,Hn=Ze?.duration??0,pn=Ze?.completed===!0||Ze?.completed===1||Rn(Wn,Hn),[Ne,Ve]=S(!1),xe=P(!1),gn=P(null),Nt=P(null);v(()=>{xe.current=!1,Nt.current=null,Ve(!1)},[q,s,h]);const[Ie,Kt]=S(!1),[ht,Kn]=S(0),[tt,Yn]=S(!1),[Ke,nt]=S(!1),[Tr,vn]=S(!1),[Cr,jn]=S(""),[Yt,kr]=S(!1),[Er,yn]=S(!1),{isTheaterMode:Fe,toggleTheaterMode:Sn,handleLayoutClick:Nr}=hs();v(()=>{const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="t"&&Sn()};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[Sn]),bs(p,(O.length>0||yt!=="")&&!Fe&&!Ie&&!Ne&&!Ke);const xr=Hs(),[bt,Ir]=S(Os),Ar=T(e=>{Ir(e),Vs(e)},[]),he=P(!1),rt=P(null),_n=P(0),Gn=P(!1),Qn=P(0),J=P(null),xt=P(""),wr=dr(Wn,Hn),It=!he.current&&!xe.current&&(Ie||Ne||Ke||pn||wr),ft=P(It);ft.current=It;const pt=P(!1);v(()=>{pt.current=tt},[tt]);const Ye=T((e,n)=>{if(!q||!n||n<30)return;const i=Rn(e,n),u=i?n:e;Math.abs(u-_n.current)<10&&!i||(_n.current=u,On.mutate({mediaId:q,season:s,episode:h,currentTime:Math.floor(u),duration:Math.floor(n),completed:i,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:A||"tv",adult:r?.adult?1:0}))},[q,s,h,On,r,A]),Ae=T((e,n)=>{sn();const i=new URLSearchParams(m);i.set("type",m.get("type")||"tv"),i.set("s",String(e)),i.set("e",String(n)),M(`${window.location.pathname}?${i.toString()}`)},[m,M,sn]),At=T(()=>{const e=l.current;if(!e||b||w==null){vn(!1);return}const n=e.duration||0,i=e.currentTime||0;vn(n>0&&i/n>=.8)},[b,w,l]),jt=T((e,n)=>["tv-sources",d,b?"movie":"tv",a,e,n,me],[d,b,a,me]),Gt=T(async(e,n)=>{if(!r||!a||!d)return{valid:!1,sources:[]};const i=b?"movie":"tv",u=await vt.tv.sources.query({provider:d,type:i,tmdbId:String(a),season:e,episode:n,title:r.title||"",year:r.year||"",totalSeasons:String(r.number_of_seasons||1),imdbId:r.imdb_id||"",...Z.length>0&&me?{server:me}:{}});return{valid:"valid"in u?u.valid:!1,error:"error"in u?u.error:void 0,sources:u.sources,referer:"referer"in u?u.referer:void 0,audioTracks:u.audioTracks,subtitles:"subtitles"in u?u.subtitles:void 0,servers:"servers"in u?u.servers:void 0,embedUrl:"embedUrl"in u?u.embedUrl:void 0}},[r,a,d,b,Z,me]),Xn=T(()=>{if(b||!r||!a||!d||L||w==null)return;const e=jt(s,w);R.getQueryState(e)?.status!=="success"&&R.prefetchQuery({queryKey:e,queryFn:()=>Gt(s,w),staleTime:300*1e3,gcTime:1800*1e3})},[b,r,a,d,L,w,s,R,jt,Gt]),Mr=T(()=>{if(ae)return;At();const e=l.current;!e||e.paused||e.ended||(e.duration>0&&e.duration-e.currentTime<=60&&Xn(),rt.current&&clearTimeout(rt.current),rt.current=setTimeout(()=>{Ye(e.currentTime,e.duration||0)},5e3))},[Ye,l,ae,At,Xn]),Lr=T(()=>{const e=l.current;if(!e||!r)return;rt.current&&clearTimeout(rt.current),Ye(e.currentTime,e.duration||0),Gn.current=!0;const n=Fs({seekInduced:Date.now()-Qn.current<qs,autoplayEnabled:bt,hasNext:!b&&w!=null,isFinal:b||w==null});n==="advance"&&w!=null?(j(w),Ae(s,w)):n==="prompt-next"?(xe.current=!1,he.current=!0,Ve(!0)):n==="prompt-complete"&&(jn(b?r.title:`${r.title} - Season ${s}`),nt(!0),xe.current=!0,he.current=!0)},[b,r,s,w,bt,Ye,Ae,l]),Br=T(()=>{Gn.current=!1,p.actions.onPlay()},[p.actions]),Pr=T(()=>{p.actions.onPause();const e=l.current;e&&!e.ended&&Ye(e.currentTime,e.duration||0)},[p.actions,Ye,l]),Rr=T(()=>{p.actions.onLoadedMetadata();const e=l.current;if(e){try{const n=parseFloat(localStorage.getItem("playerVolume")||"");isNaN(n)||(e.volume=Math.max(0,Math.min(1,n))),e.muted=localStorage.getItem("playerMuted")==="true"}catch{}if(J.current!=null&&J.current>0){try{e.currentTime=J.current}catch{}J.current=null}At()}},[p.actions,l,At]),Tn=T(()=>{const e=l.current;if(e&&J.current!=null&&J.current>0){try{e.currentTime=J.current}catch{}J.current=null}},[l]),zr=T(()=>{ht>0&&(J.current=ht);const e=l.current;if(e&&ht>0){try{e.currentTime=ht,J.current=null}catch{}e.play().catch(()=>{})}Kt(!1),he.current=!0},[ht,l]),Jn=T(()=>{J.current=null;const e=l.current;e&&(e.currentTime=0,e.play().catch(()=>{})),Kt(!1),he.current=!0},[l]),$r=T(()=>{xe.current=!0,Ve(!1),he.current=!0},[]),Dr=T(()=>{xe.current=!0,Ve(!1),he.current=!0,J.current=null;const e=l.current;if(e){try{e.currentTime=0}catch{}e.play().catch(()=>{})}},[l]),Zn=T(()=>{w!=null&&(xe.current=!0,Ve(!1),he.current=!0,j(w),Ae(s,w))},[w,s,Ae]),er=T(()=>{Se!=null&&(xe.current=!0,Ve(!1),nt(!1),he.current=!0,C(Se),j(1),Ae(Se,1))},[Se,Ae]),Or=T(async()=>{if(q)try{await qt.mutateAsync({id:q,status:"Completed"}),nt(!1),Ve(!1),M("/")}catch{}},[q,qt,M]);v(()=>{he.current=!1,gn.current=null,Kt(!1),vn(!1),Kn(0),Yn(!1),pt.current=!1,J.current=null,xt.current=`${q}:${s}:${h}`,_n.current=0},[q,s,h]),v(()=>{qn&&(Yn(!0),pt.current=!0)},[qn,q,s,h]),v(()=>{if(!Ze||he.current)return;const e=`${q}:${s}:${h}`;if(gn.current===e)return;gn.current=e;const n=Ze,i=n.currentTime??0,u=n.duration??0;dr(i,u)&&(Kn(i),Kt(!0))},[Ze,q,s,h]),v(()=>{if(!tt||he.current||xe.current||Ie||Ke||Ne)return;const e=`${q}:${s}:${h}`;if(Nt.current!==e){if(!pn){Un||(Nt.current=e);return}if(b){Nt.current=e,Ve(!0);return}if(!(!r||et<0||F.length===0)){if(Nt.current=e,w==null&&Se==null){r&&F.length>0&&(jn(`${r.title} - Season ${s}`),nt(!0),xe.current=!0,he.current=!0);return}Ve(!0)}}},[tt,pn,Un,Ie,Ke,Ne,b,w,Se,r,et,F.length,q,s,h]),v(()=>{(Ie||Ne)&&l.current&&l.current.pause()},[Ie,Ne,l]),v(()=>{const e=l.current;return()=>{rt.current&&clearTimeout(rt.current),e&&!e.ended&&Ye(e.currentTime,e.duration||0)}},[Ye,l]);const Cn=T(e=>{let n=null,i=!0;try{n=localStorage.getItem("tvLastSubtitle"),i=localStorage.getItem("tvSubtitlesEnabled")!=="false"}catch{}return $n(e,{lastKey:n,enabled:i})},[]),kn=T(e=>{if(!(e<0))try{localStorage.setItem("tvSubtitlesEnabled","true"),localStorage.setItem("tvSelectedSubtitle",String(e))}catch{}},[]),tr=T(e=>{if(e.length===0)return 0;let n=null;try{n=localStorage.getItem("tvLastAudio")}catch{}if(n){const i=e.findIndex(f=>Bn(f)===n);if(i>=0)return i;const u=n.indexOf("|||"),c=u>=0?n.slice(0,u):n,I=u>=0?n.slice(u+3):n,$=e.findIndex(f=>f.language===c||f.label===I);if($>=0)return $}return $n(e,{lastKey:null,enabled:!0})},[]),{data:nr}=Ds(q||void 0),rr=Te(()=>(nr?.progress??[]).filter(n=>n.season===s&&(n.completed===1||n.completed===1||Rn(n.currentTime,n.duration))).map(n=>String(n.episode)),[nr,s]),sr=Te(()=>F.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})),[F]),ar=Te(()=>(r?.genres??[]).map(e=>e.name).slice(0,5),[r]),En=Te(()=>[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]);v(()=>{if(G.length!==0&&!G.some(e=>e.id===d)){const e=G.find(n=>n.tier==="direct")?.id??G[0].id;qe(e);try{localStorage.setItem("tvProvider",e)}catch{}}},[G,d]),v(()=>{Bt([]),Pt(""),Tt(""),ve(!1)},[d]),v(()=>{if(Z.length!==0&&!Z.includes(me)){St(Z[0]);try{localStorage.setItem("tvServer",Z[0])}catch{}}},[Z,me]),v(()=>{if(!a){_(null),X([]),Pe(""),K(""),Xe("");return}const e=Number(a),n=A||"tv";_(null),X([]),Pe(""),K(""),Xe("");const i=parseInt(V.current.get("s")||"",10),u=parseInt(V.current.get("e")||"",10);C(isNaN(i)?1:i),j(isNaN(u)?1:u),$e(0),vt.tv.details.query({type:n,id:String(e)}).then(c=>{const I={id:c.id,title:c.title||"",overview:c.overview||"",vote_average:c.vote_average,year:c.year,poster:c.poster,backdrop:c.backdrop,imdb_id:c.imdb_id||void 0,adult:c.adult,seasons:c.seasons,number_of_seasons:c.number_of_seasons};_(I),I.seasons&&I.seasons.length>0&&isNaN(i)&&C(I.seasons[0].season_number)}).catch(()=>{})},[a,A]),v(()=>{if(!r||!a)return;if(!(r.seasons!==void 0||r.number_of_seasons!==void 0)){z([]);return}const n=parseInt(m.get("e")||"",10);vt.tv.episodes.query({id:String(a),season:String(s)}).then(i=>{const u=(i.episodes||[]).map(c=>({episode_number:c.episode_number,name:c.name||"",vote_average:c.vote_average,overview:c.overview||"",still_path:c.still_path||""}));z(u),u.length!==0&&j(c=>!isNaN(n)&&u.some(I=>I.episode_number===n)?n:u.some(I=>I.episode_number===c)?c:u[0].episode_number)}).catch(()=>{})},[r,a,s,m]),v(()=>{if(!L||!r||!a)return;Ln(`/api/tv/embed/${d}/${b?"movie":"tv"}/${a}?season=${s}&episode=${h}`).then(n=>{if(n.url)return Xe(n.url),Ln(`/api/resolve?url=${encodeURIComponent(n.url)}`).then(i=>{i.finalUrl&&Xe(i.finalUrl)})}).catch(()=>{})},[d,r,a,s,h,b,L]);const Qt=T(async()=>{if(!r||!a||!d||L||r.adult&&!Et)return;const e=`${q}:${s}:${h}`;Q(!0),K(""),ut.current.length===0&&(X([]),$e(0),He([]),it([]));try{const n=await R.fetchQuery({queryKey:jt(s,h),queryFn:()=>Gt(s,h),staleTime:3e5,gcTime:18e5});if(xt.current!==e){Q(!1);return}if(Q(!1),!n.valid||!n.sources?.length){K(n.error?`${n.error}`:Z.length>0?`No streams from ${me}. Try another server.`:"No streams available.");return}X(n.sources),Pe(e),n.servers?.length&&Bt(n.servers),n.embedUrl&&Pt(n.embedUrl),$e(0),n.referer&&Lt(n.referer);const i=n.audioTracks||[];He(i),x(i.length>0?tr(i):0);const u=n.subtitles||[];if(it(u),u.length>0){const $=Cn(u);ze($),kn($)}else ze(-1);const c=b?"movie":"tv",I=a;vt.tv.subtitles.query({type:c,tmdbId:String(I),season:String(s),episode:String(h)}).then($=>{if(xt.current!==e)return;const f=Array.isArray($.subtitles)?$.subtitles:[];f.length!==0&&it(re=>{const be=[...re,...f.filter(y=>!re.some(fe=>fe.url===y.url))];if(re.length===0){const y=Cn(be);ze(y),kn(y)}return be})}).catch(()=>{}),K("")}catch(n){if(xt.current!==e)return;Q(!1),K(n instanceof Error?n.message:"Failed to load streams.")}},[r,a,d,s,h,b,L,Et,Z,me,Cn,kn,tr,q,R,jt,Gt]),Nn=T(()=>{const e=l.current;e&&!isNaN(e.currentTime)&&(J.current=e.currentTime)},[l]),Vr=T(e=>{if(e==="Embed"){ve(!0);return}Nn(),ve(!1),St(e);try{localStorage.setItem("tvServer",e)}catch{}K("")},[Nn]),Fr=T(e=>{qe(e);try{localStorage.setItem("tvProvider",e)}catch{}},[]);v(()=>{d&&r&&!L&&Qt()},[d,r,Qt,L]),v(()=>{if(!l.current)return;if(ce.current&&(ce.current.destroy(),ce.current=null),L||Je){const f=l.current;f&&(f.pause(),f.removeAttribute("src"),f.load());return}let e=!1;if(ae){const f=l.current;return f&&(f.pause(),f.removeAttribute("src"),f.load(),f.src="/av-sync-test.mp4",ft.current||f.play().catch(()=>{})),()=>{e=!0}}if(Vt.current!=null&&(J.current=Vt.current,Vt.current=null),xt.current===`${q}:${s}:${h}`&&J.current==null&&!ft.current)try{const f=l.current;f&&!f.ended&&f.currentTime>1&&(J.current=f.currentTime)}catch{}const i=J.current??0,u=!Ce&&Be===`${q}:${s}:${h}`?Je?"":O[Ee]?.url||"":"";if(!u){try{l.current?.pause(),l.current?.removeAttribute("src"),l.current?.load()}catch{}return}const c=l.current;c.pause(),c.removeAttribute("src"),c.load(),p.actions.resetMediaState();const I=`/api/tv/stream-proxy?url=${encodeURIComponent(u)}&referer=${encodeURIComponent(lt)}&provider=${encodeURIComponent(d)}`;O[Ee]?.type==="hls"?(async()=>{const f=await Us();if(!e)if(f&&f.isSupported()){const re=Oa()||document.body.classList.contains("low-end"),be=re?60:180,y=new f({enableWorker:!0,lowLatencyMode:!1,startPosition:i>0?i:-1,maxBufferLength:be,maxMaxBufferLength:be+(re?30:60),backBufferLength:re?30:60,maxBufferSize:(re?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}}}});ce.current=y,y.on(f.Events.ERROR,(D,N)=>{N.fatal&&(K(`Stream failed (${N.details}). Try another source or reload.`),Q(!1),y.destroy(),ce.current=null)}),y.loadSource(I),y.attachMedia(c);const fe=()=>{let D=!1,N=0;try{D=localStorage.getItem("tvSubtitlesEnabled")==="true";const k=parseInt(localStorage.getItem("tvSelectedSubtitle")||"0",10);!isNaN(k)&&k>=0&&(N=k)}catch{}return{enabled:D,index:N}},U=()=>{if(typeof y.subtitleTrack!="number")return;if(ue.current.length>0){y.subtitleTrack=-1;return}const D=Array.isArray(y.subtitleTracks)?y.subtitleTracks:[];if(D.length===0){y.subtitleTrack=-1;return}const N=fe();if(N.enabled){const k=N.index<D.length?N.index:0;y.subtitleTrack=k,ze(k),bn()}else y.subtitleTrack=-1};$a(y,f.Events,{getWant:()=>Rt.current,onResolve:D=>x(D)}),y.on(f.Events.MANIFEST_PARSED,()=>{U(),(i>0||!ft.current&&pt.current)&&c.play().catch(()=>p.actions.setShowControls(!0))}),y.on(f.Events.SUBTITLE_TRACKS_UPDATED,()=>{U()}),y.on(f.Events.SUBTITLE_TRACK_SWITCH,(D,N)=>{if(ue.current.length>0){if(N.id!==-1)try{y.subtitleTrack=-1}catch{}return}const k=Array.isArray(y.subtitleTracks)?y.subtitleTracks:[];if(k.length!==0){if(N.id===-1){const _e=fe();if(_e.enabled){const oe=_e.index<k.length?_e.index:0;y.subtitleTrack=oe;return}}ze(N.id),bn()}})}else Ws(c)&&(c.src=I,(i>0||!ft.current&&pt.current)&&c.play().catch(()=>{K("Failed to play stream. Try another source.")}))})():(c.src=I,(i>0||!ft.current&&pt.current)&&c.play().catch(()=>{K("Failed to play stream. Try another source.")}));const $=()=>{const be=c.error?.code===4?"Video source not supported or not found":"Failed to load video stream";K(`${be}. The source may be invalid or expired. Try switching source or reloading.`),Q(!1)};return c.addEventListener("error",$),()=>{e=!0,c.removeEventListener("error",$)}},[O,Be,Ce,Ee,d,lt,L,Je,l,Vt,ae,q,s,h,Tn,bn,p.actions]),v(()=>{if(!tt||Ie||Ne||Ke||It||L||ae)return;const e=l.current;!e||!e.paused||e.ended||e.readyState<1||(Tn(),e.play().catch(()=>{}))},[tt,Ie,Ne,Ke,It,L,ae,Tn,l]),v(()=>{const e=ce.current;!e||typeof e.audioTrack!="number"||(e.audioTrack=ge)},[ge]),v(()=>{const e=ce.current;!e||typeof e.subtitleTrack!="number"||!Array.isArray(e.subtitleTracks)||e.subtitleTracks.length===0||ue.current.length>0||(le>=0?e.subtitleTrack=le:e.subtitleTrack=-1)},[le]),v(()=>{const e=l.current;if(!(!e||L)&&(e.querySelectorAll("track").forEach(n=>n.remove()),ue.current=[],Y.length!==0&&(Y.forEach(n=>{const i=document.createElement("track");i.kind="subtitles",i.label=n.label||n.language||"Unknown",i.srclang=n.language||n.label||"en";const u=`/api/subtitle-proxy?url=${encodeURIComponent(n.url)}&referer=${encodeURIComponent(lt)}`;i.src=u,i.addEventListener("load",()=>{const c=ue.current.indexOf(i),I=i.track;if(I&&c>=0){const $=c===dt.current;I.mode=$&&!hn.current?"showing":"hidden"}}),e.appendChild(i),ue.current.push(i)}),Y.length>0)))try{const n=ce.current;n&&typeof n.subtitleTrack=="number"&&n.subtitleTrack!==-1&&(n.subtitleTrack=-1)}catch{}},[Y,lt,L,d,l]),v(()=>{const e=l.current;if(!e||L)return;const n=ce.current;ue.current.length>0&&n&&typeof n.subtitleTrack=="number"&&Array.isArray(n.subtitleTracks)&&n.subtitleTracks.length>0&&(n.subtitleTrack=-1);const i=()=>{const I=Dn(p.state.subtitleFontSize,e.clientHeight||720),$=Math.max(0,Math.min(100,100-p.state.subtitlePosition)),f=()=>{const U=I*16,D=e.videoHeight||e.clientHeight||720,N=e.videoWidth||e.clientWidth||1280;return{step:U*1.3/D*100,chars:Math.max(20,Math.floor(N/(U*.55)))}},re=(U,D)=>{const N=U;N.snapToLines=!1,N.line=D},be=U=>{if(!U.cues)return;Array.from(U.cues).forEach(oe=>re(oe,$));const D=Array.from(U.activeCues??[]);if(D.length<=1){D.forEach(oe=>re(oe,$));return}const{step:N,chars:k}=f();let _e=$;for(let oe=D.length-1;oe>=0;oe--){const je=String(D[oe].text??"").replace(/<[^>]*>/g,"").split(`
|
|
3
|
+
`).reduce((Jt,wt)=>Jt+Math.max(1,Math.ceil(wt.length/k)),0);_e=Math.max(0,_e-je*N),re(D[oe],_e),_e-=N*.4}},y=ue.current;if(y.length>0){y.forEach((U,D)=>{const N=U.track;if(!N)return;const k=D===le;N.mode=k&&!ye?"showing":"hidden",k&&!ye&&be(N)});return}const fe=Array.from(e.textTracks);fe.length!==0&&fe.forEach((U,D)=>{const N=D===le;U.mode=N&&!ye?"showing":"hidden",N&&!ye&&be(U)})};i();const u=()=>i();e.textTracks.addEventListener("addtrack",u),e.addEventListener("loadedmetadata",i,{once:!0});const c=window.setTimeout(i,600);return()=>{e.textTracks.removeEventListener("addtrack",u),e.removeEventListener("loadedmetadata",i),window.clearTimeout(c)}},[le,Y,L,d,l,ye,p.state.subtitleFontSize,p.state.subtitlePosition]),v(()=>{if(!ye)return;const e=l.current,n=B.current;if(!e||!n)return;const i=mt/1e3,u=cn/1e3,c=new Set;let I=[],$=-1,f=-1,re=-1,be=-1,y=0,fe=0,U=!1;const D=()=>{const W=dt.current;if(W<0)return null;const Ge=ue.current;return Ge.length>0?Ge[W]?.track??null:Array.from(e.textTracks)[W]??null},N=(W,Ge)=>{const pe=W.cues;if(!pe||pe.length===0)return Array.from(W.activeCues??[]);let st=0,at=pe.length;for(;st<at;){const we=st+at>>>1;pe[we].endTime+i<Ge?st=we+1:at=we}const Mt=[];for(let we=st;we<pe.length;we++){const Zt=pe[we];if(Zt.startTime+i>Ge)break;Zt.endTime+i>=Ge&&Mt.push(Zt)}return Mt},k=()=>{const W=D(),Ge=e.currentTime-u,pe=W?N(W,Ge):[],st=e.clientWidth,at=e.clientHeight,Mt=e.videoWidth,we=e.videoHeight;if(pe.length===I.length&&pe.every((An,wn)=>An===I[wn])&&st===$&&at===f&&Mt===re&&we===be||(I=pe,$=st,f=at,re=Mt,be=we,n.textContent="",pe.length===0))return;const lr={fontSize:Dn(p.state.subtitleFontSize,at),position:p.state.subtitlePosition,bgOpacity:p.state.subtitleBgOpacity,bgColor:p.state.subtitleBgColor,textColor:p.state.subtitleTextColor,edge:p.state.subtitleEdge,bold:p.state.subtitleBold},Hr=fs(lr),Kr=ps(e,lr.position);pe.forEach((An,wn)=>{const cr=String(An.text??"");if(!gs(cr).trim())return;const Mn=document.createElement("div"),Yr=(pe.length-1-wn)*1.7;Mn.style.cssText=`${Hr}
|
|
4
|
+
bottom: calc(${Kr}px + ${Yr}em);`,Mn.innerHTML=vs(cr),n.appendChild(Mn)})},_e=()=>{Array.from(e.textTracks).forEach(W=>{c.has(W)||(c.add(W),W.addEventListener("cuechange",k))})},oe=()=>{_e(),k()},In=()=>{if(U||fe)return;const W=()=>{fe=0,!(U||e.paused||e.ended)&&(k(),In())};fe=window.requestAnimationFrame(W)},je=e,Jt=()=>{y=0,k(),!U&&je.requestVideoFrameCallback&&(y=je.requestVideoFrameCallback(Jt))},wt=()=>{k(),je.requestVideoFrameCallback?y||(y=je.requestVideoFrameCallback(Jt)):In()};_e(),e.textTracks.addEventListener("addtrack",oe),e.textTracks.addEventListener("removetrack",oe),e.addEventListener("timeupdate",k),e.addEventListener("seeked",k),e.addEventListener("loadedmetadata",k),e.addEventListener("play",wt);const or=Array.from(e.querySelectorAll("track"));or.forEach(W=>W.addEventListener("load",k));const ir=typeof ResizeObserver>"u"?null:new ResizeObserver(()=>k());return ir?.observe(e),k(),wt(),()=>{U=!0,c.forEach(W=>W.removeEventListener("cuechange",k)),e.textTracks.removeEventListener("addtrack",oe),e.textTracks.removeEventListener("removetrack",oe),e.removeEventListener("timeupdate",k),e.removeEventListener("seeked",k),e.removeEventListener("loadedmetadata",k),e.removeEventListener("play",wt),or.forEach(W=>W.removeEventListener("load",k)),ir?.disconnect(),fe&&window.cancelAnimationFrame(fe),y&&je.cancelVideoFrameCallback&&je.cancelVideoFrameCallback(y),n.textContent=""}},[ye,mt,le,Y,cn,l,p.state.subtitleFontSize,p.state.subtitlePosition,p.state.subtitleBgOpacity,p.state.subtitleBgColor,p.state.subtitleTextColor,p.state.subtitleEdge,p.state.subtitleBold]);const xn=()=>{_(null),X([]),Xe(""),M(-1)},qr=T(e=>{C(e),j(1),Ae(e,1)},[Ae]),Xt=!b&&r?.seasons&&r.seasons.length>1?t("label",{className:g.sidebarSeason,children:[t("span",{children:"Season"}),t("select",{value:s,onChange:e=>qr(parseInt(e.currentTarget.value,10)||1),className:g.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,gt=T(e=>{const n=parseInt(e,10);if(!isNaN(n)){try{l.current?.pause()}catch{}j(n),Ae(s,n)}yn(!1)},[s,Ae,l]);v(()=>{if(b)return;const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="n"&&(w!=null?gt(String(w)):ts.error("No next episode available"))};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[b,w,gt]);const Ur=e=>{x(e);try{const i=Re[e];i&&localStorage.setItem("tvLastAudio",Bn(i))}catch{}const n=ce.current;n&&n.audioTrack!==void 0&&(n.audioTrack=e)},Wr=e=>{ze(e);try{if(e===-1)localStorage.setItem("tvSubtitlesEnabled","false");else{localStorage.setItem("tvSubtitlesEnabled","true"),localStorage.setItem("tvSelectedSubtitle",String(e));const c=Y[e];c&&localStorage.setItem("tvLastSubtitle",Bn(c))}}catch{}const n=l.current,i=ce.current;if(i&&typeof i.subtitleTrack=="number"&&Array.isArray(i.subtitleTracks)&&i.subtitleTracks.length>0&&(i.subtitleTrack=ue.current.length>0||e<0?-1:e),!n)return;const u=ue.current;if(u.length>0){u.forEach((c,I)=>{const $=c.track;if(!$)return;const f=I===e;$.mode=f&&!ye?"showing":"hidden"});return}Array.from(n.textTracks).forEach((c,I)=>{const $=I===e;c.mode=$&&!ye?"showing":"hidden"})};return v(()=>{if(!r){document.title="TV & Movies - dango";return}document.title=b?`${r.title} - dango`:`${r.title} - Season ${s} Episode ${h} - dango`},[r,b,s,h]),v(()=>{if(!r||b)return;const e=new URLSearchParams(m),n=e.get("s"),i=e.get("e"),u=String(s),c=String(h);n===u&&i===c||(e.set("type",m.get("type")||"tv"),e.set("s",u),e.set("e",c),M(`${window.location.pathname}?${e.toString()}`,{replace:!0}))},[r,b,s,h,m,M]),t("div",{className:`${Me.playerPageLayout} ${Fe?Me.theaterMode:""} ${b?Me.noSidebar:""}`,onClick:Nr,children:[Fe&&t(ys,{videoRef:l,active:mn.enabled&&!L&&O.length>0&&!ke&&!(r?.adult&&!Et),settings:mn}),!Fe&&!b&&t("aside",{className:Me.episodeSidebar,children:r?t(Ss,{episodes:sr,currentEpisode:String(h),watchedEpisodes:rr,onEpisodeClick:gt,header:Xt}):t(_s,{variant:"sidebar"})}),t("div",{className:Me.playerMain,children:[r&&t("div",{className:g.playerSection,onContextMenu:e=>e.preventDefault(),style:r.adult&&!Et?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:L&&yt?t("iframe",{src:yt,className:g.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!L&&Ct?t("iframe",{src:Ct,className:g.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!L&&(O.length>0||Ce)?t(Le,{children:[ke&&t(hr,{error:ke,onRetry:Qt}),t(Ba,{player:p,title:r.title,episodeLabel:b?void 0:`S${s} E${h}`,audioTracks:Re,selectedAudioTrack:ge,onAudioTrackChange:Ur,subtitles:Y,selectedSubtitle:le,onSubtitleChange:Wr,streams:O,resolutionIdx:Ee,onResolutionChange:e=>{Nn(),$e(e)},onBack:xn,videoDelayEnabled:ne,onVideoDelayToggle:zt,videoDelayMs:ee,onVideoDelayChange:$t,onCalibrateAvSync:an,subtitleDelayMs:mt,onSubtitleDelayChange:pr,showNextEpisodeButton:Tr&&!Ie&&!Ne&&!Ke,onNextEpisode:Zn,isLoading:Ce,isTheaterMode:Fe,onTheaterModeToggle:Sn,ambientSettings:mn,onAmbientChange:gr,children:[t("video",{ref:l,autoPlay:tt&&!It,playsInline:!0,disablePictureInPicture:!0,className:`${g.video} ${dn?g.videoHidden:""}`,onTimeUpdate:Mr,onEnded:()=>{ae||Lr()},onPlay:Br,onPause:Pr,onSeeked:()=>{Qn.current=Date.now(),At()},onLoadedMetadata:Rr,onVolumeChange:p.actions.onVolumeChange,onWaiting:p.actions.onWaiting,onPlaying:p.actions.onPlaying,onCanPlay:p.actions.onCanPlay,onContextMenu:e=>e.preventDefault(),onError:()=>{K("Video failed to load. Try another server or reload."),Q(!1)}}),t("canvas",{ref:kt,className:`${g.delayCanvas} ${dn?g.delayCanvasActive:""}`}),ye&&t("div",{ref:B,className:g.subtitleOverlay}),t(Ts,{isOpen:Dt,ms:ee,onChange:$t,onApply:on,onClose:Ot,testClipActive:ae,onTestClip:ln})]})]}):ke&&!L?t(hr,{error:ke,onRetry:Qt}):null}),!Fe&&r&&t(Cs,{}),!Fe&&Xt&&t("div",{className:g.mobileSeasonRow,children:Xt}),!Fe&&r&&t("div",{className:de.streamPanel,children:[t("div",{className:g.providerSelectWrap,children:t("label",{className:g.controlLabel,children:["Provider",t("select",{value:d,onChange:e=>Fr(e.currentTarget.value),className:g.select,disabled:G.length===0,children:Qe?t("option",{value:"",children:"Loading..."}):G.length===0?t("option",{value:"",children:"No providers available"}):t(Le,{children:[E.length>0&&t("optgroup",{label:"Direct HLS",children:E.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&&(Ce?t("div",{className:g.sourceLoader,children:t("div",{className:g.ringSpinner})}):t(Ra,{servers:se,selectedServer:Oe?"Embed":me,onServerSelect:Vr}))]}),!Fe&&r&&t("div",{className:Me.playerInfoContainer,children:[t("div",{className:Me.playerInfoHeader,children:[t("div",{className:Me.playerAnimeCard,children:r.poster&&t("img",{src:`https://image.tmdb.org/t/p/w342${r.poster}`,alt:r.title,loading:"lazy",decoding:"async"})}),t("div",{className:Me.videoTitleSection,children:[t("div",{className:de.titleContainer,children:[t("h1",{children:r.title}),t("div",{className:g.meta,children:[t("span",{className:g.year,children:r.year}),r.vote_average!=null&&r.vote_average>0&&t("span",{className:g.rating,children:[t(H,{name:"star",size:12}),Number(r.vote_average).toFixed(1)]}),t("span",{className:`${g.typeBadge} ${g[b?"movie":"tv"]}`,children:b?"Movie":"TV Show"})]}),ar.length>0&&t("div",{className:g.genreRow,children:ar.map(e=>t("span",{className:g.genreChip,children:e},e))}),En.length>0&&t("div",{className:g.metaRow,children:En.map((e,n)=>t("span",{children:[e,n<En.length-1?" · ":""]},`${e}-${n}`))})]}),t("div",{className:de.controls,children:[t("button",{className:`${de.watchlistBtn} ${Ut?de.inList:""}`,onClick:_r,disabled:Sr,type:"button",children:[Ut?t(H,{name:"check",size:14}):t(H,{name:"plus",size:14}),Ut?"In Watchlist":"Add to Watchlist"]}),!b&&t(Le,{children:[t("button",{className:`${de.watchlistBtn}`,onClick:()=>fn!=null&>(String(fn)),disabled:fn==null,type:"button",children:[t(H,{name:"chevron-left",size:14}),"Prev EP"]}),t("button",{className:`${de.watchlistBtn}`,onClick:()=>w!=null&>(String(w)),disabled:w==null,type:"button",children:["Next EP",t(H,{name:"chevron-right",size:14})]}),!b&&t("button",{className:`${de.watchlistBtn} ${de.modeToggleBtn} ${bt?de.modeToggleActive:""}`,onClick:()=>Ar(!bt),type:"button","aria-pressed":bt,children:bt?"AUTOPLAY: ON":"AUTOPLAY: OFF"}),xr&&t("button",{className:`${de.watchlistBtn}`,onClick:()=>yn(!0),type:"button",children:[t(H,{name:"list-ul",size:14}),"Episodes"]})]})]})]})]}),t("div",{className:Me.infoColumns,children:[t("div",{className:`${de.descriptionSection} ${de.synopsisFlat}`,children:[t("h3",{children:"Synopsis"}),t(Ks,{text:r.overview,emptyText:"No description available."}),t("button",{className:de.detailsToggleBtn,onClick:()=>kr(!Yt),type:"button",children:[Yt?t(H,{name:"chevron-up"}):t(H,{name:"chevron-down"}),Yt?"Hide Details":"Show Details"]})]}),Yt&&t("div",{className:g.detailGrid,children:[r.first_air_date&&t("div",{className:g.detailItem,children:[t("strong",{children:b?"Release Date":"First Air Date"}),t("span",{children:r.first_air_date})]}),r.last_air_date&&t("div",{className:g.detailItem,children:[t("strong",{children:"Last Air Date"}),t("span",{children:r.last_air_date})]}),r.networks&&r.networks.length>0&&t("div",{className:g.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:g.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:g.detailItem,children:[t("strong",{children:"Episode Runtime"}),t("span",{children:[r.episode_run_time[0]," min"]})]}),r.imdb_id&&t("div",{className:g.detailItem,children:[t("strong",{children:"IMDb"}),t("a",{href:`https://www.imdb.com/title/${r.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:g.imdbLink,children:"View on IMDb"})]})]})]})]}),!b&&t(ks,{isOpen:Er,onClose:()=>yn(!1),episodes:sr,currentEpisode:String(h),watchedEpisodes:rr,onEpisodeClick:gt,header:Xt}),r?.adult&&!Et&&t(ws,{isOpen:!0,onClose:xn,onGrant:vr}),t(Es,{isOpen:Ie,onClose:Jn,title:"Resume Watching",message:t(Le,{children:["You were at ",t("strong",{children:nn(ht)})]}),restartLabel:"Start from Beginning",onResume:zr,onRestart:Jn}),t(ur,{isOpen:Ne,onClose:$r,title:b?"Movie Completed":"Episode Completed",children:t("div",{style:{padding:"1rem",textAlign:"center"},children:[t("p",{children:b?t(Le,{children:"You've already watched this movie."}):t(Le,{children:["You've already watched"," ",t("strong",{children:["Season ",s," Episode ",h]}),". Would you like to continue?"]})}),t("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center",flexWrap:"wrap"},children:[t(ot,{variant:"secondary",onClick:Dr,children:"Replay"}),w!=null?t(ot,{onClick:Zn,children:["Watch EP ",w]}):Se!=null?t(ot,{onClick:er,children:["Start Season ",Se]}):null]})]})}),t(ur,{isOpen:Ke,onClose:()=>nt(!1),title:b?"Movie Completed!":Se!=null?"Season Complete!":"Show Completed!",children:t("div",{style:{padding:"1rem",textAlign:"center"},children:[t(H,{name:"check-circle",size:48,style:{color:"var(--accent-lighter)",marginBottom:"0.5rem"}}),t("p",{style:{fontSize:"1.1rem",fontWeight:600},children:Cr}),t("p",{style:{color:"var(--text-secondary)"},children:b?"You finished this movie!":Se!=null?`You finished Season ${s}.`:"Congratulations! You finished all available episodes."}),t("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center",flexWrap:"wrap"},children:[t(ot,{variant:"secondary",onClick:()=>nt(!1),children:"Close"}),Se!=null?t(ot,{onClick:er,children:["Start Season ",Se]}):t(Le,{children:[t(ot,{onClick:()=>{nt(!1),xn()},children:"Back to Details"}),Ut&&t(ot,{onClick:Or,disabled:qt.isPending,children:qt.isPending?"Saving...":"Move to Completed"})]})]})]})}),!r&&t("div",{className:g.statusMsg,children:[t(H,{name:"spinner",className:g.spinner})," Loading..."]})]})]})};export{Ro as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as R,a as q,p as E,d as l,h as C,T,u as e,g as F}from"./vendor-core-DfaOB3Rn.js";import{I as a}from"./vendor-icons-DrybRNxP.js";import{e as j,t as U,B as w}from"./index-BLh_CXtu.js";import{n as H,d as J,e as K,f as Q,t as I}from"./useTvLibrary-B4vcRzQc.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-AzFLnbjH.js";const X="_container_198yg_1",Y="_heroSection_198yg_11",Z="_bannerContainer_198yg_17",ee="_banner_198yg_17",ne="_bannerOverlay_198yg_37",te="_heroContent_198yg_49",se="_posterContainer_198yg_62",ae="_poster_198yg_62",oe="_infoGlass_198yg_86",ie="_title_198yg_100",re="_quickMeta_198yg_110",le="_metaItem_198yg_118",ce="_iconStar_198yg_126",de="_iconTv_198yg_130",me="_iconType_198yg_134",_e="_genres_198yg_139",he="_genre_198yg_139",ge="_metaRow_198yg_156",ve="_metaValue_198yg_164",pe="_metaDivider_198yg_168",ue="_synopsisSection_198yg_173",ye="_sectionTitleSmall_198yg_179",ke="_synopsis_198yg_173",be="_actions_198yg_196",Ne="_watchBtn_198yg_202",Se="_watchlistBtn_198yg_226",fe="_active_198yg_250",Ce="_seasonPickerLabel_198yg_256",Te="_seasonSelect_198yg_267",we="_detailsToggleBtn_198yg_286",Ie="_expandedContent_198yg_304",Be="_detailGrid_198yg_309",De="_detailItem_198yg_315",Me="_imdbLink_198yg_333",Le="_heroSkeleton_198yg_343",Pe="_skeletonBanner_198yg_347",$e="_skeletonContent_198yg_354",Ge="_skeletonPoster_198yg_365",xe="_skeletonInfo_198yg_373",Oe="_skeletonTitle_198yg_380",Ae="_skeletonMeta_198yg_388",Ve="_skeletonDesc_198yg_396",We="_skeletonActions_198yg_404",ze="_errorState_198yg_413",Re="_matureOverlay_198yg_434",qe="_matureContent_198yg_444",n={container:X,heroSection:Y,bannerContainer:Z,banner:ee,bannerOverlay:ne,heroContent:te,posterContainer:se,poster:ae,infoGlass:oe,title:ie,quickMeta:re,metaItem:le,iconStar:ce,iconTv:de,iconType:me,genres:_e,genre:he,metaRow:ge,metaValue:ve,metaDivider:pe,synopsisSection:ue,sectionTitleSmall:ye,synopsis:ke,actions:be,watchBtn:Ne,watchlistBtn:Se,active:fe,seasonPickerLabel:Ce,seasonSelect:Te,detailsToggleBtn:we,expandedContent:Ie,detailGrid:Be,detailItem:De,imdbLink:Me,heroSkeleton:Le,skeletonBanner:Pe,skeletonContent:$e,skeletonPoster:Ge,skeletonInfo:xe,skeletonTitle:Oe,skeletonMeta:Ae,skeletonDesc:Ve,skeletonActions:We,errorState:ze,matureOverlay:Re,matureContent:qe};function Ke(){const{id:o}=R(),c=q(),[B]=E(),i=H(B.get("type")),{hasConsent:D}=j(),[t,M]=l(null),[L,_]=l(!0),[u,y]=l(""),[d,P]=l(!1),[h,$]=l(1),G=J(i,o??""),x=Number(o),{data:O}=K(t?G:void 0),g=!!O?.inLibrary,{toggle:A}=Q();C(()=>{o&&(_(!0),y(""),U.tv.details.query({type:i,id:String(o)}).then(s=>{const m={id:s.id,title:s.title||"",overview:s.overview||"",vote_average:s.vote_average,year:s.year,poster:s.poster,backdrop:s.backdrop,imdb_id:s.imdb_id||void 0,adult:s.adult,seasons:s.seasons?.map(z=>({...z,name:""})),number_of_seasons:s.number_of_seasons};M(m),_(!1)}).catch(s=>{y(s.message),_(!1)}))},[o,i]),C(()=>{document.title=t?.title?`${t.title} - dango`:"TV & Movies - dango"},[t?.title]);const V=()=>{!o||!t||c(r?I(i,o):I(i,o,h,1))},W=()=>{t&&A({tmdbId:x,mediaType:i,title:t.title,poster:t.poster,year:t.year,adult:t.adult})},r=i==="movie",v=!r,k=t?.backdrop?`https://image.tmdb.org/t/p/w1280${t.backdrop}`:"",b=t?.poster?`https://image.tmdb.org/t/p/w500${t.poster}`:"",N=T(()=>t?.genres?t.genres.map(s=>s.name).slice(0,5):[],[t?.genres]),S=T(()=>t?.seasons?t.seasons.filter(s=>s.season_number>0):[],[t?.seasons]),p=[t?.year,t?.status,v&&t?.number_of_seasons?`${t.number_of_seasons} Season${t.number_of_seasons>1?"s":""}`:null,v&&t?.number_of_episodes?`${t.number_of_episodes} Episodes`:null].filter(Boolean);if(L)return e("div",{className:n.container,children:e("div",{className:n.heroSkeleton,children:[e("div",{className:n.skeletonBanner}),e("div",{className:n.skeletonContent,children:[e("div",{className:n.skeletonPoster}),e("div",{className:n.skeletonInfo,children:[e("div",{className:n.skeletonTitle}),e("div",{className:n.skeletonMeta}),e("div",{className:n.skeletonDesc}),e("div",{className:n.skeletonActions})]})]})]})});if(u||!t)return e("div",{className:n.container,children:e("div",{className:n.errorState,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Failed to load details"}),e("p",{children:u||"Something went wrong"}),e(w,{onClick:()=>c(-1),children:"Go Back"})]})});const f=t.adult&&!D;return e("div",{className:n.container,style:f?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:[e("div",{className:n.heroSection,children:[e("div",{className:n.bannerContainer,children:[k&&e("div",{className:n.banner,style:{backgroundImage:`url(${k})`}}),e("div",{className:n.bannerOverlay})]}),e("div",{className:n.heroContent,children:[e("div",{className:n.posterContainer,children:b&&e("img",{src:b,alt:t.title,className:n.poster,decoding:"async"})}),e("div",{className:n.infoGlass,children:[e("div",{children:[e("h1",{className:n.title,children:t.title}),e("div",{className:n.quickMeta,children:[t.vote_average!=null&&t.vote_average>0&&e("div",{className:n.metaItem,children:[e(a,{name:"star",className:n.iconStar}),e("span",{children:Number(t.vote_average).toFixed(1)})]}),e("div",{className:n.metaItem,children:[e(a,{name:"tv",className:n.iconTv}),e("span",{children:r?"Movie":"TV Show"})]}),t.vote_count!=null&&e("div",{className:n.metaItem,children:[e(a,{name:"users",className:n.iconType}),e("span",{children:[t.vote_count.toLocaleString()," votes"]})]})]}),N.length>0&&e("div",{className:n.genres,children:N.map(s=>e("span",{className:n.genre,children:s},s))})]}),p.length>0&&e("div",{className:n.metaRow,children:p.map((s,m)=>e(F.Fragment,{children:[e("span",{className:n.metaValue,children:s}),m<p.length-1&&e("span",{className:n.metaDivider,children:"·"})]},m))}),t.overview&&e("div",{className:n.synopsisSection,children:[e("h2",{className:n.sectionTitleSmall,children:"Synopsis"}),e("p",{className:n.synopsis,children:t.overview})]}),e("div",{className:n.actions,children:[e("button",{className:n.watchBtn,onClick:V,children:[e(a,{name:"play",size:14}),r?"Watch Now":`Start S${h}`]}),e("button",{className:`${n.watchlistBtn} ${g?n.active:""}`,onClick:W,children:[g?e(a,{name:"check",size:14}):e(a,{name:"plus",size:14}),g?"In Watchlist":"Add to Watchlist"]})]}),v&&S.length>1&&e("label",{className:n.seasonPickerLabel,children:[e("span",{children:"Season"}),e("select",{value:h,onChange:s=>$(parseInt(s.currentTarget.value,10)||1),className:n.seasonSelect,children:S.map(s=>e("option",{value:s.season_number,children:["Season ",s.season_number," (",s.episode_count," Episodes)"]},s.season_number))})]}),e("button",{className:n.detailsToggleBtn,onClick:()=>P(!d),children:[d?e(a,{name:"chevron-up"}):e(a,{name:"chevron-down"}),d?"Hide Details":"Show Details"]}),d&&e("div",{className:n.expandedContent,children:e("div",{className:n.detailGrid,children:[t.first_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:r?"Release Date":"First Air Date"}),e("span",{children:t.first_air_date})]}),t.last_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:"Last Air Date"}),e("span",{children:t.last_air_date})]}),t.networks&&t.networks.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Networks"}),e("span",{children:t.networks.map(s=>s.name).join(", ")})]}),t.created_by&&t.created_by.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Created By"}),e("span",{children:t.created_by.map(s=>s.name).join(", ")})]}),t.episode_run_time&&t.episode_run_time.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Episode Runtime"}),e("span",{children:[t.episode_run_time[0]," min"]})]}),t.imdb_id&&e("div",{className:n.detailItem,children:[e("strong",{children:"IMDb"}),e("a",{href:`https://www.imdb.com/title/${t.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:n.imdbLink,children:"View on IMDb"})]})]})})]})]})]}),f&&e("div",{className:n.matureOverlay,children:e("div",{className:n.matureContent,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Content Warning"}),e("p",{children:"This content may contain mature themes."}),e(w,{onClick:()=>c("/"),children:"Go Back"})]})})]})}export{Ke as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as n,h as b,T,u as _}from"./vendor-core-DfaOB3Rn.js";import{f as k,d as m,c as w,t as I}from"./useTvLibrary-B4vcRzQc.js";import{t as P,h as D}from"./index-BLh_CXtu.js";import{a as W}from"./MediaCard-C1jNesfK.js";const S=({item:e,anchorRect:l,onMouseEnter:i,onMouseLeave:c,onRequestClose:p})=>{const[t,u]=n(null),[d,r]=n(!0),{toggle:v,bookmarkedIds:g}=k(),y=m(e.type,e.id),f=g.has(y);b(()=>{let o=!1;return r(!0),P.tv.details.query({type:e.type,id:String(e.id)}).then(s=>{o||(u({overview:s.overview,vote_average:s.vote_average,number_of_seasons:s.number_of_seasons}),r(!1))}).catch(()=>{o||r(!1)}),()=>{o=!0}},[e.id,e.type]);const h=T(()=>t?.genres?t.genres.slice(0,4).map(o=>o.name):[],[t?.genres]),a=[];return t?.vote_average!=null&&t.vote_average>0&&a.push({icon:"star",label:Number(t.vote_average).toFixed(1),accent:!0}),a.push({icon:"tv",label:e.type==="tv"?"TV Show":"Movie"}),e.year&&a.push({label:e.year}),t?.status&&a.push({label:t.status}),_(W,{anchorRect:l,title:e.title,loading:d,meta:a,genres:h,synopsis:D(t?.overview,200),primaryAction:{to:I(e.type,e.id),label:"Watch now",icon:"play"},secondaryAction:{to:w(e.type,e.id),label:"Details",icon:"info-circle"},bookmarked:f,onToggleBookmark:()=>v({tmdbId:e.id,mediaType:e.type,title:e.title,poster:e.image,year:e.year}),onMouseEnter:i,onMouseLeave:c,onRequestClose:p})};export{S as T};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{h as I,p as ae,A as re,d as o,T as Y,q as M,u as t}from"./vendor-core-DfaOB3Rn.js";import{I as h}from"./vendor-icons-DrybRNxP.js";import{P as D}from"./MediaCard-C1jNesfK.js";import{a as ne,T as se}from"./useTv-D4zQ1BsQ.js";import{S as le}from"./SkeletonGrid-CYJeh04P.js";import{u as ie,U as oe,B as x}from"./index-BLh_CXtu.js";import{E as ce}from"./ErrorMessage-DAxegITP.js";import{T as W,M as Q}from"./useTvLibrary-B4vcRzQc.js";import{s as r}from"./Search.module-C_qwCdHS.js";import"./vendor-ui-3qrARCPr.js";import"./useIsMobile-Dvx1uJ82.js";import"./MatureConsentModal-BsdpNeXA.js";import"./TvPopup-DHXB5ZSF.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-AzFLnbjH.js";const de=[{value:"multi",label:"All"},{value:"tv",label:"TV Shows"},{value:"movie",label:"Movies"}],ue=[{value:"popularity.desc",label:"Popularity"},{value:"vote_average.desc",label:"Top Rated"},{value:"primary_release_date.desc",label:"Newest"},{value:"primary_release_date.asc",label:"Oldest"},{value:"vote_count.desc",label:"Most Voted"}],O=new Date().getFullYear(),me=[{value:"ALL",label:"All Years"},...Array.from({length:O-1980+1},(l,m)=>({value:String(O-m),label:String(O-m)}))];function _e(){I(()=>{document.title="Search TV & Movies - dango"},[]);const[l,m]=ae(),{lowEndMode:K}=ie(),C=re(null),[g,U]=o(l.get("q")||""),[p,H]=o(l.get("q")||""),[u,v]=o(parseInt(l.get("page")||"1",10)||1),[i,J]=o(l.get("type")||"multi"),[$,k]=o(l.get("genre")||""),[y,B]=o(l.get("year")||"ALL"),[f,E]=o(l.get("sort_by")||"popularity.desc"),[b,X]=o(!1),[c,N]=o(()=>{const e={},a=l.get("genre")||"";return a&&(e[a]="include"),e}),P=Y(()=>{if(i==="tv")return Object.entries(W).map(([a,n])=>({id:a,name:n}));if(i==="movie")return Object.entries(Q).map(([a,n])=>({id:a,name:n}));const e=new Map;for(const[a,n]of Object.entries(W))e.set(a,n);for(const[a,n]of Object.entries(Q))e.set(a,n);return Array.from(e.entries()).map(([a,n])=>({id:a,name:n}))},[i]),S=Y(()=>Object.entries(c).filter(([,a])=>a==="include").map(([a])=>a).join(","),[c]),{data:L,isLoading:w,isError:Z,error:ee}=ne({query:p,type:i,genre:S,year:y,sort_by:f,page:u}),T=L?.results||[],_=L?.total_pages||0,j=L?.total_results||0,R=u<Math.min(_,500),d=M((e={})=>{const a=new URLSearchParams,n=e.q!==void 0?e.q:p,s=e.type!==void 0?e.type:i,G=e.year!==void 0?e.year:y,V=e.sort!==void 0?e.sort:f,F=e.page!==void 0?e.page:String(u),z=e.genre!==void 0?e.genre:S;n.trim()&&a.set("q",n.trim()),s!=="multi"&&a.set("type",s),z&&a.set("genre",z),G!=="ALL"&&a.set("year",G),V!=="popularity.desc"&&a.set("sort_by",V),F!=="1"&&a.set("page",F),m(a,{replace:!0})},[p,i,y,f,u,S,m]),A=M(()=>{oe(),v(1),H(g),d({q:g,page:"1"}),window.scrollTo({top:0,behavior:"smooth"})},[g,d]),q=M(e=>{if(v(e),d({page:String(e)}),C.current){const a=C.current.getBoundingClientRect().top+window.scrollY-100;window.scrollTo({top:a,behavior:"smooth"})}},[d]),te=M(e=>{N(a=>{const n=a[e],s={...a};return n==="include"?s[e]="exclude":n==="exclude"?delete s[e]:s[e]="include",s}),v(1)},[]);return I(()=>{const a=Object.entries(c).filter(([,n])=>n==="include").map(([n])=>n).join(",");a!==$&&(k(a),d({genre:a,page:"1"}))},[c,$,k,d]),t("div",{className:"page-container",children:[t("div",{className:r.header,children:[t("h1",{className:r.pageTitle,children:"Search TV & Movies"}),t("p",{className:r.pageSubtitle,children:"Discover trending shows, movies, and more powered by TMDB"})]}),t("div",{className:r.filterContainer,children:[t("div",{className:r.searchBarWrapper,children:[t("div",{className:r.inputIconWrapper,children:[t(h,{name:"search",className:r.searchIcon}),t("input",{type:"text","data-virtual-keyboard":"true",className:r.searchInput,placeholder:"Search titles...",value:g,onInput:e=>U(e.currentTarget.value),onKeyDown:e=>e.key==="Enter"&&A()})]}),t("div",{className:r.searchActions,children:[t("select",{value:i,onChange:e=>{J(e.currentTarget.value),N({})},className:r.providerSelect,"aria-label":"Media type",children:de.map(e=>t("option",{value:e.value,children:e.label},e.value))}),t(x,{onClick:A,className:r.searchBtn,children:"Search"}),t("button",{className:`${r.filterToggleBtn} ${b?r.active:""}`,onClick:()=>X(!b),children:[t(h,{name:"filter",size:14}),t("span",{children:"Filters"}),b?t(h,{name:"chevron-up",size:12}):t(h,{name:"chevron-down",size:12})]})]})]}),t("div",{className:`${r.advancedFilters} ${b?r.show:""}`,children:[t("div",{className:r.filterDivider}),t("div",{className:r.filterGrid,children:[t("div",{className:r.filterItem,children:[t("label",{children:"Sort By"}),t("select",{value:f,onChange:e=>E(e.currentTarget.value),children:ue.map(e=>t("option",{value:e.value,children:e.label},e.value))})]}),t("div",{className:r.filterItem,children:[t("label",{children:"Year"}),t("select",{value:y,onChange:e=>B(e.currentTarget.value),children:me.map(e=>t("option",{value:e.value,children:e.label},e.value))})]})]}),P.length>0&&t("div",{className:r.genreSection,children:[t("label",{className:r.genreLabel,children:"Genres"}),t("div",{className:r.genreContainer,children:P.map(e=>t("button",{className:`${r.genreButton} ${r[c[e.id]||""]}`,onClick:()=>te(e.id),children:e.name},e.id))})]}),t("div",{className:r.filterActions,children:[t(x,{variant:"secondary",onClick:()=>{N({}),B("ALL"),E("popularity.desc"),v(1),d({genre:"",year:"ALL",sort:"popularity.desc",page:"1"})},children:"Reset All"}),t(x,{onClick:A,className:r.searchBtn,children:"Apply Filters"})]})]})]}),Z&&t(ce,{message:ee?.message||"Search failed"}),Object.keys(c).length>0&&t("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px",marginBottom:"1.5rem"},children:[t("span",{style:{fontSize:"0.8rem",color:"var(--text-muted)",fontWeight:600},children:"Active Filters:"}),Object.entries(c).map(([e,a])=>{const n=P.find(s=>s.id===e)?.name||e;return t("span",{className:`badge ${a==="include"?"badge-primary":"badge-danger"}`,style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:[a==="include"?`+ ${n}`:`- ${n}`,t("button",{onClick:()=>{const s={...c};delete s[e],N(s)},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]},e)})]}),t("div",{className:r.resultsHeader,ref:C,children:[t("h2",{className:r.resultsTitle,children:[p?`Results for "${p}"`:S?"Browsing genres":i==="tv"?"Popular TV Shows":i==="movie"?"Popular Movies":"Trending",j>0&&t("span",{style:{fontWeight:400,color:"var(--text-tertiary)",fontSize:"0.85em",marginLeft:"0.5em"},children:["(",j.toLocaleString(),")"]})]}),T.length>0&&t(D,{page:u,totalPages:Math.max(1,Math.min(_,500)),canGoNext:R,onChange:q,isLoading:w})]}),t("div",{className:`${r.resultsGrid} ${K?r.lowEnd:""}`,children:w?t(le,{}):T.map(e=>t(se,{item:{id:e.id,title:e.title,year:e.year,type:e.type,image:e.image,vote_average:e.vote_average,adult:e.adult}},`${e.type}-${e.id}`))}),!w&&T.length===0&&t("div",{className:r.noResults,children:[t(h,{name:"search",size:48,className:r.noResultsIcon}),t("h3",{children:"No results found"}),t("p",{children:"Try adjusting your search or filters to find what you're looking for."})]}),T.length>0&&t("div",{className:r.bottomPagination,children:t(D,{page:u,totalPages:Math.max(1,Math.min(_,500)),canGoNext:R,onChange:q,isLoading:w,variant:"labeled"})})]})}export{_e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as $,d as f,h as L,T as U,u as d}from"./vendor-core-DfaOB3Rn.js";import{M as x}from"./MediaCard-C1jNesfK.js";import{L as F}from"./LibraryListPage-CRqv737t.js";import{R as N}from"./ResetProgressModal-BYNYqwwl.js";import{T as _}from"./TvPopup-DHXB5ZSF.js";import{g as u}from"./index-BLh_CXtu.js";import{l as q,u as K,a as O,b as Q,h as Y,m as z,o as G,p as Z,t as y,i as R,q as I}from"./useTvLibrary-B4vcRzQc.js";import"./vendor-icons-DrybRNxP.js";import"./vendor-ui-3qrARCPr.js";import"./useIsMobile-Dvx1uJ82.js";import"./MatureConsentModal-BsdpNeXA.js";import"./SkeletonGrid-CYJeh04P.js";import"./ErrorMessage-DAxegITP.js";import"./LibraryListPage.module-r6k9nyT9.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-AzFLnbjH.js";const j=["All","Continue Watching",...I],S=24;function ct(){const{filter:l="All"}=$(),[c,m]=f(1),[s,v]=f(null);L(()=>{document.title="TV Watchlist - dango"},[]),L(()=>{m(1)},[l]);const o=l==="Continue Watching",r=q(o?"All":l,c,S),i=K(100),T=O(),P=Q(),w=Y(),k=z(),C=G(),B=Z(),M=U(()=>o?(i.data?.data??[]).map(t=>{const a=t.currentTime??0,e=t.duration??0,g=t.season??1,h=t.episode??1,n=t.mediaType==="movie",p=n?"Movie":`S${g} E${h}`,b=t.completed===1||e>0&&a>=e*.8;return{key:t.id,libId:t.id,tmdbId:t.tmdbId??0,mediaType:t.mediaType,title:t.title||"",poster:t.poster||"",year:t.year,adult:R({adult:t.adult===1}),status:t.watchlistStatus??"",badge:p,progressPercent:b?100:e>0?a/e*100:0,progressLabel:e>0?b?"Watched":n?`${u(a)} / ${u(e)}`:`${p} · ${u(a)} / ${u(e)}`:p,watchTarget:y(t.mediaType,t.tmdbId??0,n?void 0:g,n?void 0:h)}}):(r.data?.data??[]).map(t=>({key:t.id,libId:t.id,tmdbId:t.tmdbId,mediaType:t.mediaType,title:t.title,poster:t.poster||"",year:t.year,adult:R({adult:t.adult===1}),status:t.status,badge:t.lastSeason&&t.lastEpisode?`S${t.lastSeason} E${t.lastEpisode}`:void 0,progressPercent:void 0,progressLabel:void 0,watchTarget:y(t.mediaType,t.tmdbId,t.lastSeason??void 0,t.lastEpisode??void 0)})),[o,i.data,r.data]),W=o?i.data?.total??0:r.data?.total??0,E=o?i.isLoading:r.isLoading,A=o?i.error:r.error,V=t=>{s&&(P.mutate({mediaId:s.libId}),t&&T.mutate(s.libId))};return d(F,{headerTitle:"My TV Watchlist",headerSubtitle:"Track and manage your movies and shows",filters:j,filterBy:l,filterBasePath:"/tv-watchlist",continueFilter:"Continue Watching",statusOptions:[...I],entries:M,total:W,isLoading:E,error:A,page:c,pageSize:S,onPageChange:m,emptyTitle:"Your TV watchlist is looking a bit empty",emptyFilteredText:"No titles match this filter.",emptyAllText:"Let's find something to watch!",browseLabel:"Browse TV & Movies",browseTarget:"/tv",removeListLabel:"Remove from TV Watchlist",listNoun:"TV watchlist",skipConfirmKey:"tvSkipRemoveConfirmation",onBulkStatus:(t,a)=>k.mutate({ids:t,status:a}),onBulkRemove:t=>{o?B.mutate(t):C.mutate(t)},onStatusChange:(t,a)=>w.mutate({id:t,status:a}),onRemoveItem:t=>T.mutate(t),renderCard:t=>d(x,{item:{id:t.libId,title:t.title,thumbnail:t.poster,typeBadge:t.mediaType==="movie"?"Movie":"TV",chapterBadge:t.badge??null,isAdult:t.adult},linkTo:t.watchTarget,hoverIcon:"play",progress:t.progressPercent!==void 0&&t.progressLabel?{percent:t.progressPercent,label:t.progressLabel}:void 0,showProgress:o,metaRow:t.year?d("span",{style:{opacity:.75},children:t.year}):void 0,onRemove:o?()=>v(t):void 0,renderPopup:(a,e)=>d(_,{item:{id:t.tmdbId??0,title:t.title||"",year:t.year||"",type:t.mediaType||"tv",image:t.poster||""},anchorRect:a,onMouseEnter:e.onMouseEnter,onMouseLeave:e.onMouseLeave,onRequestClose:e.close})}),modals:d(N,{isOpen:!!s,itemName:s?.title,progressKind:"watch",listLabel:"my TV watchlist",onClose:()=>{v(null)},onConfirm:V})})}export{ct as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._keyboard_b2w6l_1{position:fixed;z-index:var(--z-overlay);width:min(var(--keyboard-width),calc(100vw - 24px));overflow:hidden;color:var(--text-primary);background:linear-gradient(180deg,#ffffff14,#ffffff05),#0f0f11f7;border:1px solid var(--border-secondary);border-radius:var(--radius-md);box-shadow:0 18px 60px #00000075;backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);-webkit-user-select:none;user-select:none}._topBar_b2w6l_18{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2);background:#ffffff0f;border-bottom:1px solid var(--border-primary)}._dragHandle_b2w6l_27{flex:1;min-height:34px;display:flex;align-items:center;gap:var(--space-2);color:var(--text-secondary);font-size:var(--font-size-sm);cursor:move}._grip_b2w6l_38{width:22px;height:14px;background-image:radial-gradient(currentColor 1px,transparent 1px);background-size:6px 6px;opacity:.8}._topButton_b2w6l_46,._key_b2w6l_1{border:1px solid var(--border-secondary);color:var(--text-primary);background:#ffffff14;font:inherit;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,transform .08s ease}._topButton_b2w6l_46{min-height:34px;padding:0 var(--space-3);border-radius:var(--radius-sm);font-size:var(--font-size-sm)}._topButton_b2w6l_46:hover,._key_b2w6l_1:hover{background:#ffffff24;border-color:#ffffff42}._topButton_b2w6l_46:active,._key_b2w6l_1:active{transform:translateY(1px)}._closeButton_b2w6l_77{width:44px;height:44px;padding:0}._keys_b2w6l_83{display:grid;gap:var(--keyboard-gap);padding:var(--space-3);justify-items:center}._row_b2w6l_90{display:flex;justify-content:center;gap:var(--keyboard-gap);width:100%;max-width:calc((var(--key-size) * 10) + (var(--key-size) * 1.75) + (var(--keyboard-gap) * 10))}._key_b2w6l_1{min-width:var(--key-size);height:var(--key-size);border-radius:var(--radius-sm);font-size:var(--key-font);font-weight:var(--font-weight-semibold)}._wideKey_b2w6l_106{min-width:calc(var(--key-size) * 1.75)}._spaceKey_b2w6l_110{flex:1;max-width:calc((var(--key-size) * 10) + (var(--key-size) * 1.75) + (var(--keyboard-gap) * 10) - (var(--key-size) * 5.5) - (var(--keyboard-gap) * 4))}._spaceIcon_b2w6l_118{width:14%;height:12px;border-bottom:2px solid currentColor;display:inline-block;opacity:.9}._activeKey_b2w6l_126{border-color:var(--accent);background:linear-gradient(135deg,var(--accent),var(--accent-dark))}@media(max-width:700px){._keyboard_b2w6l_1{left:8px!important;width:calc(100vw - 16px)}._dragHandle_b2w6l_27 span{display:none}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as _,A as E,h as k,q as N,$ as I,u as o}from"./vendor-core-DfaOB3Rn.js";const D="_keyboard_b2w6l_1",O="_topBar_b2w6l_18",R="_dragHandle_b2w6l_27",T="_grip_b2w6l_38",q="_topButton_b2w6l_46",U="_key_b2w6l_1",V="_closeButton_b2w6l_77",W="_keys_b2w6l_83",X="_row_b2w6l_90",Y="_wideKey_b2w6l_106",j="_spaceKey_b2w6l_110",A="_spaceIcon_b2w6l_118",F="_activeKey_b2w6l_126",t={keyboard:D,topBar:O,dragHandle:R,grip:T,topButton:q,key:U,closeButton:V,keys:W,row:X,wideKey:Y,spaceKey:j,spaceIcon:A,activeKey:F},x="virtual-keyboard-state",m=["small","medium","large"],J=["1","2","3","4","5","6","7","8","9","0"],P=["!","@","#","$","%","^","&","*","(",")"],G=[["q","w","e","r","t","y","u","i","o","p"],["a","s","d","f","g","h","j","k","l"],["z","x","c","v","b","n","m"]],Q=()=>{const i={position:{x:Math.max(12,window.innerWidth-690),y:Math.max(90,window.innerHeight-330)},size:"medium"};try{const c=localStorage.getItem(x);if(!c)return i;const s=JSON.parse(c);return{position:s.position&&Number.isFinite(s.position.x)&&Number.isFinite(s.position.y)?s.position:i.position,size:s.size&&m.includes(s.size)?s.size:i.size}}catch{return i}},K=(i,c)=>{const s=c?.offsetWidth??650,r=c?.offsetHeight??270;return{x:Math.min(Math.max(8,i.x),Math.max(8,window.innerWidth-s-8)),y:Math.min(Math.max(8,i.y),Math.max(8,window.innerHeight-r-8))}};function ee({activeInputRef:i,isVisible:c,onClose:s}){const[{position:r,size:l},w]=_(Q),[f,S]=_(!1),[g,$]=_(!1),h=E(null),u=E(null);k(()=>{localStorage.setItem(x,JSON.stringify({position:r,size:l}))},[r,l]),k(()=>{const e=()=>{w(n=>({...n,position:K(n.position,h.current)}))};return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[]);const v=()=>i.current&&document.contains(i.current)?i.current:document.activeElement instanceof HTMLInputElement?document.activeElement:null,d=e=>{const n=v();if(!n)return;const a=n.selectionStart??n.value.length,b=n.selectionEnd??n.value.length;n.setRangeText(e,a,b,"end"),n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()},z=()=>{const e=v();if(!e)return;const n=e.selectionStart??e.value.length,a=e.selectionEnd??e.value.length;n===a&&n===0||(e.setRangeText("",n===a?n-1:n,a,"end"),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus())},M=()=>{const e=v();if(!e){s();return}const n=e.form;n?n.requestSubmit():e.dispatchEvent(new KeyboardEvent("keydown",{key:"Enter",bubbles:!0})),s()},B=e=>{e.preventDefault()},p=N(e=>{if(!u.current)return;const n={x:e.clientX-u.current.x,y:e.clientY-u.current.y};w(a=>({...a,position:K(n,h.current)}))},[]),y=N(()=>{u.current=null,window.removeEventListener("mousemove",p),window.removeEventListener("mouseup",y)},[p]),C=e=>{e.preventDefault(),u.current={x:e.clientX-r.x,y:e.clientY-r.y},window.addEventListener("mousemove",p),window.addEventListener("mouseup",y)};if(k(()=>()=>{window.removeEventListener("mousemove",p),window.removeEventListener("mouseup",y)},[p,y]),!c)return null;const L=g?P:J,H=()=>{w(e=>{const n=m[(m.indexOf(e.size)+1)%m.length];return{...e,size:n}})};return I(o("div",{ref:h,className:`${t.keyboard} ${t[l]}`,style:{left:r.x,top:r.y},onMouseDown:B,"data-virtual-keyboard-root":!0,children:[o("div",{className:t.topBar,children:[o("div",{className:t.dragHandle,onMouseDown:C,"aria-label":"Move virtual keyboard",children:[o("span",{className:t.grip,"aria-hidden":"true"}),o("span",{children:"Virtual Keyboard"})]}),o("button",{type:"button",className:t.topButton,onClick:H,children:["Size: ",l[0].toUpperCase()+l.slice(1)]}),o("button",{type:"button",className:`${t.topButton} ${t.closeButton}`,onClick:s,children:"X"})]}),o("div",{className:t.keys,children:[o("div",{className:t.row,children:[L.map(e=>o("button",{type:"button",className:t.key,onClick:()=>d(e),children:e},e)),o("button",{type:"button",className:`${t.key} ${t.wideKey}`,onClick:z,"aria-label":"Backspace",children:"⟵"})]}),G.map((e,n)=>o("div",{className:t.row,children:[e.map(a=>{const b=f?a.toUpperCase():a;return o("button",{type:"button",className:t.key,onClick:()=>d(b),children:b},a)}),n===1&&o("button",{type:"button",className:`${t.key} ${t.wideKey}`,onClick:M,children:"Enter"})]},e.join(""))),o("div",{className:t.row,children:[o("button",{type:"button",className:`${t.key} ${t.wideKey} ${g?t.activeKey:""}`,onClick:()=>$(e=>!e),children:"Ctrl"}),o("button",{type:"button",className:`${t.key} ${t.wideKey} ${f?t.activeKey:""}`,onClick:()=>S(e=>!e),children:"Shift"}),o("button",{type:"button",className:`${t.key} ${t.spaceKey}`,onClick:()=>d(" "),"aria-label":"Space",children:o("span",{className:t.spaceIcon})}),o("button",{type:"button",className:t.key,onClick:()=>d("."),children:"."}),o("button",{type:"button",className:t.key,onClick:()=>d("-"),children:"-"})]})]})]}),document.body)}export{ee as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{h as fe,o as He,a as Ze,p as Je,d as h,A as ye,T,u as t,S as Xe}from"./vendor-core-DfaOB3Rn.js";import{u as et,a as Se}from"./vendor-query-BBT5_sHx.js";import{i as tt,u as at,d as nt,x as st,y as _e,z as Ae,q as we,A as lt,t as rt,l as ct,C as it,D as ot,E as dt,F as ht,G as ut,B as W,M as se}from"./index-BLh_CXtu.js";import{I as g}from"./vendor-icons-DrybRNxP.js";import{A as mt}from"./AnimeCard-CoPx634q.js";import{S as pt}from"./SkeletonGrid-CYJeh04P.js";import{E as gt}from"./ErrorMessage-DAxegITP.js";import{P as Le}from"./MediaCard-C1jNesfK.js";import{s as n}from"./LibraryListPage.module-r6k9nyT9.js";import{A as vt}from"./ActiveFilterChips-olGfwxle.js";import"./useAnimeInfoData-MPNJXLaM.js";import"./QueueOptionsButton-DNzKPzPw.js";import"./vendor-ui-3qrARCPr.js";import"./playbackCompletion-DuUs8u-8.js";import"./useIsMobile-Dvx1uJ82.js";import"./MatureConsentModal-BsdpNeXA.js";const ft=(d,v)=>{const l=new URLSearchParams(v);return l.delete("page"),l.sort(),`${d}|${l.toString()}`},yt=(d,v)=>{const l=new Set(d);return v.forEach(A=>l.add(A)),l},St=(d,v)=>{const l=new Set(d);return v.forEach(A=>l.delete(A)),l},_t="_sortSelect_cahhw_1",At="_filterContainer_cahhw_30",wt="_slideUpIn_cahhw_1",Lt="_searchBarWrapper_cahhw_44",Ct="_inputIconWrapper_cahhw_50",Nt="_searchIcon_cahhw_55",bt="_searchInput_cahhw_64",Bt="_searchActions_cahhw_84",kt="_searchBtn_cahhw_89",Rt="_filterToggleBtn_cahhw_94",Tt="_advancedFilters_cahhw_115",Wt="_show_cahhw_122",It="_filterDivider_cahhw_128",xt="_filterGrid_cahhw_134",$t="_filterItem_cahhw_141",Pt="_genreSection_cahhw_183",Ft="_genreLabel_cahhw_189",Gt="_genreContainer_cahhw_199",Mt="_genreButton_cahhw_205",Ot="_include_cahhw_222",Et="_exclude_cahhw_228",Dt="_filterActions_cahhw_235",zt="_applyBtn_cahhw_246",c={sortSelect:_t,filterContainer:At,slideUpIn:wt,searchBarWrapper:Lt,inputIconWrapper:Ct,searchIcon:Nt,searchInput:bt,searchActions:Bt,searchBtn:kt,filterToggleBtn:Rt,advancedFilters:Tt,show:Wt,filterDivider:It,filterGrid:xt,filterItem:$t,genreSection:Pt,genreLabel:Ft,genreContainer:Gt,genreButton:Mt,include:Ot,exclude:Et,filterActions:Dt,applyBtn:zt},Ne=["All","Continue Watching","Watching","Completed","On-Hold","Dropped","Planned"],Ce=Ne.slice(2),Ut=[{value:"ALL",label:"All Types"},{value:"TV",label:"TV Series"},{value:"Movie",label:"Movie"},{value:"OVA",label:"OVA"},{value:"ONA",label:"ONA"},{value:"TV_SHORT",label:"TV Short"},{value:"SPECIAL",label:"Special"},{value:"ADULT",label:"Adult (18+)"}],qt=[{value:"ALL",label:"All Seasons"},{value:"WINTER",label:"Winter"},{value:"SPRING",label:"Spring"},{value:"SUMMER",label:"Summer"},{value:"FALL",label:"Fall"}],ca=()=>{fe(()=>{document.title="Watchlist - dango"},[]);const{filter:d="All"}=He(),v=Ze(),[l,A]=Je(),Q=et(),le=tt(),[f,I]=h(parseInt(l.get("page")||"1")),[w,x]=h(l.get("query")||""),[L,V]=h(l.get("sortBy")||"last_added"),[C,$]=h(l.get("type")||"ALL"),[N,P]=h(l.get("season")||"ALL"),[b,F]=h(l.get("year")||"ALL"),[k,G]=h(()=>{const e={},a=l.get("genres")?.split(",").map(r=>r.trim()).filter(Boolean)||[],s=l.get("excludeGenres")?.split(",").map(r=>r.trim()).filter(Boolean)||[];return a.forEach(r=>r&&(e[r]="include")),s.forEach(r=>r&&(e[r]="exclude")),e}),[M,be]=h(()=>["type","season","year","genres","excludeGenres"].some(e=>l.has(e))),{lowEndMode:Be}=at(),{titlePreference:O}=nt(),{data:ke}=st(),re=ke?.genres||[],H=ye(null),[o,B]=h(null),[Z,E]=h(!1),[ce,D]=h(!1),[z,Re]=h(!1),[p,y]=h(new Set),J=ye(null),i=d==="Continue Watching",U=T(()=>{const e=new URLSearchParams(l);return e.delete("page"),e.set("titlePreference",O),e.toString()},[l,O]),{data:q,isLoading:Te,error:We}=_e(U,f,14),{data:Y,isLoading:Ie,error:xe}=Ae(d,U,f,14),{data:$e}=_e(U,f+1,14),{data:Pe}=Ae(d,U,f+1,14),X=T(()=>(i?q?.data:Y?.data)||[],[i,q,Y]),R=T(()=>(i?q?.total:Y?.total)||0,[i,q,Y]),j=i?Te:Ie,ie=i?We:xe,oe=i?$e:Pe;fe(()=>{x(l.get("query")||""),V(l.get("sortBy")||"last_added"),$(l.get("type")||"ALL"),P(l.get("season")||"ALL"),F(l.get("year")||"ALL");const e={},a=l.get("genres")?.split(",").map(u=>u.trim()).filter(Boolean)||[],s=l.get("excludeGenres")?.split(",").map(u=>u.trim()).filter(Boolean)||[];a.forEach(u=>u&&(e[u]="include")),s.forEach(u=>u&&(e[u]="exclude")),G(e),I(parseInt(l.get("page")||"1"));const r=ft(d,l);J.current!==null&&J.current!==r&&y(new Set),J.current=r},[l,d]);const Fe=Se({mutationFn:async({id:e,status:a})=>{await rt.watchlist.setStatus.mutate({id:e,status:a})},onSuccess:()=>{Q.invalidateQueries({queryKey:[we.watchlist]}),lt.success("Status updated")}}),Ge=Se(le.continueWatching.remove.mutationOptions({onSuccess:()=>{Q.invalidateQueries(le.continueWatching.pathFilter()),Q.invalidateQueries({queryKey:[we.continueWatching]})}})),ee=ct(),{data:de}=it("skipRemoveConfirmation"),Me=ot(),te=T(()=>{const e=a=>a[O]||a.name||"";return[...X].sort((a,s)=>L==="name_asc"?e(a).localeCompare(e(s)):L==="name_desc"?e(s).localeCompare(e(a)):0)},[X,L,O]),ae=new Date().getFullYear(),Oe=[{value:"ALL",label:"All Years"},...Array.from({length:ae-1980+1},(e,a)=>({value:String(ae-a),label:String(ae-a)}))],m=(e=L,a=1)=>{const s=new URLSearchParams;w.trim()&&s.set("query",w.trim()),e!=="last_added"&&s.set("sortBy",e),C!=="ALL"&&s.set("type",C),N!=="ALL"&&s.set("season",N),b!=="ALL"&&s.set("year",b);const r=Object.entries(k).filter(([,_])=>_==="include").map(([_])=>_),u=Object.entries(k).filter(([,_])=>_==="exclude").map(([_])=>_);r.length>0&&s.set("genres",r.join(",")),u.length>0&&s.set("excludeGenres",u.join(",")),a>1&&s.set("page",a.toString()),A(s),a!==f&&I(a)},he=e=>{if(m(L,e),H.current){const a=H.current.getBoundingClientRect().top+window.scrollY-100;window.scrollTo({top:a,behavior:"smooth"})}},Ee=()=>{x(""),V("last_added"),$("ALL"),P("ALL"),F("ALL"),G({}),A(new URLSearchParams),I(1)},De=e=>{G(a=>{const s=a[e],r={...a};return s==="include"?r[e]="exclude":s==="exclude"?delete r[e]:r[e]="include",r})},ue=(e,a)=>{if(i){B({id:e,name:a});return}String(de)==="true"||String(de)==="1"?ee.mutate({id:e}):B({id:e,name:a})},ze=()=>{if(o){if(o.ids){i?(Ue.mutate({ids:o.ids}),Z&&pe.mutate({ids:o.ids})):pe.mutate({ids:o.ids}),y(new Set),B(null),E(!1),D(!1);return}i?(Ge.mutate({showId:o.id}),Z&&ee.mutate({id:o.id})):ee.mutate({id:o.id}),ce&&Me.mutate({key:"skipRemoveConfirmation",value:!0}),B(null),E(!1),D(!1)}},me=()=>{B(null),E(!1),D(!1)},pe=dt(),Ue=ht(),qe=ut(),Ye=()=>{Re(e=>{const a=!e;return a||y(new Set),a})},je=e=>{y(a=>{const s=new Set(a);return s.has(e)?s.delete(e):s.add(e),s})},K=te.map(e=>e.id),ne=K.length>0&&K.every(e=>p.has(e)),Ke=()=>{y(ne?e=>St(e,K):e=>yt(e,K))},Qe=e=>{p.size!==0&&(qe.mutate({ids:[...p],status:e}),y(new Set))},Ve=()=>{p.size!==0&&B({ids:[...p]})},ge=X.length>=14&&oe&&oe.data.length>0,ve=T(()=>Math.max(1,Math.ceil(R/14)),[R]),S=[];w.trim()&&S.push({key:"query",label:`Search: ${w}`,onRemove:()=>{x(""),m()}}),C!=="ALL"&&S.push({key:"type",label:`Type: ${C}`,onRemove:()=>{$("ALL"),m()}}),N!=="ALL"&&S.push({key:"season",label:`Season: ${N}`,onRemove:()=>{P("ALL"),m()}}),b!=="ALL"&&S.push({key:"year",label:`Year: ${b}`,onRemove:()=>{F("ALL"),m()}});for(const[e,a]of Object.entries(k))S.push({key:e,label:a==="include"?`+ ${e}`:`-${e}`,tone:a==="include"?"primary":"danger",onRemove:()=>{G(s=>{const r={...s};return delete r[e],r}),m()}});return t("div",{className:"page-container",children:[t("header",{className:n.header,children:[t("h2",{className:n.title,children:"My Watchlist"}),t("p",{className:n.subtitle,children:"Track and manage your anime collection"})]}),t("div",{className:n.controls,children:[t("div",{className:n.filters,children:Ne.map(e=>t("button",{className:`${n.filterBtn} ${d===e?n.active:""}`,onClick:()=>{const a=new URLSearchParams(l);a.delete("page"),v({pathname:`/watchlist/${e}`,search:a.toString()}),I(1)},children:e},e))}),t("div",{children:t("select",{className:c.sortSelect,value:L,onChange:e=>{const a=e.currentTarget.value;V(a),m(a,f)},children:[t("option",{value:"last_added",children:"Recently Added"}),t("option",{value:"name_asc",children:"Name (A-Z)"}),t("option",{value:"name_desc",children:"Name (Z-A)"})]})})]}),t("div",{className:c.filterContainer,children:[t("div",{className:c.searchBarWrapper,children:[t("div",{className:c.inputIconWrapper,children:[t(g,{name:"search",className:c.searchIcon}),t("input",{className:c.searchInput,placeholder:"Search your watchlist by title...",value:w,onInput:e=>x(e.currentTarget.value),onKeyDown:e=>e.key==="Enter"&&m()})]}),t("div",{className:c.searchActions,children:[t(W,{onClick:()=>m(),className:c.searchBtn,children:"Search"}),t("button",{className:`${c.filterToggleBtn} ${M?n.active:""}`,onClick:()=>be(!M),children:[t(g,{name:"filter",size:14}),t("span",{children:"Filters"}),M?t(g,{name:"chevron-up",size:12}):t(g,{name:"chevron-down",size:12})]})]})]}),t("div",{className:`${c.advancedFilters} ${M?c.show:""}`,children:[t("div",{className:c.filterDivider}),t("div",{className:c.filterGrid,children:[t("div",{className:c.filterItem,children:[t("label",{children:"Type"}),t("select",{value:C,onChange:e=>$(e.currentTarget.value),children:Ut.map(e=>t("option",{value:e.value,children:e.label},e.value))})]}),t("div",{className:c.filterItem,children:[t("label",{children:"Season"}),t("select",{value:N,onChange:e=>P(e.currentTarget.value),children:qt.map(e=>t("option",{value:e.value,children:e.label},e.value))})]}),t("div",{className:c.filterItem,children:[t("label",{children:"Year"}),t("select",{value:b,onChange:e=>F(e.currentTarget.value),children:Oe.map(e=>t("option",{value:e.value,children:e.label},e.value))})]})]}),re.length>0&&t("div",{className:c.genreSection,children:[t("label",{className:c.genreLabel,children:"Genres"}),t("div",{className:c.genreContainer,children:re.map(e=>t("button",{className:`${c.genreButton} ${c[k[e]||""]}`,onClick:()=>De(e),children:e},e))})]}),t("div",{className:c.filterActions,children:[t(W,{variant:"secondary",onClick:Ee,children:"Reset All"}),t(W,{onClick:()=>m(),className:c.applyBtn,children:"Apply Filters"})]})]})]}),t("div",{className:n.resultsHeader,ref:H,children:[t("h3",{className:n.resultsTitle,children:[i?"Continue Watching":d,t("span",{className:n.itemCount,children:["(",R," items)"]})]}),t("div",{className:n.headerActions,children:[t("button",{className:`${n.manageBtn} ${z?n.active:""}`,onClick:Ye,children:[t(g,{name:"pencil-alt",size:13}),t("span",{children:"Bulk Manage"})]}),R>0&&t(Le,{page:f,totalPages:ve,canGoNext:ge,onChange:he,isLoading:j})]})]}),z&&t("div",{className:n.manageBar,children:[t("button",{className:n.selectAllBtn,onClick:Ke,children:[t("span",{className:`${n.selectAllBox} ${ne?n.selectAllBoxChecked:""}`,"aria-hidden":"true"}),t("span",{children:ne?"Clear Page":"Select All"})]}),t("span",{className:n.manageCount,children:[p.size," selected"]}),t("div",{className:n.manageSpacer}),!i&&t("select",{className:n.manageStatusSelect,value:"",onChange:e=>{e.currentTarget.value&&Qe(e.currentTarget.value)},disabled:p.size===0,title:"Set status for selected items",children:[t("option",{value:"",children:"Set status…"}),Ce.map(e=>t("option",{value:e,children:e},e))]}),t("button",{className:n.manageRemoveBtn,onClick:Ve,disabled:p.size===0,children:[t(g,{name:"trash",size:13}),t("span",{children:"Remove Selected"})]})]}),j?t(pt,{}):ie?t(gt,{message:ie.message}):t(Xe,{children:[S.length>0&&t(vt,{chips:S}),t("div",{className:`${n.grid} ${Be?n.lowEnd:""}`,children:te.map(e=>{const a=p.has(e.id);return t("div",{className:`${n.itemWrapper} ${a?n.selected:""}`,children:[z&&t("div",{className:n.selectOverlay,onClick:()=>je(e.id),title:a?"Deselect":"Select",children:t("span",{className:n.selectBadge,children:a?t(g,{name:"check",size:12}):null})}),t(mt,{anime:e,continueWatching:i,onRemove:()=>ue(e.id,e.name),layout:"vertical"}),!i&&!z&&t("div",{className:n.cardActions,children:[t("select",{className:n.statusSelect,value:e.status,onChange:s=>Fe.mutate({id:e.id,status:s.currentTarget.value}),children:Ce.map(s=>t("option",{value:s,children:s},s))}),t("button",{className:n.removeBtn,onClick:()=>ue(e.id,e.name),title:"Remove from Watchlist","aria-label":"Remove from Watchlist",children:t(g,{name:"trash",size:12})})]})]},e._id)})})]}),!j&&te.length===0&&t("div",{className:n.emptyState,children:[t("h3",{className:n.emptyTitle,children:"Your watchlist is looking a bit lonely"}),t("p",{className:n.emptyText,children:d!=="All"||w||C!=="ALL"||N!=="ALL"||b!=="ALL"||Object.keys(k).length>0?"No anime match these filters. Try adjusting them to see more titles.":"Let's find something to watch!"}),t("button",{className:n.emptyBtn,onClick:()=>v("/search"),children:[t(g,{name:"search",size:14}),t("span",{children:"Browse Anime"})]})]}),R>0&&t("div",{className:n.bottomPagination,children:t(Le,{page:f,totalPages:ve,canGoNext:ge,onChange:he,isLoading:j,variant:"labeled"})}),t(se,{isOpen:!!o,onClose:me,title:i?"Reset Progress":"Remove from Watchlist",children:[t(se.Body,{children:[t("p",{children:o?.ids&&o.ids.length>1?i?`Are you sure you want to remove watch progress for ${o.ids.length} items?`:`Are you sure you want to remove ${o.ids.length} items from your watchlist?`:i?`Are you sure you want to remove your watch progress for "${o?.name}"?`:`Are you sure you want to remove "${o?.name}" from your watchlist?`}),i&&t("label",{children:[t("input",{type:"checkbox",checked:Z,onChange:e=>E(e.currentTarget.checked)}),"Also remove from my watchlist"]}),!i&&!(o?.ids&&o.ids.length>1)&&t("label",{children:[t("input",{type:"checkbox",checked:ce,onChange:e=>D(e.currentTarget.checked)}),"Remember my choice"]})]}),t(se.Actions,{children:[t(W,{variant:"secondary",onClick:me,children:"No"}),t(W,{variant:"danger",onClick:ze,children:"Yes"})]})]})]})};export{ca as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._sortSelect_cahhw_1{width:180px;height:44px;padding:0 var(--space-4);background-color:var(--bg-tertiary);border:1px solid var(--border-primary);border-radius:var(--radius-lg);color:var(--text-primary);font-size:var(--font-size-sm);font-weight:600;cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2371717a' stroke-width='2' viewBox='0 0 12 12'%3E%3Cpolyline points='3 5 6 8 9 5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 1rem center;transition:all var(--transition-fast)}._sortSelect_cahhw_1:hover{background-color:var(--bg-elevated);border-color:var(--border-secondary)}._sortSelect_cahhw_1:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}._filterContainer_cahhw_30{background:var(--glass-bg);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--glass-border);padding:var(--space-6);border-radius:var(--radius-xl);margin-bottom:var(--space-10);box-shadow:var(--glass-shadow);animation:_slideUpIn_cahhw_1 .8s var(--ease-smooth);width:100%;box-sizing:border-box}._searchBarWrapper_cahhw_44{display:flex;gap:var(--space-4);align-items:center}._inputIconWrapper_cahhw_50{flex:1;position:relative}._searchIcon_cahhw_55{position:absolute;left:var(--space-4);top:50%;transform:translateY(-50%);color:var(--text-tertiary);pointer-events:none}._searchInput_cahhw_64{width:100%;height:52px;padding:0 var(--space-4) 0 3.2rem;background:var(--bg-tertiary);border:1px solid var(--border-primary);border-radius:var(--radius-lg);color:var(--text-primary);font-size:var(--font-size-base);font-family:inherit;transition:all var(--transition-fast)}._searchInput_cahhw_64:focus{outline:none;border-color:var(--accent);background:var(--bg-elevated);box-shadow:0 0 0 4px var(--accent-glow)}._searchActions_cahhw_84{display:flex;gap:var(--space-3)}._searchBtn_cahhw_89{height:52px;padding:0 var(--space-8)!important}._filterToggleBtn_cahhw_94{display:flex;align-items:center;gap:var(--space-2);height:52px;padding:0 var(--space-4);background:#ffffff0d;border:1px solid var(--border-secondary);border-radius:var(--radius-lg);color:var(--text-primary);font-weight:600;font-size:var(--font-size-sm);cursor:pointer;transition:all var(--transition-fast)}._filterToggleBtn_cahhw_94:hover{background:#ffffff1a;border-color:var(--text-secondary)}._advancedFilters_cahhw_115{max-height:0;overflow:hidden;transition:all .4s cubic-bezier(.4,0,.2,1);opacity:0}._advancedFilters_cahhw_115._show_cahhw_122{max-height:1200px;opacity:1;margin-top:var(--space-6)}._filterDivider_cahhw_128{height:1px;background:var(--border-primary);margin-bottom:var(--space-6)}._filterGrid_cahhw_134{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:var(--space-6);margin-bottom:var(--space-8)}._filterItem_cahhw_141{display:flex;flex-direction:column;gap:var(--space-2)}._filterItem_cahhw_141 label{font-size:.7rem;font-weight:700;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.05em}._filterItem_cahhw_141 select{height:44px;padding:0 var(--space-4);background:var(--bg-tertiary);border:1px solid var(--border-primary);border-radius:var(--radius-md);color:var(--text-primary);font-size:var(--font-size-sm);font-family:inherit;cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2371717a' stroke-width='2' viewBox='0 0 12 12'%3E%3Cpolyline points='3 5 6 8 9 5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 1rem center;transition:all var(--transition-fast)}._filterItem_cahhw_141 select:hover{border-color:var(--border-secondary);background-color:var(--bg-elevated)}._filterItem_cahhw_141 select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}._genreSection_cahhw_183{border-top:1px solid var(--border-primary);padding-top:var(--space-6);margin-bottom:var(--space-8)}._genreLabel_cahhw_189{display:block;font-size:.7rem;font-weight:700;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.05em;margin-bottom:var(--space-4)}._genreContainer_cahhw_199{display:flex;flex-wrap:wrap;gap:var(--space-2)}._genreButton_cahhw_205{background:#ffffff0d;border:1px solid var(--border-primary);color:var(--text-secondary);padding:.5rem 1rem;border-radius:var(--radius-full);font-size:var(--font-size-xs);font-weight:600;cursor:pointer;transition:all var(--transition-fast)}._genreButton_cahhw_205:hover{border-color:var(--accent);color:var(--text-primary)}._genreButton_cahhw_205._include_cahhw_222{background:color-mix(in srgb,var(--color-success) 10%,transparent);border-color:var(--color-success);color:var(--color-success)}._genreButton_cahhw_205._exclude_cahhw_228{background:color-mix(in srgb,var(--color-danger) 10%,transparent);border-color:var(--color-danger);color:var(--color-danger);text-decoration:line-through}._filterActions_cahhw_235{display:flex;justify-content:flex-end;gap:var(--space-4);border-top:1px solid var(--border-primary);padding-top:var(--space-6)}@keyframes _slideUpIn_cahhw_1{}._applyBtn_cahhw_246{align-self:flex-start}
|