mirror of
https://github.com/violettoolssite/CFspider.git
synced 2026-04-05 11:29:03 +08:00
1 line
62 KiB
JavaScript
1 line
62 KiB
JavaScript
import{connect as e}from"cloudflare:sockets";let t,n,s,r="",o=null,a=!1,i="",c={},l=0,d=!0,u="https://doh.cmliussss.net/CMLiussss",p=["*tapecontent.net","*cloudatacdn.com","*loadshare.org","*cdn-centaurus.com","scholar.google.com"];const h="https://edt-pages.github.io";export default{async fetch(e,n,s){const l=new URL(e.url),w=e.headers.get("User-Agent")||"null",b=e.headers.get("Upgrade"),C=n.ADMIN||n.admin||n.PASSWORD||n.password||n.pswd||n.TOKEN||n.KEY||n.UUID||n.uuid||"cfspider-public",A=n.KEY||"cfspider-default-key",E=await T(C+A),O=/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/,R=n.UUID||n.uuid,_=R&&O.test(R)?R.toLowerCase():[E.slice(0,8),E.slice(8,12),"4"+E.slice(13,16),"8"+E.slice(17,20),E.slice(20)].join("-"),j=(n.HOST?(await S(n.HOST)).map(e=>e.toLowerCase().replace(/^https?:\/\//,"").split("/")[0].split(":")[0]):[l.hostname])[0];if(n.PROXYIP){const e=await S(n.PROXYIP);r=e[Math.floor(Math.random()*e.length)],d=!1}else r=(e.cf.colo+".PrOxYIp.CmLiUsSsS.nEt").toLowerCase();const N=e.headers.get("X-Real-IP")||e.headers.get("CF-Connecting-IP")||e.headers.get("X-Forwarded-For")||e.headers.get("True-Client-IP")||e.headers.get("Fly-Client-IP")||e.headers.get("X-Appengine-Remote-Addr")||e.headers.get("X-Forwarded-For")||e.headers.get("X-Real-IP")||e.headers.get("X-Cluster-Client-IP")||e.cf?.clientTcpRtt||"unknownIP";if(n.GO2SOCKS5&&(p=await S(n.GO2SOCKS5)),u=n.ECH_DOH||n.DOH||u,b&&"websocket"===b){if(C){await async function(e){const t=new URL(e.url),{pathname:n,searchParams:s}=t,l=n.toLowerCase();i=s.get("socks5")||s.get("http")||null,a=s.has("globalproxy")||!1;const u=l.match(/\/(proxyip[.=]|pyip=|ip=)(.+)/);if(s.has("proxyip")){const e=s.get("proxyip");return r=e.includes(",")?e.split(",")[Math.floor(Math.random()*e.split(",").length)]:e,void(d=!1)}if(u){const e="proxyip."===u[1]?`proxyip.${u[2]}`:u[2];return r=e.includes(",")?e.split(",")[Math.floor(Math.random()*e.split(",").length)]:e,void(d=!1)}let p;if(p=n.match(/\/(socks5?|http):\/?\/?(.+)/i)){if(o="http"===p[1].toLowerCase()?"http":"socks5",i=p[2].split("#")[0],a=!0,i.includes("@")){const e=i.lastIndexOf("@");let t=i.substring(0,e).replaceAll("%3D","=");/^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=)?$/i.test(t)&&!t.includes(":")&&(t=atob(t)),i=`${t}@${i.substring(e+1)}`}}else if(p=n.match(/\/(g?s5|socks5|g?http)=(.+)/i)){const e=p[1].toLowerCase();i=p[2],o=e.includes("http")?"http":"socks5",a=e.startsWith("g")||a}if(i)try{c=await v(i),o=s.get("http")?"http":o}catch(e){console.error("parseSOCKS5addrFailed:",e.message),o=null}else o=null}(e);const t=new URL(e.url).pathname;let s="";if(t.includes("two_proxy=")){const e=t.match(/two_proxy=([^&]+)/);e&&(s=decodeURIComponent(decodeURIComponent(e[1])))}const l=s||n.TWO_PROXY||n.two_proxy||"";return await async function(e,t,n=""){const s=new WebSocketPair,[r,o]=Object.values(s);o.accept();let a={socket:null},i=!1;const c=e.headers.get("sec-websocket-protocol")||"",l=function(e,t){let n=!1;return new ReadableStream({start(s){e.addEventListener("message",e=>{n||s.enqueue(e.data)}),e.addEventListener("close",()=>{n||(m(e),s.close())}),e.addEventListener("error",e=>s.error(e));const{earlyData:r,error:o}=function(e){if(!e)return{error:null};try{const t=atob(e.replace(/-/g,"+").replace(/_/g,"/")),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return{earlyData:n.buffer,error:null}}catch(e){return{error:e}}}(t);o?s.error(o):r&&s.enqueue(r)},cancel(){n=!0,m(e)}})}(o,c);let d=null,u=null;if(n){const e=n.split(":");e.length>=2&&(u={hostname:e[0],port:parseInt(e[1],10),username:e[2]||"",password:e[3]||""},console.log(`[twoProxy] enabled: ${u.hostname}:${u.port}`))}return l.pipeTo(new WritableStream({async write(e){if(i)return await g(e,o,null);if(a.socket){const t=a.socket.writable.getWriter();return await t.write(e),void t.releaseLock()}if(null===d){const t=new Uint8Array(e);d=t.byteLength>=58&&13===t[56]&&10===t[57]}if(a.socket){const t=a.socket.writable.getWriter();return await t.write(e),void t.releaseLock()}if(d){const{port:n,hostname:s,rawClientData:r}=function(e,t){const n=function(e){const t=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],n=(e,t)=>(e>>>t|e<<32-t)>>>0,s=8*(e=unescape(encodeURIComponent(e))).length;e+=String.fromCharCode(128);for(;8*e.length%512!=448;)e+=String.fromCharCode(0);const r=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428],o=Math.floor(s/4294967296),a=4294967295&s;e+=String.fromCharCode(o>>>24&255,o>>>16&255,o>>>8&255,255&o,a>>>24&255,a>>>16&255,a>>>8&255,255&a);const i=[];for(let t=0;t<e.length;t+=4)i.push(e.charCodeAt(t)<<24|e.charCodeAt(t+1)<<16|e.charCodeAt(t+2)<<8|e.charCodeAt(t+3));for(let e=0;e<i.length;e+=16){const s=new Array(64).fill(0);for(let t=0;t<16;t++)s[t]=i[e+t];for(let e=16;e<64;e++){const t=n(s[e-15],7)^n(s[e-15],18)^s[e-15]>>>3,r=n(s[e-2],17)^n(s[e-2],19)^s[e-2]>>>10;s[e]=s[e-16]+t+s[e-7]+r>>>0}let[o,a,c,l,d,u,p,h]=r;for(let e=0;e<64;e++){const r=h+(n(d,6)^n(d,11)^n(d,25))+(d&u^~d&p)+t[e]+s[e]>>>0,i=o&a^o&c^a&c;h=p,p=u,u=d,d=l+r>>>0,l=c,c=a,a=o,o=r+((n(o,2)^n(o,13)^n(o,22))+i>>>0)>>>0}for(let e=0;e<8;e++)r[e]=r[e]+(0===e?o:1===e?a:2===e?c:3===e?l:4===e?d:5===e?u:6===e?p:h)>>>0}let c="";for(let e=0;e<7;e++)for(let t=24;t>=0;t-=8)c+=(r[e]>>>t&255).toString(16).padStart(2,"0");return c}(t);if(e.byteLength<56)return{hasError:!0,message:"invalid data"};let s=56;if(13!==new Uint8Array(e.slice(56,57))[0]||10!==new Uint8Array(e.slice(57,58))[0])return{hasError:!0,message:"invalid header format"};if((new TextDecoder).decode(e.slice(0,s))!==n)return{hasError:!0,message:"invalid password"};const r=e.slice(s+2);if(r.byteLength<6)return{hasError:!0,message:"invalid S5 request data"};const o=new DataView(r);if(1!==o.getUint8(0))return{hasError:!0,message:"unsupported command, only TCP is allowed"};const a=o.getUint8(1);let i=0,c=2,l="";switch(a){case 1:i=4,l=new Uint8Array(r.slice(c,c+i)).join(".");break;case 3:i=new Uint8Array(r.slice(c,c+1))[0],c+=1,l=(new TextDecoder).decode(r.slice(c,c+i));break;case 4:i=16;const e=new DataView(r.slice(c,c+i)),t=[];for(let n=0;n<8;n++)t.push(e.getUint16(2*n).toString(16));l=t.join(":");break;default:return{hasError:!0,message:`invalid addressType is ${a}`}}if(!l)return{hasError:!0,message:`address is empty, addressType is ${a}`};const d=c+i,u=r.slice(d,d+2),p=new DataView(u).getUint16(0);return{hasError:!1,addressType:a,port:p,hostname:l,rawClientData:r.slice(d+4)}}(e,t);if(y(s))throw new Error("Speedtest site is blocked");await f(s,n,r,o,null,a,t,u)}else{const{port:n,hostname:s,rawIndex:r,version:c,isUDP:l}=function(e,t){if(e.byteLength<24)return{hasError:!0,message:"Invalid data"};const n=new Uint8Array(e.slice(0,1));if(function(e,t=0){const n=[...e.slice(t,t+16)].map(e=>e.toString(16).padStart(2,"0")).join("");return`${n.substring(0,8)}-${n.substring(8,12)}-${n.substring(12,16)}-${n.substring(16,20)}-${n.substring(20)}`}(new Uint8Array(e.slice(1,17)))!==t)return{hasError:!0,message:"Invalid uuid"};const s=new Uint8Array(e.slice(17,18))[0],r=new Uint8Array(e.slice(18+s,19+s))[0];let o=!1;if(1===r);else{if(2!==r)return{hasError:!0,message:"Invalid command"};o=!0}const a=19+s,i=new DataView(e.slice(a,a+2)).getUint16(0);let c=a+2,l=0,d=c+1,u="";const p=new Uint8Array(e.slice(c,d))[0];switch(p){case 1:l=4,u=new Uint8Array(e.slice(d,d+l)).join(".");break;case 2:l=new Uint8Array(e.slice(d,d+1))[0],d+=1,u=(new TextDecoder).decode(e.slice(d,d+l));break;case 3:l=16;const t=[],n=new DataView(e.slice(d,d+l));for(let e=0;e<8;e++)t.push(n.getUint16(2*e).toString(16));u=t.join(":");break;default:return{hasError:!0,message:`Invalid address type: ${p}`}}return u?{hasError:!1,addressType:p,port:i,hostname:u,isUDP:o,rawIndex:d+l,version:n}:{hasError:!0,message:`Invalid address: ${p}`}}(e,t);if(y(s))throw new Error("Speedtest site is blocked");if(l){if(53!==n)throw new Error("UDP is not supported");i=!0}const d=new Uint8Array([c[0],0]),p=e.slice(r);if(i)return g(p,o,d);await f(s,n,p,o,d,a,t,u)}}})).catch(e=>{}),new Response(null,{status:101,webSocket:r})}(e,_,l)}}else{if("http:"===l.protocol)return Response.redirect(l.href.replace(`http://${l.hostname}`,`https://${l.hostname}`),301);const r=l.pathname.slice(1).toLowerCase(),o=("false"!==n.NEW_IP&&n.NEW_IP,!R||!O.test(R)),a=n.TWO_PROXY||n.two_proxy||"";if(""===r||"/"===r){const t=e.cf?.colo||"UNKNOWN",n="/"+_+(a?"?two_proxy="+encodeURIComponent(a):""),s="vless://"+_+"@"+l.hostname+":443?security=tls&type=ws&host="+l.hostname+"&sni="+l.hostname+"&path="+encodeURIComponent(n)+"&encryption=none#CFspider-"+t;return new Response(JSON.stringify({status:"online",version:"1.8.7",colo:t,host:l.hostname,uuid:_,vless:s,two_proxy:a||null},null,2),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("api/proxyip"===r){const t=e.cf?.colo||"UNKNOWN",s=(t+".proxyip.cmliussss.net").toLowerCase(),r=n.PROXYIP||"";return new Response(JSON.stringify({colo:t,default:s,hk:"proxyip.cfspider.com",env:r||null,current:r||s,options:{default:{name:"nlNode",address:s},hk:{name:"hkNode",address:"proxyip.cfspider.com"}}}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("api/uuid"===r||"api/config"===r){const e="false"!==n.NEW_IP&&"0"!==n.NEW_IP,t=n.TWO_PROXY||n.two_proxy||"",s={host:l.hostname,new_ip:e,version:"1.8.7",is_default_uuid:o,two_proxy_enabled:!!t};if(o?(s.uuid=_,s.vless_path=t?"/"+_+"?two_proxy="+encodeURIComponent(t):"/"+_):t&&(s.two_proxy=t),t){const e=t.split(":");s.two_proxy_host=e[0]||"",s.two_proxy_port=e[1]||""}return new Response(JSON.stringify(s),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("proxy"===r||r.startsWith("proxy?")){const t=l.searchParams.get("url"),s=l.searchParams.get("method")||"GET",r=l.searchParams.get("two_proxy");if(!t)return new Response(JSON.stringify({error:"Missing url parameter"}),{status:400,headers:{"Content-Type":"application/json"}});try{const o={};for(const[t,n]of e.headers)if(t.toLowerCase().startsWith("x-cfspider-header-")){o[t.substring(18)]=n}let a;const i=r||n.TWO_PROXY||n.two_proxy||"";if(i){const n=i.split(":"),r=n[0],a=parseInt(n[1])||3128,c=n[2]||"",l=n[3]||"",d=new URL(t),u=d.hostname,p=(d.port||d.protocol,"https:"===d.protocol),{connect:h}=await import("cloudflare:sockets");if(p)return new Response(JSON.stringify({error:"HTTPS + two_proxy notSupportedViaProxyAPI。useCfspiderGetWithTwoProxy。",hint:"cfspider.get(url, cf_proxies=..., uuid=..., two_proxy=...)",reason:"Workers /proxy API onlyHTTPTwoProxySupported"}),{status:501,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}});{const n=h({hostname:r,port:a}),i=n.writable.getWriter(),d=n.readable.getReader();let p=`${s} ${t} HTTP/1.1\r\nHost: ${u}\r\n`;if(c&&l){p+=`Proxy-Authorization: Basic ${btoa(`${c}:${l}`)}\r\n`}for(const[e,t]of Object.entries(o))p+=`${e}: ${t}\r\n`;p+="Connection: close\r\n\r\n",await i.write((new TextEncoder).encode(p));let f=new Uint8Array(0);for(;;){const{value:e,done:t}=await d.read();if(t)break;const n=new Uint8Array(f.length+e.length);n.set(f),n.set(e,f.length),f=n}const g=(new TextDecoder).decode(f),m=g.indexOf("\r\n\r\n"),w=g.substring(0,m),y=f.slice((new TextEncoder).encode(g.substring(0,m+4)).length),b=w.split("\r\n")[0],C=parseInt(b.split(" ")[1])||200,x=new Headers;return w.split("\r\n").slice(1).forEach(e=>{const[t,...n]=e.split(":");t&&n.length&&x.set(t.trim(),n.join(":").trim())}),x.set("Access-Control-Allow-Origin","*"),x.set("X-CF-Colo",e.cf?.colo||"unknown"),x.set("X-CFspider-Version","1.8.6"),x.set("X-CFspider-TwoProxy","enabled"),new Response(y,{status:C,headers:x})}}{const n=new Request(t,{method:s,headers:o,body:"GET"!==s&&"HEAD"!==s?e.body:null});a=await fetch(n);const r=new Headers(a.headers);return r.set("Access-Control-Allow-Origin","*"),r.set("X-CF-Colo",e.cf?.colo||"unknown"),r.set("X-CFspider-Version","1.8.6"),new Response(a.body,{status:a.status,headers:r})}}catch(e){return new Response(JSON.stringify({error:e.message}),{status:500,headers:{"Content-Type":"application/json"}})}}if("api/config/new_ip"===r&&"POST"===e.method){const e="false"!==n.NEW_IP&&"0"!==n.NEW_IP;return new Response(JSON.stringify({new_ip:e,message:"setNEWIPViaDashboard"}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if(!C)return fetch(h+"/noADMIN").then(e=>{const t=new Headers(e.headers);return t.set("Cache-Control","no-store, no-cache, must-revalidate, proxy-revalidate"),t.set("Pragma","no-cache"),t.set("Expires","0"),new Response(e.body,{status:404,statusText:e.statusText,headers:t})});if(n.KV&&"function"==typeof n.KV.get){const r=l.pathname.slice(1).toLowerCase(),o=l.pathname.slice(1);if(o===A&&"doNotModifyDefaultKey"!==A){const e=new URLSearchParams(l.search);return e.set("token",await T(j+_)),new Response("redirecting...",{status:302,headers:{Location:`/sub?${e.toString()}`}})}if("login"===r){const t=e.headers.get("Cookie")||"",n=t.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(n==await T(w+A+C))return new Response("redirecting...",{status:302,headers:{Location:"/admin"}});if("POST"===e.method){const t=await e.text();if(new URLSearchParams(t).get("password")===C){const e=new Response(JSON.stringify({success:!0}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}});return e.headers.set("Set-Cookie",`auth=${await T(w+A+C)}; Path=/; Max-Age=86400; HttpOnly`),e}}return fetch(h+"/login")}if("admin"===r||r.startsWith("admin/")){const a=e.headers.get("Cookie")||"",i=a.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(!i||i!==await T(w+A+C))return new Response("redirecting...",{status:302,headers:{Location:"/login"}});if("admin/log.json"===r){const e=await n.KV.get("log.json")||"[]";return new Response(e,{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}if("admin/getCloudflareUsage"===o)try{const e=await U(l.searchParams.get("Email"),l.searchParams.get("GlobalAPIKey"),l.searchParams.get("AccountID"),l.searchParams.get("APIToken"));return new Response(JSON.stringify(e,null,2),{status:200,headers:{"Content-Type":"application/json"}})}catch(e){const t={msg:"queryRequestFailed,reason:"+e.message,error:e.message};return new Response(JSON.stringify(t,null,2),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else{if("admin/getADDAPI"===o){if(l.searchParams.get("url")){const e=l.searchParams.get("url");try{new URL(e);const t=await I([e],l.searchParams.get("port")||"443"),n=t[0].length>0?t[0]:t[1];return new Response(JSON.stringify({success:!0,data:n},null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){const t={msg:"verifyAPIFailed,reason:"+e.message,error:e.message};return new Response(JSON.stringify(t,null,2),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}}return new Response(JSON.stringify({success:!1,data:[]},null,2),{status:403,headers:{"Content-Type":"application/json;charset=utf-8"}})}if("admin/check"===r){let e;if(l.searchParams.has("socks5"))e=await k("socks5",l.searchParams.get("socks5"));else{if(!l.searchParams.has("http"))return new Response(JSON.stringify({error:"missingProxyParam"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});e=await k("http",l.searchParams.get("http"))}return new Response(JSON.stringify(e,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}}if(t=await $(n,j,_,n.PATH),"admin/init"===r)try{return t=await $(n,j,_,n.PATH,!0),s.waitUntil(x(n,e,N,"Init_Config",t)),t.init="configResetToDefault",new Response(JSON.stringify(t,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){const t={msg:"configResetFailed,reason:"+e.message,error:e.message};return new Response(JSON.stringify(t,null,2),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else if("POST"===e.method)if("admin/config.json"===r)try{const r=await e.json();return r.UUID&&r.HOST?(await n.KV.put("config.json",JSON.stringify(r,null,2)),s.waitUntil(x(n,e,N,"Save_Config",t)),new Response(JSON.stringify({success:!0,message:"configSaved"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})):new Response(JSON.stringify({error:"incompleteConfig"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("saveConfigFailed:",e),new Response(JSON.stringify({error:"saveConfigFailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else if("admin/cf.json"===r)try{const r=await e.json(),o={Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null};if(!r.init||!0!==r.init)if(r.Email&&r.GlobalAPIKey)o.Email=r.Email,o.GlobalAPIKey=r.GlobalAPIKey;else if(r.AccountID&&r.APIToken)o.AccountID=r.AccountID,o.APIToken=r.APIToken;else{if(!r.UsageAPI)return new Response(JSON.stringify({error:"incompleteConfig"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});o.UsageAPI=r.UsageAPI}return await n.KV.put("cf.json",JSON.stringify(o,null,2)),s.waitUntil(x(n,e,N,"Save_Config",t)),new Response(JSON.stringify({success:!0,message:"configSaved"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("saveConfigFailed:",e),new Response(JSON.stringify({error:"saveConfigFailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else if("admin/tg.json"===r)try{const r=await e.json();if(r.init&&!0===r.init){const e={BotToken:null,ChatID:null};await n.KV.put("tg.json",JSON.stringify(e,null,2))}else{if(!r.BotToken||!r.ChatID)return new Response(JSON.stringify({error:"incompleteConfig"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});await n.KV.put("tg.json",JSON.stringify(r,null,2))}return s.waitUntil(x(n,e,N,"Save_Config",t)),new Response(JSON.stringify({success:!0,message:"configSaved"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("saveConfigFailed:",e),new Response(JSON.stringify({error:"saveConfigFailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else{if("admin/ADD.txt"!==o)return new Response(JSON.stringify({error:"unsupportedPOSTPath"}),{status:404,headers:{"Content-Type":"application/json;charset=utf-8"}});try{const r=await e.text();return await n.KV.put("ADD.txt",r),s.waitUntil(x(n,e,N,"Save_Custom_IPs",t)),new Response(JSON.stringify({success:!0,message:"customIPSaved"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("saveCustomIPfailed:",e),new Response(JSON.stringify({error:"saveCustomIPfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}}else{if("admin/config.json"===r)return new Response(JSON.stringify(t,null,2),{status:200,headers:{"Content-Type":"application/json"}});if("admin/ADD.txt"===o){let s=await n.KV.get("ADD.txt")||"null";return"null"==s&&(s=(await P(e,t.subGenerator.localIPPool.randomCount,t.subGenerator.localIPPool.specifiedPort))[1]),new Response(s,{status:200,headers:{"Content-Type":"text/plain;charset=utf-8",asn:e.cf.asn}})}if("admin/cf.json"===r)return new Response(JSON.stringify(e.cf,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}return s.waitUntil(x(n,e,N,"Admin_Login",t)),fetch(h+"/admin")}if("logout"===r||O.test(r)){const e=new Response("redirecting...",{status:302,headers:{Location:"/login"}});return e.headers.set("Set-Cookie","auth=; Path=/; Max-Age=0; HttpOnly"),e}if("sub"===r){const r=await T(j+_);if(l.searchParams.get("token")===r){t=await $(n,j,_,n.PATH),s.waitUntil(x(n,e,N,"Get_SUB",t));const o=w.toLowerCase(),a=4102329600,i=Date.now(),c=new Date(i);c.setHours(0,0,0,0);const d=Math.floor((i-c.getTime())/864e5*24*1099511627776/2);let p=d,h=d,f=26388279066624;t.CF.Usage.success&&(p=t.CF.Usage.pages,h=t.CF.Usage.workers,f=Number.isFinite(t.CF.Usage.max)?t.CF.Usage.max/1e3*1024:102400);const g={"content-type":"text/plain; charset=utf-8","Profile-Update-Interval":t.subGenerator.SUBUpdateTime,"Profile-web-page-url":l.protocol+"//"+l.host+"/admin","Subscription-Userinfo":`upload=${p}; download=${h}; total=${f}; expire=${a}`,"Cache-Control":"no-store"},m=l.searchParams.has("b64")||l.searchParams.has("base64")||e.headers.get("subconverter-request")||e.headers.get("subconverter-version")||o.includes("subconverter")||o.includes("CF-Workers-SUB".toLowerCase())?"mixed":l.searchParams.has("target")?l.searchParams.get("target"):l.searchParams.has("clash")||o.includes("clash")||o.includes("meta")||o.includes("mihomo")?"clash":l.searchParams.has("sb")||l.searchParams.has("singbox")||o.includes("singbox")||o.includes("sing-box")?"singbox":l.searchParams.has("surge")||o.includes("surge")?"surge&ver=4":l.searchParams.has("quanx")||o.includes("quantumult")?"quanx":l.searchParams.has("loon")||o.includes("loon")?"loon":"mixed";o.includes("mozilla")||(g["Content-Disposition"]=`attachment; filename*=utf-8''${encodeURIComponent(t.subGenerator.SUBNAME)}`);const y=l.searchParams.has("surge")||o.includes("surge")?"trojan":t.protocolType;let b="";if("mixed"===m){const s=t.enable0RTT?t.PATH+"?ed=2560":t.PATH,r="Shadowrocket"==t.tlsFragment?`&fragment=${encodeURIComponent("1,40-60,30-50,tlshello")}`:"Happ"==t.tlsFragment?`&fragment=${encodeURIComponent("3,1,tlshello")}`:"";let o=[],a="";if(!l.searchParams.has("sub")&&t.subGenerator.local){const s=t.subGenerator.localIPPool.randomIP?(await P(e,t.subGenerator.localIPPool.randomCount,t.subGenerator.localIPPool.specifiedPort))[0]:await n.KV.get("ADD.txt")?await S(await n.KV.get("ADD.txt")):(await P(e,t.subGenerator.localIPPool.randomCount,t.subGenerator.localIPPool.specifiedPort))[0],r=[],i=[],c=[];for(const e of s)if(e.toLowerCase().startsWith("https://"))r.push(e);else if(e.toLowerCase().includes("://"))if(e.includes("#")){const t=e.split("#");c.push(t[0]+"#"+encodeURIComponent(decodeURIComponent(t[1])))}else c.push(e);else i.push(e);const l=await I(r),d=[...new Set(c.concat(l[1]))];a=d.length>0?d.join("\n")+"\n":"";const u=l[0];o=[...new Set(i.concat(u))]}else{let e=l.searchParams.get("sub")||t.subGenerator.SUB;e=e&&!/^https?:\/\//i.test(e)?`https://${e}`:e;const n=`${e}/sub?host=example.com&uuid=00000000-0000-4000-8000-000000000000`;try{const e=await fetch(n,{headers:{"User-Agent":"v2rayN/edgetunnel (https://github.com/cmliu/edgetunnel)"}});if(!e.ok)return new Response("subGenError:"+e.statusText,{status:e.status});const t=atob(await e.text()),s=t.includes("\r\n")?t.split("\r\n"):t.split("\n");for(const e of s)if(e.trim())if(e.includes("00000000-0000-4000-8000-000000000000")&&e.includes("example.com")){const t=e.match(/:\/\/[^@]+@([^?]+)/);if(t){let n=t[1],s="";const r=e.match(/#(.+)$/);r&&(s="#"+decodeURIComponent(r[1])),o.push(n+s)}}else a+=e+"\n"}catch(e){return new Response("subGenError:"+e.message,{status:403})}}const i=t.ECH?`&ech=${encodeURIComponent("cloudflare-ech.com+"+u)}`:"";b=a+o.map(e=>{const n=e.match(/^(\[[\da-fA-F:]+\]|[\d.]+|[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*)(?::(\d+))?(?:#(.+))?$/);let o,a,c="443";return n?(o=n[1],c=n[2]||"443",a=n[3]||o,`${y}://00000000-0000-4000-8000-000000000000@${o}:${c}?security=tls&type=${t.transport+i}&host=example.com&fp=${t.Fingerprint}&sni=example.com&path=${encodeURIComponent(t.randomPath?function(){const e=["about","account","acg","act","activity","ad","ads","ajax","album","albums","anime","api","app","apps","archive","archives","article","articles","ask","auth","avatar","bbs","bd","blog","blogs","book","books","bt","buy","cart","category","categories","cb","channel","channels","chat","china","city","class","classify","clip","clips","club","cn","code","collect","collection","comic","comics","community","company","config","contact","content","course","courses","cp","data","detail","details","dh","directory","discount","discuss","dl","dload","doc","docs","document","documents","doujin","download","downloads","drama","edu","en","ep","episode","episodes","event","events","f","faq","favorite","favourites","favs","feedback","file","files","film","films","forum","forums","friend","friends","game","games","gif","go","go.html","go.php","group","groups","help","home","hot","htm","html","image","images","img","index","info","intro","item","items","ja","jp","jump","jump.html","jump.php","jumping","knowledge","lang","lesson","lessons","lib","library","link","links","list","live","lives","m","mag","magnet","mall","manhua","map","member","members","message","messages","mobile","movie","movies","music","my","new","news","note","novel","novels","online","order","out","out.html","out.php","outbound","p","page","pages","pay","payment","pdf","photo","photos","pic","pics","picture","pictures","play","player","playlist","post","posts","product","products","program","programs","project","qa","question","rank","ranking","read","readme","redirect","redirect.html","redirect.php","reg","register","res","resource","retrieve","sale","search","season","seasons","section","seller","series","service","services","setting","settings","share","shop","show","shows","site","soft","sort","source","special","star","stars","static","stock","store","stream","streaming","streams","student","study","tag","tags","task","teacher","team","tech","temp","test","thread","tool","tools","topic","topics","torrent","trade","travel","tv","txt","type","u","upload","uploads","url","urls","user","users","v","version","video","videos","view","vip","vod","watch","web","wenku","wiki","work","www","zh","zh-cn","zh-tw","zip"],t=Math.floor(3*Math.random()+1),n=e.sort(()=>.5-Math.random()).slice(0,t).join("/");return`/${n}`}()+s:s)+r}&encryption=none${t.skipCertVerify?"&insecure=1&allowInsecure=1":""}#${encodeURIComponent(a)}`):(console.warn(`[subContent] invalidIPIgnored: ${e}`),null)}).filter(e=>null!==e).join("\n")}else{const e=`${t.subConverterConfig.SUBAPI}/sub?target=${m}&url=${encodeURIComponent(l.protocol+"//"+l.host+"/sub?target=mixed&token="+r+(l.searchParams.has("sub")&&""!=l.searchParams.get("sub")?`&sub=${l.searchParams.get("sub")}`:""))}&config=${encodeURIComponent(t.subConverterConfig.SUBCONFIG)}&emoji=${t.subConverterConfig.SUBEMOJI}&scv=${t.skipCertVerify}`;try{const n=await fetch(e,{headers:{"User-Agent":"Subconverter for "+m+" edgetunnel(https://github.com/cmliu/edgetunnel)"}});if(!n.ok)return new Response("subConverterError:"+n.statusText,{status:n.status});b=await n.text(),(l.searchParams.has("surge")||o.includes("surge"))&&(b=function(e,t,n){const s=e.includes("\r\n")?e.split("\r\n"):e.split("\n");let r="";const o=n.enable0RTT?n.PATH+"?ed=2560":n.PATH;for(let e of s)if(!e.includes("= trojan,")||e.includes("ws=true")||e.includes("ws-path="))r+=e+"\n";else{const t=e.split("sni=")[1].split(",")[0],s=`sni=${t}, skip-cert-verify=${n.skipCertVerify}`,a=`sni=${t}, skip-cert-verify=${n.skipCertVerify}, ws=true, ws-path=${o}, ws-headers=Host:"${t}"`;r+=e.replace(new RegExp(s,"g"),a).replace("[","").replace("]","")+"\n"}return r=`#!MANAGED-CONFIG ${t} interval=${60*n.subGenerator.SUBUpdateTime*60} strict=false`+r.substring(r.indexOf("\n")),r}(b,l.protocol+"//"+l.host+"/sub?token="+r+"&surge",t))}catch(e){return new Response("subConverterError:"+e.message,{status:403})}}return o.includes("subconverter")||(b=await function(e,t,n=2){const s=[...t].sort(()=>Math.random()-.5);let r=0,o=null;return e.replace(/example\.com/g,()=>(r%n===0&&(o=function(e){if(!e?.includes("*"))return e;const t="abcdefghijklmnopqrstuvwxyz0123456789";return e.replace(/\*/g,()=>{let e="";for(let n=0;n<Math.floor(14*Math.random())+3;n++)e+=t[Math.floor(36*Math.random())];return e})}(s[Math.floor(r/n)%s.length])),r++,o))}(b.replace(/00000000-0000-4000-8000-000000000000/g,t.UUID),t.HOSTS)),"mixed"!==m||o.includes("mozilla")&&!l.searchParams.has("b64")&&!l.searchParams.has("base64")||(b=btoa(b)),"singbox"===m?(b=function(e,t=null,n="chrome",s=null){try{let r=JSON.parse(e);Array.isArray(r.inbounds)&&r.inbounds.forEach(e=>{if("tun"===e.type){const t=[];e.inet4_address&&t.push(e.inet4_address),e.inet6_address&&t.push(e.inet6_address),t.length>0&&(e.address=t,delete e.inet4_address,delete e.inet6_address);const n=[];Array.isArray(e.inet4_route_address)&&n.push(...e.inet4_route_address),Array.isArray(e.inet6_route_address)&&n.push(...e.inet6_route_address),n.length>0&&(e.route_address=n,delete e.inet4_route_address,delete e.inet6_route_address);const s=[];Array.isArray(e.inet4_route_exclude_address)&&s.push(...e.inet4_route_exclude_address),Array.isArray(e.inet6_route_exclude_address)&&s.push(...e.inet6_route_exclude_address),s.length>0&&(e.route_exclude_address=s,delete e.inet4_route_exclude_address,delete e.inet6_route_exclude_address)}});const o=new Map,a=(e,t=!1)=>{Array.isArray(e)&&e.forEach(e=>{if(e.geosite){const t=Array.isArray(e.geosite)?e.geosite:[e.geosite];e.rule_set=t.map(e=>{const t=`geosite-${e}`;return o.has(t)||o.set(t,{tag:t,type:"remote",format:"binary",url:`https://gh.090227.xyz/https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-${e}.srs`,download_detour:"DIRECT"}),t}),delete e.geosite}if(e.geoip){const t=Array.isArray(e.geoip)?e.geoip:[e.geoip];e.rule_set=e.rule_set||[],t.forEach(t=>{const n=`geoip-${t}`;o.has(n)||o.set(n,{tag:n,type:"remote",format:"binary",url:`https://gh.090227.xyz/https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-${t}.srs`,download_detour:"DIRECT"}),e.rule_set.push(n)}),delete e.geoip}const n=t?"server":"outbound",s=String(e[n]).toUpperCase();"REJECT"!==s&&"BLOCK"!==s||(e.action="reject",e.method="drop",delete e[n])})};r.dns&&r.dns.rules&&a(r.dns.rules,!0),r.route&&r.route.rules&&a(r.route.rules,!1),o.size>0&&(r.route||(r.route={}),r.route.rule_set=Array.from(o.values())),r.outbounds||(r.outbounds=[]),r.outbounds=r.outbounds.filter(e=>"REJECT"!==e.tag&&"block"!==e.tag);const i=new Set(r.outbounds.map(e=>e.tag));if(i.has("DIRECT")||(r.outbounds.push({type:"direct",tag:"DIRECT"}),i.add("DIRECT")),r.dns&&r.dns.servers){const e=new Set(r.dns.servers.map(e=>e.tag));r.dns.rules&&r.dns.rules.forEach(t=>{t.server&&!e.has(t.server)&&("dns_block"===t.server&&e.has("block")?t.server="block":t.server.toLowerCase().includes("block")&&!e.has(t.server)&&(r.dns.servers.push({tag:t.server,address:"rcode://success"}),e.add(t.server)))})}return r.outbounds.forEach(e=>{"selector"!==e.type&&"urltest"!==e.type||Array.isArray(e.outbounds)&&(e.outbounds=e.outbounds.filter(e=>{const t=e.toUpperCase();return i.has(e)&&"REJECT"!==t&&"BLOCK"!==t}),0===e.outbounds.length&&e.outbounds.push("DIRECT"))}),t&&r.outbounds.forEach(e=>{(e.uuid&&e.uuid===t||e.password&&e.password===t)&&(e.tls||(e.tls={enabled:!0}),n&&(e.tls.utls={enabled:!0,fingerprint:n}),s&&(e.tls.ech={enabled:!0,config:`-----BEGIN ECH CONFIGS-----\n${s}\n-----END ECH CONFIGS-----`}))}),JSON.stringify(r,null,2)}catch(t){return console.error("singboxPatchFailed:",t),JSON.stringify(JSON.parse(e),null,2)}}(b,t.UUID,t.Fingerprint,t.ECH?await async function(e){try{const t=await fetch(`https://1.1.1.1/dns-query?name=${encodeURIComponent(e)}&type=65`,{headers:{accept:"application/dns-json"}}),n=await t.json();if(!n.Answer?.length)return"";for(let e of n.Answer){if(65!==e.type||!e.data)continue;const t=e.data.match(/ech=([^\s]+)/);if(t)return t[1].replace(/"/g,"");if(e.data.startsWith("\\#")){const t=e.data.split(" ").slice(2).join(""),n=new Uint8Array(t.match(/.{1,2}/g).map(e=>parseInt(e,16)));let s=2;for(;s<n.length&&0!==n[s++];)s+=n[s-1];for(;s+4<=n.length;){const e=n[s]<<8|n[s+1],t=n[s+2]<<8|n[s+3];if(s+=4,5===e)return btoa(String.fromCharCode(...n.slice(s,s+t)));s+=t}}}return""}catch{return""}}(j):null),g["content-type"]="application/json; charset=utf-8"):"clash"===m&&(b=function(e,t=null,n=!1,s=[]){let r=e.replace(/mode:\s*Rule\b/g,"mode: rule");const o="dns:\n enable: true\n default-nameserver:\n - 223.5.5.5\n - 119.29.29.29\n - 114.114.114.114\n use-hosts: true\n nameserver:\n - https://sm2.doh.pub/dns-query\n - https://dns.alidns.com/dns-query\n fallback:\n - 8.8.4.4\n - 101.101.101.101\n - 208.67.220.220\n fallback-filter:\n geoip: true\n domain: [+.google.com, +.facebook.com, +.youtube.com]\n ipcidr:\n - 240.0.0.0/4\n - 0.0.0.0/32\n geoip-code: CN\n";/^dns:\s*(?:\n|$)/m.test(r)||(r=o+r);if(n&&s.length>0){const e=s.map(e=>` "${e}":\n - tls://8.8.8.8\n - https://doh.cmliussss.com/CMLiussss\n - ${u}`).join("\n");if(/^\s{2}nameserver-policy:\s*(?:\n|$)/m.test(r))r=r.replace(/^(\s{2}nameserver-policy:\s*\n)/m,`$1${e}\n`);else{const t=r.split("\n");let n=-1,s=!1;for(let e=0;e<t.length;e++){const r=t[e];if(/^dns:\s*$/.test(r))s=!0;else if(s&&/^[a-zA-Z]/.test(r)){n=e;break}}const o=` nameserver-policy:\n${e}`;-1!==n?t.splice(n,0,o):t.push(o),r=t.join("\n")}}if(!t||!n)return r;const a=r.split("\n"),i=[];let c=0;for(;c<a.length;){const e=a[c],n=e.trim();if(n.startsWith("- {")&&(n.includes("uuid:")||n.includes("password:"))){let n=e,s=(e.match(/\{/g)||[]).length-(e.match(/\}/g)||[]).length;for(;s>0&&c+1<a.length;)c++,n+="\n"+a[c],s+=(a[c].match(/\{/g)||[]).length-(a[c].match(/\}/g)||[]).length;const r=n.match(/type:\s*(\w+)/);let o="uuid";"trojan"===(r?r[1]:"vless")&&(o="password");const l=new RegExp(`${o}:\\s*([^,}\\n]+)`),d=n.match(l);d&&d[1].trim()===t.trim()&&(n=n.replace(/\}(\s*)$/,", ech-opts: {enable: true}}$1")),i.push(n),c++}else if(n.startsWith("- name:")){let n=[e],s=e.search(/\S/),r=s+2;for(c++;c<a.length;){const e=a[c],t=e.trim();if(!t){n.push(e),c++;break}const r=e.search(/\S/);if(r<=s&&t.startsWith("- "))break;if(r<s&&t)break;n.push(e),c++}const o=n.join("\n"),l=o.match(/type:\s*(\w+)/);let d="uuid";"trojan"===(l?l[1]:"vless")&&(d="password");const u=new RegExp(`${d}:\\s*([^\\n]+)`),p=o.match(u);if(p&&p[1].trim()===t.trim()){let e=-1;for(let t=n.length-1;t>=0;t--)if(n[t].trim()){e=t;break}if(e>=0){const t=" ".repeat(r);n.splice(e+1,0,`${t}ech-opts:`,`${t} enable: true`)}}i.push(...n)}else i.push(e),c++}return i.join("\n")}(b,t.UUID,t.ECH,t.HOSTS),g["content-type"]="application/x-yaml; charset=utf-8"),new Response(b,{status:200,headers:g})}}else if("locations"===r){const t=e.headers.get("Cookie")||"",n=t.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(n&&n==await T(w+A+C))return fetch(new Request("https://speed.cloudflare.com/locations",{headers:{Referer:"https://speed.cloudflare.com/"}}))}else if("robots.txt"===r)return new Response("User-agent: *\nDisallow: /",{status:200,headers:{"Content-Type":"text/plain; charset=UTF-8"}})}else if(!R)return fetch(h+"/noKV").then(e=>{const t=new Headers(e.headers);return t.set("Cache-Control","no-store, no-cache, must-revalidate, proxy-revalidate"),t.set("Pragma","no-cache"),t.set("Expires","0"),new Response(e.body,{status:404,statusText:e.statusText,headers:t})})}let D=n.URL||"nginx";if(D&&"nginx"!==D&&"1101"!==D){D=D.trim().replace(/\/$/,""),D.match(/^https?:\/\//i)||(D="https://"+D),D.toLowerCase().startsWith("http://")&&(D="https://"+D.substring(7));try{const e=new URL(D);D=e.protocol+"//"+e.host}catch(e){D="nginx"}}if("1101"===D)return new Response(await async function(e,t){const n=new Date,s=n.getFullYear()+"-"+String(n.getMonth()+1).padStart(2,"0")+"-"+String(n.getDate()).padStart(2,"0")+" "+String(n.getHours()).padStart(2,"0")+":"+String(n.getMinutes()).padStart(2,"0")+":"+String(n.getSeconds()).padStart(2,"0"),r=Array.from(crypto.getRandomValues(new Uint8Array(8))).map(e=>e.toString(16).padStart(2,"0")).join("");return`<!DOCTYPE html>\n\x3c!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en-US"> <![endif]--\x3e\n\x3c!--[if IE 7]> <html class="no-js ie7 oldie" lang="en-US"> <![endif]--\x3e\n\x3c!--[if IE 8]> <html class="no-js ie8 oldie" lang="en-US"> <![endif]--\x3e\n\x3c!--[if gt IE 8]>\x3c!--\x3e <html class="no-js" lang="en-US"> \x3c!--<![endif]--\x3e\n<head>\n<title>Worker threw exception | ${e} | Cloudflare</title>\n<meta charset="UTF-8" />\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\n<meta http-equiv="X-UA-Compatible" content="IE=Edge" />\n<meta name="robots" content="noindex, nofollow" />\n<meta name="viewport" content="width=device-width,initial-scale=1" />\n<link rel="stylesheet" id="cf_styles-css" href="/cdn-cgi/styles/cf.errors.css" />\n\x3c!--[if lt IE 9]><link rel="stylesheet" id='cf_styles-ie-css' href="/cdn-cgi/styles/cf.errors.ie.css" /><![endif]--\x3e\n<style>body{margin:0;padding:0}</style>\n\n\n\x3c!--[if gte IE 10]>\x3c!--\x3e\n<script>\n if (!navigator.cookieEnabled) {\n window.addEventListener('DOMContentLoaded', function () {\n var cookieEl = document.getElementById('cookie-alert');\n cookieEl.style.display = 'block';\n })\n }\n<\/script>\n\x3c!--<![endif]--\x3e\n\n</head>\n<body>\n <div id="cf-wrapper">\n <div class="cf-alert cf-alert-error cf-cookie-error" id="cookie-alert" data-translate="enable_cookies">Please enable cookies.</div>\n <div id="cf-error-details" class="cf-error-details-wrapper">\n <div class="cf-wrapper cf-header cf-error-overview">\n <h1>\n <span class="cf-error-type" data-translate="error">Error</span>\n <span class="cf-error-code">1101</span>\n <small class="heading-ray-id">Ray ID: ${r} • ${s} UTC</small>\n </h1>\n <h2 class="cf-subheadline" data-translate="error_desc">Worker threw exception</h2>\n </div>\x3c!-- /.header --\x3e\n \n <section></section>\x3c!-- spacer --\x3e\n \n <div class="cf-section cf-wrapper">\n <div class="cf-columns two">\n <div class="cf-column">\n <h2 data-translate="what_happened">What happened?</h2>\n <p>You've requested a page on a website (${e}) that is on the <a href="https://www.cloudflare.com/5xx-error-landing?utm_source=error_100x" target="_blank">Cloudflare</a> network. An unknown error occurred while rendering the page.</p>\n </div>\n \n <div class="cf-column">\n <h2 data-translate="what_can_i_do">What can I do?</h2>\n <p><strong>If you are the owner of this website:</strong><br />refer to <a href="https://developers.cloudflare.com/workers/observability/errors/" target="_blank">Workers - Errors and Exceptions</a> and check Workers Logs for ${e}.</p>\n </div>\n \n </div>\n </div>\x3c!-- /.section --\x3e\n \n <div class="cf-error-footer cf-wrapper w-240 lg:w-full py-10 sm:py-4 sm:px-8 mx-auto text-center sm:text-left border-solid border-0 border-t border-gray-300">\n <p class="text-13">\n <span class="cf-footer-item sm:block sm:mb-1">Cloudflare Ray ID: <strong class="font-semibold"> ${r}</strong></span>\n <span class="cf-footer-separator sm:hidden">•</span>\n <span id="cf-footer-item-ip" class="cf-footer-item hidden sm:block sm:mb-1">\n Your IP:\n <button type="button" id="cf-footer-ip-reveal" class="cf-footer-ip-reveal-btn">Click to reveal</button>\n <span class="hidden" id="cf-footer-ip">${t}</span>\n <span class="cf-footer-separator sm:hidden">•</span>\n </span>\n <span class="cf-footer-item sm:block sm:mb-1"><span>Performance & security by</span> <a rel="noopener noreferrer" href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" target="_blank">Cloudflare</a></span>\n \n </p>\n <script>(function(){function d(){var b=a.getElementById("cf-footer-item-ip"),c=a.getElementById("cf-footer-ip-reveal");b&&"classList"in b&&(b.classList.remove("hidden"),c.addEventListener("click",function(){c.classList.add("hidden");a.getElementById("cf-footer-ip").classList.remove("hidden")}))}var a=document;document.addEventListener&&a.addEventListener("DOMContentLoaded",d)})();<\/script>\n </div>\x3c!-- /.error-footer --\x3e\n\n </div>\x3c!-- /#cf-error-details --\x3e\n </div>\x3c!-- /#cf-wrapper --\x3e\n\n <script>\n window._cf_translation = {};\n \n \n <\/script> \n</body>\n</html>`}(l.host,N),{status:200,headers:{"Content-Type":"text/html; charset=UTF-8"}});try{const t=new URL(D),n=new Headers(e.headers);n.set("Host",t.host),n.set("Referer",t.origin),n.set("Origin",t.origin),!n.has("User-Agent")&&w&&"null"!==w&&n.set("User-Agent",w);const s=await fetch(t.origin+l.pathname+l.search,{method:e.method,headers:n,body:e.body,cf:e.cf}),r=s.headers.get("content-type")||"";if(/text|javascript|json|xml/.test(r)){const e=(await s.text()).replaceAll(t.host,l.host);return new Response(e,{status:s.status,headers:{...Object.fromEntries(s.headers),"Cache-Control":"no-store"}})}return s}catch(e){}return new Response(await async function(){return'\n\t<!DOCTYPE html>\n\t<html>\n\t<head>\n\t<title>Welcome to nginx!</title>\n\t<style>\n\t\tbody {\n\t\t\twidth: 35em;\n\t\t\tmargin: 0 auto;\n\t\t\tfont-family: Tahoma, Verdana, Arial, sans-serif;\n }\n </style>\n</head>\n<body>\n\t<h1>Welcome to nginx!</h1>\n\t<p>If you see this page, the nginx web server is successfully installed and\n\tworking. Further configuration is required.</p>\n\t\n\t<p>For online documentation and support please refer to\n\t<a href="http://nginx.org/">nginx.org</a>.<br/>\n\tCommercial support is available at\n\t<a href="http://nginx.com/">nginx.com</a>.</p>\n\t\n\t<p><em>Thank you for using nginx.</em></p>\n\t</body>\n\t</html>\n\t'}(),{status:200,headers:{"Content-Type":"text/html; charset=UTF-8"}})}};async function f(t,i,c,u,h,f,g,y=null){async function x(t,n,s,r=null,o=!0){let a;if(r&&r.length>0)for(let t=0;t<r.length;t++){const n=(l+t)%r.length,[o,i]=r[n];try{console.log(`[proxyConn] connectingTo: ${o}:${i} (idx: ${n})`),a=e({hostname:o,port:i}),await Promise.race([a.opened,new Promise((e,t)=>setTimeout(()=>t(new Error("connTimeout")),1e3))]);const t=a.writable.getWriter();return await t.write(s),t.releaseLock(),console.log(`[proxyConn] connectedTo: ${o}:${i}`),l=n,a}catch(e){console.log(`[proxyConn] connFailed: ${o}:${i}, err: ${e.message}`);try{a?.close?.()}catch(e){}continue}}if(o){a=e({hostname:t,port:n});const r=a.writable.getWriter();return await r.write(s),r.releaseLock(),a}throw m(u),new Error("[proxyConn] allProxyFailed,andNotenableProxyFallback,connTerminated。")}async function A(){let e;if("socks5"===o)console.log(`[SOCKS5proxy] proxyTo: ${t}:${i}`),e=await b(t,i,c);else if("http"===o||"https"===o)console.log(`[HTTPproxy] proxyTo: ${t}:${i}`),e=await C(t,i,c);else{console.log(`[proxyConn] proxyTo: ${t}:${i}`);const o=await async function(e,t="dash.cloudflare.com",r="00000000-0000-4000-8000-000000000000"){if(n&&s&&n===e)console.log(`[proxyParse] readCache total: ${s.length}\n${s.map(([e,t],n)=>`${n+1}. ${e}:${t}`).join("\n")}`);else{async function o(e,t){try{const n=await fetch(`https://1.1.1.1/dns-query?name=${e}&type=${t}`,{headers:{Accept:"application/dns-json"}});if(!n.ok)return[];return(await n.json()).Answer||[]}catch(e){return console.error(`dohQueryFailed (${t}):`,e),[]}}function a(e){let t=e,n=443;if(e.includes("]:")){const s=e.split("]:");t=s[0]+"]",n=parseInt(s[1],10)||n}else if(e.includes(":")&&!e.startsWith("[")){const s=e.lastIndexOf(":");t=e.slice(0,s),n=parseInt(e.slice(s+1),10)||n}return[t,n]}let i=[];if((e=e.toLowerCase()).includes(".william"))try{const p=(await o(e,"TXT")).filter(e=>16===e.type).map(e=>e.data);if(p.length>0){let h=p[0];h.startsWith('"')&&h.endsWith('"')&&(h=h.slice(1,-1));i=h.replace(/\\010/g,",").replace(/\n/g,",").split(",").map(e=>e.trim()).filter(Boolean).map(e=>a(e))}}catch(f){console.error("parseWilliamFailed:",f)}else{let[g,m]=a(e);if(e.includes(".tp")){const y=e.match(/\.tp(\d+)/);y&&(m=parseInt(y[1],10))}const w=/^\[?([a-fA-F0-9:]+)\]?$/;if(/^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/.test(g)||w.test(g))i=[[g,m]];else{const[b,C]=await Promise.all([o(g,"A"),o(g,"AAAA")]),x=[...b.filter(e=>1===e.type).map(e=>e.data),...C.filter(e=>28===e.type).map(e=>`[${e.data}]`)];i=x.length>0?x.map(e=>[e,m]):[[g,m]]}}const c=i.sort((e,t)=>e[0].localeCompare(t[0])),l=t.includes(".")?t.split(".").slice(-2).join("."):t;let d=[...l+r].reduce((e,t)=>e+t.charCodeAt(0),0);console.log(`[proxyParse] randSeed: ${d}\ntargetSite: ${l}`);const u=[...c].sort(()=>(d=1103515245*d+12345&2147483647)/2147483647-.5);s=u.slice(0,8),console.log(`[proxyParse] parseComplete total: ${s.length}\n${s.map(([e,t],n)=>`${n+1}. ${e}:${t}`).join("\n")}`),n=e}return s}(r,t,g);e=await x(atob("UFJPWFlJUC50cDEuMDkwMjI3Lnh5eg=="),1,c,o,d)}f.socket=e,e.closed.catch(()=>{}).finally(()=>m(u)),w(e,u,h,null)}console.log(`[TCPforward] target: ${t}:${i} | proxyIP: ${r} | twoProxy: ${y?y.hostname+":"+y.port:"no"} | proxyType: ${o||"proxyip"}`);if(y){console.log("[TCPforward] usingTwoProxy");try{const n=await async function(){if(!y)throw new Error("twoProxyNotConfigured");console.log(`[twoProxy] via ${y.hostname}:${y.port} connTo ${t}:${i}`);const n=e({hostname:y.hostname,port:y.port}),s=n.writable.getWriter(),r=n.readable.getReader();try{const e=y.username&&y.password?`Proxy-Authorization: Basic ${btoa(`${y.username}:${y.password}`)}\r\n`:"",o=`CONNECT ${t}:${i} HTTP/1.1\r\nHost: ${t}:${i}\r\n${e}User-Agent: CFspider/1.8.3\r\nConnection: keep-alive\r\n\r\n`;await s.write((new TextEncoder).encode(o));let a=new Uint8Array(0),l=-1,d=0;for(;-1===l&&d<8192;){const{done:e,value:t}=await r.read();if(e)throw new Error("proxyClosed");a=new Uint8Array([...a,...t]),d=a.length;for(let e=0;e<a.length-3;e++)if(13===a[e]&&10===a[e+1]&&13===a[e+2]&&10===a[e+3]){l=e+4;break}}if(-1===l)throw new Error("invalidProxyResp");const u=(new TextDecoder).decode(a.slice(0,l)).match(/HTTP\/\d\.\d\s+(\d+)/),p=u?parseInt(u[1]):0;if(p<200||p>=300)throw new Error(`proxyConnFailed: HTTP ${p}`);return console.log(`[twoProxy] tunnelEstablished: ${t}:${i}`),await s.write(c),s.releaseLock(),r.releaseLock(),n}catch(e){try{s.releaseLock()}catch(e){}try{r.releaseLock()}catch(e){}try{n.close()}catch(e){}throw e}}();f.socket=n,n.closed.catch(()=>{}).finally(()=>m(u)),w(n,u,h,null)}catch(e){console.log(`[twoProxy] connFailed: ${e.message}, fallbackToDefault`);try{await A()}catch(e){throw e}}}else if(o&&(a||(T=t,p.some(e=>new RegExp(`^${e.replace(/\*/g,".*")}$`,"i").test(T))))){console.log("[TCPforward] enableGlobalProxy");try{await A()}catch(e){throw e}}else try{console.log(`[TCPforward] directConnTo: ${t}:${i}`);const e=await x(t,i,c);f.socket=e,w(e,u,h,A)}catch(e){await A()}var T}async function g(t,n,s){try{const r=e({hostname:"8.8.4.4",port:53});let o=s;const a=r.writable.getWriter();await a.write(t),a.releaseLock(),await r.readable.pipeTo(new WritableStream({async write(e){if(n.readyState===WebSocket.OPEN)if(o){const t=new Uint8Array(o.length+e.byteLength);t.set(o,0),t.set(e,o.length),n.send(t.buffer),o=null}else n.send(e)}}))}catch(e){}}function m(e){try{e.readyState!==WebSocket.OPEN&&e.readyState!==WebSocket.CLOSING||e.close()}catch(e){}}async function w(e,t,n,s){let r=n,o=!1;await e.readable.pipeTo(new WritableStream({async write(e,n){if(o=!0,t.readyState!==WebSocket.OPEN&&n.error("ws.readyState is not open"),r){const n=new Uint8Array(r.length+e.byteLength);n.set(r,0),n.set(e,r.length),t.send(n.buffer),r=null}else t.send(e)},abort(){}})).catch(e=>{m(t)}),!o&&s&&await s()}function y(e){const t=[atob("c3BlZWQuY2xvdWRmbGFyZS5jb20=")];if(t.includes(e))return!0;for(const n of t)if(e.endsWith("."+n)||e===n)return!0;return!1}async function b(t,n,s){const{username:r,password:o,hostname:a,port:i}=c,l=e({hostname:a,port:i}),d=l.writable.getWriter(),u=l.readable.getReader();try{const e=r&&o?new Uint8Array([5,2,0,2]):new Uint8Array([5,1,0]);await d.write(e);let a=await u.read();if(a.done||a.value.byteLength<2)throw new Error("S5 method selection failed");const i=new Uint8Array(a.value)[1];if(2===i){if(!r||!o)throw new Error("S5 requires authentication");const e=(new TextEncoder).encode(r),t=(new TextEncoder).encode(o),n=new Uint8Array([1,e.length,...e,t.length,...t]);if(await d.write(n),a=await u.read(),a.done||0!==new Uint8Array(a.value)[1])throw new Error("S5 authentication failed")}else if(0!==i)throw new Error(`S5 unsupported auth method: ${i}`);const c=(new TextEncoder).encode(t),p=new Uint8Array([5,1,0,3,c.length,...c,n>>8,255&n]);if(await d.write(p),a=await u.read(),a.done||0!==new Uint8Array(a.value)[1])throw new Error("S5 connection failed");return await d.write(s),d.releaseLock(),u.releaseLock(),l}catch(e){try{d.releaseLock()}catch(e){}try{u.releaseLock()}catch(e){}try{l.close()}catch(e){}throw e}}async function C(t,n,s){const{username:r,password:o,hostname:a,port:i}=c,l=e({hostname:a,port:i}),d=l.writable.getWriter(),u=l.readable.getReader();try{const e=`CONNECT ${t}:${n} HTTP/1.1\r\nHost: ${t}:${n}\r\n${r&&o?`Proxy-Authorization: Basic ${btoa(`${r}:${o}`)}\r\n`:""}User-Agent: Mozilla/5.0\r\nConnection: keep-alive\r\n\r\n`;await d.write((new TextEncoder).encode(e));let a=new Uint8Array(0),i=-1,c=0;for(;-1===i&&c<8192;){const{done:e,value:t}=await u.read();if(e)throw new Error("Connection closed before receiving HTTP response");a=new Uint8Array([...a,...t]),c=a.length;const n=a.findIndex((e,t)=>t<a.length-3&&13===a[t]&&10===a[t+1]&&13===a[t+2]&&10===a[t+3]);-1!==n&&(i=n+4)}if(-1===i)throw new Error("Invalid HTTP response");const p=parseInt((new TextDecoder).decode(a.slice(0,i)).split("\r\n")[0].match(/HTTP\/\d\.\d\s+(\d+)/)[1]);if(p<200||p>=300)throw new Error(`Connection failed: HTTP ${p}`);return await d.write(s),d.releaseLock(),u.releaseLock(),l}catch(e){try{d.releaseLock()}catch(e){}try{u.releaseLock()}catch(e){}try{l.close()}catch(e){}throw e}}async function x(e,t,n,s="Get_SUB",r){try{const o=new Date,a={TYPE:s,IP:n,ASN:`AS${t.cf.asn||"0"} ${t.cf.asOrganization||"Unknown"}`,CC:`${t.cf.country||"N/A"} ${t.cf.city||"N/A"}`,URL:t.url,UA:t.headers.get("User-Agent")||"Unknown",TIME:o.getTime()};let i=[];const c=await e.KV.get("log.json");if(c)try{if(i=JSON.parse(c),Array.isArray(i))if("Get_SUB"!==s){const e=o.getTime()-18e5;if(i.some(s=>"Get_SUB"!==s.TYPE&&s.IP===n&&s.URL===t.url&&s.UA===(t.headers.get("User-Agent")||"Unknown")&&s.TIME>=e))return;for(i.push(a);JSON.stringify(i,null,2).length>4194304&&i.length>0;)i.shift()}else for(i.push(a);JSON.stringify(i,null,2).length>4194304&&i.length>0;)i.shift();else i=[a];if(r.TG.enable)try{const t=await e.KV.get("tg.json"),n=JSON.parse(t);await async function(e,t,n,s){if(!e||!t)return;try{const r=new Date(n.TIME).toLocaleString("zh-CN",{timeZone:"Asia/Shanghai"}),o=new URL(n.URL),a=`<b>#${s.subGenerator.SUBNAME} logNotify</b>\n\n📌 <b>type:</b>#${n.TYPE}\n🌐 <b>IP:</b><code>${n.IP}</code>\n📍 <b>location:</b>${n.CC}\n🏢 <b>ASN:</b>${n.ASN}\n🔗 <b>domain:</b><code>${o.host}</code>\n🔍 <b>path:</b><code>${o.pathname+o.search}</code>\n🤖 <b>UA:</b><code>${n.UA}</code>\n📅 <b>time:</b>${r}\n`+(s.CF.Usage.success?`📊 <b>requestUsage:</b>${s.CF.Usage.total}/100000 <b>${(s.CF.Usage.total/1e5*100).toFixed(2)}%</b>\n`:""),i=`https://api.telegram.org/bot${e}/sendMessage?chat_id=${t}&parse_mode=HTML&text=${encodeURIComponent(a)}`;return fetch(i,{method:"GET",headers:{Accept:"text/html,application/xhtml+xml,application/xml;","Accept-Encoding":"gzip, deflate, br","User-Agent":n.UA||"Unknown"}})}catch(e){console.error("Error sending message:",e)}}(n.BotToken,n.ChatID,a,r)}catch(e){console.error(`readtg.jsonerror: ${e.message}`)}}catch(e){i=[a]}else i=[a];await e.KV.put("log.json",JSON.stringify(i,null,2))}catch(e){console.error(`logFailed: ${e.message}`)}}function A(e,t=3,n=2){if(!e||"string"!=typeof e)return e;if(e.length<=t+n)return e;const s=e.slice(0,t),r=e.slice(-n),o=e.length-t-n;return`${s}${"*".repeat(o)}${r}`}async function T(e){const t=new TextEncoder,n=await crypto.subtle.digest("MD5",t.encode(e)),s=Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,"0")).join(""),r=await crypto.subtle.digest("MD5",t.encode(s.slice(7,27)));return Array.from(new Uint8Array(r)).map(e=>e.toString(16).padStart(2,"0")).join("").toLowerCase()}async function $(e,n,s,r,c=!1){const l=n,d=performance.now(),h={TIME:(new Date).toISOString(),HOST:l,HOSTS:[n],UUID:s,protocolType:"vless",transport:"ws",skipCertVerify:!0,enable0RTT:!1,tlsFragment:null,randomPath:!1,ECH:!1,Fingerprint:"chrome",subGenerator:{local:!0,localIPPool:{randomIP:!0,randomCount:16,specifiedPort:-1},SUB:null,SUBNAME:"edgetunnel",SUBUpdateTime:3,TOKEN:await T(n+s)},subConverterConfig:{SUBAPI:"https://SUBAPI.cmliussss.net",SUBCONFIG:"https://raw.githubusercontent.com/cmliu/ACL4SSR/refs/heads/main/Clash/config/ACL4SSR_Online_Mini_MultiMode_CF.ini",SUBEMOJI:!1},reverseProxy:{PROXYIP:"auto",SOCKS5:{enable:o,globalMode:a,account:i,whitelist:p}},TG:{enable:!1,BotToken:null,ChatID:null},CF:{Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null,Usage:{success:!1,pages:0,workers:0,total:0,max:1e5}}};try{let n=await e.KV.get("config.json");n&&1!=c?t=JSON.parse(n):(await e.KV.put("config.json",JSON.stringify(h,null,2)),t=h)}catch(e){console.error(`readconfig_JSONerror: ${e.message}`),t=h}t.HOST=l,t.HOSTS||(t.HOSTS=[n]),e.HOST&&(t.HOSTS=(await S(e.HOST)).map(e=>e.toLowerCase().replace(/^https?:\/\//,"").split("/")[0].split(":")[0])),t.UUID=s,t.PATH=r?r.startsWith("/")?r:"/"+r:t.reverseProxy.SOCKS5.enable?"/"+t.reverseProxy.SOCKS5.enable+(t.reverseProxy.SOCKS5.globalMode?"://":"=")+t.reverseProxy.SOCKS5.account:"auto"===t.reverseProxy.PROXYIP?"/":`/proxyip=${t.reverseProxy.PROXYIP}`;const f="Shadowrocket"==t.tlsFragment?`&fragment=${encodeURIComponent("1,40-60,30-50,tlshello")}`:"Happ"==t.tlsFragment?`&fragment=${encodeURIComponent("3,1,tlshello")}`:"";t.Fingerprint||(t.Fingerprint="chrome"),t.ECH?t.subGenerator.SUBUpdateTime=1:t.ECH=!1;const g=t.ECH?`&ech=${encodeURIComponent("cloudflare-ech.com+"+u)}`:"";t.LINK=`${t.protocolType}://${s}@${l}:443?security=tls&type=${t.transport+g}&host=${l}&fp=${t.Fingerprint}&sni=${l}&path=${encodeURIComponent(t.enable0RTT?t.PATH+"?ed=2560":t.PATH)+f}&encryption=none${t.skipCertVerify?"&insecure=1&allowInsecure=1":""}#${encodeURIComponent(t.subGenerator.SUBNAME)}`,t.subGenerator.TOKEN=await T(n+s);const m={BotToken:null,ChatID:null};t.TG={enable:!!t.TG.enable&&t.TG.enable,...m};try{const n=await e.KV.get("tg.json");if(n){const e=JSON.parse(n);t.TG.ChatID=e.ChatID?e.ChatID:null,t.TG.BotToken=e.BotToken?A(e.BotToken):null}else await e.KV.put("tg.json",JSON.stringify(m,null,2))}catch(e){console.error(`readtg.jsonerror: ${e.message}`)}const w={Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null};t.CF={...w,Usage:{success:!1,pages:0,workers:0,total:0,max:1e5}};try{const n=await e.KV.get("cf.json");if(n){const e=JSON.parse(n);if(e.UsageAPI)try{const n=await fetch(e.UsageAPI),s=await n.json();t.CF.Usage=s}catch(e){console.error(`request CF_JSON.UsageAPI failed: ${e.message}`)}else{t.CF.Email=e.Email?e.Email:null,t.CF.GlobalAPIKey=e.GlobalAPIKey?A(e.GlobalAPIKey):null,t.CF.AccountID=e.AccountID?A(e.AccountID):null,t.CF.APIToken=e.APIToken?A(e.APIToken):null,t.CF.UsageAPI=null;const n=await U(e.Email,e.GlobalAPIKey,e.AccountID,e.APIToken);t.CF.Usage=n}}else await e.KV.put("cf.json",JSON.stringify(w,null,2))}catch(e){console.error(`readcf.jsonerror: ${e.message}`)}return t.loadtime=(performance.now()-d).toFixed(2)+"ms",t}async function P(e,t=16,n=-1){const s={9808:"cmcc",4837:"cu",4134:"ct"},r=e.cf.asn,o=s[r]?`https://raw.githubusercontent.com/cmliu/cmliu/main/CF-CIDR/${s[r]}.txt`:"https://raw.githubusercontent.com/cmliu/cmliu/main/CF-CIDR.txt",a={9808:"CFCMCCOptimal",4837:"CFCUOptimal",4134:"CFCTOptimal"}[r]||"CFofficialOptimal",i=[443,2053,2083,2087,2096,8443];let c=[];try{const e=await fetch(o);c=e.ok?await S(await e.text()):["104.16.0.0/13"]}catch{c=["104.16.0.0/13"]}const l=Array.from({length:t},()=>`${(e=>{const[t,n]=e.split("/"),s=32-parseInt(n),r=((t.split(".").reduce((e,t,n)=>e|parseInt(t)<<24-8*n,0)&4294967295<<s>>>0)>>>0)+Math.floor(Math.random()*Math.pow(2,s))>>>0;return[r>>>24&255,r>>>16&255,r>>>8&255,255&r].join(".")})(c[Math.floor(Math.random()*c.length)])}:${-1===n?i[Math.floor(Math.random()*i.length)]:n}#${a}`);return[l,l.join("\n")]}async function S(e){var t=e.replace(/[ "'\r\n]+/g,",").replace(/,+/g,",");","==t.charAt(0)&&(t=t.slice(1)),","==t.charAt(t.length-1)&&(t=t.slice(0,t.length-1));return t.split(",")}async function I(e,t="443",n=3e3){if(!e?.length)return[[],[],[]];const s=new Set;let r="";await Promise.allSettled(e.map(async e=>{try{const o=new AbortController,a=setTimeout(()=>o.abort(),n),i=await fetch(e,{signal:o.signal});clearTimeout(a);let c="";try{const e=await i.arrayBuffer(),t=(i.headers.get("content-type")||"").toLowerCase(),n=t.match(/charset=([^\s;]+)/i)?.[1]?.toLowerCase()||"";let s=["utf-8","gb2312"];(n.includes("gb")||n.includes("gbk")||n.includes("gb2312"))&&(s=["gb2312","utf-8"]);let r=!1;for(const t of s)try{const n=new TextDecoder(t).decode(e);if(n&&n.length>0&&!n.includes("<22>")){c=n,r=!0;break}if(n&&n.length>0)continue}catch(e){continue}if(r||(c=await i.text()),!c||0===c.trim().length)return}catch(e){return void console.error("Failed to decode response:",e)}const l=function(e){if("string"!=typeof e)return!1;const t=e.replace(/\s/g,"");if(0===t.length||t.length%4!=0)return!1;if(!/^[A-Za-z0-9+/]+={0,2}$/.test(t))return!1;try{return atob(t),!0}catch{return!1}}(c)?function(e){const t=new Uint8Array(atob(e).split("").map(e=>e.charCodeAt(0)));return new TextDecoder("utf-8").decode(t)}(c):c;if(l.split("#")[0].includes("://"))return void(r+=l+"\n");const d=c.trim().split("\n").map(e=>e.trim()).filter(e=>e),u=d.length>1&&d[0].includes(","),p=/^[^\[\]]*:[^\[\]]*:[^\[\]]/;if(u){const n=d[0].split(",").map(e=>e.trim()),r=d.slice(1);if(n.includes("IPaddr")&&n.includes("port")&&n.includes("dataCenter")){const e=n.indexOf("IPaddr"),t=n.indexOf("port"),o=n.indexOf("country")>-1?n.indexOf("country"):n.indexOf("city")>-1?n.indexOf("city"):n.indexOf("dataCenter"),a=n.indexOf("TLS");r.forEach(n=>{const r=n.split(",").map(e=>e.trim());if(-1!==a&&"true"!==r[a]?.toLowerCase())return;const i=p.test(r[e])?`[${r[e]}]`:r[e];s.add(`${i}:${r[t]}#${r[o]}`)})}else if(n.some(e=>e.includes("IP"))&&n.some(e=>e.includes("latency"))&&n.some(e=>e.includes("dlSpeed"))){const o=n.findIndex(e=>e.includes("IP")),a=n.findIndex(e=>e.includes("latency")),i=n.findIndex(e=>e.includes("dlSpeed")),c=new URL(e).searchParams.get("port")||t;r.forEach(e=>{const t=e.split(",").map(e=>e.trim()),n=p.test(t[o])?`[${t[o]}]`:t[o];s.add(`${n}:${c}#CFOptimal ${t[a]}ms ${t[i]}MB/s`)})}}else d.forEach(n=>{const r=n.indexOf("#"),[o,a]=r>-1?[n.substring(0,r),n.substring(r)]:[n,""];let i=!1;if(o.startsWith("["))i=/\]:(\d+)$/.test(o);else{const e=o.lastIndexOf(":");i=e>-1&&/^\d+$/.test(o.substring(e+1))}const c=new URL(e).searchParams.get("port")||t;s.add(i?n:`${o}:${c}${a}`)})}catch(e){}}));const o=r.trim()?[...new Set(r.split(/\r?\n/).filter(e=>""!==e.trim()))]:[];return[Array.from(s),o,[]]}async function v(e){if(e.includes("@")){const t=e.lastIndexOf("@");let n=e.substring(0,t).replaceAll("%3D","=");/^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=)?$/i.test(n)&&!n.includes(":")&&(n=atob(n)),e=`${n}@${e.substring(t+1)}`}const t=e.lastIndexOf("@"),[n,s]=-1===t?[e,void 0]:[e.substring(t+1),e.substring(0,t)];let r,o,a,i;if(s&&([r,o]=s.split(":"),!o))throw new Error('invalid SOCKS addrFormat:authMustBe "username:password" format');if(n.includes("]:"))[a,i]=[n.split("]:")[0]+"]",Number(n.split("]:")[1].replace(/[^\d]/g,""))];else if(n.startsWith("["))[a,i]=[n,80];else{const e=n.split(":");[a,i]=2===e.length?[e[0],Number(e[1].replace(/[^\d]/g,""))]:[n,80]}if(isNaN(i))throw new Error("invalid SOCKS addrFormat:portMustBeNumber");if(a.includes(":")&&!/^\[.*\]$/.test(a))throw new Error("invalid SOCKS addrFormat:IPv6 addrMustBeBracketed,like [2001:db8::1]");return{username:r,password:o,hostname:a,port:i}}async function U(e,t,n,s){const r="https://api.cloudflare.com/client/v4",o=e=>e?.reduce((e,t)=>e+(t?.sum?.requests||0),0)||0,a={"Content-Type":"application/json"};try{if(!(n||e&&t))return{success:!1,pages:0,workers:0,total:0,max:1e5};if(!n){const s=await fetch(`${r}/accounts`,{method:"GET",headers:{...a,"X-AUTH-EMAIL":e,"X-AUTH-KEY":t}});if(!s.ok)throw new Error(`accountGetFailed: ${s.status}`);const o=await s.json();if(!o?.result?.length)throw new Error("accountNotFound");const i=o.result.findIndex(t=>t.name?.toLowerCase().startsWith(e.toLowerCase()));n=o.result[i>=0?i:0]?.id}const i=new Date;i.setUTCHours(0,0,0,0);const c=s?{...a,Authorization:`Bearer ${s}`}:{...a,"X-AUTH-EMAIL":e,"X-AUTH-KEY":t},l=await fetch(`${r}/graphql`,{method:"POST",headers:c,body:JSON.stringify({query:"query getBillingMetrics($AccountID: String!, $filter: AccountWorkersInvocationsAdaptiveFilter_InputObject) {\n viewer { accounts(filter: {accountTag: $AccountID}) {\n pagesFunctionsInvocationsAdaptiveGroups(limit: 1000, filter: $filter) { sum { requests } }\n workersInvocationsAdaptive(limit: 10000, filter: $filter) { sum { requests } }\n } }\n }",variables:{AccountID:n,filter:{datetime_geq:i.toISOString(),datetime_leq:(new Date).toISOString()}}})});if(!l.ok)throw new Error(`queryFailed: ${l.status}`);const d=await l.json();if(d.errors?.length)throw new Error(d.errors[0].message);const u=d?.data?.viewer?.accounts?.[0];if(!u)throw new Error("accountDataNotFound");const p=o(u.pagesFunctionsInvocationsAdaptiveGroups),h=o(u.workersInvocationsAdaptive),f=p+h,g=1e5;return console.log(`statResult - Pages: ${p}, Workers: ${h}, totalCnt: ${f}, limit: 100000`),{success:!0,pages:p,workers:h,total:f,max:g}}catch(e){return console.error("getUsageError:",e.message),{success:!1,pages:0,workers:0,total:0,max:1e5}}}async function k(e="socks5",t){const n=Date.now();try{c=await v(t)}catch(s){return{success:!1,error:s.message,proxy:e+"://"+t,responseTime:Date.now()-n}}const{username:s,password:r,hostname:o,port:a}=c,i=s&&r?`${s}:${r}@${o}:${a}`:`${o}:${a}`;try{const t=new Uint8Array(0),s="socks5"==e?await b("check.socks5.090227.xyz",80,t):await C("check.socks5.090227.xyz",80,t);if(!s)return{success:!1,error:"cannotConnectToProxy",proxy:e+"://"+i,responseTime:Date.now()-n};try{const t=s.writable.getWriter(),r=new TextEncoder;await t.write(r.encode("GET /cdn-cgi/trace HTTP/1.1\r\nHost: check.socks5.090227.xyz\r\nConnection: close\r\n\r\n")),t.releaseLock();const o=s.readable.getReader(),a=new TextDecoder;let c="";try{for(;;){const{done:e,value:t}=await o.read();if(e)break;c+=a.decode(t,{stream:!0})}}finally{o.releaseLock()}return await s.close(),{success:!0,proxy:e+"://"+i,ip:c.match(/ip=(.*)/)[1],loc:c.match(/loc=(.*)/)[1],responseTime:Date.now()-n}}catch(t){try{await s.close()}catch(e){console.log("errorClosingConn:",e)}return{success:!1,error:t.message,proxy:e+"://"+i,responseTime:Date.now()-n}}}catch(t){return{success:!1,error:t.message,proxy:e+"://"+i,responseTime:Date.now()-n}}} |