@serifpersia/dango 3.7.2 → 3.7.4

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 (66) hide show
  1. package/README.md +1 -1
  2. package/client/dist/assets/{AnimeCard-CoPx634q.js → AnimeCard-CBxkRKU-.js} +1 -1
  3. package/client/dist/assets/{AnimeInfo-COVCRujg.js → AnimeInfo-D3LmqzJo.js} +1 -1
  4. package/client/dist/assets/{AnimeInfoPage-BwlKpRXY.js → AnimeInfoPage-CeJHVkQ0.js} +2 -2
  5. package/client/dist/assets/{Asmr-nOUcDsWe.js → Asmr-CrHIKmJ4.js} +2 -2
  6. package/client/dist/assets/Asmr-Do89pEHG.css +1 -0
  7. package/client/dist/assets/{AsmrResetProgressModal-Mj1PYE2c.js → AsmrResetProgressModal-C13uw5lH.js} +1 -1
  8. package/client/dist/assets/{Home-wi0a_BDQ.js → Home-CC9XyO9O.js} +1 -1
  9. package/client/dist/assets/{Insights-MLCDyTnY.js → Insights-BZGAhYrz.js} +1 -1
  10. package/client/dist/assets/{LibraryListPage-CRqv737t.js → LibraryListPage-DosBFeR_.js} +1 -1
  11. package/client/dist/assets/{ListeningList-8dzhiDeb.js → ListeningList-nq279J8O.js} +1 -1
  12. package/client/dist/assets/{Manga-dkD-uWJk.js → Manga-DiCcXa9I.js} +1 -1
  13. package/client/dist/assets/{MangaInfoPage-nCeWZNcO.js → MangaInfoPage-sZn0qDxf.js} +1 -1
  14. package/client/dist/assets/{MangaReadPage-NdDNCyLg.js → MangaReadPage-ChgW4VO8.js} +1 -1
  15. package/client/dist/assets/{MangaResetProgressModal-C28AiLJl.js → MangaResetProgressModal-BkNHdClw.js} +1 -1
  16. package/client/dist/assets/{Mature-D5WSkhIJ.js → Mature-D7bJH6LQ.js} +1 -1
  17. package/client/dist/assets/{MatureConsentModal-BsdpNeXA.js → MatureConsentModal-B3u3RgAE.js} +1 -1
  18. package/client/dist/assets/MediaCard-B1llLoho.js +1 -0
  19. package/client/dist/assets/{MediaCard-B0PJStxp.css → MediaCard-CoyScn-7.css} +1 -1
  20. package/client/dist/assets/OptionListMenu-1QikgQ8d.js +1 -0
  21. package/client/dist/assets/Player-hVrgi0J1.js +56 -0
  22. package/client/dist/assets/PlayerSettings-CWc5Tf-B.js +1 -0
  23. package/client/dist/assets/{QueueOptionsButton-DNzKPzPw.js → QueueOptionsButton-Cpm6Jovo.js} +1 -1
  24. package/client/dist/assets/{QueueRail-BWcDVSHd.js → QueueRail-DpUQ2Ba2.js} +1 -1
  25. package/client/dist/assets/{ReadingList-zkFp3wpF.js → ReadingList-DMxkudSM.js} +1 -1
  26. package/client/dist/assets/{ResetProgressModal-BYNYqwwl.js → ResetProgressModal-6X8ciSFl.js} +1 -1
  27. package/client/dist/assets/{Search-yDP_wGJ1.js → Search-CbXvziWY.js} +1 -1
  28. package/client/dist/assets/Settings-BEZZSWsj.js +21 -0
  29. package/client/dist/assets/Settings-DYjRBgpE.css +1 -0
  30. package/client/dist/assets/{SkeletonGrid-CYJeh04P.js → SkeletonGrid-BDR-fKs1.js} +1 -1
  31. package/client/dist/assets/{Trackers-D2KUt71k.js → Trackers-DO0mA01O.js} +1 -1
  32. package/client/dist/assets/Tv-DP4rcV9T.js +4 -0
  33. package/client/dist/assets/{TvInfo-D_4QdgV4.js → TvInfo-WNJynk-5.js} +1 -1
  34. package/client/dist/assets/{TvPopup-DHXB5ZSF.js → TvPopup-Q9_MFJdx.js} +1 -1
  35. package/client/dist/assets/{TvSearch-COwVoGru.js → TvSearch-C-RBZ1iq.js} +1 -1
  36. package/client/dist/assets/{TvWatchlist-CU3r-NO5.js → TvWatchlist-BXE6yUS0.js} +1 -1
  37. package/client/dist/assets/{Watchlist-DHyuTLJG.js → Watchlist-7x__Rf-s.js} +1 -1
  38. package/client/dist/assets/{hls-DOAVt6Ry.js → hls-DIyfUbGZ.js} +1 -1
  39. package/client/dist/assets/{index-BLh_CXtu.js → index-D0DdVatn.js} +2 -2
  40. package/client/dist/assets/{libraryInvalidation-AzFLnbjH.js → libraryInvalidation-BFqNv8Cx.js} +1 -1
  41. package/client/dist/assets/playbackCompletion-IPHm9fp5.js +1 -0
  42. package/client/dist/assets/{useAnimeInfoData-MPNJXLaM.js → useAnimeInfoData-D_qedrui.js} +1 -1
  43. package/client/dist/assets/{useAsmr-2dFEmQD_.js → useAsmr-CrshwDPO.js} +1 -1
  44. package/client/dist/assets/{useAsmrPopup-N2vUf3Pw.js → useAsmrPopup-HwNC-ZRo.js} +1 -1
  45. package/client/dist/assets/{useMangaLibrary-B3Ni34a7.js → useMangaLibrary-BPSi9vcc.js} +1 -1
  46. package/client/dist/assets/{useMangaPopup-h8NHEPUk.js → useMangaPopup-DdueqAi5.js} +1 -1
  47. package/client/dist/assets/usePlaybackEnd-DLFOYx3Q.css +1 -0
  48. package/client/dist/assets/usePlaybackEnd-DjZq1szR.js +10 -0
  49. package/client/dist/assets/{useProviders-z8L8GKy0.js → useProviders-_ilIsyde.js} +1 -1
  50. package/client/dist/assets/{useTv-D4zQ1BsQ.js → useTv-C558DPdT.js} +1 -1
  51. package/client/dist/assets/{useTvLibrary-B4vcRzQc.js → useTvLibrary-CNQcDI7O.js} +1 -1
  52. package/client/dist/index.html +1 -1
  53. package/package.json +2 -2
  54. package/server/dist/server.js +2 -2
  55. package/server/package.json +1 -1
  56. package/client/dist/assets/Asmr-Dl1EZqaI.css +0 -1
  57. package/client/dist/assets/AvSyncCalibrator-BtUHM1mW.css +0 -1
  58. package/client/dist/assets/AvSyncCalibrator-C5GxpyPE.js +0 -10
  59. package/client/dist/assets/MediaCard-C1jNesfK.js +0 -1
  60. package/client/dist/assets/OptionListMenu-CIvW5WmO.js +0 -1
  61. package/client/dist/assets/Player-PGj8YYO8.js +0 -56
  62. package/client/dist/assets/PlayerSettings-CAYfF0sA.js +0 -1
  63. package/client/dist/assets/Settings-BEHII_8K.css +0 -1
  64. package/client/dist/assets/Settings-BpKwWesn.js +0 -21
  65. package/client/dist/assets/Tv-Ul3jFq-x.js +0 -4
  66. package/client/dist/assets/playbackCompletion-DuUs8u-8.js +0 -1
@@ -891,7 +891,7 @@ If you want to call this function on the server, see https://trpc.io/docs/v11/se
891
891
  WHERE p.rn = 1
892
892
  AND (l.status IS NULL OR l.status = 'Watching')
893
893
  ORDER BY p.updatedAt DESC, p.progressRowid DESC
894
- ${y.raw(r)}`)}};function Lgt(e){return String(e).toLowerCase()==="movie"?"movie":"tv"}var Mgt=()=>pe(e=>{let t=ye(e);return{tmdbId:t.tmdbId,mediaType:t.mediaType,id:t.id,title:t.title,poster:t.poster,backdrop:t.backdrop,year:t.year,overview:t.overview,status:t.status,adult:t.adult}}),Oye=At(om({db:e=>e.tvDb,write:rh,repo:gx,progress:{deleteByKey:(e,t)=>gu.deleteByKey(e,t),deleteMany:(e,t)=>gu.deleteMany(e,t)},statuses:Uye,defaultStatus:"Watching",add:{input:Mgt(),build:(e,t)=>{let r=Number(e.tmdbId);if(!r||!e.id&&!e.mediaType)throw it("tmdbId and mediaType are required");let n=Lgt(e.mediaType||(String(e.id).startsWith("movie:")?"movie":"tv")),i=e.id&&String(e.id).includes(":")?String(e.id):_ye(n,r);return{id:i,row:{id:i,tmdbId:r,mediaType:n,title:String(e.title||""),poster:String(e.poster||""),backdrop:e.backdrop?String(e.backdrop):void 0,year:e.year?String(e.year):void 0,overview:e.overview?String(e.overview):void 0,status:t,adult:e.adult===!0}}}}}));var Fgt=e=>rl(e,"tv_progress","tv_library","mediaId","COALESCE(l.adult, p.adult) = 1"),Ugt=()=>kd("mediaId"),_gt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode}}),Ogt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode,currentTime:t.currentTime,duration:t.duration,completed:t.completed,title:cA(t,"title"),poster:cA(t,"poster"),backdrop:cA(t,"backdrop"),year:cA(t,"year"),overview:cA(t,"overview"),tmdbId:t.tmdbId??null,mediaType:cA(t,"mediaType"),adult:t.adult??null}}),Pgt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode}}),cm=am({db:e=>e.tvDb,write:rh,repo:gu,keyField:"mediaId",byKeyInput:Ugt(),removeInput:Pgt(),normalizeKey:fx,removeOne:(e,t,r)=>r.season===void 0||r.episode===void 0?!1:(gu.deleteEpisode(e,t,Number(r.season),Number(r.episode)),!0),continueRows:(e,t)=>gu.getContinueWatching(e,t),continueSettings:{ignoreAdult:"tvIgnoreAdultContent",listOnly:"tvCwWatchlistOnly"},isAdult:e=>e.adult===1,watchlistStatus:"Watching",adultIds:Fgt}),Pye=At({getByMedia:cm.byKey,latest:ee.input(_gt()).query(async({ctx:e,input:t})=>{let r=fx(t.mediaId),n=parseInt(String(t.season),10),i=parseInt(String(t.episode),10);return Number.isFinite(n)&&Number.isFinite(i)?await gu.getEpisode(e.tvDb,r,n,i)||{currentTime:0,duration:0,completed:0}:await gu.getLatest(e.tvDb,r)||{currentTime:0,duration:0,completed:0}}),save:ee.input(Ogt()).mutation(async({ctx:e,input:t})=>{let r=fx(t.mediaId);if(!r)throw it("mediaId is required");let n=Math.max(Number(t.season)||1,1),i=Math.max(Number(t.episode)||1,1),s=Math.max(Number(t.currentTime)||0,0),o=Math.max(Number(t.duration)||0,0),a=o>0?Math.min(s,o):s,A=o>0&&a>=o*.8?o:a,u=Number(t.completed)===1||o>0&&A>=o*.8?1:0;return await rh(e.tvDb,async c=>{await gu.upsert(c,{mediaId:String(r),season:Math.round(n),episode:Math.round(i),currentTime:A,duration:o,completed:u,title:t.title??null,poster:t.poster??null,backdrop:t.backdrop??null,year:t.year??null,overview:t.overview??null,tmdbId:t.tmdbId!=null?Number(t.tmdbId):null,mediaType:t.mediaType??null,adult:t.adult!=null?Number(t.adult):null}),await gx.touchProgress(c,String(r),{season:Math.round(n),episode:Math.round(i)})}),{success:!0}}),remove:cm.remove,removeMany:cm.removeMany,continueWatching:cm.continue,adultCount:cm.adultCount,purgeAdult:cm.purgeAdult});async function Hgt(e,t,r){let n={...r};if(n.title&&n.imdbId&&n.year)return n;let i=await Lse(e,t);return i&&(n.title||(n.title=i.title||i.name||""),n.year||(n.year=(i.release_date||i.first_air_date||"").split("-")[0]||""),n.imdbId||(n.imdbId=i.external_ids?.imdb_id||i.imdb_id||""),e==="tv"&&i.number_of_seasons&&(n.totalSeasons=String(i.number_of_seasons))),n}function J5(e,t){return{id:e.id,title:e.title||e.name||"",year:(e.release_date||e.first_air_date||"").split("-")[0],type:t,image:e.poster_path?`${Xl}/w500${e.poster_path}`:"",backdrop:e.backdrop_path?`${Xl}/w780${e.backdrop_path}`:"",overview:e.overview||"",vote_average:e.vote_average||0,adult:e.adult===!0,genre_ids:e.genre_ids||[]}}var Ggt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"q");n!==void 0&&(r.q=n),t.page!==void 0&&(r.page=Ri(t));let i=le(t,"type");i!==void 0&&(r.type=i);let s=le(t,"genre");s!==void 0&&(r.genre=s);let o=le(t,"year");o!==void 0&&(r.year=o);let a=le(t,"sortBy");return a!==void 0&&(r.sortBy=a),r}),Ygt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"mediaType");n!==void 0&&(r.mediaType=n);let i=le(t,"timeWindow");return i!==void 0&&(r.timeWindow=i),t.page!==void 0&&(r.page=Ri(t)),r}),Vgt=()=>pe(e=>{let t=ye(e);return{type:gt(t,"type"),id:uA(t,"id")}}),qgt=()=>pe(e=>{let t=ye(e);return{id:uA(t,"id"),season:uA(t,"season")}}),Wgt=()=>pe(e=>{let t=ye(e),r={type:gt(t,"type"),tmdbId:uA(t,"tmdbId")},n=le(t,"season");n!==void 0&&(r.season=n);let i=le(t,"episode");return i!==void 0&&(r.episode=i),r}),Jgt=()=>pe(e=>{let t=ye(e),r={provider:gt(t,"provider"),type:gt(t,"type"),tmdbId:uA(t,"tmdbId")};t.season!==void 0&&(r.season=$y(t,"season",1)),t.episode!==void 0&&(r.episode=$y(t,"episode",1));let n=le(t,"server");n!==void 0&&(r.server=n);let i=le(t,"title");i!==void 0&&(r.title=i);let s=le(t,"year");s!==void 0&&(r.year=s);let o=le(t,"imdbId");o!==void 0&&(r.imdbId=o);let a=le(t,"totalSeasons");return a!==void 0&&(r.totalSeasons=a),r}),Hye=At({search:ee.input(Ggt()).query(async({ctx:e,input:t})=>{let r=t.q||"",n=t.page||1,i=t.type||"multi",s=t.genre||"",o=t.year||"",a=t.sortBy||"popularity.desc",A=`tv-search-${r.toLowerCase()}-${n}-${i}-${s}-${o}-${a}`,u=e.apiCache.get(A);if(u)return u;try{let c=await Rse({query:r,page:n,type:i,genre:s,year:o,sortBy:a}),l;i==="tv"||i==="movie"?l=(c.results||[]).map(h=>J5(h,i)):l=(c.results||[]).filter(h=>h.media_type!=="person").map(h=>J5(h,h.media_type||"tv"));let d={results:l,total_results:c.total_results||0,total_pages:c.total_pages||0,page:c.page||n};return e.apiCache.set(A,d,1800),d}catch(c){throw c instanceof nt?c:yr(c.message)}}),trending:ee.input(Ygt()).query(async({ctx:e,input:t})=>{let r=t.mediaType||"all",n=t.timeWindow||"week",i=t.page||1,s=`tv-trending-${r}-${n}-${i}`,o=e.apiCache.get(s);if(o)return o;try{let a=await xse(r,n,i),u={results:(a.results||[]).filter(c=>c.media_type!=="person").map(c=>J5(c,c.media_type||"tv")),total_results:a.total_results||0,total_pages:a.total_pages||0,page:a.page||i};return e.apiCache.set(s,u,3600),u}catch(a){throw a instanceof nt?a:yr(a.message)}}),details:ee.input(Vgt()).query(async({input:e})=>{let t=e.type,r=e.id;try{let n=await vse(t,r),i={id:n.id,imdb_id:n.external_ids?.imdb_id||n.imdb_id||null,title:n.title||n.name,overview:n.overview,vote_average:n.vote_average,year:(n.release_date||n.first_air_date||"").split("-")[0],poster:n.poster_path?`${Xl}/w500${n.poster_path}`:"",backdrop:n.backdrop_path?`${Xl}/original${n.backdrop_path}`:"",adult:n.adult===!0};return t==="tv"&&(i.seasons=(n.seasons||[]).filter(s=>s.season_number>0).map(s=>({season_number:s.season_number,episode_count:s.episode_count})),i.number_of_seasons=n.number_of_seasons),i}catch(n){throw n instanceof nt?n:yr(n.message)}}),episodes:ee.input(qgt()).query(async({input:e})=>{let t=e.id,r=e.season;try{return{episodes:(await kse(t,r)).map(i=>({episode_number:i.episode_number,name:i.name,vote_average:i.vote_average,overview:i.overview,still_path:i.still_path}))}}catch(n){throw n instanceof nt?n:yr(n.message)}}),subtitles:ee.input(Wgt()).query(async({ctx:e,input:t})=>{let r=t.type,n=t.tmdbId,i=parseInt(n,10);if(!i)return{subtitles:[]};let s=r==="movie"?"movie":"tv",o=t.season||"1",a=t.episode||"1",A=s==="tv"?`tv-subs-${i}-${o}-${a}`:`tv-subs-${i}-movie`,u=e.apiCache.get(A);if(u)return u;try{let c=s==="tv"?`https://subtitles.vidy.st/search?id=${i}&season=${encodeURIComponent(o)}&episode=${encodeURIComponent(a)}`:`https://subtitles.vidy.st/search?id=${i}`,l=await Sr(c,{headers:{"User-Agent":"Mozilla/5.0"}},{timeoutMs:1e4});if(!l.ok)return{subtitles:[]};let d=await Vt(l),f={subtitles:(Array.isArray(d)?d:[]).filter(g=>typeof g.url=="string"&&g.url.startsWith("https://")).map(g=>({language:String(g.language||"en"),label:String(g.display||g.language||"Unknown"),url:String(g.url),trusted:g.isTrusted===!0,hi:g.isHearingImpaired===!0,downloads:Number(g.downloadCount)||0,media:String(g.media||g.release||"")})).sort((g,p)=>{let m=g.language.toLowerCase().startsWith("en")?0:1,I=p.language.toLowerCase().startsWith("en")?0:1;return m!==I?m-I:g.trusted!==p.trusted?g.trusted?-1:1:p.downloads-g.downloads}).slice(0,50)};return e.apiCache.set(A,f,3600),f}catch(c){return U.warn({err:c,mediaType:s,tmdbId:n},"Subtitle fetch failed"),{subtitles:[]}}}),sources:ee.input(Jgt()).query(async({ctx:e,input:t})=>{let r=t.provider,n=t.type,i=t.tmdbId,s=n==="movie"?"movie":"tv",o=parseInt(i,10);if(!o)throw it("Bad tmdb id");let a=e.getTvProvider(String(r).toLowerCase());if(!a||typeof a.getSources!="function")throw it(`Unknown TV provider ${r}`);let A=t.season||1,u=t.episode||1,c=t.server,l=await Hgt(s,o,{title:t.title||"",year:t.year||"",imdbId:t.imdbId||"",totalSeasons:t.totalSeasons||"1"}),d=tx({tmdbId:o,type:s,season:A,episode:u,title:l.title,year:l.year,imdbId:l.imdbId,totalSeasons:parseInt(l.totalSeasons,10)||1});try{let h=await a.getSources(d,c);return!h||!Array.isArray(h.sources)||h.sources.length===0?{provider:a.name,server:h?.server||c,sources:[],audioTracks:[],valid:!1,error:"No sources found"}:{provider:a.name,server:h.server||c,servers:h.servers,embedUrl:h.embedUrl,sources:h.sources,audioTracks:h.audioTracks||[],subtitles:h.subtitles||[],referer:h.referer||"",valid:!0}}catch(h){throw yr(h.message)}})});async function jn(e,t,r,n,i){let s=e.apiCache.get(t);if(s)return s;let o=await n();return(!i||i(o))&&(r!==void 0?e.apiCache.set(t,o,r):e.apiCache.set(t,o)),o}var Gye=["safe"];function Yye(e){let t=e.mature==="1",r=String(e.rating||"safe").split(",").map(i=>i.trim().toLowerCase()).filter(i=>["safe","suggestive","erotica","pornographic"].includes(i));if(!t)return Gye;let n=[...new Set(r)];return n.length>0?n:Gye}function $5(e,t){return e.getMangaProvider(t.toLowerCase())}async function Vye(e,t,r){let n=t?[t]:e.getCatalog().filter(i=>i.kind==="manga"&&i.loaded).map(i=>i.id);for(let i of n){let s=$5(e,i);if(!s)continue;let o=await s.search({query:r.query,page:r.page,limit:r.limit,sort:r.sort,status:r.status,type:r.type,ratings:r.ratings}),a=o?.items??[];if(a.length>0||t)return{items:a,hasNext:o?.hasNext??!1,provider:i}}return{items:[],hasNext:!1,provider:t||n[0]||""}}async function j5(e,t,r,n){let i=await jn(e,t,r,n,s=>{let o=s.status??200;return o>=200&&o<400});if(i.status!==void 0&&i.status!==200){let s=i.body?.error||"Request failed";throw i.status===400?it(s):i.status===404?Mc(s):yr(s)}return i.body}var jgt=()=>pe(e=>{let t=ye(e),r={};for(let n of["provider","q","sort","status","type","rating","mature"]){let i=le(t,n);i!==void 0&&(r[n]=i)}return t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,24,50)),r}),$gt=()=>pe(e=>{let t=ye(e),r={};for(let n of["provider","id","rating","mature"]){let i=le(t,n);i!==void 0&&(r[n]=i)}return r}),Kgt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"provider");n!==void 0&&(r.provider=n);let i=le(t,"id");return i!==void 0&&(r.id=i),r}),qye=At({trending:ee.query(async({ctx:e})=>{let t="route-manga-trending",r=e.apiCache.get(t);if(r)return r;let n=await Vye(e,"",{query:"",page:1,limit:6,sort:"followed",status:"",type:"",ratings:["safe","suggestive"]}),i=n.items.map(s=>({id:s.id,provider:n.provider,title:s.title,description:typeof s.description=="string"?s.description:"",tags:Array.isArray(s.genres)?s.genres:[],year:typeof s.year=="number"?s.year:null,status:typeof s.status=="string"?s.status:null,cover:s.cover??""}));return e.apiCache.set(t,i,600),i}),search:ee.input(jgt()).query(async({ctx:e,input:t})=>{let r=t.provider||"",n=t.q||"",i=t.page||1;return j5(e,`route-manga-search-${r}-${n}-${i}-${t.sort||""}-${t.status||""}-${t.type||""}-${t.rating||""}-${t.mature||""}`,300,async()=>{try{let s=Yye({rating:t.rating,mature:t.mature}),o=t.type||"",a=o==="doujinshi"&&t.mature!=="1"?"":o,A=await Vye(e,r,{query:n,page:i,limit:t.limit||24,sort:t.sort||"popular",status:t.status||"",type:a,ratings:s});return{body:{...A,items:A.items??[]}}}catch(s){return U.error({err:s},"[Manga] search failed"),{body:{items:[],hasNext:!1,provider:r}}}})}),info:ee.input($gt()).query(async({ctx:e,input:t})=>{let r=String(t.provider||""),n=String(t.id||""),i=String(t.rating||""),s=String(t.mature||"");return j5(e,`route-manga-info-${r}-${n}-${i}-${s}`,600,async()=>{try{if(!n)return{status:400,body:{error:"Missing id"}};let o=await $5(e,r)?.getDetail(n,Yye({rating:i,mature:s}));return o?{body:o}:{status:404,body:{error:"Not found"}}}catch(o){return U.error({err:o},"[Manga] info failed"),{status:500,body:{error:"Failed to load manga"}}}})}),pages:ee.input(Kgt()).query(async({ctx:e,input:t})=>{let r=String(t.provider||""),n=String(t.id||"");return j5(e,`route-manga-pages-${r}-${n}`,300,async()=>{try{return n?{body:{pages:await $5(e,r)?.getPages(n)??[]}}:{status:400,body:{error:"Missing id"}}}catch(i){return U.error({err:i},"[Manga] pages failed"),{body:{pages:[]}}}})})});var Xgt=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"q");n!==void 0&&(r.q=n),t.page!==void 0&&(r.page=parseInt(String(t.page),10)||1);let i=le(t,"sort");i!==void 0&&(r.sort=i);let s=le(t,"rating");return s!==void 0&&(r.rating=s),r}),zgt=()=>pe(e=>({rj:gt(ye(e),"rj")})),Wye=At({browse:ee.input(Xgt()).query(async({ctx:e,input:t})=>{let r=t.q||"",n=t.page||1,i=t.sort||"",s=t.rating||"";return jn(e,`route-asmr-browse-${r}-${n}-${i}-${s}-${i==="random"?Date.now():""}`,300,async()=>{try{let o=e.getJasmr();return o?await o.browse({query:r,page:n,sort:i,rating:s}):{shows:[],hasNext:!1}}catch(o){if(o.message==="AUTH_REQUIRED")throw Fc("jasmr");return U.error({err:o},"[Asmr] browse failed"),{shows:[],hasNext:!1}}})}),work:ee.input(zgt()).query(async({ctx:e,input:t})=>{let r=t.rj;return jn(e,`route-asmr-work-${r}`,1800,async()=>{try{let n=e.getJasmr();if(!n)return{rjCode:r,description:"",tracks:[],images:[],chapters:[]};let i=String(r).trim().toUpperCase(),s=await n.getEpisodes(i),[o,a,A]=await Promise.all([n.getStreamUrls(i,"1"),n.getImages(i),n.getChapters(i)]);return{rjCode:i,description:s?.description||"",tracks:o?.[0]?.links||[],images:a,chapters:A}}catch(n){if(n.message==="AUTH_REQUIRED")throw Fc("jasmr");return U.error({err:n,rj:r},"[Asmr] work fetch failed"),{rjCode:r,description:"",tracks:[],images:[],chapters:[]}}})})});var K5="tracker_anilist_token",eQ="tracker_anilist_sync_state";function X5(e){if(!(!e||e<=0))return new Date(e*1e3).toISOString().slice(0,19).replace("T"," ")}function Zgt(e){return["Watching","Completed","On-Hold","Dropped","Planned"].includes(e)?e:void 0}async function Jye(e,t){return(await hi(e,"SELECT COUNT(DISTINCT episodeNumber) as total FROM watched_episodes WHERE showId = ?",[t]))?.total??0}async function z5(e){let r=(await xe.getByKey(e,K5))?.value;if(!r)throw new Error("AniList is not connected. Please log in first.");let n=new ma(r),i=await n.getViewer(),s=await n.fetchUserAnimeList(i.id),o=await _t.getAll(e),a=await Td(e,eQ),A=new Map;for(let B of s)A.set(B.mediaId,B);let u=new Map;for(let B of o){let w=(await ct.getById(e,B.id))?.anilistId;w==null||!Number.isFinite(w)||String(w)!==String(B.id)||u.has(w)||u.set(w,B)}let c=$R(u.keys(),A.keys(),a),l={pushed:0,pulled:0,merged:0,unchanged:0,errors:[]},d=[],h=[],f=[],g={},p=[],m=[],I=[],C=Math.floor(Date.now()/1e3);for(let B of c){let Q=u.get(B),w=A.get(B),R=String(B);try{if(Q&&!w){if(a[R]&&s.length>0){p.push(R),g[R]=void 0,l.pulled++;continue}let N=await Jye(e,R);m.push({mediaId:B,status:Zgt(Q.status),progress:N}),g[R]={lastSyncedAt:C,remoteUpdatedAt:C},l.pushed++;continue}if(!Q&&w){if(a[R]){if(w.entryId){I.push({showId:R,entryId:w.entryId}),g[R]=void 0,l.pushed++;continue}g[R]=void 0,l.pushed++;continue}U.debug({mediaId:B,remoteStatus:w.status},"[AniList Sync] Remote only -> pulling to local");let N=w.title.english||w.title.romaji||`Anime #${B}`;d.push({id:R,name:N,thumbnail:w.coverImage??"",status:w.status,nativeName:w.title.native??"",englishName:w.title.english??"",type:"TV"}),h.push({id:R,name:N,thumbnail:w.coverImage,nativeName:w.title.native,englishName:w.title.english,episodeCount:w.totalEpisodes,anilistId:B,episodeDuration:w.episodeDuration}),w.progress>0&&f.push({showId:R,from:1,to:w.progress,updatedAt:w.updatedAt}),g[R]={lastSyncedAt:C,remoteUpdatedAt:w.updatedAt},l.pulled++;continue}if(!Q&&!w&&a[R]){g[R]=void 0;continue}if(Q&&w){let N=await Jye(e,R),T=a[R]?.lastSyncedAt??0,Y=w.updatedAt||0,P=Math.max(N,w.progress),O=N>w.progress,W=w.progress>N,{status:oe,pull:ue}=jR(Q.status,w.status,Y,T),Ce=w.status!==Q.status;O||!ue&&Ce?(m.push({mediaId:B,status:oe,progress:P}),oe!==Q.status&&d.push({id:R,name:Q.name,thumbnail:Q.thumbnail??"",status:oe,nativeName:Q.nativeName??"",englishName:Q.englishName??"",type:Q.type??""}),W&&f.push({showId:R,from:N+1,to:P,updatedAt:Y}),g[R]={lastSyncedAt:C,remoteUpdatedAt:C},l.merged++):ue||W?(oe!==Q.status&&d.push({id:R,name:Q.name,thumbnail:Q.thumbnail??"",status:oe,nativeName:Q.nativeName??"",englishName:Q.englishName??"",type:Q.type??""}),W&&f.push({showId:R,from:N+1,to:P,updatedAt:Y}),g[R]={lastSyncedAt:C,remoteUpdatedAt:Y},l.merged++):l.unchanged++}}catch(N){let T=N instanceof Error?N.message:String(N);U.warn({err:N,mediaId:B},"[AniList Sync] Entry failed"),l.errors.push(`${Q?.name??`Media ${B}`}: ${T}`)}}return(m.length>0||I.length>0||p.length>0)&&KR({totalDeletes:p.length+I.length,localItemCount:o.length,fetched:s.length,message:`AniList sync would delete ${p.length+I.length} shows but only ${s.length} were fetched. Aborting to protect your library - if you really removed that many shows on AniList, delete them locally first and sync again.`}),await XR(n,m,I),(d.length>0||h.length>0||f.length>0||p.length>0||Object.keys(g).length>0)&&await tt(e,async B=>{for(let w of d)await _t.upsert(B,w);for(let w of h)await ct.upsert(B,w);for(let w of f)for(let R=w.from;R<=w.to;R++)await Qr.insertIfMissing(B,{showId:w.showId,episodeNumber:String(R),watchedAt:X5(w.updatedAt)});for(let w of p)await _t.delete(B,w),await Qr.deleteByShow(B,w),await Zr.deleteByShow(B,w);let Q={...a};for(let[w,R]of Object.entries(g))R===void 0?delete Q[w]:Q[w]=R;await xe.upsert(B,eQ,JSON.stringify(Q))}),l}async function Z5(e,t,r=!1){let i=(await xe.getByKey(e,K5))?.value,s=new ma(i),o;if(i){let u=await s.getViewer();o=await s.fetchUserAnimeList(u.id)}else o=await s.fetchUserAnimeList(t);if(o.length===0)return 0;let a=Math.floor(Date.now()/1e3),A=await Td(e,eQ);return await tt(e,async u=>{r&&await xe.clearWatchlist(u);for(let c of o){let l=String(c.mediaId),d=c.title.english||c.title.romaji||`Anime #${c.mediaId}`;if(await _t.upsert(u,{id:l,name:d,thumbnail:c.coverImage??"",status:c.status,nativeName:c.title.native??"",englishName:c.title.english??"",type:"TV"}),await ct.upsert(u,{id:l,name:d,thumbnail:c.coverImage,nativeName:c.title.native,englishName:c.title.english,episodeCount:c.totalEpisodes,anilistId:c.mediaId}),c.progress>0)for(let h=1;h<=c.progress;h++)await Qr.insertIfMissing(u,{showId:l,episodeNumber:String(h),watchedAt:X5(c.updatedAt)});A[l]={lastSyncedAt:a,remoteUpdatedAt:c.updatedAt}}await xe.upsert(u,eQ,JSON.stringify(A))}),o.length}function jye(e){switch(e){case 1:return"Watching";case 2:return"Completed";case 3:return"On-Hold";case 4:return"Dropped";case 6:return"Planned";default:return null}}async function e0t(e){let t=await ys(e);if(t)return t.id;if(qi())try{let r=await ra({query:e,page:1,perPage:5});if(r.length>0)return r[0].id>0?r[0].id:null}catch{}return null}async function eG(e,t,r={}){let{erase:n=!1,useOfflineDb:i=!0,skipFallback:s=!1}=r,o=await mP(t);if(o.length===0)return 0;let a=[],A=[],u=[],c=[];for(let l of o){let d=jye(l.status);if(!d)continue;let h=i?pn.getByMalId(l.malId):null;if(h){let f=String(h.anilistId),g=h.title||l.titleEnglish||l.title||`MAL #${l.malId}`;a.push({id:f,name:g,thumbnail:h.thumbnail??l.imageUrl??void 0,status:d,englishName:l.titleEnglish??void 0,type:h.type??l.type??void 0}),(h.thumbnail||h.type||h.genres)&&A.push({id:f,thumbnail:h.thumbnail,type:h.type,genres:h.genres}),l.watchedEpisodes>0&&u.push({showId:f,progress:l.watchedEpisodes})}else c.push(l)}if(c.length>0&&!s)for(let d=0;d<c.length;d+=5){let h=c.slice(d,d+5);(await Promise.allSettled(h.map(async g=>{let p=await cc(g.malId).catch(()=>null);if(p?.anilistId)return p;let m=g.titleEnglish||g.title;if(!m)return null;let I=await e0t(m);return I?bi(String(I)).catch(()=>null):null}))).forEach((g,p)=>{if(g.status!=="fulfilled"||!g.value)return;let m=g.value,I=h[p],C=jye(I.status);if(!C)return;let B=m.anilistId?String(m.anilistId):m._id,Q=m.names?.english||m.names?.romaji||I.titleEnglish||I.title||`MAL #${I.malId}`;a.push({id:B,name:Q,thumbnail:m.thumbnail||I.imageUrl||void 0,status:C,englishName:I.titleEnglish??void 0,type:m.type??I.type??"TV"}),(m.thumbnail||m.type)&&A.push({id:B,thumbnail:m.thumbnail,type:m.type}),I.watchedEpisodes>0&&u.push({showId:B,progress:I.watchedEpisodes})})}return(a.length>0||n)&&await tt(e,async l=>{n&&await xe.clearWatchlist(l);for(let d of a)await _t.upsert(l,{id:d.id,name:d.name,thumbnail:d.thumbnail??"",status:d.status,nativeName:"",englishName:d.englishName??"",type:d.type??"TV"});for(let d of A)(d.thumbnail||d.type||d.genres)&&await ct.upsert(l,{id:d.id,thumbnail:d.thumbnail,type:d.type,genres:d.genres});for(let d of u)for(let h=1;h<=d.progress;h++)await Qr.insertIfMissing(l,{showId:d.showId,episodeNumber:String(h)})}),a.length}var tG="tracker_anilist_token",rG="tracker_anilist_user";function tQ(e){return e==null?{}:ye(e)}var t0t=()=>pe(e=>{let t=tQ(e);return{token:t.token,code:t.code,redirectUri:t.redirectUri}}),r0t=()=>pe(e=>({provider:tQ(e).provider})),nG=()=>pe(e=>{let t=tQ(e);return{username:t.username,erase:t.erase}}),n0t=()=>pe(e=>{let t=tQ(e);return{username:t.username,erase:t.erase,useOfflineDb:t.useOfflineDb,skipFallback:t.skipFallback}}),i0t=()=>pe(e=>({direction:tQ(e).direction}));function $ye(e){return e.includes("private")||e.includes("not found")?Mc(e):e.includes("blocked")||e.includes("HTTP 429")?PBe(e):yr(e)}var Kye=At({status:ee.query(async({ctx:e})=>{try{let t=await xe.getByKey(e.db,tG),r=await xe.getByKey(e.db,rG),n=null;if(r?.value)try{n=JSON.parse(r.value)}catch(i){U.warn({err:i},"The stored tracker user is not valid json"),n=null}return{anilist:{connected:!!t?.value,user:n}}}catch{throw yr("Failed to read tracker status")}}),anilistAuth:ee.input(t0t()).mutation(async({ctx:e,input:t})=>{let r=typeof t.token=="string"?t.token.trim():"";if(!r)throw it("Access token is required");try{let i=await new ma(r).getViewer();return await tt(e.db,async s=>{await xe.upsert(s,tG,r),await xe.upsert(s,rG,JSON.stringify(i))}),{success:!0,user:i}}catch(n){throw GBe(n instanceof Error?n.message:"Authentication failed")}}),anilistDisconnect:ee.mutation(async({ctx:e})=>{try{return await tt(e.db,async t=>{await xe.upsert(t,tG,""),await xe.upsert(t,rG,"")}),{success:!0}}catch{throw yr("Failed to disconnect")}}),sync:ee.input(r0t()).mutation(async({ctx:e,input:t})=>{let{provider:r="anilist"}=t;if(r!=="anilist")throw it(`Provider "${r}" is not supported yet`);try{return{success:!0,summary:await z5(e.db)}}catch(n){throw yr(n instanceof Error?n.message:"Sync failed")}}),anilistImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{return{success:!0,count:await Z5(e.db,r.trim(),n===!0)}}catch(i){throw yr(i instanceof Error?i.message:"Import failed")}}),malImport:ee.input(n0t()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n,useOfflineDb:i,skipFallback:s}=t;if(!r||typeof r!="string")throw it("MAL username is required");try{return{success:!0,count:await eG(e.db,r.trim(),{erase:n===!0,useOfflineDb:i!==!1,skipFallback:s===!0})}}catch(o){throw $ye(o instanceof Error?o.message:"Import failed")}}),mangaSync:ee.input(i0t()).mutation(async({ctx:e,input:t})=>{let{direction:r}=t;try{let n=e.mangaDb;if(!n||n.isClosedCheck())throw vd("Manga database is not ready");let i=r==="pull-only"?"pull-only":"two-way",s=await p5(e.db,n,{direction:i});return{success:!0,summary:s.summary,details:s.details,direction:i}}catch(n){throw n instanceof nt?n:yr(n instanceof Error?n.message:"Manga sync failed")}}),mangaImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{let i=e.mangaDb;if(!i||i.isClosedCheck())throw vd("Manga database is not ready");return{success:!0,count:await m5(e.db,i,r.trim(),n===!0)}}catch(i){throw i instanceof nt?i:yr(i instanceof Error?i.message:"Import failed")}}),mangaMalImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{let i=e.mangaDb;if(!i||i.isClosedCheck())throw vd("Manga database is not ready");return{success:!0,...await I5(e.db,i,r.trim(),n===!0)}}catch(i){throw i instanceof nt?i:$ye(i instanceof Error?i.message:"Import failed")}})});var Ms={getCoreStats:async e=>(await te(e).all(y`
894
+ ${y.raw(r)}`)}};function Lgt(e){return String(e).toLowerCase()==="movie"?"movie":"tv"}var Mgt=()=>pe(e=>{let t=ye(e);return{tmdbId:t.tmdbId,mediaType:t.mediaType,id:t.id,title:t.title,poster:t.poster,backdrop:t.backdrop,year:t.year,overview:t.overview,status:t.status,adult:t.adult}}),Oye=At(om({db:e=>e.tvDb,write:rh,repo:gx,progress:{deleteByKey:(e,t)=>gu.deleteByKey(e,t),deleteMany:(e,t)=>gu.deleteMany(e,t)},statuses:Uye,defaultStatus:"Watching",add:{input:Mgt(),build:(e,t)=>{let r=Number(e.tmdbId);if(!r||!e.id&&!e.mediaType)throw it("tmdbId and mediaType are required");let n=Lgt(e.mediaType||(String(e.id).startsWith("movie:")?"movie":"tv")),i=e.id&&String(e.id).includes(":")?String(e.id):_ye(n,r);return{id:i,row:{id:i,tmdbId:r,mediaType:n,title:String(e.title||""),poster:String(e.poster||""),backdrop:e.backdrop?String(e.backdrop):void 0,year:e.year?String(e.year):void 0,overview:e.overview?String(e.overview):void 0,status:t,adult:e.adult===!0}}}}}));var Fgt=e=>rl(e,"tv_progress","tv_library","mediaId","COALESCE(l.adult, p.adult) = 1"),Ugt=()=>kd("mediaId"),_gt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode}}),Ogt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode,currentTime:t.currentTime,duration:t.duration,completed:t.completed,title:cA(t,"title"),poster:cA(t,"poster"),backdrop:cA(t,"backdrop"),year:cA(t,"year"),overview:cA(t,"overview"),tmdbId:t.tmdbId??null,mediaType:cA(t,"mediaType"),adult:t.adult??null}}),Pgt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode}}),cm=am({db:e=>e.tvDb,write:rh,repo:gu,keyField:"mediaId",byKeyInput:Ugt(),removeInput:Pgt(),normalizeKey:fx,removeOne:(e,t,r)=>r.season===void 0||r.episode===void 0?!1:(gu.deleteEpisode(e,t,Number(r.season),Number(r.episode)),!0),continueRows:(e,t)=>gu.getContinueWatching(e,t),continueSettings:{ignoreAdult:"tvIgnoreAdultContent",listOnly:"tvCwWatchlistOnly"},isAdult:e=>e.adult===1,watchlistStatus:"Watching",adultIds:Fgt}),Pye=At({getByMedia:cm.byKey,latest:ee.input(_gt()).query(async({ctx:e,input:t})=>{let r=fx(t.mediaId),n=parseInt(String(t.season),10),i=parseInt(String(t.episode),10);return Number.isFinite(n)&&Number.isFinite(i)?await gu.getEpisode(e.tvDb,r,n,i)||{currentTime:0,duration:0,completed:0}:await gu.getLatest(e.tvDb,r)||{currentTime:0,duration:0,completed:0}}),save:ee.input(Ogt()).mutation(async({ctx:e,input:t})=>{let r=fx(t.mediaId);if(!r)throw it("mediaId is required");let n=Math.max(Number(t.season)||1,1),i=Math.max(Number(t.episode)||1,1),s=Math.max(Number(t.currentTime)||0,0),o=Math.max(Number(t.duration)||0,0),a=o>0?Math.min(s,o):s,A=Number(t.completed)===1||o>0&&a>=o*.8?1:0;return await rh(e.tvDb,async u=>{await gu.upsert(u,{mediaId:String(r),season:Math.round(n),episode:Math.round(i),currentTime:a,duration:o,completed:A,title:t.title??null,poster:t.poster??null,backdrop:t.backdrop??null,year:t.year??null,overview:t.overview??null,tmdbId:t.tmdbId!=null?Number(t.tmdbId):null,mediaType:t.mediaType??null,adult:t.adult!=null?Number(t.adult):null}),await gx.touchProgress(u,String(r),{season:Math.round(n),episode:Math.round(i)})}),{success:!0}}),remove:cm.remove,removeMany:cm.removeMany,continueWatching:cm.continue,adultCount:cm.adultCount,purgeAdult:cm.purgeAdult});async function Hgt(e,t,r){let n={...r};if(n.title&&n.imdbId&&n.year)return n;let i=await Lse(e,t);return i&&(n.title||(n.title=i.title||i.name||""),n.year||(n.year=(i.release_date||i.first_air_date||"").split("-")[0]||""),n.imdbId||(n.imdbId=i.external_ids?.imdb_id||i.imdb_id||""),e==="tv"&&i.number_of_seasons&&(n.totalSeasons=String(i.number_of_seasons))),n}function J5(e,t){return{id:e.id,title:e.title||e.name||"",year:(e.release_date||e.first_air_date||"").split("-")[0],type:t,image:e.poster_path?`${Xl}/w500${e.poster_path}`:"",backdrop:e.backdrop_path?`${Xl}/w780${e.backdrop_path}`:"",overview:e.overview||"",vote_average:e.vote_average||0,adult:e.adult===!0,genre_ids:e.genre_ids||[]}}var Ggt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"q");n!==void 0&&(r.q=n),t.page!==void 0&&(r.page=Ri(t));let i=le(t,"type");i!==void 0&&(r.type=i);let s=le(t,"genre");s!==void 0&&(r.genre=s);let o=le(t,"year");o!==void 0&&(r.year=o);let a=le(t,"sortBy");return a!==void 0&&(r.sortBy=a),r}),Ygt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"mediaType");n!==void 0&&(r.mediaType=n);let i=le(t,"timeWindow");return i!==void 0&&(r.timeWindow=i),t.page!==void 0&&(r.page=Ri(t)),r}),Vgt=()=>pe(e=>{let t=ye(e);return{type:gt(t,"type"),id:uA(t,"id")}}),qgt=()=>pe(e=>{let t=ye(e);return{id:uA(t,"id"),season:uA(t,"season")}}),Wgt=()=>pe(e=>{let t=ye(e),r={type:gt(t,"type"),tmdbId:uA(t,"tmdbId")},n=le(t,"season");n!==void 0&&(r.season=n);let i=le(t,"episode");return i!==void 0&&(r.episode=i),r}),Jgt=()=>pe(e=>{let t=ye(e),r={provider:gt(t,"provider"),type:gt(t,"type"),tmdbId:uA(t,"tmdbId")};t.season!==void 0&&(r.season=$y(t,"season",1)),t.episode!==void 0&&(r.episode=$y(t,"episode",1));let n=le(t,"server");n!==void 0&&(r.server=n);let i=le(t,"title");i!==void 0&&(r.title=i);let s=le(t,"year");s!==void 0&&(r.year=s);let o=le(t,"imdbId");o!==void 0&&(r.imdbId=o);let a=le(t,"totalSeasons");return a!==void 0&&(r.totalSeasons=a),r}),Hye=At({search:ee.input(Ggt()).query(async({ctx:e,input:t})=>{let r=t.q||"",n=t.page||1,i=t.type||"multi",s=t.genre||"",o=t.year||"",a=t.sortBy||"popularity.desc",A=`tv-search-${r.toLowerCase()}-${n}-${i}-${s}-${o}-${a}`,u=e.apiCache.get(A);if(u)return u;try{let c=await Rse({query:r,page:n,type:i,genre:s,year:o,sortBy:a}),l;i==="tv"||i==="movie"?l=(c.results||[]).map(h=>J5(h,i)):l=(c.results||[]).filter(h=>h.media_type!=="person").map(h=>J5(h,h.media_type||"tv"));let d={results:l,total_results:c.total_results||0,total_pages:c.total_pages||0,page:c.page||n};return e.apiCache.set(A,d,1800),d}catch(c){throw c instanceof nt?c:yr(c.message)}}),trending:ee.input(Ygt()).query(async({ctx:e,input:t})=>{let r=t.mediaType||"all",n=t.timeWindow||"week",i=t.page||1,s=`tv-trending-${r}-${n}-${i}`,o=e.apiCache.get(s);if(o)return o;try{let a=await xse(r,n,i),u={results:(a.results||[]).filter(c=>c.media_type!=="person").map(c=>J5(c,c.media_type||"tv")),total_results:a.total_results||0,total_pages:a.total_pages||0,page:a.page||i};return e.apiCache.set(s,u,3600),u}catch(a){throw a instanceof nt?a:yr(a.message)}}),details:ee.input(Vgt()).query(async({input:e})=>{let t=e.type,r=e.id;try{let n=await vse(t,r),i={id:n.id,imdb_id:n.external_ids?.imdb_id||n.imdb_id||null,title:n.title||n.name,overview:n.overview,vote_average:n.vote_average,year:(n.release_date||n.first_air_date||"").split("-")[0],poster:n.poster_path?`${Xl}/w500${n.poster_path}`:"",backdrop:n.backdrop_path?`${Xl}/original${n.backdrop_path}`:"",adult:n.adult===!0};return t==="tv"&&(i.seasons=(n.seasons||[]).filter(s=>s.season_number>0).map(s=>({season_number:s.season_number,episode_count:s.episode_count})),i.number_of_seasons=n.number_of_seasons),i}catch(n){throw n instanceof nt?n:yr(n.message)}}),episodes:ee.input(qgt()).query(async({input:e})=>{let t=e.id,r=e.season;try{return{episodes:(await kse(t,r)).map(i=>({episode_number:i.episode_number,name:i.name,vote_average:i.vote_average,overview:i.overview,still_path:i.still_path}))}}catch(n){throw n instanceof nt?n:yr(n.message)}}),subtitles:ee.input(Wgt()).query(async({ctx:e,input:t})=>{let r=t.type,n=t.tmdbId,i=parseInt(n,10);if(!i)return{subtitles:[]};let s=r==="movie"?"movie":"tv",o=t.season||"1",a=t.episode||"1",A=s==="tv"?`tv-subs-${i}-${o}-${a}`:`tv-subs-${i}-movie`,u=e.apiCache.get(A);if(u)return u;try{let c=s==="tv"?`https://subtitles.vidy.st/search?id=${i}&season=${encodeURIComponent(o)}&episode=${encodeURIComponent(a)}`:`https://subtitles.vidy.st/search?id=${i}`,l=await Sr(c,{headers:{"User-Agent":"Mozilla/5.0"}},{timeoutMs:1e4});if(!l.ok)return{subtitles:[]};let d=await Vt(l),f={subtitles:(Array.isArray(d)?d:[]).filter(g=>typeof g.url=="string"&&g.url.startsWith("https://")).map(g=>({language:String(g.language||"en"),label:String(g.display||g.language||"Unknown"),url:String(g.url),trusted:g.isTrusted===!0,hi:g.isHearingImpaired===!0,downloads:Number(g.downloadCount)||0,media:String(g.media||g.release||"")})).sort((g,p)=>{let m=g.language.toLowerCase().startsWith("en")?0:1,I=p.language.toLowerCase().startsWith("en")?0:1;return m!==I?m-I:g.trusted!==p.trusted?g.trusted?-1:1:p.downloads-g.downloads}).slice(0,50)};return e.apiCache.set(A,f,3600),f}catch(c){return U.warn({err:c,mediaType:s,tmdbId:n},"Subtitle fetch failed"),{subtitles:[]}}}),sources:ee.input(Jgt()).query(async({ctx:e,input:t})=>{let r=t.provider,n=t.type,i=t.tmdbId,s=n==="movie"?"movie":"tv",o=parseInt(i,10);if(!o)throw it("Bad tmdb id");let a=e.getTvProvider(String(r).toLowerCase());if(!a||typeof a.getSources!="function")throw it(`Unknown TV provider ${r}`);let A=t.season||1,u=t.episode||1,c=t.server,l=await Hgt(s,o,{title:t.title||"",year:t.year||"",imdbId:t.imdbId||"",totalSeasons:t.totalSeasons||"1"}),d=tx({tmdbId:o,type:s,season:A,episode:u,title:l.title,year:l.year,imdbId:l.imdbId,totalSeasons:parseInt(l.totalSeasons,10)||1});try{let h=await a.getSources(d,c);return!h||!Array.isArray(h.sources)||h.sources.length===0?{provider:a.name,server:h?.server||c,sources:[],audioTracks:[],valid:!1,error:"No sources found"}:{provider:a.name,server:h.server||c,servers:h.servers,embedUrl:h.embedUrl,sources:h.sources,audioTracks:h.audioTracks||[],subtitles:h.subtitles||[],referer:h.referer||"",valid:!0}}catch(h){throw yr(h.message)}})});async function jn(e,t,r,n,i){let s=e.apiCache.get(t);if(s)return s;let o=await n();return(!i||i(o))&&(r!==void 0?e.apiCache.set(t,o,r):e.apiCache.set(t,o)),o}var Gye=["safe"];function Yye(e){let t=e.mature==="1",r=String(e.rating||"safe").split(",").map(i=>i.trim().toLowerCase()).filter(i=>["safe","suggestive","erotica","pornographic"].includes(i));if(!t)return Gye;let n=[...new Set(r)];return n.length>0?n:Gye}function $5(e,t){return e.getMangaProvider(t.toLowerCase())}async function Vye(e,t,r){let n=t?[t]:e.getCatalog().filter(i=>i.kind==="manga"&&i.loaded).map(i=>i.id);for(let i of n){let s=$5(e,i);if(!s)continue;let o=await s.search({query:r.query,page:r.page,limit:r.limit,sort:r.sort,status:r.status,type:r.type,ratings:r.ratings}),a=o?.items??[];if(a.length>0||t)return{items:a,hasNext:o?.hasNext??!1,provider:i}}return{items:[],hasNext:!1,provider:t||n[0]||""}}async function j5(e,t,r,n){let i=await jn(e,t,r,n,s=>{let o=s.status??200;return o>=200&&o<400});if(i.status!==void 0&&i.status!==200){let s=i.body?.error||"Request failed";throw i.status===400?it(s):i.status===404?Mc(s):yr(s)}return i.body}var jgt=()=>pe(e=>{let t=ye(e),r={};for(let n of["provider","q","sort","status","type","rating","mature"]){let i=le(t,n);i!==void 0&&(r[n]=i)}return t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,24,50)),r}),$gt=()=>pe(e=>{let t=ye(e),r={};for(let n of["provider","id","rating","mature"]){let i=le(t,n);i!==void 0&&(r[n]=i)}return r}),Kgt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"provider");n!==void 0&&(r.provider=n);let i=le(t,"id");return i!==void 0&&(r.id=i),r}),qye=At({trending:ee.query(async({ctx:e})=>{let t="route-manga-trending",r=e.apiCache.get(t);if(r)return r;let n=await Vye(e,"",{query:"",page:1,limit:6,sort:"followed",status:"",type:"",ratings:["safe","suggestive"]}),i=n.items.map(s=>({id:s.id,provider:n.provider,title:s.title,description:typeof s.description=="string"?s.description:"",tags:Array.isArray(s.genres)?s.genres:[],year:typeof s.year=="number"?s.year:null,status:typeof s.status=="string"?s.status:null,cover:s.cover??""}));return e.apiCache.set(t,i,600),i}),search:ee.input(jgt()).query(async({ctx:e,input:t})=>{let r=t.provider||"",n=t.q||"",i=t.page||1;return j5(e,`route-manga-search-${r}-${n}-${i}-${t.sort||""}-${t.status||""}-${t.type||""}-${t.rating||""}-${t.mature||""}`,300,async()=>{try{let s=Yye({rating:t.rating,mature:t.mature}),o=t.type||"",a=o==="doujinshi"&&t.mature!=="1"?"":o,A=await Vye(e,r,{query:n,page:i,limit:t.limit||24,sort:t.sort||"popular",status:t.status||"",type:a,ratings:s});return{body:{...A,items:A.items??[]}}}catch(s){return U.error({err:s},"[Manga] search failed"),{body:{items:[],hasNext:!1,provider:r}}}})}),info:ee.input($gt()).query(async({ctx:e,input:t})=>{let r=String(t.provider||""),n=String(t.id||""),i=String(t.rating||""),s=String(t.mature||"");return j5(e,`route-manga-info-${r}-${n}-${i}-${s}`,600,async()=>{try{if(!n)return{status:400,body:{error:"Missing id"}};let o=await $5(e,r)?.getDetail(n,Yye({rating:i,mature:s}));return o?{body:o}:{status:404,body:{error:"Not found"}}}catch(o){return U.error({err:o},"[Manga] info failed"),{status:500,body:{error:"Failed to load manga"}}}})}),pages:ee.input(Kgt()).query(async({ctx:e,input:t})=>{let r=String(t.provider||""),n=String(t.id||"");return j5(e,`route-manga-pages-${r}-${n}`,300,async()=>{try{return n?{body:{pages:await $5(e,r)?.getPages(n)??[]}}:{status:400,body:{error:"Missing id"}}}catch(i){return U.error({err:i},"[Manga] pages failed"),{body:{pages:[]}}}})})});var Xgt=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"q");n!==void 0&&(r.q=n),t.page!==void 0&&(r.page=parseInt(String(t.page),10)||1);let i=le(t,"sort");i!==void 0&&(r.sort=i);let s=le(t,"rating");return s!==void 0&&(r.rating=s),r}),zgt=()=>pe(e=>({rj:gt(ye(e),"rj")})),Wye=At({browse:ee.input(Xgt()).query(async({ctx:e,input:t})=>{let r=t.q||"",n=t.page||1,i=t.sort||"",s=t.rating||"";return jn(e,`route-asmr-browse-${r}-${n}-${i}-${s}-${i==="random"?Date.now():""}`,300,async()=>{try{let o=e.getJasmr();return o?await o.browse({query:r,page:n,sort:i,rating:s}):{shows:[],hasNext:!1}}catch(o){if(o.message==="AUTH_REQUIRED")throw Fc("jasmr");return U.error({err:o},"[Asmr] browse failed"),{shows:[],hasNext:!1}}})}),work:ee.input(zgt()).query(async({ctx:e,input:t})=>{let r=t.rj;return jn(e,`route-asmr-work-${r}`,1800,async()=>{try{let n=e.getJasmr();if(!n)return{rjCode:r,description:"",tracks:[],images:[],chapters:[]};let i=String(r).trim().toUpperCase(),s=await n.getEpisodes(i),[o,a,A]=await Promise.all([n.getStreamUrls(i,"1"),n.getImages(i),n.getChapters(i)]);return{rjCode:i,description:s?.description||"",tracks:o?.[0]?.links||[],images:a,chapters:A}}catch(n){if(n.message==="AUTH_REQUIRED")throw Fc("jasmr");return U.error({err:n,rj:r},"[Asmr] work fetch failed"),{rjCode:r,description:"",tracks:[],images:[],chapters:[]}}})})});var K5="tracker_anilist_token",eQ="tracker_anilist_sync_state";function X5(e){if(!(!e||e<=0))return new Date(e*1e3).toISOString().slice(0,19).replace("T"," ")}function Zgt(e){return["Watching","Completed","On-Hold","Dropped","Planned"].includes(e)?e:void 0}async function Jye(e,t){return(await hi(e,"SELECT COUNT(DISTINCT episodeNumber) as total FROM watched_episodes WHERE showId = ?",[t]))?.total??0}async function z5(e){let r=(await xe.getByKey(e,K5))?.value;if(!r)throw new Error("AniList is not connected. Please log in first.");let n=new ma(r),i=await n.getViewer(),s=await n.fetchUserAnimeList(i.id),o=await _t.getAll(e),a=await Td(e,eQ),A=new Map;for(let B of s)A.set(B.mediaId,B);let u=new Map;for(let B of o){let w=(await ct.getById(e,B.id))?.anilistId;w==null||!Number.isFinite(w)||String(w)!==String(B.id)||u.has(w)||u.set(w,B)}let c=$R(u.keys(),A.keys(),a),l={pushed:0,pulled:0,merged:0,unchanged:0,errors:[]},d=[],h=[],f=[],g={},p=[],m=[],I=[],C=Math.floor(Date.now()/1e3);for(let B of c){let Q=u.get(B),w=A.get(B),R=String(B);try{if(Q&&!w){if(a[R]&&s.length>0){p.push(R),g[R]=void 0,l.pulled++;continue}let N=await Jye(e,R);m.push({mediaId:B,status:Zgt(Q.status),progress:N}),g[R]={lastSyncedAt:C,remoteUpdatedAt:C},l.pushed++;continue}if(!Q&&w){if(a[R]){if(w.entryId){I.push({showId:R,entryId:w.entryId}),g[R]=void 0,l.pushed++;continue}g[R]=void 0,l.pushed++;continue}U.debug({mediaId:B,remoteStatus:w.status},"[AniList Sync] Remote only -> pulling to local");let N=w.title.english||w.title.romaji||`Anime #${B}`;d.push({id:R,name:N,thumbnail:w.coverImage??"",status:w.status,nativeName:w.title.native??"",englishName:w.title.english??"",type:"TV"}),h.push({id:R,name:N,thumbnail:w.coverImage,nativeName:w.title.native,englishName:w.title.english,episodeCount:w.totalEpisodes,anilistId:B,episodeDuration:w.episodeDuration}),w.progress>0&&f.push({showId:R,from:1,to:w.progress,updatedAt:w.updatedAt}),g[R]={lastSyncedAt:C,remoteUpdatedAt:w.updatedAt},l.pulled++;continue}if(!Q&&!w&&a[R]){g[R]=void 0;continue}if(Q&&w){let N=await Jye(e,R),T=a[R]?.lastSyncedAt??0,Y=w.updatedAt||0,P=Math.max(N,w.progress),O=N>w.progress,W=w.progress>N,{status:oe,pull:ue}=jR(Q.status,w.status,Y,T),Ce=w.status!==Q.status;O||!ue&&Ce?(m.push({mediaId:B,status:oe,progress:P}),oe!==Q.status&&d.push({id:R,name:Q.name,thumbnail:Q.thumbnail??"",status:oe,nativeName:Q.nativeName??"",englishName:Q.englishName??"",type:Q.type??""}),W&&f.push({showId:R,from:N+1,to:P,updatedAt:Y}),g[R]={lastSyncedAt:C,remoteUpdatedAt:C},l.merged++):ue||W?(oe!==Q.status&&d.push({id:R,name:Q.name,thumbnail:Q.thumbnail??"",status:oe,nativeName:Q.nativeName??"",englishName:Q.englishName??"",type:Q.type??""}),W&&f.push({showId:R,from:N+1,to:P,updatedAt:Y}),g[R]={lastSyncedAt:C,remoteUpdatedAt:Y},l.merged++):l.unchanged++}}catch(N){let T=N instanceof Error?N.message:String(N);U.warn({err:N,mediaId:B},"[AniList Sync] Entry failed"),l.errors.push(`${Q?.name??`Media ${B}`}: ${T}`)}}return(m.length>0||I.length>0||p.length>0)&&KR({totalDeletes:p.length+I.length,localItemCount:o.length,fetched:s.length,message:`AniList sync would delete ${p.length+I.length} shows but only ${s.length} were fetched. Aborting to protect your library - if you really removed that many shows on AniList, delete them locally first and sync again.`}),await XR(n,m,I),(d.length>0||h.length>0||f.length>0||p.length>0||Object.keys(g).length>0)&&await tt(e,async B=>{for(let w of d)await _t.upsert(B,w);for(let w of h)await ct.upsert(B,w);for(let w of f)for(let R=w.from;R<=w.to;R++)await Qr.insertIfMissing(B,{showId:w.showId,episodeNumber:String(R),watchedAt:X5(w.updatedAt)});for(let w of p)await _t.delete(B,w),await Qr.deleteByShow(B,w),await Zr.deleteByShow(B,w);let Q={...a};for(let[w,R]of Object.entries(g))R===void 0?delete Q[w]:Q[w]=R;await xe.upsert(B,eQ,JSON.stringify(Q))}),l}async function Z5(e,t,r=!1){let i=(await xe.getByKey(e,K5))?.value,s=new ma(i),o;if(i){let u=await s.getViewer();o=await s.fetchUserAnimeList(u.id)}else o=await s.fetchUserAnimeList(t);if(o.length===0)return 0;let a=Math.floor(Date.now()/1e3),A=await Td(e,eQ);return await tt(e,async u=>{r&&await xe.clearWatchlist(u);for(let c of o){let l=String(c.mediaId),d=c.title.english||c.title.romaji||`Anime #${c.mediaId}`;if(await _t.upsert(u,{id:l,name:d,thumbnail:c.coverImage??"",status:c.status,nativeName:c.title.native??"",englishName:c.title.english??"",type:"TV"}),await ct.upsert(u,{id:l,name:d,thumbnail:c.coverImage,nativeName:c.title.native,englishName:c.title.english,episodeCount:c.totalEpisodes,anilistId:c.mediaId}),c.progress>0)for(let h=1;h<=c.progress;h++)await Qr.insertIfMissing(u,{showId:l,episodeNumber:String(h),watchedAt:X5(c.updatedAt)});A[l]={lastSyncedAt:a,remoteUpdatedAt:c.updatedAt}}await xe.upsert(u,eQ,JSON.stringify(A))}),o.length}function jye(e){switch(e){case 1:return"Watching";case 2:return"Completed";case 3:return"On-Hold";case 4:return"Dropped";case 6:return"Planned";default:return null}}async function e0t(e){let t=await ys(e);if(t)return t.id;if(qi())try{let r=await ra({query:e,page:1,perPage:5});if(r.length>0)return r[0].id>0?r[0].id:null}catch{}return null}async function eG(e,t,r={}){let{erase:n=!1,useOfflineDb:i=!0,skipFallback:s=!1}=r,o=await mP(t);if(o.length===0)return 0;let a=[],A=[],u=[],c=[];for(let l of o){let d=jye(l.status);if(!d)continue;let h=i?pn.getByMalId(l.malId):null;if(h){let f=String(h.anilistId),g=h.title||l.titleEnglish||l.title||`MAL #${l.malId}`;a.push({id:f,name:g,thumbnail:h.thumbnail??l.imageUrl??void 0,status:d,englishName:l.titleEnglish??void 0,type:h.type??l.type??void 0}),(h.thumbnail||h.type||h.genres)&&A.push({id:f,thumbnail:h.thumbnail,type:h.type,genres:h.genres}),l.watchedEpisodes>0&&u.push({showId:f,progress:l.watchedEpisodes})}else c.push(l)}if(c.length>0&&!s)for(let d=0;d<c.length;d+=5){let h=c.slice(d,d+5);(await Promise.allSettled(h.map(async g=>{let p=await cc(g.malId).catch(()=>null);if(p?.anilistId)return p;let m=g.titleEnglish||g.title;if(!m)return null;let I=await e0t(m);return I?bi(String(I)).catch(()=>null):null}))).forEach((g,p)=>{if(g.status!=="fulfilled"||!g.value)return;let m=g.value,I=h[p],C=jye(I.status);if(!C)return;let B=m.anilistId?String(m.anilistId):m._id,Q=m.names?.english||m.names?.romaji||I.titleEnglish||I.title||`MAL #${I.malId}`;a.push({id:B,name:Q,thumbnail:m.thumbnail||I.imageUrl||void 0,status:C,englishName:I.titleEnglish??void 0,type:m.type??I.type??"TV"}),(m.thumbnail||m.type)&&A.push({id:B,thumbnail:m.thumbnail,type:m.type}),I.watchedEpisodes>0&&u.push({showId:B,progress:I.watchedEpisodes})})}return(a.length>0||n)&&await tt(e,async l=>{n&&await xe.clearWatchlist(l);for(let d of a)await _t.upsert(l,{id:d.id,name:d.name,thumbnail:d.thumbnail??"",status:d.status,nativeName:"",englishName:d.englishName??"",type:d.type??"TV"});for(let d of A)(d.thumbnail||d.type||d.genres)&&await ct.upsert(l,{id:d.id,thumbnail:d.thumbnail,type:d.type,genres:d.genres});for(let d of u)for(let h=1;h<=d.progress;h++)await Qr.insertIfMissing(l,{showId:d.showId,episodeNumber:String(h)})}),a.length}var tG="tracker_anilist_token",rG="tracker_anilist_user";function tQ(e){return e==null?{}:ye(e)}var t0t=()=>pe(e=>{let t=tQ(e);return{token:t.token,code:t.code,redirectUri:t.redirectUri}}),r0t=()=>pe(e=>({provider:tQ(e).provider})),nG=()=>pe(e=>{let t=tQ(e);return{username:t.username,erase:t.erase}}),n0t=()=>pe(e=>{let t=tQ(e);return{username:t.username,erase:t.erase,useOfflineDb:t.useOfflineDb,skipFallback:t.skipFallback}}),i0t=()=>pe(e=>({direction:tQ(e).direction}));function $ye(e){return e.includes("private")||e.includes("not found")?Mc(e):e.includes("blocked")||e.includes("HTTP 429")?PBe(e):yr(e)}var Kye=At({status:ee.query(async({ctx:e})=>{try{let t=await xe.getByKey(e.db,tG),r=await xe.getByKey(e.db,rG),n=null;if(r?.value)try{n=JSON.parse(r.value)}catch(i){U.warn({err:i},"The stored tracker user is not valid json"),n=null}return{anilist:{connected:!!t?.value,user:n}}}catch{throw yr("Failed to read tracker status")}}),anilistAuth:ee.input(t0t()).mutation(async({ctx:e,input:t})=>{let r=typeof t.token=="string"?t.token.trim():"";if(!r)throw it("Access token is required");try{let i=await new ma(r).getViewer();return await tt(e.db,async s=>{await xe.upsert(s,tG,r),await xe.upsert(s,rG,JSON.stringify(i))}),{success:!0,user:i}}catch(n){throw GBe(n instanceof Error?n.message:"Authentication failed")}}),anilistDisconnect:ee.mutation(async({ctx:e})=>{try{return await tt(e.db,async t=>{await xe.upsert(t,tG,""),await xe.upsert(t,rG,"")}),{success:!0}}catch{throw yr("Failed to disconnect")}}),sync:ee.input(r0t()).mutation(async({ctx:e,input:t})=>{let{provider:r="anilist"}=t;if(r!=="anilist")throw it(`Provider "${r}" is not supported yet`);try{return{success:!0,summary:await z5(e.db)}}catch(n){throw yr(n instanceof Error?n.message:"Sync failed")}}),anilistImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{return{success:!0,count:await Z5(e.db,r.trim(),n===!0)}}catch(i){throw yr(i instanceof Error?i.message:"Import failed")}}),malImport:ee.input(n0t()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n,useOfflineDb:i,skipFallback:s}=t;if(!r||typeof r!="string")throw it("MAL username is required");try{return{success:!0,count:await eG(e.db,r.trim(),{erase:n===!0,useOfflineDb:i!==!1,skipFallback:s===!0})}}catch(o){throw $ye(o instanceof Error?o.message:"Import failed")}}),mangaSync:ee.input(i0t()).mutation(async({ctx:e,input:t})=>{let{direction:r}=t;try{let n=e.mangaDb;if(!n||n.isClosedCheck())throw vd("Manga database is not ready");let i=r==="pull-only"?"pull-only":"two-way",s=await p5(e.db,n,{direction:i});return{success:!0,summary:s.summary,details:s.details,direction:i}}catch(n){throw n instanceof nt?n:yr(n instanceof Error?n.message:"Manga sync failed")}}),mangaImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{let i=e.mangaDb;if(!i||i.isClosedCheck())throw vd("Manga database is not ready");return{success:!0,count:await m5(e.db,i,r.trim(),n===!0)}}catch(i){throw i instanceof nt?i:yr(i instanceof Error?i.message:"Import failed")}}),mangaMalImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{let i=e.mangaDb;if(!i||i.isClosedCheck())throw vd("Manga database is not ready");return{success:!0,...await I5(e.db,i,r.trim(),n===!0)}}catch(i){throw i instanceof nt?i:$ye(i instanceof Error?i.message:"Import failed")}})});var Ms={getCoreStats:async e=>(await te(e).all(y`
895
895
  SELECT
896
896
  (SELECT SUM(
897
897
  CASE WHEN we.currentTime > 0 THEN we.currentTime
@@ -982,7 +982,7 @@ If you want to call this function on the server, see https://trpc.io/docs/v11/se
982
982
  (SELECT COUNT(*) FROM watched_episodes we WHERE we.showId = w.id) as episodesWatched,
983
983
  COALESCE(sm.popularityScore, 0) as popularityScore
984
984
  FROM watchlist w
985
- LEFT JOIN shows_meta sm ON sm.id = w.id`),getAllAnilistIds:e=>te(e).all(y`SELECT anilistId FROM shows_meta WHERE anilistId IS NOT NULL`)};function Xye(e,t,r){if(!e)return[];try{return e.startsWith("[")?JSON.parse(e):e.split(",").map(n=>n.trim())}catch(n){return U.warn({err:n,showId:t},`Failed to parse genres for ${r}`),[]}}async function zye(e){let[t,r,n,i,s,o,a,A]=await Promise.all([Ms.getCoreStats(e),Ms.getActivityGrid(e),Ms.getHourlyDist(e),Ms.getSeasonality(e),Ms.getAllWatches(e),Ms.getWatchedShowsMeta(e),Ms.getDroppedShows(e),Ms.getCompletionVelocities(e)]),u=r.length>0?Math.max(...r.map(C=>C.count)):0,c=[];if(s.length>0){let C=s[0].effectiveSeconds??s[0].currentTime;for(let B=1;B<s.length;B++){let Q=new Date(s[B-1].watchedAt).getTime(),R=new Date(s[B].watchedAt).getTime()-Q;Number.isFinite(R)&&R>0&&R<36e5?C+=s[B].effectiveSeconds??s[B].currentTime:(c.push(C),C=s[B].effectiveSeconds??s[B].currentTime)}c.push(C)}let l=c.length>0?Math.round(c.reduce((C,B)=>C+B,0)/c.length/60):0,d={},h=0,f=0;for(let C of o){let B=Xye(C.genres,C.id,"insights");for(let Q of B)d[Q]=(d[Q]||0)+1;if(C.popularityScore){let Q=C.popularityScore;Q>10&&(Q=Q/10),h+=Q,f++}}let g=Object.entries(d).sort((C,B)=>B[1]-C[1])[0]?.[0],m={Action:"Shonen Warrior",Romance:"Hopeless Romantic",Comedy:"Chaos Enjoyer","Slice of Life":"Vibe Seeker",Horror:"Fearless Watcher",Fantasy:"Isekai Traveller","Sci-Fi":"Future Scientist",Drama:"Feels Collector"}[g||""]||"Anime Enthusiast",I=A.length>0?Math.round(A.reduce((C,B)=>C+B.daysToFinish,0)/A.length):0;return{totalHours:Math.round((t?.totalSeconds||0)/3600),totalEpisodes:t?.totalEpisodes||0,totalAnime:t?.totalAnime||0,completedAnime:t?.completedCount||0,completionRate:t?.totalWatchlist>0?Math.round(t.completedCount/t.totalWatchlist*100):0,persona:m,bingeFactor:u,avgSessionMinutes:l,avgCompletionDays:I,popularityScore:f>0?Math.round(h/f):0,genreSplit:Object.entries(d).map(([C,B])=>({name:C,count:B})).sort((C,B)=>B.count-C.count).slice(0,8)||[],activityGrid:r||[],hourlyDist:Array.from({length:24},(C,B)=>{let Q=B.toString().padStart(2,"0");return{hour:Q,count:n?.find(w=>w.hour===Q)?.count||0}})||[],seasonality:Array.from({length:12},(C,B)=>{let Q=(B+1).toString().padStart(2,"0");return{month:Q,seconds:i?.find(w=>w.month===Q)?.seconds||0}})||[],droppedShows:(a||[]).slice(0,5)}}async function Zye(e){let t=await Ms.getWatchedEpisodesWithMeta(e),r={};for(let i of t){let s=Xye(i.genres,i.showId,"genre cards"),o=(i.effectiveSeconds??i.currentTime)||0,a=i.popularityScore||0;a>10&&(a=a/10);for(let A of s)r[A]||(r[A]={count:0,totalTime:0,scores:[],showWatches:{},showMeta:{}}),r[A].count++,r[A].totalTime+=o,a>0&&r[A].scores.push(a),r[A].showWatches[i.showId]=(r[A].showWatches[i.showId]||0)+1,(i.name||i.thumbnail)&&(r[A].showMeta[i.showId]={name:i.name,nativeName:i.nativeName,englishName:i.englishName,thumbnail:i.thumbnail})}let n=Object.entries(r).map(([i,s])=>{let o=Object.entries(s.showWatches).sort((a,A)=>A[1]-a[1]).slice(0,4).map(([a])=>({id:a,name:s.showMeta[a]?.name||"",nativeName:s.showMeta[a]?.nativeName,englishName:s.showMeta[a]?.englishName,thumbnail:s.showMeta[a]?.thumbnail||""}));return{rank:0,name:i,count:s.count,meanScore:s.scores.length>0?s.scores.reduce((a,A)=>a+A,0)/s.scores.length:0,timeWatched:s0t(s.totalTime),topShows:o}});return n.sort((i,s)=>s.count-i.count),n.forEach((i,s)=>{i.rank=s+1}),n}function s0t(e){let t=Math.floor(e/86400),r=Math.floor(e%86400/3600),n=Math.floor(e%3600/60);return t>0?`${t} days ${r>0?`${r} hours`:""}`:r>0?`${r} hours${n>0?` ${n} mins`:""}`:`${n} mins`}function eQe(e){if(!e)return[];try{if(e.startsWith("[")){let t=JSON.parse(e);return Array.isArray(t)?t.map(String):[]}return e.split(",").map(t=>t.trim()).filter(Boolean)}catch{return[]}}async function o0t(e){let[t,r,n]=await Promise.all([Ms.getLibraryShowsWithGenres(e),Ms.getAllAnilistIds(e),Ms.getWatchedEpisodesWithMeta(e)]),i={},s={};for(let c of t){let l=eQe(c.genres);if(c.status==="Completed")for(let d of l)i[d]=(i[d]||0)+1;else if(c.status==="Dropped")for(let d of l)s[d]=(s[d]||0)+1}let o={};for(let c of n){let l=c.englishName||c.name||c.showId;for(let d of eQe(c.genres)){o[d]||(o[d]=new Map);let h=o[d].get(c.showId)||{title:l,count:0};h.count+=1,o[d].set(c.showId,h)}}let a={},A=Object.entries(i).sort((c,l)=>l[1]-c[1]).slice(0,6);for(let[c]of A)a[c]=[...o[c]?.values()||[]].sort((l,d)=>d.count-l.count).slice(0,2).map(l=>l.title);let u=new Set;for(let c of t)/^\d+$/.test(c.id)&&u.add(Number(c.id));for(let c of r)c.anilistId&&u.add(c.anilistId);return{genreComp:i,genreDrop:s,exemplars:a,knownIds:[...u]}}var a0t="id title { romaji english } coverImage { large } averageScore popularity episodes seasonYear format genres isAdult status";function A0t(e,t){let r=Math.max(1,...Object.values(e)),n={};for(let[i,s]of Object.entries(e)){let o=t[i]||0;n[i]=s/r*(s/(s+o))}return n}function u0t(e){let t=Object.entries(e).sort((i,s)=>s[1]-i[1]).slice(0,4).map(([i])=>i);for(;t.length<2;)t.push("Fantasy");let r=[[t[0],t[1]],[t[0],t[2]||t[1]],[t[1],t[2]||t[0]],[t[0],t[3]||t[1]]],n=new Set;return r.filter(i=>{let s=[...i].sort().join("|");return n.has(s)?!1:(n.add(s),!0)})}function c0t(e,t,r=2){let n=new Map;for(let i of t)for(let s of e[i]||[])n.set(s,(n.get(s)||0)+1);return[...n.entries()].sort((i,s)=>s[1]-i[1]).slice(0,r).map(([i])=>i)}async function l0t(e){let t=new Set(e.knownIds||[]);if(t.size===0)return[];let r=A0t(e.genreComp,e.genreDrop),n=.15,i=Object.values(r).reduce((u,c)=>u+c,0)||1,s=new Map;for(let u of u0t(r))try{let c=await rr(`query ($g: [String]) { Page(page: 1, perPage: 20) { media(genre_in: $g, type: ANIME, status: FINISHED, isAdult: false, averageScore_greater: 68, sort: SCORE_DESC) { ${a0t} } } }`,{g:u});for(let l of c?.data?.Page?.media||[])s.has(l.id)||s.set(l.id,l)}catch{}if(s.size===0)return[];let o=[];for(let u of s.values()){if(t.has(u.id)||u.isAdult||u.format==="MUSIC"||u.format==="SPECIAL")continue;let c=u.genres||[],d=.65*(c.reduce((h,f)=>h+(r[f]??n),0)/i)+.25*((u.averageScore||70)/100)+.1*Math.min(1,(u.popularity||0)/2e5);o.push({m:u,score:d,overlap:c.filter(h=>(r[h]??0)>.3)})}o.sort((u,c)=>c.score-u.score);let a=o.slice(0,15),A=new Map;try{let u=await rr("query ($ids: [Int]) { Page(page: 1, perPage: 50) { media(id_in: $ids, type: ANIME) { id relations { edges { relationType node { id title { romaji english } type } } } } } }",{ids:a.map(c=>c.m.id)});for(let c of u?.data?.Page?.media||[])A.set(c.id,c)}catch{}return a.map(u=>{let l=A.get(u.m.id)?.relations?.edges?.find(m=>m.relationType==="PREQUEL"&&m.node?.type==="ANIME")?.node,d=u.score,h="entry",f=null;l&&l.id&&!t.has(l.id)?(h="sequel",f=l.title?.english||l.title?.romaji||null,d-=.3):l&&(h="continue",d+=.05);let g=u.m.genres||[],p=u.m.title?.english||u.m.title?.romaji||"Unknown";return{id:u.m.id,title:p,url:`https://anilist.co/anime/${u.m.id}`,cover:u.m.coverImage?.large||null,year:u.m.seasonYear??null,format:u.m.format||"TV",episodes:u.m.episodes??null,averageScore:u.m.averageScore??null,genres:g,matchPct:Math.round(d*100),sharedGenres:u.overlap,exemplars:c0t(e.exemplars,g),kind:h,prequelTitle:f}})}var Ex=null;function d0t(e){return JSON.stringify([e.genreComp,e.genreDrop,e.knownIds.length])}async function h0t(e,t){if(!Ex||Ex.hash!==t)try{let r=await l0t(e);r.length>0&&(Ex={hash:t,candidates:r})}catch(r){U.warn({err:r?.message},"Recommendation candidates failed, reusing previous")}return Ex?.candidates||[]}async function tQe(e){let t=await o0t(e);return h0t(t,d0t(t))}var rQe=At({summary:ee.query(async({ctx:e})=>zye(e.db)),genreCards:ee.query(async({ctx:e})=>Zye(e.db)),recommendations:ee.query(async({ctx:e})=>({candidates:await tQe(e.db)}))});Nn();zd();async function iG(e,t,r){let n=ae.IS_DEV?ae.REMOTE_FOLDER_DEV:ae.REMOTE_FOLDER_PROD;await Yb({db:t,mangaDb:e.mangaDb,tvDb:e.tvDb,asmrDb:e.asmrDb},{remoteFolder:n,preferredProvider:r})}var f0t=()=>pe(e=>{let t=ye(e);return{clientId:t.clientId,clientSecret:t.clientSecret,workerUrl:t.workerUrl}}),g0t=()=>pe(e=>{let t=ye(e);if(typeof t.clientId!="string")throw it("clientId required");return{clientId:t.clientId}}),E0t=()=>pe(e=>({provider:ye(e).provider})),p0t=()=>pe(e=>({remote:ye(e).remote})),m0t=()=>pe(e=>({port:ye(e).port})),nQe=At({configStatus:ee.query(async()=>{let e=!!ae.GOOGLE_AUTH_WORKER_URL,t=!!process.env.GOOGLE_CLIENT_ID&&!!process.env.GOOGLE_CLIENT_SECRET;return{hasConfig:e||t,useWorker:e}}),googleAuth:ee.query(async()=>({useWorker:!!ae.GOOGLE_AUTH_WORKER_URL,hasCustomWorkerUrl:!!process.env.GOOGLE_AUTH_WORKER_URL,hasCustomClientId:!!process.env.GOOGLE_CLIENT_ID,hasClientSecret:!!process.env.GOOGLE_CLIENT_SECRET})),saveGoogleAuth:ee.input(f0t()).mutation(async({input:e})=>{let{clientId:t,clientSecret:r,workerUrl:n}=e,i={};return typeof t=="string"&&(i.GOOGLE_CLIENT_ID=t),typeof r=="string"&&(i.GOOGLE_CLIENT_SECRET=r),typeof n=="string"&&(i.GOOGLE_AUTH_WORKER_URL=n),await Rn(i),typeof n=="string"&&(ae.GOOGLE_AUTH_WORKER_URL=n),typeof t=="string"&&(ae.GOOGLE_CLIENT_ID=t||void 0),typeof r=="string"&&(ae.GOOGLE_CLIENT_SECRET=r||void 0),await Jg(),{success:!0}}),saveGithubAuth:ee.input(g0t()).mutation(async({input:e})=>(await Rn({GITHUB_CLIENT_ID:e.clientId}),{success:!0})),rcloneSettings:ee.query(async()=>{let e=await Ui.listRemotes();return{remote:ae.RCLONE_REMOTE||"",availableRemotes:e,activeRemote:Ui.isActive()?Ui.getRemoteName():null}}),syncSettings:ee.query(async()=>({activeProvider:process.env.SYNC_PROVIDER||"default",actualActiveProvider:j2(),authenticatedProviders:{github:as.isAuthenticated(),google:Fi.isAuthenticated(),rclone:Ui.isActive()}})),saveSyncProvider:ee.input(E0t()).mutation(async({input:e})=>{let{provider:t}=e;return await Rn({SYNC_PROVIDER:t==="default"?"":t}),await Jg(),{success:!0,activeProvider:process.env.SYNC_PROVIDER||"default"}}),githubStatus:ee.query(async()=>{try{let e=await as.getUserProfile();return{authenticated:!!e,user:e,device:as.getDeviceState(),hasCustomClientId:!!process.env.GITHUB_CLIENT_ID}}catch(e){return U.error({err:e},"Failed to fetch GitHub auth status"),{authenticated:!1,user:null,device:as.getDeviceState(),hasCustomClientId:!!process.env.GITHUB_CLIENT_ID}}}),githubStart:ee.mutation(async({ctx:e})=>await as.startDeviceAuth(e.db,(r,n)=>iG(e,r,n))),githubPoll:ee.query(async()=>as.getDeviceState()),githubLogout:ee.mutation(async()=>(await as.logout(),await Rn({SYNC_PROVIDER:""}),await Jg(),{success:!0})),saveRclone:ee.input(p0t()).mutation(async({ctx:e,input:t})=>{let{remote:r}=t;return await Rn({RCLONE_REMOTE:r,SYNC_PROVIDER:"rclone"}),await iG(e,e.db,"rclone"),{success:!0}}),setServerPort:ee.input(m0t()).mutation(async({input:e})=>{let t=Number(e.port);if(!Number.isInteger(t)||t<1||t>65535)throw it("Port must be an integer between 1 and 65535");return await Rn({PORT:String(t)}),U.info({port:t},"Server port saved. Restart required to apply."),{success:!0,port:t}}),googleLogin:ee.mutation(async({ctx:e})=>{if(Fi.isAuthenticated()){if(await Fi.getUserProfile())return await Rn({SYNC_PROVIDER:"google"}),await iG(e,e.db,"google"),{url:null,authenticated:!0};U.warn("Google tokens found but invalid. Clearing and requesting new auth."),await Fi.logout()}return{url:await Fi.getAuthUrl(),authenticated:!1}}),user:ee.query(async()=>await Fi.getUserProfile()),logout:ee.mutation(async()=>(await Fi.logout(),await Rn({SYNC_PROVIDER:""}),await Jg(),{success:!0}))});var iQe=()=>pe(e=>{let t=ye(e),r={date:gt(t,"date")},n=le(t,"format");return n!==void 0&&(r.format=n),r}),sQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"format");return n!==void 0&&(r.format=n),t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,12,50,"size")),r}),oQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"query");n!==void 0&&(r.query=n),t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,14,50));let i=le(t,"sortBy");i!==void 0&&(r.sortBy=i);let s=le(t,"type");s!==void 0&&(r.type=s);let o=le(t,"status");o!==void 0&&(r.status=o);let a=le(t,"season");a!==void 0&&(r.season=a);let A=Ls(t,"year");A!==void 0&&(r.year=A);let u=le(t,"country");u!==void 0&&(r.country=u);let c=le(t,"genres");c!==void 0&&(r.genres=c);let l=le(t,"excludeGenres");l!==void 0&&(r.excludeGenres=l);let d=le(t,"excludeTags");d!==void 0&&(r.excludeTags=d);let h=Ls(t,"minScore");h!==void 0&&(r.minScore=h);let f=Ls(t,"minEpisodes");f!==void 0&&(r.minEpisodes=f);let g=le(t,"adult");return g!==void 0&&(r.adult=g),r}),aQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"title");return n!==void 0&&(r.title=n),r}),AQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"episodeNumber");return i!==void 0&&(r.episodeNumber=i),r}),uQe=()=>pe(e=>{let t=ye(e),r={};t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,14,50,"size"));let n=le(t,"format");return n!==void 0&&(r.format=n),r}),cQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"sort");return n!==void 0&&(r.sort=n),t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,20,50,"size")),r}),lQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"mode");(i==="sub"||i==="dub")&&(r.mode=i);let s=le(t,"provider");return s!==void 0&&(r.provider=s),r}),dQe=()=>pe(e=>({id:gt(ye(e),"id")})),hQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"episodeNumber");i!==void 0&&(r.episodeNumber=i);let s=le(t,"mode");(s==="sub"||s==="dub")&&(r.mode=s);let o=le(t,"provider");return o!==void 0&&(r.provider=o),r}),fQe=()=>pe(e=>{let t=ye(e),r={};for(let o of["provider","query","type","status","season","country","genres","genre","excludeGenres","sortBy","order","studio","blacklist"]){let a=le(t,o);a!==void 0&&(r[o]=a)}t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,14,50));let n=Ls(t,"year");n!==void 0&&(r.year=n);let i=Ls(t,"minScore");i!==void 0&&(r.minScore=i);let s=Ls(t,"minEpisodes");return s!==void 0&&(r.minEpisodes=s),r}),gQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"provider");n!==void 0&&(r.provider=n);let i=le(t,"nativeId");i!==void 0&&(r.nativeId=i);let s=le(t,"title");s!==void 0&&(r.title=s);let o=le(t,"thumbnail");return o!==void 0&&(r.thumbnail=o),r});function EQe(e,t){let r=t?.toLowerCase();return r&&e.getProviders()[r]||null}function _d(e,t){let r=(t||"").toLowerCase(),n=e.getProviders();if(!r||!n[r]||r==="mal"||r==="anilist")return!1;let i=pQe(e);return i?i.has(r):!0}function pQe(e){let t=e.getCatalog();return!t||t.length===0?null:new Set(t.filter(r=>r.mature&&(r.kind??"anime")==="anime"&&r.loaded).map(r=>r.id.toLowerCase()))}async function sG(e,t,r){let n=e.getProviders(),i=pQe(e),s=i?[...i]:Object.keys(n),o=[r,...s].filter(A=>!!A&&A!=="mal"&&A!=="anilist"&&!!n[A]),a=new Set;for(let A of o)if(!a.has(A)){a.add(A);try{let u=await n[A].resolveShowId?.(t);if(u)return{provider:n[A],nativeId:u}}catch{}}return null}function lm(e){if(typeof e!="string"||!e.trim())return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length>0?t:void 0}var dm=e=>Array.isArray(e)&&e.length>0,mQe=At({schedule:ee.input(iQe()).query(async({ctx:e,input:t})=>{let r=t.date,n=t.format||"TV";return jn(e,`schedule-${r}-${n}`,1800,async()=>{try{let i=new Date(r+"T00:00:00.000Z"),s=n==="ADULT";return await kP(i,s?void 0:n,s)}catch(i){return U.error({err:i,date:r},"Schedule fetch failed"),[]}},dm)}),latestReleases:ee.input(sQe()).query(async({ctx:e,input:t})=>{let r=t.format||"TV",n=t.page||1,i=t.size||12;return jn(e,`latest-releases-${r}-${n}-${i}`,300,async()=>{try{return await NP(r,n,i)}catch(s){return U.error({err:s},"Latest releases fetch failed"),[]}},dm)}),search:ee.input(oQe()).query(async({ctx:e,input:t})=>{let r={};return t.query!==void 0&&(r.query=t.query),t.page!==void 0&&(r.page=String(t.page)),t.limit!==void 0&&(r.limit=String(t.limit)),t.sortBy!==void 0&&(r.sortBy=t.sortBy),t.type!==void 0&&(r.type=t.type),t.status!==void 0&&(r.status=t.status),t.season!==void 0&&(r.season=t.season),t.year!==void 0&&(r.year=String(t.year)),t.country!==void 0&&(r.country=t.country),t.genres!==void 0&&(r.genres=t.genres),t.excludeGenres!==void 0&&(r.excludeGenres=t.excludeGenres),t.excludeTags!==void 0&&(r.excludeTags=t.excludeTags),t.minScore!==void 0&&(r.minScore=String(t.minScore)),t.minEpisodes!==void 0&&(r.minEpisodes=String(t.minEpisodes)),t.adult!==void 0&&(r.adult=t.adult),jn(e,`search-${JSON.stringify(r)}`,1800,async()=>{try{return await pf({query:t.query||"",page:t.page||1,perPage:t.limit||14,format:t.type,status:t.status,season:t.season,seasonYear:t.year,countryOfOrigin:t.country,genre:t.genres,genre_not_in:lm(t.excludeGenres),tag_not_in:lm(t.excludeTags),averageScore_greater:t.minScore,episodes_greater:t.minEpisodes,isAdult:t.adult==="true"?!0:t.adult==="false"?!1:void 0,sort:t.sortBy})}catch(n){return U.error({err:n},"search failed"),[]}},dm)}),seasonal:ee.input(uQe()).query(async({ctx:e,input:t})=>{let r=t.page||1,n=t.size||14,i=t.format;return jn(e,`seasonal-${i||"ALL"}-${r}-${n}`,300,async()=>{try{return await RP(r,n,i)}catch(s){return U.error({err:s},"Seasonal fetch failed"),[]}},dm)}),popularList:ee.input(cQe()).query(async({ctx:e,input:t})=>{let r=t.sort==="POPULARITY_DESC"?"POPULARITY_DESC":"TRENDING_DESC",n=t.page||1,i=t.size||20;return jn(e,`popular-list-${t.sort||"TRENDING_DESC"}-${n}-${i}`,300,async()=>{try{return await xP(n,i,r)}catch(s){return U.error({err:s},"Popular list fetch failed"),[]}},dm)}),spotlight:ee.query(async({ctx:e})=>jn(e,"spotlight",300,async()=>{try{return await vP(1,20)}catch(t){return U.error({err:t},"Spotlight fetch failed"),[]}},dm)),genresAndTags:ee.query(async()=>{try{return await ZO()}catch(e){throw U.error({err:e},"genres-and-tags failed"),yr("Failed to load genres")}}),anilistStatus:ee.query(async()=>{let e=!Qi();return e||OC().catch(()=>{}),{available:e,wasDownAtBoot:cT()}}),systemNotifications:ee.query(async()=>{let e=[];return cT()&&Qi()&&e.push({id:"system-anilist-down",type:"system",title:"AniList API",message:"AniList metadata API is currently down. dango is experiencing degraded performance. MAL + Kitsu is being used as a fallback in the meantime. Some features may be limited until service is restored.",icon:"warning",createdAt:Date.now()}),e})});var I0t=e=>Array.isArray(e)&&e.length>0,IQe=At({matureResolve:ee.input(aQe()).query(async({ctx:e,input:t})=>jn(e,`mature-resolve-${t.title||""}`,3600,async()=>{try{let r=(t.title||"").trim();if(!r)throw it("title is required");let n=await ys(r);if(n){let s=n.id;return{id:typeof s=="number"&&s<0?`mal-${Math.abs(s)}`:s}}let i=await EP(e.malCacheStore(),r);if(i)return{id:i,provider:"mal"};throw Mc("No match found")}catch(r){throw r instanceof nt?r:(U.error({err:r},"mature resolve failed"),yr("Resolve failed"))}},I0t)),matureSearch:ee.input(fQe()).query(async({ctx:e,input:t})=>{let r=(t.provider||"anilist").toLowerCase();if(r!=="anilist"&&r!=="mal"&&!_d(e,r))throw it("Unknown mature provider");let n={};for(let[i,s]of Object.entries(t))s!==void 0&&(n[i]=String(s));return jn(e,`mature-search-${JSON.stringify(n)}`,600,async()=>{try{let i=t.query||"",s=t.page||1,o=t.limit||14;if(r==="anilist"){let a=await pf({query:i,page:s,perPage:o,format:t.type,status:t.status,season:t.season,seasonYear:t.year,countryOfOrigin:t.country,genre:t.genres,genre_not_in:lm(t.excludeGenres),isAdult:!0,sort:t.sortBy});return{data:a,hasMore:a.length>=o}}if(_d(e,r)){let a=e.getProviders()[r];if(a?.browse){let u=t.genre||t.genres||void 0,c=await a.browse({query:i,page:s,limit:o,pageSize:o,genre:u,genres:t.genres||u,order:t.order||t.sortBy||void 0,sort:t.sortBy||t.order||void 0,studio:t.studio||void 0,blacklist:t.blacklist||void 0});return{data:c.shows,hasMore:c.hasMore,...c.total!==void 0?{total:c.total}:{},...c.genres?{genres:c.genres}:{}}}return{data:(await a.search({query:i})).map(u=>({...u,isAdult:!0})),hasMore:!1}}if(r==="mal"){let a=[];try{a=await Kl(e.malCacheStore(),{query:i,page:s,perPage:50,format:t.type,status:t.status,genre:t.genres||void 0,genre_not_in:lm(t.excludeGenres),isAdult:!0,sort:t.sortBy,averageScore_greater:t.minScore,episodes_greater:t.minEpisodes})}catch(c){U.error({err:c},"mal mature search failed")}let A=a.map(c=>({...cr(c),isAdult:!0}));return{data:A.slice(0,o),hasMore:A.length>=o}}return{data:[],hasMore:!1}}catch(i){return U.error({err:i},"mature search failed"),{data:[],hasMore:!1}}},i=>!!i&&typeof i=="object"&&Array.isArray(i.data))}),matureFilters:ee.query(async({ctx:e})=>{try{let t=e.getCatalog()??[],r={};for(let n of t)!n.mature||(n.kind??"anime")!=="anime"||!n.loaded||(r[n.id]={label:n.label,...n.browse?{browse:n.browse}:{},...n.facets?.genres?.length?{genres:n.facets.genres}:{},...n.facets?.orders?.length?{orders:n.facets.orders}:{}});return{providers:r}}catch(t){throw U.error({err:t},"mature filters failed"),yr("Failed to load filters")}}),matureAllocate:ee.input(gQe()).mutation(async({ctx:e,input:t})=>{try{let r=String(t.provider||"").toLowerCase(),n=String(t.nativeId||"").trim(),i=String(t.title||"").trim(),s=String(t.thumbnail||"");if(!r||!_d(e,r))throw it("Unknown provider");if(!n||!i)throw it("nativeId and title are required");return{id:(await ko.allocate(e.db,{provider:r,nativeId:n,title:i,thumbnail:s})).id}}catch(r){throw r instanceof nt?r:(U.error({err:r},"temp show allocate failed"),yr("Allocate failed"))}})});var C0t=e=>Array.isArray(e)&&e.length>0,CQe=At({skipTimes:ee.input(AQe()).query(async({input:e})=>{let t=e.showId||"",r=e.episodeNumber||"";try{if(/^\d+$/.test(t)){let n=await Sr(`https://api.aniskip.com/v1/skip-times/${t}/${r}?types=op&types=ed`,{},{timeoutMs:1e4});if(n.ok)return await Vt(n)}return{found:!1,results:[]}}catch(n){return U.warn({err:n,showId:t,episodeNumber:r},"Skip-times fetch failed"),{found:!1,results:[]}}}),episodes:ee.input(lQe()).query(async({ctx:e,input:t})=>{let r=t.showId;return jn(e,`episodes-${r||""}`,3600,async()=>{let n=r;if(!n)return{episodes:[]};let i=e.db,s=e.getProviders(),o=await vr(i,n),a=jA(o);if(a)try{let l=await cc(a);l?.anilistId&&l.anilistId>0&&(o=String(l.anilistId))}catch{}if(vg(o)){try{let l=await ko.getById(i,o);if(!l||!_d(e,l.provider))return{episodes:[]};let d=String(t.provider||"").toLowerCase(),h=s[l.provider];if(h&&(!d||d===l.provider)){let g=await h.getEpisodes(l.nativeId,t.mode);return g?.episodes?.length?g:{episodes:[]}}let f=await sG(e,l.title,d);if(f){let g=await f.provider.getEpisodes(f.nativeId,t.mode);if(g?.episodes?.length)return g}}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc(String(t.provider||"animepahe"));U.warn({err:l,showId:o},"Temp show episodes fetch failed")}return{episodes:[]}}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(o))try{if(s.animepahe)return await s.animepahe.getEpisodes(o,t.mode)||{episodes:[]}}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc("animepahe");return U.warn({err:l,showId:o},"Animepahe episodes fetch failed"),{episodes:[]}}if(/^(mal-\d+|-?\d+)$/i.test(o)){let l=[];try{l=await KC(o)}catch(d){U.error({err:d,showId:o},"Episodes fetch failed")}if(l.length===0){let d=Math.abs(parseInt(o,10));if(!Number.isFinite(d))return{episodes:l};try{let f=(await $l(e.malCacheStore(),d)).detail?.episodes;f&&f>0&&f<=500&&(l=Array.from({length:f},(g,p)=>(p+1).toString()))}catch{}}if(l.length===0){let d=t.provider?.toLowerCase(),h=d?s[d]:void 0;if(h?.isDirectId?.(o))try{let f=await h.getEpisodes(o,t.mode);if(f?.episodes?.length)return f}catch(f){if(f.message==="AUTH_REQUIRED")throw Fc(d||"animepahe");U.warn({err:f,showId:o,provider:d},"Episodes fetch failed")}}return{episodes:l}}let u=t.provider?.toLowerCase(),c=u?s[u]:void 0;if(c)try{let l=await c.getEpisodes(o,t.mode);if(l?.episodes?.length)return l}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc(u||"animepahe");U.warn({err:l,showId:o,provider:u},"Episodes fetch failed")}return{episodes:[]}},C0t)}),showMeta:ee.input(dQe()).query(async({ctx:e,input:t})=>{let r=t.id;return jn(e,`meta-${r}`,3600,async()=>{let n=e.db,i=await vr(n,r);if(vg(i)){let o=await ko.getById(n,i);return!o||!_d(e,o.provider)?{}:{_id:o.id,id:o.id,name:o.title,englishName:o.title,thumbnail:o.thumbnail||"",type:"TV",isAdult:!0,status:"UNKNOWN",provider:o.provider,nativeId:o.nativeId}}if(/^(mal-\d+|-?\d+)$/i.test(i)){let o=null;try{o=await bi(i)}catch(a){U.warn({err:a,id:i},"AniList show-meta fetch failed, trying local cache");let A=await ct.getById(n,i);if(A){if(typeof A.genres=="string")try{A.genres=JSON.parse(A.genres)}catch{A.genres=[]}return A}}if(o){let a=o.thumbnail?.trim()?o.thumbnail:void 0,A=!!a;try{await ct.upsert(n,{id:i,name:o.name,thumbnail:a,nativeName:o.nativeName,englishName:o.englishName,popularityScore:o.score??(o.averageScore!=null?o.averageScore/10:void 0),genres:o.genres?JSON.stringify(o.genres.map(u=>typeof u=="string"?u:u?.name).filter(Boolean)):void 0,status:o.status,episodeCount:o.episodeCount!=null?Number(o.episodeCount):void 0,type:o.type,anilistId:o.anilistId})}catch{}if(A&&a){let u=await _t.getById(n,i);if(u&&u.thumbnail!==a)try{await _t.updateThumbnail(n,i,a)}catch{}}}if(/^(mal-\d+|-\d+)$/i.test(i)&&o?.anilistId&&o.anilistId>0)try{Ia.set(n,i,String(o.anilistId))}catch{}return o||{}}return{}},n=>!!n)}),video:ee.input(hQe()).query(async({ctx:e,input:t})=>{let r=e.db,n=e.getProviders();try{let i=t.showId,s=jA(i);if(s)try{let h=await cc(s);h?.anilistId&&h.anilistId>0&&(i=String(h.anilistId))}catch{}if(vg(i)){try{let h=await ko.getById(r,i);if(!h||!_d(e,h.provider))return[];let f=String(t.provider||"").toLowerCase(),g=n[h.provider];if(g&&(!f||f===h.provider))return await g.getStreamUrls(h.nativeId,t.episodeNumber,t.mode)||[];let p=await sG(e,h.title,f);if(p)return await p.provider.getStreamUrls(p.nativeId,t.episodeNumber,t.mode)||[]}catch(h){U.error({err:h,showId:i},"Temp show video fetch failed")}return[]}let a=t.provider?.toLowerCase(),A=jA(i)!==null,c=!!!(a&&n[a]?.isDirectId?.(i))&&(/^\d+$/.test(i)||A);if(a&&c){let h=await ct.getById(r,i),f=h?.englishName||h?.name,g=null;if(!f)try{g=await bi(i),f=g?.englishName||g?.name,g&&f&&await ct.upsert(r,{id:i,name:g.name,thumbnail:g.thumbnail,nativeName:g.nativeName,englishName:g.englishName,genres:g.genres?JSON.stringify(g.genres.map(p=>p.name)):void 0,status:g.status,episodeCount:g.episodeCount!=null?Number(g.episodeCount):void 0,type:g.type,anilistId:g.anilistId})}catch(p){U.warn({err:p,provider:a,showId:i},"[Video] AniList metadata lookup failed while resolving numeric showId")}if(f){let p=g?.names?.romaji,m=g?.names?.native,I=g?.names?.synonyms;if(!p||!m)try{let w=await bi(i);p=p||w?.names?.romaji,m=m||w?.names?.native,I=I||w?.names?.synonyms}catch{}let C=[f,p,m,...(I??[]).slice(0,2)].filter(w=>!!w&&w.trim().length>0),B=[...new Set(C.map(w=>w.trim()))].filter((w,R,N)=>N.findIndex(T=>T.toLowerCase()===w.toLowerCase())===R),Q=null;for(let w of B){try{Q=await n[a]?.resolveShowId?.(w,p,t.mode)??null}catch(R){if(R.message==="AUTH_REQUIRED")throw R;Q=null}if(Q)break}if(Q)i=Q;else{U.warn({provider:a,showId:i,title:f,romaji:p},"[Video] resolveShowId failed, attempting fallback provider search");try{let w=await n[a]?.search?.({query:f}),R=ac((w||[]).map(N=>({title:N.name||N.englishName||"",id:N.id||N._id||""})),B);if(R)i=R.item.id;else return U.warn({provider:a,showId:i,title:f},"[Video] fallback provider search returned no results"),[]}catch(w){if(w.message==="AUTH_REQUIRED")throw w;return U.error({err:w,provider:a,showId:i,title:f},"[Video] fallback provider search failed"),[]}}}else return U.warn({provider:a,showId:i},"[Video] numeric showId passed to provider but local meta missing title"),[]}let l=EQe(e,t.provider);return l?await l.getStreamUrls(i,t.episodeNumber,t.mode)||[]:[]}catch(i){if(i.message==="AUTH_REQUIRED")throw Fc(i.provider||t.provider||"animepahe");return U.error({err:i,provider:t.provider},"Provider video fetch failed"),[]}})});var BQe=VBe(mQe,CQe,IQe);var yQe=new So({ttlSeconds:3600,maxKeys:2e3}),QQe=new So({ttlSeconds:3600,maxKeys:2e3});async function bQe(e){let t=e.trim().toLowerCase();if(!t)return null;let r=QQe.get(t);if(r!==void 0)return r;try{let n=new URLSearchParams({title:e.trim(),limit:"5","includes[]":"cover_art","order[relevance]":"desc"});for(let u of["safe","suggestive","erotica","pornographic"])n.append("contentRating[]",u);let i=await fetch(`https://api.mangadex.org/manga?${n.toString()}`,{headers:{"User-Agent":"Dango/3.0",Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!i.ok)return null;let s=await Vt(i),o=[];for(let u of s.data||[]){let c=u.relationships?.find(f=>f.type==="cover_art")?.attributes?.fileName;if(!c)continue;let l=`https://uploads.mangadex.org/covers/${u.id}/${c}.256.jpg`,d=u.attributes?.title,h=d?.en||d?.["ja-ro"]||Object.values(d||{})[0];h&&o.push({title:h,cover:l});for(let f of u.attributes?.altTitles||[]){let g=Object.values(f)[0];g&&o.push({title:g,cover:l})}}let a=ac(o,[e]),A=a?a.item.cover:null;return QQe.set(t,A),A}catch(n){return U.warn({err:n,title:e},"The MangaDex cover lookup failed"),null}}async function wQe(e){let t=String(e).trim().toUpperCase();if(!/^RJ\d{5,}$/.test(t))return null;let r=yQe.get(t);if(r!==void 0)return r;try{let n=await fetch(`https://www.dlsite.com/maniax/product/info/ajax?product_id=${t}`,{headers:{"User-Agent":"Mozilla/5.0",Accept:"application/json"},signal:AbortSignal.timeout(5e3)});if(!n.ok)return null;let s=await Vt(n),a=s[t]??s,A=typeof a?.work_image=="string"?a.work_image:void 0;if(!A)return null;let u=A.startsWith("//")?`https:${A}`:A;return yQe.set(t,u),u}catch(n){return U.warn({err:n,rjCode:t},"The DLsite poster lookup failed"),null}}zd();function oG(e){return e?e.slice(0,8)+"..."+e.slice(-4):"none"}var rQ=U.child({module:"DiscordGatewayRoutes"});function aG(e){let t=String(e||"");if(t.includes("/api/proxy")||t.includes("/api/image-proxy")){let r=t.match(/url=([^&]+)/);if(r)try{t=decodeURIComponent(r[1])}catch(n){return rQ.warn({err:n,thumb:t},"The proxy thumbnail url is not decodable"),""}}return!t.startsWith("https://")||t.includes("localhost")||t.includes("127.0.0.1")?"":t}var AG=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={};for(let o of["sessionId","title","thumbnail","trackLabel","chapterLabel","episodeLabel","rjCode"]){let a=le(t,o);a!==void 0&&(r[o]=a)}let n=t.thumbnails;Array.isArray(n)&&(r.thumbnails=n.map(String).filter(Boolean)),typeof t.isPlaying=="boolean"&&(r.isPlaying=t.isPlaying),typeof t.isAdult=="boolean"&&(r.isAdult=t.isAdult);let i=Ls(t,"currentTime");i!==void 0&&(r.currentTime=i);let s=Ls(t,"duration");return s!==void 0&&(r.duration=s),r}),B0t=()=>pe(e=>{if(e==null)return{};let t=le(ye(e),"page");return t===void 0?{}:{page:t}}),SQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"sessionId");return n!==void 0&&(r.sessionId=n),typeof t.bye=="boolean"&&(r.bye=t.bye),r}),y0t={asmr:{provider:"ASMR",labelField:"trackLabel",fallbackTitle:"ASMR",playingByDefault:!1,state:()=>""},manga:{provider:"Manga",labelField:"chapterLabel",fallbackTitle:"Manga",playingByDefault:!0,state:e=>e?`Reading ${e}`:"Reading"},tv:{provider:"TV",labelField:"episodeLabel",fallbackTitle:"TV",playingByDefault:!1,state:e=>e||"Movie"}};async function Q0t(e,t){let r=e.thumbnail||"";if(t==="asmr"){let n=r;if((!n||n.includes("weeabo0.xyz")||n.includes("japaneseasmr.com"))&&e.rjCode){let s=await wQe(e.rjCode);s&&(n=s)}return(n.includes("/api/image-proxy")||n.includes("weeabo0.xyz"))&&(n=""),{thumb:n,thumbs:e.thumbnails?.filter(Boolean)}}if(t==="manga"){let n=aG(r),i=e.thumbnails?.map(aG).filter(Boolean);if(!n&&e.title){let s=await bQe(e.title);if(s)return{thumb:s,thumbs:[s,...i||[]]}}return{thumb:n,thumbs:i}}return{thumb:aG(r)}}async function uG(e,t,r){if(!e.isServiceEnabled)return;t.sessionId&&e.heartbeat(t.sessionId);let n=y0t[r],i=t[n.labelField]||"",{thumb:s,thumbs:o}=await Q0t(t,r),a=r!=="manga";e.updatePresence({title:(t.title||n.fallbackTitle).slice(0,128),episode:i.slice(0,64),totalEpisodes:"",stateLine:n.state(i).slice(0,64),currentTime:a&&t.currentTime||0,duration:a&&t.duration||0,thumbnail:s,thumbnails:o,isPlaying:t.isPlaying===void 0?n.playingByDefault:t.isPlaying,providerName:n.provider,sessionId:t.sessionId,isAdult:t.isAdult===!0})}var TQe=At({pageStatus:ee.input(B0t()).mutation(async({ctx:e,input:t})=>!t.page||!e.discordRPC.isServiceEnabled?{success:!0}:(e.discordRPC.setIdleStatus(t.page),{success:!0})),heartbeat:ee.input(SQe()).mutation(async({ctx:e,input:t})=>!t.sessionId||!e.discordRPC.isServiceEnabled?{success:!0}:(t.bye?e.discordRPC.removeHeartbeat(t.sessionId):e.discordRPC.heartbeat(t.sessionId),{success:!0})),clear:ee.input(SQe()).mutation(async({ctx:e,input:t})=>e.discordRPC.isServiceEnabled?(e.discordRPC.clearPresence(t.sessionId),{success:!0}):{success:!0}),asmrPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"asmr"),{success:!0})),mangaPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"manga"),{success:!0})),tvPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"tv"),{success:!0})),gatewayStatus:ee.query(()=>{let e=Hr.hasToken();return{hasToken:e,masked:e?oG(process.env.DISCORD_GATEWAY_TOKEN):null,enabled:Hr.serviceEnabled}}),gatewaySave:ee.input(pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"token");return n!==void 0&&(r.token=n),r})).mutation(async({input:e})=>{let t=(e.token||"").trim();if(t.startsWith('"')&&t.endsWith('"')&&(t=t.slice(1,-1)),t.length<30)throw it("Token too short");try{return await Rn({DISCORD_GATEWAY_TOKEN:t}),Hr.reloadToken(),rQ.info(`Discord Gateway token saved ${oG(t)} (not logged)`),{ok:!0,masked:oG(t)}}catch(r){throw rQ.error({err:r},"Failed to save Discord Gateway token"),yr("Failed to save token")}}),gatewayRemove:ee.mutation(async()=>{try{return await Rn({DISCORD_GATEWAY_TOKEN:""}),Hr.reloadToken(),rQ.info("Discord Gateway token removed"),{ok:!0}}catch(e){throw rQ.error({err:e},"Failed to remove Discord Gateway token"),yr("Failed to remove token")}})});var DQe=At({settings:cye,queue:hye,watchlist:pye,progress:Cye,notifications:Bye,continueWatching:Qye,discovery:xye,mangaLibrary:vye,mangaProgress:kye,asmrLibrary:Mye,asmrProgress:Fye,tvLibrary:Oye,tvProgress:Pye,tv:Hye,manga:qye,asmr:Wye,tracker:Kye,insights:rQe,auth:nQe,data:BQe,discord:TQe});function NQe(e,t,r){return{...e,lanAuthed:!Sd()||Uy(Jp(t,r))}}var b0t=new wd({isArray:e=>e==="manga",parseTagValue:!1,trimValues:!0});function px(e){return Array.isArray(e)?String(e[0]??""):String(e??"")}function w0t(e){switch(e){case"Plan to Read":return"Planned";case"On Hold":return"On-Hold";case"Reading":case"Completed":case"Dropped":return e;default:return"Planned"}}function S0t(e){try{return DQ(e).remote.address}catch{return e.req.header("x-dango-client-ip")??void 0}}var xQe="x-dango-not-ready";function fm(e,t){return e.header(xQe,"1"),typeof t=="string"?e.text(t,503):e.json(t,503)}async function T0t(e,t){let r=process.hrtime.bigint(),n=new URL(e.req.url),i=`${n.pathname}${n.search}`;await t();let s=Math.round(Number(process.hrtime.bigint()-r)/1e6*10)/10,o=e.res.status,a={method:e.req.method,url:i,status:o,ms:s};o>=500&&!e.res.headers.get(xQe)?U.warn(a,"request failed"):i.startsWith("/api/proxy")||U.trace(`${e.req.method} ${i} ${o} ${s}ms`)}async function D0t(e,t){let r=new Map,n=e.req.header("x-animepahe-ua");n&&r.set("ua",n);let i=e.req.header("x-animepahe-cookie");i&&r.set("cookie",i);let s=e.req.header("x-jasmr-ua");s&&r.set("jasmr_ua",s);let o=e.req.header("x-jasmr-cookie");return o&&r.set("jasmr_cookie",o),aT.run(r,()=>t())}async function N0t(e,t,r){let n;try{n=JSON.parse(r.toString("utf-8"))}catch{return e.json({error:"Invalid backup file."},400)}let i=n?.databases;if(!i||typeof i!="object")return e.json({error:"Invalid backup file: missing databases."},400);let s={anime:t.db,manga:t.mangaDb,tv:t.tvDb,asmr:t.asmrDb},a=Object.keys(ei).map(c=>({key:c,db:s[c],tables:bn[c].tables,libraryTables:bn[c].libraryTables,backupName:bn[c].backupName,setVersion:l=>Hb(c,l)})).filter(c=>i[c.key]!==void 0);if(a.length===0)return e.json({error:"Invalid backup file: no databases found."},400);let A=new Map;try{for(let c of a)A.set(c.key,nl(i[c.key],c.tables,`backup ${c.key}`))}catch(c){return U.warn({err:c},"Multi-database restore rejected: invalid payload"),e.json({error:"Invalid backup file."},400)}let u=[];try{for(let c of a){let l=A.get(c.key);l&&(il(c.db,c.tables,l,{libraryTables:c.libraryTables,backupName:c.backupName}),await c.setVersion(xa(l)),u.push(c.key))}}catch(c){return U.error({err:c,restored:u},"Multi-database restore failed partway"),e.json({error:"Restore failed partway.",restored:u},500)}return U.warn({restored:u},"Databases restored from backup file by user request"),e.json({success:!0,message:"Databases restored.",restored:u})}function R0t(e,t,r,n){let i=ae.IS_DEV?ae.DB_NAME_DEV:ae.DB_NAME_PROD,s=RQe.join(ae.ROOT,"restore_temp.db"),o=RQe.join(ae.ROOT,i);try{hm.writeFileSync(s,r)}catch(A){return U.error({err:A},"Failed to stage legacy database restore file"),Promise.resolve(e.json({error:"Failed to stage restore file."},500))}let a=t.db;return new Promise(A=>{a.close(u=>{if(u){A(e.json({error:"Failed to close database."},500));return}try{a.checkpoint()}catch(c){U.warn({err:c},"WAL checkpoint failed")}try{hm.existsSync(`${o}-wal`)&&hm.unlinkSync(`${o}-wal`),hm.existsSync(`${o}-shm`)&&hm.unlinkSync(`${o}-shm`)}catch(c){U.warn({err:c},"Failed to clean up WAL files")}hm.rename(s,o,async c=>{if(c){try{n.setDb(await n.initializeDatabase(o))}catch(l){U.error({err:l},"Failed to reopen DB after rename failure")}A(e.json({error:"Failed to replace database file."},500));return}try{n.setDb(await n.initializeDatabase(o)),A(e.json({success:!0,message:"Database restored."}))}catch(l){U.error({err:l},"Failed to initialize restored database"),A(e.json({error:"Failed to initialize restored database."},500))}})})})}function vQe(e,t,r,n,i,s,o){let a=new Y6;a.use(T0t),a.use(D0t),a.get("/api/health",u=>{let c=e();return c.shuttingDown?fm(u,{status:"shutting-down",ready:!1}):c.dbReady?u.json({status:"ok",ready:!0}):fm(u,{status:"starting",ready:!1})}),a.use(async(u,c)=>{let l=t();if(l.shuttingDown)return fm(u,"Server is shutting down...");if(!l.dbsReady)return fm(u,"Database initializing...");if(l.bootSyncing&&u.req.method!=="GET"&&u.req.method!=="HEAD"&&u.req.method!=="OPTIONS")return fm(u,"Sync in progress...");await c()});let A=jIe({threshold:1024});return a.use(async(u,c)=>{if(u.req.header("x-no-compression")){await c();return}await A(u,c)}),a.use(async(u,c)=>{let l=u.req.header("origin");if(u.req.method==="OPTIONS"){if(!l||!Ly(l)){await c();return}let d=u.req.header("access-control-request-headers");return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":l,"Access-Control-Allow-Credentials":"true","Access-Control-Allow-Methods":"GET,HEAD,PUT,PATCH,POST,DELETE",...d?{"Access-Control-Allow-Headers":d}:{},Vary:"Origin"}})}(!l||Ly(l))&&(l&&u.header("Access-Control-Allow-Origin",l),u.header("Access-Control-Allow-Credentials","true"),u.header("Vary","Origin")),await c()}),a.use(async(u,c)=>{let l=u.req.method.toUpperCase();if(!["POST","PUT","DELETE","PATCH"].includes(l)){await c();return}if(u.req.header("sec-fetch-site")==="cross-site"){let f=u.req.header("origin");if(!Ly(f))return u.json({error:"Forbidden: cross-site request rejected"},403)}let h=u.req.header("origin");if(h&&!Ly(h))return u.json({error:"Forbidden: cross-origin request rejected"},403);await c()}),a.get("/api/auth/app-status",u=>{let c=!Sd()||Uy(Jp(u.req.header("authorization"),u.req.header("cookie")));return u.json({hasPassword:Sd(),isAuthenticated:c,port:ae.PORT})}),a.post("/api/auth/app-login",async u=>{let c=await u.req.json().catch(()=>{}),l=String(c?.password||"");if(!Sd())return u.json({success:!0});if(!l)return u.json({error:"Password required"},400);if(!ICe(l))return u.json({error:"Invalid password"},401);let d=BCe();return u.header("Set-Cookie",wCe(d.token,d.expiry)),u.json({success:!0})}),a.post("/api/auth/app-logout",u=>(yCe(Jp(u.req.header("authorization"),u.req.header("cookie"))),u.header("Set-Cookie",SCe()),u.json({success:!0}))),a.post("/api/auth/app-setup",async u=>{if(!f5(u.req.header("x-dango-client-ip")))return u.json({error:"Forbidden"},403);let c=await u.req.json().catch(()=>{}),l=String(c?.password||"");try{return await CCe(l),QCe(),u.json({success:!0,hasPassword:Sd()})}catch{return u.json({error:"Failed to update password"},500)}}),a.use(async(u,c)=>{let l=u.req.path;if(!l.startsWith("/api/")){await c();return}if(bCe.has(l)){await c();return}if(l.startsWith("/api/internal/")&&f5(S0t(u))){await c();return}if(!Sd()){await c();return}if(Uy(Jp(u.req.header("authorization"),u.req.header("cookie")))){await c();return}return u.json({error:"LAN_AUTH_REQUIRED"},401)}),a.all("/api/trpc/*",u=>kBe({endpoint:"/api/trpc",req:u.req.raw,router:DQe,createContext:()=>NQe({...r(),apiCache:o.getApiCache(),getTvProvider:o.getTvProvider,getMangaProvider:o.getMangaProvider,getJasmr:o.getJasmr,getProviders:o.getProviders,getCatalog:i.getCatalog,discordRPC:Qy,offlineDb:pn,malCacheStore:Ur},u.req.header("authorization"),u.req.header("cookie"))})),a.post("/api/import/mal-xml",async u=>{let c=r(),l=await u.req.parseBody().catch(()=>({})),d=l.xmlfile,h=d instanceof File?Buffer.from(await d.arrayBuffer()):void 0,f=qCe(h,{erase:l.erase,useOfflineDb:l.useOfflineDb,skipFallback:l.skipFallback});if(!f.ok)return u.json(f.body,f.status);let g=new TransformStream,p=g.writable.getWriter(),m=new TextEncoder,I=!1;u.req.raw.signal.addEventListener("abort",()=>{I=!0},{once:!0});let C=(B,Q)=>{I||p.write(m.encode(`event: ${B}
985
+ LEFT JOIN shows_meta sm ON sm.id = w.id`),getAllAnilistIds:e=>te(e).all(y`SELECT anilistId FROM shows_meta WHERE anilistId IS NOT NULL`)};function Xye(e,t,r){if(!e)return[];try{return e.startsWith("[")?JSON.parse(e):e.split(",").map(n=>n.trim())}catch(n){return U.warn({err:n,showId:t},`Failed to parse genres for ${r}`),[]}}async function zye(e){let[t,r,n,i,s,o,a,A]=await Promise.all([Ms.getCoreStats(e),Ms.getActivityGrid(e),Ms.getHourlyDist(e),Ms.getSeasonality(e),Ms.getAllWatches(e),Ms.getWatchedShowsMeta(e),Ms.getDroppedShows(e),Ms.getCompletionVelocities(e)]),u=r.length>0?Math.max(...r.map(C=>C.count)):0,c=[];if(s.length>0){let C=s[0].effectiveSeconds??s[0].currentTime;for(let B=1;B<s.length;B++){let Q=new Date(s[B-1].watchedAt).getTime(),R=new Date(s[B].watchedAt).getTime()-Q;Number.isFinite(R)&&R>0&&R<36e5?C+=s[B].effectiveSeconds??s[B].currentTime:(c.push(C),C=s[B].effectiveSeconds??s[B].currentTime)}c.push(C)}let l=c.length>0?Math.round(c.reduce((C,B)=>C+B,0)/c.length/60):0,d={},h=0,f=0;for(let C of o){let B=Xye(C.genres,C.id,"insights");for(let Q of B)d[Q]=(d[Q]||0)+1;if(C.popularityScore){let Q=C.popularityScore;Q>10&&(Q=Q/10),h+=Q,f++}}let g=Object.entries(d).sort((C,B)=>B[1]-C[1])[0]?.[0],m={Action:"Shonen Warrior",Romance:"Hopeless Romantic",Comedy:"Chaos Enjoyer","Slice of Life":"Vibe Seeker",Horror:"Fearless Watcher",Fantasy:"Isekai Traveller","Sci-Fi":"Future Scientist",Drama:"Feels Collector"}[g||""]||"Anime Enthusiast",I=A.length>0?Math.round(A.reduce((C,B)=>C+B.daysToFinish,0)/A.length):0;return{totalHours:Math.round((t?.totalSeconds||0)/3600),totalEpisodes:t?.totalEpisodes||0,totalAnime:t?.totalAnime||0,completedAnime:t?.completedCount||0,completionRate:t?.totalWatchlist>0?Math.round(t.completedCount/t.totalWatchlist*100):0,persona:m,bingeFactor:u,avgSessionMinutes:l,avgCompletionDays:I,popularityScore:f>0?Math.round(h/f):0,genreSplit:Object.entries(d).map(([C,B])=>({name:C,count:B})).sort((C,B)=>B.count-C.count).slice(0,8)||[],activityGrid:r||[],hourlyDist:Array.from({length:24},(C,B)=>{let Q=B.toString().padStart(2,"0");return{hour:Q,count:n?.find(w=>w.hour===Q)?.count||0}})||[],seasonality:Array.from({length:12},(C,B)=>{let Q=(B+1).toString().padStart(2,"0");return{month:Q,seconds:i?.find(w=>w.month===Q)?.seconds||0}})||[],droppedShows:(a||[]).slice(0,5)}}async function Zye(e){let t=await Ms.getWatchedEpisodesWithMeta(e),r={};for(let i of t){let s=Xye(i.genres,i.showId,"genre cards"),o=(i.effectiveSeconds??i.currentTime)||0,a=i.popularityScore||0;a>10&&(a=a/10);for(let A of s)r[A]||(r[A]={count:0,totalTime:0,scores:[],showWatches:{},showMeta:{}}),r[A].count++,r[A].totalTime+=o,a>0&&r[A].scores.push(a),r[A].showWatches[i.showId]=(r[A].showWatches[i.showId]||0)+1,(i.name||i.thumbnail)&&(r[A].showMeta[i.showId]={name:i.name,nativeName:i.nativeName,englishName:i.englishName,thumbnail:i.thumbnail})}let n=Object.entries(r).map(([i,s])=>{let o=Object.entries(s.showWatches).sort((a,A)=>A[1]-a[1]).slice(0,4).map(([a])=>({id:a,name:s.showMeta[a]?.name||"",nativeName:s.showMeta[a]?.nativeName,englishName:s.showMeta[a]?.englishName,thumbnail:s.showMeta[a]?.thumbnail||""}));return{rank:0,name:i,count:s.count,meanScore:s.scores.length>0?s.scores.reduce((a,A)=>a+A,0)/s.scores.length:0,timeWatched:s0t(s.totalTime),topShows:o}});return n.sort((i,s)=>s.count-i.count),n.forEach((i,s)=>{i.rank=s+1}),n}function s0t(e){let t=Math.floor(e/86400),r=Math.floor(e%86400/3600),n=Math.floor(e%3600/60);return t>0?`${t} days ${r>0?`${r} hours`:""}`:r>0?`${r} hours${n>0?` ${n} mins`:""}`:`${n} mins`}function eQe(e){if(!e)return[];try{if(e.startsWith("[")){let t=JSON.parse(e);return Array.isArray(t)?t.map(String):[]}return e.split(",").map(t=>t.trim()).filter(Boolean)}catch{return[]}}async function o0t(e){let[t,r,n]=await Promise.all([Ms.getLibraryShowsWithGenres(e),Ms.getAllAnilistIds(e),Ms.getWatchedEpisodesWithMeta(e)]),i={},s={};for(let c of t){let l=eQe(c.genres);if(c.status==="Completed")for(let d of l)i[d]=(i[d]||0)+1;else if(c.status==="Dropped")for(let d of l)s[d]=(s[d]||0)+1}let o={};for(let c of n){let l=c.englishName||c.name||c.showId;for(let d of eQe(c.genres)){o[d]||(o[d]=new Map);let h=o[d].get(c.showId)||{title:l,count:0};h.count+=1,o[d].set(c.showId,h)}}let a={},A=Object.entries(i).sort((c,l)=>l[1]-c[1]).slice(0,6);for(let[c]of A)a[c]=[...o[c]?.values()||[]].sort((l,d)=>d.count-l.count).slice(0,2).map(l=>l.title);let u=new Set;for(let c of t)/^\d+$/.test(c.id)&&u.add(Number(c.id));for(let c of r)c.anilistId&&u.add(c.anilistId);return{genreComp:i,genreDrop:s,exemplars:a,knownIds:[...u]}}var a0t="id title { romaji english } coverImage { large } averageScore popularity episodes seasonYear format genres isAdult status";function A0t(e,t){let r=Math.max(1,...Object.values(e)),n={};for(let[i,s]of Object.entries(e)){let o=t[i]||0;n[i]=s/r*(s/(s+o))}return n}function u0t(e){let t=Object.entries(e).sort((i,s)=>s[1]-i[1]).slice(0,4).map(([i])=>i);for(;t.length<2;)t.push("Fantasy");let r=[[t[0],t[1]],[t[0],t[2]||t[1]],[t[1],t[2]||t[0]],[t[0],t[3]||t[1]]],n=new Set;return r.filter(i=>{let s=[...i].sort().join("|");return n.has(s)?!1:(n.add(s),!0)})}function c0t(e,t,r=2){let n=new Map;for(let i of t)for(let s of e[i]||[])n.set(s,(n.get(s)||0)+1);return[...n.entries()].sort((i,s)=>s[1]-i[1]).slice(0,r).map(([i])=>i)}async function l0t(e){let t=new Set(e.knownIds||[]);if(t.size===0)return[];let r=A0t(e.genreComp,e.genreDrop),n=.15,i=Object.values(r).reduce((u,c)=>u+c,0)||1,s=new Map;for(let u of u0t(r))try{let c=await rr(`query ($g: [String]) { Page(page: 1, perPage: 20) { media(genre_in: $g, type: ANIME, status: FINISHED, isAdult: false, averageScore_greater: 68, sort: SCORE_DESC) { ${a0t} } } }`,{g:u});for(let l of c?.data?.Page?.media||[])s.has(l.id)||s.set(l.id,l)}catch{}if(s.size===0)return[];let o=[];for(let u of s.values()){if(t.has(u.id)||u.isAdult||u.format==="MUSIC"||u.format==="SPECIAL")continue;let c=u.genres||[],d=.65*(c.reduce((h,f)=>h+(r[f]??n),0)/i)+.25*((u.averageScore||70)/100)+.1*Math.min(1,(u.popularity||0)/2e5);o.push({m:u,score:d,overlap:c.filter(h=>(r[h]??0)>.3)})}o.sort((u,c)=>c.score-u.score);let a=o.slice(0,15),A=new Map;try{let u=await rr("query ($ids: [Int]) { Page(page: 1, perPage: 50) { media(id_in: $ids, type: ANIME) { id relations { edges { relationType node { id title { romaji english } type } } } } } }",{ids:a.map(c=>c.m.id)});for(let c of u?.data?.Page?.media||[])A.set(c.id,c)}catch{}return a.map(u=>{let l=A.get(u.m.id)?.relations?.edges?.find(m=>m.relationType==="PREQUEL"&&m.node?.type==="ANIME")?.node,d=u.score,h="entry",f=null;l&&l.id&&!t.has(l.id)?(h="sequel",f=l.title?.english||l.title?.romaji||null,d-=.3):l&&(h="continue",d+=.05);let g=u.m.genres||[],p=u.m.title?.english||u.m.title?.romaji||"Unknown";return{id:u.m.id,title:p,url:`https://anilist.co/anime/${u.m.id}`,cover:u.m.coverImage?.large||null,year:u.m.seasonYear??null,format:u.m.format||"TV",episodes:u.m.episodes??null,averageScore:u.m.averageScore??null,genres:g,matchPct:Math.round(d*100),sharedGenres:u.overlap,exemplars:c0t(e.exemplars,g),kind:h,prequelTitle:f}})}var Ex=null;function d0t(e){return JSON.stringify([e.genreComp,e.genreDrop,e.knownIds.length])}async function h0t(e,t){if(!Ex||Ex.hash!==t)try{let r=await l0t(e);r.length>0&&(Ex={hash:t,candidates:r})}catch(r){U.warn({err:r?.message},"Recommendation candidates failed, reusing previous")}return Ex?.candidates||[]}async function tQe(e){let t=await o0t(e);return h0t(t,d0t(t))}var rQe=At({summary:ee.query(async({ctx:e})=>zye(e.db)),genreCards:ee.query(async({ctx:e})=>Zye(e.db)),recommendations:ee.query(async({ctx:e})=>({candidates:await tQe(e.db)}))});Nn();zd();async function iG(e,t,r){let n=ae.IS_DEV?ae.REMOTE_FOLDER_DEV:ae.REMOTE_FOLDER_PROD;await Yb({db:t,mangaDb:e.mangaDb,tvDb:e.tvDb,asmrDb:e.asmrDb},{remoteFolder:n,preferredProvider:r})}var f0t=()=>pe(e=>{let t=ye(e);return{clientId:t.clientId,clientSecret:t.clientSecret,workerUrl:t.workerUrl}}),g0t=()=>pe(e=>{let t=ye(e);if(typeof t.clientId!="string")throw it("clientId required");return{clientId:t.clientId}}),E0t=()=>pe(e=>({provider:ye(e).provider})),p0t=()=>pe(e=>({remote:ye(e).remote})),m0t=()=>pe(e=>({port:ye(e).port})),nQe=At({configStatus:ee.query(async()=>{let e=!!ae.GOOGLE_AUTH_WORKER_URL,t=!!process.env.GOOGLE_CLIENT_ID&&!!process.env.GOOGLE_CLIENT_SECRET;return{hasConfig:e||t,useWorker:e}}),googleAuth:ee.query(async()=>({useWorker:!!ae.GOOGLE_AUTH_WORKER_URL,hasCustomWorkerUrl:!!process.env.GOOGLE_AUTH_WORKER_URL,hasCustomClientId:!!process.env.GOOGLE_CLIENT_ID,hasClientSecret:!!process.env.GOOGLE_CLIENT_SECRET})),saveGoogleAuth:ee.input(f0t()).mutation(async({input:e})=>{let{clientId:t,clientSecret:r,workerUrl:n}=e,i={};return typeof t=="string"&&(i.GOOGLE_CLIENT_ID=t),typeof r=="string"&&(i.GOOGLE_CLIENT_SECRET=r),typeof n=="string"&&(i.GOOGLE_AUTH_WORKER_URL=n),await Rn(i),typeof n=="string"&&(ae.GOOGLE_AUTH_WORKER_URL=n),typeof t=="string"&&(ae.GOOGLE_CLIENT_ID=t||void 0),typeof r=="string"&&(ae.GOOGLE_CLIENT_SECRET=r||void 0),await Jg(),{success:!0}}),saveGithubAuth:ee.input(g0t()).mutation(async({input:e})=>(await Rn({GITHUB_CLIENT_ID:e.clientId}),{success:!0})),rcloneSettings:ee.query(async()=>{let e=await Ui.listRemotes();return{remote:ae.RCLONE_REMOTE||"",availableRemotes:e,activeRemote:Ui.isActive()?Ui.getRemoteName():null}}),syncSettings:ee.query(async()=>({activeProvider:process.env.SYNC_PROVIDER||"default",actualActiveProvider:j2(),authenticatedProviders:{github:as.isAuthenticated(),google:Fi.isAuthenticated(),rclone:Ui.isActive()}})),saveSyncProvider:ee.input(E0t()).mutation(async({input:e})=>{let{provider:t}=e;return await Rn({SYNC_PROVIDER:t==="default"?"":t}),await Jg(),{success:!0,activeProvider:process.env.SYNC_PROVIDER||"default"}}),githubStatus:ee.query(async()=>{try{let e=await as.getUserProfile();return{authenticated:!!e,user:e,device:as.getDeviceState(),hasCustomClientId:!!process.env.GITHUB_CLIENT_ID}}catch(e){return U.error({err:e},"Failed to fetch GitHub auth status"),{authenticated:!1,user:null,device:as.getDeviceState(),hasCustomClientId:!!process.env.GITHUB_CLIENT_ID}}}),githubStart:ee.mutation(async({ctx:e})=>await as.startDeviceAuth(e.db,(r,n)=>iG(e,r,n))),githubPoll:ee.query(async()=>as.getDeviceState()),githubLogout:ee.mutation(async()=>(await as.logout(),await Rn({SYNC_PROVIDER:""}),await Jg(),{success:!0})),saveRclone:ee.input(p0t()).mutation(async({ctx:e,input:t})=>{let{remote:r}=t;return await Rn({RCLONE_REMOTE:r,SYNC_PROVIDER:"rclone"}),await iG(e,e.db,"rclone"),{success:!0}}),setServerPort:ee.input(m0t()).mutation(async({input:e})=>{let t=Number(e.port);if(!Number.isInteger(t)||t<1||t>65535)throw it("Port must be an integer between 1 and 65535");return await Rn({PORT:String(t)}),U.info({port:t},"Server port saved. Restart required to apply."),{success:!0,port:t}}),googleLogin:ee.mutation(async({ctx:e})=>{if(Fi.isAuthenticated()){if(await Fi.getUserProfile())return await Rn({SYNC_PROVIDER:"google"}),await iG(e,e.db,"google"),{url:null,authenticated:!0};U.warn("Google tokens found but invalid. Clearing and requesting new auth."),await Fi.logout()}return{url:await Fi.getAuthUrl(),authenticated:!1}}),user:ee.query(async()=>await Fi.getUserProfile()),logout:ee.mutation(async()=>(await Fi.logout(),await Rn({SYNC_PROVIDER:""}),await Jg(),{success:!0}))});var iQe=()=>pe(e=>{let t=ye(e),r={date:gt(t,"date")},n=le(t,"format");return n!==void 0&&(r.format=n),r}),sQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"format");return n!==void 0&&(r.format=n),t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,12,50,"size")),r}),oQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"query");n!==void 0&&(r.query=n),t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,14,50));let i=le(t,"sortBy");i!==void 0&&(r.sortBy=i);let s=le(t,"type");s!==void 0&&(r.type=s);let o=le(t,"status");o!==void 0&&(r.status=o);let a=le(t,"season");a!==void 0&&(r.season=a);let A=Ls(t,"year");A!==void 0&&(r.year=A);let u=le(t,"country");u!==void 0&&(r.country=u);let c=le(t,"genres");c!==void 0&&(r.genres=c);let l=le(t,"excludeGenres");l!==void 0&&(r.excludeGenres=l);let d=le(t,"excludeTags");d!==void 0&&(r.excludeTags=d);let h=Ls(t,"minScore");h!==void 0&&(r.minScore=h);let f=Ls(t,"minEpisodes");f!==void 0&&(r.minEpisodes=f);let g=le(t,"adult");return g!==void 0&&(r.adult=g),r}),aQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"title");return n!==void 0&&(r.title=n),r}),AQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"episodeNumber");return i!==void 0&&(r.episodeNumber=i),r}),uQe=()=>pe(e=>{let t=ye(e),r={};t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,14,50,"size"));let n=le(t,"format");return n!==void 0&&(r.format=n),r}),cQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"sort");return n!==void 0&&(r.sort=n),t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,20,50,"size")),r}),lQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"mode");(i==="sub"||i==="dub")&&(r.mode=i);let s=le(t,"provider");return s!==void 0&&(r.provider=s),r}),dQe=()=>pe(e=>({id:gt(ye(e),"id")})),hQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"episodeNumber");i!==void 0&&(r.episodeNumber=i);let s=le(t,"mode");(s==="sub"||s==="dub")&&(r.mode=s);let o=le(t,"provider");return o!==void 0&&(r.provider=o),r}),fQe=()=>pe(e=>{let t=ye(e),r={};for(let o of["provider","query","type","status","season","country","genres","genre","excludeGenres","sortBy","order","studio","blacklist"]){let a=le(t,o);a!==void 0&&(r[o]=a)}t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,14,50));let n=Ls(t,"year");n!==void 0&&(r.year=n);let i=Ls(t,"minScore");i!==void 0&&(r.minScore=i);let s=Ls(t,"minEpisodes");return s!==void 0&&(r.minEpisodes=s),r}),gQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"provider");n!==void 0&&(r.provider=n);let i=le(t,"nativeId");i!==void 0&&(r.nativeId=i);let s=le(t,"title");s!==void 0&&(r.title=s);let o=le(t,"thumbnail");return o!==void 0&&(r.thumbnail=o),r});function EQe(e,t){let r=t?.toLowerCase();return r&&e.getProviders()[r]||null}function _d(e,t){let r=(t||"").toLowerCase(),n=e.getProviders();if(!r||!n[r]||r==="mal"||r==="anilist")return!1;let i=pQe(e);return i?i.has(r):!0}function pQe(e){let t=e.getCatalog();return!t||t.length===0?null:new Set(t.filter(r=>r.mature&&(r.kind??"anime")==="anime"&&r.loaded).map(r=>r.id.toLowerCase()))}async function sG(e,t,r){let n=e.getProviders(),i=pQe(e),s=i?[...i]:Object.keys(n),o=[r,...s].filter(A=>!!A&&A!=="mal"&&A!=="anilist"&&!!n[A]),a=new Set;for(let A of o)if(!a.has(A)){a.add(A);try{let u=await n[A].resolveShowId?.(t);if(u)return{provider:n[A],nativeId:u}}catch{}}return null}function lm(e){if(typeof e!="string"||!e.trim())return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length>0?t:void 0}var dm=e=>Array.isArray(e)&&e.length>0,mQe=At({schedule:ee.input(iQe()).query(async({ctx:e,input:t})=>{let r=t.date,n=t.format||"TV";return jn(e,`schedule-${r}-${n}`,1800,async()=>{try{let i=new Date(r+"T00:00:00.000Z"),s=n==="ADULT";return await kP(i,s?void 0:n,s)}catch(i){return U.error({err:i,date:r},"Schedule fetch failed"),[]}},dm)}),latestReleases:ee.input(sQe()).query(async({ctx:e,input:t})=>{let r=t.format||"TV",n=t.page||1,i=t.size||12;return jn(e,`latest-releases-${r}-${n}-${i}`,300,async()=>{try{return await NP(r,n,i)}catch(s){return U.error({err:s},"Latest releases fetch failed"),[]}},dm)}),search:ee.input(oQe()).query(async({ctx:e,input:t})=>{let r={};return t.query!==void 0&&(r.query=t.query),t.page!==void 0&&(r.page=String(t.page)),t.limit!==void 0&&(r.limit=String(t.limit)),t.sortBy!==void 0&&(r.sortBy=t.sortBy),t.type!==void 0&&(r.type=t.type),t.status!==void 0&&(r.status=t.status),t.season!==void 0&&(r.season=t.season),t.year!==void 0&&(r.year=String(t.year)),t.country!==void 0&&(r.country=t.country),t.genres!==void 0&&(r.genres=t.genres),t.excludeGenres!==void 0&&(r.excludeGenres=t.excludeGenres),t.excludeTags!==void 0&&(r.excludeTags=t.excludeTags),t.minScore!==void 0&&(r.minScore=String(t.minScore)),t.minEpisodes!==void 0&&(r.minEpisodes=String(t.minEpisodes)),t.adult!==void 0&&(r.adult=t.adult),jn(e,`search-${JSON.stringify(r)}`,1800,async()=>{try{return await pf({query:t.query||"",page:t.page||1,perPage:t.limit||14,format:t.type,status:t.status,season:t.season,seasonYear:t.year,countryOfOrigin:t.country,genre:t.genres,genre_not_in:lm(t.excludeGenres),tag_not_in:lm(t.excludeTags),averageScore_greater:t.minScore,episodes_greater:t.minEpisodes,isAdult:t.adult==="true"?!0:t.adult==="false"?!1:void 0,sort:t.sortBy})}catch(n){return U.error({err:n},"search failed"),[]}},dm)}),seasonal:ee.input(uQe()).query(async({ctx:e,input:t})=>{let r=t.page||1,n=t.size||14,i=t.format;return jn(e,`seasonal-${i||"ALL"}-${r}-${n}`,300,async()=>{try{return await RP(r,n,i)}catch(s){return U.error({err:s},"Seasonal fetch failed"),[]}},dm)}),popularList:ee.input(cQe()).query(async({ctx:e,input:t})=>{let r=t.sort==="POPULARITY_DESC"?"POPULARITY_DESC":"TRENDING_DESC",n=t.page||1,i=t.size||20;return jn(e,`popular-list-${t.sort||"TRENDING_DESC"}-${n}-${i}`,300,async()=>{try{return await xP(n,i,r)}catch(s){return U.error({err:s},"Popular list fetch failed"),[]}},dm)}),spotlight:ee.query(async({ctx:e})=>jn(e,"spotlight",300,async()=>{try{return await vP(1,20)}catch(t){return U.error({err:t},"Spotlight fetch failed"),[]}},dm)),genresAndTags:ee.query(async()=>{try{return await ZO()}catch(e){throw U.error({err:e},"genres-and-tags failed"),yr("Failed to load genres")}}),anilistStatus:ee.query(async()=>{let e=!Qi();return e||OC().catch(()=>{}),{available:e,wasDownAtBoot:cT()}}),systemNotifications:ee.query(async()=>{let e=[];return cT()&&Qi()&&e.push({id:"system-anilist-down",type:"system",title:"AniList API",message:"AniList metadata API is currently down. dango is experiencing degraded performance. MAL + Kitsu is being used as a fallback in the meantime. Some features may be limited until service is restored.",icon:"warning",createdAt:Date.now()}),e})});var I0t=e=>Array.isArray(e)&&e.length>0,IQe=At({matureResolve:ee.input(aQe()).query(async({ctx:e,input:t})=>jn(e,`mature-resolve-${t.title||""}`,3600,async()=>{try{let r=(t.title||"").trim();if(!r)throw it("title is required");let n=await ys(r);if(n){let s=n.id;return{id:typeof s=="number"&&s<0?`mal-${Math.abs(s)}`:s}}let i=await EP(e.malCacheStore(),r);if(i)return{id:i,provider:"mal"};throw Mc("No match found")}catch(r){throw r instanceof nt?r:(U.error({err:r},"mature resolve failed"),yr("Resolve failed"))}},I0t)),matureSearch:ee.input(fQe()).query(async({ctx:e,input:t})=>{let r=(t.provider||"anilist").toLowerCase();if(r!=="anilist"&&r!=="mal"&&!_d(e,r))throw it("Unknown mature provider");let n={};for(let[i,s]of Object.entries(t))s!==void 0&&(n[i]=String(s));return jn(e,`mature-search-${JSON.stringify(n)}`,600,async()=>{try{let i=t.query||"",s=t.page||1,o=t.limit||14;if(r==="anilist"){let a=await pf({query:i,page:s,perPage:o,format:t.type,status:t.status,season:t.season,seasonYear:t.year,countryOfOrigin:t.country,genre:t.genres,genre_not_in:lm(t.excludeGenres),isAdult:!0,sort:t.sortBy});return{data:a,hasMore:a.length>=o}}if(_d(e,r)){let a=e.getProviders()[r];if(a?.browse){let u=t.genre||t.genres||void 0,c=await a.browse({query:i,page:s,limit:o,pageSize:o,genre:u,genres:t.genres||u,order:t.order||t.sortBy||void 0,sort:t.sortBy||t.order||void 0,studio:t.studio||void 0,blacklist:t.blacklist||void 0});return{data:c.shows,hasMore:c.hasMore,...c.total!==void 0?{total:c.total}:{},...c.genres?{genres:c.genres}:{}}}return{data:(await a.search({query:i})).map(u=>({...u,isAdult:!0})),hasMore:!1}}if(r==="mal"){let a=[];try{a=await Kl(e.malCacheStore(),{query:i,page:s,perPage:50,format:t.type,status:t.status,genre:t.genres||void 0,genre_not_in:lm(t.excludeGenres),isAdult:!0,sort:t.sortBy,averageScore_greater:t.minScore,episodes_greater:t.minEpisodes})}catch(c){U.error({err:c},"mal mature search failed")}let A=a.map(c=>({...cr(c),isAdult:!0}));return{data:A.slice(0,o),hasMore:A.length>=o}}return{data:[],hasMore:!1}}catch(i){return U.error({err:i},"mature search failed"),{data:[],hasMore:!1}}},i=>!!i&&typeof i=="object"&&Array.isArray(i.data))}),matureFilters:ee.query(async({ctx:e})=>{try{let t=e.getCatalog()??[],r={};for(let n of t)!n.mature||(n.kind??"anime")!=="anime"||!n.loaded||(r[n.id]={label:n.label,...n.browse?{browse:n.browse}:{},...n.facets?.genres?.length?{genres:n.facets.genres}:{},...n.facets?.orders?.length?{orders:n.facets.orders}:{}});return{providers:r}}catch(t){throw U.error({err:t},"mature filters failed"),yr("Failed to load filters")}}),matureAllocate:ee.input(gQe()).mutation(async({ctx:e,input:t})=>{try{let r=String(t.provider||"").toLowerCase(),n=String(t.nativeId||"").trim(),i=String(t.title||"").trim(),s=String(t.thumbnail||"");if(!r||!_d(e,r))throw it("Unknown provider");if(!n||!i)throw it("nativeId and title are required");return{id:(await ko.allocate(e.db,{provider:r,nativeId:n,title:i,thumbnail:s})).id}}catch(r){throw r instanceof nt?r:(U.error({err:r},"temp show allocate failed"),yr("Allocate failed"))}})});var C0t=e=>Array.isArray(e)&&e.length>0,CQe=At({skipTimes:ee.input(AQe()).query(async({input:e})=>{let t=e.showId||"",r=e.episodeNumber||"";try{if(/^\d+$/.test(t)){let n=await Sr(`https://api.aniskip.com/v1/skip-times/${t}/${r}?types=op&types=ed`,{},{timeoutMs:1e4});if(n.ok)return await Vt(n)}return{found:!1,results:[]}}catch(n){return U.warn({err:n,showId:t,episodeNumber:r},"Skip-times fetch failed"),{found:!1,results:[]}}}),episodes:ee.input(lQe()).query(async({ctx:e,input:t})=>{let r=t.showId;return jn(e,`episodes-${r||""}`,3600,async()=>{let n=r;if(!n)return{episodes:[]};let i=e.db,s=e.getProviders(),o=await vr(i,n),a=jA(o);if(a)try{let l=await cc(a);l?.anilistId&&l.anilistId>0&&(o=String(l.anilistId))}catch{}if(vg(o)){try{let l=await ko.getById(i,o);if(!l||!_d(e,l.provider))return{episodes:[]};let d=String(t.provider||"").toLowerCase(),h=s[l.provider];if(h&&(!d||d===l.provider)){let g=await h.getEpisodes(l.nativeId,t.mode);return g?.episodes?.length?g:{episodes:[]}}let f=await sG(e,l.title,d);if(f){let g=await f.provider.getEpisodes(f.nativeId,t.mode);if(g?.episodes?.length)return g}}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc(String(t.provider||"animepahe"));U.warn({err:l,showId:o},"Temp show episodes fetch failed")}return{episodes:[]}}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(o))try{if(s.animepahe)return await s.animepahe.getEpisodes(o,t.mode)||{episodes:[]}}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc("animepahe");return U.warn({err:l,showId:o},"Animepahe episodes fetch failed"),{episodes:[]}}if(/^(mal-\d+|-?\d+)$/i.test(o)){let l=[];try{l=await KC(o)}catch(d){U.error({err:d,showId:o},"Episodes fetch failed")}if(l.length===0){let d=Math.abs(parseInt(o,10));if(!Number.isFinite(d))return{episodes:l};try{let f=(await $l(e.malCacheStore(),d)).detail?.episodes;f&&f>0&&f<=500&&(l=Array.from({length:f},(g,p)=>(p+1).toString()))}catch{}}if(l.length===0){let d=t.provider?.toLowerCase(),h=d?s[d]:void 0;if(h?.isDirectId?.(o))try{let f=await h.getEpisodes(o,t.mode);if(f?.episodes?.length)return f}catch(f){if(f.message==="AUTH_REQUIRED")throw Fc(d||"animepahe");U.warn({err:f,showId:o,provider:d},"Episodes fetch failed")}}return{episodes:l}}let u=t.provider?.toLowerCase(),c=u?s[u]:void 0;if(c)try{let l=await c.getEpisodes(o,t.mode);if(l?.episodes?.length)return l}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc(u||"animepahe");U.warn({err:l,showId:o,provider:u},"Episodes fetch failed")}return{episodes:[]}},C0t)}),showMeta:ee.input(dQe()).query(async({ctx:e,input:t})=>{let r=t.id;return jn(e,`meta-${r}`,3600,async()=>{let n=e.db,i=await vr(n,r);if(vg(i)){let o=await ko.getById(n,i);return!o||!_d(e,o.provider)?{}:{_id:o.id,id:o.id,name:o.title,englishName:o.title,thumbnail:o.thumbnail||"",type:"TV",isAdult:!0,status:"UNKNOWN",provider:o.provider,nativeId:o.nativeId}}if(/^(mal-\d+|-?\d+)$/i.test(i)){let o=null;try{o=await bi(i)}catch(c){U.warn({err:c,id:i},"AniList show-meta fetch failed, trying local cache")}let a=await ct.getById(n,i);if(!o){if(!a)return{};if(typeof a.genres=="string")try{let c=JSON.parse(a.genres);a.genres=Array.isArray(c)?c.map(l=>({name:typeof l=="string"?l:String(l?.name??"")})):[]}catch{a.genres=[]}return a}!o.status&&a?.status&&(o.status=String(a.status)),!o.episodeCount&&a?.episodeCount&&(o.episodeCount=Number(a.episodeCount));let A=o.thumbnail?.trim()?o.thumbnail:void 0,u=!!A;try{await ct.upsert(n,{id:i,name:o.name,thumbnail:A,nativeName:o.nativeName,englishName:o.englishName,popularityScore:o.score??(o.averageScore!=null?o.averageScore/10:void 0),genres:o.genres?JSON.stringify(o.genres.map(c=>typeof c=="string"?c:c?.name).filter(Boolean)):void 0,status:o.status,episodeCount:o.episodeCount!=null?Number(o.episodeCount):void 0,type:o.type,anilistId:o.anilistId})}catch{}if(u&&A){let c=await _t.getById(n,i);if(c&&c.thumbnail!==A)try{await _t.updateThumbnail(n,i,A)}catch{}}if(/^(mal-\d+|-\d+)$/i.test(i)&&o.anilistId&&o.anilistId>0)try{Ia.set(n,i,String(o.anilistId))}catch{}return o||{}}return{}},n=>!!n&&Object.keys(n).length>0)}),video:ee.input(hQe()).query(async({ctx:e,input:t})=>{let r=e.db,n=e.getProviders();try{let i=t.showId,s=jA(i);if(s)try{let h=await cc(s);h?.anilistId&&h.anilistId>0&&(i=String(h.anilistId))}catch{}if(vg(i)){try{let h=await ko.getById(r,i);if(!h||!_d(e,h.provider))return[];let f=String(t.provider||"").toLowerCase(),g=n[h.provider];if(g&&(!f||f===h.provider))return await g.getStreamUrls(h.nativeId,t.episodeNumber,t.mode)||[];let p=await sG(e,h.title,f);if(p)return await p.provider.getStreamUrls(p.nativeId,t.episodeNumber,t.mode)||[]}catch(h){U.error({err:h,showId:i},"Temp show video fetch failed")}return[]}let a=t.provider?.toLowerCase(),A=jA(i)!==null,c=!!!(a&&n[a]?.isDirectId?.(i))&&(/^\d+$/.test(i)||A);if(a&&c){let h=await ct.getById(r,i),f=h?.englishName||h?.name,g=null;if(!f)try{g=await bi(i),f=g?.englishName||g?.name,g&&f&&await ct.upsert(r,{id:i,name:g.name,thumbnail:g.thumbnail,nativeName:g.nativeName,englishName:g.englishName,genres:g.genres?JSON.stringify(g.genres.map(p=>p.name)):void 0,status:g.status,episodeCount:g.episodeCount!=null?Number(g.episodeCount):void 0,type:g.type,anilistId:g.anilistId})}catch(p){U.warn({err:p,provider:a,showId:i},"[Video] AniList metadata lookup failed while resolving numeric showId")}if(f){let p=g?.names?.romaji,m=g?.names?.native,I=g?.names?.synonyms;if(!p||!m)try{let w=await bi(i);p=p||w?.names?.romaji,m=m||w?.names?.native,I=I||w?.names?.synonyms}catch{}let C=[f,p,m,...(I??[]).slice(0,2)].filter(w=>!!w&&w.trim().length>0),B=[...new Set(C.map(w=>w.trim()))].filter((w,R,N)=>N.findIndex(T=>T.toLowerCase()===w.toLowerCase())===R),Q=null;for(let w of B){try{Q=await n[a]?.resolveShowId?.(w,p,t.mode)??null}catch(R){if(R.message==="AUTH_REQUIRED")throw R;Q=null}if(Q)break}if(Q)i=Q;else{U.warn({provider:a,showId:i,title:f,romaji:p},"[Video] resolveShowId failed, attempting fallback provider search");try{let w=await n[a]?.search?.({query:f}),R=ac((w||[]).map(N=>({title:N.name||N.englishName||"",id:N.id||N._id||""})),B);if(R)i=R.item.id;else return U.warn({provider:a,showId:i,title:f},"[Video] fallback provider search returned no results"),[]}catch(w){if(w.message==="AUTH_REQUIRED")throw w;return U.error({err:w,provider:a,showId:i,title:f},"[Video] fallback provider search failed"),[]}}}else return U.warn({provider:a,showId:i},"[Video] numeric showId passed to provider but local meta missing title"),[]}let l=EQe(e,t.provider);return l?await l.getStreamUrls(i,t.episodeNumber,t.mode)||[]:[]}catch(i){if(i.message==="AUTH_REQUIRED")throw Fc(i.provider||t.provider||"animepahe");return U.error({err:i,provider:t.provider},"Provider video fetch failed"),[]}})});var BQe=VBe(mQe,CQe,IQe);var yQe=new So({ttlSeconds:3600,maxKeys:2e3}),QQe=new So({ttlSeconds:3600,maxKeys:2e3});async function bQe(e){let t=e.trim().toLowerCase();if(!t)return null;let r=QQe.get(t);if(r!==void 0)return r;try{let n=new URLSearchParams({title:e.trim(),limit:"5","includes[]":"cover_art","order[relevance]":"desc"});for(let u of["safe","suggestive","erotica","pornographic"])n.append("contentRating[]",u);let i=await fetch(`https://api.mangadex.org/manga?${n.toString()}`,{headers:{"User-Agent":"Dango/3.0",Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!i.ok)return null;let s=await Vt(i),o=[];for(let u of s.data||[]){let c=u.relationships?.find(f=>f.type==="cover_art")?.attributes?.fileName;if(!c)continue;let l=`https://uploads.mangadex.org/covers/${u.id}/${c}.256.jpg`,d=u.attributes?.title,h=d?.en||d?.["ja-ro"]||Object.values(d||{})[0];h&&o.push({title:h,cover:l});for(let f of u.attributes?.altTitles||[]){let g=Object.values(f)[0];g&&o.push({title:g,cover:l})}}let a=ac(o,[e]),A=a?a.item.cover:null;return QQe.set(t,A),A}catch(n){return U.warn({err:n,title:e},"The MangaDex cover lookup failed"),null}}async function wQe(e){let t=String(e).trim().toUpperCase();if(!/^RJ\d{5,}$/.test(t))return null;let r=yQe.get(t);if(r!==void 0)return r;try{let n=await fetch(`https://www.dlsite.com/maniax/product/info/ajax?product_id=${t}`,{headers:{"User-Agent":"Mozilla/5.0",Accept:"application/json"},signal:AbortSignal.timeout(5e3)});if(!n.ok)return null;let s=await Vt(n),a=s[t]??s,A=typeof a?.work_image=="string"?a.work_image:void 0;if(!A)return null;let u=A.startsWith("//")?`https:${A}`:A;return yQe.set(t,u),u}catch(n){return U.warn({err:n,rjCode:t},"The DLsite poster lookup failed"),null}}zd();function oG(e){return e?e.slice(0,8)+"..."+e.slice(-4):"none"}var rQ=U.child({module:"DiscordGatewayRoutes"});function aG(e){let t=String(e||"");if(t.includes("/api/proxy")||t.includes("/api/image-proxy")){let r=t.match(/url=([^&]+)/);if(r)try{t=decodeURIComponent(r[1])}catch(n){return rQ.warn({err:n,thumb:t},"The proxy thumbnail url is not decodable"),""}}return!t.startsWith("https://")||t.includes("localhost")||t.includes("127.0.0.1")?"":t}var AG=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={};for(let o of["sessionId","title","thumbnail","trackLabel","chapterLabel","episodeLabel","rjCode"]){let a=le(t,o);a!==void 0&&(r[o]=a)}let n=t.thumbnails;Array.isArray(n)&&(r.thumbnails=n.map(String).filter(Boolean)),typeof t.isPlaying=="boolean"&&(r.isPlaying=t.isPlaying),typeof t.isAdult=="boolean"&&(r.isAdult=t.isAdult);let i=Ls(t,"currentTime");i!==void 0&&(r.currentTime=i);let s=Ls(t,"duration");return s!==void 0&&(r.duration=s),r}),B0t=()=>pe(e=>{if(e==null)return{};let t=le(ye(e),"page");return t===void 0?{}:{page:t}}),SQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"sessionId");return n!==void 0&&(r.sessionId=n),typeof t.bye=="boolean"&&(r.bye=t.bye),r}),y0t={asmr:{provider:"ASMR",labelField:"trackLabel",fallbackTitle:"ASMR",playingByDefault:!1,state:()=>""},manga:{provider:"Manga",labelField:"chapterLabel",fallbackTitle:"Manga",playingByDefault:!0,state:e=>e?`Reading ${e}`:"Reading"},tv:{provider:"TV",labelField:"episodeLabel",fallbackTitle:"TV",playingByDefault:!1,state:e=>e||"Movie"}};async function Q0t(e,t){let r=e.thumbnail||"";if(t==="asmr"){let n=r;if((!n||n.includes("weeabo0.xyz")||n.includes("japaneseasmr.com"))&&e.rjCode){let s=await wQe(e.rjCode);s&&(n=s)}return(n.includes("/api/image-proxy")||n.includes("weeabo0.xyz"))&&(n=""),{thumb:n,thumbs:e.thumbnails?.filter(Boolean)}}if(t==="manga"){let n=aG(r),i=e.thumbnails?.map(aG).filter(Boolean);if(!n&&e.title){let s=await bQe(e.title);if(s)return{thumb:s,thumbs:[s,...i||[]]}}return{thumb:n,thumbs:i}}return{thumb:aG(r)}}async function uG(e,t,r){if(!e.isServiceEnabled)return;t.sessionId&&e.heartbeat(t.sessionId);let n=y0t[r],i=t[n.labelField]||"",{thumb:s,thumbs:o}=await Q0t(t,r),a=r!=="manga";e.updatePresence({title:(t.title||n.fallbackTitle).slice(0,128),episode:i.slice(0,64),totalEpisodes:"",stateLine:n.state(i).slice(0,64),currentTime:a&&t.currentTime||0,duration:a&&t.duration||0,thumbnail:s,thumbnails:o,isPlaying:t.isPlaying===void 0?n.playingByDefault:t.isPlaying,providerName:n.provider,sessionId:t.sessionId,isAdult:t.isAdult===!0})}var TQe=At({pageStatus:ee.input(B0t()).mutation(async({ctx:e,input:t})=>!t.page||!e.discordRPC.isServiceEnabled?{success:!0}:(e.discordRPC.setIdleStatus(t.page),{success:!0})),heartbeat:ee.input(SQe()).mutation(async({ctx:e,input:t})=>!t.sessionId||!e.discordRPC.isServiceEnabled?{success:!0}:(t.bye?e.discordRPC.removeHeartbeat(t.sessionId):e.discordRPC.heartbeat(t.sessionId),{success:!0})),clear:ee.input(SQe()).mutation(async({ctx:e,input:t})=>e.discordRPC.isServiceEnabled?(e.discordRPC.clearPresence(t.sessionId),{success:!0}):{success:!0}),asmrPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"asmr"),{success:!0})),mangaPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"manga"),{success:!0})),tvPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"tv"),{success:!0})),gatewayStatus:ee.query(()=>{let e=Hr.hasToken();return{hasToken:e,masked:e?oG(process.env.DISCORD_GATEWAY_TOKEN):null,enabled:Hr.serviceEnabled}}),gatewaySave:ee.input(pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"token");return n!==void 0&&(r.token=n),r})).mutation(async({input:e})=>{let t=(e.token||"").trim();if(t.startsWith('"')&&t.endsWith('"')&&(t=t.slice(1,-1)),t.length<30)throw it("Token too short");try{return await Rn({DISCORD_GATEWAY_TOKEN:t}),Hr.reloadToken(),rQ.info(`Discord Gateway token saved ${oG(t)} (not logged)`),{ok:!0,masked:oG(t)}}catch(r){throw rQ.error({err:r},"Failed to save Discord Gateway token"),yr("Failed to save token")}}),gatewayRemove:ee.mutation(async()=>{try{return await Rn({DISCORD_GATEWAY_TOKEN:""}),Hr.reloadToken(),rQ.info("Discord Gateway token removed"),{ok:!0}}catch(e){throw rQ.error({err:e},"Failed to remove Discord Gateway token"),yr("Failed to remove token")}})});var DQe=At({settings:cye,queue:hye,watchlist:pye,progress:Cye,notifications:Bye,continueWatching:Qye,discovery:xye,mangaLibrary:vye,mangaProgress:kye,asmrLibrary:Mye,asmrProgress:Fye,tvLibrary:Oye,tvProgress:Pye,tv:Hye,manga:qye,asmr:Wye,tracker:Kye,insights:rQe,auth:nQe,data:BQe,discord:TQe});function NQe(e,t,r){return{...e,lanAuthed:!Sd()||Uy(Jp(t,r))}}var b0t=new wd({isArray:e=>e==="manga",parseTagValue:!1,trimValues:!0});function px(e){return Array.isArray(e)?String(e[0]??""):String(e??"")}function w0t(e){switch(e){case"Plan to Read":return"Planned";case"On Hold":return"On-Hold";case"Reading":case"Completed":case"Dropped":return e;default:return"Planned"}}function S0t(e){try{return DQ(e).remote.address}catch{return e.req.header("x-dango-client-ip")??void 0}}var xQe="x-dango-not-ready";function fm(e,t){return e.header(xQe,"1"),typeof t=="string"?e.text(t,503):e.json(t,503)}async function T0t(e,t){let r=process.hrtime.bigint(),n=new URL(e.req.url),i=`${n.pathname}${n.search}`;await t();let s=Math.round(Number(process.hrtime.bigint()-r)/1e6*10)/10,o=e.res.status,a={method:e.req.method,url:i,status:o,ms:s};o>=500&&!e.res.headers.get(xQe)?U.warn(a,"request failed"):i.startsWith("/api/proxy")||U.trace(`${e.req.method} ${i} ${o} ${s}ms`)}async function D0t(e,t){let r=new Map,n=e.req.header("x-animepahe-ua");n&&r.set("ua",n);let i=e.req.header("x-animepahe-cookie");i&&r.set("cookie",i);let s=e.req.header("x-jasmr-ua");s&&r.set("jasmr_ua",s);let o=e.req.header("x-jasmr-cookie");return o&&r.set("jasmr_cookie",o),aT.run(r,()=>t())}async function N0t(e,t,r){let n;try{n=JSON.parse(r.toString("utf-8"))}catch{return e.json({error:"Invalid backup file."},400)}let i=n?.databases;if(!i||typeof i!="object")return e.json({error:"Invalid backup file: missing databases."},400);let s={anime:t.db,manga:t.mangaDb,tv:t.tvDb,asmr:t.asmrDb},a=Object.keys(ei).map(c=>({key:c,db:s[c],tables:bn[c].tables,libraryTables:bn[c].libraryTables,backupName:bn[c].backupName,setVersion:l=>Hb(c,l)})).filter(c=>i[c.key]!==void 0);if(a.length===0)return e.json({error:"Invalid backup file: no databases found."},400);let A=new Map;try{for(let c of a)A.set(c.key,nl(i[c.key],c.tables,`backup ${c.key}`))}catch(c){return U.warn({err:c},"Multi-database restore rejected: invalid payload"),e.json({error:"Invalid backup file."},400)}let u=[];try{for(let c of a){let l=A.get(c.key);l&&(il(c.db,c.tables,l,{libraryTables:c.libraryTables,backupName:c.backupName}),await c.setVersion(xa(l)),u.push(c.key))}}catch(c){return U.error({err:c,restored:u},"Multi-database restore failed partway"),e.json({error:"Restore failed partway.",restored:u},500)}return U.warn({restored:u},"Databases restored from backup file by user request"),e.json({success:!0,message:"Databases restored.",restored:u})}function R0t(e,t,r,n){let i=ae.IS_DEV?ae.DB_NAME_DEV:ae.DB_NAME_PROD,s=RQe.join(ae.ROOT,"restore_temp.db"),o=RQe.join(ae.ROOT,i);try{hm.writeFileSync(s,r)}catch(A){return U.error({err:A},"Failed to stage legacy database restore file"),Promise.resolve(e.json({error:"Failed to stage restore file."},500))}let a=t.db;return new Promise(A=>{a.close(u=>{if(u){A(e.json({error:"Failed to close database."},500));return}try{a.checkpoint()}catch(c){U.warn({err:c},"WAL checkpoint failed")}try{hm.existsSync(`${o}-wal`)&&hm.unlinkSync(`${o}-wal`),hm.existsSync(`${o}-shm`)&&hm.unlinkSync(`${o}-shm`)}catch(c){U.warn({err:c},"Failed to clean up WAL files")}hm.rename(s,o,async c=>{if(c){try{n.setDb(await n.initializeDatabase(o))}catch(l){U.error({err:l},"Failed to reopen DB after rename failure")}A(e.json({error:"Failed to replace database file."},500));return}try{n.setDb(await n.initializeDatabase(o)),A(e.json({success:!0,message:"Database restored."}))}catch(l){U.error({err:l},"Failed to initialize restored database"),A(e.json({error:"Failed to initialize restored database."},500))}})})})}function vQe(e,t,r,n,i,s,o){let a=new Y6;a.use(T0t),a.use(D0t),a.get("/api/health",u=>{let c=e();return c.shuttingDown?fm(u,{status:"shutting-down",ready:!1}):c.dbReady?u.json({status:"ok",ready:!0}):fm(u,{status:"starting",ready:!1})}),a.use(async(u,c)=>{let l=t();if(l.shuttingDown)return fm(u,"Server is shutting down...");if(!l.dbsReady)return fm(u,"Database initializing...");if(l.bootSyncing&&u.req.method!=="GET"&&u.req.method!=="HEAD"&&u.req.method!=="OPTIONS")return fm(u,"Sync in progress...");await c()});let A=jIe({threshold:1024});return a.use(async(u,c)=>{if(u.req.header("x-no-compression")){await c();return}await A(u,c)}),a.use(async(u,c)=>{let l=u.req.header("origin");if(u.req.method==="OPTIONS"){if(!l||!Ly(l)){await c();return}let d=u.req.header("access-control-request-headers");return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":l,"Access-Control-Allow-Credentials":"true","Access-Control-Allow-Methods":"GET,HEAD,PUT,PATCH,POST,DELETE",...d?{"Access-Control-Allow-Headers":d}:{},Vary:"Origin"}})}(!l||Ly(l))&&(l&&u.header("Access-Control-Allow-Origin",l),u.header("Access-Control-Allow-Credentials","true"),u.header("Vary","Origin")),await c()}),a.use(async(u,c)=>{let l=u.req.method.toUpperCase();if(!["POST","PUT","DELETE","PATCH"].includes(l)){await c();return}if(u.req.header("sec-fetch-site")==="cross-site"){let f=u.req.header("origin");if(!Ly(f))return u.json({error:"Forbidden: cross-site request rejected"},403)}let h=u.req.header("origin");if(h&&!Ly(h))return u.json({error:"Forbidden: cross-origin request rejected"},403);await c()}),a.get("/api/auth/app-status",u=>{let c=!Sd()||Uy(Jp(u.req.header("authorization"),u.req.header("cookie")));return u.json({hasPassword:Sd(),isAuthenticated:c,port:ae.PORT})}),a.post("/api/auth/app-login",async u=>{let c=await u.req.json().catch(()=>{}),l=String(c?.password||"");if(!Sd())return u.json({success:!0});if(!l)return u.json({error:"Password required"},400);if(!ICe(l))return u.json({error:"Invalid password"},401);let d=BCe();return u.header("Set-Cookie",wCe(d.token,d.expiry)),u.json({success:!0})}),a.post("/api/auth/app-logout",u=>(yCe(Jp(u.req.header("authorization"),u.req.header("cookie"))),u.header("Set-Cookie",SCe()),u.json({success:!0}))),a.post("/api/auth/app-setup",async u=>{if(!f5(u.req.header("x-dango-client-ip")))return u.json({error:"Forbidden"},403);let c=await u.req.json().catch(()=>{}),l=String(c?.password||"");try{return await CCe(l),QCe(),u.json({success:!0,hasPassword:Sd()})}catch{return u.json({error:"Failed to update password"},500)}}),a.use(async(u,c)=>{let l=u.req.path;if(!l.startsWith("/api/")){await c();return}if(bCe.has(l)){await c();return}if(l.startsWith("/api/internal/")&&f5(S0t(u))){await c();return}if(!Sd()){await c();return}if(Uy(Jp(u.req.header("authorization"),u.req.header("cookie")))){await c();return}return u.json({error:"LAN_AUTH_REQUIRED"},401)}),a.all("/api/trpc/*",u=>kBe({endpoint:"/api/trpc",req:u.req.raw,router:DQe,createContext:()=>NQe({...r(),apiCache:o.getApiCache(),getTvProvider:o.getTvProvider,getMangaProvider:o.getMangaProvider,getJasmr:o.getJasmr,getProviders:o.getProviders,getCatalog:i.getCatalog,discordRPC:Qy,offlineDb:pn,malCacheStore:Ur},u.req.header("authorization"),u.req.header("cookie"))})),a.post("/api/import/mal-xml",async u=>{let c=r(),l=await u.req.parseBody().catch(()=>({})),d=l.xmlfile,h=d instanceof File?Buffer.from(await d.arrayBuffer()):void 0,f=qCe(h,{erase:l.erase,useOfflineDb:l.useOfflineDb,skipFallback:l.skipFallback});if(!f.ok)return u.json(f.body,f.status);let g=new TransformStream,p=g.writable.getWriter(),m=new TextEncoder,I=!1;u.req.raw.signal.addEventListener("abort",()=>{I=!0},{once:!0});let C=(B,Q)=>{I||p.write(m.encode(`event: ${B}
986
986
  data: ${JSON.stringify(Q)}
987
987
 
988
988
  `)).catch(()=>{})};return WCe(c.db,f.import,C).finally(()=>{p.close().catch(()=>{})}),new Response(g.readable,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}),a.get("/api/providers",u=>(u.header("Cache-Control","public, max-age=300"),u.json(i.getCatalog()))),a.post("/api/providers/refresh",async u=>{try{return u.json(await i.refresh())}catch(c){return u.json({error:c.message||"refresh failed"},500)}}),a.get("/api/tracker/anilist/callback",u=>u.html(`<!doctype html>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dango-server",
3
3
  "private": true,
4
- "version": "3.7.2",
4
+ "version": "3.7.4",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=22.12.0"
@@ -1 +0,0 @@
1
- ._sortSelect_12kj5_1{padding:var(--space-2-5) var(--space-3);border:var(--space-px) solid var(--border-primary);border-radius:var(--radius-md);background:var(--bg-secondary);color:var(--text-primary);font-size:var(--font-size-sm);cursor:pointer}._grid_12kj5_11{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--size-250),1fr));gap:var(--space-4);transition:opacity var(--transition-fast)}._fetching_12kj5_18{opacity:.45;pointer-events:none}._card_12kj5_23{display:flex;flex-direction:column;text-align:left;padding:0;border:none;background:none;cursor:pointer;color:inherit}._thumbWrap_12kj5_34{position:relative;aspect-ratio:4 / 3;border-radius:var(--radius-lg);overflow:hidden;background:var(--bg-tertiary);transition:transform var(--transition-fast) var(--ease-smooth),box-shadow var(--transition-fast) var(--ease-smooth)}._card_12kj5_23:hover ._thumbWrap_12kj5_34{transform:translateY(calc(var(--space-1) * -1));box-shadow:var(--shadow-lg)}._thumb_12kj5_34{width:100%;height:100%;object-fit:cover;display:block}._thumbPlaceholder_12kj5_57{display:flex;align-items:center;justify-content:center;color:var(--text-tertiary);font-size:var(--font-size-sm)}._adultBadge_12kj5_65{position:absolute;top:var(--space-2);right:var(--space-2);padding:var(--space-2px) var(--space-2);border-radius:var(--radius-full);background:var(--color-danger-bg);color:var(--text-primary);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold)}._cardTitle_12kj5_77{margin:var(--space-2) 0 var(--space-2px);font-size:var(--font-size-sm);color:var(--text-primary);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}._cardMeta_12kj5_87{margin:0;font-size:var(--font-size-xs);color:var(--text-tertiary)}._asmrCardWrap_12kj5_93{position:relative;min-width:0}._bookmarkBtn_12kj5_98{position:absolute;top:var(--space-2);right:var(--space-2);width:28px;height:28px;border-radius:50%;background-color:#0009;color:#fff;border:1px solid rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:0;transition:opacity .15s ease,background-color .15s ease,transform .15s ease;z-index:20}._asmrCardWrap_12kj5_93:hover ._bookmarkBtn_12kj5_98,._asmrCardWrap_12kj5_93:focus-within ._bookmarkBtn_12kj5_98,._bookmarkBtn_12kj5_98._bookmarked_12kj5_122{opacity:1}._bookmarkBtn_12kj5_98:hover{background-color:var(--accent);border-color:var(--accent);color:var(--accent-text);transform:scale(1.08)}._bookmarkBtn_12kj5_98._bookmarked_12kj5_122{background-color:var(--accent);border-color:var(--accent);color:var(--accent-text)}@media(hover:none),(pointer:coarse){._bookmarkBtn_12kj5_98{opacity:1}}._statusMsg_12kj5_145{text-align:center;color:var(--text-secondary);padding:var(--space-8) 0}._skeletonCard_12kj5_153{display:flex;flex-direction:column}._skeletonThumb_12kj5_158{aspect-ratio:4 / 3;border-radius:var(--radius-lg);background:var(--bg-tertiary)}._skeletonLine_12kj5_164{height:var(--space-3);border-radius:var(--radius-xs);margin-top:var(--space-2);background:var(--bg-tertiary)}._shimmer_12kj5_171{position:relative;overflow:hidden}._shimmer_12kj5_171:after{content:"";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,var(--shimmer-highlight),transparent);animation:_skeleton-wave_12kj5_1 var(--duration-shimmer) infinite}._pagination_12kj5_185{display:flex;align-items:center;justify-content:center;gap:var(--space-4);margin-top:var(--space-6)}._pageBtn_12kj5_193{padding:var(--space-2) var(--space-5);border:var(--space-px) solid var(--border-primary);border-radius:var(--radius-md);background:var(--bg-elevated);color:var(--text-primary);cursor:pointer}._pageBtn_12kj5_193:disabled{opacity:.4;cursor:not-allowed}._pageIndicator_12kj5_207{color:var(--text-secondary);font-size:var(--font-size-sm)}._matureToggleWrap_12kj5_212{display:flex;align-items:center;gap:var(--space-2);margin-left:auto}._matureLabel_12kj5_219{font-size:var(--font-size-xs);font-weight:var(--font-weight-bold);color:var(--text-secondary)}._translateToggleWrap_12kj5_225{display:flex;align-items:center;gap:var(--space-2);margin-left:auto}._filterTogglesGroup_12kj5_232{display:flex;align-items:center;gap:var(--space-4);margin-left:auto}._filterTogglesGroup_12kj5_232 ._translateToggleWrap_12kj5_225,._filterTogglesGroup_12kj5_232 ._matureToggleWrap_12kj5_212{margin-left:0}._filterBar_12kj5_244{display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-4)}._filterLabel_12kj5_251{font-size:var(--font-size-sm);color:var(--text-secondary)}._detailOverlay_12kj5_256{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;background:var(--bg-overlay-heavy);-webkit-backdrop-filter:blur(var(--blur-sm));backdrop-filter:blur(var(--blur-sm));padding:var(--space-4)}._detailModal_12kj5_268{position:relative;width:min(var(--size-720),100%);max-height:85vh;overflow-y:auto;border-radius:var(--radius-xl);border:var(--space-px) solid var(--border-secondary);background:var(--bg-elevated);box-shadow:var(--glass-shadow);padding:var(--space-5)}._detailClose_12kj5_280{position:absolute;top:var(--space-3);right:var(--space-3);display:flex;align-items:center;justify-content:center;width:var(--size-34);height:var(--size-34);border:none;border-radius:var(--radius-full);background:var(--bg-tertiary);color:var(--text-primary);cursor:pointer}._detailHeader_12kj5_296{display:flex;flex-direction:column;gap:var(--space-4)}._detailCover_12kj5_302{width:100%;aspect-ratio:16 / 9;object-fit:cover;border-radius:var(--radius-lg);flex-shrink:0;background:var(--bg-tertiary)}._detailInfo_12kj5_311{min-width:0}._detailTitle_12kj5_315{margin:0 0 var(--space-2);font-size:var(--font-size-lg);color:var(--text-primary);line-height:1.35}._detailRj_12kj5_322{margin:0 0 var(--space-3);font-size:var(--font-size-xs);color:var(--text-tertiary)}._metaRow_12kj5_328{margin:0 0 4px;font-size:var(--font-size-sm);color:var(--text-secondary)}._metaLabel_12kj5_334{display:inline-block;min-width:var(--space-16);color:var(--text-tertiary)}._tagChips_12kj5_340{display:inline-flex;flex-wrap:wrap;gap:var(--space-1)}._tagChip_12kj5_340{padding:var(--space-2px) var(--space-2);border-radius:var(--radius-full);background:var(--bg-tertiary);color:var(--text-secondary);font-size:var(--font-size-xs)}._npOverlay_12kj5_356{position:fixed;inset:0;z-index:var(--z-overlay);display:flex;flex-direction:column;background:var(--bg-dark);overflow:hidden;overscroll-behavior:contain}body.asmr-player-open{overflow:hidden}._playerBarDocked_12kj5_371{position:static;transform:translateY(0);max-height:var(--size-240);overflow:visible;transition:transform var(--transition-emphasized),max-height var(--transition-emphasized),opacity var(--transition-base),padding var(--transition-base),border-width var(--transition-base);will-change:transform,max-height,opacity}._playerBarDockedHidden_12kj5_385{max-height:0!important;opacity:0;transform:translateY(18%);padding-top:0!important;padding-bottom:0!important;border-width:0!important;pointer-events:none;overflow:hidden!important}._npOverlayControlsHidden_12kj5_396 ._npArrow_12kj5_396,._npOverlayControlsHidden_12kj5_396 ._npImageCount_12kj5_397{opacity:0;pointer-events:none;transform:translateY(-50%) scale(.96);transition:opacity var(--transition-base),transform var(--transition-emphasized)}._npOverlayControlsHidden_12kj5_396 ._npStage_12kj5_406{cursor:pointer}._npStage_12kj5_406{position:relative;flex:1;min-height:0;display:flex;align-items:center;justify-content:center;background:var(--bg-black);transition:padding var(--transition-emphasized)}._npStage_12kj5_406,._sliderViewport_12kj5_422,._slide_12kj5_422,._slideImg_12kj5_424{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;outline:none;-webkit-user-select:none;user-select:none}._npStage_12kj5_406:focus,._sliderViewport_12kj5_422:focus,._slide_12kj5_422:focus,._slideImg_12kj5_424:focus{outline:none!important;box-shadow:none!important}._slideImg_12kj5_424::-moz-focus-inner{border:0}._npStageBlank_12kj5_443{background:var(--bg-dark)}._npStageImg_12kj5_447{max-width:min(92vw,var(--size-900));max-height:100%;object-fit:contain;-webkit-user-select:none;user-select:none}._sliderViewport_12kj5_422{position:absolute;inset:0;overflow:hidden}._sliderTrack_12kj5_462{display:flex;height:100%;transition:transform var(--transition-normal);will-change:transform}._slide_12kj5_422{flex:0 0 100%;height:100%;display:flex;align-items:center;justify-content:center;padding:var(--space-5) var(--size-84);box-sizing:border-box;transition:padding var(--transition-emphasized)}._slideImg_12kj5_424{max-width:100%;max-height:100%;object-fit:contain;-webkit-user-select:none;user-select:none;opacity:0;transform:scale(.985);-webkit-tap-highlight-color:transparent;outline:none;transition:opacity var(--transition-base),transform var(--transition-emphasized),max-height var(--transition-emphasized)}._slideImgLoaded_12kj5_495{opacity:1;transform:none}._slideSpinner_12kj5_500{position:absolute;left:50%;top:50%;width:var(--size-44);height:var(--size-44);margin:calc(var(--size-22) * -1) 0 0 calc(var(--size-22) * -1);border-radius:var(--radius-full);border:var(--space-2px) solid var(--border-strong);border-top-color:var(--text-primary);animation:_spin_12kj5_1 var(--duration-spin) linear infinite;pointer-events:none}@keyframes _spin_12kj5_1{to{transform:rotate(360deg)}}._npArrow_12kj5_396{position:absolute;top:50%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center;width:var(--size-48);height:var(--size-48);border:var(--space-px) solid var(--border-strong);border-radius:var(--radius-full);background:var(--bg-scrim);-webkit-backdrop-filter:blur(var(--blur-md));backdrop-filter:blur(var(--blur-md));box-shadow:var(--shadow-scrim);color:var(--text-primary);cursor:pointer;transition:background var(--transition-fast),opacity var(--transition-fast)}._npArrow_12kj5_396:hover:not(:disabled){background:var(--bg-scrim-strong)}._npArrow_12kj5_396:disabled{opacity:.25;cursor:not-allowed}._npArrowLeft_12kj5_550{left:var(--space-5)}._npArrowRight_12kj5_554{right:var(--space-5)}._npImageCount_12kj5_397{position:absolute;top:calc(var(--space-4) + var(--space-16));right:var(--space-4);padding:var(--space-2px) var(--space-2-5);border-radius:var(--radius-full);background:var(--bg-overlay-strong);color:var(--text-secondary);font-size:var(--font-size-xs);font-variant-numeric:tabular-nums;z-index:var(--z-base)}._chapterPanel_12kj5_571{position:absolute;bottom:calc(100% + var(--space-2-5));right:var(--space-5);width:min(var(--size-440),calc(100vw - var(--space-8)));max-height:min(46vh,var(--size-420));overflow-y:auto;background:var(--bg-elevated);border:var(--space-px) solid var(--border-secondary);border-radius:var(--radius-lg);box-shadow:var(--shadow-panel);padding:var(--space-1-5);z-index:var(--z-dropdown)}._chapterRow_12kj5_586{display:flex;align-items:baseline;gap:var(--space-3);width:100%;text-align:left;padding:var(--space-2) var(--space-3);border:none;border-radius:var(--radius-md);background:transparent;color:var(--text-primary);cursor:pointer;font-size:var(--font-size-sm)}._chapterRow_12kj5_586:hover{background:var(--bg-tertiary)}._chapterRowActive_12kj5_605{background:var(--bg-selected)}._chapterRowTime_12kj5_609{flex-shrink:0;color:var(--text-tertiary);font-variant-numeric:tabular-nums}._chapterRowActive_12kj5_605 ._chapterRowTime_12kj5_609{color:var(--accent);font-weight:var(--font-weight-semibold)}._chapterRowLabel_12kj5_620{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._npBackdrop_12kj5_626{position:fixed;inset:0;z-index:-1}._playerBtn_12kj5_632._playerBtnActive_12kj5_632{color:var(--accent);background:color-mix(in srgb,var(--accent) 20%,transparent);box-shadow:0 0 10px var(--accent-glow)}._tracksSection_12kj5_638{margin-top:var(--space-5)}._tracksHeading_12kj5_642{font-size:var(--font-size-base);color:var(--text-primary);margin:0 0 var(--space-2)}._trackList_12kj5_648{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-1-5)}._trackRow_12kj5_657{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-2) var(--space-3);border:var(--space-px) solid var(--border-secondary);border-radius:var(--radius-md);background:var(--bg-secondary);color:var(--text-primary);cursor:pointer;font-size:var(--font-size-sm)}._trackRow_12kj5_657:hover{border-color:var(--accent)}._trackIcon_12kj5_675{color:var(--accent);flex-shrink:0}._trackLabel_12kj5_680{flex:1;text-align:left}._trackType_12kj5_685{font-size:var(--font-size-xs);color:var(--text-tertiary)}._noTracks_12kj5_690{color:var(--text-secondary);font-size:var(--font-size-sm)}._playAllBtn_12kj5_695{display:inline-flex;align-items:center;gap:var(--space-2);padding:var(--space-2-5) var(--space-5);border:none;border-radius:var(--radius-md);background:var(--accent);color:var(--accent-text);font-size:var(--font-size-base);cursor:pointer}._detailActions_12kj5_708{display:flex;flex-wrap:wrap;gap:var(--space-3);margin-top:var(--space-5)}._playerBar_12kj5_371{position:fixed;left:0;right:0;bottom:0;z-index:var(--z-overlay);display:flex;align-items:center;gap:var(--space-4);padding:var(--space-2-5) var(--space-5);padding-bottom:calc(var(--space-2-5) + env(safe-area-inset-bottom,0px));background:var(--glass-bg);border-top:var(--space-px) solid var(--glass-border);-webkit-backdrop-filter:blur(var(--blur-lg));backdrop-filter:blur(var(--blur-lg))}._playerActions_12kj5_731{display:flex;align-items:center;gap:var(--space-2)}._playerInfo_12kj5_737{min-width:0;width:var(--size-240)}._playerTitle_12kj5_742{margin:0;font-size:var(--font-size-sm);color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._playerTrack_12kj5_751{margin:var(--space-2px) 0 0;font-size:var(--font-size-xs);color:var(--text-tertiary)}._playerControls_12kj5_757{display:flex;align-items:center;gap:var(--space-3);flex:1}._seekRow_12kj5_764{display:flex;align-items:center;gap:var(--space-3);flex:1;min-width:0}._playerButtons_12kj5_772{display:flex;align-items:center;gap:var(--space-2)}._playerBtn_12kj5_632{display:flex;align-items:center;justify-content:center;width:var(--size-36);height:var(--size-36);border:none;border-radius:var(--radius-full);background:transparent;color:var(--text-primary);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast),transform var(--transition-quick),opacity var(--transition-fast)}._playerBtn_12kj5_632:disabled{opacity:.35;cursor:not-allowed}@media(hover:hover)and (pointer:fine){._playerBtn_12kj5_632:hover:not(:disabled){background:var(--bg-hover);color:var(--text-primary)}._seekBtn_12kj5_807:hover:not(:disabled){background:var(--bg-hover-strong);color:var(--accent)}._seekBtn_12kj5_807:hover ._seekBtnLabel_12kj5_812{background:var(--accent);color:var(--accent-text)}._playBtn_12kj5_817:hover:not(:disabled){background:var(--accent-light);color:var(--accent-text);box-shadow:0 0 12px var(--accent-glow)}}._playerBtn_12kj5_632:active:not(:disabled){transform:scale(.94);transition:transform var(--transition-quick),background var(--transition-quick)}._playBtn_12kj5_817{background:var(--accent);color:var(--accent-text);width:var(--size-42);height:var(--size-42)}._playBtn_12kj5_817:disabled{opacity:1}._seekBtn_12kj5_807{position:relative;font-size:var(--font-size-sm);color:var(--text-primary)}._seekBtnLabel_12kj5_812{position:absolute;bottom:var(--space-px);left:50%;transform:translate(-50%);font-size:var(--font-size-2xs);font-weight:var(--font-weight-bold);line-height:1;letter-spacing:-.02em;background:var(--bg-overlay);color:var(--text-primary);padding:var(--space-px) var(--space-2px);border-radius:var(--radius-sm);pointer-events:none}._seekBar_12kj5_864,._volumeBar_12kj5_865{-webkit-appearance:none;appearance:none;height:var(--size-18);background:transparent;cursor:pointer}._seekBar_12kj5_864::-webkit-slider-runnable-track,._volumeBar_12kj5_865::-webkit-slider-runnable-track{width:100%;height:var(--space-1);border-radius:var(--space-1)}._seekBar_12kj5_864::-webkit-slider-runnable-track{background:linear-gradient(to right,var(--accent) 0%,var(--accent) var(--played-percent, 0%),var(--track-buffered) var(--played-percent, 0%),var(--track-buffered) var(--buffered-percent, 0%),var(--track-bg) var(--buffered-percent, 0%),var(--track-bg) 100%)}._volumeBar_12kj5_865::-webkit-slider-runnable-track{background:linear-gradient(to right,var(--accent) 0%,var(--accent) var(--volume-percent, 100%),var(--track-bg) var(--volume-percent, 100%),var(--track-bg) 100%)}._seekBar_12kj5_864::-moz-range-track{width:100%;height:var(--space-1);border-radius:var(--space-1);background:linear-gradient(to right,var(--accent) 0%,var(--accent) var(--played-percent, 0%),var(--track-buffered) var(--played-percent, 0%),var(--track-buffered) var(--buffered-percent, 0%),var(--track-bg) var(--buffered-percent, 0%),var(--track-bg) 100%)}._volumeBar_12kj5_865::-moz-range-track{width:100%;height:var(--space-1);border-radius:var(--space-1);background:linear-gradient(to right,var(--accent) 0%,var(--accent) var(--volume-percent, 100%),var(--track-bg) var(--volume-percent, 100%),var(--track-bg) 100%)}._seekBar_12kj5_864::-webkit-slider-thumb,._volumeBar_12kj5_865::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;height:var(--space-3);width:var(--space-3);border-radius:var(--radius-full);background:var(--text-primary);margin-top:calc(var(--space-1) * -1);box-shadow:var(--shadow-thumb)}._seekBar_12kj5_864::-moz-range-thumb,._volumeBar_12kj5_865::-moz-range-thumb{height:var(--space-3);width:var(--space-3);border:none;border-radius:var(--radius-full);background:var(--text-primary);box-shadow:var(--shadow-thumb)}._seekBar_12kj5_864{flex:1;min-width:0}._timeLabel_12kj5_957{font-size:var(--font-size-xs);color:var(--text-secondary);font-variant-numeric:tabular-nums}._playerRight_12kj5_963{display:flex;align-items:center;gap:var(--space-2)}._volumeIcon_12kj5_969{color:var(--text-secondary)}._volumeBar_12kj5_865{width:var(--size-90)}@media(max-width:768px){._detailHeader_12kj5_296{flex-direction:column}._detailCover_12kj5_302{width:100%}._filterBar_12kj5_244{flex-wrap:wrap}._filterBar_12kj5_244 ._sortSelect_12kj5_1{flex:1 1 var(--size-140);min-width:0}._pageWithPlayer_12kj5_995{padding-bottom:var(--layout-player-mobile)}._playerBar_12kj5_371{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:"toggle info actions" "controls controls controls" "volume volume volume";align-items:center;column-gap:var(--space-2);row-gap:var(--space-2px);padding:var(--space-2) var(--space-3);padding-bottom:calc(var(--space-2) + env(safe-area-inset-bottom,0px))}._playerToggle_12kj5_1013{grid-area:toggle}._playerInfo_12kj5_737{grid-area:info;width:auto}._playerActions_12kj5_731{grid-area:actions;margin-right:calc(var(--space-1-5) * -1)}._playerControls_12kj5_757{grid-area:controls;gap:var(--space-2);min-width:0;justify-content:center}._playerRight_12kj5_963{grid-area:volume;width:100%}._volumeBar_12kj5_865{flex:1;width:auto;height:var(--space-6)}._slide_12kj5_422{padding:0 var(--size-52)}._npArrow_12kj5_396{width:var(--size-42);height:var(--size-42);opacity:.85}._npArrowLeft_12kj5_550{left:var(--space-2)}._npArrowRight_12kj5_554{right:var(--space-2)}._npImageCount_12kj5_397{top:calc(var(--space-3) + env(safe-area-inset-top,0px));right:var(--space-3)}._chapterPanel_12kj5_571{right:var(--space-3);max-height:55vh}}@media(max-width:768px)and (orientation:portrait){._npStage_12kj5_406{height:100%}._sliderViewport_12kj5_422{inset:0}._slide_12kj5_422{padding:0}._npOverlay_12kj5_356:not(._npOverlayControlsHidden_12kj5_396) ._slide_12kj5_422{padding-bottom:var(--space-2-5)}._npOverlay_12kj5_356:not(._npOverlayControlsHidden_12kj5_396) ._slideImg_12kj5_424{max-height:calc(100% - var(--space-2-5))}._slideImg_12kj5_424{width:auto;height:auto;max-width:100%;max-height:100%;object-fit:contain;object-position:center}._playerBar_12kj5_371{grid-template-areas:"toggle info actions" "controls controls controls" "volume volume volume";row-gap:var(--space-2-5);padding:var(--space-2-5) var(--space-3);padding-bottom:calc(var(--space-2-5) + env(safe-area-inset-bottom,0px))}._playerControls_12kj5_757{flex-direction:column;align-items:center;gap:var(--space-2);width:100%}._playerButtons_12kj5_772{justify-content:center;width:100%;gap:var(--space-1-5)}._seekRow_12kj5_764{width:100%;justify-content:center}._seekRow_12kj5_764 ._seekBar_12kj5_864{flex:1}._playerRight_12kj5_963{justify-content:center;width:100%}._playerRight_12kj5_963 ._volumeBar_12kj5_865{flex:1;width:100%;max-width:var(--size-320)}}
@@ -1 +0,0 @@
1
- ._controls_1ljql_1{display:flex;align-items:stretch;gap:1rem;flex-wrap:wrap;width:100%}._titleContainer_1ljql_9{display:flex;flex-direction:column;gap:.75rem}._scheduleInfo_1ljql_15{display:flex;gap:1rem;font-size:.95rem;color:var(--text-tertiary);align-items:center}._status_1ljql_23{background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent-light);border:1px solid color-mix(in srgb,var(--accent) 20%,transparent);padding:.35rem .85rem;border-radius:var(--radius-full);font-weight:700;font-size:.75rem;text-transform:uppercase;letter-spacing:.05em}._nextEpisode_1ljql_35{background:#ffffff0d;color:var(--text-secondary);padding:.35rem .85rem;border-radius:var(--radius-full);font-size:.8rem;font-weight:600;border:1px solid var(--glass-border)}._watchlistBtn_1ljql_45{background:#ffffff0d;color:var(--text-primary);border:1px solid rgba(255,255,255,.1);padding:.65rem 1.25rem;border-radius:var(--radius-full);font-weight:600;cursor:pointer;transition:all var(--transition-normal);display:flex;align-items:center;gap:.6rem;font-size:.85rem;flex:0 1 auto;min-width:120px;justify-content:center;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}._watchlistBtn_1ljql_45:hover{background:#ffffff1f;border-color:#ffffff40;transform:translateY(-2px);box-shadow:0 4px 12px #00000040}._watchlistBtn_1ljql_45._inList_1ljql_72{background:color-mix(in srgb,var(--color-success) 12%,transparent);border-color:color-mix(in srgb,var(--color-success) 35%,transparent);color:var(--color-success)}._watchlistBtn_1ljql_45._inList_1ljql_72:hover{background:color-mix(in srgb,var(--color-success) 18%,transparent);border-color:var(--color-success)}._queueBtn_1ljql_83{background:color-mix(in srgb,var(--accent) 8%,transparent);border-color:color-mix(in srgb,var(--accent) 25%,transparent);color:var(--accent-light)}._queueBtn_1ljql_83:hover{background:color-mix(in srgb,var(--accent) 14%,transparent);border-color:color-mix(in srgb,var(--accent) 45%,transparent);color:var(--accent-lighter)}._queueActive_1ljql_95{background:color-mix(in srgb,var(--accent) 15%,transparent);border-color:color-mix(in srgb,var(--accent) 60%,transparent);color:var(--accent-lighter)}._modeToggleBtn_1ljql_101{background:#ffffff0d;color:var(--text-primary);border-color:#ffffff1a;flex:0 1 auto}._modeToggleActive_1ljql_108{background:color-mix(in srgb,var(--color-info) 12%,transparent);border-color:color-mix(in srgb,var(--color-info) 45%,transparent);color:#dbeafe}._modeToggleActive_1ljql_108:hover{background:color-mix(in srgb,var(--color-info) 18%,transparent);border-color:color-mix(in srgb,var(--color-info) 65%,transparent)}._watchlistBtn_1ljql_45:disabled{opacity:.7;cursor:wait;transform:none}._watchlistBtn_1ljql_45:disabled:hover{transform:none}._markWatchedBtn_1ljql_129{background:color-mix(in srgb,var(--color-info) 8%,transparent);border-color:color-mix(in srgb,var(--color-info) 25%,transparent);color:#93c5fd;flex:0 1 auto;justify-content:center}._markWatchedBtn_1ljql_129:hover{background:color-mix(in srgb,var(--color-info) 14%,transparent);border-color:color-mix(in srgb,var(--color-info) 45%,transparent);color:#dbeafe}._markWatchedDone_1ljql_143{background:color-mix(in srgb,var(--color-success) 12%,transparent);border-color:color-mix(in srgb,var(--color-success) 35%,transparent);color:var(--color-success)}._markWatchedDone_1ljql_143:hover{background:color-mix(in srgb,var(--color-success) 18%,transparent);border-color:var(--color-success)}._streamPanel_1ljql_154{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.875rem 1rem;align-items:center;background:var(--glass-bg);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--glass-border);border-radius:var(--radius-lg);padding:1.25rem;box-shadow:var(--glass-shadow)}._streamPanel_1ljql_154 ._desktopEpisodeActions_1ljql_168{flex:0 0 auto;align-self:center;margin:0}._streamPanel_1ljql_154 ._sourceLoader_1ljql_174{grid-column:1 / -1;animation:none}._streamPanel_1ljql_154>:last-child:not(:first-child){grid-column:1 / -1}._streamPanel_1ljql_154 select{max-width:320px}._episodeActions_1ljql_187{display:flex;flex-wrap:wrap;gap:.75rem;margin:.5rem 0 .25rem}._desktopEpisodeActions_1ljql_168{flex:1 1 320px;justify-content:flex-end;align-self:flex-end;margin:0}._mobileEpisodeActions_1ljql_201{margin:.5rem 0 .25rem}._episodeNavBtn_1ljql_205{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border:1px solid var(--glass-border);border-radius:var(--radius-lg);padding:.7rem 1rem;background:#ffffff0d;color:var(--text-primary);cursor:pointer;font-size:.9rem;font-weight:700;transition:background-color var(--transition-fast),border-color var(--transition-fast),color var(--transition-fast)}._episodeNavBtn_1ljql_205:hover:not(:disabled){border-color:var(--text-secondary);background:#ffffff14}._episodeNavBtn_1ljql_205:disabled{opacity:.45;cursor:not-allowed;transform:none}._episodeNavBtn_1ljql_205._primary_1ljql_235{background:linear-gradient(135deg,var(--accent) 0%,var(--accent-dark) 100%);border-color:transparent;color:#fff}._episodeNavBtn_1ljql_205._primary_1ljql_235:hover:not(:disabled){background:linear-gradient(135deg,var(--accent-light) 0%,var(--accent) 100%)}._episodeNavBtn_1ljql_205._secondary_1ljql_245{background:#ffffff0a}._episodePickerBtn_1ljql_249{display:none}._queueCountdown_1ljql_253{position:absolute;left:50%;bottom:1.5rem;transform:translate(-50%);z-index:75;padding:.7rem 1rem;border:1px solid var(--glass-border);border-radius:var(--radius-md);background:#121216eb;color:#fff;font-weight:700;box-shadow:var(--glass-shadow)}._speedBoostBadge_1ljql_268{position:absolute;top:1.5rem;left:50%;transform:translate(-50%);z-index:75;display:flex;align-items:center;gap:.7rem;padding:.65rem 1rem;border:1px solid color-mix(in srgb,var(--accent) 45%,transparent);border-radius:var(--radius-md);background:#121216eb;color:#f5f3ff;font-weight:800;letter-spacing:.06em;text-transform:none;box-shadow:var(--glass-shadow);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}._speedBoostBadge_1ljql_268 span{line-height:1}._speedBoostBadge_1ljql_268 svg{display:block;flex-shrink:0}._videoContainer_1ljql_299{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#000;display:flex;justify-content:center;align-items:center;container-type:inline-size}._loadingOverlay_1ljql_312{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;z-index:10;background:#00000080;border-radius:inherit}._loadingDots_1ljql_326{display:flex;gap:10px}._dot_1ljql_331{width:12px;height:12px;border-radius:50%;background-color:var(--accent);animation:_bounce_1ljql_1 1.4s infinite ease-in-out both;box-shadow:0 0 10px var(--accent-glow)}._dot_1ljql_331:nth-child(1){animation-delay:-.32s}._dot_1ljql_331:nth-child(2){animation-delay:-.16s}._bufferingOverlay_1ljql_348{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);pointer-events:none;z-index:20}._bufferingSpinner_1ljql_357{width:50px;height:50px;border:4px solid rgba(255,255,255,.3);border-radius:50%;border-top-color:var(--accent);animation:_spin_1ljql_444 1s ease-in-out infinite}._videoIframe_1ljql_366{width:100%;height:100%;border:none;position:absolute;top:0;left:0;object-fit:cover;border-radius:inherit}._videoContainer_1ljql_299 video{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;object-fit:contain;background-color:#000;border-radius:inherit}._videoContainer_1ljql_299 video._videoElementHidden_1ljql_389{opacity:0;pointer-events:none}._upscalerCanvas_1ljql_394{position:absolute;top:0;left:0;width:100%;height:100%;z-index:2;object-fit:contain;opacity:0;pointer-events:none;border-radius:inherit}._upscalerCanvas_1ljql_394._upscalerActive_1ljql_407{opacity:1}._upscalerStatusBadge_1ljql_411{position:absolute;top:12px;right:12px;z-index:4;background:#000000a6;color:var(--text-primary);font-size:.75rem;font-weight:600;padding:.35em .8em;border-radius:999px;border:1px solid var(--glass-border);pointer-events:none}._subtitleOverlay_1ljql_426{position:absolute;top:0;left:0;width:100%;height:100%;z-index:3;pointer-events:none;overflow:hidden;border-radius:inherit}._sourceLoader_1ljql_174{padding:.75rem;display:flex;justify-content:center}._spinner_1ljql_444{width:40px;height:40px;border:4px solid rgba(255,255,255,.1);border-left-color:var(--accent);border-radius:50%;animation:_spin_1ljql_444 1s linear infinite}@media(max-width:768px){._titleContainer_1ljql_9 h1{font-size:1.25rem}._episodeActions_1ljql_187{margin-top:.25rem}._controls_1ljql_1{gap:.5rem}._watchlistBtn_1ljql_45,._queueBtn_1ljql_83,._markWatchedBtn_1ljql_129,._modeToggleBtn_1ljql_101{flex:1 1 calc(50% - .25rem);min-width:0;padding:.5rem .75rem;font-size:.78rem;gap:.4rem}._episodeNavBtn_1ljql_205{flex:1 1 calc(50% - .25rem);min-width:0;padding:.45rem .75rem;font-size:.8rem;min-height:44px}._episodePickerBtn_1ljql_249{display:inline-flex;flex-basis:100%;padding:.4rem .75rem;font-size:.78rem;min-height:44px}._desktopEpisodeActions_1ljql_168{display:none}._mobileEpisodeActions_1ljql_201{display:flex}._streamPanel_1ljql_154{grid-template-columns:minmax(0,1fr)}._errorOverlay_1ljql_505{padding:1rem;gap:.5rem;overflow-y:auto}._errorOverlay_1ljql_505 p{font-size:1rem}._retryButton_1ljql_515{padding:.5rem 1.25rem;font-size:.9rem;margin-top:0}}@media(min-width:769px){._mobileEpisodeActions_1ljql_201{display:none}}._detailsToggleBtn_1ljql_528{background:transparent;border:1px solid var(--border-accent);color:var(--accent-light);padding:.5rem .9rem;border-radius:var(--radius-full);cursor:pointer;font-size:.85rem;font-weight:700;transition:all var(--transition-fast);display:flex;align-items:center;gap:.4rem;margin-top:1rem;width:fit-content}._detailsToggleBtn_1ljql_528:hover{background:var(--accent-subtle);color:var(--accent-lighter);border-color:var(--accent)}._descriptionSection_1ljql_551{margin-top:1.75rem;padding:1.5rem;background:#ffffff05;border-radius:var(--radius-lg);border:1px solid var(--glass-border)}._descriptionSection_1ljql_551._synopsisFlat_1ljql_559{margin-top:0;padding:0;background:none;border:0;border-radius:0;min-width:0}._synopsisFlat_1ljql_559 p{max-width:80ch}._descriptionSection_1ljql_551 h3{font-size:.95rem;font-weight:800;margin-bottom:.85rem;color:var(--text-primary);text-transform:uppercase;letter-spacing:.05em;display:flex;align-items:center;gap:.75rem}._descriptionSection_1ljql_551 h3:before{content:"";width:4px;height:16px;background:var(--accent);border-radius:var(--radius-full);box-shadow:0 0 10px var(--accent-glow)}._videoContainer_1ljql_299._fullscreenActive_1ljql_593{cursor:none;border-radius:0}._videoContainer_1ljql_299:fullscreen,._videoContainer_1ljql_299:-webkit-full-screen{width:100vw;height:100vh;border-radius:0}._videoContainer_1ljql_299:fullscreen video,._videoContainer_1ljql_299:fullscreen canvas,._videoContainer_1ljql_299:-webkit-full-screen video,._videoContainer_1ljql_299:-webkit-full-screen canvas{border-radius:0}._errorOverlay_1ljql_505{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;background:#000c;color:#fff;z-index:30;padding:2rem;text-align:center;gap:1rem;border-radius:inherit}._errorOverlay_1ljql_505 p{margin:0;font-size:1.2rem;font-weight:500}._errorSubtext_1ljql_637{color:var(--text-tertiary)!important;font-size:.9rem!important}._retryButton_1ljql_515{background:var(--accent);color:var(--accent-text);border:none;padding:.6rem 2rem;border-radius:var(--radius-md);font-weight:600;cursor:pointer;transition:all .2s;margin-top:.5rem;box-shadow:0 4px 12px var(--accent-glow)}._retryButton_1ljql_515:hover{background:var(--accent-light);transform:translateY(-2px)}._playerPageLayout_q7ra9_1{display:grid;grid-template-columns:320px 1fr;gap:2.5rem;padding:2rem;width:100%;max-width:1800px;margin:0 auto;align-items:start;min-height:calc(100vh - var(--header-height));background-color:transparent;animation:_fadeIn_q7ra9_1 .8s var(--ease-smooth)}._playerPageLayout_q7ra9_1._noSidebar_q7ra9_15{grid-template-columns:minmax(0,1fr)}._episodeSidebar_q7ra9_19{background:var(--glass-bg);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--glass-border);border-radius:var(--radius-lg);overflow:visible;display:flex;flex-direction:column;box-shadow:var(--glass-shadow);animation:_slideUpIn_q7ra9_1 .8s var(--ease-smooth)}._playerMain_q7ra9_32{min-width:0;display:flex;flex-direction:column;gap:1.25rem;animation:_slideUpIn_q7ra9_1 .8s .1s var(--ease-smooth) both}._videoPlayerWrapper_q7ra9_40{width:100%;padding-top:56.25%;background-color:#000;border-radius:0;overflow:clip;isolation:isolate;position:relative;box-shadow:0 20px 50px #00000080;border:1px solid var(--glass-border)}._playerInfoHeader_q7ra9_56{display:flex;gap:2rem;align-items:flex-start}._playerAnimeCard_q7ra9_62{width:160px;flex-shrink:0;border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);border:1px solid var(--glass-border);transform:translateZ(0);aspect-ratio:2/3;height:auto}._playerInfoContainer_q7ra9_74{background:var(--glass-bg);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--glass-border);padding:2rem;border-radius:var(--radius-2xl);box-shadow:var(--glass-shadow);display:flex;flex-direction:column}._infoColumns_q7ra9_86{display:grid;grid-template-columns:minmax(0,1fr);gap:1.5rem 2.5rem;border-top:1px solid var(--border-primary);padding-top:1.5rem;margin-top:1.5rem}._playerAnimeCard_q7ra9_62 img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s cubic-bezier(.2,.8,.2,1)}._playerAnimeCard_q7ra9_62:hover img{transform:scale(1.1)}._videoTitleSection_q7ra9_107{flex:1;display:flex;flex-direction:column;justify-content:flex-start;gap:1.25rem}._videoTitleSection_q7ra9_107 h1{margin:0;font-size:2.25rem;line-height:1.1;font-weight:800;color:var(--text-primary);letter-spacing:-.02em}@keyframes _fadeIn_q7ra9_1{}@keyframes _slideUpIn_q7ra9_1{}body.low-end ._playerPageLayout_q7ra9_1,body.low-end ._episodeSidebar_q7ra9_19,body.low-end ._playerInfoContainer_q7ra9_74{animation:none!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important;box-shadow:none!important;background:var(--bg-secondary)!important}body.low-end ._videoPlayerWrapper_q7ra9_40{box-shadow:none!important;border-color:var(--border-primary)!important}body.low-end ._episodeSidebar_q7ra9_19{background:var(--bg-secondary)!important}._theaterMode_q7ra9_150{display:flex!important;justify-content:center!important;align-items:center!important;position:fixed!important;top:0!important;left:0!important;width:100vw!important;height:100vh!important;min-height:100vh!important;max-width:none!important;padding:2.5rem!important;margin:0!important;background-color:var(--bg-main)!important;backdrop-filter:blur(24px)!important;-webkit-backdrop-filter:blur(24px)!important;animation:_fadeIn_q7ra9_1 .4s var(--ease-smooth)!important;overflow:hidden!important;z-index:var(--z-overlay)!important}._theaterMode_q7ra9_150 ._playerMain_q7ra9_32{width:90%!important;max-width:1200px!important;height:auto!important;aspect-ratio:16/9!important;gap:0!important;margin:auto!important;padding:0!important;animation:_scaleUpIn_q7ra9_1 .4s cubic-bezier(.25,1,.5,1)!important;position:relative!important;z-index:1!important}._theaterMode_q7ra9_150 ._videoPlayerWrapper_q7ra9_40{width:100%!important;height:100%!important;padding-top:0!important;border-radius:0!important;border-color:#ffffff26!important;box-shadow:0 20px 60px color-mix(in srgb,var(--accent) 15%,transparent),0 0 100px #000000e6!important;overflow:hidden!important;position:relative!important}@keyframes _scaleUpIn_q7ra9_1{}body.theater-mode header,body.theater-mode footer{display:none!important}body.theater-mode main{padding:0!important;max-width:none!important;margin:0!important;width:100vw!important;height:100vh!important}body.theater-mode{overflow:hidden!important;background:#000!important}._shell_41rxp_1{position:relative;width:100%;aspect-ratio:16 / 9;background:#000;overflow:clip;isolation:isolate;border-radius:0;container-type:inline-size;touch-action:manipulation;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}@media(max-width:480px)and (orientation:portrait){._shell_41rxp_1{aspect-ratio:1 / 1}}@media(min-width:481px)and (max-width:768px)and (orientation:portrait){._shell_41rxp_1{aspect-ratio:4 / 3}}._shell_41rxp_1:fullscreen,._shell_41rxp_1:-webkit-full-screen{width:100vw;height:100vh;aspect-ratio:auto;border-radius:0}._shell_41rxp_1:fullscreen,._shell_41rxp_1:fullscreen ._stage_41rxp_37,._shell_41rxp_1:fullscreen ._stage_41rxp_37>video,._shell_41rxp_1:fullscreen ._stage_41rxp_37>canvas,._shell_41rxp_1:fullscreen ._stage_41rxp_37>iframe,._shell_41rxp_1:-webkit-full-screen,._shell_41rxp_1:-webkit-full-screen ._stage_41rxp_37,._shell_41rxp_1:-webkit-full-screen ._stage_41rxp_37>video,._shell_41rxp_1:-webkit-full-screen ._stage_41rxp_37>canvas,._shell_41rxp_1:-webkit-full-screen ._stage_41rxp_37>iframe{border-radius:0!important}@media(max-width:900px)and (orientation:landscape){._shell_41rxp_1{aspect-ratio:auto;height:100vh;border-radius:0}}._stage_41rxp_37{position:absolute;inset:0;z-index:1;touch-action:manipulation;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}._stage_41rxp_37>video,._stage_41rxp_37>canvas,._stage_41rxp_37>iframe{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:contain;display:block;background:#000;border:none;border-radius:inherit;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}._shellFill_41rxp_85{position:absolute;inset:0;width:100%;height:100%;aspect-ratio:auto}._shellFullscreen_41rxp_93,._shellFullscreen_41rxp_93 ._stage_41rxp_37,._shellFullscreen_41rxp_93 ._stage_41rxp_37>video,._shellFullscreen_41rxp_93 ._stage_41rxp_37>canvas,._shellFullscreen_41rxp_93 ._stage_41rxp_37>iframe{border-radius:0!important}._shellFullscreen_41rxp_93{width:100vw;height:100vh;aspect-ratio:auto}._uiLayer_41rxp_107{position:absolute;inset:0;z-index:50;pointer-events:none}._uiLayer_41rxp_107>*{pointer-events:auto}._volumeWrap_41rxp_118{display:flex;align-items:center;position:relative}._volumeSlider_41rxp_124{width:0;opacity:0;transform:scaleX(0);transform-origin:left center;transition:width .25s ease,opacity .25s ease,transform .25s ease;cursor:pointer;margin-left:8px;-webkit-appearance:none;appearance:none;background:transparent;height:24px;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}._volumeWrap_41rxp_118[data-expanded=true] ._volumeSlider_41rxp_124{width:84px;opacity:1;transform:scaleX(1)}@media(hover:hover)and (pointer:fine){._volumeWrap_41rxp_118:hover ._volumeSlider_41rxp_124,._volumeSlider_41rxp_124:focus-visible{width:84px;opacity:1;transform:scaleX(1)}}._volumeSlider_41rxp_124::-webkit-slider-runnable-track{width:100%;height:4px;background:linear-gradient(to right,var(--accent) 0%,var(--accent) var(--volume-percent, 0%),rgba(255,255,255,.2) var(--volume-percent, 0%),rgba(255,255,255,.2) 100%);border-radius:4px}._volumeSlider_41rxp_124::-moz-range-track{width:100%;height:4px;background:#fff3;border-radius:4px}._volumeSlider_41rxp_124::-moz-range-progress{height:4px;background:var(--accent);border-radius:4px}._volumeSlider_41rxp_124::-webkit-slider-thumb{-webkit-appearance:none;height:12px;width:12px;border-radius:50%;background:#fff;margin-top:-4px;box-shadow:0 0 5px #00000080}@media(pointer:coarse){._volumeWrap_41rxp_118[data-expanded=true] ._volumeSlider_41rxp_124{width:96px;height:32px}}._centerControls_bxt8c_1{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) scale(1);display:flex;align-items:center;gap:3rem;gap:clamp(1rem,5cqw,3rem);z-index:10;pointer-events:auto;transition:transform .4s cubic-bezier(.2,.8,.2,1)}._centerSkipBtn_bxt8c_15{background:transparent;border:none;border-radius:50%;color:#ffffffe6;width:clamp(2.5rem,6.5cqw,3.5rem);height:clamp(2.5rem,6.5cqw,3.5rem);font-size:clamp(1.1rem,2.8cqw,1.8rem);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .35s cubic-bezier(.34,1.56,.64,1);filter:drop-shadow(0 2px 8px rgba(0,0,0,.85))}._centerSkipBtn_bxt8c_15:hover{color:#fff;transform:scale(1.15);filter:drop-shadow(0 2px 8px rgba(0,0,0,.85)) drop-shadow(0 0 14px var(--accent-glow))}._centerPlayPause_bxt8c_37{display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:50%;color:#fff;width:clamp(3rem,8cqw,5rem);height:clamp(3rem,8cqw,5rem);font-size:clamp(1.4rem,3.4cqw,2.3rem);cursor:pointer;transition:all .35s cubic-bezier(.34,1.56,.64,1);filter:drop-shadow(0 2px 8px rgba(0,0,0,.85))}@media(pointer:coarse){._centerSkipBtn_bxt8c_15{width:clamp(2.75rem,7cqw,3.75rem);height:clamp(2.75rem,7cqw,3.75rem)}}._centerPlayPause_bxt8c_37:hover{transform:scale(1.08);filter:drop-shadow(0 2px 8px rgba(0,0,0,.85)) drop-shadow(0 0 16px var(--accent-glow))}._playIconOffset_bxt8c_65{transform:translate(3px)}._statusArea_1xccu_1{display:flex;flex-direction:column;align-items:flex-start;gap:.6rem;background:var(--bg-secondary);border:1px solid var(--border-primary);padding:.75rem 1.25rem;border-radius:var(--radius-lg);margin-top:.5rem;margin-bottom:0;color:var(--text-secondary);box-shadow:var(--shadow-lg);width:fit-content;max-width:100%;-webkit-user-select:none;user-select:none;flex-wrap:wrap}._toggleBtn_1xccu_20{display:inline-flex;align-items:center;gap:.5rem;background:transparent;border:none;color:var(--text-secondary);font-size:.8rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;cursor:pointer;padding:.15rem .25rem;border-radius:var(--radius-sm);transition:color var(--transition-fast);pointer-events:auto}._toggleBtn_1xccu_20:hover{color:var(--text-primary)}._toggleBtn_1xccu_20 svg{color:var(--accent)}._shortcuts_1xccu_46{display:flex;gap:1.5rem;align-items:center;flex-wrap:wrap;padding-top:.6rem;border-top:1px solid var(--border-primary);width:100%}._shortcutGroup_1xccu_56{display:flex;gap:1rem;align-items:center;flex-wrap:nowrap}._shortcut_1xccu_46{display:flex;align-items:center;gap:.3rem;white-space:nowrap}._key_1xccu_70{background:#ffffff14;padding:.15rem .4rem;border-radius:5px;border:1px solid rgba(255,255,255,.1);font-weight:800;color:var(--text-primary);font-size:.75rem;min-width:1.4rem;height:1.4rem;display:flex;align-items:center;justify-content:center;font-family:var(--font-mono);box-shadow:0 1.5px #0000004d}._key_1xccu_70+._key_1xccu_70{margin-left:-.15rem}._label_1xccu_91{color:var(--text-tertiary);font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.03em}@media(max-width:768px){._statusArea_1xccu_1{display:none}}._episodeListContainer_9tyin_1{display:flex;flex-direction:column;height:100%;min-height:0;background:transparent}._drawerContainer_9tyin_9{height:auto;min-height:100%}._episodeListHeader_9tyin_14{background:transparent;padding:var(--space-6);border-bottom:1px solid var(--glass-border)}._drawerHeader_9tyin_20{position:sticky;top:0;z-index:5;background:#0c0c0ffa;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}._episodeListTitle_9tyin_29{margin:0 0 var(--space-5) 0;font-size:.85rem;font-weight:800;color:var(--text-tertiary);display:flex;align-items:center;gap:var(--space-3);letter-spacing:.1em;text-transform:uppercase}._rangeSelector_9tyin_41{display:flex;flex-wrap:wrap;gap:var(--space-2)}._rangeButton_9tyin_47{background:#ffffff0d;border:1px solid var(--glass-border);color:var(--text-secondary);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);font-size:.8rem;font-weight:600;transition:all var(--transition-fast);cursor:pointer}._rangeButton_9tyin_47:hover{border-color:var(--text-secondary);color:var(--text-primary);background:#ffffff1a}._rangeButton_9tyin_47:focus-visible{outline:none;box-shadow:var(--shadow-focus)}._rangeButton_9tyin_47._active_9tyin_70{background:var(--accent);color:var(--accent-text);border-color:var(--accent)}._episodeList_9tyin_1{flex:1;display:flex;flex-direction:column;padding:var(--space-4);overflow-y:auto;-webkit-overflow-scrolling:touch;min-height:0;touch-action:pan-y;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.14) transparent}._drawerList_9tyin_89{overflow:visible;-webkit-overflow-scrolling:auto;touch-action:pan-y}._episodeList_9tyin_1::-webkit-scrollbar{width:6px}._episodeList_9tyin_1::-webkit-scrollbar-track{background:transparent}._episodeList_9tyin_1::-webkit-scrollbar-thumb{background:#ffffff24;background-clip:padding-box;border-radius:var(--radius-full);border:2px solid transparent}._episodeList_9tyin_1:hover::-webkit-scrollbar-thumb{background-color:#ffffff47}._episodeList_9tyin_1::-webkit-scrollbar-thumb:hover{background-color:var(--accent)}._episodeItem_9tyin_118{padding:var(--space-4) var(--space-5);margin-bottom:var(--space-2);border-radius:var(--radius-lg);cursor:pointer;transition:all var(--transition-normal);color:var(--text-secondary);font-weight:600;display:flex;justify-content:space-between;align-items:center;font-size:.9rem;border:1px solid transparent}._episodeItem_9tyin_118:hover{background:#ffffff0d;color:var(--text-primary);transform:translate(6px);border-color:var(--glass-border)}._episodeItem_9tyin_118:focus-visible{outline:none;box-shadow:var(--shadow-focus)}._episodeItem_9tyin_118._watched_9tyin_145{color:var(--text-muted);opacity:.6}._episodeItem_9tyin_118._active_9tyin_70{background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent-light);border:1px solid color-mix(in srgb,var(--accent) 30%,transparent)}._episodeItem_9tyin_118._active_9tyin_70:hover{transform:none;background:color-mix(in srgb,var(--accent) 15%,transparent)}._episodeItem_9tyin_118 span{display:flex;align-items:center;gap:var(--space-3)}._episodeThumb_9tyin_167{width:72px;aspect-ratio:16 / 9;object-fit:cover;border-radius:var(--radius-md);flex-shrink:0;background:#ffffff0f}._episodeText_9tyin_176{flex-direction:column!important;align-items:flex-start!important;gap:2px!important;min-width:0;flex:1}._episodeLabel_9tyin_184{font-weight:700;color:inherit}._episodeSub_9tyin_189{font-size:.78rem;font-weight:500;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}._shell_cys6s_1{position:fixed;inset:0;z-index:var(--z-drawer);display:flex;align-items:flex-end;justify-content:center}._overlay_cys6s_10{position:absolute;inset:0;border:0;padding:0;background:#0000008f;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);animation:_fadeIn_cys6s_1 .2s ease-out}._drawer_cys6s_21{position:relative;z-index:1;width:min(100vw,100%);max-height:86vh;background:#0c0c0ffa;border-radius:var(--radius-lg) var(--radius-lg) 0 0;border:1px solid var(--glass-border);border-bottom:none;display:flex;flex-direction:column;overflow:hidden;animation:_slideUpIn_cys6s_1 .25s ease-out}@keyframes _fadeIn_cys6s_1{0%{opacity:0}to{opacity:1}}@keyframes _slideUpIn_cys6s_1{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}._handle_cys6s_56{width:52px;height:5px;border-radius:999px;background:#ffffff2e;margin:.7rem auto 0}._header_cys6s_64{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;padding:1rem 1rem .9rem;border-bottom:1px solid var(--glass-border)}._headerCopy_cys6s_73{display:flex;flex-direction:column;gap:.25rem}._kicker_cys6s_79{color:var(--text-tertiary);font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.14em}._title_cys6s_87{margin:0;font-size:1.1rem;font-weight:800;color:var(--text-primary)}._closeBtn_cys6s_94{width:38px;height:38px;border-radius:999px;border:1px solid var(--glass-border);background:#ffffff0d;color:var(--text-primary);display:inline-flex;align-items:center;justify-content:center;cursor:pointer}._closeBtn_cys6s_94:hover{background:#ffffff1a}._closeBtn_cys6s_94:focus-visible{outline:none;box-shadow:var(--shadow-focus)}._body_cys6s_116{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;touch-action:pan-y}._sourceSelectionContainer_1am19_1{display:flex;flex-direction:column;gap:1.5rem;background:var(--glass-bg);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--glass-border);padding:2rem;border-radius:var(--radius-xl);width:100%}._providerSelectContainer_1am19_14{display:flex;flex-direction:column;gap:1rem;width:100%}._providerSelect_1am19_14,._sourceSelect_1am19_1{height:44px;padding:0 1.25rem;background:var(--bg-tertiary);border:1px solid var(--border-primary);border-radius:var(--radius-lg);color:var(--text-primary);font-size:.95rem;font-family:inherit;cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2371717a' stroke-width='2' viewBox='0 0 12 12'%3E%3Cpolyline points='3 5 6 8 9 5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 1.25rem center;transition:all var(--transition-fast);width:100%;max-width:400px}._providerSelect_1am19_14:hover,._sourceSelect_1am19_1:hover{border-color:var(--border-secondary);background-color:var(--bg-elevated)}._providerSelect_1am19_14:focus,._sourceSelect_1am19_1:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}._providerSelect_1am19_14 option,._sourceSelect_1am19_1 option{background:var(--bg-tertiary);color:var(--text-primary)}._sourceSelectionContainer_1am19_1 h4,._providerSelectContainer_1am19_14 h4{margin:0;color:var(--text-tertiary);font-weight:700;text-transform:uppercase;font-size:.75rem;letter-spacing:.1em}._sourceButtons_1am19_70{display:flex;flex-wrap:wrap;gap:.75rem}._sourceButton_1am19_70{background:#ffffff0d;color:var(--text-secondary);border:1px solid var(--glass-border);padding:.75rem 1.5rem;border-radius:var(--radius-lg);cursor:pointer;font-size:.95rem;font-weight:600;transition:all var(--transition-normal)}._sourceButton_1am19_70:hover{background:#ffffff1a;border-color:var(--text-primary);color:var(--text-primary);transform:translateY(-2px)}._sourceButton_1am19_70._active_1am19_95{background:var(--accent);border-color:var(--accent);color:var(--accent-text)}._theaterAmbient_x9t0o_1{position:absolute!important;inset:0!important;width:100%!important;height:100%!important;object-fit:cover!important;transform:scale(1.15)!important;pointer-events:none!important;z-index:0!important}body.low-end ._theaterAmbient_x9t0o_1{display:none!important}._row_1fq55_1{display:flex;flex-direction:column;gap:.3rem;padding:.5rem .75rem .6rem;min-width:0}._rowHeader_1fq55_9{display:flex;align-items:baseline;justify-content:space-between;gap:.75rem;min-width:0}._rowLabel_1fq55_17{font-size:.68rem;font-weight:700;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._rowValue_1fq55_28{font-size:.72rem;font-weight:600;color:var(--text-secondary);font-variant-numeric:tabular-nums;white-space:nowrap}._slider_1fq55_36{width:100%;min-width:8rem;cursor:pointer;-webkit-appearance:none;appearance:none;background:transparent;height:1.375rem;margin:0;touch-action:pan-y}._slider_1fq55_36::-webkit-slider-runnable-track{width:100%;height:4px;background:linear-gradient(to right,var(--accent) 0%,var(--accent) var(--slider-percent, 0%),rgba(255,255,255,.25) var(--slider-percent, 0%),rgba(255,255,255,.25) 100%);border-radius:4px;border:none}._slider_1fq55_36::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:12px;height:12px;background-color:#fff;border:2px solid var(--accent);border-radius:50%;cursor:pointer;margin-top:-4px;box-shadow:0 0 8px #00000080}._slider_1fq55_36::-moz-range-track{width:100%;height:4px;background:#ffffff40;border-radius:4px;border:none}._slider_1fq55_36::-moz-range-progress{height:4px;background:var(--accent);border-radius:4px}._slider_1fq55_36::-moz-range-thumb{width:10px;height:10px;background-color:#fff;border:2px solid var(--accent);border-radius:50%;cursor:pointer;box-shadow:0 0 8px #00000080}._swatches_1fq55_99{display:flex;gap:.375rem;align-items:center}._swatch_1fq55_99{width:1.25rem;height:1.25rem;padding:0;border-radius:50%;cursor:pointer;flex:0 0 auto}._swatchPicked_1fq55_114{box-shadow:0 0 0 2px var(--panel-bg, #141416),0 0 0 3.5px var(--accent)}._colorInput_1fq55_120{width:1.75rem;height:1.25rem;padding:0;border:none;border-radius:.3rem;background:transparent;cursor:pointer;flex:0 0 auto}._segmented_1fq55_131{display:flex;gap:.25rem;background:#ffffff0d;border:1px solid var(--glass-border);border-radius:var(--radius-sm);padding:.2rem}._segmented_1fq55_131 button{flex:1 1 0;min-width:0;background:transparent;border:none;border-radius:calc(var(--radius-sm) - 2px);color:var(--text-secondary);font-size:.72rem;font-weight:700;text-transform:capitalize;padding:.3rem .25rem;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:.3rem;white-space:nowrap}._segmented_1fq55_131 button:hover{color:var(--text-primary)}._segmented_1fq55_131 button[aria-pressed=true]{background:color-mix(in srgb,var(--accent) 25%,transparent);color:var(--accent-light)}@media(pointer:coarse){._row_1fq55_1{gap:.4rem;padding:.6rem .85rem .7rem}._slider_1fq55_36{height:1.875rem}._slider_1fq55_36::-webkit-slider-thumb{width:16px;height:16px;margin-top:-6px}._slider_1fq55_36::-moz-range-thumb{width:14px;height:14px}._swatch_1fq55_99{width:1.5rem;height:1.5rem}._segmented_1fq55_131 button{padding:.5rem .25rem;min-height:2.5rem}}