diff --git a/dist/animetsu/catalog.js b/dist/animetsu/catalog.js
index 9541f48..660346e 100644
--- a/dist/animetsu/catalog.js
+++ b/dist/animetsu/catalog.js
@@ -1 +1 @@
-"use strict";var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),catalog_exports={};__export(catalog_exports,{catalog:()=>catalog,genres:()=>genres});var catalog=[{title:"Popular",filter:"/api/anime/search?query=&page=1&perPage=35&year=any&sort=favourites&season=any&format=any&status=any"},{title:"Trending",filter:"/api/anime/search?query=&page=1&perPage=35&year=any&sort=trending&season=any&format=any&status=any"},{title:"Top Rated",filter:"/api/anime/search?query=&page=1&perPage=35&year=any&sort=rating&season=any&format=any&status=any"},{title:"Favourites",filter:"/api/anime/search?query=&page=1&perPage=35&year=any&sort=updated&season=any&format=any&status=any"}],genres=[];exports.catalog=catalog,exports.genres=genres;
\ No newline at end of file
+"use strict";var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),catalog_exports={};__export(catalog_exports,{catalog:()=>catalog,genres:()=>genres});var catalog=[{title:"Popular",filter:"popular"},{title:"Trending",filter:"trending"},{title:"Top Rated",filter:"top"},{title:"Seasonal",filter:"seasonal"}],genres=[];exports.catalog=catalog,exports.genres=genres;
\ No newline at end of file
diff --git a/dist/animetsu/meta.js b/dist/animetsu/meta.js
index ec6b712..7cff6fe 100644
--- a/dist/animetsu/meta.js
+++ b/dist/animetsu/meta.js
@@ -1 +1 @@
-"use strict";var __defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropNames=Object.getOwnPropertyNames,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:!0,configurable:!0,writable:!0,value:value}):obj[key]=value,__spreadValues=(a,b)=>{for(var prop in b||(b={}))__hasOwnProp.call(b,prop)&&__defNormalProp(a,prop,b[prop]);if(__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(b))__propIsEnum.call(b,prop)&&__defNormalProp(a,prop,b[prop]);return a},__spreadProps=(a,b)=>__defProps(a,__getOwnPropDescs(b)),__name=(target,value)=>__defProp(target,"name",{value:value,configurable:!0}),__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),__async=(__this,__arguments,generator)=>new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}},rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}},step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())}),meta_exports={};__export(meta_exports,{getMeta:()=>getMeta});var getMeta=__name(function(_0){return __async(this,arguments,function*({link:link,providerContext:providerContext}){var _a,_b,_c,_d,_e,_f;try{const{axios:axios}=providerContext,baseUrl="https://backend.animetsu.to",url=`${baseUrl}/api/anime/info/${link}`,data=(yield axios.get(url,{headers:{Referer:"https://animetsu.to/"}})).data,meta={title:(null==(_a=data.title)?void 0:_a.english)||(null==(_b=data.title)?void 0:_b.romaji)||(null==(_c=data.title)?void 0:_c.native)||"",synopsis:data.description||"",image:(null==(_d=data.coverImage)?void 0:_d.extraLarge)||(null==(_e=data.coverImage)?void 0:_e.large)||(null==(_f=data.coverImage)?void 0:_f.medium)||"",tags:[null==data?void 0:data.format,null==data?void 0:data.status,...(null==data?void 0:data.genres)||[]].filter(Boolean),imdbId:"",type:"MOVIE"===data.format?"movie":"series"},linkList=[];try{const episodes=(yield axios.get(`${baseUrl}/api/anime/eps/${link}`,{headers:{Referer:"https://animetsu.to/"}})).data;if(episodes&&episodes.length>0){const directLinks=[];episodes.forEach(episode=>{const title=`Episode ${episode.number}`,episodeLink=`${link}:${episode.number}`;episodeLink&&title&&directLinks.push({title:title,link:episodeLink})}),linkList.push({title:meta.title,directLinks:directLinks})}else linkList.push({title:meta.title,directLinks:[{title:"Movie",link:`${link}:1`}]})}catch(episodeErr){console.error("Error fetching episodes:",episodeErr),linkList.push({title:meta.title,directLinks:[{title:meta.title,link:`${link}:1`}]})}return __spreadProps(__spreadValues({},meta),{linkList:linkList})}catch(err){return console.error("animetsu meta error:",err),{title:"",synopsis:"",image:"",imdbId:"",type:"movie",linkList:[]}}})},"getMeta");exports.getMeta=getMeta;
\ No newline at end of file
+"use strict";var __defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropNames=Object.getOwnPropertyNames,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:!0,configurable:!0,writable:!0,value:value}):obj[key]=value,__spreadValues=(a,b)=>{for(var prop in b||(b={}))__hasOwnProp.call(b,prop)&&__defNormalProp(a,prop,b[prop]);if(__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(b))__propIsEnum.call(b,prop)&&__defNormalProp(a,prop,b[prop]);return a},__spreadProps=(a,b)=>__defProps(a,__getOwnPropDescs(b)),__name=(target,value)=>__defProp(target,"name",{value:value,configurable:!0}),__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),__async=(__this,__arguments,generator)=>new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}},rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}},step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())}),meta_exports={};__export(meta_exports,{getMeta:()=>getMeta});var getMeta=__name(function(_0){return __async(this,arguments,function*({link:link,providerContext:providerContext}){var _a,_b,_c,_d,_e,_f,_g;try{const{axios:axios,openWebView:openWebView,commonHeaders:commonHeaders}=providerContext,baseUrl="https://animetsu.net",url=`${baseUrl}/v2/api/anime/${link}`;let cookies,res;try{res=yield axios.get(url,{headers:__spreadProps(__spreadValues({},commonHeaders),{Referer:baseUrl})})}catch(error){if(403!==(null==(_a=error.response)?void 0:_a.status))throw error;{const wafResult=yield openWebView(baseUrl,{title:"Solve the captcha below and click done",description:"Required to bypass Animetsu anti-bot protection.",headers:__spreadProps(__spreadValues({},commonHeaders),{Referer:baseUrl}),force:!0,waitForCookie:"cf_clearance"});cookies=wafResult.cookies,res=yield axios.get(url,{headers:__spreadProps(__spreadValues({},commonHeaders),{Referer:baseUrl,Cookie:cookies})})}}const data=res.data,meta={title:(null==(_b=data.title)?void 0:_b.english)||(null==(_c=data.title)?void 0:_c.romaji)||(null==(_d=data.title)?void 0:_d.native)||"",synopsis:data.description||"",image:(null==(_e=data.cover_image)?void 0:_e.large)||(null==(_f=data.cover_image)?void 0:_f.medium)||(null==(_g=data.cover_image)?void 0:_g.small)||"",tags:[null==data?void 0:data.format,null==data?void 0:data.status,...(null==data?void 0:data.genres)||[]].filter(Boolean),imdbId:"",type:"MOVIE"===data.format?"movie":"series"},linkList=[],seasons=data.seasons;if(seasons&&seasons.length>0)yield Promise.all(seasons.map(season=>__async(null,null,function*(){var _a2,_b2,_c2;const seasonTitle=(null==(_a2=season.title)?void 0:_a2.english)||(null==(_b2=season.title)?void 0:_b2.romaji)||(null==(_c2=season.title)?void 0:_c2.native),directLinks=[];try{const episodes=(yield axios.get(`${baseUrl}/api/anime/eps/${season.id}`,{headers:__spreadValues(__spreadProps(__spreadValues({},commonHeaders),{Referer:baseUrl}),cookies?{Cookie:cookies}:{})})).data;episodes&&episodes.length>0&&episodes.forEach(ep=>{directLinks.push({title:`Episode ${ep.number}`,link:`${season.id}:${ep.number}`})})}catch(e){const total=season.total_eps||1;for(let i=1;i<=total;i++)directLinks.push({title:`Episode ${i}`,link:`${season.id}:${i}`})}directLinks.length>0&&linkList.push({title:seasonTitle||meta.title,directLinks:directLinks})})));else{const total=data.total_eps||1,directLinks=[];for(let i=1;i<=total;i++)directLinks.push({title:1===total?"Movie":`Episode ${i}`,link:`${link}:${i}`});linkList.push({title:meta.title,directLinks:directLinks})}return __spreadProps(__spreadValues({},meta),{linkList:linkList})}catch(err){return console.error("animetsu meta error:",err),{title:"",synopsis:"",image:"",imdbId:"",type:"movie",linkList:[]}}})},"getMeta");exports.getMeta=getMeta;
\ No newline at end of file
diff --git a/dist/animetsu/posts.js b/dist/animetsu/posts.js
index bfe4e74..49a6fad 100644
--- a/dist/animetsu/posts.js
+++ b/dist/animetsu/posts.js
@@ -1 +1 @@
-"use strict";var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__name=(target,value)=>__defProp(target,"name",{value:value,configurable:!0}),__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),__async=(__this,__arguments,generator)=>new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}},rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}},step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())}),posts_exports={};__export(posts_exports,{getPosts:()=>getPosts,getSearchPosts:()=>getSearchPosts});var getPosts=__name(function(_0){return __async(this,arguments,function*({filter:filter,page:page,signal:signal,providerContext:providerContext}){const{axios:axios}=providerContext,url="https://backend.animetsu.to"+filter+"&page="+page.toString();return console.log("animetsuGetPosts url",url),posts({url:url.toString(),signal:signal,axios:axios})})},"getPosts"),getSearchPosts=__name(function(_0){return __async(this,arguments,function*({searchQuery:searchQuery,page:page,signal:signal,providerContext:providerContext}){const{axios:axios}=providerContext;return posts({url:`https://backend.animetsu.to/api/anime/search?query=${encodeURIComponent(searchQuery)}&page=${page}&perPage=35&year=any&sort=favourites&season=any&format=any&status=any`,signal:signal,axios:axios})})},"getSearchPosts");function posts(_0){return __async(this,arguments,function*({url:url,signal:signal,axios:axios}){var _a;try{const data=null==(_a=(yield axios.get(url,{signal:signal,headers:{Referer:"https://animetsu.to/"}})).data)?void 0:_a.results,catalog=[];return null==data||data.map(element=>{var _a2,_b,_c,_d,_e,_f,_g;const title=(null==(_a2=element.title)?void 0:_a2.english)||(null==(_b=element.title)?void 0:_b.romaji)||(null==(_c=element.title)?void 0:_c.native),link=null==(_d=element.id)?void 0:_d.toString(),image=(null==(_e=element.coverImage)?void 0:_e.large)||(null==(_f=element.coverImage)?void 0:_f.extraLarge)||(null==(_g=element.coverImage)?void 0:_g.medium);title&&link&&image&&catalog.push({title:title,link:link,image:image})}),catalog}catch(err){return console.error("animetsu error ",err),[]}})}__name(posts,"posts"),exports.getPosts=getPosts,exports.getSearchPosts=getSearchPosts;
\ No newline at end of file
+"use strict";var __defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropNames=Object.getOwnPropertyNames,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:!0,configurable:!0,writable:!0,value:value}):obj[key]=value,__spreadValues=(a,b)=>{for(var prop in b||(b={}))__hasOwnProp.call(b,prop)&&__defNormalProp(a,prop,b[prop]);if(__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(b))__propIsEnum.call(b,prop)&&__defNormalProp(a,prop,b[prop]);return a},__spreadProps=(a,b)=>__defProps(a,__getOwnPropDescs(b)),__name=(target,value)=>__defProp(target,"name",{value:value,configurable:!0}),__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),__async=(__this,__arguments,generator)=>new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}},rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}},step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())}),posts_exports={};__export(posts_exports,{getPosts:()=>getPosts,getSearchPosts:()=>getSearchPosts});var getPosts=__name(function(_0){return __async(this,arguments,function*({filter:filter,page:page,signal:signal,providerContext:providerContext}){if(page>1)return[];const{axios:axios,commonHeaders:commonHeaders}=providerContext;return posts({url:"https://animetsu.net/v2/api/anime/home",filter:filter,signal:signal,axios:axios,providerContext:providerContext,headers:commonHeaders})})},"getPosts"),getSearchPosts=__name(function(_0){return __async(this,arguments,function*({searchQuery:searchQuery,page:page,signal:signal,providerContext:providerContext}){const{axios:axios,commonHeaders:commonHeaders}=providerContext;return posts({url:`https://animetsu.net/v2/api/anime/search/?query=${encodeURIComponent(searchQuery)}`,signal:signal,axios:axios,providerContext:providerContext,headers:commonHeaders})})},"getSearchPosts");function posts(_0){return __async(this,arguments,function*({url:url,filter:filter,signal:signal,axios:axios,providerContext:providerContext,headers:headers}){var _a,_b,_c;const baseUrl="https://animetsu.net",{openWebView:openWebView}=providerContext;try{let cookies,res;try{res=yield axios.get(url,{signal:signal,headers:__spreadProps(__spreadValues({},headers),{Referer:baseUrl})})}catch(error){if(403!==(null==(_a=error.response)?void 0:_a.status))throw error;cookies=(yield openWebView(baseUrl,{title:"Solve the captcha below and click done",description:"Required to bypass Animetsu anti-bot protection.",headers:__spreadProps(__spreadValues({},headers),{Referer:baseUrl}),force:!0,waitForCookie:"cf_clearance"})).cookies,res=yield axios.get(url,{signal:signal,headers:__spreadProps(__spreadValues({},headers),{Referer:baseUrl,Cookie:cookies})})}const data=filter?null==(_b=res.data)?void 0:_b[filter]:(null==(_c=res.data)?void 0:_c.results)||res.data,catalog=[];return null==data||data.map(element=>{var _a2,_b2,_c2,_d,_e,_f,_g,_h,_i,_j,_k;const title=(null==(_a2=element.title)?void 0:_a2.english)||(null==(_b2=element.title)?void 0:_b2.romaji)||(null==(_c2=element.title)?void 0:_c2.native),link=null==(_d=element.id)?void 0:_d.toString(),image=(null==(_e=element.cover_image)?void 0:_e.large)||(null==(_f=element.cover_image)?void 0:_f.extraLarge)||(null==(_g=element.cover_image)?void 0:_g.medium)||(null==(_h=element.cover_image)?void 0:_h.small)||(null==(_i=element.coverImage)?void 0:_i.large)||(null==(_j=element.coverImage)?void 0:_j.extraLarge)||(null==(_k=element.coverImage)?void 0:_k.medium);title&&link&&image&&catalog.push({title:title,link:link,image:image})}),catalog}catch(err){return console.error("animetsu error ",err),[]}})}__name(posts,"posts"),exports.getPosts=getPosts,exports.getSearchPosts=getSearchPosts;
\ No newline at end of file
diff --git a/dist/animetsu/stream.js b/dist/animetsu/stream.js
index 04b73ae..c350049 100644
--- a/dist/animetsu/stream.js
+++ b/dist/animetsu/stream.js
@@ -1 +1 @@
-"use strict";var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__name=(target,value)=>__defProp(target,"name",{value:value,configurable:!0}),__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),__async=(__this,__arguments,generator)=>new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}},rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}},step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())}),stream_exports={};__export(stream_exports,{getStream:()=>getStream});var getStream=__name(function(_0){return __async(this,arguments,function*({link:id,providerContext:providerContext}){try{const{axios:axios}=providerContext,baseUrl="https://backend.animetsu.to",[animeId,episodeNumber]=id.split(":");if(!animeId||!episodeNumber)throw new Error("Invalid link format");const servers=["pahe","zoro"],streamLinks=[];return yield Promise.all(servers.map(server=>__async(null,null,function*(){try{const url=`${baseUrl}/api/anime/tiddies?server=${server}&id=${animeId}&num=${episodeNumber}&subType=sub`,res=yield axios.get(url,{headers:{Referer:"https://animetsu.to/"}});if(res.data&&res.data.sources){const subtitles=[];res.data.sources.forEach(source=>{streamLinks.push({server:server+`: ${source.quality}`,link:`https://m3u8.8man.workers.dev?url=${source.url}`,type:"m3u8",quality:source.quality,headers:{referer:"https://animetsu.to/"},subtitles:subtitles.length>0?subtitles:[]})})}}catch(e){console.log(`Error with server ${server}:`,e)}}))),yield Promise.all(servers.map(server=>__async(null,null,function*(){try{const url=`${baseUrl}/api/anime/tiddies?server=${server}&id=${animeId}&num=${episodeNumber}&subType=dub`,res=yield axios.get(url,{headers:{referer:"https://animetsu.to/"}});if(res.data&&res.data.sources){const subtitles=[];res.data.sources.forEach(source=>{streamLinks.push({server:`${server} (Dub) : ${source.quality}`,link:`https://m3u8.8man.workers.dev?url=${source.url}`,type:"m3u8",quality:source.quality,headers:{referer:"https://animetsu.to/"},subtitles:subtitles.length>0?subtitles:[]})})}}catch(e){console.log(`Error with server ${server} (dub):`,e)}}))),console.log("Stream links:",streamLinks),streamLinks}catch(err){return console.error("animetsu stream error:",err),[]}})},"getStream");exports.getStream=getStream;
\ No newline at end of file
+"use strict";var __defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropNames=Object.getOwnPropertyNames,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:!0,configurable:!0,writable:!0,value:value}):obj[key]=value,__spreadValues=(a,b)=>{for(var prop in b||(b={}))__hasOwnProp.call(b,prop)&&__defNormalProp(a,prop,b[prop]);if(__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(b))__propIsEnum.call(b,prop)&&__defNormalProp(a,prop,b[prop]);return a},__spreadProps=(a,b)=>__defProps(a,__getOwnPropDescs(b)),__name=(target,value)=>__defProp(target,"name",{value:value,configurable:!0}),__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),__async=(__this,__arguments,generator)=>new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}},rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}},step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())}),stream_exports={};__export(stream_exports,{getStream:()=>getStream});var getStream=__name(function(_0){return __async(this,arguments,function*({link:id,providerContext:providerContext}){var _a;try{const{axios:axios,openWebView:openWebView,commonHeaders:commonHeaders}=providerContext,baseUrl="https://animetsu.net";let wafCookies;try{yield axios.get(baseUrl,{headers:__spreadProps(__spreadValues({},commonHeaders),{Referer:baseUrl})})}catch(error){if(403===(null==(_a=error.response)?void 0:_a.status)){const wafResult=yield openWebView(baseUrl,{title:"Solve the captcha below and click done",description:"Required to bypass Animetsu anti-bot protection.",headers:__spreadProps(__spreadValues({},commonHeaders),{Referer:baseUrl}),force:!0,waitForCookie:"cf_clearance"});wafCookies=wafResult.cookies}}const[animeId,episodeNumber]=id.split(":");if(!animeId||!episodeNumber)throw new Error("Invalid link format");const servers=["sage","meg","dio","kite"],streamLinks=[];return yield Promise.all(servers.map(server=>__async(null,null,function*(){try{const url=`${baseUrl}/v2/api/anime/oppai/${animeId}/${episodeNumber}?server=${server}&source_type=sub`,res=yield axios.get(url,{headers:__spreadValues(__spreadProps(__spreadValues({},commonHeaders),{Referer:baseUrl}),wafCookies?{Cookie:wafCookies}:{})});if(res.data&&res.data.sources){const subtitles=[];res.data.subs&&Array.isArray(res.data.subs)&&res.data.subs.forEach(sub=>{if(sub.url&&sub.lang){const langCode=sub.lang.toLowerCase().includes("english")?"en":sub.lang.toLowerCase().includes("arabic")?"ar":sub.lang.toLowerCase().includes("french")?"fr":sub.lang.toLowerCase().includes("german")?"de":sub.lang.toLowerCase().includes("italian")?"it":sub.lang.toLowerCase().includes("portuguese")?"pt":sub.lang.toLowerCase().includes("russian")?"ru":sub.lang.toLowerCase().includes("spanish")?"es":"und";subtitles.push({title:sub.lang,language:langCode,type:"text/vtt",uri:sub.url})}}),res.data.sources.forEach(source=>{const sourceUrl=source.url.startsWith("/")?`${baseUrl}${source.url}`:source.url;streamLinks.push({server:`${server} (Sub): ${source.quality}`,link:`https://m3u8.8man.workers.dev?url=${encodeURIComponent(sourceUrl)}`,type:"m3u8",quality:source.quality,headers:{referer:baseUrl},subtitles:subtitles.length>0?subtitles:[]})})}}catch(e){console.log(`Error with server ${server}:`,e)}}))),yield Promise.all(servers.map(server=>__async(null,null,function*(){try{const url=`${baseUrl}/v2/api/anime/oppai/${animeId}/${episodeNumber}?server=${server}&source_type=dub`,res=yield axios.get(url,{headers:__spreadValues(__spreadProps(__spreadValues({},commonHeaders),{Referer:baseUrl}),wafCookies?{Cookie:wafCookies}:{})});if(res.data&&res.data.sources){const subtitles=[];res.data.subs&&Array.isArray(res.data.subs)&&res.data.subs.forEach(sub=>{if(sub.url&&sub.lang){const langCode=sub.lang.toLowerCase().includes("english")?"en":sub.lang.toLowerCase().includes("arabic")?"ar":sub.lang.toLowerCase().includes("french")?"fr":sub.lang.toLowerCase().includes("german")?"de":sub.lang.toLowerCase().includes("italian")?"it":sub.lang.toLowerCase().includes("portuguese")?"pt":sub.lang.toLowerCase().includes("russian")?"ru":sub.lang.toLowerCase().includes("spanish")?"es":"und";subtitles.push({title:sub.lang,language:langCode,type:"text/vtt",uri:sub.url})}}),res.data.sources.forEach(source=>{const sourceUrl=source.url.startsWith("/")?`${baseUrl}${source.url}`:source.url;streamLinks.push({server:`${server} (Dub): ${source.quality}`,link:`https://m3u8.8man.workers.dev?url=${encodeURIComponent(sourceUrl)}`,type:"m3u8",quality:source.quality,headers:{referer:baseUrl},subtitles:subtitles.length>0?subtitles:[]})})}}catch(e){console.log(`Error with server ${server} (dub):`,e)}}))),console.log("Stream links:",streamLinks),streamLinks}catch(err){return console.error("animetsu stream error:",err),[]}})},"getStream");exports.getStream=getStream;
\ No newline at end of file
diff --git a/dist/movies4u/stream.js b/dist/movies4u/stream.js
index 36e0cae..4c99a08 100644
--- a/dist/movies4u/stream.js
+++ b/dist/movies4u/stream.js
@@ -1 +1 @@
-"use strict";var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__name=(target,value)=>__defProp(target,"name",{value:value,configurable:!0}),__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),__async=(__this,__arguments,generator)=>new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}},rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}},step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())}),stream_exports={};__export(stream_exports,{getStream:()=>getStream});var hubcloudDecode=__name(function(value){return void 0===value?"":atob(value.toString())},"hubcloudDecode"),extractUrlFromScript=__name(html=>{var _a,_b,_c;const doubleAtobMatch=html.match(/var\s+url\s*=\s*atob\(atob\(['"]([^'"]+)['"]\)\)/);if(null==doubleAtobMatch?void 0:doubleAtobMatch[1])return atob(atob(doubleAtobMatch[1]));const plainMatch=html.match(/var\s+url\s*=\s*['"]([^'"]+)['"]/);return hubcloudDecode(null!=(_c=null==(_b=null==(_a=null==plainMatch?void 0:plainMatch[1])?void 0:_a.split("r="))?void 0:_b[1])?_c:"")||(null==plainMatch?void 0:plainMatch[1])||""},"extractUrlFromScript"),getPixelDrainUrl=__name(html=>{const match=html.match(/var\s+pxl\s*=\s*['"]([^'"]+)['"];?/i);return(null==match?void 0:match[1])||""},"getPixelDrainUrl"),getRedirectedPixelDrainUrl=__name((...htmlSources)=>{for(const html of htmlSources){if(!html)continue;const redirectedUrl=getPixelDrainUrl(html);if(redirectedUrl)return redirectedUrl}return""},"getRedirectedPixelDrainUrl");function hubcloudExtractor(link,signal,axios,cheerio,headers2){return __async(this,null,function*(){var _a,_b,_c,_d,_e;try{headers2.Cookie="ext_name=ojplmecpdpgccookcobabopnaifgidhf; xla=s4t; cf_clearance=woQrFGXtLfmEMBEiGUsVHrUBMT8s3cmguIzmMjmvpkg-1770053679-1.2.1.1-xBrQdciOJsweUF6F2T_OtH6jmyanN_TduQ0yslc_XqjU6RcHSxI7.YOKv6ry7oYo64868HYoULnVyww536H2eVI3R2e4wKzsky6abjPdfQPxqpUaXjxfJ02o6jl3_Vkwr4uiaU7Wy596Vdst3y78HXvVmKdIohhtPvp.vZ9_L7wvWdce0GRixjh_6JiqWmWMws46hwEt3hboaS1e1e4EoWCvj5b0M_jVwvSxBOAW5emFzvT3QrnRh4nyYmKDERnY",console.log("hubcloudExtractor",link);const baseUrl=link.split("/").slice(0,3).join("/"),streamLinks=[],vLinkText=(yield axios(`${link}`,{headers:headers2,signal:signal})).data,$vLink=cheerio.load(vLinkText);let vcloudLink=extractUrlFromScript(vLinkText)||$vLink(".fa-file-download.fa-lg").parent().attr("href")||link;console.log("vcloudLink",vcloudLink),(null==vcloudLink?void 0:vcloudLink.startsWith("/"))&&(vcloudLink=`${baseUrl}${vcloudLink}`,console.log("New vcloudLink",vcloudLink));const vcloudRes=yield fetch(vcloudLink,{headers:headers2,signal:signal,redirect:"follow"}),vcloudText=yield vcloudRes.text(),$=cheerio.load(vcloudText),linkClass=$(".btn-success.btn-lg.h6,.btn-danger,.btn-secondary");for(const element of linkClass){let link2=$(element).attr("href")||"";switch(!0){case null==link2?void 0:link2.includes("pixeld"):if(console.log("Pixeldrain link found:",link2),!(null==link2?void 0:link2.includes("api"))){const redirectedPixelDrainUrl=getRedirectedPixelDrainUrl(vLinkText,vcloudText);redirectedPixelDrainUrl&&(console.log("Special case for token negn6f",redirectedPixelDrainUrl),link2=redirectedPixelDrainUrl);const token=null==(_a=link2.split("/").pop())?void 0:_a.split("?")[0],baseUrl2=link2.split("/").slice(0,-2).join("/");link2=`${baseUrl2}/api/file/${token}`}streamLinks.push({server:"Pixeldrain",link:link2,type:"mkv"});break;case(null==link2?void 0:link2.includes(".dev"))&&!(null==link2?void 0:link2.includes("/?id=")):streamLinks.push({server:"Cf Worker",link:link2,type:"mkv"});break;case(null==link2?void 0:link2.includes("hubcloud"))||(null==link2?void 0:link2.includes("/?id=")):try{const newLinkRes=yield fetch(link2,{method:"HEAD",headers:headers2,signal:signal,redirect:"manual"});let newLink=link2;if(newLink=newLinkRes.status>=300&&newLinkRes.status<400?newLinkRes.headers.get("location")||link2:newLinkRes.url&&newLinkRes.url!==link2?newLinkRes.url:newLinkRes.headers.get("location")||link2,newLink.includes("googleusercontent"))newLink=newLink.split("?link=")[1];else{const newLinkRes2=yield fetch(newLink,{method:"HEAD",headers:headers2,signal:signal,redirect:"manual"});newLink=newLinkRes2.status>=300&&newLinkRes2.status<400?(null==(_b=newLinkRes2.headers.get("location"))?void 0:_b.split("?link=")[1])||newLink:newLinkRes2.url&&newLinkRes2.url!==newLink?newLinkRes2.url.split("?link=")[1]||newLinkRes2.url:(null==(_c=newLinkRes2.headers.get("location"))?void 0:_c.split("?link=")[1])||newLink}streamLinks.push({server:"hubcloud",link:newLink,type:"mkv"})}catch(error){console.log("hubcloudExtractor error in hubcloud link: ",error)}break;case null==link2?void 0:link2.includes("cloudflarestorage"):streamLinks.push({server:"CfStorage",link:link2,type:"mkv"});break;case(null==link2?void 0:link2.includes("fastdl"))||(null==link2?void 0:link2.includes("fsl.")):streamLinks.push({server:"FastDl",link:link2,type:"mkv"});break;case link2.includes("hubcdn")&&!link2.includes("/?id="):streamLinks.push({server:"HubCdn",link:link2,type:"mkv"});break;default:if((null==link2?void 0:link2.includes(".mkv"))||(null==link2?void 0:link2.includes("?token="))){const serverName=(null==(_e=null==(_d=link2.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/i))?void 0:_d[1])?void 0:_e.replace(/\./g," "))||"Unknown";streamLinks.push({server:serverName,link:link2,type:"mkv"})}}}return console.log("streamLinks",streamLinks),streamLinks}catch(error){return console.log("hubcloudExtractor error: ",(null==error?void 0:error.message)||error),[]}})}__name(hubcloudExtractor,"hubcloudExtractor");var headers={Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","Cache-Control":"no-store","Accept-Language":"en-US,en;q=0.9",DNT:"1","sec-ch-ua":'"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"Sec-Fetch-Dest":"document","Sec-Fetch-Mode":"navigate","Sec-Fetch-Site":"none","Sec-Fetch-User":"?1",Cookie:"xla=s4t; _ga=GA1.1.1081149560.1756378968; _ga_BLZGKYN5PF=GS2.1.s1756378968$o1$g1$t1756378984$j44$l0$h0","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"};function getStream(_0){return __async(this,arguments,function*({link:link,type:type,signal:signal,providerContext:providerContext}){var _a,_b,_c,_d;const{axios:axios,cheerio:cheerio,commonHeaders:commonHeaders}=providerContext;try{const streamLinks=[];if(console.log("dotlink",link),"movie"===type){const dotlinkText=(yield axios(`${link}`,{headers:headers})).data,vlink=dotlinkText.match(/{const href=$(el).attr("href")||"";return href.includes("hubcloud")||href.includes("gdflix")||href.includes("filebee")||href.includes("fastdl")}).first().attr("href");directLink&&(link=directLink)}if(link.includes("fastdl.zip"))try{const reurlMatch=(yield axios.get(link,{headers:headers})).data.match(/var reurl = "([^"]+)";/);if(reurlMatch&&reurlMatch[1]){const actualLink=reurlMatch[1].replace("https://fastdl.zip/dl.php?link=","");return streamLinks.push({server:"fastdl",link:actualLink,type:"mkv"}),streamLinks}}catch(error){console.log("fastdl error: ",error)}try{const filepressLink=cheerio.load(dotlinkText)('.btn.btn-sm.btn-outline[style="background:linear-gradient(135deg,rgb(252,185,0) 0%,rgb(0,0,0)); color: #fdf8f2;"]').parent().attr("href"),filepressID=null==filepressLink?void 0:filepressLink.split("/").pop(),filepressBaseUrl=null==filepressLink?void 0:filepressLink.split("/").slice(0,-2).join("/"),filepressTokenRes=yield axios.post(filepressBaseUrl+"/api/file/downlaod/",{id:filepressID,method:"indexDownlaod",captchaValue:null},{headers:{"Content-Type":"application/json",Referer:filepressBaseUrl}});if(null==(_a=filepressTokenRes.data)?void 0:_a.status){const filepressToken=null==(_b=filepressTokenRes.data)?void 0:_b.data,filepressStreamLink=yield axios.post(filepressBaseUrl+"/api/file/downlaod2/",{id:filepressToken,method:"indexDownlaod",captchaValue:null},{headers:{"Content-Type":"application/json",Referer:filepressBaseUrl}});streamLinks.push({server:"filepress",link:null==(_d=null==(_c=filepressStreamLink.data)?void 0:_c.data)?void 0:_d[0],type:"mkv"})}}catch(error){console.log("filepress error: ")}}return yield hubcloudExtractor(link,signal,axios,cheerio,commonHeaders)}catch(error){return console.log("getStream error: ",error),error.message.includes("Aborted"),[]}})}__name(getStream,"getStream"),exports.getStream=getStream;
\ No newline at end of file
+"use strict";var __defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropNames=Object.getOwnPropertyNames,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:!0,configurable:!0,writable:!0,value:value}):obj[key]=value,__spreadValues=(a,b)=>{for(var prop in b||(b={}))__hasOwnProp.call(b,prop)&&__defNormalProp(a,prop,b[prop]);if(__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(b))__propIsEnum.call(b,prop)&&__defNormalProp(a,prop,b[prop]);return a},__spreadProps=(a,b)=>__defProps(a,__getOwnPropDescs(b)),__name=(target,value)=>__defProp(target,"name",{value:value,configurable:!0}),__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to},__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod),__async=(__this,__arguments,generator)=>new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}},rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}},step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())}),stream_exports={};__export(stream_exports,{getStream:()=>getStream});var hubcloudDecode=__name(function(value){return void 0===value?"":atob(value.toString())},"hubcloudDecode"),extractUrlFromScript=__name(html=>{var _a,_b,_c;const doubleAtobMatch=html.match(/var\s+url\s*=\s*atob\(atob\(['"]([^'"]+)['"]\)\)/);if(null==doubleAtobMatch?void 0:doubleAtobMatch[1])return atob(atob(doubleAtobMatch[1]));const plainMatch=html.match(/var\s+url\s*=\s*['"]([^'"]+)['"]/);return hubcloudDecode(null!=(_c=null==(_b=null==(_a=null==plainMatch?void 0:plainMatch[1])?void 0:_a.split("r="))?void 0:_b[1])?_c:"")||(null==plainMatch?void 0:plainMatch[1])||""},"extractUrlFromScript"),getPixelDrainUrl=__name(html=>{const match=html.match(/var\s+pxl\s*=\s*['"]([^'"]+)['"];?/i);return(null==match?void 0:match[1])||""},"getPixelDrainUrl"),getRedirectedPixelDrainUrl=__name((...htmlSources)=>{for(const html of htmlSources){if(!html)continue;const redirectedUrl=getPixelDrainUrl(html);if(redirectedUrl)return redirectedUrl}return""},"getRedirectedPixelDrainUrl");function hubcloudExtractor(link,signal,axios,cheerio,headers2){return __async(this,null,function*(){var _a,_b,_c,_d,_e;try{headers2.Cookie="ext_name=ojplmecpdpgccookcobabopnaifgidhf; xla=s4t; cf_clearance=woQrFGXtLfmEMBEiGUsVHrUBMT8s3cmguIzmMjmvpkg-1770053679-1.2.1.1-xBrQdciOJsweUF6F2T_OtH6jmyanN_TduQ0yslc_XqjU6RcHSxI7.YOKv6ry7oYo64868HYoULnVyww536H2eVI3R2e4wKzsky6abjPdfQPxqpUaXjxfJ02o6jl3_Vkwr4uiaU7Wy596Vdst3y78HXvVmKdIohhtPvp.vZ9_L7wvWdce0GRixjh_6JiqWmWMws46hwEt3hboaS1e1e4EoWCvj5b0M_jVwvSxBOAW5emFzvT3QrnRh4nyYmKDERnY",console.log("hubcloudExtractor",link);const baseUrl=link.split("/").slice(0,3).join("/"),streamLinks=[],vLinkText=(yield axios(`${link}`,{headers:headers2,signal:signal})).data,$vLink=cheerio.load(vLinkText);let vcloudLink=extractUrlFromScript(vLinkText)||$vLink(".fa-file-download.fa-lg").parent().attr("href")||link;console.log("vcloudLink",vcloudLink),(null==vcloudLink?void 0:vcloudLink.startsWith("/"))&&(vcloudLink=`${baseUrl}${vcloudLink}`,console.log("New vcloudLink",vcloudLink));const vcloudRes=yield fetch(vcloudLink,{headers:headers2,signal:signal,redirect:"follow"}),vcloudText=yield vcloudRes.text(),$=cheerio.load(vcloudText),linkClass=$(".btn-success.btn-lg.h6,.btn-danger,.btn-secondary");for(const element of linkClass){let link2=$(element).attr("href")||"";switch(!0){case null==link2?void 0:link2.includes("pixeld"):if(console.log("Pixeldrain link found:",link2),!(null==link2?void 0:link2.includes("api"))){const redirectedPixelDrainUrl=getRedirectedPixelDrainUrl(vLinkText,vcloudText);redirectedPixelDrainUrl&&(console.log("Special case for token negn6f",redirectedPixelDrainUrl),link2=redirectedPixelDrainUrl);const token=null==(_a=link2.split("/").pop())?void 0:_a.split("?")[0],baseUrl2=link2.split("/").slice(0,-2).join("/");link2=`${baseUrl2}/api/file/${token}`}streamLinks.push({server:"Pixeldrain",link:link2,type:"mkv"});break;case(null==link2?void 0:link2.includes(".dev"))&&!(null==link2?void 0:link2.includes("/?id=")):streamLinks.push({server:"Cf Worker",link:link2,type:"mkv"});break;case(null==link2?void 0:link2.includes("hubcloud"))||(null==link2?void 0:link2.includes("/?id=")):try{const newLinkRes=yield fetch(link2,{method:"HEAD",headers:headers2,signal:signal,redirect:"manual"});let newLink=link2;if(newLink=newLinkRes.status>=300&&newLinkRes.status<400?newLinkRes.headers.get("location")||link2:newLinkRes.url&&newLinkRes.url!==link2?newLinkRes.url:newLinkRes.headers.get("location")||link2,newLink.includes("googleusercontent"))newLink=newLink.split("?link=")[1];else{const newLinkRes2=yield fetch(newLink,{method:"HEAD",headers:headers2,signal:signal,redirect:"manual"});newLink=newLinkRes2.status>=300&&newLinkRes2.status<400?(null==(_b=newLinkRes2.headers.get("location"))?void 0:_b.split("?link=")[1])||newLink:newLinkRes2.url&&newLinkRes2.url!==newLink?newLinkRes2.url.split("?link=")[1]||newLinkRes2.url:(null==(_c=newLinkRes2.headers.get("location"))?void 0:_c.split("?link=")[1])||newLink}streamLinks.push({server:"hubcloud",link:newLink,type:"mkv"})}catch(error){console.log("hubcloudExtractor error in hubcloud link: ",error)}break;case null==link2?void 0:link2.includes("cloudflarestorage"):streamLinks.push({server:"CfStorage",link:link2,type:"mkv"});break;case(null==link2?void 0:link2.includes("fastdl"))||(null==link2?void 0:link2.includes("fsl.")):streamLinks.push({server:"FastDl",link:link2,type:"mkv"});break;case link2.includes("hubcdn")&&!link2.includes("/?id="):streamLinks.push({server:"HubCdn",link:link2,type:"mkv"});break;default:if((null==link2?void 0:link2.includes(".mkv"))||(null==link2?void 0:link2.includes("?token="))){const serverName=(null==(_e=null==(_d=link2.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/i))?void 0:_d[1])?void 0:_e.replace(/\./g," "))||"Unknown";streamLinks.push({server:serverName,link:link2,type:"mkv"})}}}return console.log("streamLinks",streamLinks),streamLinks}catch(error){return console.log("hubcloudExtractor error: ",(null==error?void 0:error.message)||error),[]}})}__name(hubcloudExtractor,"hubcloudExtractor");var headers={Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","Cache-Control":"no-store","Accept-Language":"en-US,en;q=0.9",DNT:"1","sec-ch-ua":'"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"Sec-Fetch-Dest":"document","Sec-Fetch-Mode":"navigate","Sec-Fetch-Site":"none","Sec-Fetch-User":"?1"};function getStream(_0){return __async(this,arguments,function*({link:link,type:type,signal:signal,providerContext:providerContext}){var _a,_b,_c,_d,_e;const{axios:axios,cheerio:cheerio,commonHeaders:commonHeaders,openWebView:openWebView}=providerContext;try{const streamLinks=[];if(console.log("dotlink",link),"movie"===type){let dotlinkRes,cookies;try{dotlinkRes=yield axios(`${link}`,{headers:__spreadProps(__spreadValues({},commonHeaders),{Referer:link})})}catch(error){if(403!==(null==(_a=error.response)?void 0:_a.status))throw error;{console.log("Solving WAF for Movies4U...");const wafResult=yield openWebView(link,{title:"Solve the captcha below and click done",description:"This is required to bypass the anti-bot protection and retrieve the stream link.",headers:__spreadProps(__spreadValues({},commonHeaders),{Referer:link}),force:!0,waitForCookie:"cf_clearance"});console.log("WAF solved",wafResult.cookies),cookies=wafResult.cookies,dotlinkRes=yield axios(`${link}`,{headers:__spreadProps(__spreadValues({},commonHeaders),{Referer:link,Cookie:cookies})})}}const dotlinkText=dotlinkRes.data,vlink=dotlinkText.match(/{const href=$(el).attr("href")||"";return href.includes("hubcloud")||href.includes("gdflix")||href.includes("filebee")||href.includes("fastdl")}).first().attr("href");directLink&&(link=directLink)}if(link.includes("fastdl.zip"))try{const reurlMatch=(yield axios.get(link,{headers:headers})).data.match(/var reurl = "([^"]+)";/);if(reurlMatch&&reurlMatch[1]){const actualLink=reurlMatch[1].replace("https://fastdl.zip/dl.php?link=","");return streamLinks.push({server:"fastdl",link:actualLink,type:"mkv"}),streamLinks}}catch(error){console.log("fastdl error: ",error)}try{const filepressLink=cheerio.load(dotlinkText)('.btn.btn-sm.btn-outline[style="background:linear-gradient(135deg,rgb(252,185,0) 0%,rgb(0,0,0)); color: #fdf8f2;"]').parent().attr("href"),filepressID=null==filepressLink?void 0:filepressLink.split("/").pop(),filepressBaseUrl=null==filepressLink?void 0:filepressLink.split("/").slice(0,-2).join("/"),filepressTokenRes=yield axios.post(filepressBaseUrl+"/api/file/downlaod/",{id:filepressID,method:"indexDownlaod",captchaValue:null},{headers:{"Content-Type":"application/json",Referer:filepressBaseUrl}});if(null==(_b=filepressTokenRes.data)?void 0:_b.status){const filepressToken=null==(_c=filepressTokenRes.data)?void 0:_c.data,filepressStreamLink=yield axios.post(filepressBaseUrl+"/api/file/downlaod2/",{id:filepressToken,method:"indexDownlaod",captchaValue:null},{headers:{"Content-Type":"application/json",Referer:filepressBaseUrl}});streamLinks.push({server:"filepress",link:null==(_e=null==(_d=filepressStreamLink.data)?void 0:_d.data)?void 0:_e[0],type:"mkv"})}}catch(error){console.log("filepress error: ")}}return yield hubcloudExtractor(link,signal,axios,cheerio,commonHeaders)}catch(error){return console.log("getStream error: ",error),error.message.includes("Aborted"),[]}})}__name(getStream,"getStream"),exports.getStream=getStream;
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index eff9627..62a9fab 100644
--- a/manifest.json
+++ b/manifest.json
@@ -114,7 +114,7 @@
{
"display_name": "Movies4U",
"value": "movies4u",
- "version": "1.6",
+ "version": "1.7",
"icon": "",
"type": "global",
"disabled": false
@@ -258,10 +258,10 @@
{
"display_name": "Animetsu",
"value": "animetsu",
- "version": "1.1",
+ "version": "1.2",
"icon": "",
"type": "english",
- "disabled": true
+ "disabled": false
},
{
"display_name": "TokyoInsider",
diff --git a/providers/animetsu/catalog.ts b/providers/animetsu/catalog.ts
index ac14620..26e6437 100644
--- a/providers/animetsu/catalog.ts
+++ b/providers/animetsu/catalog.ts
@@ -1,23 +1,19 @@
export const catalog = [
{
title: "Popular",
- filter:
- "/api/anime/search?query=&page=1&perPage=35&year=any&sort=favourites&season=any&format=any&status=any",
+ filter: "popular",
},
{
title: "Trending",
- filter:
- "/api/anime/search?query=&page=1&perPage=35&year=any&sort=trending&season=any&format=any&status=any",
+ filter: "trending",
},
{
title: "Top Rated",
- filter:
- "/api/anime/search?query=&page=1&perPage=35&year=any&sort=rating&season=any&format=any&status=any",
+ filter: "top",
},
{
- title: "Favourites",
- filter:
- "/api/anime/search?query=&page=1&perPage=35&year=any&sort=updated&season=any&format=any&status=any",
+ title: "Seasonal",
+ filter: "seasonal",
},
];
diff --git a/providers/animetsu/meta.ts b/providers/animetsu/meta.ts
index a25b587..0716996 100644
--- a/providers/animetsu/meta.ts
+++ b/providers/animetsu/meta.ts
@@ -8,15 +8,33 @@ export const getMeta = async function ({
providerContext: ProviderContext;
}): Promise {
try {
- const { axios } = providerContext;
- const baseUrl = "https://backend.animetsu.to";
- const url = `${baseUrl}/api/anime/info/${link}`;
+ const { axios, openWebView, commonHeaders } = providerContext;
+ const baseUrl = "https://animetsu.net";
+ const url = `${baseUrl}/v2/api/anime/${link}`;
- const res = await axios.get(url, {
- headers: {
- Referer: "https://animetsu.to/",
- },
- });
+ let cookies: string | undefined;
+ let res: any;
+ try {
+ res = await axios.get(url, {
+ headers: { ...commonHeaders, Referer: baseUrl },
+ });
+ } catch (error: any) {
+ if (error.response?.status === 403) {
+ const wafResult = await openWebView(baseUrl, {
+ title: "Solve the captcha below and click done",
+ description: "Required to bypass Animetsu anti-bot protection.",
+ headers: { ...commonHeaders, Referer: baseUrl },
+ force: true,
+ waitForCookie: "cf_clearance",
+ });
+ cookies = wafResult.cookies;
+ res = await axios.get(url, {
+ headers: { ...commonHeaders, Referer: baseUrl, Cookie: cookies },
+ });
+ } else {
+ throw error;
+ }
+ }
const data = res.data;
const meta = {
@@ -24,12 +42,12 @@ export const getMeta = async function ({
data.title?.english || data.title?.romaji || data.title?.native || "",
synopsis: data.description || "",
image:
- data.coverImage?.extraLarge ||
- data.coverImage?.large ||
- data.coverImage?.medium ||
+ data.cover_image?.large ||
+ data.cover_image?.medium ||
+ data.cover_image?.small ||
"",
tags: [data?.format, data?.status, ...(data?.genres || [])].filter(
- Boolean
+ Boolean,
),
imdbId: "",
type: data.format === "MOVIE" ? "movie" : "series",
@@ -37,58 +55,66 @@ export const getMeta = async function ({
const linkList: Link[] = [];
- // Get episodes data
- try {
- const episodesRes = await axios.get(`${baseUrl}/api/anime/eps/${link}`, {
- headers: {
- Referer: "https://animetsu.to/",
- },
- });
- const episodes = episodesRes.data;
+ const seasons = data.seasons;
+ if (seasons && seasons.length > 0) {
+ await Promise.all(
+ seasons.map(async (season: any) => {
+ const seasonTitle =
+ season.title?.english ||
+ season.title?.romaji ||
+ season.title?.native;
+ const directLinks: Link["directLinks"] = [];
- if (episodes && episodes.length > 0) {
- const directLinks: Link["directLinks"] = [];
+ try {
+ const epsRes = await axios.get(
+ `${baseUrl}/api/anime/eps/${season.id}`,
+ {
+ headers: {
+ ...commonHeaders,
+ Referer: baseUrl,
+ ...(cookies ? { Cookie: cookies } : {}),
+ },
+ },
+ );
+ const episodes = epsRes.data;
+ if (episodes && episodes.length > 0) {
+ episodes.forEach((ep: any) => {
+ directLinks.push({
+ title: `Episode ${ep.number}`,
+ link: `${season.id}:${ep.number}`,
+ });
+ });
+ }
+ } catch {
+ // fallback: use total_eps count
+ const total = season.total_eps || 1;
+ for (let i = 1; i <= total; i++) {
+ directLinks.push({
+ title: `Episode ${i}`,
+ link: `${season.id}:${i}`,
+ });
+ }
+ }
- episodes.forEach((episode: any) => {
- const title = `Episode ${episode.number}`;
- const episodeLink = `${link}:${episode.number}`;
-
- if (episodeLink && title) {
- directLinks.push({
- title,
- link: episodeLink,
+ if (directLinks.length > 0) {
+ linkList.push({
+ title: seasonTitle || meta.title,
+ directLinks,
});
}
- });
-
- linkList.push({
- title: meta.title,
- directLinks: directLinks,
- });
- } else {
- // Movie case - single episode
- linkList.push({
- title: meta.title,
- directLinks: [
- {
- title: "Movie",
- link: `${link}:1`,
- },
- ],
+ }),
+ );
+ } else {
+ // Movie or single-season fallback
+ const total = data.total_eps || 1;
+ const directLinks: Link["directLinks"] = [];
+ for (let i = 1; i <= total; i++) {
+ directLinks.push({
+ title: total === 1 ? "Movie" : `Episode ${i}`,
+ link: `${link}:${i}`,
});
}
- } catch (episodeErr) {
- console.error("Error fetching episodes:", episodeErr);
- // Fallback for movie or single episode
- linkList.push({
- title: meta.title,
- directLinks: [
- {
- title: meta.title,
- link: `${link}:1`,
- },
- ],
- });
+ linkList.push({ title: meta.title, directLinks });
}
return {
diff --git a/providers/animetsu/posts.ts b/providers/animetsu/posts.ts
index 097f4ee..571a5d9 100644
--- a/providers/animetsu/posts.ts
+++ b/providers/animetsu/posts.ts
@@ -12,14 +12,21 @@ export const getPosts = async function ({
signal: AbortSignal;
providerContext: ProviderContext;
}): Promise {
- const { axios } = providerContext;
- const baseUrl = "https://backend.animetsu.to";
+ if (page > 1) {
+ return [];
+ }
+ const { axios, commonHeaders } = providerContext;
+ const baseUrl = "https://animetsu.net";
+ const url = `${baseUrl}/v2/api/anime/home`;
- // Parse filter to modify page parameter
- const url = baseUrl + filter + "&page=" + page.toString();
- console.log("animetsuGetPosts url", url);
-
- return posts({ url: url.toString(), signal, axios });
+ return posts({
+ url,
+ filter,
+ signal,
+ axios,
+ providerContext,
+ headers: commonHeaders,
+ });
};
export const getSearchPosts = async function ({
@@ -34,32 +41,62 @@ export const getSearchPosts = async function ({
signal: AbortSignal;
providerContext: ProviderContext;
}): Promise {
- const { axios } = providerContext;
- const baseUrl = "https://backend.animetsu.to";
- const url = `${baseUrl}/api/anime/search?query=${encodeURIComponent(
- searchQuery
- )}&page=${page}&perPage=35&year=any&sort=favourites&season=any&format=any&status=any`;
+ const { axios, commonHeaders } = providerContext;
+ const baseUrl = "https://animetsu.net";
+ const url = `${baseUrl}/v2/api/anime/search/?query=${encodeURIComponent(
+ searchQuery,
+ )}`;
- return posts({ url, signal, axios });
+ return posts({ url, signal, axios, providerContext, headers: commonHeaders });
};
async function posts({
url,
+ filter,
signal,
axios,
+ providerContext,
+ headers,
}: {
url: string;
+ filter?: string;
signal: AbortSignal;
axios: ProviderContext["axios"];
+ providerContext: ProviderContext;
+ headers?: Record;
}): Promise {
+ const baseUrl = "https://animetsu.net";
+ const { openWebView } = providerContext;
try {
- const res = await axios.get(url, {
- signal,
- headers: {
- Referer: "https://animetsu.to/",
- },
- });
- const data = res.data?.results;
+ let cookies: string | undefined;
+ let res: any;
+ try {
+ res = await axios.get(url, {
+ signal,
+ headers: {
+ ...headers,
+ Referer: baseUrl,
+ },
+ });
+ } catch (error: any) {
+ if (error.response?.status === 403) {
+ const wafResult = await openWebView(baseUrl, {
+ title: "Solve the captcha below and click done",
+ description: "Required to bypass Animetsu anti-bot protection.",
+ headers: { ...headers, Referer: baseUrl },
+ force: true,
+ waitForCookie: "cf_clearance",
+ });
+ cookies = wafResult.cookies;
+ res = await axios.get(url, {
+ signal,
+ headers: { ...headers, Referer: baseUrl, Cookie: cookies },
+ });
+ } else {
+ throw error;
+ }
+ }
+ const data = filter ? res.data?.[filter] : res.data?.results || res.data;
const catalog: Post[] = [];
data?.map((element: any) => {
@@ -69,6 +106,10 @@ async function posts({
element.title?.native;
const link = element.id?.toString();
const image =
+ element.cover_image?.large ||
+ element.cover_image?.extraLarge ||
+ element.cover_image?.medium ||
+ element.cover_image?.small ||
element.coverImage?.large ||
element.coverImage?.extraLarge ||
element.coverImage?.medium;
diff --git a/providers/animetsu/stream.ts b/providers/animetsu/stream.ts
index ac25ede..315c5f1 100644
--- a/providers/animetsu/stream.ts
+++ b/providers/animetsu/stream.ts
@@ -8,8 +8,26 @@ export const getStream = async function ({
providerContext: ProviderContext;
}): Promise {
try {
- const { axios } = providerContext;
- const baseUrl = "https://backend.animetsu.to";
+ const { axios, openWebView, commonHeaders } = providerContext;
+ const baseUrl = "https://animetsu.net";
+
+ let wafCookies: string | undefined;
+ try {
+ await axios.get(baseUrl, {
+ headers: { ...commonHeaders, Referer: baseUrl },
+ });
+ } catch (error: any) {
+ if (error.response?.status === 403) {
+ const wafResult = await openWebView(baseUrl, {
+ title: "Solve the captcha below and click done",
+ description: "Required to bypass Animetsu anti-bot protection.",
+ headers: { ...commonHeaders, Referer: baseUrl },
+ force: true,
+ waitForCookie: "cf_clearance",
+ });
+ wafCookies = wafResult.cookies;
+ }
+ }
// Parse link format: "animeId:episodeNumber"
const [animeId, episodeNumber] = id.split(":");
@@ -18,61 +36,65 @@ export const getStream = async function ({
throw new Error("Invalid link format");
}
- const servers = ["pahe", "zoro"]; // Available servers based on API structure
+ const servers = ["sage", "meg", "dio", "kite"];
const streamLinks: Stream[] = [];
await Promise.all(
servers.map(async (server) => {
try {
- const url = `${baseUrl}/api/anime/tiddies?server=${server}&id=${animeId}&num=${episodeNumber}&subType=sub`;
+ const url = `${baseUrl}/v2/api/anime/oppai/${animeId}/${episodeNumber}?server=${server}&source_type=sub`;
const res = await axios.get(url, {
headers: {
- Referer: "https://animetsu.to/",
+ ...commonHeaders,
+ Referer: baseUrl,
+ ...(wafCookies ? { Cookie: wafCookies } : {}),
},
});
if (res.data && res.data.sources) {
const subtitles: TextTracks = [];
- // if (res.data.subtitles && Array.isArray(res.data.subtitles)) {
- // res.data.subtitles.forEach((sub: any) => {
- // if (sub.url && sub.lang) {
- // // Extract language code from lang string (e.g., "English" -> "en", "Arabic - CR" -> "ar")
- // const langCode = sub.lang.toLowerCase().includes("english")
- // ? "en"
- // : sub.lang.toLowerCase().includes("arabic")
- // ? "ar"
- // : sub.lang.toLowerCase().includes("french")
- // ? "fr"
- // : sub.lang.toLowerCase().includes("german")
- // ? "de"
- // : sub.lang.toLowerCase().includes("italian")
- // ? "it"
- // : sub.lang.toLowerCase().includes("portuguese")
- // ? "pt"
- // : sub.lang.toLowerCase().includes("russian")
- // ? "ru"
- // : sub.lang.toLowerCase().includes("spanish")
- // ? "es"
- // : "und";
+ if (res.data.subs && Array.isArray(res.data.subs)) {
+ res.data.subs.forEach((sub: any) => {
+ if (sub.url && sub.lang) {
+ const langCode = sub.lang.toLowerCase().includes("english")
+ ? "en"
+ : sub.lang.toLowerCase().includes("arabic")
+ ? "ar"
+ : sub.lang.toLowerCase().includes("french")
+ ? "fr"
+ : sub.lang.toLowerCase().includes("german")
+ ? "de"
+ : sub.lang.toLowerCase().includes("italian")
+ ? "it"
+ : sub.lang.toLowerCase().includes("portuguese")
+ ? "pt"
+ : sub.lang.toLowerCase().includes("russian")
+ ? "ru"
+ : sub.lang.toLowerCase().includes("spanish")
+ ? "es"
+ : "und";
- // subtitles.push({
- // title: sub.lang,
- // language: langCode,
- // type: "text/vtt",
- // uri: sub.url,
- // });
- // }
- // });
- // }
+ subtitles.push({
+ title: sub.lang,
+ language: langCode,
+ type: "text/vtt",
+ uri: sub.url,
+ });
+ }
+ });
+ }
res.data.sources.forEach((source: any) => {
+ const sourceUrl = source.url.startsWith("/")
+ ? `${baseUrl}${source.url}`
+ : source.url;
streamLinks.push({
- server: server + `: ${source.quality}`,
- link: `https://m3u8.8man.workers.dev?url=${source.url}`,
+ server: `${server} (Sub): ${source.quality}`,
+ link: `https://m3u8.8man.workers.dev?url=${encodeURIComponent(sourceUrl)}`,
type: "m3u8",
quality: source.quality,
headers: {
- referer: "https://animetsu.to/",
+ referer: baseUrl,
},
subtitles: subtitles.length > 0 ? subtitles : [],
});
@@ -81,62 +103,67 @@ export const getStream = async function ({
} catch (e) {
console.log(`Error with server ${server}:`, e);
}
- })
+ }),
);
// Try dub version as well
await Promise.all(
servers.map(async (server) => {
try {
- const url = `${baseUrl}/api/anime/tiddies?server=${server}&id=${animeId}&num=${episodeNumber}&subType=dub`;
+ const url = `${baseUrl}/v2/api/anime/oppai/${animeId}/${episodeNumber}?server=${server}&source_type=dub`;
const res = await axios.get(url, {
headers: {
- referer: "https://animetsu.to/",
+ ...commonHeaders,
+ Referer: baseUrl,
+ ...(wafCookies ? { Cookie: wafCookies } : {}),
},
});
if (res.data && res.data.sources) {
const subtitles: TextTracks = [];
- // if (res.data.subtitles && Array.isArray(res.data.subtitles)) {
- // res.data.subtitles.forEach((sub: any) => {
- // if (sub.url && sub.lang) {
- // // Extract language code from lang string (e.g., "English" -> "en", "Arabic - CR" -> "ar")
- // const langCode = sub.lang.toLowerCase().includes("english")
- // ? "en"
- // : sub.lang.toLowerCase().includes("arabic")
- // ? "ar"
- // : sub.lang.toLowerCase().includes("french")
- // ? "fr"
- // : sub.lang.toLowerCase().includes("german")
- // ? "de"
- // : sub.lang.toLowerCase().includes("italian")
- // ? "it"
- // : sub.lang.toLowerCase().includes("portuguese")
- // ? "pt"
- // : sub.lang.toLowerCase().includes("russian")
- // ? "ru"
- // : sub.lang.toLowerCase().includes("spanish")
- // ? "es"
- // : "und";
+ if (res.data.subs && Array.isArray(res.data.subs)) {
+ res.data.subs.forEach((sub: any) => {
+ if (sub.url && sub.lang) {
+ // Extract language code from lang string (e.g., "English" -> "en", "Arabic - CR" -> "ar")
+ const langCode = sub.lang.toLowerCase().includes("english")
+ ? "en"
+ : sub.lang.toLowerCase().includes("arabic")
+ ? "ar"
+ : sub.lang.toLowerCase().includes("french")
+ ? "fr"
+ : sub.lang.toLowerCase().includes("german")
+ ? "de"
+ : sub.lang.toLowerCase().includes("italian")
+ ? "it"
+ : sub.lang.toLowerCase().includes("portuguese")
+ ? "pt"
+ : sub.lang.toLowerCase().includes("russian")
+ ? "ru"
+ : sub.lang.toLowerCase().includes("spanish")
+ ? "es"
+ : "und";
- // subtitles.push({
- // title: sub.lang,
- // language: langCode,
- // type: "text/vtt",
- // uri: sub.url,
- // });
- // }
- // });
- // }
+ subtitles.push({
+ title: sub.lang,
+ language: langCode,
+ type: "text/vtt",
+ uri: sub.url,
+ });
+ }
+ });
+ }
res.data.sources.forEach((source: any) => {
+ const sourceUrl = source.url.startsWith("/")
+ ? `${baseUrl}${source.url}`
+ : source.url;
streamLinks.push({
- server: `${server} (Dub) : ${source.quality}`,
- link: `https://m3u8.8man.workers.dev?url=${source.url}`,
+ server: `${server} (Dub): ${source.quality}`,
+ link: `https://m3u8.8man.workers.dev?url=${encodeURIComponent(sourceUrl)}`,
type: "m3u8",
quality: source.quality,
headers: {
- referer: "https://animetsu.to/",
+ referer: baseUrl,
},
subtitles: subtitles.length > 0 ? subtitles : [],
});
@@ -145,7 +172,7 @@ export const getStream = async function ({
} catch (e) {
console.log(`Error with server ${server} (dub):`, e);
}
- })
+ }),
);
console.log("Stream links:", streamLinks);
diff --git a/providers/movies4u/stream.ts b/providers/movies4u/stream.ts
index 6c2f776..fdcaddd 100644
--- a/providers/movies4u/stream.ts
+++ b/providers/movies4u/stream.ts
@@ -15,11 +15,6 @@ const headers = {
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
- Cookie:
- "xla=s4t; _ga=GA1.1.1081149560.1756378968; _ga_BLZGKYN5PF=GS2.1.s1756378968$o1$g1$t1756378984$j44$l0$h0",
- "Upgrade-Insecure-Requests": "1",
- "User-Agent":
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0",
};
export async function getStream({
@@ -33,13 +28,50 @@ export async function getStream({
signal: AbortSignal;
providerContext: ProviderContext;
}) {
- const { axios, cheerio, commonHeaders } = providerContext;
+ const { axios, cheerio, commonHeaders, openWebView } = providerContext;
try {
const streamLinks: Stream[] = [];
console.log("dotlink", link);
if (type === "movie") {
- // vlink
- const dotlinkRes = await axios(`${link}`, { headers });
+ let dotlinkRes;
+ let cookies: string | undefined;
+
+ try {
+ dotlinkRes = await axios(`${link}`, {
+ headers: {
+ ...commonHeaders,
+ Referer: link,
+ },
+ });
+ } catch (error: any) {
+ if (error.response?.status === 403) {
+ console.log("Solving WAF for Movies4U...");
+ const wafResult = await openWebView(link, {
+ title: "Solve the captcha below and click done",
+ description:
+ "This is required to bypass the anti-bot protection and retrieve the stream link.",
+ headers: {
+ ...commonHeaders,
+ Referer: link,
+ },
+ force: true,
+ waitForCookie: "cf_clearance",
+ });
+ console.log("WAF solved", wafResult.cookies);
+ cookies = wafResult.cookies;
+
+ dotlinkRes = await axios(`${link}`, {
+ headers: {
+ ...commonHeaders,
+ Referer: link,
+ Cookie: cookies,
+ },
+ });
+ } else {
+ throw error;
+ }
+ }
+
const dotlinkText = dotlinkRes.data;
// console.log('dotlinkText', dotlinkText);
const vlink = dotlinkText.match(/