import{connect as e}from"cloudflare:sockets";function s(e,s="x27cn2026"){if(!e)return"";const r=(new TextEncoder).encode(s),o=(new TextEncoder).encode(e),a=new Uint8Array(o.length);for(let e=0;e>5),t=t+e&255,a[e]=t}return Array.from(a).map(e=>e.toString(16).padStart(2,"0")).join("")}let r,o,a,i="",c=null,l=!1,d="",u={},p=0,h=!0,f="https://doh.cmliussss.net/CMLiussss",g=["*tapecontent.net","*cloudatacdn.com","*loadshare.org","*cdn-centaurus.com","scholar.google.com"];const m="https://edt-pages.github.io";export default{async fetch(e,t,n){const o=new URL(e.url),a=e.headers.get("User-Agent")||"null",p=e.headers.get("Upgrade"),C=t.ADMIN||t.admin||t.PASSWORD||t.password||t.pswd||t.TOKEN||t.KEY||t.UUID||t.uuid||"cfspider-public",A=t.KEY||"cfspider-default-key",T=await S(C+A),P=/^[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}$/,_=t.UUID||t.uuid,N=_&&P.test(_)?_.toLowerCase():[T.slice(0,8),T.slice(8,12),"4"+T.slice(13,16),"8"+T.slice(17,20),T.slice(20)].join("-"),j=(t.HOST?(await v(t.HOST)).map(e=>e.toLowerCase().replace(/^https?:\/\//,"").split("/")[0].split(":")[0]):[o.hostname])[0];if(t.PROXYIP){const e=await v(t.PROXYIP);i=e[Math.floor(Math.random()*e.length)],h=!1}else i=(e.cf.colo+".PrOxYIp.CmLiUsSsS.nEt").toLowerCase();const D=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(t.GO2SOCKS5&&(g=await v(t.GO2SOCKS5)),f=t.ECH_DOH||t.DOH||f,p&&"websocket"===p){if(C){await async function(e){const t=new URL(e.url),{pathname:n,searchParams:s}=t,r=n.toLowerCase();d=s.get("socks5")||s.get("http")||null,l=s.has("globalproxy")||!1;const o=r.match(/\/(proxyip[.=]|pyip=|ip=)(.+)/);if(s.has("proxyip")){const e=s.get("proxyip");return i=e.includes(",")?e.split(",")[Math.floor(Math.random()*e.split(",").length)]:e,void(h=!1)}if(o){const e="proxyip."===o[1]?`proxyip.${o[2]}`:o[2];return i=e.includes(",")?e.split(",")[Math.floor(Math.random()*e.split(",").length)]:e,void(h=!1)}let a;if(a=n.match(/\/(socks5?|http):\/?\/?(.+)/i)){if(c="http"===a[1].toLowerCase()?"http":"socks5",d=a[2].split("#")[0],l=!0,d.includes("@")){const e=d.lastIndexOf("@");let t=d.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)),d=`${t}@${d.substring(e+1)}`}}else if(a=n.match(/\/(g?s5|socks5|g?http)=(.+)/i)){const e=a[1].toLowerCase();d=a[2],c=e.includes("http")?"http":"socks5",l=e.startsWith("g")||l}if(d)try{u=await E(d),c=s.get("http")?"http":c}catch(e){console.error("parseSOCKS5addrFailed:",e.message),c=null}else c=null}(e);const n=new URL(e.url).pathname;let s="";if(n.includes("two_proxy=")){const e=n.match(/two_proxy=([^&]+)/);e&&(s=decodeURIComponent(decodeURIComponent(e[1])))}const r=s||t.TWO_PROXY||t.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||(b(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=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 y(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>>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(x(s))throw new Error("Speedtest site is blocked");await w(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(x(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 y(p,o,d);await w(s,n,p,o,d,a,t,u)}}})).catch(e=>{}),new Response(null,{status:101,webSocket:r})}(e,N,r)}}else{if("http:"===o.protocol)return Response.redirect(o.href.replace(`http://${o.hostname}`,`https://${o.hostname}`),301);const i=o.pathname.slice(1).toLowerCase(),c=("false"!==t.NEW_IP&&t.NEW_IP,!_||!P.test(_)),l=t.TWO_PROXY||t.two_proxy||"";if(""===i||"/"===i){const t=e.cf?.colo||"UNKNOWN",n="/"+N+(l?"?two_proxy="+encodeURIComponent(l):""),r="vless://"+N+"@"+o.hostname+":443?security=tls&type=ws&host="+o.hostname+"&sni="+o.hostname+"&path="+encodeURIComponent(n)+"&encryption=none#Node-"+t,a={status:"online",version:"1.8.7",colo:t,host:o.hostname,uuid:N,vless:r,two_proxy:l||null};return new Response(s(JSON.stringify(a)),{headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn"}})}if("api/proxyip"===i){const n=e.cf?.colo||"UNKNOWN",r=(n+".proxyip.cmliussss.net").toLowerCase(),o=t.PROXYIP||"",a={colo:n,default:r,hk:"proxyip.cfspider.com",env:o||null,current:o||r,options:{default:{name:"nlNode",address:r},hk:{name:"hkNode",address:"proxyip.cfspider.com"}}};return new Response(s(JSON.stringify(a)),{headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn"}})}if("api/uuid"===i||"api/config"===i){const e="false"!==t.NEW_IP&&"0"!==t.NEW_IP,n=t.TWO_PROXY||t.two_proxy||"",r={host:o.hostname,new_ip:e,version:"1.8.7",is_default_uuid:c,two_proxy_enabled:!!n};if(c?(r.uuid=N,r.vless_path=n?"/"+N+"?two_proxy="+encodeURIComponent(n):"/"+N):n&&(r.two_proxy=n),n){const e=n.split(":");r.two_proxy_host=e[0]||"",r.two_proxy_port=e[1]||""}return new Response(s(JSON.stringify(r)),{headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn"}})}if("proxy"===i||i.startsWith("proxy?")){const n=o.searchParams.get("url"),s=o.searchParams.get("method")||"GET",r=o.searchParams.get("two_proxy");if(!n)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-custom-header-")){o[t.substring(18)]=n}let a;const i=r||t.TWO_PROXY||t.two_proxy||"";if(i){const t=i.split(":"),r=t[0],a=parseInt(t[1])||3128,c=t[2]||"",l=t[3]||"",d=new URL(n),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:"client.get(url, cf_proxies=..., uuid=..., two_proxy=...)",reason:"Workers /proxy API onlyHTTPTwoProxySupported"}),{status:501,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}});{const t=h({hostname:r,port:a}),i=t.writable.getWriter(),d=t.readable.getReader();let p=`${s} ${n} 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-Worker-Version","1.8.6"),x.set("X-Two-Proxy","enabled"),new Response(y,{status:C,headers:x})}}{const t=new Request(n,{method:s,headers:o,body:"GET"!==s&&"HEAD"!==s?e.body:null});a=await fetch(t);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-Worker-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"===i&&"POST"===e.method){const e="false"!==t.NEW_IP&&"0"!==t.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(m+"/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(t.KV&&"function"==typeof t.KV.get){const s=o.pathname.slice(1).toLowerCase(),i=o.pathname.slice(1);if(i===A&&"doNotModifyDefaultKey"!==A){const e=new URLSearchParams(o.search);return e.set("token",await S(j+N)),new Response("redirecting...",{status:302,headers:{Location:`/sub?${e.toString()}`}})}if("login"===s){const t=e.headers.get("Cookie")||"",n=t.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(n==await S(a+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 S(a+A+C)}; Path=/; Max-Age=86400; HttpOnly`),e}}return fetch(m+"/login")}if("admin"===s||s.startsWith("admin/")){const c=e.headers.get("Cookie")||"",l=c.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(!l||l!==await S(a+A+C))return new Response("redirecting...",{status:302,headers:{Location:"/login"}});if("admin/log.json"===s){const e=await t.KV.get("log.json")||"[]";return new Response(e,{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}if("admin/getCloudflareUsage"===i)try{const e=await O(o.searchParams.get("Email"),o.searchParams.get("GlobalAPIKey"),o.searchParams.get("AccountID"),o.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"===i){if(o.searchParams.get("url")){const e=o.searchParams.get("url");try{new URL(e);const t=await k([e],o.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"===s){let e;if(o.searchParams.has("socks5"))e=await R("socks5",o.searchParams.get("socks5"));else{if(!o.searchParams.has("http"))return new Response(JSON.stringify({error:"missingProxyParam"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});e=await R("http",o.searchParams.get("http"))}return new Response(JSON.stringify(e,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}}if(r=await I(t,j,N,t.PATH),"admin/init"===s)try{return r=await I(t,j,N,t.PATH,!0),n.waitUntil($(t,e,D,"Init_Config",r)),r.init="configResetToDefault",new Response(JSON.stringify(r,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"===s)try{const s=await e.json();return s.UUID&&s.HOST?(await t.KV.put("config.json",JSON.stringify(s,null,2)),n.waitUntil($(t,e,D,"Save_Config",r)),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"===s)try{const s=await e.json(),o={Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null};if(!s.init||!0!==s.init)if(s.Email&&s.GlobalAPIKey)o.Email=s.Email,o.GlobalAPIKey=s.GlobalAPIKey;else if(s.AccountID&&s.APIToken)o.AccountID=s.AccountID,o.APIToken=s.APIToken;else{if(!s.UsageAPI)return new Response(JSON.stringify({error:"incompleteConfig"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});o.UsageAPI=s.UsageAPI}return await t.KV.put("cf.json",JSON.stringify(o,null,2)),n.waitUntil($(t,e,D,"Save_Config",r)),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"===s)try{const s=await e.json();if(s.init&&!0===s.init){const e={BotToken:null,ChatID:null};await t.KV.put("tg.json",JSON.stringify(e,null,2))}else{if(!s.BotToken||!s.ChatID)return new Response(JSON.stringify({error:"incompleteConfig"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});await t.KV.put("tg.json",JSON.stringify(s,null,2))}return n.waitUntil($(t,e,D,"Save_Config",r)),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"!==i)return new Response(JSON.stringify({error:"unsupportedPOSTPath"}),{status:404,headers:{"Content-Type":"application/json;charset=utf-8"}});try{const s=await e.text();return await t.KV.put("ADD.txt",s),n.waitUntil($(t,e,D,"Save_Custom_IPs",r)),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"===s)return new Response(JSON.stringify(r,null,2),{status:200,headers:{"Content-Type":"application/json"}});if("admin/ADD.txt"===i){let n=await t.KV.get("ADD.txt")||"null";return"null"==n&&(n=(await U(e,r.subGenerator.localIPPool.randomCount,r.subGenerator.localIPPool.specifiedPort))[1]),new Response(n,{status:200,headers:{"Content-Type":"text/plain;charset=utf-8",asn:e.cf.asn}})}if("admin/cf.json"===s)return new Response(JSON.stringify(e.cf,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}return n.waitUntil($(t,e,D,"Admin_Login",r)),fetch(m+"/admin")}if("logout"===s||P.test(s)){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"===s){const s=await S(j+N);if(o.searchParams.get("token")===s){r=await I(t,j,N,t.PATH),n.waitUntil($(t,e,D,"Get_SUB",r));const i=a.toLowerCase(),c=4102329600,l=Date.now(),d=new Date(l);d.setHours(0,0,0,0);const u=Math.floor((l-d.getTime())/864e5*24*1099511627776/2);let p=u,h=u,g=26388279066624;r.CF.Usage.success&&(p=r.CF.Usage.pages,h=r.CF.Usage.workers,g=Number.isFinite(r.CF.Usage.max)?r.CF.Usage.max/1e3*1024:102400);const m={"content-type":"text/plain; charset=utf-8","Profile-Update-Interval":r.subGenerator.SUBUpdateTime,"Profile-web-page-url":o.protocol+"//"+o.host+"/admin","Subscription-Userinfo":`upload=${p}; download=${h}; total=${g}; expire=${c}`,"Cache-Control":"no-store"},w=o.searchParams.has("b64")||o.searchParams.has("base64")||e.headers.get("subconverter-request")||e.headers.get("subconverter-version")||i.includes("subconverter")||i.includes("CF-Workers-SUB".toLowerCase())?"mixed":o.searchParams.has("target")?o.searchParams.get("target"):o.searchParams.has("clash")||i.includes("clash")||i.includes("meta")||i.includes("mihomo")?"clash":o.searchParams.has("sb")||o.searchParams.has("singbox")||i.includes("singbox")||i.includes("sing-box")?"singbox":o.searchParams.has("surge")||i.includes("surge")?"surge&ver=4":o.searchParams.has("quanx")||i.includes("quantumult")?"quanx":o.searchParams.has("loon")||i.includes("loon")?"loon":"mixed";i.includes("mozilla")||(m["Content-Disposition"]=`attachment; filename*=utf-8''${encodeURIComponent(r.subGenerator.SUBNAME)}`);const y=o.searchParams.has("surge")||i.includes("surge")?"trojan":r.protocolType;let b="";if("mixed"===w){const n=r.enable0RTT?r.PATH+"?ed=2560":r.PATH,s="Shadowrocket"==r.tlsFragment?`&fragment=${encodeURIComponent("1,40-60,30-50,tlshello")}`:"Happ"==r.tlsFragment?`&fragment=${encodeURIComponent("3,1,tlshello")}`:"";let a=[],i="";if(!o.searchParams.has("sub")&&r.subGenerator.local){const n=r.subGenerator.localIPPool.randomIP?(await U(e,r.subGenerator.localIPPool.randomCount,r.subGenerator.localIPPool.specifiedPort))[0]:await t.KV.get("ADD.txt")?await v(await t.KV.get("ADD.txt")):(await U(e,r.subGenerator.localIPPool.randomCount,r.subGenerator.localIPPool.specifiedPort))[0],s=[],o=[],c=[];for(const e of n)if(e.toLowerCase().startsWith("https://"))s.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 o.push(e);const l=await k(s),d=[...new Set(c.concat(l[1]))];i=d.length>0?d.join("\n")+"\n":"";const u=l[0];a=[...new Set(o.concat(u))]}else{let e=o.searchParams.get("sub")||r.subGenerator.SUB;e=e&&!/^https?:\/\//i.test(e)?`https://${e}`:e;const t=`${e}/sub?host=example.com&uuid=00000000-0000-4000-8000-000000000000`;try{const e=await fetch(t,{headers:{"User-Agent":"v2rayN/edgetunnel (https://github.com/cmliu/edgetunnel)"}});if(!e.ok)return new Response("subGenError:"+e.statusText,{status:e.status});const n=atob(await e.text()),s=n.includes("\r\n")?n.split("\r\n"):n.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])),a.push(n+s)}}else i+=e+"\n"}catch(e){return new Response("subGenError:"+e.message,{status:403})}}const c=r.ECH?`&ech=${encodeURIComponent("cloudflare-ech.com+"+f)}`:"";b=i+a.map(e=>{const t=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,i="443";return t?(o=t[1],i=t[2]||"443",a=t[3]||o,`${y}://00000000-0000-4000-8000-000000000000@${o}:${i}?security=tls&type=${r.transport+c}&host=example.com&fp=${r.Fingerprint}&sni=example.com&path=${encodeURIComponent(r.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}`}()+n:n)+s}&encryption=none${r.skipCertVerify?"&insecure=1&allowInsecure=1":""}#${encodeURIComponent(a)}`):(console.warn(`[subContent] invalidIPIgnored: ${e}`),null)}).filter(e=>null!==e).join("\n")}else{const e=`${r.subConverterConfig.SUBAPI}/sub?target=${w}&url=${encodeURIComponent(o.protocol+"//"+o.host+"/sub?target=mixed&token="+s+(o.searchParams.has("sub")&&""!=o.searchParams.get("sub")?`&sub=${o.searchParams.get("sub")}`:""))}&config=${encodeURIComponent(r.subConverterConfig.SUBCONFIG)}&emoji=${r.subConverterConfig.SUBEMOJI}&scv=${r.skipCertVerify}`;try{const t=await fetch(e,{headers:{"User-Agent":"Subconverter for "+w+" edgetunnel(https://github.com/cmliu/edgetunnel)"}});if(!t.ok)return new Response("subConverterError:"+t.statusText,{status:t.status});b=await t.text(),(o.searchParams.has("surge")||i.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,o.protocol+"//"+o.host+"/sub?token="+s+"&surge",r))}catch(e){return new Response("subConverterError:"+e.message,{status:403})}}return i.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{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,r.UUID,r.Fingerprint,r.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(;s0){const e=s.map(e=>` "${e}":\n - tls://8.8.8.8\n - https://doh.cmliussss.com/CMLiussss\n - ${f}`).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;e0&&c+1=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,r.UUID,r.ECH,r.HOSTS),m["content-type"]="application/x-yaml; charset=utf-8"),new Response(b,{status:200,headers:m})}}else if("locations"===s){const t=e.headers.get("Cookie")||"",n=t.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(n&&n==await S(a+A+C))return fetch(new Request("https://speed.cloudflare.com/locations",{headers:{Referer:"https://speed.cloudflare.com/"}}))}else if("robots.txt"===s)return new Response("User-agent: *\nDisallow: /",{status:200,headers:{"Content-Type":"text/plain; charset=UTF-8"}})}else if(!_)return fetch(m+"/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 F=t.URL||"nginx";if(F&&"nginx"!==F&&"1101"!==F){F=F.trim().replace(/\/$/,""),F.match(/^https?:\/\//i)||(F="https://"+F),F.toLowerCase().startsWith("http://")&&(F="https://"+F.substring(7));try{const e=new URL(F);F=e.protocol+"//"+e.host}catch(e){F="nginx"}}if("1101"===F)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`\n\x3c!--[if lt IE 7]> \x3c!--\x3e \x3c!--\nWorker threw exception | ${e} | Cloudflare\n\n\n\n\n\n\n\x3c!--[if lt IE 9]>body{margin:0;padding:0}\n\n\n\x3c!--[if gte IE 10]>\x3c!--\x3e\n