@serifpersia/dango 3.4.6 → 3.4.7

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.
Files changed (79) hide show
  1. package/README.md +1 -1
  2. package/client/dist/assets/{AnimeCard-BVdH0EeW.js → AnimeCard-Cll26FQe.js} +1 -1
  3. package/client/dist/assets/{AnimeInfo-Dw2Nop6Q.js → AnimeInfo-zMQgNycF.js} +1 -1
  4. package/client/dist/assets/{AnimeInfoPage-Cw-Tq3YX.js → AnimeInfoPage-DEPX3FFf.js} +2 -2
  5. package/client/dist/assets/Asmr-BbHVH9pC.js +2 -0
  6. package/client/dist/assets/Asmr-D1KuQwQy.css +1 -0
  7. package/client/dist/assets/Asmr.module-CdWlioTY.js +1 -0
  8. package/client/dist/assets/{AsmrResetProgressModal-CYjpcYpb.js → AsmrResetProgressModal-D4zRL_b8.js} +1 -1
  9. package/client/dist/assets/AvSyncCalibrator-CbzA-56T.js +10 -0
  10. package/client/dist/assets/{AvSyncCalibrator-D0FYSwiz.css → AvSyncCalibrator-gEONBv5a.css} +1 -1
  11. package/client/dist/assets/Home-q7a1RjQM.js +1 -0
  12. package/client/dist/assets/{Insights-DDWry-t1.js → Insights-6H3qK9Q_.js} +1 -1
  13. package/client/dist/assets/{LibraryListPage-CV8Z9JlO.js → LibraryListPage-Cc-I_48d.js} +1 -1
  14. package/client/dist/assets/ListeningList-CxfHV13T.js +1 -0
  15. package/client/dist/assets/Manga-BmNPKJB8.js +1 -0
  16. package/client/dist/assets/Manga-CqAceKxR.css +1 -0
  17. package/client/dist/assets/Manga.module-depGEacJ.js +1 -0
  18. package/client/dist/assets/MangaInfoPage-Csyq4TAu.js +1 -0
  19. package/client/dist/assets/MangaReadPage-jaSR2qX6.js +1 -0
  20. package/client/dist/assets/{MangaResetProgressModal-DyhQYBDy.js → MangaResetProgressModal-DrfFCtDE.js} +1 -1
  21. package/client/dist/assets/{Mature-Db53R-LR.js → Mature-20QVU1lQ.js} +1 -1
  22. package/client/dist/assets/{MediaCard-BcLjlpfR.js → MediaCard-CoRm07Vb.js} +1 -1
  23. package/client/dist/assets/Music-Yry6890T.js +1 -0
  24. package/client/dist/assets/OptionListMenu-DSTuvk6i.js +1 -0
  25. package/client/dist/assets/Player-yVWIsyOS.js +56 -0
  26. package/client/dist/assets/PlayerSettings-CiazXo-J.js +1 -0
  27. package/client/dist/assets/{QueueOptionsButton-ClVTpH8J.js → QueueOptionsButton-CpyBvbsh.js} +1 -1
  28. package/client/dist/assets/{QueueRail-DeJKVRs5.js → QueueRail-DRxByiUx.js} +1 -1
  29. package/client/dist/assets/Radio-DxL91QOj.js +1 -0
  30. package/client/dist/assets/ReadingList-CNm6nFC1.js +1 -0
  31. package/client/dist/assets/{ResetProgressModal-C6ukct_c.js → ResetProgressModal-DiYoRAaR.js} +1 -1
  32. package/client/dist/assets/{Search-DjjKA_Wu.js → Search-BBRaD1PE.js} +1 -1
  33. package/client/dist/assets/{Settings-DQt_S5Qw.js → Settings-C3ZhNo9P.js} +1 -1
  34. package/client/dist/assets/{SkeletonGrid-nx2HEi4P.js → SkeletonGrid-BAQn8Rru.js} +1 -1
  35. package/client/dist/assets/{Trackers-BcGzeqj2.js → Trackers-CZd3KCwM.js} +1 -1
  36. package/client/dist/assets/Tv-O1-yrBt9.js +4 -0
  37. package/client/dist/assets/{TvInfo-CUd1agFy.js → TvInfo-oMcOTrSG.js} +1 -1
  38. package/client/dist/assets/{TvPopup-CJeu3tgc.js → TvPopup-BaAmlbH4.js} +1 -1
  39. package/client/dist/assets/{TvSearch-BIypjbU3.js → TvSearch-CjGUazdR.js} +1 -1
  40. package/client/dist/assets/{TvWatchlist-DZrBdiqZ.js → TvWatchlist-W51KZDQP.js} +1 -1
  41. package/client/dist/assets/{Watchlist-Dw8cPe0n.js → Watchlist-DBtN7kPt.js} +1 -1
  42. package/client/dist/assets/{hls-B3_1VuDP.js → hls-CSxWA5I-.js} +1 -1
  43. package/client/dist/assets/index-CQWyVhME.js +178 -0
  44. package/client/dist/assets/page-DRvjODkg.css +1 -0
  45. package/client/dist/assets/page.module-C1MlZzf3.js +1 -0
  46. package/client/dist/assets/{useAnimeInfoData-_iOLEAa8.js → useAnimeInfoData-CthDMEMc.js} +1 -1
  47. package/client/dist/assets/{useAsmr-Blk4v41t.js → useAsmr-DH8inTBw.js} +1 -1
  48. package/client/dist/assets/useAsmrPopup-BfkGmSSw.js +1 -0
  49. package/client/dist/assets/{useMangaLibrary-B60at6ni.js → useMangaLibrary-CpQLCvkU.js} +1 -1
  50. package/client/dist/assets/useMangaPopup-B5LXZINf.js +1 -0
  51. package/client/dist/assets/usePopup-DS9jMzp6.js +1 -0
  52. package/client/dist/assets/useProviders-DYy7lHj6.js +1 -0
  53. package/client/dist/assets/{useTv-WJCDL5_5.js → useTv-DvKLIudk.js} +1 -1
  54. package/client/dist/assets/{useTvLibrary-Fgn5i9rJ.js → useTvLibrary-ChI7tnUw.js} +1 -1
  55. package/client/dist/index.html +1 -1
  56. package/package.json +2 -2
  57. package/server/package.json +1 -1
  58. package/client/dist/assets/Asmr-BrjzzyOi.js +0 -2
  59. package/client/dist/assets/Asmr-Cq2ua6Zk.css +0 -1
  60. package/client/dist/assets/Asmr.module-ChUXDZKx.js +0 -1
  61. package/client/dist/assets/AvSyncCalibrator-BuHurVgo.js +0 -10
  62. package/client/dist/assets/Home-KdnP7sNM.js +0 -1
  63. package/client/dist/assets/ListeningList-DSMbMZT7.js +0 -1
  64. package/client/dist/assets/Manga-Dp_-l1Pw.css +0 -1
  65. package/client/dist/assets/Manga-J6XoqEKq.js +0 -1
  66. package/client/dist/assets/Manga.module-BcfOdsNP.js +0 -1
  67. package/client/dist/assets/MangaInfoPage-N7TxsN5u.js +0 -1
  68. package/client/dist/assets/MangaReadPage-D_VzSNWq.js +0 -1
  69. package/client/dist/assets/Music-DjxQjJOl.js +0 -1
  70. package/client/dist/assets/OptionListMenu-DngTgHxH.js +0 -1
  71. package/client/dist/assets/Player-Be_7Ne5p.js +0 -56
  72. package/client/dist/assets/PlayerSettings-D47ItGDR.js +0 -1
  73. package/client/dist/assets/Radio-DU0ma3GA.js +0 -1
  74. package/client/dist/assets/ReadingList-qXW7Dk5z.js +0 -1
  75. package/client/dist/assets/Tv-COvyHdeJ.js +0 -4
  76. package/client/dist/assets/index-gMxawd-E.js +0 -178
  77. package/client/dist/assets/useAsmrPopup-D9SQIgZa.js +0 -1
  78. package/client/dist/assets/useMangaPopup-DEfGjWSu.js +0 -1
  79. package/client/dist/assets/useProviders-Ca0bZWt7.js +0 -1
@@ -0,0 +1 @@
1
+ import{d as h,A as F,h as y,g as se,u as e,S as R,$ as J,T as K}from"./vendor-core-DfaOB3Rn.js";import{I as o}from"./vendor-icons-DrybRNxP.js";import{b as Z}from"./vendor-query-BBT5_sHx.js";import{h as x,t as G,W as re}from"./index-CQWyVhME.js";import{a}from"./Asmr.module-CdWlioTY.js";import{r as i}from"./Radio.module-DGSZLpKM.js";import{p as L}from"./page.module-C1MlZzf3.js";const ee=300*1e3,le="https://cdn.listen.moe/covers/";function q(n){return n?n.startsWith("http")?n:`${le}${n}`:null}function oe(n){return n?q(n.albums[0]?.image)||q(n.artists[0]?.image)||q(n.sources[0]?.image):null}function U(n){return n?n.artists.map(s=>s.nameRomaji||s.name).join(", "):""}const ie=()=>{const n=x();return Z({...n.radio.stations.queryOptions(),staleTime:ee})},ce=n=>{const s=x();return Z({...s.radio.search.queryOptions({q:n}),enabled:n.trim().length>0,staleTime:ee})},X={song:null,lastPlayed:[],listeners:0,startTime:null},de=n=>{const[s,p]=h(X),[l,c]=h(!1),d=F(null);return y(()=>{if(p(X),c(!1),!n)return;let u=null,f=!1;try{u=new WebSocket(n)}catch{return}return u.onopen=()=>{f||c(!0)},u.onmessage=v=>{try{const m=JSON.parse(v.data);if(m.op===0){const N=m.d?.heartbeat||35e3;d.current&&window.clearInterval(d.current),d.current=window.setInterval(()=>{u&&u.readyState===WebSocket.OPEN&&u.send(JSON.stringify({op:9}))},N)}else m.op===1&&p({song:m.d?.song||null,lastPlayed:m.d?.lastPlayed||[],listeners:m.d?.listeners||0,startTime:m.d?.startTime||null})}catch{}},u.onclose=()=>{f||c(!1)},()=>{f=!0,d.current&&window.clearInterval(d.current),d.current=null,u&&u.close()}},[n]),{nowPlaying:s,connected:l}};function Y(n){if(!n)return"";const s=Math.max(0,Math.floor((Date.now()-new Date(n).getTime())/1e3)),p=Math.floor(s/60),l=s%60;return`${p}:${String(l).padStart(2,"0")}`}const me=({station:n,nowPlaying:s,connected:p,expanded:l,onStationStep:c,onExpandedChange:d,onClose:u})=>{const f=F(null),[v,m]=h(!1),[N,V]=h(!0),[S,I]=h(!1),[T,k]=h(!0),[A,E]=h(""),[b,D]=h(()=>{const t=parseFloat(localStorage.getItem("radioVolume")||"");return Number.isFinite(t)?t:1}),r=F(""),g=F(b);g.current=b,r.current||(r.current=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`radio-${Date.now()}-${Math.random().toString(36).slice(2)}`);const w=s.song,C=oe(w)||n.favicon||null,[B,z]=h(!1);y(()=>{z(!1)},[C]);const M=B?null:C,W=!!M,P=w?`${U(w)} — ${w.title}`:n.name;y(()=>{const t=f.current;if(t)return m(!1),t.src=n.streamUrl,t.load(),t.volume=g.current,t.play().catch(()=>m(!1)),()=>{t.removeAttribute("src")}},[n.id,n.streamUrl]),y(()=>{const t=f.current;t&&(t.volume=b)},[b]),y(()=>{if(l)return document.body.classList.add("asmr-player-open"),()=>document.body.classList.remove("asmr-player-open")},[l]),y(()=>{l&&k(!0)},[l]);const te=t=>t?Math.max(0,Math.floor((Date.now()-new Date(t).getTime())/1e3)):0,H=se.useCallback(t=>{n&&(G.discord.radioPresence.mutate({title:P,stationLabel:n.name,isPlaying:t,thumbnail:M||"",currentTime:te(s.startTime),sessionId:r.current}).catch(()=>{}),G.discord.heartbeat.mutate({sessionId:r.current}).catch(()=>{}))},[n,P,M,s.startTime]);y(()=>{H(v)},[H,v,n.id,P,l]),y(()=>{if(!v)return;const t=window.setInterval(()=>H(!0),15e3);return()=>window.clearInterval(t)},[v,H]),y(()=>{const t=r.current,$=()=>re(t),O=()=>$(),_=()=>{document.visibilityState==="hidden"&&$()};return window.addEventListener("pagehide",O),window.addEventListener("beforeunload",O),document.addEventListener("visibilitychange",_),()=>{window.removeEventListener("pagehide",O),window.removeEventListener("beforeunload",O),document.removeEventListener("visibilitychange",_),$()}},[]),y(()=>{if(!s.startTime){E("");return}E(Y(s.startTime));const t=window.setInterval(()=>E(Y(s.startTime)),1e3);return()=>window.clearInterval(t)},[s.startTime,s.song?.id]),y(()=>{if(!l)return;const t=$=>{$.key==="Escape"&&(S?I(!1):d(!1))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[l,S,d]);const ae=()=>{const t=f.current;t&&(t.paused?(t.load(),t.play().catch(()=>{})):t.pause())},ne=e(R,{children:[e("div",{className:a.playerButtons,children:[e("button",{className:a.playerBtn,onClick:()=>c(-1),"aria-label":"Previous station",children:e(o,{name:"step-backward"})}),e("button",{className:`${a.playerBtn} ${a.playBtn}`,onClick:ae,"aria-label":v?"Pause":"Play",children:v?e(o,{name:"pause"}):e(o,{name:"play"})}),e("button",{className:a.playerBtn,onClick:()=>c(1),"aria-label":"Next station",children:e(o,{name:"step-forward"})})]}),e("div",{className:a.seekRow,children:[e("span",{className:i.liveBadge,children:[e(o,{name:"broadcast-tower",size:10})," LIVE"]}),A&&e("span",{className:a.timeLabel,children:A}),p&&s.listeners>0&&e("span",{className:a.timeLabel,children:[s.listeners," listening"]}),!p&&n.source==="listen.moe"&&e("span",{className:a.timeLabel,children:"connecting…"})]})]}),j=e(R,{children:[e("button",{className:`${a.playerBtn} ${a.playerToggle}`,onClick:()=>d(!l),"aria-label":l?"Minimize player":"Expand player",title:l?"Minimize to browse":"Expand",children:l?e(o,{name:"chevron-down"}):e(o,{name:"chevron-up"})}),e("div",{className:a.playerInfo,children:[e("p",{className:a.playerTitle,title:P,children:P}),e("p",{className:a.playerTrack,children:n.name})]}),e("div",{className:a.playerControls,children:ne}),e("div",{className:a.playerRight,children:[b===0?e(o,{name:"volume-mute",className:a.volumeIcon}):b<.5?e(o,{name:"volume-down",className:a.volumeIcon}):e(o,{name:"volume-up",className:a.volumeIcon}),e("input",{className:a.volumeBar,type:"range",min:0,max:1,step:.01,value:b,onChange:t=>{const $=parseFloat(t.target.value);D($),localStorage.setItem("radioVolume",String($))},style:{"--volume-percent":`${b*100}%`},"aria-label":"Volume"})]}),e("div",{className:a.playerActions,children:[l&&W&&e("button",{className:a.playerBtn,onClick:()=>V(t=>!t),"aria-label":N?"Hide art":"Show art",title:N?"Hide art":"Show art",children:N?e(o,{name:"eye-slash"}):e(o,{name:"image"})}),l&&s.lastPlayed.length>0&&e("button",{className:`${a.playerBtn} ${S?a.playerBtnActive:""}`,onClick:()=>I(t=>!t),"aria-label":S?"Hide history":"Show history",title:"Recently played",children:e(o,{name:"list-ol"})}),e("button",{className:a.playerBtn,onClick:u,"aria-label":"Close player",children:e(o,{name:"times"})})]})]}),Q=e("audio",{ref:f,preload:"none",onPlay:()=>m(!0),onPause:()=>m(!1)});return l?J(e(R,{children:[Q,e("div",{className:`${a.npOverlay} ${T?"":a.npOverlayControlsHidden}`,children:[e("div",{className:`${a.npStage} ${!N||!W?a.npStageBlank:""}`,onClick:()=>k(t=>!t),children:N&&W&&M&&e("div",{className:i.coverWrap,children:e("img",{src:M,alt:P,loading:"lazy",decoding:"async",draggable:!1,className:i.cover,onError:()=>z(!0)})})}),e("div",{className:`${a.playerBar} ${a.playerBarDocked} ${T?"":a.playerBarDockedHidden}`,onClick:t=>t.stopPropagation(),children:[j,S&&e(R,{children:[e("div",{className:a.npBackdrop,onClick:()=>I(!1)}),e("div",{className:a.chapterPanel,children:s.lastPlayed.map(t=>e("div",{className:a.chapterRow,children:e("span",{className:a.chapterRowLabel,title:`${U(t)} — ${t.title}`,children:[U(t)," — ",t.title]})},t.id))})]})]})]})]}),document.body):J(e(R,{children:[Q,e("div",{className:a.playerBar,children:j})]}),document.body)},Ne=()=>{y(()=>{document.title="Radio - dango"},[]);const[n,s]=h(""),[p,l]=h(""),[c,d]=h(null),[u,f]=h(!0),{data:v,isLoading:m}=ie(),{data:N,isLoading:V}=ce(p),S=K(()=>v?.stations||[],[v]),I=K(()=>N?.stations||[],[N]),T=p?I:S,{nowPlaying:k,connected:A}=de(c?.gateway),E=r=>{d(r),f(!0)},b=r=>{const g=T.length>0?T:S;if(g.length===0||!c)return;const w=g.findIndex(B=>B.id===c.id),C=g[(w<0?0:w+r+g.length)%g.length];d(C)},D=r=>{const g=c?.id===r.id,w=g&&k.song?`${U(k.song)} — ${k.song.title}`:null,C=[r.codec,r.bitrate?`${r.bitrate}k`:"",r.tags].filter(Boolean).join(" · ");return e("button",{className:`${i.stationRow} ${g?i.stationRowActive:""}`,onClick:()=>E(r),children:[r.favicon?e("img",{src:r.favicon,alt:"",className:i.stationThumb,loading:"lazy",decoding:"async",onError:B=>{B.target.style.display="none"}}):e("span",{className:i.stationThumbPlaceholder,children:e(o,{name:"broadcast-tower"})}),e("span",{className:i.stationMeta,children:[e("span",{className:i.stationName,children:r.name}),C&&e("span",{className:i.stationSub,children:C})]}),w&&e("span",{className:i.stationNowPlaying,children:w})]},r.id)};return e("div",{className:`${L.page} ${c?L.pageWithPlayer:""}`,children:[e("div",{className:L.header,children:[e("h1",{className:L.pageTitle,children:[e(o,{name:"broadcast-tower"})," Radio"]}),e("form",{className:L.searchForm,onSubmit:r=>{r.preventDefault(),l(n)},children:[e("input",{className:L.searchInput,value:n,onChange:r=>s(r.target.value),placeholder:"Search stations (anime, j-pop, k-pop…)","aria-label":"Search radio stations"}),e("button",{className:L.searchBtn,type:"submit","aria-label":"Search",children:e(o,{name:"search"})})]})]}),p?e(R,{children:[e("h2",{className:i.sectionTitle,children:["Results for “",p,"”"]}),V?e("p",{className:a.statusMsg,children:"Searching…"}):I.length===0?e("p",{className:a.statusMsg,children:"No stations found."}):e("div",{className:i.stationList,children:I.map(D)})]}):e(R,{children:[e("h2",{className:i.sectionTitle,children:"Featured"}),m?e("p",{className:a.statusMsg,children:"Loading…"}):e("div",{className:i.stationList,children:S.map(D)})]}),c&&e(me,{station:c,nowPlaying:k,connected:A,expanded:u,onStationStep:b,onExpandedChange:f,onClose:()=>d(null)})]})};export{Ne as default};
@@ -0,0 +1 @@
1
+ import{o as U,d as v,h as b,T as w,u as i,S as E}from"./vendor-core-DfaOB3Rn.js";import{M as x}from"./MediaCard-CoRm07Vb.js";import{L as F}from"./LibraryListPage-Cc-I_48d.js";import{u as _,M as z}from"./useMangaPopup-B5LXZINf.js";import{M as D}from"./MangaResetProgressModal-DrfFCtDE.js";import{x as G,d as O,o as Q,p as Y,u as q,y as H,z as K,A as V,M as h,m as Z,i as j,b as J,c as W}from"./useMangaLibrary-CpQLCvkU.js";import"./vendor-ui-3qrARCPr.js";import"./vendor-icons-DrybRNxP.js";import"./index-CQWyVhME.js";import"./vendor-query-BBT5_sHx.js";import"./useIsMobile-Dvx1uJ82.js";import"./SkeletonGrid-BAQn8Rru.js";import"./ErrorMessage-DAxegITP.js";import"./Watchlist.module-XGtVQr1d.js";import"./usePopup-DS9jMzp6.js";import"./ResetProgressModal-DiYoRAaR.js";const X=["All","Continue Reading",...h],R=24,y=e=>({provider:e.provider,mangaId:e.mangaId,title:e.title,altTitle:e.altTitle,cover:e.cover,contentRating:e.contentRating,readTarget:e.detailTarget,progressLabel:e.progressLabel});function ba(){const{filter:e="All"}=U(),[g,p]=v(1),[d,u]=v(null);b(()=>{document.title="Reading List - dango"},[]),b(()=>{p(1)},[e]);const r=e==="Continue Reading",n=G(r?"All":e,g,R),s=O(100),I=Q(),T=Y(),{toggle:L,bookmarkedIds:C}=q(),{popup:t,openPopup:k,scheduleClose:c,cancelClose:m,closePopup:M}=_(),f=H(),P=K(),B=V(),S=w(()=>r?(s.data?.data??[]).map(a=>{const o=a.page??0,l=a.pageCount??0;return{key:a.id,libId:a.id,provider:a.provider,mangaId:a.mangaId,title:a.title,altTitle:a.altTitle,cover:a.cover||"",status:a.status,contentRating:a.contentRating||void 0,chapterLabel:a.chapterNumber?`Ch. ${a.chapterNumber}`:void 0,progressPercent:l>0?o/l*100:0,progressLabel:a.chapterNumber&&l>0?`Ch. ${a.chapterNumber} · p. ${o}/${l}`:void 0,detailTarget:a.chapterId&&a.provider&&a.mangaId?`/manga/${a.provider}/${encodeURIComponent(a.mangaId)}/read?chapter=${encodeURIComponent(a.chapterId)}`:`/manga/${a.provider}/${encodeURIComponent(a.mangaId)}`}}):(n.data?.data??[]).map(a=>({key:a.id,libId:a.id,provider:a.provider,mangaId:a.mangaId,title:a.title,altTitle:a.altTitle,cover:a.cover||"",status:a.status,contentRating:a.contentRating||void 0,chapterLabel:a.lastChapterNumber?`Ch. ${a.lastChapterNumber}`:void 0,progressPercent:void 0,progressLabel:void 0,detailTarget:`/manga/${a.provider}/${encodeURIComponent(a.mangaId)}`})),[r,s.data,n.data]),A=r?s.data?.total??0:n.data?.total??0,$=r?s.isLoading:n.isLoading,N=r?s.error:n.error;return i(F,{headerTitle:"My Reading List",headerSubtitle:"Track and manage your manga collection",filters:X,filterBy:e,filterBasePath:"/reading-list",continueFilter:"Continue Reading",statusOptions:[...h],entries:S,total:A,isLoading:$,error:N,page:g,pageSize:R,onPageChange:p,emptyTitle:"Your reading list is looking a bit lonely",emptyFilteredText:"No titles match this filter.",emptyAllText:"Let's find something to read!",browseLabel:"Browse Manga",browseTarget:"/manga",removeListLabel:"Remove from Reading List",listNoun:"reading list",skipConfirmKey:"mangaSkipRemoveConfirmation",onBulkStatus:(a,o)=>f.mutate({ids:a,status:o}),onBulkRemove:a=>{r?B.mutate(a):P.mutate(a)},onStatusChange:(a,o)=>T.mutate({id:a,status:o}),onRemoveItem:a=>I.mutate(a),renderCard:a=>i(x,{item:{id:a.libId,title:a.title,...W({title:a.title,altTitle:a.altTitle}),thumbnail:J(a.provider,a.cover),chapterBadge:a.chapterLabel??null,isAdult:j(a)},linkTo:a.detailTarget,hoverIcon:"book",progress:a.progressPercent!==void 0&&a.progressLabel?{percent:a.progressPercent,label:a.progressLabel}:void 0,showProgress:r,display:{elements:{poster:{typeBadge:!1,chapterBadge:!0,adultBadge:!0},info:{title:!0,mobileBadges:!0,progress:!0,meta:!1}}},onRemove:r?()=>u(a):void 0,onOpenDetails:o=>k(o,y(a)),onPopupHoverIntent:o=>o?m():c(),rawThumbnail:!0}),modals:i(E,{children:[t&&t.data.provider&&i(z,{data:t.data,anchorRect:t.rect,bookmarked:C.has(Z(t.data.provider,t.data.mangaId)),onToggleBookmark:()=>L({id:t.data.mangaId,provider:t.data.provider,title:t.data.title,cover:t.data.cover,altTitle:t.data.altTitle??void 0,contentRating:t.data.contentRating}),onMouseEnter:m,onMouseLeave:c,onRequestClose:M}),i(D,{mangaId:d?d.libId:null,title:d?.title,onClose:()=>u(null)})]})})}export{ba as default};
@@ -1 +1 @@
1
- import{u as e}from"./vendor-core-DfaOB3Rn.js";import{M as r,B as n}from"./index-gMxawd-E.js";const p=({isOpen:t,itemName:c,progressKind:i,listLabel:s,alsoRemove:a,onAlsoRemoveChange:d,onClose:o,onConfirm:l})=>e(r,{isOpen:t,onClose:o,title:"Reset Progress",children:[e(r.Body,{children:[e("p",{children:["Are you sure you want to remove your ",i,' progress for "',c,'"?']}),e("label",{children:[e("input",{type:"checkbox",checked:a,onChange:h=>d(h.target.checked)}),"Also remove from ",s]})]}),e(r.Actions,{children:[e(n,{variant:"secondary",onClick:o,children:"No"}),e(n,{variant:"danger",onClick:l,children:"Yes"})]})]});export{p as R};
1
+ import{u as e}from"./vendor-core-DfaOB3Rn.js";import{M as r,B as n}from"./index-CQWyVhME.js";const p=({isOpen:t,itemName:c,progressKind:i,listLabel:s,alsoRemove:a,onAlsoRemoveChange:d,onClose:o,onConfirm:l})=>e(r,{isOpen:t,onClose:o,title:"Reset Progress",children:[e(r.Body,{children:[e("p",{children:["Are you sure you want to remove your ",i,' progress for "',c,'"?']}),e("label",{children:[e("input",{type:"checkbox",checked:a,onChange:h=>d(h.target.checked)}),"Also remove from ",s]})]}),e(r.Actions,{children:[e(n,{variant:"secondary",onClick:o,children:"No"}),e(n,{variant:"danger",onClick:l,children:"Yes"})]})]});export{p as R};
@@ -1 +1 @@
1
- import{h as O,p as me,a as ge,d as o,A as ve,g as fe,u as a}from"./vendor-core-DfaOB3Rn.js";import{I as L}from"./vendor-icons-DrybRNxP.js";import{P as ee,S as Le}from"./SkeletonGrid-nx2HEi4P.js";import{A as Ae}from"./AnimeCard-BVdH0EeW.js";import{t as be,u as ye,v as Se,R as ae,B as w,U as Ne}from"./index-gMxawd-E.js";import{E as Ce}from"./ErrorMessage-DAxegITP.js";import{s as t}from"./Search.module-CMEai-B-.js";import"./useAnimeInfoData-_iOLEAa8.js";import"./vendor-query-BBT5_sHx.js";import"./QueueOptionsButton-ClVTpH8J.js";import"./vendor-ui-3qrARCPr.js";import"./MediaCard-BcLjlpfR.js";import"./useIsMobile-Dvx1uJ82.js";const Te=[{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:"Mature"}],Ee=[{value:"ALL",label:"All Seasons"},{value:"Winter",label:"Winter"},{value:"Spring",label:"Spring"},{value:"Summer",label:"Summer"},{value:"Fall",label:"Fall"}],Ie=[{value:"ALL",label:"All Countries"},{value:"JP",label:"Japan"},{value:"CN",label:"China"}],De=[{value:"POPULARITY_DESC",label:"Popularity"},{value:"TRENDING_DESC",label:"Trending"},{value:"SCORE_DESC",label:"Score"},{value:"START_DATE_DESC",label:"Newest"},{value:"START_DATE_ASC",label:"Oldest"},{value:"EPISODES_DESC",label:"Most Episodes"},{value:"FAVOURITES_DESC",label:"Favourites"}],Pe=[{value:"RELEASING",label:"Currently Airing"},{value:"FINISHED",label:"Finished"},{value:"NOT_YET_RELEASED",label:"Not Yet Released"},{value:"CANCELLED",label:"Cancelled"},{value:"HIATUS",label:"Hiatus"}];function Ve(){O(()=>{document.title="Search - dango"},[]);const[r,te]=me(),le=ge(),[h,k]=o(r.get("query")||""),[p,_]=o(parseInt(r.get("page")||"1")),[u,A]=o(r.get("type")||"ALL"),[m,b]=o(r.get("season")||"ALL"),[g,y]=o(r.get("year")||"ALL"),[B,E]=o(r.get("country")||"ALL"),[G,ne]=o(r.get("provider")||"anilist"),[Y,I]=o(r.get("sortBy")||"POPULARITY_DESC"),[U,D]=o(r.get("status")||""),[S,re]=o(!1),[se,F]=o(null);O(()=>{let e=!1;return be.data.anilistStatus.query().then(n=>{e||F(n.available)}).catch(()=>{e||F(!0)}),()=>{e=!0}},[]);const{lowEndMode:ie}=ye(),P=ve(null),{data:oe}=Se(),M=oe?.genres||[],[v,N]=o(()=>{const e={},n=r.get("genres")?.split(",").map(l=>l.trim()).filter(Boolean)||[],s=r.get("excludeGenres")?.split(",").map(l=>l.trim()).filter(Boolean)||[];return n.forEach(l=>l&&(e[l]="include")),s.forEach(l=>l&&(e[l]="exclude")),e}),$=new URLSearchParams(r);$.delete("page");const V=$.toString(),{data:f=[],isLoading:C,isError:ce,error:ue}=ae(V,p,14),{data:j}=ae(V,p+1,14),[x,de]=o(!1),T=fe.useMemo(()=>G==="anilist"&&u==="ADULT"||x?f:f.filter(e=>!(e.isAdult||e.rating==="R+"||e.rating==="Rx"||e.rating?.includes("17+"))),[f,x,G,u]);O(()=>{k(r.get("query")||""),A(r.get("type")||"ALL"),b(r.get("season")||"ALL"),y(r.get("year")||"ALL"),E(r.get("country")||"ALL"),ne(r.get("provider")||"anilist"),I(r.get("sortBy")||"POPULARITY_DESC"),D(r.get("status")||""),_(parseInt(r.get("page")||"1"));const e={},n=r.get("genres")?.split(",").map(l=>l.trim()).filter(Boolean)||[],s=r.get("excludeGenres")?.split(",").map(l=>l.trim()).filter(Boolean)||[];n.forEach(l=>l&&(e[l]="include")),s.forEach(l=>l&&(e[l]="exclude")),N(e)},[r]);const c=(e=1,n={})=>{Ne();const s=n.type??u,l=n.status??U,q=n.season??m,H=n.year??g,J=n.country??B,K=n.sort??Y,Q=n.genreState??v,pe=n.showMature??x,i=new URLSearchParams;h.trim()&&i.set("query",h.trim()),s!=="ALL"&&i.set("type",s),l&&i.set("status",l),q!=="ALL"&&i.set("season",q),H!=="ALL"&&i.set("year",H),J!=="ALL"&&i.set("country",J),K!=="POPULARITY_DESC"&&i.set("sortBy",K);const X=Object.entries(Q).filter(([,d])=>d==="include").map(([d])=>d),Z=Object.entries(Q).filter(([,d])=>d==="exclude").map(([d])=>d);X.length>0&&i.set("genres",X.join(",")),Z.length>0&&i.set("excludeGenres",Z.join(",")),s!=="ADULT"&&!pe&&i.set("adult","false"),i.set("provider","anilist"),e>1&&i.set("page",e.toString()),te(i),e!==p&&_(e)},W=e=>{if(c(e),P.current){const n=P.current.getBoundingClientRect().top+window.scrollY-100;window.scrollTo({top:n,behavior:"smooth"})}},R=new Date().getFullYear(),he=[{value:"ALL",label:"All Years"},...Array.from({length:R-1980+1},(e,n)=>({value:String(R-n),label:String(R-n)}))],z=f.length>=14&&j&&j.length>0;return a("div",{className:"page-container",children:[a("div",{className:t.header,children:[a("h1",{className:t.pageTitle,children:"Search Anime"}),a("p",{className:t.pageSubtitle,children:"Search through thousands of titles and discover your next favorite"})]}),a("div",{className:t.filterContainer,children:[a("div",{className:t.searchBarWrapper,children:[a("div",{className:t.inputIconWrapper,children:[a(L,{name:"search",className:t.searchIcon}),a("input",{type:"text","data-virtual-keyboard":"true",className:t.searchInput,placeholder:"Search by title, character, or studio...",value:h,onInput:e=>k(e.currentTarget.value),onKeyDown:e=>e.key==="Enter"&&c()})]}),a("div",{className:t.searchActions,children:[a(w,{onClick:()=>c(),className:t.searchBtn,children:"Search"}),a("button",{className:`${t.filterToggleBtn} ${S?t.active:""}`,onClick:()=>re(!S),children:[a(L,{name:"filter",size:14}),a("span",{children:"Filters"}),S?a(L,{name:"chevron-up",size:12}):a(L,{name:"chevron-down",size:12})]})]})]}),a("div",{className:`${t.advancedFilters} ${S?t.show:""}`,children:[a("div",{className:t.filterDivider}),a("div",{className:t.filterGrid,children:[a("div",{className:t.filterItem,children:[a("label",{children:"Type"}),a("select",{value:u,onChange:e=>{if(e.currentTarget.value==="ADULT"){le("/mature?provider=mal");return}A(e.currentTarget.value)},children:Te.map(e=>a("option",{value:e.value,children:e.label},e.value))})]}),a("div",{className:t.filterItem,children:[a("label",{children:"Status"}),a("select",{value:U,onChange:e=>D(e.currentTarget.value),children:[a("option",{value:"",children:"All Status"}),Pe.map(e=>a("option",{value:e.value,children:e.label},e.value))]})]}),a("div",{className:t.filterItem,children:[a("label",{children:"Season"}),a("select",{value:m,onChange:e=>b(e.currentTarget.value),children:Ee.map(e=>a("option",{value:e.value,children:e.label},e.value))})]}),a("div",{className:t.filterItem,children:[a("label",{children:"Year"}),a("select",{value:g,onChange:e=>y(e.currentTarget.value),children:he.map(e=>a("option",{value:e.value,children:e.label},e.value))})]}),a("div",{className:t.filterItem,children:[a("label",{children:["Country",se===!1&&a("span",{style:{display:"block",fontSize:"0.75rem",color:"var(--text-muted)",fontWeight:400},children:"AniList only — ignored by fallback providers"})]}),a("select",{value:B,onChange:e=>E(e.currentTarget.value),children:Ie.map(e=>a("option",{value:e.value,children:e.label},e.value))})]}),a("div",{className:t.filterItem,children:[a("label",{children:"Sort By"}),a("select",{value:Y,onChange:e=>I(e.currentTarget.value),children:De.map(e=>a("option",{value:e.value,children:e.label},e.value))})]})]}),M.length>0&&a("div",{className:t.genreSection,children:[a("label",{className:t.genreLabel,children:"Genres"}),a("div",{className:t.genreContainer,children:M.map(e=>a("button",{className:`${t.genreButton} ${t[v[e]||""]}`,onClick:()=>{N(n=>{const s=n[e],l={...n};return s==="include"?l[e]="exclude":s==="exclude"?delete l[e]:l[e]="include",l})},children:e},e))})]}),a("div",{className:t.filterActions,children:[a(w,{variant:"secondary",onClick:()=>{N({}),A("ALL"),b("ALL"),y("ALL"),E("ALL"),I("POPULARITY_DESC"),D(""),de(!1),c(1,{type:"ALL",status:"",season:"ALL",year:"ALL",country:"ALL",sort:"POPULARITY_DESC",genreState:{},showMature:!1})},children:"Reset All"}),a(w,{onClick:()=>c(),className:t.applyBtn,children:"Apply Filters"})]})]})]}),ce&&a(Ce,{message:ue?.message||"Error"}),(u!=="ALL"||m!=="ALL"||g!=="ALL"||Object.keys(v).length>0)&&a("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px",alignItems:"center",marginBottom:"1.5rem"},children:[a("span",{style:{fontSize:"0.8rem",color:"var(--text-muted)",fontWeight:600},children:"Active Filters:"}),u!=="ALL"&&a("span",{className:"badge badge-secondary",style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:["Type: ",u,a("button",{onClick:e=>{e.stopPropagation(),e.preventDefault(),A("ALL"),c(1,{type:"ALL"})},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]}),m!=="ALL"&&a("span",{className:"badge badge-secondary",style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:["Season: ",m,a("button",{onClick:e=>{e.stopPropagation(),e.preventDefault(),b("ALL"),c(1,{season:"ALL"})},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]}),g!=="ALL"&&a("span",{className:"badge badge-secondary",style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:["Year: ",g,a("button",{onClick:e=>{e.stopPropagation(),e.preventDefault(),y("ALL"),c(1,{year:"ALL"})},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]}),Object.entries(v).map(([e,n])=>a("span",{className:`badge ${n==="include"?"badge-primary":"badge-danger"}`,style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:[n==="include"?`+ ${e}`:`- ${e}`,a("button",{onClick:s=>{s.stopPropagation(),s.preventDefault();const l={...v};delete l[e],N(l),c(1,{genreState:l})},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]},e))]}),a("div",{className:t.resultsHeader,ref:P,children:[a("h2",{className:t.resultsTitle,children:h?`Search Results for "${h}"`:"Discover Anime"}),T.length>0&&a(ee,{page:p,canGoNext:z,onChange:W,isLoading:C})]}),a("div",{className:`${t.resultsGrid} ${ie?t.lowEnd:""}`,children:C?a(Le,{}):T.map(e=>a(Ae,{anime:e},e._id))}),!C&&T.length===0&&a("div",{className:t.noResults,children:[a(L,{name:"search",size:48,className:t.noResultsIcon}),a("h3",{children:"No results found"}),a("p",{children:"Try adjusting your search or filters to find what you're looking for."})]}),T.length>0&&a("div",{className:t.bottomPagination,children:a(ee,{page:p,canGoNext:z,onChange:W,isLoading:C,variant:"labeled"})})]})}export{Ve as default};
1
+ import{h as O,p as me,a as ge,d as o,A as ve,g as fe,u as a}from"./vendor-core-DfaOB3Rn.js";import{I as L}from"./vendor-icons-DrybRNxP.js";import{P as ee,S as Le}from"./SkeletonGrid-BAQn8Rru.js";import{A as Ae}from"./AnimeCard-Cll26FQe.js";import{t as be,u as ye,v as Se,R as ae,B as w,U as Ne}from"./index-CQWyVhME.js";import{E as Ce}from"./ErrorMessage-DAxegITP.js";import{s as t}from"./Search.module-CMEai-B-.js";import"./useAnimeInfoData-CthDMEMc.js";import"./vendor-query-BBT5_sHx.js";import"./QueueOptionsButton-CpyBvbsh.js";import"./vendor-ui-3qrARCPr.js";import"./MediaCard-CoRm07Vb.js";import"./useIsMobile-Dvx1uJ82.js";const Te=[{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:"Mature"}],Ee=[{value:"ALL",label:"All Seasons"},{value:"Winter",label:"Winter"},{value:"Spring",label:"Spring"},{value:"Summer",label:"Summer"},{value:"Fall",label:"Fall"}],Ie=[{value:"ALL",label:"All Countries"},{value:"JP",label:"Japan"},{value:"CN",label:"China"}],De=[{value:"POPULARITY_DESC",label:"Popularity"},{value:"TRENDING_DESC",label:"Trending"},{value:"SCORE_DESC",label:"Score"},{value:"START_DATE_DESC",label:"Newest"},{value:"START_DATE_ASC",label:"Oldest"},{value:"EPISODES_DESC",label:"Most Episodes"},{value:"FAVOURITES_DESC",label:"Favourites"}],Pe=[{value:"RELEASING",label:"Currently Airing"},{value:"FINISHED",label:"Finished"},{value:"NOT_YET_RELEASED",label:"Not Yet Released"},{value:"CANCELLED",label:"Cancelled"},{value:"HIATUS",label:"Hiatus"}];function Ve(){O(()=>{document.title="Search - dango"},[]);const[r,te]=me(),le=ge(),[h,k]=o(r.get("query")||""),[p,_]=o(parseInt(r.get("page")||"1")),[u,A]=o(r.get("type")||"ALL"),[m,b]=o(r.get("season")||"ALL"),[g,y]=o(r.get("year")||"ALL"),[B,E]=o(r.get("country")||"ALL"),[G,ne]=o(r.get("provider")||"anilist"),[Y,I]=o(r.get("sortBy")||"POPULARITY_DESC"),[U,D]=o(r.get("status")||""),[S,re]=o(!1),[se,F]=o(null);O(()=>{let e=!1;return be.data.anilistStatus.query().then(n=>{e||F(n.available)}).catch(()=>{e||F(!0)}),()=>{e=!0}},[]);const{lowEndMode:ie}=ye(),P=ve(null),{data:oe}=Se(),M=oe?.genres||[],[v,N]=o(()=>{const e={},n=r.get("genres")?.split(",").map(l=>l.trim()).filter(Boolean)||[],s=r.get("excludeGenres")?.split(",").map(l=>l.trim()).filter(Boolean)||[];return n.forEach(l=>l&&(e[l]="include")),s.forEach(l=>l&&(e[l]="exclude")),e}),$=new URLSearchParams(r);$.delete("page");const V=$.toString(),{data:f=[],isLoading:C,isError:ce,error:ue}=ae(V,p,14),{data:j}=ae(V,p+1,14),[x,de]=o(!1),T=fe.useMemo(()=>G==="anilist"&&u==="ADULT"||x?f:f.filter(e=>!(e.isAdult||e.rating==="R+"||e.rating==="Rx"||e.rating?.includes("17+"))),[f,x,G,u]);O(()=>{k(r.get("query")||""),A(r.get("type")||"ALL"),b(r.get("season")||"ALL"),y(r.get("year")||"ALL"),E(r.get("country")||"ALL"),ne(r.get("provider")||"anilist"),I(r.get("sortBy")||"POPULARITY_DESC"),D(r.get("status")||""),_(parseInt(r.get("page")||"1"));const e={},n=r.get("genres")?.split(",").map(l=>l.trim()).filter(Boolean)||[],s=r.get("excludeGenres")?.split(",").map(l=>l.trim()).filter(Boolean)||[];n.forEach(l=>l&&(e[l]="include")),s.forEach(l=>l&&(e[l]="exclude")),N(e)},[r]);const c=(e=1,n={})=>{Ne();const s=n.type??u,l=n.status??U,q=n.season??m,H=n.year??g,J=n.country??B,K=n.sort??Y,Q=n.genreState??v,pe=n.showMature??x,i=new URLSearchParams;h.trim()&&i.set("query",h.trim()),s!=="ALL"&&i.set("type",s),l&&i.set("status",l),q!=="ALL"&&i.set("season",q),H!=="ALL"&&i.set("year",H),J!=="ALL"&&i.set("country",J),K!=="POPULARITY_DESC"&&i.set("sortBy",K);const X=Object.entries(Q).filter(([,d])=>d==="include").map(([d])=>d),Z=Object.entries(Q).filter(([,d])=>d==="exclude").map(([d])=>d);X.length>0&&i.set("genres",X.join(",")),Z.length>0&&i.set("excludeGenres",Z.join(",")),s!=="ADULT"&&!pe&&i.set("adult","false"),i.set("provider","anilist"),e>1&&i.set("page",e.toString()),te(i),e!==p&&_(e)},W=e=>{if(c(e),P.current){const n=P.current.getBoundingClientRect().top+window.scrollY-100;window.scrollTo({top:n,behavior:"smooth"})}},R=new Date().getFullYear(),he=[{value:"ALL",label:"All Years"},...Array.from({length:R-1980+1},(e,n)=>({value:String(R-n),label:String(R-n)}))],z=f.length>=14&&j&&j.length>0;return a("div",{className:"page-container",children:[a("div",{className:t.header,children:[a("h1",{className:t.pageTitle,children:"Search Anime"}),a("p",{className:t.pageSubtitle,children:"Search through thousands of titles and discover your next favorite"})]}),a("div",{className:t.filterContainer,children:[a("div",{className:t.searchBarWrapper,children:[a("div",{className:t.inputIconWrapper,children:[a(L,{name:"search",className:t.searchIcon}),a("input",{type:"text","data-virtual-keyboard":"true",className:t.searchInput,placeholder:"Search by title, character, or studio...",value:h,onInput:e=>k(e.currentTarget.value),onKeyDown:e=>e.key==="Enter"&&c()})]}),a("div",{className:t.searchActions,children:[a(w,{onClick:()=>c(),className:t.searchBtn,children:"Search"}),a("button",{className:`${t.filterToggleBtn} ${S?t.active:""}`,onClick:()=>re(!S),children:[a(L,{name:"filter",size:14}),a("span",{children:"Filters"}),S?a(L,{name:"chevron-up",size:12}):a(L,{name:"chevron-down",size:12})]})]})]}),a("div",{className:`${t.advancedFilters} ${S?t.show:""}`,children:[a("div",{className:t.filterDivider}),a("div",{className:t.filterGrid,children:[a("div",{className:t.filterItem,children:[a("label",{children:"Type"}),a("select",{value:u,onChange:e=>{if(e.currentTarget.value==="ADULT"){le("/mature?provider=mal");return}A(e.currentTarget.value)},children:Te.map(e=>a("option",{value:e.value,children:e.label},e.value))})]}),a("div",{className:t.filterItem,children:[a("label",{children:"Status"}),a("select",{value:U,onChange:e=>D(e.currentTarget.value),children:[a("option",{value:"",children:"All Status"}),Pe.map(e=>a("option",{value:e.value,children:e.label},e.value))]})]}),a("div",{className:t.filterItem,children:[a("label",{children:"Season"}),a("select",{value:m,onChange:e=>b(e.currentTarget.value),children:Ee.map(e=>a("option",{value:e.value,children:e.label},e.value))})]}),a("div",{className:t.filterItem,children:[a("label",{children:"Year"}),a("select",{value:g,onChange:e=>y(e.currentTarget.value),children:he.map(e=>a("option",{value:e.value,children:e.label},e.value))})]}),a("div",{className:t.filterItem,children:[a("label",{children:["Country",se===!1&&a("span",{style:{display:"block",fontSize:"0.75rem",color:"var(--text-muted)",fontWeight:400},children:"AniList only — ignored by fallback providers"})]}),a("select",{value:B,onChange:e=>E(e.currentTarget.value),children:Ie.map(e=>a("option",{value:e.value,children:e.label},e.value))})]}),a("div",{className:t.filterItem,children:[a("label",{children:"Sort By"}),a("select",{value:Y,onChange:e=>I(e.currentTarget.value),children:De.map(e=>a("option",{value:e.value,children:e.label},e.value))})]})]}),M.length>0&&a("div",{className:t.genreSection,children:[a("label",{className:t.genreLabel,children:"Genres"}),a("div",{className:t.genreContainer,children:M.map(e=>a("button",{className:`${t.genreButton} ${t[v[e]||""]}`,onClick:()=>{N(n=>{const s=n[e],l={...n};return s==="include"?l[e]="exclude":s==="exclude"?delete l[e]:l[e]="include",l})},children:e},e))})]}),a("div",{className:t.filterActions,children:[a(w,{variant:"secondary",onClick:()=>{N({}),A("ALL"),b("ALL"),y("ALL"),E("ALL"),I("POPULARITY_DESC"),D(""),de(!1),c(1,{type:"ALL",status:"",season:"ALL",year:"ALL",country:"ALL",sort:"POPULARITY_DESC",genreState:{},showMature:!1})},children:"Reset All"}),a(w,{onClick:()=>c(),className:t.applyBtn,children:"Apply Filters"})]})]})]}),ce&&a(Ce,{message:ue?.message||"Error"}),(u!=="ALL"||m!=="ALL"||g!=="ALL"||Object.keys(v).length>0)&&a("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px",alignItems:"center",marginBottom:"1.5rem"},children:[a("span",{style:{fontSize:"0.8rem",color:"var(--text-muted)",fontWeight:600},children:"Active Filters:"}),u!=="ALL"&&a("span",{className:"badge badge-secondary",style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:["Type: ",u,a("button",{onClick:e=>{e.stopPropagation(),e.preventDefault(),A("ALL"),c(1,{type:"ALL"})},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]}),m!=="ALL"&&a("span",{className:"badge badge-secondary",style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:["Season: ",m,a("button",{onClick:e=>{e.stopPropagation(),e.preventDefault(),b("ALL"),c(1,{season:"ALL"})},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]}),g!=="ALL"&&a("span",{className:"badge badge-secondary",style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:["Year: ",g,a("button",{onClick:e=>{e.stopPropagation(),e.preventDefault(),y("ALL"),c(1,{year:"ALL"})},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]}),Object.entries(v).map(([e,n])=>a("span",{className:`badge ${n==="include"?"badge-primary":"badge-danger"}`,style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:[n==="include"?`+ ${e}`:`- ${e}`,a("button",{onClick:s=>{s.stopPropagation(),s.preventDefault();const l={...v};delete l[e],N(l),c(1,{genreState:l})},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]},e))]}),a("div",{className:t.resultsHeader,ref:P,children:[a("h2",{className:t.resultsTitle,children:h?`Search Results for "${h}"`:"Discover Anime"}),T.length>0&&a(ee,{page:p,canGoNext:z,onChange:W,isLoading:C})]}),a("div",{className:`${t.resultsGrid} ${ie?t.lowEnd:""}`,children:C?a(Le,{}):T.map(e=>a(Ae,{anime:e},e._id))}),!C&&T.length===0&&a("div",{className:t.noResults,children:[a(L,{name:"search",size:48,className:t.noResultsIcon}),a("h3",{children:"No results found"}),a("p",{children:"Try adjusting your search or filters to find what you're looking for."})]}),T.length>0&&a("div",{className:t.bottomPagination,children:a(ee,{page:p,canGoNext:z,onChange:W,isLoading:C,variant:"labeled"})})]})}export{Ve as default};
@@ -1,4 +1,4 @@
1
- import{d as r,A as V,h as A,u as e,q as ae,S as te,T as Le,p as xe,a as Pe,g as pe,_ as Ae}from"./vendor-core-DfaOB3Rn.js";import{d as Oe,t as b,B as I,M as F,j as ve,h as Ue,T as H,z as ye,F as oe,G as Me,H as Ee,u as $e,e as Ge,I as Fe,y as fe,A as Ke,J as He,K as Be,V as ze,L as qe,N as je,O as We}from"./index-gMxawd-E.js";import{u as ue}from"./vendor-query-BBT5_sHx.js";import{I as W}from"./vendor-icons-DrybRNxP.js";const ce={"title-preference-container":"_title-preference-container_sdqgs_1","toggle-button":"_toggle-button_sdqgs_21","toggle-label":"_toggle-label_sdqgs_51"},le=["name","nativeName","englishName"],de={name:"Default (Romaji)",nativeName:"Native",englishName:"English"},Ve=()=>{const{titlePreference:t,setTitlePreference:s,loading:i}=Oe(),[c,h]=r(de[t]),[d,_]=r(!1),m=V(null);A(()=>{i||h(de[t])},[t,i]);const a=async()=>{if(d)return;_(!0);const f=(le.indexOf(t)+1)%le.length,p=le[f],l=de[p];m.current&&(m.current.style.transform="translateX(-100%)",m.current.style.opacity="0"),setTimeout(async()=>{h(l),s(p),m.current&&(m.current.style.transition="none",m.current.style.transform="translateX(100%)",m.current.style.opacity="0",m.current.offsetWidth,m.current.style.transition="transform 0.3s ease-out, opacity 0.3s ease-out",m.current.style.transform="translateX(0)",m.current.style.opacity="1");try{await b.settings.set.mutate({key:"titlePreference",value:p})}catch(T){console.error("Error saving title preference:",T)}finally{_(!1)}},300)};return i?e("p",{children:"Loading title preference..."}):e("div",{className:ce["title-preference-container"],children:[e("h4",{children:"Anime Title Display Preference"}),e("button",{onClick:a,className:ce["toggle-button"],disabled:d,children:e("span",{ref:m,className:ce["toggle-label"],children:c})})]})},Ye="_settingsHeader_14a5d_1",Je="_pageTitle_14a5d_6",Qe="_pageSubtitle_14a5d_14",Xe="_settingsLayout_14a5d_20",Ze="_sidebar_14a5d_27",et="_sidebarIndicator_14a5d_35",tt="_sidebarItem_14a5d_50",at="_active_14a5d_72",nt="_mainContent_14a5d_80",st="_tabContent_14a5d_85",rt="_sectionCard_14a5d_103",it="_settingItem_14a5d_127",ot="_settingRow_14a5d_132",ct="_controls_14a5d_145",lt="_status_14a5d_151",g={settingsHeader:Ye,pageTitle:Je,pageSubtitle:Qe,settingsLayout:Xe,sidebar:Ze,sidebarIndicator:et,sidebarItem:tt,active:at,mainContent:nt,tabContent:st,sectionCard:rt,settingItem:it,settingRow:ot,controls:ct,status:lt},dt="_sectionCard_wt900_12",ut="_title_wt900_22",ht="_signIn_wt900_29",gt="_userInfo_wt900_36",mt="_warning_wt900_58",pt="_formGroup_wt900_65",yt="_label_wt900_69",ft="_inputWrapper_wt900_79",wt="_input_wt900_79",vt="_select_wt900_103",bt="_actions_wt900_140",_t="_hr_wt900_148",y={sectionCard:dt,title:ut,signIn:ht,userInfo:gt,warning:mt,formGroup:pt,label:yt,inputWrapper:ft,input:wt,select:vt,actions:bt,hr:_t},kt=()=>{const[t,s]=r(!0),[i,c]=r(!1),[h,d]=r(!1),[_,m]=r(null),[a,u]=r({status:"idle"}),[f,p]=r(!1),[l,T]=r(""),[w,C]=r(!1),x=V(null),[L,D]=r({show:!1,message:"",type:"info"}),O=()=>{x.current&&(window.clearInterval(x.current),x.current=null)},N=ae(S=>{d(S.authenticated),m(S.user||S.device.user||null),u(S.device),p(!!S.hasCustomClientId)},[]),R=ae(async()=>{const S=await b.auth.githubStatus.query();N(S)},[N]),M=async()=>{try{const S=await b.auth.githubPoll.query();u(S),S.status==="success"?(O(),await R(),D({show:!0,message:"GitHub authentication complete. Sync has been initialized.",type:"success"})):S.status==="error"&&(O(),D({show:!0,message:S.error||"GitHub authentication failed.",type:"error"}))}catch{O(),D({show:!0,message:"Failed to poll GitHub authentication status.",type:"error"})}},v=(S=5)=>{O(),x.current=window.setInterval(M,Math.max(S,5)*1e3)};A(()=>(R().catch(()=>{D({show:!0,message:"Failed to load GitHub sync status.",type:"error"})}).finally(()=>s(!1)),O),[R]);const k=async()=>{c(!0);try{const S=await b.auth.githubStart.mutate();u(S),v(S.verification?.interval)}catch(S){D({show:!0,message:S instanceof Error?S.message:"Failed to start GitHub authentication.",type:"error"})}finally{c(!1)}},U=async()=>{try{await b.auth.githubLogout.mutate(),d(!1),m(null),u({status:"idle"}),D({show:!0,message:"Signed out of GitHub sync.",type:"success"})}catch{D({show:!0,message:"Failed to sign out of GitHub.",type:"error"})}},E=async()=>{C(!0);try{await b.auth.saveGithubAuth.mutate({clientId:l}),T(""),await R(),D({show:!0,message:"Custom GitHub auth saved.",type:"success"})}catch{D({show:!0,message:"Failed to save override.",type:"error"})}finally{C(!1)}},z=async()=>{C(!0);try{await b.auth.saveGithubAuth.mutate({clientId:""}),T(""),await R(),D({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{D({show:!0,message:"Failed to clear override.",type:"error"})}finally{C(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:y.sectionCard,children:[e("h3",{className:y.title,children:"GitHub Cloud Sync"}),e("p",{className:y.signIn,children:"Sync local data through a private GitHub repository named dango-sync-data."}),h&&_?e("div",{className:y.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:_.name||_.login})]}),e(I,{variant:"danger",onClick:U,children:"Sign Out"})]}):e("div",{className:y.signIn,children:e(I,{onClick:k,disabled:i||a.status==="pending",children:i||a.status==="pending"?"Waiting for GitHub...":"Sign in with GitHub"})}),a.status==="pending"&&a.verification&&e(te,{children:[e("hr",{className:y.hr}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Verification URL"}),e("div",{className:y.inputWrapper,children:[e("input",{className:y.input,value:a.verification.verification_uri,readOnly:!0}),e(I,{onClick:()=>{const S=a.verification?.verification_uri;S&&/^https?:\/\//i.test(S)&&window.open(S,"_blank","noopener,noreferrer")},children:"Open"})]})]}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Device Code"}),e("input",{className:y.input,value:a.verification.user_code,readOnly:!0})]})]}),a.status==="error"&&e("p",{className:y.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 ",f?"(override active)":""]}),e("div",{className:y.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:y.label,children:"Client ID (optional)"}),e("input",{className:y.input,value:l,onChange:S=>T(S.currentTarget.value),placeholder:"Your GitHub OAuth app ID"})]}),e("div",{className:y.actions,children:[e(I,{onClick:E,disabled:w,children:"Save override"}),e(I,{variant:"secondary",onClick:z,disabled:w,children:"Use dango defaults"})]})]}),e(F,{isOpen:L.show,onClose:()=>D(S=>({...S,show:!1})),width:"sm",children:[e(F.Body,{children:e("p",{children:L.message})}),e(F.Actions,{children:e(I,{onClick:()=>D(S=>({...S,show:!1})),children:"OK"})})]})]})},St=()=>{const[t,s]=r(!0),[i,c]=r(null),[h,d]=r(!1),[_,m]=r(!1),[a,u]=r(""),[f,p]=r(""),[l,T]=r(""),[w,C]=r(!1),[x,L]=r({show:!1,message:"",type:"info"}),D=async()=>{try{const k=await b.auth.user.query();c(k?.email?k:null)}catch{c(null)}},O=async()=>{try{const[k,U]=await Promise.all([b.auth.configStatus.query(),b.auth.googleAuth.query()]);d(!!k.hasConfig),m(!!(U.hasCustomWorkerUrl||U.hasCustomClientId||U.hasClientSecret))}catch(k){console.error("Failed to fetch config status",k)}};A(()=>{(async()=>{s(!0),await Promise.all([D(),O()]);try{new URLSearchParams(window.location.search).get("google_auth")==="success"&&(await D(),window.history.replaceState(null,"",window.location.pathname))}catch{}s(!1)})();const U=E=>{E.origin===window.location.origin&&typeof E.data=="object"&&E.data!==null&&E.data.type==="GOOGLE_AUTH_SUCCESS"&&(c(E.data.user),window.location.reload())};return window.addEventListener("message",U),()=>window.removeEventListener("message",U)},[]);const N=async()=>{try{const k=await b.auth.googleLogin.mutate();if(k.authenticated){window.location.reload();return}if(k.url){if(typeof window.DangoBridge<"u"){window.location.href=k.url;return}const E=600,z=700,S=window.innerWidth/2-E/2,ne=window.innerHeight/2-z/2;window.open(k.url,"GoogleAuth",`width=${E},height=${z},top=${ne},left=${S}`)}else throw new Error("Auth URL not available")}catch{L({show:!0,message:"Authentication failed. Ensure server is configured correctly.",type:"error"})}},R=async()=>{try{await b.auth.logout.mutate(),c(null),L({show:!0,message:"Successfully signed out.",type:"success"}),window.location.reload()}catch(k){console.error("Sign out failed",k),L({show:!0,message:"Failed to sign out.",type:"error"})}},M=async()=>{C(!0);try{await b.auth.saveGoogleAuth.mutate({workerUrl:a,clientId:f,clientSecret:l}),u(""),p(""),T(""),await O(),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{C(!1)}},v=async()=>{C(!0);try{await b.auth.saveGoogleAuth.mutate({workerUrl:"",clientId:"",clientSecret:""}),u(""),p(""),T(""),await O(),L({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{L({show:!0,message:"Failed to clear override.",type:"error"})}finally{C(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:y.sectionCard,children:[e("h3",{className:y.title,children:"Google Drive Sync"}),i?e("div",{className:y.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:i.name})," (",i.email,")"]}),e(I,{variant:"danger",onClick:R,children:"Sign Out"})]}):e("div",{className:y.signIn,children:[e("p",{children:"Sign in with your Google account to enable synchronization features."}),e(I,{onClick:N,disabled:!h,children:"Sign in with Google"}),!h&&e("p",{className:y.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 ",_?"(override active)":""]}),e("div",{className:y.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:y.label,children:"Worker URL (optional)"}),e("input",{className:y.input,value:a,onChange:k=>u(k.currentTarget.value),placeholder:"https://your-worker.workers.dev"})]}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Client ID (optional)"}),e("input",{className:y.input,value:f,onChange:k=>p(k.currentTarget.value),placeholder:"Your Google OAuth client ID"})]}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Client Secret (optional)"}),e("input",{type:"password",className:y.input,value:l,onChange:k=>T(k.currentTarget.value),placeholder:"Your Google OAuth secret"})]}),e("div",{className:y.actions,children:[e(I,{onClick:M,disabled:w,children:"Save override"}),e(I,{variant:"secondary",onClick:v,disabled:w,children:"Use dango defaults"})]})]}),e(F,{isOpen:x.show,onClose:()=>L(k=>({...k,show:!1})),width:"sm",children:[e(F.Body,{children:e("p",{children:x.message})}),e(F.Actions,{children:e(I,{onClick:()=>L(k=>({...k,show:!1})),children:"OK"})})]})]})},Ct="_sectionCard_1pqo4_1",Nt="_settingItem_1pqo4_26",Tt="_settingRow_1pqo4_31",Rt="_modalOverlay_1pqo4_38",Dt="_modal_1pqo4_38",It="_modalActions_1pqo4_73",Lt="_modalSecondary_1pqo4_79",xt="_modalPrimary_1pqo4_89",G={sectionCard:Ct,settingItem:Nt,settingRow:Tt,modalOverlay:Rt,modal:Dt,modalActions:It,modalSecondary:Lt,modalPrimary:xt},Pt={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"]]}},At=(t,s)=>{if(t==null)return s;const i=String(t);return i==="true"||i==="1"?!0:i==="false"||i==="0"?!1:s},we=(t,s,i)=>{const[c,h]=r(s),[d,_]=r(!1),m=ue();return A(()=>{(async()=>{try{const f=await b.settings.getByKey.query({key:t});h(At(f.value,s))}catch(f){console.error("Failed to fetch setting",f)}})()},[t,s]),{value:c,setValue:h,isUpdating:d,toggle:async()=>{if(d)return;_(!0);const u=!c;h(u);try{await b.settings.set.mutate({key:t,value:u});for(const f of i)m.invalidateQueries({queryKey:f})}catch(f){console.error("Error saving setting:",f),h(!u)}finally{_(!1)}}}},Ot=()=>{const{contentType:t}=ve(),s=Pt[t],[i,c]=r(!1),[h,d]=r(!0),[_,m]=r(!1),a=we(s.ignoreKey,!0,s.invalidateKeys),u=we(s.listOnlyKey,!1,s.invalidateKeys),[f,p]=r(null),[l,T]=r(!1),w=ue(),C=Ue();A(()=>{d(!0),(async()=>{try{const R=await b.settings.getByKey.query({key:s.skipKey});String(R.value)==="true"||String(R.value)==="1"?c(!0):c(!1)}catch(R){console.error("Failed to fetch setting",R)}finally{d(!1)}})()},[s.skipKey]);const x=async()=>{if(_)return;m(!0);const N=!i;c(N);try{await b.settings.set.mutate({key:s.skipKey,value:N})}catch(R){console.error("Error saving setting:",R),c(!N)}finally{m(!1)}},L=async()=>{if(!a.isUpdating){if(a.value)try{let N;if(t==="anime"?N=(await b.continueWatching.adultCount.query()).count:t==="manga"?N=(await b.mangaProgress.adultCount.query()).count:t==="asmr"?N=(await b.asmrProgress.adultCount.query()).count:N=(await b.tvProgress.adultCount.query()).count,typeof N=="number"&&N>0){p(N);return}}catch(N){console.error("Failed to fetch adult count",N)}a.toggle()}},D=()=>{p(null),a.toggle()},O=async()=>{if(!l){T(!0);try{let N;t==="anime"?N=(await b.continueWatching.purgeAdult.mutate()).removed:t==="manga"?N=(await b.mangaProgress.purgeAdult.mutate()).removed:t==="asmr"?N=(await b.asmrProgress.purgeAdult.mutate()).removed:N=(await b.tvProgress.purgeAdult.mutate()).removed,ye.success(s.purgeDoneText(N??0));for(const R of s.invalidateKeys)w.invalidateQueries({queryKey:R});t==="anime"&&w.invalidateQueries(C.continueWatching.pathFilter()),t==="manga"&&w.invalidateQueries(C.mangaProgress.pathFilter()),t==="asmr"&&w.invalidateQueries(C.asmrProgress.pathFilter()),t==="tv"&&w.invalidateQueries(C.tvProgress.pathFilter())}catch(N){console.error("Failed to purge adult entries",N),ye.error("Failed to remove adult entries")}finally{T(!1),p(null)}a.toggle()}};return h?e("div",{children:"Loading settings..."}):e("div",{className:G.sectionCard,children:[e("h3",{children:s.heading}),e("p",{children:s.blurb}),e("div",{className:G.settingItem,children:e("div",{className:G.settingRow,children:[e("label",{htmlFor:"skip-confirmation-toggle",children:s.skipLabel}),e(H,{isChecked:i,onChange:x,id:"skip-confirmation-toggle",disabled:_})]})}),e("div",{className:G.settingItem,children:e("div",{className:G.settingRow,children:[e("label",{htmlFor:"ignore-adult-toggle",children:s.ignoreLabel}),e(H,{isChecked:a.value,onChange:L,id:"ignore-adult-toggle",disabled:a.isUpdating})]})}),e("div",{className:G.settingItem,children:e("div",{className:G.settingRow,children:[e("label",{htmlFor:"cw-watchlist-only-toggle",children:s.listOnlyLabel}),e(H,{isChecked:u.value,onChange:u.toggle,id:"cw-watchlist-only-toggle",disabled:u.isUpdating})]})}),f!==null&&e("div",{className:G.modalOverlay,onClick:()=>p(null),children:e("div",{className:G.modal,onClick:N=>N.stopPropagation(),children:[e("h4",{children:"Show adult entries?"}),e("p",{children:[f," adult ",f===1?"entry":"entries"," not in your"," ",s.listNoun," ",f===1?"is":"are"," currently hidden from"," ",s.continueNoun,". You can purge ",f===1?"it":"them"," from the database instead of showing ",f===1?"it":"them","."]}),e("div",{className:G.modalActions,children:[e("button",{type:"button",className:G.modalSecondary,onClick:D,disabled:l,children:"Show them"}),e("button",{type:"button",className:G.modalPrimary,onClick:O,disabled:l,children:l?"Purging...":`Purge ${f}`})]})]})})]})},Ut="_sectionCard_jkggs_1",Mt="_statsGrid_jkggs_26",Et="_statCard_jkggs_33",$t="_statLabel_jkggs_43",Gt="_statValue_jkggs_51",Ft="_statMeta_jkggs_57",Kt="_statusBanner_jkggs_63",Ht="_statusSuccess_jkggs_74",Bt="_statusUpdating_jkggs_80",zt="_statusError_jkggs_86",qt="_sha_jkggs_92",jt="_settingItem_jkggs_99",Wt="_settingRow_jkggs_104",Vt="_settingTitle_jkggs_111",Yt="_settingSubtitle_jkggs_117",Jt="_actionsRow_jkggs_124",P={sectionCard:Ut,statsGrid:Mt,statCard:Et,statLabel:$t,statValue:Gt,statMeta:Ft,statusBanner:Kt,statusSuccess:Ht,statusUpdating:Bt,statusError:zt,sha:qt,settingItem:jt,settingRow:Wt,settingTitle:Vt,settingSubtitle:Yt,actionsRow:Jt},Qt=()=>{const[t,s]=r(null),[i,c]=r(!0),[h,d]=r(!1),[_,m]=r(!1),a=V(null),u=async()=>{try{const w=await b.settings.offlineDbInfo.query();return s(w),w}catch(w){console.error("Failed to fetch offline DB info:",w)}finally{c(!1)}return null};A(()=>(u(),()=>{a.current&&window.clearInterval(a.current)}),[]),A(()=>{t?.isRefreshing?a.current||(a.current=window.setInterval(async()=>{const w=await u();w&&!w.isRefreshing&&a.current&&(window.clearInterval(a.current),a.current=null)},2e3)):a.current&&(window.clearInterval(a.current),a.current=null)},[t?.isRefreshing]);const f=async()=>{if(!t||h)return;const w=!t.autoUpdateEnabled;d(!0),s({...t,autoUpdateEnabled:w});try{await b.settings.setOfflineDbAutoUpdate.mutate({enabled:w})}catch(C){console.error("Failed to update auto update setting:",C),s({...t,autoUpdateEnabled:!w})}finally{d(!1)}},p=async()=>{if(!(t?.isRefreshing||_)){m(!0);try{await b.settings.triggerOfflineDbUpdate.mutate(),s(w=>w?{...w,isRefreshing:!0,lastStatus:"updating",lastMessage:"Downloading database..."}:null)}catch(w){console.error("Failed to trigger offline DB update:",w)}finally{m(!1)}}},l=w=>{if(!w)return"Never";try{return new Date(w).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"})}catch{return w}},T=t?.isRefreshing||_;return e("div",{className:P.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:i?"—":(t?.totalMalMapped??0).toLocaleString()})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Release"}),e("span",{className:P.statMeta,children:i?"—":t?.releaseTag??"Never"})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Last Checked"}),e("span",{className:P.statMeta,children:i?"—":l(t?.lastCheckedAt??null)})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Last Updated"}),e("span",{className:P.statMeta,children:i?"—":l(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:P.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(H,{id:"offline-db-auto-update-toggle",isChecked:t?t.autoUpdateEnabled:!0,onChange:f,disabled:i||h})]})}),e("div",{className:P.actionsRow,children:e(I,{onClick:p,disabled:i||T,children:T?"Updating Database...":"Update Offline Database Now"})})]})},Xt="_sectionCard_1g4qx_1",Zt="_dangerCard_1g4qx_26",ea="_status_1g4qx_34",ta="_warningText_1g4qx_40",aa="_ackLabel_1g4qx_44",ee={sectionCard:Xt,dangerCard:Zt,status:ea,warningText:ta,ackLabel:aa},na=()=>{const t=ue(),[s,i]=r(!1),[c,h]=r(!1),[d,_]=r(!1),[m,a]=r(""),u=()=>{h(!1),a(""),i(!0)},f=()=>{d||(i(!1),h(!1))},p=async()=>{if(!(!c||d)){_(!0),a("");try{const l=await fetch("/api/database/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({confirm:!0})}),T=await l.json();if(!l.ok)throw new Error(T.error||"Failed to clear database");const w=T.deleted,C=T.deletedManga,x=T.deletedTv,L=T.deletedAsmr,D=Object.values(w).reduce((M,v)=>M+(v||0),0)+Object.values(C??{}).reduce((M,v)=>M+(v||0),0)+Object.values(x??{}).reduce((M,v)=>M+(v||0),0)+Object.values(L??{}).reduce((M,v)=>M+(v||0),0),O=(C?.manga_library??0)+(C?.manga_progress??0),N=(x?.tv_library??0)+(x?.tv_progress??0),R=(L?.asmr_library??0)+(L?.asmr_progress??0);a(`Library cleared — ${w.watchlist??0} watchlist entries, ${O} manga rows, ${N} TV rows, ${R} ASMR rows and ${D} total rows removed.`),t.invalidateQueries({queryKey:["watchlist"]}),t.invalidateQueries({queryKey:["allContinueWatching"]}),t.invalidateQueries({queryKey:["manga-library"]}),t.invalidateQueries({queryKey:["manga-continue-reading"]}),t.invalidateQueries({queryKey:["tv-library"]}),t.invalidateQueries({queryKey:["tv-continue-watching"]}),t.invalidateQueries({queryKey:["asmr-library"]}),t.invalidateQueries({queryKey:["asmr-continue-listening"]}),i(!1)}catch(l){a(l.message)}finally{_(!1),h(!1)}}};return e("div",{className:`${ee.sectionCard} ${ee.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(I,{variant:"danger",onClick:u,children:"Clear Library Data"}),m&&e("p",{className:ee.status,children:m}),e(F,{isOpen:s,onClose:f,title:"Clear library data?",width:"sm",children:[e(F.Body,{children:[e("p",{className:ee.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:ee.ackLabel,children:[e("input",{type:"checkbox",checked:c,onChange:l=>h(l.target.checked),disabled:d}),e("span",{children:"I understand this permanently deletes my library"})]})]}),e(F.Actions,{children:[e(I,{variant:"secondary",onClick:f,disabled:d,children:"Cancel"}),e(I,{variant:"danger",onClick:p,disabled:!c||d,children:d?"Clearing...":"Yes, delete everything"})]})]})]})},sa=()=>{const[t,s]=r(""),[i,c]=r([]),[h,d]=r(null),[_,m]=r(!0),[a,u]=r({show:!1,message:"",type:"info"}),f=async()=>{try{m(!0);const T=await(await fetch("/api/auth/settings/rclone")).json();s(T.remote||""),c(T.availableRemotes||[]),d(T.activeRemote||null)}catch(l){console.error("Failed to fetch Rclone settings",l)}finally{m(!1)}};A(()=>{f()},[]);const p=async()=>{try{if((await fetch("/api/auth/settings/rclone",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({remote:t})})).ok)u({show:!0,message:"Rclone configuration saved successfully. You must restart the server for these changes to take effect.",type:"success"}),f();else throw new Error("Failed to save")}catch{u({show:!0,message:"Failed to save Rclone configuration.",type:"error"})}};return _?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:y.sectionCard,children:[e("h3",{className:y.title,children:"Rclone Cloud Sync"}),e("p",{className:y.signIn,children:"Configure which Rclone remote to use for database synchronization."}),h?e("div",{className:y.userInfo,children:e("p",{children:["Current Active Remote: ",e("strong",{children:h})]})}):e("p",{className:y.warning,style:{marginBottom:"1.5rem"},children:"Rclone sync is not currently active. Ensure rclone is installed and a remote is configured."}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Remote Name"}),e("div",{className:y.inputWrapper,children:e("select",{className:y.select,value:t,onChange:l=>s(l.target.value),children:[e("option",{value:"",children:"(Disabled / None)"}),i.map(l=>e("option",{value:l,children:l},l)),t&&!i.includes(t)&&e("option",{value:t,children:[t," (Manual)"]})]})}),e("p",{className:y.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:y.actions,children:e(I,{onClick:p,children:"Save Rclone Settings"})}),e(F,{isOpen:a.show,onClose:()=>u(l=>({...l,show:!1})),width:"sm",children:[e(F.Body,{children:e("p",{children:a.message})}),e(F.Actions,{children:e(I,{onClick:()=>u(l=>({...l,show:!1})),children:"OK"})})]})]})},ra=()=>{const[t,s]=r(null),[i,c]=r(!0),h=async()=>{try{const u=await(await fetch("/api/auth/settings/sync")).json();s(u)}catch(a){console.error("Failed to fetch sync settings",a)}finally{c(!1)}};A(()=>{h()},[]);const d=async a=>{const u=a.target.value;try{const f=await fetch("/api/auth/settings/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:u})});if(f.ok){const p=await f.json();s(l=>l?{...l,activeProvider:p.activeProvider}:null),await h(),oe.success(`Sync provider updated to ${u==="default"?"Default Order":u}`)}else oe.error("Failed to update sync provider")}catch{oe.error("Error updating sync provider")}};if(i||!t)return null;const _=[{value:"default",label:"Default (Priority Based)"}];t.authenticatedProviders.github&&_.push({value:"github",label:"GitHub"}),t.authenticatedProviders.google&&_.push({value:"google",label:"Google Drive"}),t.authenticatedProviders.rclone&&_.push({value:"rclone",label:"Rclone"}),_.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:g.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:g.settingRow,children:[e("label",{htmlFor:"sync-provider-select",children:"Selected Preference"}),e("select",{id:"sync-provider-select",value:t.activeProvider,onChange:d,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:_.map(a=>e("option",{value:a.value,children:a.label},a.value))})]})]})};function ia(){return"javascript:"+encodeURIComponent(`(function(){
1
+ import{d as r,A as V,h as A,u as e,q as ae,S as te,T as Le,p as xe,a as Pe,g as pe,_ as Ae}from"./vendor-core-DfaOB3Rn.js";import{d as Oe,t as b,B as I,M as F,j as ve,h as Ue,T as H,z as ye,F as oe,G as Me,H as Ee,u as $e,e as Ge,I as Fe,y as fe,A as Ke,J as He,K as Be,V as ze,L as qe,N as je,O as We}from"./index-CQWyVhME.js";import{u as ue}from"./vendor-query-BBT5_sHx.js";import{I as W}from"./vendor-icons-DrybRNxP.js";const ce={"title-preference-container":"_title-preference-container_sdqgs_1","toggle-button":"_toggle-button_sdqgs_21","toggle-label":"_toggle-label_sdqgs_51"},le=["name","nativeName","englishName"],de={name:"Default (Romaji)",nativeName:"Native",englishName:"English"},Ve=()=>{const{titlePreference:t,setTitlePreference:s,loading:i}=Oe(),[c,h]=r(de[t]),[d,_]=r(!1),m=V(null);A(()=>{i||h(de[t])},[t,i]);const a=async()=>{if(d)return;_(!0);const f=(le.indexOf(t)+1)%le.length,p=le[f],l=de[p];m.current&&(m.current.style.transform="translateX(-100%)",m.current.style.opacity="0"),setTimeout(async()=>{h(l),s(p),m.current&&(m.current.style.transition="none",m.current.style.transform="translateX(100%)",m.current.style.opacity="0",m.current.offsetWidth,m.current.style.transition="transform 0.3s ease-out, opacity 0.3s ease-out",m.current.style.transform="translateX(0)",m.current.style.opacity="1");try{await b.settings.set.mutate({key:"titlePreference",value:p})}catch(T){console.error("Error saving title preference:",T)}finally{_(!1)}},300)};return i?e("p",{children:"Loading title preference..."}):e("div",{className:ce["title-preference-container"],children:[e("h4",{children:"Anime Title Display Preference"}),e("button",{onClick:a,className:ce["toggle-button"],disabled:d,children:e("span",{ref:m,className:ce["toggle-label"],children:c})})]})},Ye="_settingsHeader_14a5d_1",Je="_pageTitle_14a5d_6",Qe="_pageSubtitle_14a5d_14",Xe="_settingsLayout_14a5d_20",Ze="_sidebar_14a5d_27",et="_sidebarIndicator_14a5d_35",tt="_sidebarItem_14a5d_50",at="_active_14a5d_72",nt="_mainContent_14a5d_80",st="_tabContent_14a5d_85",rt="_sectionCard_14a5d_103",it="_settingItem_14a5d_127",ot="_settingRow_14a5d_132",ct="_controls_14a5d_145",lt="_status_14a5d_151",g={settingsHeader:Ye,pageTitle:Je,pageSubtitle:Qe,settingsLayout:Xe,sidebar:Ze,sidebarIndicator:et,sidebarItem:tt,active:at,mainContent:nt,tabContent:st,sectionCard:rt,settingItem:it,settingRow:ot,controls:ct,status:lt},dt="_sectionCard_wt900_12",ut="_title_wt900_22",ht="_signIn_wt900_29",gt="_userInfo_wt900_36",mt="_warning_wt900_58",pt="_formGroup_wt900_65",yt="_label_wt900_69",ft="_inputWrapper_wt900_79",wt="_input_wt900_79",vt="_select_wt900_103",bt="_actions_wt900_140",_t="_hr_wt900_148",y={sectionCard:dt,title:ut,signIn:ht,userInfo:gt,warning:mt,formGroup:pt,label:yt,inputWrapper:ft,input:wt,select:vt,actions:bt,hr:_t},kt=()=>{const[t,s]=r(!0),[i,c]=r(!1),[h,d]=r(!1),[_,m]=r(null),[a,u]=r({status:"idle"}),[f,p]=r(!1),[l,T]=r(""),[w,C]=r(!1),x=V(null),[L,D]=r({show:!1,message:"",type:"info"}),O=()=>{x.current&&(window.clearInterval(x.current),x.current=null)},N=ae(S=>{d(S.authenticated),m(S.user||S.device.user||null),u(S.device),p(!!S.hasCustomClientId)},[]),R=ae(async()=>{const S=await b.auth.githubStatus.query();N(S)},[N]),M=async()=>{try{const S=await b.auth.githubPoll.query();u(S),S.status==="success"?(O(),await R(),D({show:!0,message:"GitHub authentication complete. Sync has been initialized.",type:"success"})):S.status==="error"&&(O(),D({show:!0,message:S.error||"GitHub authentication failed.",type:"error"}))}catch{O(),D({show:!0,message:"Failed to poll GitHub authentication status.",type:"error"})}},v=(S=5)=>{O(),x.current=window.setInterval(M,Math.max(S,5)*1e3)};A(()=>(R().catch(()=>{D({show:!0,message:"Failed to load GitHub sync status.",type:"error"})}).finally(()=>s(!1)),O),[R]);const k=async()=>{c(!0);try{const S=await b.auth.githubStart.mutate();u(S),v(S.verification?.interval)}catch(S){D({show:!0,message:S instanceof Error?S.message:"Failed to start GitHub authentication.",type:"error"})}finally{c(!1)}},U=async()=>{try{await b.auth.githubLogout.mutate(),d(!1),m(null),u({status:"idle"}),D({show:!0,message:"Signed out of GitHub sync.",type:"success"})}catch{D({show:!0,message:"Failed to sign out of GitHub.",type:"error"})}},E=async()=>{C(!0);try{await b.auth.saveGithubAuth.mutate({clientId:l}),T(""),await R(),D({show:!0,message:"Custom GitHub auth saved.",type:"success"})}catch{D({show:!0,message:"Failed to save override.",type:"error"})}finally{C(!1)}},z=async()=>{C(!0);try{await b.auth.saveGithubAuth.mutate({clientId:""}),T(""),await R(),D({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{D({show:!0,message:"Failed to clear override.",type:"error"})}finally{C(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:y.sectionCard,children:[e("h3",{className:y.title,children:"GitHub Cloud Sync"}),e("p",{className:y.signIn,children:"Sync local data through a private GitHub repository named dango-sync-data."}),h&&_?e("div",{className:y.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:_.name||_.login})]}),e(I,{variant:"danger",onClick:U,children:"Sign Out"})]}):e("div",{className:y.signIn,children:e(I,{onClick:k,disabled:i||a.status==="pending",children:i||a.status==="pending"?"Waiting for GitHub...":"Sign in with GitHub"})}),a.status==="pending"&&a.verification&&e(te,{children:[e("hr",{className:y.hr}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Verification URL"}),e("div",{className:y.inputWrapper,children:[e("input",{className:y.input,value:a.verification.verification_uri,readOnly:!0}),e(I,{onClick:()=>{const S=a.verification?.verification_uri;S&&/^https?:\/\//i.test(S)&&window.open(S,"_blank","noopener,noreferrer")},children:"Open"})]})]}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Device Code"}),e("input",{className:y.input,value:a.verification.user_code,readOnly:!0})]})]}),a.status==="error"&&e("p",{className:y.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 ",f?"(override active)":""]}),e("div",{className:y.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:y.label,children:"Client ID (optional)"}),e("input",{className:y.input,value:l,onChange:S=>T(S.currentTarget.value),placeholder:"Your GitHub OAuth app ID"})]}),e("div",{className:y.actions,children:[e(I,{onClick:E,disabled:w,children:"Save override"}),e(I,{variant:"secondary",onClick:z,disabled:w,children:"Use dango defaults"})]})]}),e(F,{isOpen:L.show,onClose:()=>D(S=>({...S,show:!1})),width:"sm",children:[e(F.Body,{children:e("p",{children:L.message})}),e(F.Actions,{children:e(I,{onClick:()=>D(S=>({...S,show:!1})),children:"OK"})})]})]})},St=()=>{const[t,s]=r(!0),[i,c]=r(null),[h,d]=r(!1),[_,m]=r(!1),[a,u]=r(""),[f,p]=r(""),[l,T]=r(""),[w,C]=r(!1),[x,L]=r({show:!1,message:"",type:"info"}),D=async()=>{try{const k=await b.auth.user.query();c(k?.email?k:null)}catch{c(null)}},O=async()=>{try{const[k,U]=await Promise.all([b.auth.configStatus.query(),b.auth.googleAuth.query()]);d(!!k.hasConfig),m(!!(U.hasCustomWorkerUrl||U.hasCustomClientId||U.hasClientSecret))}catch(k){console.error("Failed to fetch config status",k)}};A(()=>{(async()=>{s(!0),await Promise.all([D(),O()]);try{new URLSearchParams(window.location.search).get("google_auth")==="success"&&(await D(),window.history.replaceState(null,"",window.location.pathname))}catch{}s(!1)})();const U=E=>{E.origin===window.location.origin&&typeof E.data=="object"&&E.data!==null&&E.data.type==="GOOGLE_AUTH_SUCCESS"&&(c(E.data.user),window.location.reload())};return window.addEventListener("message",U),()=>window.removeEventListener("message",U)},[]);const N=async()=>{try{const k=await b.auth.googleLogin.mutate();if(k.authenticated){window.location.reload();return}if(k.url){if(typeof window.DangoBridge<"u"){window.location.href=k.url;return}const E=600,z=700,S=window.innerWidth/2-E/2,ne=window.innerHeight/2-z/2;window.open(k.url,"GoogleAuth",`width=${E},height=${z},top=${ne},left=${S}`)}else throw new Error("Auth URL not available")}catch{L({show:!0,message:"Authentication failed. Ensure server is configured correctly.",type:"error"})}},R=async()=>{try{await b.auth.logout.mutate(),c(null),L({show:!0,message:"Successfully signed out.",type:"success"}),window.location.reload()}catch(k){console.error("Sign out failed",k),L({show:!0,message:"Failed to sign out.",type:"error"})}},M=async()=>{C(!0);try{await b.auth.saveGoogleAuth.mutate({workerUrl:a,clientId:f,clientSecret:l}),u(""),p(""),T(""),await O(),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{C(!1)}},v=async()=>{C(!0);try{await b.auth.saveGoogleAuth.mutate({workerUrl:"",clientId:"",clientSecret:""}),u(""),p(""),T(""),await O(),L({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{L({show:!0,message:"Failed to clear override.",type:"error"})}finally{C(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:y.sectionCard,children:[e("h3",{className:y.title,children:"Google Drive Sync"}),i?e("div",{className:y.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:i.name})," (",i.email,")"]}),e(I,{variant:"danger",onClick:R,children:"Sign Out"})]}):e("div",{className:y.signIn,children:[e("p",{children:"Sign in with your Google account to enable synchronization features."}),e(I,{onClick:N,disabled:!h,children:"Sign in with Google"}),!h&&e("p",{className:y.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 ",_?"(override active)":""]}),e("div",{className:y.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:y.label,children:"Worker URL (optional)"}),e("input",{className:y.input,value:a,onChange:k=>u(k.currentTarget.value),placeholder:"https://your-worker.workers.dev"})]}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Client ID (optional)"}),e("input",{className:y.input,value:f,onChange:k=>p(k.currentTarget.value),placeholder:"Your Google OAuth client ID"})]}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Client Secret (optional)"}),e("input",{type:"password",className:y.input,value:l,onChange:k=>T(k.currentTarget.value),placeholder:"Your Google OAuth secret"})]}),e("div",{className:y.actions,children:[e(I,{onClick:M,disabled:w,children:"Save override"}),e(I,{variant:"secondary",onClick:v,disabled:w,children:"Use dango defaults"})]})]}),e(F,{isOpen:x.show,onClose:()=>L(k=>({...k,show:!1})),width:"sm",children:[e(F.Body,{children:e("p",{children:x.message})}),e(F.Actions,{children:e(I,{onClick:()=>L(k=>({...k,show:!1})),children:"OK"})})]})]})},Ct="_sectionCard_1pqo4_1",Nt="_settingItem_1pqo4_26",Tt="_settingRow_1pqo4_31",Rt="_modalOverlay_1pqo4_38",Dt="_modal_1pqo4_38",It="_modalActions_1pqo4_73",Lt="_modalSecondary_1pqo4_79",xt="_modalPrimary_1pqo4_89",G={sectionCard:Ct,settingItem:Nt,settingRow:Tt,modalOverlay:Rt,modal:Dt,modalActions:It,modalSecondary:Lt,modalPrimary:xt},Pt={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"]]}},At=(t,s)=>{if(t==null)return s;const i=String(t);return i==="true"||i==="1"?!0:i==="false"||i==="0"?!1:s},we=(t,s,i)=>{const[c,h]=r(s),[d,_]=r(!1),m=ue();return A(()=>{(async()=>{try{const f=await b.settings.getByKey.query({key:t});h(At(f.value,s))}catch(f){console.error("Failed to fetch setting",f)}})()},[t,s]),{value:c,setValue:h,isUpdating:d,toggle:async()=>{if(d)return;_(!0);const u=!c;h(u);try{await b.settings.set.mutate({key:t,value:u});for(const f of i)m.invalidateQueries({queryKey:f})}catch(f){console.error("Error saving setting:",f),h(!u)}finally{_(!1)}}}},Ot=()=>{const{contentType:t}=ve(),s=Pt[t],[i,c]=r(!1),[h,d]=r(!0),[_,m]=r(!1),a=we(s.ignoreKey,!0,s.invalidateKeys),u=we(s.listOnlyKey,!1,s.invalidateKeys),[f,p]=r(null),[l,T]=r(!1),w=ue(),C=Ue();A(()=>{d(!0),(async()=>{try{const R=await b.settings.getByKey.query({key:s.skipKey});String(R.value)==="true"||String(R.value)==="1"?c(!0):c(!1)}catch(R){console.error("Failed to fetch setting",R)}finally{d(!1)}})()},[s.skipKey]);const x=async()=>{if(_)return;m(!0);const N=!i;c(N);try{await b.settings.set.mutate({key:s.skipKey,value:N})}catch(R){console.error("Error saving setting:",R),c(!N)}finally{m(!1)}},L=async()=>{if(!a.isUpdating){if(a.value)try{let N;if(t==="anime"?N=(await b.continueWatching.adultCount.query()).count:t==="manga"?N=(await b.mangaProgress.adultCount.query()).count:t==="asmr"?N=(await b.asmrProgress.adultCount.query()).count:N=(await b.tvProgress.adultCount.query()).count,typeof N=="number"&&N>0){p(N);return}}catch(N){console.error("Failed to fetch adult count",N)}a.toggle()}},D=()=>{p(null),a.toggle()},O=async()=>{if(!l){T(!0);try{let N;t==="anime"?N=(await b.continueWatching.purgeAdult.mutate()).removed:t==="manga"?N=(await b.mangaProgress.purgeAdult.mutate()).removed:t==="asmr"?N=(await b.asmrProgress.purgeAdult.mutate()).removed:N=(await b.tvProgress.purgeAdult.mutate()).removed,ye.success(s.purgeDoneText(N??0));for(const R of s.invalidateKeys)w.invalidateQueries({queryKey:R});t==="anime"&&w.invalidateQueries(C.continueWatching.pathFilter()),t==="manga"&&w.invalidateQueries(C.mangaProgress.pathFilter()),t==="asmr"&&w.invalidateQueries(C.asmrProgress.pathFilter()),t==="tv"&&w.invalidateQueries(C.tvProgress.pathFilter())}catch(N){console.error("Failed to purge adult entries",N),ye.error("Failed to remove adult entries")}finally{T(!1),p(null)}a.toggle()}};return h?e("div",{children:"Loading settings..."}):e("div",{className:G.sectionCard,children:[e("h3",{children:s.heading}),e("p",{children:s.blurb}),e("div",{className:G.settingItem,children:e("div",{className:G.settingRow,children:[e("label",{htmlFor:"skip-confirmation-toggle",children:s.skipLabel}),e(H,{isChecked:i,onChange:x,id:"skip-confirmation-toggle",disabled:_})]})}),e("div",{className:G.settingItem,children:e("div",{className:G.settingRow,children:[e("label",{htmlFor:"ignore-adult-toggle",children:s.ignoreLabel}),e(H,{isChecked:a.value,onChange:L,id:"ignore-adult-toggle",disabled:a.isUpdating})]})}),e("div",{className:G.settingItem,children:e("div",{className:G.settingRow,children:[e("label",{htmlFor:"cw-watchlist-only-toggle",children:s.listOnlyLabel}),e(H,{isChecked:u.value,onChange:u.toggle,id:"cw-watchlist-only-toggle",disabled:u.isUpdating})]})}),f!==null&&e("div",{className:G.modalOverlay,onClick:()=>p(null),children:e("div",{className:G.modal,onClick:N=>N.stopPropagation(),children:[e("h4",{children:"Show adult entries?"}),e("p",{children:[f," adult ",f===1?"entry":"entries"," not in your"," ",s.listNoun," ",f===1?"is":"are"," currently hidden from"," ",s.continueNoun,". You can purge ",f===1?"it":"them"," from the database instead of showing ",f===1?"it":"them","."]}),e("div",{className:G.modalActions,children:[e("button",{type:"button",className:G.modalSecondary,onClick:D,disabled:l,children:"Show them"}),e("button",{type:"button",className:G.modalPrimary,onClick:O,disabled:l,children:l?"Purging...":`Purge ${f}`})]})]})})]})},Ut="_sectionCard_jkggs_1",Mt="_statsGrid_jkggs_26",Et="_statCard_jkggs_33",$t="_statLabel_jkggs_43",Gt="_statValue_jkggs_51",Ft="_statMeta_jkggs_57",Kt="_statusBanner_jkggs_63",Ht="_statusSuccess_jkggs_74",Bt="_statusUpdating_jkggs_80",zt="_statusError_jkggs_86",qt="_sha_jkggs_92",jt="_settingItem_jkggs_99",Wt="_settingRow_jkggs_104",Vt="_settingTitle_jkggs_111",Yt="_settingSubtitle_jkggs_117",Jt="_actionsRow_jkggs_124",P={sectionCard:Ut,statsGrid:Mt,statCard:Et,statLabel:$t,statValue:Gt,statMeta:Ft,statusBanner:Kt,statusSuccess:Ht,statusUpdating:Bt,statusError:zt,sha:qt,settingItem:jt,settingRow:Wt,settingTitle:Vt,settingSubtitle:Yt,actionsRow:Jt},Qt=()=>{const[t,s]=r(null),[i,c]=r(!0),[h,d]=r(!1),[_,m]=r(!1),a=V(null),u=async()=>{try{const w=await b.settings.offlineDbInfo.query();return s(w),w}catch(w){console.error("Failed to fetch offline DB info:",w)}finally{c(!1)}return null};A(()=>(u(),()=>{a.current&&window.clearInterval(a.current)}),[]),A(()=>{t?.isRefreshing?a.current||(a.current=window.setInterval(async()=>{const w=await u();w&&!w.isRefreshing&&a.current&&(window.clearInterval(a.current),a.current=null)},2e3)):a.current&&(window.clearInterval(a.current),a.current=null)},[t?.isRefreshing]);const f=async()=>{if(!t||h)return;const w=!t.autoUpdateEnabled;d(!0),s({...t,autoUpdateEnabled:w});try{await b.settings.setOfflineDbAutoUpdate.mutate({enabled:w})}catch(C){console.error("Failed to update auto update setting:",C),s({...t,autoUpdateEnabled:!w})}finally{d(!1)}},p=async()=>{if(!(t?.isRefreshing||_)){m(!0);try{await b.settings.triggerOfflineDbUpdate.mutate(),s(w=>w?{...w,isRefreshing:!0,lastStatus:"updating",lastMessage:"Downloading database..."}:null)}catch(w){console.error("Failed to trigger offline DB update:",w)}finally{m(!1)}}},l=w=>{if(!w)return"Never";try{return new Date(w).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"})}catch{return w}},T=t?.isRefreshing||_;return e("div",{className:P.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:i?"—":(t?.totalMalMapped??0).toLocaleString()})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Release"}),e("span",{className:P.statMeta,children:i?"—":t?.releaseTag??"Never"})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Last Checked"}),e("span",{className:P.statMeta,children:i?"—":l(t?.lastCheckedAt??null)})]}),e("div",{className:P.statCard,children:[e("span",{className:P.statLabel,children:"Last Updated"}),e("span",{className:P.statMeta,children:i?"—":l(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:P.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(H,{id:"offline-db-auto-update-toggle",isChecked:t?t.autoUpdateEnabled:!0,onChange:f,disabled:i||h})]})}),e("div",{className:P.actionsRow,children:e(I,{onClick:p,disabled:i||T,children:T?"Updating Database...":"Update Offline Database Now"})})]})},Xt="_sectionCard_1g4qx_1",Zt="_dangerCard_1g4qx_26",ea="_status_1g4qx_34",ta="_warningText_1g4qx_40",aa="_ackLabel_1g4qx_44",ee={sectionCard:Xt,dangerCard:Zt,status:ea,warningText:ta,ackLabel:aa},na=()=>{const t=ue(),[s,i]=r(!1),[c,h]=r(!1),[d,_]=r(!1),[m,a]=r(""),u=()=>{h(!1),a(""),i(!0)},f=()=>{d||(i(!1),h(!1))},p=async()=>{if(!(!c||d)){_(!0),a("");try{const l=await fetch("/api/database/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({confirm:!0})}),T=await l.json();if(!l.ok)throw new Error(T.error||"Failed to clear database");const w=T.deleted,C=T.deletedManga,x=T.deletedTv,L=T.deletedAsmr,D=Object.values(w).reduce((M,v)=>M+(v||0),0)+Object.values(C??{}).reduce((M,v)=>M+(v||0),0)+Object.values(x??{}).reduce((M,v)=>M+(v||0),0)+Object.values(L??{}).reduce((M,v)=>M+(v||0),0),O=(C?.manga_library??0)+(C?.manga_progress??0),N=(x?.tv_library??0)+(x?.tv_progress??0),R=(L?.asmr_library??0)+(L?.asmr_progress??0);a(`Library cleared — ${w.watchlist??0} watchlist entries, ${O} manga rows, ${N} TV rows, ${R} ASMR rows and ${D} total rows removed.`),t.invalidateQueries({queryKey:["watchlist"]}),t.invalidateQueries({queryKey:["allContinueWatching"]}),t.invalidateQueries({queryKey:["manga-library"]}),t.invalidateQueries({queryKey:["manga-continue-reading"]}),t.invalidateQueries({queryKey:["tv-library"]}),t.invalidateQueries({queryKey:["tv-continue-watching"]}),t.invalidateQueries({queryKey:["asmr-library"]}),t.invalidateQueries({queryKey:["asmr-continue-listening"]}),i(!1)}catch(l){a(l.message)}finally{_(!1),h(!1)}}};return e("div",{className:`${ee.sectionCard} ${ee.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(I,{variant:"danger",onClick:u,children:"Clear Library Data"}),m&&e("p",{className:ee.status,children:m}),e(F,{isOpen:s,onClose:f,title:"Clear library data?",width:"sm",children:[e(F.Body,{children:[e("p",{className:ee.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:ee.ackLabel,children:[e("input",{type:"checkbox",checked:c,onChange:l=>h(l.target.checked),disabled:d}),e("span",{children:"I understand this permanently deletes my library"})]})]}),e(F.Actions,{children:[e(I,{variant:"secondary",onClick:f,disabled:d,children:"Cancel"}),e(I,{variant:"danger",onClick:p,disabled:!c||d,children:d?"Clearing...":"Yes, delete everything"})]})]})]})},sa=()=>{const[t,s]=r(""),[i,c]=r([]),[h,d]=r(null),[_,m]=r(!0),[a,u]=r({show:!1,message:"",type:"info"}),f=async()=>{try{m(!0);const T=await(await fetch("/api/auth/settings/rclone")).json();s(T.remote||""),c(T.availableRemotes||[]),d(T.activeRemote||null)}catch(l){console.error("Failed to fetch Rclone settings",l)}finally{m(!1)}};A(()=>{f()},[]);const p=async()=>{try{if((await fetch("/api/auth/settings/rclone",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({remote:t})})).ok)u({show:!0,message:"Rclone configuration saved successfully. You must restart the server for these changes to take effect.",type:"success"}),f();else throw new Error("Failed to save")}catch{u({show:!0,message:"Failed to save Rclone configuration.",type:"error"})}};return _?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:y.sectionCard,children:[e("h3",{className:y.title,children:"Rclone Cloud Sync"}),e("p",{className:y.signIn,children:"Configure which Rclone remote to use for database synchronization."}),h?e("div",{className:y.userInfo,children:e("p",{children:["Current Active Remote: ",e("strong",{children:h})]})}):e("p",{className:y.warning,style:{marginBottom:"1.5rem"},children:"Rclone sync is not currently active. Ensure rclone is installed and a remote is configured."}),e("div",{className:y.formGroup,children:[e("label",{className:y.label,children:"Remote Name"}),e("div",{className:y.inputWrapper,children:e("select",{className:y.select,value:t,onChange:l=>s(l.target.value),children:[e("option",{value:"",children:"(Disabled / None)"}),i.map(l=>e("option",{value:l,children:l},l)),t&&!i.includes(t)&&e("option",{value:t,children:[t," (Manual)"]})]})}),e("p",{className:y.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:y.actions,children:e(I,{onClick:p,children:"Save Rclone Settings"})}),e(F,{isOpen:a.show,onClose:()=>u(l=>({...l,show:!1})),width:"sm",children:[e(F.Body,{children:e("p",{children:a.message})}),e(F.Actions,{children:e(I,{onClick:()=>u(l=>({...l,show:!1})),children:"OK"})})]})]})},ra=()=>{const[t,s]=r(null),[i,c]=r(!0),h=async()=>{try{const u=await(await fetch("/api/auth/settings/sync")).json();s(u)}catch(a){console.error("Failed to fetch sync settings",a)}finally{c(!1)}};A(()=>{h()},[]);const d=async a=>{const u=a.target.value;try{const f=await fetch("/api/auth/settings/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:u})});if(f.ok){const p=await f.json();s(l=>l?{...l,activeProvider:p.activeProvider}:null),await h(),oe.success(`Sync provider updated to ${u==="default"?"Default Order":u}`)}else oe.error("Failed to update sync provider")}catch{oe.error("Error updating sync provider")}};if(i||!t)return null;const _=[{value:"default",label:"Default (Priority Based)"}];t.authenticatedProviders.github&&_.push({value:"github",label:"GitHub"}),t.authenticatedProviders.google&&_.push({value:"google",label:"Google Drive"}),t.authenticatedProviders.rclone&&_.push({value:"rclone",label:"Rclone"}),_.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:g.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:g.settingRow,children:[e("label",{htmlFor:"sync-provider-select",children:"Selected Preference"}),e("select",{id:"sync-provider-select",value:t.activeProvider,onChange:d,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:_.map(a=>e("option",{value:a.value,children:a.label},a.value))})]})]})};function ia(){return"javascript:"+encodeURIComponent(`(function(){
2
2
  if(!/(^|\\.)discord\\.com$/.test(location.hostname)){alert('Dango: use this bookmarklet while on discord.com');return}
3
3
  var t=null;
4
4
  try{
@@ -1 +1 @@
1
- import{d as _,A as v,h as E,T as R,u as e,g as A}from"./vendor-core-DfaOB3Rn.js";import{I as P}from"./vendor-icons-DrybRNxP.js";import{u as L}from"./index-gMxawd-E.js";const x="_pagination_zelsc_1",M="_pageBtn_zelsc_7",S="_pageInfo_zelsc_38",G="_pagePicker_zelsc_48",F="_dropdown_zelsc_52",K="_flipDown_zelsc_68",T="_jumpRow_zelsc_73",W="_jumpInput_zelsc_79",q="_jumpGo_zelsc_90",J="_optionList_zelsc_105",O="_optionBtn_zelsc_113",H="_current_zelsc_132",s={pagination:x,pageBtn:M,pageInfo:S,pagePicker:G,dropdown:F,flipDown:K,jumpRow:T,jumpInput:W,jumpGo:q,optionList:J,optionBtn:O,current:H},cn=({page:t,totalPages:d,canGoNext:m,onChange:p,isLoading:f=!1,variant:g="compact"})=>{const[l,u]=_(!1),[b,h]=_(""),[k,N]=_(0),[$,z]=_(!1),w=v(null),y=v(null),j=v(null);E(()=>{if(!l)return;const n=o=>{w.current&&!w.current.contains(o.target)&&u(!1)},r=o=>{o.key==="Escape"&&u(!1)};return document.addEventListener("pointerdown",n),document.addEventListener("keydown",r),()=>{document.removeEventListener("pointerdown",n),document.removeEventListener("keydown",r)}},[l]),E(()=>{if(!l)return;N(0),z(!1);const n=requestAnimationFrame(()=>{const r=j.current?.getBoundingClientRect(),o=y.current?.getBoundingClientRect();if(!r)return;let c=0;r.right>window.innerWidth-8?c=window.innerWidth-8-r.right:r.left<8&&(c=8-r.left),N(Math.round(c)),o&&o.top<r.height+24&&z(!0)});return()=>cancelAnimationFrame(n)},[l]);const i=d,C=R(()=>{if(i!==void 0){if(i<=100)return Array.from({length:i},(o,c)=>c+1);const r=new Set([1,i]);for(let o=t-10;o<=t+10;o++)o>=1&&o<=i&&r.add(o);return[...r].sort((o,c)=>o-c)}const n=m?t+1:t;return Array.from({length:n},(r,o)=>o+1)},[i,t,m]),B=n=>{const r=i!==void 0?Math.min(Math.max(1,n),i):Math.max(1,n);u(!1),h(""),r!==t&&p(r)},D=()=>{const n=parseInt(b,10);Number.isNaN(n)||B(n)},I=f||(i!==void 0?t>=i:!m);return e("div",{className:s.pagination,ref:w,children:[e("button",{className:s.pageBtn,onClick:()=>p(t-1),disabled:t<=1||f,"aria-label":"Previous page",children:[e(P,{name:"chevron-left",size:14}),g==="labeled"&&e("span",{children:"Previous"})]}),e("div",{className:s.pagePicker,ref:y,children:[e("button",{className:s.pageBtn,onClick:()=>{h(""),u(n=>!n)},disabled:f,"aria-label":"Jump to page","aria-expanded":l,children:e("span",{className:s.pageInfo,children:["Page ",e("strong",{children:t}),i!==void 0&&` of ${i}`]})}),l&&e("div",{ref:j,className:`${s.dropdown} ${$?s.flipDown:""}`,style:k!==0?{marginLeft:k}:void 0,children:[e("div",{className:s.jumpRow,children:[e("input",{className:s.jumpInput,type:"number",inputMode:"numeric",min:1,max:i,value:b,placeholder:"Page #",onChange:n=>h(n.currentTarget.value),onKeyDown:n=>{n.key==="Enter"&&D()}}),e("button",{className:s.jumpGo,onClick:D,children:"Go"})]}),e("div",{className:s.optionList,children:C.map(n=>e("button",{className:`${s.optionBtn} ${n===t?s.current:""}`,onClick:()=>B(n),disabled:n===t,children:n},n))})]})]}),e("button",{className:s.pageBtn,onClick:()=>p(t+1),disabled:I,"aria-label":"Next page",children:[g==="labeled"&&e("span",{children:"Next"}),e(P,{name:"chevron-right",size:14})]})]})},Q="_skeletonCard_1b0hr_1",U="_poster_1b0hr_11",V="_line_1b0hr_20",X="_info_1b0hr_38",Y="_short_1b0hr_54",Z="_horizontal_1b0hr_60",nn="_vertical_1b0hr_78",en="_lowEnd_1b0hr_97",a={skeletonCard:Q,poster:U,line:V,"skeleton-wave":"_skeleton-wave_1b0hr_1",info:X,short:Y,horizontal:Z,vertical:nn,lowEnd:en},tn=({layout:t="vertical"})=>{const{lowEndMode:d}=L();return e("div",{className:`${a.skeletonCard} ${a[t]} ${d?a.lowEnd:""}`,children:[e("div",{className:a.poster}),e("div",{className:a.info,children:[e("div",{className:a.line}),e("div",{className:`${a.line} ${a.short}`})]})]})},on=({count:t=14,layout:d="vertical"})=>e("div",{className:"grid-container",children:Array.from({length:t}).map((m,p)=>e(tn,{layout:d},p))}),ln=A.memo(on);export{tn as A,cn as P,ln as S};
1
+ import{d as _,A as v,h as E,T as R,u as e,g as A}from"./vendor-core-DfaOB3Rn.js";import{I as P}from"./vendor-icons-DrybRNxP.js";import{u as L}from"./index-CQWyVhME.js";const x="_pagination_zelsc_1",M="_pageBtn_zelsc_7",S="_pageInfo_zelsc_38",G="_pagePicker_zelsc_48",F="_dropdown_zelsc_52",K="_flipDown_zelsc_68",T="_jumpRow_zelsc_73",W="_jumpInput_zelsc_79",q="_jumpGo_zelsc_90",J="_optionList_zelsc_105",O="_optionBtn_zelsc_113",H="_current_zelsc_132",s={pagination:x,pageBtn:M,pageInfo:S,pagePicker:G,dropdown:F,flipDown:K,jumpRow:T,jumpInput:W,jumpGo:q,optionList:J,optionBtn:O,current:H},cn=({page:t,totalPages:d,canGoNext:m,onChange:p,isLoading:f=!1,variant:g="compact"})=>{const[l,u]=_(!1),[b,h]=_(""),[k,N]=_(0),[$,z]=_(!1),w=v(null),y=v(null),j=v(null);E(()=>{if(!l)return;const n=o=>{w.current&&!w.current.contains(o.target)&&u(!1)},r=o=>{o.key==="Escape"&&u(!1)};return document.addEventListener("pointerdown",n),document.addEventListener("keydown",r),()=>{document.removeEventListener("pointerdown",n),document.removeEventListener("keydown",r)}},[l]),E(()=>{if(!l)return;N(0),z(!1);const n=requestAnimationFrame(()=>{const r=j.current?.getBoundingClientRect(),o=y.current?.getBoundingClientRect();if(!r)return;let c=0;r.right>window.innerWidth-8?c=window.innerWidth-8-r.right:r.left<8&&(c=8-r.left),N(Math.round(c)),o&&o.top<r.height+24&&z(!0)});return()=>cancelAnimationFrame(n)},[l]);const i=d,C=R(()=>{if(i!==void 0){if(i<=100)return Array.from({length:i},(o,c)=>c+1);const r=new Set([1,i]);for(let o=t-10;o<=t+10;o++)o>=1&&o<=i&&r.add(o);return[...r].sort((o,c)=>o-c)}const n=m?t+1:t;return Array.from({length:n},(r,o)=>o+1)},[i,t,m]),B=n=>{const r=i!==void 0?Math.min(Math.max(1,n),i):Math.max(1,n);u(!1),h(""),r!==t&&p(r)},D=()=>{const n=parseInt(b,10);Number.isNaN(n)||B(n)},I=f||(i!==void 0?t>=i:!m);return e("div",{className:s.pagination,ref:w,children:[e("button",{className:s.pageBtn,onClick:()=>p(t-1),disabled:t<=1||f,"aria-label":"Previous page",children:[e(P,{name:"chevron-left",size:14}),g==="labeled"&&e("span",{children:"Previous"})]}),e("div",{className:s.pagePicker,ref:y,children:[e("button",{className:s.pageBtn,onClick:()=>{h(""),u(n=>!n)},disabled:f,"aria-label":"Jump to page","aria-expanded":l,children:e("span",{className:s.pageInfo,children:["Page ",e("strong",{children:t}),i!==void 0&&` of ${i}`]})}),l&&e("div",{ref:j,className:`${s.dropdown} ${$?s.flipDown:""}`,style:k!==0?{marginLeft:k}:void 0,children:[e("div",{className:s.jumpRow,children:[e("input",{className:s.jumpInput,type:"number",inputMode:"numeric",min:1,max:i,value:b,placeholder:"Page #",onChange:n=>h(n.currentTarget.value),onKeyDown:n=>{n.key==="Enter"&&D()}}),e("button",{className:s.jumpGo,onClick:D,children:"Go"})]}),e("div",{className:s.optionList,children:C.map(n=>e("button",{className:`${s.optionBtn} ${n===t?s.current:""}`,onClick:()=>B(n),disabled:n===t,children:n},n))})]})]}),e("button",{className:s.pageBtn,onClick:()=>p(t+1),disabled:I,"aria-label":"Next page",children:[g==="labeled"&&e("span",{children:"Next"}),e(P,{name:"chevron-right",size:14})]})]})},Q="_skeletonCard_1b0hr_1",U="_poster_1b0hr_11",V="_line_1b0hr_20",X="_info_1b0hr_38",Y="_short_1b0hr_54",Z="_horizontal_1b0hr_60",nn="_vertical_1b0hr_78",en="_lowEnd_1b0hr_97",a={skeletonCard:Q,poster:U,line:V,"skeleton-wave":"_skeleton-wave_1b0hr_1",info:X,short:Y,horizontal:Z,vertical:nn,lowEnd:en},tn=({layout:t="vertical"})=>{const{lowEndMode:d}=L();return e("div",{className:`${a.skeletonCard} ${a[t]} ${d?a.lowEnd:""}`,children:[e("div",{className:a.poster}),e("div",{className:a.info,children:[e("div",{className:a.line}),e("div",{className:`${a.line} ${a.short}`})]})]})},on=({count:t=14,layout:d="vertical"})=>e("div",{className:"grid-container",children:Array.from({length:t}).map((m,p)=>e(tn,{layout:d},p))}),ln=A.memo(on);export{tn as A,cn as P,ln as S};
@@ -1,2 +1,2 @@
1
- import{d as t,h as Re,g as Be,A as De,q as $e,u as e,S as d}from"./vendor-core-DfaOB3Rn.js";import{u as qe,b as Fe,a as I}from"./vendor-query-BBT5_sHx.js";import{z as i,t as h,a0 as nn,j as an,B as le}from"./index-gMxawd-E.js";import{I as l}from"./vendor-icons-DrybRNxP.js";function tn(){const K=qe(),[Y,k]=t(!1);return Re(()=>{const s=new URLSearchParams(window.location.search),b=s.get("anilist");if(b){const m=s.get("user"),_=s.get("reason");window.history.replaceState(null,"",window.location.pathname),b==="success"?(i.success(m?`Connected to AniList as ${decodeURIComponent(m)}`:"Connected to AniList"),K.invalidateQueries({queryKey:["trackerStatus"]})):i.error(_?decodeURIComponent(_):"AniList authentication failed");return}const j=new URLSearchParams(window.location.hash.substring(1)),y=j.get("access_token"),x=s.get("code");if(!y&&!x){const m=j.get("error");m&&(i.error(`AniList error: ${m}`),window.history.replaceState(null,"",window.location.pathname));return}const g=window.location.origin+window.location.pathname;window.history.replaceState(null,"",window.location.pathname),k(!0),i("Connecting to AniList..."),h.tracker.anilistAuth.mutate(y?{token:y}:{code:x,redirectUri:g}).then(async m=>{const _=m.user;i.success(`Connected to AniList as ${_?.name??"AniList user"}`),K.invalidateQueries({queryKey:["trackerStatus"]})}).catch(m=>{i.error(m instanceof Error?m.message:"Failed to authenticate with AniList")}).finally(()=>{k(!1)})},[K]),Y}const sn="_header_j1lbh_1",rn="_fadeIn_j1lbh_1",ln="_pageTitle_j1lbh_6",on="_pageSubtitle_j1lbh_14",cn="_importCard_j1lbh_20",dn="_slideUpIn_j1lbh_1",mn="_cardHeader_j1lbh_37",pn="_uploadArea_j1lbh_55",hn="_fileInputWrapper_j1lbh_59",un="_fileInput_j1lbh_59",gn="_fileDisplay_j1lbh_87",yn="_fileIcon_j1lbh_95",bn="_fileName_j1lbh_100",_n="_browseButton_j1lbh_109",fn="_optionsArea_j1lbh_120",Nn="_checkboxLabel_j1lbh_128",kn="_checkbox_j1lbh_128",wn="_checkboxCustom_j1lbh_141",vn="_optionText_j1lbh_169",In="_optionTitle_j1lbh_175",xn="_optionDesc_j1lbh_181",Mn="_actions_j1lbh_187",Cn="_importBtn_j1lbh_195",Ln="_cancelBtn_j1lbh_201",Sn="_statusMessage_j1lbh_215",Tn="_success_j1lbh_225",An="_error_j1lbh_231",jn="_progressSection_j1lbh_237",Pn="_progressBar_j1lbh_242",En="_progressFill_j1lbh_250",Bn="_progressInfo_j1lbh_257",Dn="_progressCount_j1lbh_264",$n="_progressTitle_j1lbh_271",Fn="_sourceBadge_j1lbh_289",Un="_anilist_j1lbh_301",Rn="_kitsu_j1lbh_307",qn="_offline_j1lbh_313",Kn="_skipped_j1lbh_319",On="_cardTitleRow_j1lbh_324",Qn="_anilistIcon_j1lbh_334",Gn="_malIcon_j1lbh_340",Hn="_badgeOnline_j1lbh_346",Wn="_badgeOffline_j1lbh_358",zn="_connectedProfile_j1lbh_370",Xn="_avatar_j1lbh_379",Jn="_connectedInfo_j1lbh_386",Yn="_connectedName_j1lbh_394",Vn="_connectedHint_j1lbh_400",Zn="_loginPrompt_j1lbh_405",ea="_loginSection_j1lbh_413",na="_fieldLabel_j1lbh_419",aa="_helpText_j1lbh_438",ta="_loginText_j1lbh_455",sa="_primaryBtn_j1lbh_464",ia="_secondaryBtn_j1lbh_465",ra="_syncBtn_j1lbh_466",la="_divider_j1lbh_518",oa="_actionSection_j1lbh_524",ca="_inputGroup_j1lbh_538",da="_input_j1lbh_538",ma="_syncSummary_j1lbh_559",pa="_syncErrors_j1lbh_565",ha="_spin_j1lbh_569",ua="_radioGroup_j1lbh_598",ga="_radioLabel_j1lbh_604",ya="_syncHint_j1lbh_642",ba="_importLoading_j1lbh_649",n={header:sn,fadeIn:rn,pageTitle:ln,pageSubtitle:on,importCard:cn,slideUpIn:dn,cardHeader:mn,uploadArea:pn,fileInputWrapper:hn,fileInput:un,fileDisplay:gn,fileIcon:yn,fileName:bn,browseButton:_n,optionsArea:fn,checkboxLabel:Nn,checkbox:kn,checkboxCustom:wn,optionText:vn,optionTitle:In,optionDesc:xn,actions:Mn,importBtn:Cn,cancelBtn:Ln,statusMessage:Sn,success:Tn,error:An,progressSection:jn,progressBar:Pn,progressFill:En,progressInfo:Bn,progressCount:Dn,progressTitle:$n,sourceBadge:Fn,anilist:Un,kitsu:Rn,offline:qn,skipped:Kn,cardTitleRow:On,anilistIcon:Qn,malIcon:Gn,badgeOnline:Hn,badgeOffline:Wn,connectedProfile:zn,avatar:Xn,connectedInfo:Jn,connectedName:Yn,connectedHint:Vn,loginPrompt:Zn,loginSection:ea,fieldLabel:na,helpText:aa,loginText:ta,primaryBtn:sa,secondaryBtn:ia,syncBtn:ra,divider:la,actionSection:oa,inputGroup:ca,input:da,syncSummary:ma,syncErrors:pa,spin:ha,radioGroup:ua,radioLabel:ga,syncHint:ya,importLoading:ba},oe="tracker_anilist_client_id",Ue="49887".trim(),wa=()=>{const{setIsOpen:K}=nn(),{contentType:Y}=an(),k=Y==="manga",s=qe();Be.useEffect(()=>{document.title="Trackers - dango"},[]);const[b,j]=t(""),[y,x]=t("username"),[g,m]=t(null),[_,ce]=t(""),[M,de]=t(!1),Ke=tn(),{data:me,isLoading:pe}=Fe({queryKey:["trackerStatus"],queryFn:async()=>await h.tracker.status.query()}),{data:C}=Fe({queryKey:["anilistClientId"],queryFn:async()=>(await h.settings.getByKey.query({key:oe})).value||""}),he=De(!1);Be.useEffect(()=>{he.current||C!==void 0&&(C&&ce(C),he.current=!0)},[C]);const w=me?.anilist?.connected??!1;Re(()=>{w&&x("sync")},[w]);const O=me?.anilist?.user??null,V=!!Ue,Oe=(C||"").trim(),Qe=async()=>{const a=_.trim(),r=a||Ue;if(!r){i.error("Enter your AniList client ID first");return}const N=async(A,se)=>{await h.settings.set.mutate({key:A,value:se})};try{a?a!==C&&await N(oe,a):V&&Oe&&await N(oe,""),s.invalidateQueries({queryKey:["anilistClientId"]})}catch(A){i.error(A.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(r)}&response_type=token&state=${U}`},ue=I({mutationFn:async()=>h.tracker.anilistDisconnect.mutate(),onSuccess:()=>{s.invalidateQueries({queryKey:["trackerStatus"]}),i.success("Disconnected from AniList")},onError:a=>i.error(a.message)}),Q=I({mutationFn:async()=>(await h.tracker.sync.mutate({provider:"anilist"})).summary,onSuccess:a=>{s.invalidateQueries({queryKey:["watchlist"]}),s.invalidateQueries({queryKey:["allContinueWatching"]}),m(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)}),[P,ge]=t(""),[G,ye]=t("sync"),[Z,be]=t("two-way"),[c,Ge]=t(null),H=I({mutationFn:async()=>(await h.tracker.mangaSync.mutate({direction:Z})).summary,onSuccess:a=>{s.invalidateQueries({queryKey:["manga-library"]}),s.invalidateQueries({queryKey:["manga-continue-reading"]}),Ge(a);const r=(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}${r}`,{duration:6e3})},onError:a=>i.error(a.message)}),L=I({mutationFn:async()=>{if(!P.trim())throw new Error("Please enter a username");return(await h.tracker.mangaImport.mutate({username:P.trim(),erase:M})).count},onSuccess:a=>{s.invalidateQueries({queryKey:["manga-library"]}),s.invalidateQueries({queryKey:["manga-continue-reading"]}),i.success(`Imported ${a} manga entries from AniList`),ge("")},onError:a=>i.error(a.message)}),[E,_e]=t(""),[W,fe]=t("username"),[ee,Ne]=t(null),[z,ke]=t(!1),[we,ne]=t(""),[ve,He]=t(""),f=I({mutationFn:async()=>{if(!E.trim())throw new Error("Please enter a MAL username");const a=await h.tracker.mangaMalImport.mutate({username:E.trim(),erase:M});return{imported:a.imported??0,skipped:a.skipped??0}},onSuccess:({imported:a,skipped:r})=>{s.invalidateQueries({queryKey:["manga-library"]}),s.invalidateQueries({queryKey:["manga-continue-reading"]}),i.success(`Imported ${a} manga entries from MAL${r>0?`, skipped ${r}`:""}`),_e("")},onError:a=>i.error(a.message)}),We=$e(async()=>{const a=document.getElementById("malMangaFile");if(!a.files||a.files.length===0){ne("Please select a file first.");return}ke(!0),ne(""),Ne(null);try{const r=new FormData;r.append("xmlfile",a.files[0]),r.append("erase",String(M));const N=await fetch("/api/import/mal-xml-manga",{method:"POST",body:r}),o=await N.json().catch(()=>({}));if(!N.ok)throw new Error(o.error||"Import failed");Ne({imported:o.imported??0,skipped:o.skipped??0}),s.invalidateQueries({queryKey:["manga-library"]}),s.invalidateQueries({queryKey:["manga-continue-reading"]})}catch(r){ne(r.message)}finally{ke(!1)}},[M,s]),S=I({mutationFn:async()=>{if(!b.trim())throw new Error("Please enter a username");return(await h.tracker.anilistImport.mutate({username:b.trim(),erase:v})).count},onSuccess:a=>{s.invalidateQueries({queryKey:["watchlist"]}),s.invalidateQueries({queryKey:["allContinueWatching"]}),i.success(`Imported ${a} anime entries from AniList`),j("")},onError:a=>i.error(a.message)}),[B,Ie]=t(""),u=I({mutationFn:async a=>{if(!B.trim())throw new Error("Please enter a MAL username");return(await h.tracker.malImport.mutate({username:B.trim(),erase:a.erase,useOfflineDb:a.useOfflineDb,skipFallback:a.skipFallback})).count},onSuccess:a=>{s.invalidateQueries({queryKey:["watchlist"]}),s.invalidateQueries({queryKey:["allContinueWatching"]}),i.success(`Imported ${a} anime entries from MAL`),Ie("")},onError:a=>i.error(a.message)}),[v,xe]=t(!1),[D,ze]=t(!0),[$,Xe]=t(!1),[Me,Ce]=t(""),[T,Le]=t(!1),[p,Se]=t(null),[ae,Te]=t(null),[Ae,X]=t(""),te=De(null),Je=a=>{a.target.files&&a.target.files.length>0?Ce(a.target.files[0].name):Ce("")},Ye=$e(async()=>{const a=document.getElementById("malFile");if(!a.files||a.files.length===0){X("Please select a file first.");return}const r=a.files[0];Le(!0),Se(null),Te(null),X("");const N=new AbortController;te.current=N;try{const o=new FormData;o.append("xmlfile",r),o.append("erase",String(v)),o.append("useOfflineDb",String(D)),o.append("skipFallback",String($));const U=await fetch("/api/import/mal-xml",{method:"POST",body:o,signal:N.signal});if(!U.ok){const re=await U.text();let R="Failed to import";try{R=JSON.parse(re).error||R}catch{}throw new Error(R)}const A=U.body?.getReader();if(!A)throw new Error("No response stream");const se=new TextDecoder;let ie="",J="";for(;;){const{done:re,value:R}=await A.read();if(re)break;ie+=se.decode(R,{stream:!0});const Pe=ie.split(`
1
+ import{d as t,h as Re,g as Be,A as De,q as $e,u as e,S as d}from"./vendor-core-DfaOB3Rn.js";import{u as qe,b as Fe,a as I}from"./vendor-query-BBT5_sHx.js";import{z as i,t as h,a0 as nn,j as an,B as le}from"./index-CQWyVhME.js";import{I as l}from"./vendor-icons-DrybRNxP.js";function tn(){const K=qe(),[Y,k]=t(!1);return Re(()=>{const s=new URLSearchParams(window.location.search),b=s.get("anilist");if(b){const m=s.get("user"),_=s.get("reason");window.history.replaceState(null,"",window.location.pathname),b==="success"?(i.success(m?`Connected to AniList as ${decodeURIComponent(m)}`:"Connected to AniList"),K.invalidateQueries({queryKey:["trackerStatus"]})):i.error(_?decodeURIComponent(_):"AniList authentication failed");return}const j=new URLSearchParams(window.location.hash.substring(1)),y=j.get("access_token"),x=s.get("code");if(!y&&!x){const m=j.get("error");m&&(i.error(`AniList error: ${m}`),window.history.replaceState(null,"",window.location.pathname));return}const g=window.location.origin+window.location.pathname;window.history.replaceState(null,"",window.location.pathname),k(!0),i("Connecting to AniList..."),h.tracker.anilistAuth.mutate(y?{token:y}:{code:x,redirectUri:g}).then(async m=>{const _=m.user;i.success(`Connected to AniList as ${_?.name??"AniList user"}`),K.invalidateQueries({queryKey:["trackerStatus"]})}).catch(m=>{i.error(m instanceof Error?m.message:"Failed to authenticate with AniList")}).finally(()=>{k(!1)})},[K]),Y}const sn="_header_j1lbh_1",rn="_fadeIn_j1lbh_1",ln="_pageTitle_j1lbh_6",on="_pageSubtitle_j1lbh_14",cn="_importCard_j1lbh_20",dn="_slideUpIn_j1lbh_1",mn="_cardHeader_j1lbh_37",pn="_uploadArea_j1lbh_55",hn="_fileInputWrapper_j1lbh_59",un="_fileInput_j1lbh_59",gn="_fileDisplay_j1lbh_87",yn="_fileIcon_j1lbh_95",bn="_fileName_j1lbh_100",_n="_browseButton_j1lbh_109",fn="_optionsArea_j1lbh_120",Nn="_checkboxLabel_j1lbh_128",kn="_checkbox_j1lbh_128",wn="_checkboxCustom_j1lbh_141",vn="_optionText_j1lbh_169",In="_optionTitle_j1lbh_175",xn="_optionDesc_j1lbh_181",Mn="_actions_j1lbh_187",Cn="_importBtn_j1lbh_195",Ln="_cancelBtn_j1lbh_201",Sn="_statusMessage_j1lbh_215",Tn="_success_j1lbh_225",An="_error_j1lbh_231",jn="_progressSection_j1lbh_237",Pn="_progressBar_j1lbh_242",En="_progressFill_j1lbh_250",Bn="_progressInfo_j1lbh_257",Dn="_progressCount_j1lbh_264",$n="_progressTitle_j1lbh_271",Fn="_sourceBadge_j1lbh_289",Un="_anilist_j1lbh_301",Rn="_kitsu_j1lbh_307",qn="_offline_j1lbh_313",Kn="_skipped_j1lbh_319",On="_cardTitleRow_j1lbh_324",Qn="_anilistIcon_j1lbh_334",Gn="_malIcon_j1lbh_340",Hn="_badgeOnline_j1lbh_346",Wn="_badgeOffline_j1lbh_358",zn="_connectedProfile_j1lbh_370",Xn="_avatar_j1lbh_379",Jn="_connectedInfo_j1lbh_386",Yn="_connectedName_j1lbh_394",Vn="_connectedHint_j1lbh_400",Zn="_loginPrompt_j1lbh_405",ea="_loginSection_j1lbh_413",na="_fieldLabel_j1lbh_419",aa="_helpText_j1lbh_438",ta="_loginText_j1lbh_455",sa="_primaryBtn_j1lbh_464",ia="_secondaryBtn_j1lbh_465",ra="_syncBtn_j1lbh_466",la="_divider_j1lbh_518",oa="_actionSection_j1lbh_524",ca="_inputGroup_j1lbh_538",da="_input_j1lbh_538",ma="_syncSummary_j1lbh_559",pa="_syncErrors_j1lbh_565",ha="_spin_j1lbh_569",ua="_radioGroup_j1lbh_598",ga="_radioLabel_j1lbh_604",ya="_syncHint_j1lbh_642",ba="_importLoading_j1lbh_649",n={header:sn,fadeIn:rn,pageTitle:ln,pageSubtitle:on,importCard:cn,slideUpIn:dn,cardHeader:mn,uploadArea:pn,fileInputWrapper:hn,fileInput:un,fileDisplay:gn,fileIcon:yn,fileName:bn,browseButton:_n,optionsArea:fn,checkboxLabel:Nn,checkbox:kn,checkboxCustom:wn,optionText:vn,optionTitle:In,optionDesc:xn,actions:Mn,importBtn:Cn,cancelBtn:Ln,statusMessage:Sn,success:Tn,error:An,progressSection:jn,progressBar:Pn,progressFill:En,progressInfo:Bn,progressCount:Dn,progressTitle:$n,sourceBadge:Fn,anilist:Un,kitsu:Rn,offline:qn,skipped:Kn,cardTitleRow:On,anilistIcon:Qn,malIcon:Gn,badgeOnline:Hn,badgeOffline:Wn,connectedProfile:zn,avatar:Xn,connectedInfo:Jn,connectedName:Yn,connectedHint:Vn,loginPrompt:Zn,loginSection:ea,fieldLabel:na,helpText:aa,loginText:ta,primaryBtn:sa,secondaryBtn:ia,syncBtn:ra,divider:la,actionSection:oa,inputGroup:ca,input:da,syncSummary:ma,syncErrors:pa,spin:ha,radioGroup:ua,radioLabel:ga,syncHint:ya,importLoading:ba},oe="tracker_anilist_client_id",Ue="49887".trim(),wa=()=>{const{setIsOpen:K}=nn(),{contentType:Y}=an(),k=Y==="manga",s=qe();Be.useEffect(()=>{document.title="Trackers - dango"},[]);const[b,j]=t(""),[y,x]=t("username"),[g,m]=t(null),[_,ce]=t(""),[M,de]=t(!1),Ke=tn(),{data:me,isLoading:pe}=Fe({queryKey:["trackerStatus"],queryFn:async()=>await h.tracker.status.query()}),{data:C}=Fe({queryKey:["anilistClientId"],queryFn:async()=>(await h.settings.getByKey.query({key:oe})).value||""}),he=De(!1);Be.useEffect(()=>{he.current||C!==void 0&&(C&&ce(C),he.current=!0)},[C]);const w=me?.anilist?.connected??!1;Re(()=>{w&&x("sync")},[w]);const O=me?.anilist?.user??null,V=!!Ue,Oe=(C||"").trim(),Qe=async()=>{const a=_.trim(),r=a||Ue;if(!r){i.error("Enter your AniList client ID first");return}const N=async(A,se)=>{await h.settings.set.mutate({key:A,value:se})};try{a?a!==C&&await N(oe,a):V&&Oe&&await N(oe,""),s.invalidateQueries({queryKey:["anilistClientId"]})}catch(A){i.error(A.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(r)}&response_type=token&state=${U}`},ue=I({mutationFn:async()=>h.tracker.anilistDisconnect.mutate(),onSuccess:()=>{s.invalidateQueries({queryKey:["trackerStatus"]}),i.success("Disconnected from AniList")},onError:a=>i.error(a.message)}),Q=I({mutationFn:async()=>(await h.tracker.sync.mutate({provider:"anilist"})).summary,onSuccess:a=>{s.invalidateQueries({queryKey:["watchlist"]}),s.invalidateQueries({queryKey:["allContinueWatching"]}),m(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)}),[P,ge]=t(""),[G,ye]=t("sync"),[Z,be]=t("two-way"),[c,Ge]=t(null),H=I({mutationFn:async()=>(await h.tracker.mangaSync.mutate({direction:Z})).summary,onSuccess:a=>{s.invalidateQueries({queryKey:["manga-library"]}),s.invalidateQueries({queryKey:["manga-continue-reading"]}),Ge(a);const r=(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}${r}`,{duration:6e3})},onError:a=>i.error(a.message)}),L=I({mutationFn:async()=>{if(!P.trim())throw new Error("Please enter a username");return(await h.tracker.mangaImport.mutate({username:P.trim(),erase:M})).count},onSuccess:a=>{s.invalidateQueries({queryKey:["manga-library"]}),s.invalidateQueries({queryKey:["manga-continue-reading"]}),i.success(`Imported ${a} manga entries from AniList`),ge("")},onError:a=>i.error(a.message)}),[E,_e]=t(""),[W,fe]=t("username"),[ee,Ne]=t(null),[z,ke]=t(!1),[we,ne]=t(""),[ve,He]=t(""),f=I({mutationFn:async()=>{if(!E.trim())throw new Error("Please enter a MAL username");const a=await h.tracker.mangaMalImport.mutate({username:E.trim(),erase:M});return{imported:a.imported??0,skipped:a.skipped??0}},onSuccess:({imported:a,skipped:r})=>{s.invalidateQueries({queryKey:["manga-library"]}),s.invalidateQueries({queryKey:["manga-continue-reading"]}),i.success(`Imported ${a} manga entries from MAL${r>0?`, skipped ${r}`:""}`),_e("")},onError:a=>i.error(a.message)}),We=$e(async()=>{const a=document.getElementById("malMangaFile");if(!a.files||a.files.length===0){ne("Please select a file first.");return}ke(!0),ne(""),Ne(null);try{const r=new FormData;r.append("xmlfile",a.files[0]),r.append("erase",String(M));const N=await fetch("/api/import/mal-xml-manga",{method:"POST",body:r}),o=await N.json().catch(()=>({}));if(!N.ok)throw new Error(o.error||"Import failed");Ne({imported:o.imported??0,skipped:o.skipped??0}),s.invalidateQueries({queryKey:["manga-library"]}),s.invalidateQueries({queryKey:["manga-continue-reading"]})}catch(r){ne(r.message)}finally{ke(!1)}},[M,s]),S=I({mutationFn:async()=>{if(!b.trim())throw new Error("Please enter a username");return(await h.tracker.anilistImport.mutate({username:b.trim(),erase:v})).count},onSuccess:a=>{s.invalidateQueries({queryKey:["watchlist"]}),s.invalidateQueries({queryKey:["allContinueWatching"]}),i.success(`Imported ${a} anime entries from AniList`),j("")},onError:a=>i.error(a.message)}),[B,Ie]=t(""),u=I({mutationFn:async a=>{if(!B.trim())throw new Error("Please enter a MAL username");return(await h.tracker.malImport.mutate({username:B.trim(),erase:a.erase,useOfflineDb:a.useOfflineDb,skipFallback:a.skipFallback})).count},onSuccess:a=>{s.invalidateQueries({queryKey:["watchlist"]}),s.invalidateQueries({queryKey:["allContinueWatching"]}),i.success(`Imported ${a} anime entries from MAL`),Ie("")},onError:a=>i.error(a.message)}),[v,xe]=t(!1),[D,ze]=t(!0),[$,Xe]=t(!1),[Me,Ce]=t(""),[T,Le]=t(!1),[p,Se]=t(null),[ae,Te]=t(null),[Ae,X]=t(""),te=De(null),Je=a=>{a.target.files&&a.target.files.length>0?Ce(a.target.files[0].name):Ce("")},Ye=$e(async()=>{const a=document.getElementById("malFile");if(!a.files||a.files.length===0){X("Please select a file first.");return}const r=a.files[0];Le(!0),Se(null),Te(null),X("");const N=new AbortController;te.current=N;try{const o=new FormData;o.append("xmlfile",r),o.append("erase",String(v)),o.append("useOfflineDb",String(D)),o.append("skipFallback",String($));const U=await fetch("/api/import/mal-xml",{method:"POST",body:o,signal:N.signal});if(!U.ok){const re=await U.text();let R="Failed to import";try{R=JSON.parse(re).error||R}catch{}throw new Error(R)}const A=U.body?.getReader();if(!A)throw new Error("No response stream");const se=new TextDecoder;let ie="",J="";for(;;){const{done:re,value:R}=await A.read();if(re)break;ie+=se.decode(R,{stream:!0});const Pe=ie.split(`
2
2
  `);ie=Pe.pop()||"";for(const q of Pe)if(q.startsWith("event: "))J=q.slice(7).trim();else if(q.startsWith("data: ")){const en=q.slice(6);try{const Ee=JSON.parse(en);J==="progress"?Se(Ee):J==="complete"&&Te(Ee)}catch{}}else q===""&&(J="")}s.invalidateQueries({queryKey:["watchlist"]})}catch(o){o instanceof DOMException&&o.name==="AbortError"?X("Import cancelled."):X(o.message)}finally{Le(!1),te.current=null}},[v,D,$,s]),Ve=()=>{te.current?.abort(),h.settings.malImportCancel.mutate().catch(()=>{})},Ze=p?Math.round(p.current/p.total*100):0,[F,je]=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."}),!k&&e(d,{children:e("div",{className:n.importCard,children:[e("div",{className:n.cardHeader,children:e("div",{className:n.cardTitleRow,children:[e(l,{name:"anilist",className:n.anilistIcon}),e("h3",{children:"AniList"}),pe?null:w?e("span",{className:n.badgeOnline,children:"Connected"}):e("span",{className:n.badgeOffline,children:"Not connected"})]})}),w&&O?e("div",{className:n.connectedProfile,children:[O.avatar&&e("img",{src:O.avatar,alt:"Avatar",className:n.avatar,loading:"lazy",decoding:"async"}),e("div",{className:n.connectedInfo,children:[e("span",{className:n.connectedName,children:O.name}),e("span",{className:n.connectedHint,children:"2-way sync is ready"})]}),e("button",{className:n.secondaryBtn,onClick:()=>ue.mutate(),disabled:ue.isPending,children:[e(l,{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.",Ke&&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(l,{name:"external-link-alt",size:9})]})]}),e("div",{className:n.inputGroup,children:[e("input",{type:"text",placeholder:"Client ID",value:_,onChange:a=>ce(a.target.value),className:n.input}),e("button",{className:n.primaryBtn,onClick:Qe,disabled:!(_.trim()||V),children:[e(l,{name:"external-link-alt"})," Connect"]})]}),e("p",{className:n.helpText,children:V?e(d,{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.port==="5173"?`${window.location.protocol}//${window.location.hostname}:3000/api/tracker/anilist/callback`:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste only the ",e("strong",{children:"Client ID"})," above (leave empty to use Dango's)."]}):e(d,{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.port==="5173"?`${window.location.protocol}//${window.location.hostname}:3000/api/tracker/anilist/callback`:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste the ",e("strong",{children:"Client ID"})," above."]})})]}),w&&e(d,{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:y==="username",onChange:()=>x("username")}),e("span",{children:"Quick Import"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"anilistMode",value:"sync",checked:y==="sync",onChange:()=>x("sync")}),e("span",{children:"Two-way Sync"})]})]}),y==="username"?e("div",{className:n.inputGroup,children:e("input",{type:"text",placeholder:"Enter AniList username",value:b,onChange:a=>j(a.target.value),className:n.input,disabled:S.isPending,onKeyDown:a=>{a.key==="Enter"&&b.trim()&&S.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."}),y==="username"&&e("div",{className:n.optionsArea,children:e("label",{className:n.checkboxLabel,children:[e("input",{type:"checkbox",checked:v,onChange:a=>xe(a.target.checked),className:n.checkbox,disabled:S.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."})]})]})}),y==="username"?e("button",{className:n.syncBtn,onClick:()=>S.mutate(),disabled:!b.trim()||S.isPending,children:[e(l,{name:"download"}),S.isPending?"Importing...":"Start Import"]}):e(d,{children:[e("button",{className:n.syncBtn,onClick:()=>Q.mutate(),disabled:Q.isPending,children:[e(l,{name:"sync-alt",className:Q.isPending?n.spin:""}),Q.isPending?"Syncing...":"Start Sync"]}),g&&e("div",{className:n.syncSummary,children:["Pushed: ",g.pushed," · Pulled: ",g.pulled," · Merged:"," ",g.merged," · Unchanged: ",g.unchanged,g.errors.length>0&&e("span",{className:n.syncErrors,children:[" ","· ",g.errors.length," error",g.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."]})]})]})}),k&&e(d,{children:e("div",{className:n.importCard,children:[e("div",{className:n.cardHeader,children:e("div",{className:n.cardTitleRow,children:[e(l,{name:"anilist",className:n.anilistIcon}),e("h3",{children:"AniList Manga"}),pe?null:w?e("span",{className:n.badgeOnline,children:"Connected"}):e("span",{className:n.badgeOffline,children:"Not connected"})]})}),w?e(d,{children:[e("div",{className:n.radioGroup,children:[e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"mangaMode",value:"username",checked:G==="username",onChange:()=>ye("username")}),e("span",{children:"Quick Import"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"mangaMode",value:"sync",checked:G==="sync",onChange:()=>ye("sync")}),e("span",{children:"Two-way Sync"})]})]}),G==="username"?e(d,{children:[e("div",{className:n.inputGroup,children:e("input",{type:"text",placeholder:"Enter AniList username",value:P,onChange:a=>ge(a.target.value),className:n.input,disabled:L.isPending,onKeyDown:a=>{a.key==="Enter"&&P.trim()&&L.mutate()}})}),e("div",{className:n.optionsArea,children:e("label",{className:n.checkboxLabel,children:[e("input",{type:"checkbox",checked:M,onChange:a=>de(a.target.checked),className:n.checkbox,disabled:L.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(d,{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:Z==="two-way",onChange:()=>be("two-way")}),e("span",{children:"Two-way"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"mangaDirection",value:"pull-only",checked:Z==="pull-only",onChange:()=>be("pull-only")}),e("span",{children:"Pull only (never writes to AniList)"})]})]})]}),G==="username"?e("button",{className:n.syncBtn,onClick:()=>L.mutate(),disabled:!P.trim()||L.isPending,children:[e(l,{name:"download"}),L.isPending?"Importing...":"Start Import"]}):e(d,{children:[e("button",{className:n.syncBtn,onClick:()=>H.mutate(),disabled:H.isPending,children:[e(l,{name:"sync-alt",className:H.isPending?n.spin:""}),H.isPending?"Syncing...":"Start Manga Sync"]}),c&&e(d,{children:[e("div",{className:n.syncSummary,children:["Pushed: ",c.pushed," · Pulled: ",c.pulled," · Merged: ",c.merged," · Unchanged:"," ",c.unchanged,(c.skipped??0)>0&&e("span",{children:[" · Skipped: ",c.skipped]}),c.errors.length>0&&e("span",{className:n.syncErrors,children:[" ","· ",c.errors.length," error",c.errors.length>1?"s":""]})]}),(c.warnings?.length??0)>0&&e("div",{className:n.syncErrors,style:{marginTop:"8px"},children:[(c.warnings??[]).slice(0,5).map((a,r)=>e("div",{children:["⚠ ",a]},r)),(c.warnings?.length??0)>5&&e("div",{children:["+",(c.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."})]})}),!k&&e(d,{children:e("div",{className:n.importCard,children:[e("div",{className:n.cardHeader,children:e("div",{className:n.cardTitleRow,children:[e(l,{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:F==="username",onChange:()=>je("username")}),e("span",{children:"Username"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"malMode",value:"xml",checked:F==="xml",onChange:()=>je("xml")}),e("span",{children:"XML File"})]})]}),F==="username"?e(d,{children:[e("div",{className:n.inputGroup,children:e("input",{type:"text",placeholder:"Enter MAL username",value:B,onChange:a=>Ie(a.target.value),className:n.input,disabled:u.isPending,onKeyDown:a=>{a.key==="Enter"&&B.trim()&&u.mutate({erase:v,useOfflineDb:D,skipFallback:$})}})}),u.isPending&&e("div",{className:n.importLoading,children:[e(l,{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:Je,disabled:T}),e("div",{className:n.fileDisplay,children:[e(l,{name:"file-alt",className:n.fileIcon}),e("span",{className:n.fileName,children:Me||"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:v,onChange:a=>xe(a.target.checked),className:n.checkbox,disabled:T||u.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:D,onChange:a=>ze(a.target.checked),className:n.checkbox,disabled:T||u.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=>Xe(a.target.checked),className:n.checkbox,disabled:T||u.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."})]})]})]}),F==="username"?e("button",{className:n.syncBtn,onClick:()=>u.mutate({erase:v,useOfflineDb:D,skipFallback:$}),disabled:!B.trim()||u.isPending,children:[e(l,{name:"download"}),u.isPending?"Importing...":"Start Import"]}):e("div",{className:n.actions,children:T?e(le,{onClick:Ve,className:n.cancelBtn,children:"Cancel Import"}):e(le,{onClick:Ye,className:n.importBtn,disabled:!Me,children:[e(l,{name:"upload"})," Start Import"]})}),F==="username"&&u.isError&&e("div",{className:`${n.statusMessage} ${n.error}`,children:u.error.message}),T&&p&&e("div",{className:n.progressSection,children:[e("div",{className:n.progressBar,children:e("div",{className:n.progressFill,style:{width:`${Ze}%`}})}),e("div",{className:n.progressInfo,children:[e("span",{className:n.progressCount,children:[p.current," / ",p.total]}),e("span",{className:n.progressTitle,children:p.found?e(d,{children:[p.matchedTitle,e("span",{className:`${n.sourceBadge} ${n[p.source||"anilist"]}`,children:p.source==="kitsu"?"Kitsu":p.source==="offline"?"Offline DB":"AniList"})]}):e("span",{className:n.skipped,children:["Skipped: ",p.title]})})]})]}),ae&&e("div",{className:`${n.statusMessage} ${n.success}`,children:["Import complete! Imported: ",ae.imported,", Skipped: ",ae.skipped,"."]}),Ae&&e("div",{className:`${n.statusMessage} ${n.error}`,children:Ae})]})}),k&&e("div",{className:n.importCard,children:[e("div",{className:n.cardHeader,children:e("div",{className:n.cardTitleRow,children:[e(l,{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:W==="username",onChange:()=>fe("username")}),e("span",{children:"Username"})]}),e("label",{className:n.radioLabel,children:[e("input",{type:"radio",name:"malMangaMode",value:"xml",checked:W==="xml",onChange:()=>fe("xml")}),e("span",{children:"XML File"})]})]}),W==="username"?e("div",{className:n.inputGroup,children:e("input",{type:"text",placeholder:"Enter MAL username",value:E,onChange:a=>_e(a.target.value),className:n.input,disabled:f.isPending,onKeyDown:a=>{a.key==="Enter"&&E.trim()&&f.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=>He(a.target.files?.[0]?.name??""),disabled:z}),e("div",{className:n.fileDisplay,children:[e(l,{name:"file-alt",className:n.fileIcon}),e("span",{className:n.fileName,children:ve||"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:M,onChange:a=>de(a.target.checked),className:n.checkbox,disabled:f.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."})]})]})}),W==="username"?e("button",{className:n.syncBtn,onClick:()=>f.mutate(),disabled:!E.trim()||f.isPending,children:[e(l,{name:"download"}),f.isPending?"Importing...":"Start Import"]}):e("div",{className:n.actions,children:e(le,{onClick:We,className:n.importBtn,disabled:z||!ve,children:[e(l,{name:"upload"})," ",z?"Importing...":"Start Import"]})}),f.isError&&e("div",{className:`${n.statusMessage} ${n.error}`,children:f.error.message}),we&&e("div",{className:`${n.statusMessage} ${n.error}`,children:we}),ee&&e("div",{className:`${n.statusMessage} ${n.success}`,children:["Import complete! Imported: ",ee.imported,", Skipped:"," ",ee.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{wa as default};
@@ -0,0 +1,4 @@
1
+ import{d as S,A as w,h as y,u as t,S as we,o as $r,p as Dr,a as Or,T as Ne,q as _}from"./vendor-core-DfaOB3Rn.js";import{u as Fr}from"./vendor-query-BBT5_sHx.js";import{g as ln,e as Vr,t as vt,z as jr,W as Wr,M as Rn,B as De}from"./index-CQWyVhME.js";import{I as R}from"./vendor-icons-DrybRNxP.js";import{M as zr,z as dr,j as Fn,h as Hr,C as Ur,S as Kr,U as qr,a as Yr,p as Vn,u as Qr,b as Gr,c as Xr,g as Jr,d as Zr,f as es,l as ts,y as ns,i as $n,B as rs,D as ss,F as ir,s as Dn,k as as,m as os,n as is,r as ls,o as Ge,A as cs,q as ds,E as us,w as ms,P as hs,t as ve,x as ps,R as gs}from"./AvSyncCalibrator-CbzA-56T.js";import{S as fs,O as an,a as vs,A as bs,b as ys}from"./OptionListMenu-DSTuvk6i.js";import{u as _s}from"./useProviders-DYy7lHj6.js";import{d as Ss,g as Cs,h as ks,f as Ts,e as Es,j as xs,k as Ns}from"./useTvLibrary-ChI7tnUw.js";import{l as ws,c as Is}from"./hls-CSxWA5I-.js";import{u as Bs}from"./useIsMobile-Dvx1uJ82.js";import{S as As}from"./SynopsisText-B3Sa5pRv.js";const Ms="_fullscreenFlat_1xij1_1",Ps="_timeDisplay_1xij1_15",Ls="_bottomControls_1xij1_19",Rs="_leftControls_1xij1_23",$s="_rightControls_1xij1_24",Ds="_controlBtn_1xij1_28",Os="_controlsOverlay_1xij1_47",Fs="_hidden_1xij1_67",Vs="_topControls_1xij1_73",js="_backBtn_1xij1_93",Ws="_videoTitleInfo_1xij1_113",zs="_animeTitle_1xij1_119",Hs="_episodeLabel_1xij1_127",Us="_speedBoostBadge_1xij1_134",Ks="_progressBarContainer_1xij1_180",qs="_progressBar_1xij1_180",Ys="_thumb_1xij1_199",Qs="_bufferedBar_1xij1_217",Gs="_watchedBar_1xij1_227",Xs="_scrubbing_1xij1_252",Js="_timeBubble_1xij1_256",Zs="_bottomControlsRow_1xij1_270",ea="_nextEpisodeBtn_1xij1_293",ta="_active_1xij1_346",na="_settingsPanel_1xij1_421",ra="_settingsHeader_1xij1_440",sa="_settingsBackBtn_1xij1_448",aa="_settingsTitle_1xij1_466",oa="_settingsContent_1xij1_477",ia="_currentValue_1xij1_486",la="_menuItem_1xij1_501",ca="_menuNote_1xij1_534",da="_loadingOverlay_1xij1_547",ua="_loadingDots_1xij1_558",ma="_dot_1xij1_563",ha="_bufferingOverlay_1xij1_592",pa="_bufferingSpinner_1xij1_601",a={fullscreenFlat:Ms,timeDisplay:Ps,bottomControls:Ls,leftControls:Rs,rightControls:$s,controlBtn:Ds,controlsOverlay:Os,hidden:Fs,topControls:Vs,backBtn:js,videoTitleInfo:Ws,animeTitle:zs,episodeLabel:Hs,speedBoostBadge:Us,progressBarContainer:Ks,progressBar:qs,thumb:Ys,bufferedBar:Qs,watchedBar:Gs,scrubbing:Xs,timeBubble:Js,bottomControlsRow:Zs,nextEpisodeBtn:ea,active:ta,settingsPanel:na,settingsHeader:ra,settingsBackBtn:sa,settingsTitle:aa,settingsContent:oa,currentValue:ia,menuItem:la,menuNote:ca,loadingOverlay:da,loadingDots:ua,dot:ma,bufferingOverlay:ha,bufferingSpinner:pa},on=-6e4,On=6e4,lr=500,ga=({classes:m,delayMs:E,onDelayChange:Y})=>{const[W,H]=S(null),B=W??E,r=w(Y);r.current=Y;const A=w(E);A.current=E;const i=w(null);i.current=W,y(()=>{H(null)},[E]),y(()=>()=>{const U=i.current;U!==null&&U!==A.current&&r.current(U)},[]);const oe=U=>{A.current=U,i.current=null,r.current(U),H(null)},ie=U=>{const f=i.current??A.current,be=Math.max(on,Math.min(On,f+U));oe(be)};return t(we,{children:[t("div",{style:{display:"flex",gap:6,padding:"0.5rem 0.75rem 0.25rem"},children:[t("button",{type:"button",className:m.item,onClick:()=>ie(-lr),"aria-label":"Show subtitles 0.5 seconds earlier",style:{flex:1,justifyContent:"center"},children:t("span",{children:"-0.5s"})}),t("button",{type:"button",className:m.item,onClick:()=>ie(lr),"aria-label":"Show subtitles 0.5 seconds later",style:{flex:1,justifyContent:"center"},children:t("span",{children:"+0.5s"})}),t("button",{type:"button",className:m.item,onClick:()=>oe(0),disabled:B===0,"aria-label":"Reset subtitle timing",style:{flex:1,justifyContent:"center"},children:t("span",{children:"Reset"})})]}),t(zr,{label:"Subtitle timing",display:dr(B),min:on,max:On,step:100,value:B,percent:(B-on)/(On-on)*100,onChange:U=>{const f=Math.round(U);i.current=f,H(f)},onCommit:()=>{const U=i.current;U!==null&&oe(U)}}),t("div",{className:m.note,children:"Positive delays subtitles (show later). Negative shows them earlier. 0.0s is default."})]})},fa=({player:m,title:E,episodeLabel:Y,audioTracks:W,selectedAudioTrack:H,onAudioTrackChange:B,subtitles:r,selectedSubtitle:A,onSubtitleChange:i,streams:oe,qualityIdx:ie,onQualityChange:U,onBack:f,children:be,movyServers:M=[],selectedMovyServer:bt="atlanta",onMovyServerSelect:le,isMovySource:Xe=!1,videoDelayEnabled:yt=!1,onVideoDelayToggle:_t,videoDelayMs:St=0,onVideoDelayChange:cn,onCalibrateAvSync:dn,subtitleDelayMs:Ct=0,onSubtitleDelayChange:ce,showNextEpisodeButton:Ft=!1,onNextEpisode:Vt,isLoading:Ie=!1,isTheaterMode:ye,onTheaterModeToggle:Be,ambientSettings:K,onAmbientChange:ot})=>{const{state:k,refs:Oe,actions:$}=m,F=Oe.videoRef,{subtitleFontSize:Ae,subtitlePosition:Q,subtitleBgOpacity:_e,subtitleBgColor:Fe,subtitleTextColor:Ve,subtitleEdge:je,subtitleBold:kt}=k,[T,q]=S(null),ee=w(null),[Tt,Et]=S(0);y(()=>{const l=F.current;if(!l)return;const o=()=>Et(l.clientHeight||0);o();const He=new ResizeObserver(o);return He.observe(l),()=>He.disconnect()},[F,oe]);const C=(l,o)=>{try{localStorage.setItem(l,String(o))}catch{}},te=(l,o)=>{switch(l){case"fontSize":typeof o=="number"&&($.setSubtitleFontSize(o),C("subtitleFontSize",o));break;case"position":typeof o=="number"&&($.setSubtitlePosition(o),C("subtitlePosition",o));break;case"bgOpacity":typeof o=="number"&&($.setSubtitleBgOpacity(o),C("subtitleBgOpacity",o));break;case"bgColor":typeof o=="string"&&($.setSubtitleBgColor(o),C("subtitleBgColor",o));break;case"textColor":typeof o=="string"&&($.setSubtitleTextColor(o),C("subtitleTextColor",o));break;case"edge":(o==="shadow"||o==="outline"||o==="none")&&($.setSubtitleEdge(o),C("subtitleEdge",o));break;case"bold":typeof o=="boolean"&&($.setSubtitleBold(o),C("subtitleBold",o));break}};y(()=>{const l="tv-player-subtitle-style";let o=document.getElementById(l);o||(o=document.createElement("style"),o.id=l,document.head.appendChild(o));const He={fontSize:Ae,position:Q,bgOpacity:_e,bgColor:Fe,textColor:Ve,edge:je,bold:kt},ne=F.current,lt=Fn(Ae,Tt||ne?.clientHeight||720);if(o.textContent=Hr({...He,fontSize:lt}),ne){const ct=()=>{const N=Number(Q);return isNaN(N)?0:Math.max(0,Math.min(100,N))},Me=(N,J)=>{try{const se=N;se.snapToLines=!1,se.line=J}catch{}},yn=()=>{const N=lt*16,J=ne.videoHeight||ne.clientHeight||720,se=ne.videoWidth||ne.clientWidth||1280;return{step:N*1.3/J*100,chars:Math.max(20,Math.floor(se/(N*.55)))}},Ue=N=>{const J=Math.max(0,Math.min(100,100-ct())),se=Array.from(N.activeCues??[]);if(se.length<=1){se.forEach(ae=>Me(ae,J));return}const{step:Bt,chars:dt}=yn();let qt=J;for(let ae=se.length-1;ae>=0;ae--){const Yt=String(se[ae].text??"").replace(/<[^>]*>/g,"").split(`
2
+ `).reduce((Le,At)=>Le+Math.max(1,Math.ceil(At.length/dt)),0),Ze=qt-Yt*Bt;Me(se[ae],Math.max(0,Ze)),qt=Ze-Bt*.4}},h=()=>{const N=Math.max(0,Math.min(100,100-ct()));Array.from(ne.textTracks).forEach(J=>{J.cues&&(Array.from(J.cues).forEach(se=>Me(se,N)),J.mode==="showing"&&Ue(J))})};h();const Pe=N=>{const J=N.target;J.mode==="showing"&&Ue(J)},P=()=>{Array.from(ne.textTracks).forEach(N=>{N.removeEventListener("cuechange",Pe),N.addEventListener("cuechange",Pe)}),h()};Array.from(ne.textTracks).forEach(N=>{N.addEventListener("cuechange",Pe)}),ne.textTracks.addEventListener("addtrack",P);const It=Array.from(ne.querySelectorAll("track")),Je=()=>h();return It.forEach(N=>N.addEventListener("load",Je)),()=>{Array.from(ne.textTracks).forEach(N=>{N.removeEventListener("cuechange",Pe)}),ne.textTracks.removeEventListener("addtrack",P),It.forEach(N=>N.removeEventListener("load",Je))}}},[Ae,Q,_e,Fe,Ve,je,kt,A,r,F,Tt]);const jt=l=>{const o=F.current;!o||isNaN(k.duration)||k.duration===0||(o.currentTime=l*k.duration)},Wt=()=>{F.current&&($.setIsScrubbing(!0),$.wasPlayingBeforeScrub.current=!F.current.paused,F.current.pause())},xt=l=>{const o=F.current;o&&k.duration&&(o.currentTime=l*k.duration)},b=()=>{$.setIsScrubbing(!1),$.wasPlayingBeforeScrub.current&&F.current?.play().catch(()=>{})},c=l=>{const o=F.current;o&&(o.volume=l,o.muted=l===0)},de=()=>{$.toggleMute()},X=r.length>0,We=A>=0,zt=()=>{q("main"),$.setShowControls(!0)},Ht=()=>{if(We){i(-1);return}let l=null;try{l=localStorage.getItem("tvLastSubtitle")}catch{}i(Vn(r,{lastKey:l,enabled:!0}))},it=()=>{q(null)},un=()=>t(we,{children:[oe.length>1&&t("button",{className:a.menuItem,onClick:()=>q("quality"),children:[t("span",{children:"Quality"}),t("span",{className:a.currentValue,children:oe[ie]?.quality||"Auto"})]}),Xe&&M.length>0&&t("button",{className:a.menuItem,onClick:()=>q("server"),children:[t("span",{style:{display:"flex",alignItems:"center",gap:6},children:[t(R,{name:"server",size:12})," Movy Server"]}),t("span",{className:a.currentValue,style:{textTransform:"capitalize"},children:bt})]}),X&&t("button",{className:a.menuItem,onClick:()=>q("subtitles"),children:[t("span",{children:"Subtitles"}),t("span",{className:a.currentValue,children:We?r[A]?.label||r[A]?.language:"Off"})]}),X&&t("button",{className:a.menuItem,onClick:()=>q("subtitle-style"),children:[t("span",{children:"Subtitle Style"}),t("span",{className:a.currentValue,children:[Ae.toFixed(1),"x · ",Q]})]}),X&&t("button",{className:a.menuItem,onClick:()=>q("subtitle-timing"),children:[t("span",{children:"Subtitle Timing"}),t("span",{className:a.currentValue,children:dr(Ct)})]}),W.length>0&&t("button",{className:a.menuItem,onClick:()=>q("audio"),children:[t("span",{children:"Audio Track"}),t("span",{className:a.currentValue,children:W[H]?.label||W[H]?.language})]}),t("button",{className:a.menuItem,onClick:()=>q("av-sync"),children:[t("span",{children:"A/V Sync"}),t("span",{className:a.currentValue,children:yt?`${St}ms`:"Off"})]}),K&&ot&&t("button",{className:a.menuItem,onClick:()=>q("ambient"),children:[t("span",{children:"Ambient Light"}),t("span",{className:a.currentValue,children:K.enabled?"On":"Off"})]})]}),Ut=()=>t(an,{classes:{item:a.menuItem,active:a.active},options:oe.map((l,o)=>({key:String(o),label:l.quality,selected:o===ie})),onSelect:l=>U(Number(l))}),mn=()=>t(an,{classes:{item:a.menuItem,active:a.active},options:[{key:"off",label:"Off",selected:!We},...r.map((l,o)=>({key:String(o),label:l.label||l.language,selected:o===A}))],onSelect:l=>i(l==="off"?-1:Number(l))}),Se=()=>t(vs,{classes:{item:a.menuItem,active:a.active},values:{fontSize:Ae,position:Q,bgOpacity:_e,bgColor:Fe,textColor:Ve,edge:je,bold:kt},onChange:te}),Kt=()=>t(ga,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},delayMs:Ct,onDelayChange:l=>ce?.(l)}),hn=()=>t(an,{classes:{item:a.menuItem,active:a.active},options:W.map((l,o)=>({key:String(o),label:l.label||l.language,selected:o===H})),onSelect:l=>B(Number(l))}),pn=()=>t(an,{classes:{item:a.menuItem,active:a.active},options:M.map(l=>({key:l,label:t("span",{style:{textTransform:"capitalize"},children:l}),selected:bt===l})),onSelect:l=>le?.(l)}),gn=()=>t(bs,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},enabled:yt,delayMs:St,onToggle:l=>_t?.(l),onDelayChange:l=>cn?.(l),onCalibrate:()=>{q(null),dn?.()}}),fn=()=>K&&ot?t(ys,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},values:K,onChange:ot}):null,pe=k.isMuted?t(R,{name:"volume-mute"}):k.volume<.5?t(R,{name:"volume-down"}):t(R,{name:"volume-up"}),Nt=t("div",{className:`${a.controlsOverlay} ${!k.showControls&&!T?a.hidden:""}`,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none"},children:t("div",{className:a.topControls,onClick:l=>l.stopPropagation(),children:[t("button",{className:a.backBtn,onClick:f,title:"Back","aria-label":"Back",children:t(R,{name:"chevron-left"})}),t("div",{className:a.videoTitleInfo,children:[t("span",{className:a.animeTitle,children:E}),Y&&t("span",{className:a.episodeLabel,children:Y})]})]})}),ze=!Ie&&!k.isBuffering&&k.duration>0?t(Ur,{isPlaying:k.isPlaying,onTogglePlay:$.togglePlay,onSkipBack:()=>$.seek(-10),onSkipForward:()=>$.seek(10)}):null,vn=t("div",{className:`${a.controlsOverlay} ${!k.showControls&&!T?a.hidden:""}`,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none",justifyContent:"flex-end"},children:t("div",{className:a.bottomControls,onClick:l=>l.stopPropagation(),children:[t(Kr,{classes:{container:a.progressBarContainer,scrubbing:a.scrubbing,timeBubble:a.timeBubble,bar:a.progressBar,buffered:a.bufferedBar,watched:a.watchedBar,thumb:a.thumb},videoRef:F,duration:k.duration,formatTime:ln,isScrubbing:k.isScrubbing,buffered:"full",onSeek:jt,onScrubStart:Wt,onScrubMove:xt,onScrubEnd:b,timeLabelRef:ee}),t("div",{className:a.bottomControlsRow,children:[t("div",{className:a.leftControls,children:[t("button",{className:a.controlBtn,onClick:$.togglePlay,"aria-label":k.isPlaying?"Pause":"Play",children:k.isPlaying?t(R,{name:"pause"}):t(R,{name:"play"})}),t(qr,{muted:k.isMuted,volume:k.volume,volumeIcon:pe,buttonClassName:a.controlBtn,onToggleMute:de,onVolumeChange:c,onExpandedChange:l=>$.setShowVolumeSlider(l)}),t("span",{className:a.timeDisplay,ref:ee,children:[ln(0)," / ",ln(k.duration)]})]}),t("div",{className:a.rightControls,children:[Ft&&t("button",{className:a.nextEpisodeBtn,onClick:Vt,title:"Play next episode",children:"Next EP"}),X&&t("button",{className:`${a.controlBtn} ${We?a.active:""}`,onClick:Ht,"aria-label":We?"Turn subtitles off":"Turn subtitles on",children:t(R,{name:"closed-captioning"})}),t("button",{className:`${a.controlBtn} ${T?a.active:""}`,onClick:()=>T?it():zt(),"aria-label":"Settings",children:t(R,{name:"cog"})}),t("button",{className:`${a.controlBtn} ${ye?a.active:""}`,onClick:l=>{l.stopPropagation(),Be()},title:ye?"Exit Theater Mode":"Theater Mode","aria-label":ye?"Exit Theater Mode":"Theater Mode",children:t(R,{name:"tv"})}),t("button",{className:a.controlBtn,onClick:$.toggleFullscreen,"aria-label":k.isFullscreen?"Exit Fullscreen":"Fullscreen",children:k.isFullscreen?t(R,{name:"compress"}):t(R,{name:"expand"})})]})]})]})}),wt=T?t("div",{"data-speed-boost-ignore":"true",onClick:l=>l.stopPropagation(),children:t(fs,{classes:{panel:a.settingsPanel,header:a.settingsHeader,backBtn:a.settingsBackBtn,title:a.settingsTitle,content:a.settingsContent},title:T==="main"?"Settings":T==="subtitle-style"?"Subtitle Style":T==="subtitle-timing"?"Subtitle Timing":T==="audio"?"Audio Track":T==="server"?"Movy Server":T==="av-sync"?"A/V Sync":T==="ambient"?"Ambient Light":T.charAt(0).toUpperCase()+T.slice(1),onBack:()=>T==="main"?it():q("main"),children:[T==="main"&&un(),T==="quality"&&Ut(),T==="subtitles"&&mn(),T==="subtitle-style"&&Se(),T==="subtitle-timing"&&Kt(),T==="audio"&&hn(),T==="server"&&pn(),T==="av-sync"&&gn(),T==="ambient"&&fn()]})}):null,bn=t(we,{children:[Ie&&t("div",{className:a.loadingOverlay,"aria-hidden":"true",children:t("div",{className:a.loadingDots,children:[t("div",{className:a.dot}),t("div",{className:a.dot}),t("div",{className:a.dot})]})}),k.isBuffering&&!Ie&&t("div",{className:a.bufferingOverlay,"aria-hidden":"true",children:t("div",{className:a.bufferingSpinner})}),k.isSpeedBoostActive&&t("div",{className:a.speedBoostBadge,"aria-hidden":"true",children:[t("span",{children:"2x"}),t(R,{name:"forward",size:12})]})]});return t(Yr,{player:m,topBar:Nt,centerControls:ze,bottomBar:!Ie&&k.duration>0?vn:null,settingsPanel:wt,overlays:bn,isInteracting:!!T,className:k.isFullscreen?a.fullscreenFlat:"",children:be})};function va(m,E,Y){const W=()=>{const B=Array.isArray(m.audioTracks)?m.audioTracks.length:0,r=Y.getWant(),A=B>0?Math.min(Math.max(0,r),B-1):r;m.audioTrack=A,A!==r&&Y.onResolve(A)},H=(B,r)=>{const A=Y.getWant(),i=Array.isArray(m.audioTracks)?m.audioTracks.length:0;if(r.id!==A&&A>=0&&A<i){m.audioTrack!==A&&(m.audioTrack=A);return}Y.onResolve(r.id)};return m.on(E.MANIFEST_PARSED,W),m.on(E.AUDIO_TRACK_SWITCHED,H),()=>{m.off(E.MANIFEST_PARSED,W),m.off(E.AUDIO_TRACK_SWITCHED,H)}}const ba="_page_263ma_1",ya="_header_263ma_7",_a="_pageTitle_263ma_11",Sa="_searchForm_263ma_21",Ca="_searchInput_263ma_27",ka="_searchBtn_263ma_42",Ta="_suggestions_263ma_58",Ea="_suggestionPill_263ma_65",xa="_statusMsg_263ma_81",Na="_error_263ma_87",wa="_textOnly_263ma_91",Ia="_spinner_263ma_96",Ba="_spin_263ma_96",Aa="_grid_263ma_110",Ma="_skeletonCard_263ma_116",Pa="_skeletonThumb_263ma_121",La="_skeletonLine_263ma_127",Ra="_shimmer_263ma_134",$a="_backBtn_263ma_154",Da="_meta_263ma_172",Oa="_headerActions_263ma_180",Fa="_watchlistBtn_263ma_187",Va="_active_263ma_205",ja="_year_263ma_215",Wa="_rating_263ma_220",za="_typeBadge_263ma_229",Ha="_tv_263ma_237",Ua="_movie_263ma_242",Ka="_tvSeries_263ma_247",qa="_tvMiniSeries_263ma_252",Ya="_overview_263ma_257",Qa="_controls_263ma_264",Ga="_controlLabel_263ma_272",Xa="_select_263ma_282",Ja="_playerSection_263ma_293",Za="_video_263ma_297",eo="_videoHidden_263ma_319",to="_delayCanvas_263ma_324",no="_delayCanvasActive_263ma_337",ro="_subtitleOverlay_263ma_341",so="_videoIframe_263ma_360",ao="_retryButton_263ma_368",oo="_sidebarSeason_263ma_383",io="_mobileSeasonRow_263ma_399",lo="_sidebarPosterCard_263ma_413",co="_sidebarPosterMeta_263ma_428",uo="_providerSelectWrap_263ma_445",mo="_genreRow_263ma_457",ho="_genreChip_263ma_464",po="_metaRow_263ma_474",go="_detailGrid_263ma_483",fo="_detailItem_263ma_490",vo="_imdbLink_263ma_512",v={page:ba,header:ya,pageTitle:_a,searchForm:Sa,searchInput:Ca,searchBtn:ka,suggestions:Ta,suggestionPill:Ea,statusMsg:xa,error:Na,textOnly:wa,spinner:Ia,spin:Ba,grid:Aa,skeletonCard:Ma,skeletonThumb:Pa,skeletonLine:La,shimmer:Ra,backBtn:$a,meta:Da,headerActions:Oa,watchlistBtn:Fa,active:Va,year:ja,rating:Wa,typeBadge:za,tv:Ha,movie:Ua,tvSeries:Ka,tvMiniSeries:qa,overview:Ya,controls:Qa,controlLabel:Ga,select:Xa,playerSection:Ja,video:Za,videoHidden:eo,delayCanvas:to,delayCanvasActive:no,subtitleOverlay:ro,videoIframe:so,retryButton:ao,sidebarSeason:oo,mobileSeasonRow:io,sidebarPosterCard:lo,sidebarPosterMeta:co,providerSelectWrap:uo,genreRow:mo,genreChip:ho,metaRow:po,detailGrid:go,detailItem:fo,imdbLink:vo},bo=[],yo=[];function cr({error:m,servers:E,selectedServer:Y,onRetry:W,onSelect:H}){return t("div",{className:`${v.statusMsg} ${v.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:m}),t("button",{className:v.retryButton,onClick:W,children:"Retry"})]}),E.length>0&&t("div",{style:{display:"flex",flexWrap:"wrap",gap:6,alignItems:"center",marginTop:4},children:[t("span",{style:{fontSize:"0.8rem",opacity:.9,fontWeight:600},children:"Servers:"}),E.map(B=>t("button",{onClick:()=>H(B),className:v.retryButton,style:{padding:"4px 8px",fontSize:"0.75rem",textTransform:"capitalize",background:Y===B?"var(--accent)":void 0,color:Y===B?"white":void 0},children:B},B))]})]})}const Mo=()=>{const{id:m}=$r(),[E]=Dr(),Y=w(E);Y.current=E;const W=Or(),H=Fr(),B=E.get("type"),[r,A]=S(null),[i,oe]=S(()=>parseInt(E.get("s")||"1",10)||1),[ie,U]=S([]),[f,be]=S(()=>parseInt(E.get("e")||"1",10)||1),[M,bt]=S(()=>{try{return localStorage.getItem("tvProvider")||""}catch{return""}}),[le,Xe]=S([]),[yt,_t]=S(""),{options:St,isFallback:cn,isLoading:dn}=_s(),Ct=Ne(()=>St.filter(e=>(e.kind??"tv")==="tv").map(e=>({id:e.value,label:e.label,tier:e.tier==="embed"?"embed":"direct",servers:e.servers})),[St]),ce=cn||Ct.length===0?bo:Ct,Ft=ce.filter(e=>e.tier==="direct"),Vt=ce.filter(e=>e.tier==="embed"),[Ie,ye]=S(!1),[Be,K]=S(""),[ot,k]=S([]),[Oe,$]=S(0),[F,Ae]=S([]),[Q,_e]=S(-1),[Fe,Ve]=S(0),[je,kt]=S(""),[T,q]=S(""),[ee,Tt]=S(()=>{try{return localStorage.getItem("movyServer")||""}catch{return""}}),Et=Ne(()=>ce.find(e=>e.id===M),[ce,M]),C=Et?.tier==="embed",te=Ne(()=>Et?.servers??[],[Et]),jt=w([]);y(()=>{jt.current=le},[le]);const Wt=w(Oe);y(()=>{Wt.current=Oe},[Oe]);const xt=w(Q);y(()=>{xt.current=Q},[Q]);const b=Qr({skipIntervals:yo}),c=b.refs.videoRef,de=w(null),X=w([]),We=w(null),zt=w(null),{videoDelayMs:Ht,videoDelayEnabled:it,setDelayEnabled:un,handleVideoDelayChange:Ut,isCalibrating:mn,testClipActive:Se,stopCalibration:Kt,openAvSyncCalibrator:hn,cancelAvSyncCalibrator:pn,applyAvSyncCalibrator:gn,toggleTestClip:fn,calibReturnRef:pe,effectiveVideoDelayMs:Nt}=Gr(c),[ze,vn]=S(()=>{try{const e=Number(localStorage.getItem("tvSubtitleDelayMs"));if(Number.isFinite(e)&&e>=-6e4&&e<=6e4)return Math.round(e)}catch{}return 0}),wt=w(ze);wt.current=ze;const bn=_(e=>{const n=Math.max(-6e4,Math.min(6e4,Math.round(e)));if(wt.current!==n){wt.current=n,vn(n);try{localStorage.setItem("tvSubtitleDelayMs",String(n))}catch{}}},[]);Xr({videoRef:c,canvasRef:We,delayMs:Nt,enabled:it});const l=it,o=l||ze!==0,{settings:He,update:ne}=Jr(),lt=w(o);lt.current=o;const ct=_(()=>{if(!lt.current)return;const e=c.current;e&&Array.from(e.textTracks).forEach(n=>{n.mode!=="hidden"&&(n.mode="hidden")})},[c]),{hasConsent:Me,grant:yn}=Vr(),Ue=w("");Ue.current||(Ue.current=`tv-${Date.now()}-${Math.random().toString(36).slice(2)}`);const h=B==="movie",Pe=m?Ss(B||"tv",m):"",P=Pe,It=Cs(),Je=ks(),{toggle:N,bookmarkedIds:J,pending:se}=Ts(),{data:Bt}=Es(r?Pe:void 0),dt=Bt?!!Bt.inLibrary:Pe?J.has(Pe):!1,qt=_(()=>{!r||!m||N({tmdbId:Number(m),mediaType:B||"tv",title:r.title,poster:r.poster,year:r.year,adult:r.adult})},[r,m,B,N]),{data:ae,isFetched:_n,isPending:Yt}=xs(P||void 0,i,f),Ze=Ne(()=>ie.map(e=>e.episode_number).sort((e,n)=>e-n),[ie]),Le=Ze.indexOf(f),At=Le>0?Ze[Le-1]:null,x=Le>=0&&Le<Ze.length-1?Ze[Le+1]:null,Qt=Ne(()=>(r?.seasons??[]).map(e=>e.season_number).filter(e=>Number.isFinite(e)).sort((e,n)=>e-n),[r]),ge=Ne(()=>{if(h||x!=null)return null;const e=Qt.indexOf(i);return e>=0&&e<Qt.length-1?Qt[e+1]:(r?.number_of_seasons??0)>i?i+1:null},[h,x,Qt,i,r?.number_of_seasons]),jn=ae?.currentTime??0,Wn=ae?.duration??0,Sn=ae?.completed===!0||ae?.completed===1||$n(jn,Wn),[Ce,Re]=S(!1),ke=w(!1),Cn=w(null),Mt=w(null);y(()=>{ke.current=!1,Mt.current=null,Re(!1)},[P,i,f]);const[Te,Gt]=S(!1),[ut,zn]=S(0),[et,Hn]=S(!1),[Ke,tt]=S(!1),[ur,kn]=S(!1),[mr,Un]=S(""),[Xt,hr]=S(!1),[pr,Tn]=S(!1),{isTheaterMode:$e,toggleTheaterMode:En,handleLayoutClick:gr}=Zr();y(()=>{const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="t"&&En()};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[En]),es(b,(le.length>0||T!=="")&&!$e&&!Te&&!Ce&&!Ke);const fr=Bs(),[mt,vr]=S(ts),br=_(e=>{vr(e),ns(e)},[]),ue=w(!1),nt=w(null),xn=w(0),Kn=w(!1),qn=w(0),re=w(null),Pt=w(""),yr=ir(jn,Wn),Lt=!ue.current&&!ke.current&&(Te||Ce||Ke||Sn||yr),ht=w(Lt);ht.current=Lt;const pt=w(!1);y(()=>{pt.current=et},[et]);const qe=_((e,n)=>{if(!P||!n||n<30)return;const s=$n(e,n),d=s?n:e;Math.abs(d-xn.current)<10&&!s||(xn.current=d,It.mutate({mediaId:P,season:i,episode:f,currentTime:Math.floor(d),duration:Math.floor(n),completed:s,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:B||"tv",adult:r?.adult?1:0}))},[P,i,f,It,r,B]),Ee=_((e,n)=>{Kt();const s=new URLSearchParams(E);s.set("type",E.get("type")||"tv"),s.set("s",String(e)),s.set("e",String(n)),W(`${window.location.pathname}?${s.toString()}`)},[E,W,Kt]),Rt=_(()=>{const e=c.current;if(!e||h||x==null){kn(!1);return}const n=e.duration||0,s=e.currentTime||0;kn(n>0&&s/n>=.8)},[h,x,c]),Jt=_((e,n)=>["tv-sources",M,h?"movie":"tv",m,e,n,ee],[M,h,m,ee]),Zt=_(async(e,n)=>{if(!r||!m||!M)return{valid:!1,sources:[]};const s=h?"movie":"tv",d=await vt.tv.sources.query({provider:M,type:s,tmdbId:String(m),season:e,episode:n,title:r.title||"",year:r.year||"",totalSeasons:String(r.number_of_seasons||1),imdbId:r.imdb_id||"",...te.length>0&&ee?{server:ee}:{}});return{valid:"valid"in d?d.valid:!1,error:"error"in d?d.error:void 0,sources:d.sources,referer:"referer"in d?d.referer:void 0,audioTracks:d.audioTracks,subtitles:"subtitles"in d?d.subtitles:void 0}},[r,m,M,h,te,ee]),Yn=_(()=>{if(h||!r||!m||!M||C||x==null)return;const e=Jt(i,x);H.getQueryState(e)?.status!=="success"&&H.prefetchQuery({queryKey:e,queryFn:()=>Zt(i,x),staleTime:300*1e3,gcTime:1800*1e3})},[h,r,m,M,C,x,i,H,Jt,Zt]),_r=_(()=>{if(Se)return;Rt();const e=c.current;!e||e.paused||e.ended||(e.duration>0&&e.duration-e.currentTime<=60&&Yn(),nt.current&&clearTimeout(nt.current),nt.current=setTimeout(()=>{qe(e.currentTime,e.duration||0)},5e3))},[qe,c,Se,Rt,Yn]),Sr=_(()=>{const e=c.current;if(!e||!r)return;nt.current&&clearTimeout(nt.current),qe(e.currentTime,e.duration||0),Kn.current=!0;const n=rs({seekInduced:Date.now()-qn.current<ss,autoplayEnabled:mt,hasNext:!h&&x!=null,isFinal:h||x==null});n==="advance"&&x!=null?(be(x),Ee(i,x)):n==="prompt-next"?(ke.current=!1,ue.current=!0,Re(!0)):n==="prompt-complete"&&(Un(h?r.title:`${r.title} — Season ${i}`),tt(!0),ke.current=!0,ue.current=!0)},[h,r,i,x,mt,qe,Ee,c]),Cr=_(()=>{Kn.current=!1,b.actions.onPlay()},[b.actions]),kr=_(()=>{b.actions.onPause();const e=c.current;e&&!e.ended&&qe(e.currentTime,e.duration||0)},[b.actions,qe,c]),Tr=_(()=>{b.actions.onLoadedMetadata();const e=c.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(re.current!=null&&re.current>0){try{e.currentTime=re.current}catch{}re.current=null}Rt()}},[b.actions,c,Rt]),gt=_(()=>{const e=c.current;if(e&&re.current!=null&&re.current>0){try{e.currentTime=re.current}catch{}re.current=null}},[c]),Er=_(()=>{ut>0&&(re.current=ut);const e=c.current;if(e&&ut>0){try{e.currentTime=ut,re.current=null}catch{}e.play().catch(()=>{})}Gt(!1),ue.current=!0},[ut,c]),Qn=_(()=>{re.current=null;const e=c.current;e&&(e.currentTime=0,e.play().catch(()=>{})),Gt(!1),ue.current=!0},[c]),xr=_(()=>{ke.current=!0,Re(!1),ue.current=!0},[]),Nr=_(()=>{ke.current=!0,Re(!1),ue.current=!0,re.current=null;const e=c.current;if(e){try{e.currentTime=0}catch{}e.play().catch(()=>{})}},[c]),Gn=_(()=>{x!=null&&(ke.current=!0,Re(!1),ue.current=!0,be(x),Ee(i,x))},[x,i,Ee]),Xn=_(()=>{ge!=null&&(ke.current=!0,Re(!1),tt(!1),ue.current=!0,oe(ge),be(1),Ee(ge,1))},[ge,Ee]),wr=_(async()=>{if(P)try{await Je.mutateAsync({id:P,status:"Completed"}),tt(!1),Re(!1),W("/")}catch{}},[P,Je,W]);y(()=>{ue.current=!1,Cn.current=null,Gt(!1),kn(!1),zn(0),Hn(!1),pt.current=!1,re.current=null,Pt.current=`${P}:${i}:${f}`,xn.current=0},[P,i,f]),y(()=>{_n&&(Hn(!0),pt.current=!0)},[_n,P,i,f]),y(()=>{if(!ae||ue.current)return;const e=`${P}:${i}:${f}`;if(Cn.current===e)return;Cn.current=e;const n=ae,s=n.currentTime??0,d=n.duration??0;ir(s,d)&&(zn(s),Gt(!0))},[ae,P,i,f]),y(()=>{if(!et||ue.current||ke.current||Te||Ke||Ce)return;const e=`${P}:${i}:${f}`;if(Mt.current!==e){if(!Sn){Yt||(Mt.current=e);return}if(h){Mt.current=e,Re(!0);return}if(!(!r||Le<0||ie.length===0)){if(Mt.current=e,x==null&&ge==null){r&&ie.length>0&&(Un(`${r.title} — Season ${i}`),tt(!0),ke.current=!0,ue.current=!0);return}Re(!0)}}},[et,Sn,Yt,Te,Ke,Ce,h,x,ge,r,Le,ie.length,P,i,f]),y(()=>{(Te||Ce)&&c.current&&c.current.pause()},[Te,Ce,c]),y(()=>{const e=c.current;return()=>{nt.current&&clearTimeout(nt.current),e&&!e.ended&&qe(e.currentTime,e.duration||0)}},[qe,c]);const Nn=_(e=>{let n=null,s=!0;try{n=localStorage.getItem("tvLastSubtitle"),s=localStorage.getItem("tvSubtitlesEnabled")!=="false"}catch{}return Vn(e,{lastKey:n,enabled:s})},[]),wn=_(e=>{if(!(e<0))try{localStorage.setItem("tvSubtitlesEnabled","true"),localStorage.setItem("tvSelectedSubtitle",String(e))}catch{}},[]),Jn=_(e=>{if(e.length===0)return 0;let n=null;try{n=localStorage.getItem("tvLastAudio")}catch{}if(n){const s=e.findIndex(O=>Dn(O)===n);if(s>=0)return s;const d=n.indexOf("|||"),u=d>=0?n.slice(0,d):n,p=d>=0?n.slice(d+3):n,g=e.findIndex(O=>O.language===u||O.label===p);if(g>=0)return g}return Vn(e,{lastKey:null,enabled:!0})},[]),{data:Zn}=Ns(P||void 0),er=Ne(()=>(Zn?.progress??[]).filter(n=>n.season===i&&(n.completed===!0||n.completed===1||$n(n.currentTime,n.duration))).map(n=>String(n.episode)),[Zn,i]),tr=Ne(()=>ie.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})),[ie]),nr=Ne(()=>(r?.genres??[]).map(e=>e.name).slice(0,5),[r]),In=Ne(()=>[r?.year,r?.status,r?.number_of_seasons?`${r.number_of_seasons} Season${r.number_of_seasons>1?"s":""}`:null,r?.number_of_episodes?`${r.number_of_episodes} Episodes`:null].filter(Boolean),[r]);y(()=>{if(ce.length!==0&&!ce.some(e=>e.id===M)){const e=ce.find(n=>n.tier==="direct")?.id??ce[0].id;bt(e);try{localStorage.setItem("tvProvider",e)}catch{}}},[ce,M]),y(()=>{if(te.length!==0&&!te.includes(ee)){Tt(te[0]);try{localStorage.setItem("movyServer",te[0])}catch{}}},[te,ee]),y(()=>{if(!m){A(null),Xe([]),_t(""),K(""),q("");return}const e=Number(m),n=B||"tv";A(null),Xe([]),_t(""),K(""),q("");const s=parseInt(Y.current.get("s")||"",10),d=parseInt(Y.current.get("e")||"",10);oe(isNaN(s)?1:s),be(isNaN(d)?1:d),Ve(0),vt.tv.details.query({type:n,id:String(e)}).then(u=>{const p={id:u.id,title:u.title||"",overview:u.overview||"",vote_average:u.vote_average,year:u.year,poster:u.poster,backdrop:u.backdrop,imdb_id:u.imdb_id||void 0,adult:u.adult,seasons:u.seasons,number_of_seasons:u.number_of_seasons};A(p),p.seasons&&p.seasons.length>0&&isNaN(s)&&oe(p.seasons[0].season_number)}).catch(()=>{})},[m,B]),y(()=>{if(!r||!m)return;if(!(r.seasons!==void 0||r.number_of_seasons!==void 0)){U([]);return}const n=parseInt(E.get("e")||"",10);vt.tv.episodes.query({id:String(m),season:String(i)}).then(s=>{const d=(s.episodes||[]).map(u=>({episode_number:u.episode_number,name:u.name||"",vote_average:u.vote_average,overview:u.overview||"",still_path:u.still_path||""}));U(d),d.length!==0&&be(u=>!isNaN(n)&&d.some(p=>p.episode_number===n)?n:d.some(p=>p.episode_number===u)?u:d[0].episode_number)}).catch(()=>{})},[r,m,i,E]),y(()=>{if(!C||!r||!m)return;fetch(`/api/tv/embed/${M}/${h?"movie":"tv"}/${m}?season=${i}&episode=${f}`).then(n=>n.json()).then(n=>{if(n.url)return q(n.url),fetch(`/api/resolve?url=${encodeURIComponent(n.url)}`).then(s=>s.json()).then(s=>{s.finalUrl&&q(s.finalUrl)})}).catch(()=>{})},[M,r,m,i,f,h,C]);const en=_(async()=>{if(!r||!m||!M||C||r.adult&&!Me)return;const e=`${P}:${i}:${f}`;jt.current.length>0?K(""):(ye(!0),K(""),Xe([]),Ve(0),k([]),Ae([]));try{const s=await H.fetchQuery({queryKey:Jt(i,f),queryFn:()=>Zt(i,f),staleTime:3e5,gcTime:18e5});if(Pt.current!==e)return;if(ye(!1),!s.valid||!s.sources?.length){K(s.error?`${s.error}`:te.length>0?`No streams from ${ee}. Try another server.`:"No streams available.");return}Xe(s.sources),_t(e),Ve(0),s.referer&&kt(s.referer);const d=s.audioTracks||[];k(d),$(d.length>0?Jn(d):0);const u=s.subtitles||[];if(Ae(u),u.length>0){const O=Nn(u);_e(O),wn(O)}else _e(-1);const p=h?"movie":"tv",g=m;vt.tv.subtitles.query({type:p,tmdbId:String(g),season:String(i),episode:String(f)}).then(O=>{if(Pt.current!==e)return;const fe=Array.isArray(O.subtitles)?O.subtitles:[];fe.length!==0&&Ae(z=>{const I=[...z,...fe.filter(D=>!z.some(L=>L.url===D.url))];if(z.length===0){const D=Nn(I);_e(D),wn(D)}return I})}).catch(()=>{}),K("")}catch{if(Pt.current!==e)return;ye(!1),K("Failed to load streams.")}},[r,m,M,i,f,h,C,Me,te,ee,Nn,wn,Jn,P,H,Jt,Zt]),Bn=_(e=>{const n=e.toLowerCase();Tt(n);try{localStorage.setItem("movyServer",n)}catch{}K("")},[]),Ir=_(e=>{bt(e);try{localStorage.setItem("tvProvider",e)}catch{}},[]);y(()=>{M&&r&&!C&&en()},[M,r,en,C]),y(()=>{if(!c.current||(de.current&&(de.current.destroy(),de.current=null),C))return;let e=!1;if(Se){const p=c.current;return p&&(p.pause(),p.removeAttribute("src"),p.load(),p.src="/av-sync-test.mp4",ht.current||p.play().catch(()=>{})),()=>{e=!0}}const n=yt===`${P}:${i}:${f}`&&le[Fe]?.url||"";if(!n){try{c.current?.pause()}catch{}return}const s=c.current;if(Pt.current===`${P}:${i}:${f}`&&re.current==null&&!ht.current)try{!s.ended&&s.currentTime>1&&(re.current=s.currentTime)}catch{}s.pause(),s.removeAttribute("src"),s.load(),b.actions.resetMediaState();const d=`/api/tv/stream-proxy?url=${encodeURIComponent(n)}&referer=${encodeURIComponent(je)}`;le[Fe]?.type==="hls"?(async()=>{const p=await ws();if(!e)if(p&&p.isSupported()){const g=new p({enableWorker:!0});de.current=g,g.on(p.Events.ERROR,(z,I)=>{I.fatal&&(K(`Stream failed (${I.details}). Try another source or reload.`),ye(!1),g.destroy(),de.current=null)}),g.loadSource(d),g.attachMedia(s);const O=()=>{let z=!1,I=0;try{z=localStorage.getItem("tvSubtitlesEnabled")==="true";const D=parseInt(localStorage.getItem("tvSelectedSubtitle")||"0",10);!isNaN(D)&&D>=0&&(I=D)}catch{}return{enabled:z,index:I}},fe=()=>{if(typeof g.subtitleTrack!="number")return;if(X.current.length>0){g.subtitleTrack=-1;return}const z=Array.isArray(g.subtitleTracks)?g.subtitleTracks:[];if(z.length===0){g.subtitleTrack=-1;return}const I=O();if(I.enabled){const D=I.index<z.length?I.index:0;g.subtitleTrack=D,_e(D),ct()}else g.subtitleTrack=-1};va(g,p.Events,{getWant:()=>Wt.current,onResolve:z=>$(z)}),g.on(p.Events.MANIFEST_PARSED,()=>{fe(),pe.current!=null&&(s.currentTime=pe.current,pe.current=null),gt(),!ht.current&&pt.current&&s.play().catch(()=>{})}),g.on(p.Events.SUBTITLE_TRACKS_UPDATED,()=>{fe()}),g.on(p.Events.SUBTITLE_TRACK_SWITCH,(z,I)=>{if(X.current.length>0){if(I.id!==-1)try{g.subtitleTrack=-1}catch{}return}const D=Array.isArray(g.subtitleTracks)?g.subtitleTracks:[];if(D.length!==0){if(I.id===-1){const L=O();if(L.enabled){const G=L.index<D.length?L.index:0;g.subtitleTrack=G;return}}_e(I.id),ct()}})}else Is(s)&&(s.src=d,pe.current!=null&&(s.currentTime=pe.current,pe.current=null),gt(),!ht.current&&pt.current&&s.play().catch(()=>{K("Failed to play stream. Try another source.")}))})():(s.src=d,pe.current!=null&&(s.currentTime=pe.current,pe.current=null),gt(),!ht.current&&pt.current&&s.play().catch(()=>{K("Failed to play stream. Try another source.")}));const u=()=>{const O=s.error?.code===4?"Video source not supported or not found":"Failed to load video stream";K(`${O}. The source may be invalid or expired. Try switching source or reloading.`),ye(!1)};return s.addEventListener("error",u),()=>{e=!0,s.removeEventListener("error",u)}},[le,yt,Fe,M,je,C,c,pe,Se,P,i,f,gt,ct,b.actions]),y(()=>{if(!et||Te||Ce||Ke||Lt||C||Se)return;const e=c.current;!e||!e.paused||e.ended||e.readyState<1||(gt(),e.play().catch(()=>{}))},[et,Te,Ce,Ke,Lt,C,Se,gt,c]),y(()=>{const e=de.current;!e||typeof e.audioTrack!="number"||(e.audioTrack=Oe)},[Oe]),y(()=>{const e=de.current;!e||typeof e.subtitleTrack!="number"||!Array.isArray(e.subtitleTracks)||e.subtitleTracks.length===0||X.current.length>0||(Q>=0?e.subtitleTrack=Q:e.subtitleTrack=-1)},[Q]),y(()=>{const e=c.current;if(!(!e||C)&&(e.querySelectorAll("track").forEach(n=>n.remove()),X.current=[],F.length!==0&&(F.forEach(n=>{const s=document.createElement("track");s.kind="subtitles",s.label=n.label||n.language||"Unknown",s.srclang=n.language||n.label||"en";const d=`/api/subtitle-proxy?url=${encodeURIComponent(n.url)}&referer=${encodeURIComponent(je)}`;s.src=d,s.addEventListener("load",()=>{const u=X.current.indexOf(s),p=s.track;if(p&&u>=0){const g=u===xt.current;p.mode=g&&!lt.current?"showing":"hidden"}}),e.appendChild(s),X.current.push(s)}),F.length>0)))try{const n=de.current;n&&typeof n.subtitleTrack=="number"&&n.subtitleTrack!==-1&&(n.subtitleTrack=-1)}catch{}},[F,je,C,M,c]),y(()=>{const e=c.current;if(!e||C)return;const n=de.current;X.current.length>0&&n&&typeof n.subtitleTrack=="number"&&Array.isArray(n.subtitleTracks)&&n.subtitleTracks.length>0&&(n.subtitleTrack=-1);const s=()=>{const p=Fn(b.state.subtitleFontSize,e.clientHeight||720),g=Math.max(0,Math.min(100,100-b.state.subtitlePosition)),O=()=>{const L=p*16,G=e.videoHeight||e.clientHeight||720,Z=e.videoWidth||e.clientWidth||1280;return{step:L*1.3/G*100,chars:Math.max(20,Math.floor(Z/(L*.55)))}},fe=(L,G)=>{const Z=L;Z.snapToLines=!1,Z.line=G},z=L=>{if(!L.cues)return;Array.from(L.cues).forEach(me=>fe(me,g));const G=Array.from(L.activeCues??[]);if(G.length<=1){G.forEach(me=>fe(me,g));return}const{step:Z,chars:V}=O();let rt=g;for(let me=G.length-1;me>=0;me--){const Ye=String(G[me].text??"").replace(/<[^>]*>/g,"").split(`
3
+ `).reduce((rn,Dt)=>rn+Math.max(1,Math.ceil(Dt.length/V)),0);rt=Math.max(0,rt-Ye*Z),fe(G[me],rt),rt-=Z*.4}},I=X.current;if(I.length>0){I.forEach((L,G)=>{const Z=L.track;if(!Z)return;const V=G===Q;Z.mode=V&&!o?"showing":"hidden",V&&!o&&z(Z)});return}const D=Array.from(e.textTracks);D.length!==0&&D.forEach((L,G)=>{const Z=G===Q;L.mode=Z&&!o?"showing":"hidden",Z&&!o&&z(L)})};s();const d=()=>s();e.textTracks.addEventListener("addtrack",d),e.addEventListener("loadedmetadata",s,{once:!0});const u=window.setTimeout(s,600);return()=>{e.textTracks.removeEventListener("addtrack",d),e.removeEventListener("loadedmetadata",s),window.clearTimeout(u)}},[Q,F,C,M,c,o,b.state.subtitleFontSize,b.state.subtitlePosition]),y(()=>{if(!o)return;const e=c.current,n=zt.current;if(!e||!n)return;const s=ze/1e3,d=Nt/1e3,u=new Set;let p=[],g=-1,O=-1,fe=-1,z=-1,I=0,D=0,L=!1;const G=()=>{const j=xt.current;if(j<0)return null;const Qe=X.current;return Qe.length>0?Qe[j]?.track??null:Array.from(e.textTracks)[j]??null},Z=(j,Qe)=>{const he=j.cues;if(!he||he.length===0)return Array.from(j.activeCues??[]);let st=0,at=he.length;for(;st<at;){const xe=st+at>>>1;he[xe].endTime+s<Qe?st=xe+1:at=xe}const Ot=[];for(let xe=st;xe<he.length;xe++){const sn=he[xe];if(sn.startTime+s>Qe)break;sn.endTime+s>=Qe&&Ot.push(sn)}return Ot},V=()=>{const j=G(),Qe=e.currentTime-d,he=j?Z(j,Qe):[],st=e.clientWidth,at=e.clientHeight,Ot=e.videoWidth,xe=e.videoHeight;if(he.length===p.length&&he.every((Mn,Pn)=>Mn===p[Pn])&&st===g&&at===O&&Ot===fe&&xe===z||(p=he,g=st,O=at,fe=Ot,z=xe,n.textContent="",he.length===0))return;const ar={fontSize:Fn(b.state.subtitleFontSize,at),position:b.state.subtitlePosition,bgOpacity:b.state.subtitleBgOpacity,bgColor:b.state.subtitleBgColor,textColor:b.state.subtitleTextColor,edge:b.state.subtitleEdge,bold:b.state.subtitleBold},Pr=as(ar),Lr=os(e,ar.position);he.forEach((Mn,Pn)=>{const or=String(Mn.text??"");if(!is(or).trim())return;const Ln=document.createElement("div"),Rr=(he.length-1-Pn)*1.7;Ln.style.cssText=`${Pr}
4
+ bottom: calc(${Lr}px + ${Rr}em);`,Ln.innerHTML=ls(or),n.appendChild(Ln)})},rt=()=>{Array.from(e.textTracks).forEach(j=>{u.has(j)||(u.add(j),j.addEventListener("cuechange",V))})},me=()=>{rt(),V()},An=()=>{if(L||D)return;const j=()=>{D=0,!(L||e.paused||e.ended)&&(V(),An())};D=window.requestAnimationFrame(j)},Ye=e,rn=()=>{I=0,V(),!L&&Ye.requestVideoFrameCallback&&(I=Ye.requestVideoFrameCallback(rn))},Dt=()=>{V(),Ye.requestVideoFrameCallback?I||(I=Ye.requestVideoFrameCallback(rn)):An()};rt(),e.textTracks.addEventListener("addtrack",me),e.textTracks.addEventListener("removetrack",me),e.addEventListener("timeupdate",V),e.addEventListener("seeked",V),e.addEventListener("loadedmetadata",V),e.addEventListener("play",Dt);const rr=Array.from(e.querySelectorAll("track"));rr.forEach(j=>j.addEventListener("load",V));const sr=typeof ResizeObserver>"u"?null:new ResizeObserver(()=>V());return sr?.observe(e),V(),Dt(),()=>{L=!0,u.forEach(j=>j.removeEventListener("cuechange",V)),e.textTracks.removeEventListener("addtrack",me),e.textTracks.removeEventListener("removetrack",me),e.removeEventListener("timeupdate",V),e.removeEventListener("seeked",V),e.removeEventListener("loadedmetadata",V),e.removeEventListener("play",Dt),rr.forEach(j=>j.removeEventListener("load",V)),sr?.disconnect(),D&&window.cancelAnimationFrame(D),I&&Ye.cancelVideoFrameCallback&&Ye.cancelVideoFrameCallback(I),n.textContent=""}},[o,ze,Q,F,Nt,c,b.state.subtitleFontSize,b.state.subtitlePosition,b.state.subtitleBgOpacity,b.state.subtitleBgColor,b.state.subtitleTextColor,b.state.subtitleEdge,b.state.subtitleBold]);const tn=()=>{A(null),Xe([]),q(""),W(-1)},Br=_(e=>{oe(e),be(1),Ee(e,1)},[Ee]),nn=!h&&r?.seasons&&r.seasons.length>1?t("label",{className:v.sidebarSeason,children:[t("span",{children:"Season"}),t("select",{value:i,onChange:e=>Br(parseInt(e.target.value,10)||1),className:v.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,ft=_(e=>{const n=parseInt(e,10);if(!isNaN(n)){try{c.current?.pause()}catch{}be(n),Ee(i,n)}Tn(!1)},[i,Ee,c]);y(()=>{if(h)return;const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="n"&&(x!=null?ft(String(x)):jr.error("No next episode available"))};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[h,x,ft]);const Ar=e=>{$(e);try{const s=ot[e];s&&localStorage.setItem("tvLastAudio",Dn(s))}catch{}const n=de.current;n&&n.audioTrack!==void 0&&(n.audioTrack=e)},Mr=e=>{_e(e);try{if(e===-1)localStorage.setItem("tvSubtitlesEnabled","false");else{localStorage.setItem("tvSubtitlesEnabled","true"),localStorage.setItem("tvSelectedSubtitle",String(e));const u=F[e];u&&localStorage.setItem("tvLastSubtitle",Dn(u))}}catch{}const n=c.current,s=de.current;if(s&&typeof s.subtitleTrack=="number"&&Array.isArray(s.subtitleTracks)&&s.subtitleTracks.length>0&&(s.subtitleTrack=X.current.length>0||e<0?-1:e),!n)return;const d=X.current;if(d.length>0){d.forEach((u,p)=>{const g=u.track;if(!g)return;const O=p===e;g.mode=O&&!o?"showing":"hidden"});return}Array.from(n.textTracks).forEach((u,p)=>{const g=p===e;u.mode=g&&!o?"showing":"hidden"})},$t=_(()=>{if(!r)return;const e=c.current,n=h?"":`S${String(i).padStart(2,"0")}E${String(f).padStart(2,"0")}`;vt.discord.tvPresence.mutate({title:r.title,episodeLabel:n,isPlaying:e?!e.paused&&!e.ended:!0,thumbnail:r.poster,currentTime:e?e.currentTime:0,duration:e&&e.duration||0,isAdult:r.adult===!0,sessionId:Ue.current}).catch(()=>{}),vt.discord.heartbeat.mutate({sessionId:Ue.current}).catch(()=>{})},[r,h,i,f,c]);return y(()=>{if(!r)return;$t();const e=window.setInterval(()=>{const n=c.current;(!n||!n.paused)&&$t()},15e3);return()=>window.clearInterval(e)},[$t,r,c]),y(()=>{if(!r||C||Ie||Be||le.length===0)return;const e=c.current;if(!e)return;const n=()=>$t();return e.addEventListener("play",n),e.addEventListener("pause",n),e.addEventListener("seeked",n),()=>{e.removeEventListener("play",n),e.removeEventListener("pause",n),e.removeEventListener("seeked",n)}},[r,C,Ie,Be,le,$t,c]),y(()=>{const e=Ue.current,n=()=>Wr(e),s=()=>n();return window.addEventListener("pagehide",s),window.addEventListener("beforeunload",s),()=>{window.removeEventListener("pagehide",s),window.removeEventListener("beforeunload",s),n()}},[]),y(()=>{if(!r){document.title="TV & Movies - dango";return}document.title=h?`${r.title} - dango`:`${r.title} - Season ${i} Episode ${f} - dango`},[r,h,i,f]),y(()=>{if(!r||h)return;const e=new URLSearchParams(E),n=e.get("s"),s=e.get("e"),d=String(i),u=String(f);n===d&&s===u||(e.set("type",E.get("type")||"tv"),e.set("s",d),e.set("e",u),W(`${window.location.pathname}?${e.toString()}`,{replace:!0}))},[r,h,i,f,E,W]),t("div",{className:`${Ge.playerPageLayout} ${$e?Ge.theaterMode:""}`,onClick:gr,children:[$e&&t(cs,{videoRef:c,active:He.enabled&&!C&&le.length>0&&!Be&&!(r?.adult&&!Me),settings:He}),!$e&&t("aside",{className:Ge.episodeSidebar,children:r?h?t("div",{className:v.sidebarPosterCard,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:v.sidebarPosterMeta,children:[t("strong",{children:r.title}),t("span",{children:r.year})]})]}):t(ds,{episodes:tr,currentEpisode:String(f),watchedEpisodes:er,onEpisodeClick:ft,header:nn}):h?t("div",{className:v.statusMsg,children:[t(R,{name:"spinner",className:v.spinner})," Loading..."]}):t(us,{variant:"sidebar"})}),t("div",{className:Ge.playerMain,children:[r&&t("div",{className:v.playerSection,onContextMenu:e=>e.preventDefault(),style:r.adult&&!Me?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:C&&T?t("iframe",{src:T,className:v.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!C&&(le.length>0||Ie)?t(we,{children:[Be&&t(cr,{error:Be,servers:te,selectedServer:ee,onRetry:en,onSelect:Bn}),t(fa,{player:b,title:r.title,episodeLabel:h?void 0:`S${i} E${f}`,audioTracks:ot,selectedAudioTrack:Oe,onAudioTrackChange:Ar,subtitles:F,selectedSubtitle:Q,onSubtitleChange:Mr,streams:le,qualityIdx:Fe,onQualityChange:Ve,onBack:tn,movyServers:te,selectedMovyServer:ee,onMovyServerSelect:Bn,isMovySource:te.length>0,videoDelayEnabled:it,onVideoDelayToggle:un,videoDelayMs:Ht,onVideoDelayChange:Ut,onCalibrateAvSync:hn,subtitleDelayMs:ze,onSubtitleDelayChange:bn,showNextEpisodeButton:ur&&!Te&&!Ce&&!Ke,onNextEpisode:Gn,isLoading:Ie,isTheaterMode:$e,onTheaterModeToggle:En,ambientSettings:He,onAmbientChange:ne,children:[t("video",{ref:c,autoPlay:et&&!Lt,playsInline:!0,disablePictureInPicture:!0,className:`${v.video} ${l?v.videoHidden:""}`,onTimeUpdate:_r,onEnded:()=>{Se||Sr()},onPlay:Cr,onPause:kr,onSeeked:()=>{qn.current=Date.now(),Rt()},onLoadedMetadata:Tr,onVolumeChange:b.actions.onVolumeChange,onWaiting:b.actions.onWaiting,onPlaying:b.actions.onPlaying,onCanPlay:b.actions.onCanPlay,onContextMenu:e=>e.preventDefault(),onError:()=>{K("Video failed to load. Try another server or reload."),ye(!1)}}),t("canvas",{ref:We,className:`${v.delayCanvas} ${l?v.delayCanvasActive:""}`}),o&&t("div",{ref:zt,className:v.subtitleOverlay}),t(ms,{isOpen:mn,ms:Ht,onChange:Ut,onApply:gn,onClose:pn,testClipActive:Se,onTestClip:fn})]})]}):Be&&!C?t(cr,{error:Be,servers:te,selectedServer:ee,onRetry:en,onSelect:Bn}):null}),!$e&&r&&t(hs,{}),!$e&&nn&&t("div",{className:v.mobileSeasonRow,children:nn}),!$e&&r&&t("div",{className:v.providerSelectWrap,children:t("label",{className:v.controlLabel,children:["Source",t("select",{value:M,onChange:e=>Ir(e.target.value),className:v.select,disabled:ce.length===0,children:dn?t("option",{value:"",children:"Loading…"}):ce.length===0?t("option",{value:"",children:"No providers available"}):t(we,{children:[Ft.length>0&&t("optgroup",{label:"Direct HLS",children:Ft.map(e=>t("option",{value:e.id,children:e.label},e.id))}),Vt.length>0&&t("optgroup",{label:"Embeds",children:Vt.map(e=>t("option",{value:e.id,children:e.label},e.id))})]})})]})}),!$e&&r&&t("div",{className:Ge.playerInfoContainer,children:[t("div",{className:Ge.playerInfoHeader,children:[t("div",{className:Ge.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:Ge.videoTitleSection,children:[t("div",{className:ve.titleContainer,children:[t("h1",{children:r.title}),t("div",{className:v.meta,children:[t("span",{className:v.year,children:r.year}),r.vote_average!=null&&r.vote_average>0&&t("span",{className:v.rating,children:[t(R,{name:"star",size:12}),Number(r.vote_average).toFixed(1)]}),t("span",{className:`${v.typeBadge} ${v[h?"movie":"tv"]}`,children:h?"Movie":"TV Show"})]}),nr.length>0&&t("div",{className:v.genreRow,children:nr.map(e=>t("span",{className:v.genreChip,children:e},e))}),In.length>0&&t("div",{className:v.metaRow,children:In.map((e,n)=>t("span",{children:[e,n<In.length-1?" · ":""]},`${e}-${n}`))})]}),t("div",{className:ve.controls,children:[t("button",{className:`${ve.watchlistBtn} ${dt?ve.inList:""}`,onClick:qt,disabled:se,type:"button",children:[dt?t(R,{name:"check",size:14}):t(R,{name:"plus",size:14}),dt?"In Watchlist":"Add to Watchlist"]}),!h&&t(we,{children:[t("button",{className:`${ve.watchlistBtn}`,onClick:()=>At!=null&&ft(String(At)),disabled:At==null,type:"button",children:[t(R,{name:"chevron-left",size:14}),"Prev EP"]}),t("button",{className:`${ve.watchlistBtn}`,onClick:()=>x!=null&&ft(String(x)),disabled:x==null,type:"button",children:["Next EP",t(R,{name:"chevron-right",size:14})]}),!h&&t("button",{className:`${ve.watchlistBtn} ${ve.modeToggleBtn} ${mt?ve.modeToggleActive:""}`,onClick:()=>br(!mt),type:"button","aria-pressed":mt,children:mt?"AUTOPLAY: ON":"AUTOPLAY: OFF"}),fr&&t("button",{className:`${ve.watchlistBtn}`,onClick:()=>Tn(!0),type:"button",children:[t(R,{name:"list-ul",size:14}),"Episodes"]})]})]})]})]}),t("div",{className:ve.descriptionSection,children:[t("h3",{children:"Synopsis"}),t(As,{text:r.overview,emptyText:"No description available."})]}),t("button",{className:ve.detailsToggleBtn,onClick:()=>hr(!Xt),type:"button",children:[Xt?t(R,{name:"chevron-up"}):t(R,{name:"chevron-down"}),Xt?"Hide Details":"Show Details"]}),Xt&&t("div",{className:v.detailGrid,children:[r.first_air_date&&t("div",{className:v.detailItem,children:[t("strong",{children:h?"Release Date":"First Air Date"}),t("span",{children:r.first_air_date})]}),r.last_air_date&&t("div",{className:v.detailItem,children:[t("strong",{children:"Last Air Date"}),t("span",{children:r.last_air_date})]}),r.networks&&r.networks.length>0&&t("div",{className:v.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:v.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:v.detailItem,children:[t("strong",{children:"Episode Runtime"}),t("span",{children:[r.episode_run_time[0]," min"]})]}),r.imdb_id&&t("div",{className:v.detailItem,children:[t("strong",{children:"IMDb"}),t("a",{href:`https://www.imdb.com/title/${r.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:v.imdbLink,children:"View on IMDb"})]})]})]}),!h&&t(ps,{isOpen:pr,onClose:()=>Tn(!1),episodes:tr,currentEpisode:String(f),watchedEpisodes:er,onEpisodeClick:ft,header:nn}),r?.adult&&!Me&&t(Rn,{isOpen:!0,title:"Content Warning",onClose:tn,children:t("div",{style:{padding:"1rem",textAlign:"center"},children:[t("p",{children:"This title contains mature content intended for adult audiences."}),t("p",{children:["By proceeding, you confirm that you are ",t("strong",{children:"18 years of age or older"})," ","(or the age of majority in your jurisdiction) and wish to view this content."]}),t("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center"},children:[t(De,{variant:"secondary",onClick:tn,children:"Go Back"}),t(De,{onClick:yn,children:"I'm 18+, Continue"})]})]})}),t(gs,{isOpen:Te,onClose:Qn,title:"Resume Watching",message:t(we,{children:["You were at ",t("strong",{children:ln(ut)})]}),restartLabel:"Start from Beginning",onResume:Er,onRestart:Qn}),t(Rn,{isOpen:Ce,onClose:xr,title:h?"Movie Completed":"Episode Completed",children:t("div",{style:{padding:"1rem",textAlign:"center"},children:[t("p",{children:h?t(we,{children:"You've already watched this movie."}):t(we,{children:["You've already watched"," ",t("strong",{children:["Season ",i," Episode ",f]}),". Would you like to continue?"]})}),t("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center",flexWrap:"wrap"},children:[t(De,{variant:"secondary",onClick:Nr,children:"Replay"}),x!=null?t(De,{onClick:Gn,children:["Watch EP ",x]}):ge!=null?t(De,{onClick:Xn,children:["Start Season ",ge]}):null]})]})}),t(Rn,{isOpen:Ke,onClose:()=>tt(!1),title:h?"Movie Completed!":ge!=null?"Season Complete!":"Show Completed!",children:t("div",{style:{padding:"1rem",textAlign:"center"},children:[t(R,{name:"check-circle",size:48,style:{color:"var(--accent-lighter)",marginBottom:"0.5rem"}}),t("p",{style:{fontSize:"1.1rem",fontWeight:600},children:mr}),t("p",{style:{color:"var(--text-secondary)"},children:h?"You finished this movie!":ge!=null?`You finished Season ${i}.`:"Congratulations! You finished all available episodes."}),t("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center",flexWrap:"wrap"},children:[t(De,{variant:"secondary",onClick:()=>tt(!1),children:"Close"}),ge!=null?t(De,{onClick:Xn,children:["Start Season ",ge]}):t(we,{children:[t(De,{onClick:()=>{tt(!1),tn()},children:"Back to Details"}),dt&&t(De,{onClick:wr,disabled:Je.isPending,children:Je.isPending?"Saving...":"Move to Completed"})]})]})]})}),!r&&t("div",{className:v.statusMsg,children:[t(R,{name:"spinner",className:v.spinner})," Loading..."]})]})]})};export{Mo as default};