Files
CFspider/workers/破皮版workers.js
2026-01-25 17:32:19 +08:00

1 line
70 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{connect}from"cloudflare:sockets";function x27cnEncrypt(e,t="x27cn2026"){if(!e)return"";const n=(new TextEncoder).encode(t),s=new Uint8Array(256),r=new Uint8Array(256);for(let e=0;e<256;e++)s[e]=255&(n[e%n.length]^7*e+13&255),r[e]=167*e+89&255;const o=(new TextEncoder).encode(e),a=new Uint8Array(o.length);let i=0;for(const e of n)i^=e;for(let e=0;e<o.length;e++){let t=o[e];t^=s[e%256],t=r[t],t=255&(t<<5|t>>3),t=t+3*e+i&255,i=i+t+s[(e+128)%256]&255,a[e]=t}const c=Array.from(a).map(e=>e.toString(16).padStart(2,"0")).join("");let l="";for(let e=0;e<c.length;e+=4)l+="<"+c.substr(e,4)+">";return l}function generateAccessKey(e){const t="ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";let n="";for(let s=0;s<8;s++){n+=t[parseInt(e.substr(2*s,2),16)%55]}return n}const NGINX_PAGE='<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\nhtml { color-scheme: light dark; }\nbody { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>\n<p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/>\nCommercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p>\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>';let config_JSON,cacheproxyIP,cachedProxyArray,proxyIP="",enableSocks5Proxy=null,enableGlobalSocks5=!1,mySocks5Account="",parsedSocks5Address={},cachedProxyIndex=0,enableProxyFallback=!0,ECH_DOH="https://doh.cmliussss.net/CMLiussss",socks5Whitelist=["*tapecontent.net","*cloudatacdn.com","*loadshare.org","*cdn-centaurus.com","scholar.google.com"];const pagesStaticUrl="https://edt-pages.github.io";export default{async fetch(e,t,n){const s=new URL(e.url),r=e.headers.get("User-Agent")||"null",o=e.headers.get("Upgrade"),a=t.ADMIN||t.admin||t.PASSWORD||t.password||t.pswd||t.TOKEN||t.KEY||t.UUID||t.uuid||"cfspider-public",i=t.KEY||"cfspider-default-key",c=await MD5MD5(a+i),l=/^[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}$/,d=t.UUID||t.uuid,u=d&&l.test(d)?d.toLowerCase():[c.slice(0,8),c.slice(8,12),"4"+c.slice(13,16),"8"+c.slice(17,20),c.slice(20)].join("-"),p=t.CUSTOM_HOST||t.HOST||e.headers.get("X-Forwarded-Host")||e.headers.get("Host")||s.hostname,f=(t.HOST?(await parseToArray(t.HOST)).map(e=>e.toLowerCase().replace(/^https?:\/\//,"").split("/")[0].split(":")[0]):[s.hostname])[0];if(t.PROXYIP){const e=await parseToArray(t.PROXYIP);proxyIP=e[Math.floor(Math.random()*e.length)],enableProxyFallback=!1}else proxyIP=(e.cf.colo+".PrOxYIp.CmLiUsSsS.nEt").toLowerCase();const h=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&&(socks5Whitelist=await parseToArray(t.GO2SOCKS5)),ECH_DOH=t.ECH_DOH||t.DOH||ECH_DOH,o&&"websocket"===o){if(a){await reversedelegateparamsget(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 handleWebSocket(e,u,r)}}else{if("http:"===s.protocol)return Response.redirect(s.href.replace(`http://${s.hostname}`,`https://${s.hostname}`),301);const o=s.pathname.slice(1).toLowerCase(),g=("false"!==t.NEW_IP&&t.NEW_IP,!d||!l.test(d)),m=t.TWO_PROXY||t.two_proxy||"",y=t.ACCESSKEY||t.ACCESS_KEY||t.AKEY||generateAccessKey(c);if(""===o||"/"===o)return new Response(NGINX_PAGE,{status:200,headers:{"Content-Type":"text/html",Server:"nginx/1.18.0"}});if("x2727admin"===o){const e=x27cnEncrypt(`Your access key: ${y}\n\nFull URL:\n${`https://${p}/x2727admin/${y}`}\n\nEnvironment variables (optional):\n- ACCESSKEY: Custom access key\n- UUID: UUID parameter for cfspider\n- KEY: Custom encryption key\n- PROXYIP: Custom proxy IP`);return new Response(e,{headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn","X-Hint":"Decrypt with key: x27cn2026"}})}if(o.startsWith("x2727admin/")){const t=s.pathname.slice(1).substring(11);if(t!==y)return new Response(x27cnEncrypt("Invalid key. Please visit /x2727admin to get the correct key."),{status:403,headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn"}});const n=e.cf?.colo||"UNKNOWN",r="/"+u+(m?"?two_proxy="+encodeURIComponent(m):""),o={status:"online",version:"1.8.7",colo:n,host:p,uuid:u,vless:`vless://${u}@${p}:443?security=tls&type=ws&host=${p}&sni=${p}&path=${encodeURIComponent(r)}&encryption=none#Node-${n}`,two_proxy:m||null,proxyip:proxyIP},a=x27cnEncrypt(JSON.stringify(o),t);return new Response(a,{headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn","X-Key":t}})}if("status"===o){const t=e.cf?.colo||"UNKNOWN",n="/"+u+(m?"?two_proxy="+encodeURIComponent(m):""),r="vless://"+u+"@"+s.hostname+":443?security=tls&type=ws&host="+s.hostname+"&sni="+s.hostname+"&path="+encodeURIComponent(n)+"&encryption=none#CFspider-"+t;return new Response(JSON.stringify({status:"online",version:"1.8.7",colo:t,host:s.hostname,uuid:u,vless:r,two_proxy:m||null},null,2),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("api/proxyip"===o){const n=e.cf?.colo||"UNKNOWN",s=(n+".proxyip.cmliussss.net").toLowerCase(),r=t.PROXYIP||"";return new Response(JSON.stringify({colo:n,default:s,hk:"proxyip.cfspider.com",env:r||null,current:r||s,options:{default:{name:"Netherlands",address:s},hk:{name:"Hong Kong",address:"proxyip.cfspider.com"}}}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("api/uuid"===o||"api/config"===o){const e="false"!==t.NEW_IP&&"0"!==t.NEW_IP,n=t.TWO_PROXY||t.two_proxy||"",r={host:s.hostname,new_ip:e,version:"1.8.7",is_default_uuid:g,two_proxy_enabled:!!n};if(g?(r.uuid=u,r.vless_path=n?"/"+u+"?two_proxy="+encodeURIComponent(n):"/"+u):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(JSON.stringify(r),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("proxy"===o||o.startsWith("proxy?")){const n=s.searchParams.get("url"),r=s.searchParams.get("method")||"GET",o=s.searchParams.get("two_proxy");if(!n)return new Response(JSON.stringify({error:"Missing url parameter"}),{status:400,headers:{"Content-Type":"application/json"}});try{const s={};for(const[t,n]of e.headers)if(t.toLowerCase().startsWith("x-cfspider-header-")){s[t.substring(18)]=n}let a;const i=o||t.TWO_PROXY||t.two_proxy||"";if(i){const t=i.split(":"),o=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:f}=await import("cloudflare:sockets");if(p)return new Response(JSON.stringify({error:"HTTPS + two_proxy notSupportedvia /proxy API。pleaseUse Python cfspider.get() with two_proxy params。",hint:"cfspider.get(url, cf_proxies=..., uuid=..., two_proxy=...)",reason:"Workers /proxy API onlysupport HTTP twoProxy"}),{status:501,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}});{const t=f({hostname:o,port:a}),i=t.writable.getWriter(),d=t.readable.getReader();let p=`${r} ${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(s))p+=`${e}: ${t}\r\n`;p+="Connection: close\r\n\r\n",await i.write((new TextEncoder).encode(p));let h=new Uint8Array(0);for(;;){const{value:e,done:t}=await d.read();if(t)break;const n=new Uint8Array(h.length+e.length);n.set(h),n.set(e,h.length),h=n}const g=(new TextDecoder).decode(h),m=g.indexOf("\r\n\r\n"),y=g.substring(0,m),w=h.slice((new TextEncoder).encode(g.substring(0,m+4)).length),b=y.split("\r\n")[0],S=parseInt(b.split(" ")[1])||200,x=new Headers;return y.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(w,{status:S,headers:x})}}{const t=new Request(n,{method:r,headers:s,body:"GET"!==r&&"HEAD"!==r?e.body:null});a=await fetch(t);const o=new Headers(a.headers);return o.set("Access-Control-Allow-Origin","*"),o.set("X-CF-Colo",e.cf?.colo||"unknown"),o.set("X-CFspider-Version","1.8.6"),new Response(a.body,{status:a.status,headers:o})}}catch(e){return new Response(JSON.stringify({error:e.message}),{status:500,headers:{"Content-Type":"application/json"}})}}if("api/config/new_ip"===o&&"POST"===e.method){const e="false"!==t.NEW_IP&&"0"!==t.NEW_IP;return new Response(JSON.stringify({new_ip:e,message:"pleasevia Cloudflare Dashboard or wrangler.toml set NEW_IP envVar"}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if(!a)return fetch(pagesStaticUrl+"/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 o=s.pathname.slice(1).toLowerCase(),c=s.pathname.slice(1);if(c===i&&"dontmovethisdefaultsecretkeyifNeededpleasemanuallyviaaddvariableKEYtolinemodify"!==i){const e=new URLSearchParams(s.search);return e.set("token",await MD5MD5(f+u)),new Response("redirectin...",{status:302,headers:{Location:`/sub?${e.toString()}`}})}if("login"===o){const t=e.headers.get("Cookie")||"",n=t.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(n==await MD5MD5(r+i+a))return new Response("redirectin...",{status:302,headers:{Location:"/admin"}});if("POST"===e.method){const t=await e.text();if(new URLSearchParams(t).get("password")===a){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 MD5MD5(r+i+a)}; Path=/; Max-Age=86400; HttpOnly`),e}}return fetch(pagesStaticUrl+"/login")}if("admin"===o||o.startsWith("admin/")){const l=e.headers.get("Cookie")||"",d=l.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(!d||d!==await MD5MD5(r+i+a))return new Response("redirectin...",{status:302,headers:{Location:"/login"}});if("admin/log.json"===o){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"===c)try{const e=await getCloudflareUsage(s.searchParams.get("Email"),s.searchParams.get("GlobalAPIKey"),s.searchParams.get("AccountID"),s.searchParams.get("APIToken"));return new Response(JSON.stringify(e,null,2),{status:200,headers:{"Content-Type":"application/json"}})}catch(e){const t={msg:"querypleaserequestamountfailedfailedreason"+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"===c){if(s.searchParams.get("url")){const e=s.searchParams.get("url");try{new URL(e);const t=await pleaserequestpreferredAPI([e],s.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:"verifypreferredAPIfailedfailedreason"+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"===o){let e;if(s.searchParams.has("socks5"))e=await SOCKS5canuseabilityverify("socks5",s.searchParams.get("socks5"));else{if(!s.searchParams.has("http"))return new Response(JSON.stringify({error:"missingproxyparams"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});e=await SOCKS5canuseabilityverify("http",s.searchParams.get("http"))}return new Response(JSON.stringify(e,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}}if(config_JSON=await readconfig_JSON(t,f,u,t.PATH),"admin/init"===o)try{return config_JSON=await readconfig_JSON(t,f,u,t.PATH,!0),n.waitUntil(pleaserequestlogrecord(t,e,h,"Init_Config",config_JSON)),config_JSON.init="configalreadyheavysetTodefaultvalue",new Response(JSON.stringify(config_JSON,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){const t={msg:"configresetfailedfailedreason"+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"===o)try{const s=await e.json();return s.UUID&&s.HOST?(await t.KV.put("config.json",JSON.stringify(s,null,2)),n.waitUntil(pleaserequestlogrecord(t,e,h,"Save_Config",config_JSON)),new Response(JSON.stringify({success:!0,message:"configalreadykeepstore"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})):new Response(JSON.stringify({error:"confignotcomplete"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("keepstoreconfigfailed:",e),new Response(JSON.stringify({error:"keepstoreconfigfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else if("admin/cf.json"===o)try{const s=await e.json(),r={Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null};if(!s.init||!0!==s.init)if(s.Email&&s.GlobalAPIKey)r.Email=s.Email,r.GlobalAPIKey=s.GlobalAPIKey;else if(s.AccountID&&s.APIToken)r.AccountID=s.AccountID,r.APIToken=s.APIToken;else{if(!s.UsageAPI)return new Response(JSON.stringify({error:"confignotcomplete"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});r.UsageAPI=s.UsageAPI}return await t.KV.put("cf.json",JSON.stringify(r,null,2)),n.waitUntil(pleaserequestlogrecord(t,e,h,"Save_Config",config_JSON)),new Response(JSON.stringify({success:!0,message:"configalreadykeepstore"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("keepstoreconfigfailed:",e),new Response(JSON.stringify({error:"keepstoreconfigfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else if("admin/tg.json"===o)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:"confignotcomplete"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});await t.KV.put("tg.json",JSON.stringify(s,null,2))}return n.waitUntil(pleaserequestlogrecord(t,e,h,"Save_Config",config_JSON)),new Response(JSON.stringify({success:!0,message:"configalreadykeepstore"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("keepstoreconfigfailed:",e),new Response(JSON.stringify({error:"keepstoreconfigfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else{if("admin/ADD.txt"!==c)return new Response(JSON.stringify({error:"notSupportedPOSTpleaserequestpath"}),{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(pleaserequestlogrecord(t,e,h,"Save_Custom_IPs",config_JSON)),new Response(JSON.stringify({success:!0,message:"selffixedmeaningIPalreadykeepstore"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("keepstoreselffixedmeaningIPfailed:",e),new Response(JSON.stringify({error:"keepstoreselffixedmeaningIPfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}}else{if("admin/config.json"===o)return new Response(JSON.stringify(config_JSON,null,2),{status:200,headers:{"Content-Type":"application/json"}});if("admin/ADD.txt"===c){let n=await t.KV.get("ADD.txt")||"null";return"null"==n&&(n=(await generaterandomIP(e,config_JSON.preferredsubscribegenerate.localIPlib.randomnumberamount,config_JSON.preferredsubscribegenerate.localIPlib.pointfixedport))[1]),new Response(n,{status:200,headers:{"Content-Type":"text/plain;charset=utf-8",asn:e.cf.asn}})}if("admin/cf.json"===o)return new Response(JSON.stringify(e.cf,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}return n.waitUntil(pleaserequestlogrecord(t,e,h,"Admin_Login",config_JSON)),fetch(pagesStaticUrl+"/admin")}if("logout"===o||l.test(o)){const e=new Response("redirectin...",{status:302,headers:{Location:"/login"}});return e.headers.set("Set-Cookie","auth=; Path=/; Max-Age=0; HttpOnly"),e}if("sub"===o){const o=await MD5MD5(f+u);if(s.searchParams.get("token")===o){config_JSON=await readconfig_JSON(t,f,u,t.PATH),n.waitUntil(pleaserequestlogrecord(t,e,h,"Get_SUB",config_JSON));const a=r.toLowerCase(),i=4102329600,c=Date.now(),l=new Date(c);l.setHours(0,0,0,0);const d=Math.floor((c-l.getTime())/864e5*24*1099511627776/2);let p=d,g=d,m=26388279066624;config_JSON.CF.Usage.success&&(p=config_JSON.CF.Usage.pages,g=config_JSON.CF.Usage.workers,m=Number.isFinite(config_JSON.CF.Usage.max)?config_JSON.CF.Usage.max/1e3*1024:102400);const y={"content-type":"text/plain; charset=utf-8","Profile-Update-Interval":config_JSON.preferredsubscribegenerate.SUBUpdateTime,"Profile-web-page-url":s.protocol+"//"+s.host+"/admin","Subscription-Userinfo":`upload=${p}; download=${g}; total=${m}; expire=${i}`,"Cache-Control":"no-store"},w=s.searchParams.has("b64")||s.searchParams.has("base64")||e.headers.get("subconverter-request")||e.headers.get("subconverter-version")||a.includes("subconverter")||a.includes("CF-Workers-SUB".toLowerCase())?"mixed":s.searchParams.has("target")?s.searchParams.get("target"):s.searchParams.has("clash")||a.includes("clash")||a.includes("meta")||a.includes("mihomo")?"clash":s.searchParams.has("sb")||s.searchParams.has("singbox")||a.includes("singbox")||a.includes("sing-box")?"singbox":s.searchParams.has("surge")||a.includes("surge")?"surge&ver=4":s.searchParams.has("quanx")||a.includes("quantumult")?"quanx":s.searchParams.has("loon")||a.includes("loon")?"loon":"mixed";a.includes("mozilla")||(y["Content-Disposition"]=`attachment; filename*=utf-8''${encodeURIComponent(config_JSON.preferredsubscribegenerate.SUBNAME)}`);const b=s.searchParams.has("surge")||a.includes("surge")?"trojan":config_JSON.protocoltype;let S="";if("mixed"===w){const n=config_JSON.startuse0RTT?config_JSON.PATH+"?ed=2560":config_JSON.PATH,r="Shadowrocket"==config_JSON.TLSsplitslice?`&fragment=${encodeURIComponent("1,40-60,30-50,tlshello")}`:"Happ"==config_JSON.TLSsplitslice?`&fragment=${encodeURIComponent("3,1,tlshello")}`:"";let o=[],a="";if(!s.searchParams.has("sub")&&config_JSON.preferredsubscribegenerate.local){const n=config_JSON.preferredsubscribegenerate.localIPlib.randomIP?(await generaterandomIP(e,config_JSON.preferredsubscribegenerate.localIPlib.randomnumberamount,config_JSON.preferredsubscribegenerate.localIPlib.pointfixedport))[0]:await t.KV.get("ADD.txt")?await parseToArray(await t.KV.get("ADD.txt")):(await generaterandomIP(e,config_JSON.preferredsubscribegenerate.localIPlib.randomnumberamount,config_JSON.preferredsubscribegenerate.localIPlib.pointfixedport))[0],s=[],r=[],i=[];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("#");i.push(t[0]+"#"+encodeURIComponent(decodeURIComponent(t[1])))}else i.push(e);else r.push(e);const c=await pleaserequestpreferredAPI(s),l=[...new Set(i.concat(c[1]))];a=l.length>0?l.join("\n")+"\n":"";const d=c[0];o=[...new Set(r.concat(d))]}else{let e=s.searchParams.get("sub")||config_JSON.preferredsubscribegenerate.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("preferredsubscribegeneratehandlerexception"+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])),o.push(n+s)}}else a+=e+"\n"}catch(e){return new Response("preferredsubscribegeneratehandlerexception"+e.message,{status:403})}}const i=config_JSON.ECH?`&ech=${encodeURIComponent("cloudflare-ech.com+"+ECH_DOH)}`:"";S=a+o.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 s,o,a="443";return t?(s=t[1],a=t[2]||"443",o=t[3]||s,`${b}://00000000-0000-4000-8000-000000000000@${s}:${a}?security=tls&type=${config_JSON.transmittransferprotocol+i}&host=example.com&fp=${config_JSON.Fingerprint}&sni=example.com&path=${encodeURIComponent(config_JSON.randompath?randompath()+n:n)+r}&encryption=none${config_JSON.jumppasscertificateverify?"&insecure=1&allowInsecure=1":""}#${encodeURIComponent(o)}`):(console.warn(`[subscribecontent] notstandardIPformatalreadyignore: ${e}`),null)}).filter(e=>null!==e).join("\n")}else{const e=`${config_JSON.subscribeconvertconfig.SUBAPI}/sub?target=${w}&url=${encodeURIComponent(s.protocol+"//"+s.host+"/sub?target=mixed&token="+o+(s.searchParams.has("sub")&&""!=s.searchParams.get("sub")?`&sub=${s.searchParams.get("sub")}`:""))}&config=${encodeURIComponent(config_JSON.subscribeconvertconfig.SUBCONFIG)}&emoji=${config_JSON.subscribeconvertconfig.SUBEMOJI}&scv=${config_JSON.jumppasscertificateverify}`;try{const t=await fetch(e,{headers:{"User-Agent":"Subconverter for "+w+" edgetunnel(https://github.com/cmliu/edgetunnel)"}});if(!t.ok)return new Response("subscribeconvertbackendexception"+t.statusText,{status:t.status});S=await t.text(),(s.searchParams.has("surge")||a.includes("surge"))&&(S=Surgesubscribeconfigfilehotpatch(S,s.protocol+"//"+s.host+"/sub?token="+o+"&surge",config_JSON))}catch(e){return new Response("subscribeconvertbackendexception"+e.message,{status:403})}}return a.includes("subconverter")||(S=await batchamountreplacechangedomain(S.replace(/00000000-0000-4000-8000-000000000000/g,config_JSON.UUID),config_JSON.HOSTS)),"mixed"!==w||a.includes("mozilla")&&!s.searchParams.has("b64")&&!s.searchParams.has("base64")||(S=btoa(S)),"singbox"===w?(S=Singboxsubscribeconfigfilehotpatch(S,config_JSON.UUID,config_JSON.Fingerprint,config_JSON.ECH?await getECH(f):null),y["content-type"]="application/json; charset=utf-8"):"clash"===w&&(S=Clashsubscribeconfigfilehotpatch(S,config_JSON.UUID,config_JSON.ECH,config_JSON.HOSTS),y["content-type"]="application/x-yaml; charset=utf-8"),new Response(S,{status:200,headers:y})}}else if("locations"===o){const t=e.headers.get("Cookie")||"",n=t.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(n&&n==await MD5MD5(r+i+a))return fetch(new Request("https://speed.cloudflare.com/locations",{headers:{Referer:"https://speed.cloudflare.com/"}}))}else if("robots.txt"===o)return new Response("User-agent: *\nDisallow: /",{status:200,headers:{"Content-Type":"text/plain; charset=UTF-8"}})}}let g=t.URL||"nginx";if(g&&"nginx"!==g&&"1101"!==g){g=g.trim().replace(/\/$/,""),g.match(/^https?:\/\//i)||(g="https://"+g),g.toLowerCase().startsWith("http://")&&(g="https://"+g.substring(7));try{const e=new URL(g);g=e.protocol+"//"+e.host}catch(e){g="nginx"}}if("1101"===g)return new Response(await html1101(s.host,h),{status:200,headers:{"Content-Type":"text/html; charset=UTF-8"}});try{const t=new URL(g),n=new Headers(e.headers);n.set("Host",t.host),n.set("Referer",t.origin),n.set("Origin",t.origin),!n.has("User-Agent")&&r&&"null"!==r&&n.set("User-Agent",r);const o=await fetch(t.origin+s.pathname+s.search,{method:e.method,headers:n,body:e.body,cf:e.cf}),a=o.headers.get("content-type")||"";if(/text|javascript|json|xml/.test(a)){const e=(await o.text()).replaceAll(t.host,s.host);return new Response(e,{status:o.status,headers:{...Object.fromEntries(o.headers),"Cache-Control":"no-store"}})}return o}catch(e){}return new Response(await nginx(),{status:200,headers:{"Content-Type":"text/html; charset=UTF-8"}})}};async function handleWebSocket(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=makeReadableStr(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 forwardataudp(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}=parsetrojanpleaserequest(e,t);if(isSpeedTestSite(s))throw new Error("Speedtest site is blocked");await forwardataTCP(s,n,r,o,null,a,t,u)}else{const{port:n,hostname:s,rawIndex:r,version:c,isUDP:l}=parsevlesspleaserequest(e,t);if(isSpeedTestSite(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 forwardataudp(p,o,d);await forwardataTCP(s,n,p,o,d,a,t,u)}}})).catch(e=>{}),new Response(null,{status:101,webSocket:r})}function parsetrojanpleaserequest(e,t){const n=sha224(t);if(e.byteLength<56)return{hasError:!0,message:"invalid data"};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,56))!==n)return{hasError:!0,message:"invalid password"};const s=e.slice(58);if(s.byteLength<6)return{hasError:!0,message:"invalid S5 request data"};const r=new DataView(s);if(1!==r.getUint8(0))return{hasError:!0,message:"unsupported command, only TCP is allowed"};const o=r.getUint8(1);let a=0,i=2,c="";switch(o){case 1:a=4,c=new Uint8Array(s.slice(i,i+a)).join(".");break;case 3:a=new Uint8Array(s.slice(i,i+1))[0],i+=1,c=(new TextDecoder).decode(s.slice(i,i+a));break;case 4:a=16;const e=new DataView(s.slice(i,i+a)),t=[];for(let n=0;n<8;n++)t.push(e.getUint16(2*n).toString(16));c=t.join(":");break;default:return{hasError:!0,message:`invalid addressType is ${o}`}}if(!c)return{hasError:!0,message:`address is empty, addressType is ${o}`};const l=i+a,d=s.slice(l,l+2);return{hasError:!1,addressType:o,port:new DataView(d).getUint16(0),hostname:c,rawClientData:s.slice(l+4)}}function parsevlesspleaserequest(e,t){if(e.byteLength<24)return{hasError:!0,message:"Invalid data"};const n=new Uint8Array(e.slice(0,1));if(formatIdentifier(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}`}}async function forwardataTCP(e,t,n,s,r,o,a,i=null){async function c(e,t,n,r=null,o=!0){let a;if(r&&r.length>0)for(let e=0;e<r.length;e++){const t=(cachedProxyIndex+e)%r.length,[s,o]=r[t];try{console.log(`[reversedelegateconnection] tryconnectionto: ${s}:${o} (index: ${t})`),a=connect({hostname:s,port:o}),await Promise.race([a.opened,new Promise((e,t)=>setTimeout(()=>t(new Error("connectiontimeout")),1e3))]);const e=a.writable.getWriter();return await e.write(n),e.releaseLock(),console.log(`[reversedelegateconnection] successconnectionto: ${s}:${o}`),cachedProxyIndex=t,a}catch(e){console.log(`[reversedelegateconnection] connectionfailed: ${s}:${o}, error: ${e.message}`);try{a?.close?.()}catch(e){}continue}}if(o){a=connect({hostname:e,port:t});const s=a.writable.getWriter();return await s.write(n),s.releaseLock(),a}throw closeSocketQuietly(s),new Error("[reversedelegateconnection] allhavereversedelegateconnectionfailedandnotenableProxyFallbackconnectionterminate。")}async function l(){let i;if("socks5"===enableSocks5Proxy)console.log(`[SOCKS5proxy] proxyto: ${e}:${t}`),i=await socks5Connect(e,t,n);else if("http"===enableSocks5Proxy||"https"===enableSocks5Proxy)console.log(`[HTTPproxy] proxyto: ${e}:${t}`),i=await httpConnect(e,t,n);else{console.log(`[reversedelegateconnection] proxyto: ${e}:${t}`);const s=await parseplaceaddressport(proxyIP,e,a);i=await c(atob("UFJPWFlJUC50cDEuMDkwMjI3Lnh5eg=="),1,n,s,enableProxyFallback)}o.socket=i,i.closed.catch(()=>{}).finally(()=>closeSocketQuietly(s)),connectStreams(i,s,r,null)}console.log(`[TCPturnsend] target: ${e}:${t} | proxyIP: ${proxyIP} | twoProxy: ${i?i.hostname+":"+i.port:"no"} | reversedelegatetype: ${enableSocks5Proxy||"proxyip"}`);if(i){console.log("[TCPturnsend] makeusetwoProxy");try{const a=await async function(){if(!i)throw new Error("twoProxynotconfig");console.log(`[twoProxy] via ${i.hostname}:${i.port} connectionto ${e}:${t}`);const s=connect({hostname:i.hostname,port:i.port}),r=s.writable.getWriter(),o=s.readable.getReader();try{const a=i.username&&i.password?`Proxy-Authorization: Basic ${btoa(`${i.username}:${i.password}`)}\r\n`:"",c=`CONNECT ${e}:${t} HTTP/1.1\r\nHost: ${e}:${t}\r\n${a}User-Agent: CFspider/1.8.3\r\nConnection: keep-alive\r\n\r\n`;await r.write((new TextEncoder).encode(c));let l=new Uint8Array(0),d=-1,u=0;for(;-1===d&&u<8192;){const{done:e,value:t}=await o.read();if(e)throw new Error("proxyconnectionclose");l=new Uint8Array([...l,...t]),u=l.length;for(let e=0;e<l.length-3;e++)if(13===l[e]&&10===l[e+1]&&13===l[e+2]&&10===l[e+3]){d=e+4;break}}if(-1===d)throw new Error("invalidproxyresponse");const p=(new TextDecoder).decode(l.slice(0,d)).match(/HTTP\/\d\.\d\s+(\d+)/),f=p?parseInt(p[1]):0;if(f<200||f>=300)throw new Error(`proxyconnectionfailed: HTTP ${f}`);return console.log(`[twoProxy] tunnelestablishsuccess: ${e}:${t}`),await r.write(n),r.releaseLock(),o.releaseLock(),s}catch(e){try{r.releaseLock()}catch(e){}try{o.releaseLock()}catch(e){}try{s.close()}catch(e){}throw e}}();o.socket=a,a.closed.catch(()=>{}).finally(()=>closeSocketQuietly(s)),connectStreams(a,s,r,null)}catch(e){console.log(`[twoProxy] connectionfailed: ${e.message}, backexittodefaultmethodstyle`);try{await l()}catch(e){throw e}}}else if(enableSocks5Proxy&&(enableGlobalSocks5||(d=e,socks5Whitelist.some(e=>new RegExp(`^${e.replace(/\*/g,".*")}$`,"i").test(d))))){console.log("[TCPturnsend] startuse SOCKS5/HTTP globalproxy");try{await l()}catch(e){throw e}}else try{console.log(`[TCPturnsend] trydirectto: ${e}:${t}`);const a=await c(e,t,n);o.socket=a,connectStreams(a,s,r,l)}catch(e){await l()}var d}async function forwardataudp(e,t,n){try{const s=connect({hostname:"8.8.4.4",port:53});let r=n;const o=s.writable.getWriter();await o.write(e),o.releaseLock(),await s.readable.pipeTo(new WritableStream({async write(e){if(t.readyState===WebSocket.OPEN)if(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)}}))}catch(e){}}function closeSocketQuietly(e){try{e.readyState!==WebSocket.OPEN&&e.readyState!==WebSocket.CLOSING||e.close()}catch(e){}}function formatIdentifier(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)}`}async function connectStreams(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=>{closeSocketQuietly(t)}),!o&&s&&await s()}function makeReadableStr(e,t){let n=!1;return new ReadableStream({start(s){e.addEventListener("message",e=>{n||s.enqueue(e.data)}),e.addEventListener("close",()=>{n||(closeSocketQuietly(e),s.close())}),e.addEventListener("error",e=>s.error(e));const{earlyData:r,error:o}=base64ToArray(t);o?s.error(o):r&&s.enqueue(r)},cancel(){n=!0,closeSocketQuietly(e)}})}function isSpeedTestSite(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}function base64ToArray(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}}}async function socks5Connect(e,t,n){const{username:s,password:r,hostname:o,port:a}=parsedSocks5Address,i=connect({hostname:o,port:a}),c=i.writable.getWriter(),l=i.readable.getReader();try{const o=s&&r?new Uint8Array([5,2,0,2]):new Uint8Array([5,1,0]);await c.write(o);let a=await l.read();if(a.done||a.value.byteLength<2)throw new Error("S5 method selection failed");const d=new Uint8Array(a.value)[1];if(2===d){if(!s||!r)throw new Error("S5 requires authentication");const e=(new TextEncoder).encode(s),t=(new TextEncoder).encode(r),n=new Uint8Array([1,e.length,...e,t.length,...t]);if(await c.write(n),a=await l.read(),a.done||0!==new Uint8Array(a.value)[1])throw new Error("S5 authentication failed")}else if(0!==d)throw new Error(`S5 unsupported auth method: ${d}`);const u=(new TextEncoder).encode(e),p=new Uint8Array([5,1,0,3,u.length,...u,t>>8,255&t]);if(await c.write(p),a=await l.read(),a.done||0!==new Uint8Array(a.value)[1])throw new Error("S5 connection failed");return await c.write(n),c.releaseLock(),l.releaseLock(),i}catch(e){try{c.releaseLock()}catch(e){}try{l.releaseLock()}catch(e){}try{i.close()}catch(e){}throw e}}async function httpConnect(e,t,n){const{username:s,password:r,hostname:o,port:a}=parsedSocks5Address,i=connect({hostname:o,port:a}),c=i.writable.getWriter(),l=i.readable.getReader();try{const o=`CONNECT ${e}:${t} HTTP/1.1\r\nHost: ${e}:${t}\r\n${s&&r?`Proxy-Authorization: Basic ${btoa(`${s}:${r}`)}\r\n`:""}User-Agent: Mozilla/5.0\r\nConnection: keep-alive\r\n\r\n`;await c.write((new TextEncoder).encode(o));let a=new Uint8Array(0),d=-1,u=0;for(;-1===d&&u<8192;){const{done:e,value:t}=await l.read();if(e)throw new Error("Connection closed before receiving HTTP response");a=new Uint8Array([...a,...t]),u=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&&(d=n+4)}if(-1===d)throw new Error("Invalid HTTP response");const p=parseInt((new TextDecoder).decode(a.slice(0,d)).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 c.write(n),c.releaseLock(),l.releaseLock(),i}catch(e){try{c.releaseLock()}catch(e){}try{l.releaseLock()}catch(e){}try{i.close()}catch(e){}throw e}}function Clashsubscribeconfigfilehotpatch(e,t=null,n=!1,s=[]){let r=e.replace(/mode:\s*Rule\b/g,"mode: rule");if(/^dns:\s*(?:\n|$)/m.test(r)||(r="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"+r),n&&s.length>0){const e=s.map(e=>` "${e}":\n - tls://8.8.8.8\n - https://doh.cmliussss.com/CMLiussss\n - ${ECH_DOH}`).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 o=r.split("\n"),a=[];let i=0;for(;i<o.length;){const e=o[i],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&&i+1<o.length;)i++,n+="\n"+o[i],s+=(o[i].match(/\{/g)||[]).length-(o[i].match(/\}/g)||[]).length;const r=n.match(/type:\s*(\w+)/);let c="uuid";"trojan"===(r?r[1]:"vless")&&(c="password");const l=new RegExp(`${c}:\\s*([^,}\\n]+)`),d=n.match(l);d&&d[1].trim()===t.trim()&&(n=n.replace(/\}(\s*)$/,", ech-opts: {enable: true}}$1")),a.push(n),i++}else if(n.startsWith("- name:")){let n=[e],s=e.search(/\S/),r=s+2;for(i++;i<o.length;){const e=o[i],t=e.trim();if(!t){n.push(e),i++;break}const r=e.search(/\S/);if(r<=s&&t.startsWith("- "))break;if(r<s&&t)break;n.push(e),i++}const c=n.join("\n"),l=c.match(/type:\s*(\w+)/);let d="uuid";"trojan"===(l?l[1]:"vless")&&(d="password");const u=new RegExp(`${d}:\\s*([^\\n]+)`),p=c.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`)}}a.push(...n)}else a.push(e),i++}return a.join("\n")}function Singboxsubscribeconfigfilehotpatch(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("Singboxhotpatchexecutelinefailed:",t),JSON.stringify(JSON.parse(e),null,2)}}function Surgesubscribeconfigfilehotpatch(e,t,n){const s=e.includes("\r\n")?e.split("\r\n"):e.split("\n");let r="";const o=n.startuse0RTT?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.jumppasscertificateverify}`,a=`sni=${t}, skip-cert-verify=${n.jumppasscertificateverify}, 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.preferredsubscribegenerate.SUBUpdateTime*60} strict=false`+r.substring(r.indexOf("\n")),r}async function pleaserequestlogrecord(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.startuse)try{const t=await e.KV.get("tg.json"),n=JSON.parse(t);await sendMessage(n.BotToken,n.ChatID,a,r)}catch(e){console.error(`readtg.jsonouterror: ${e.message}`)}}catch(e){i=[a]}else i=[a];await e.KV.put("log.json",JSON.stringify(i,null,2))}catch(e){console.error(`logrecordfailed: ${e.message}`)}}async function sendMessage(e,t,n,s){if(e&&t)try{const r=new Date(n.TIME).toLocaleString("zh-CN",{timeZone:"Asia/Shanghai"}),o=new URL(n.URL),a=`<b>#${s.preferredsubscribegenerate.SUBNAME} logthroughknow</b>\n\n📌 <b>type</b>#${n.TYPE}\n🌐 <b>IP</b><code>${n.IP}</code>\n📍 <b>bitset</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>pleaserequestuseamount</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)}}function maskcodesensitiveinfo(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 MD5MD5(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()}function randompath(){const e=Math.floor(3*Math.random()+1);return`/${["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"].sort(()=>.5-Math.random()).slice(0,e).join("/")}`}function randomreplacechangethroughconfigsymbol(e){if(!e?.includes("*"))return e;return e.replace(/\*/g,()=>{let e="";for(let t=0;t<Math.floor(14*Math.random())+3;t++)e+="abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())];return e})}function batchamountreplacechangedomain(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=randomreplacechangethroughconfigsymbol(s[Math.floor(r/n)%s.length])),r++,o))}async function getECH(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""}}async function readconfig_JSON(e,t,n,s,r=!1){const o=t,a=performance.now(),i={TIME:(new Date).toISOString(),HOST:o,HOSTS:[t],UUID:n,protocoltype:"vless",transmittransferprotocol:"ws",jumppasscertificateverify:!0,startuse0RTT:!1,TLSsplitslice:null,randompath:!1,ECH:!1,Fingerprint:"chrome",preferredsubscribegenerate:{local:!0,localIPlib:{randomIP:!0,randomnumberamount:16,pointfixedport:-1},SUB:null,SUBNAME:"edgetunnel",SUBUpdateTime:3,TOKEN:await MD5MD5(t+n)},subscribeconvertconfig:{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},reversedelegate:{PROXYIP:"auto",SOCKS5:{startuse:enableSocks5Proxy,global:enableGlobalSocks5,accountid:mySocks5Account,whitenamelist:socks5Whitelist}},TG:{startuse:!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 t=await e.KV.get("config.json");t&&1!=r?config_JSON=JSON.parse(t):(await e.KV.put("config.json",JSON.stringify(i,null,2)),config_JSON=i)}catch(e){console.error(`readconfig_JSONouterror: ${e.message}`),config_JSON=i}config_JSON.HOST=o,config_JSON.HOSTS||(config_JSON.HOSTS=[t]),e.HOST&&(config_JSON.HOSTS=(await parseToArray(e.HOST)).map(e=>e.toLowerCase().replace(/^https?:\/\//,"").split("/")[0].split(":")[0])),config_JSON.UUID=n,config_JSON.PATH=s?s.startsWith("/")?s:"/"+s:config_JSON.reversedelegate.SOCKS5.startuse?"/"+config_JSON.reversedelegate.SOCKS5.startuse+(config_JSON.reversedelegate.SOCKS5.global?"://":"=")+config_JSON.reversedelegate.SOCKS5.accountid:"auto"===config_JSON.reversedelegate.PROXYIP?"/":`/proxyip=${config_JSON.reversedelegate.PROXYIP}`;const c="Shadowrocket"==config_JSON.TLSsplitslice?`&fragment=${encodeURIComponent("1,40-60,30-50,tlshello")}`:"Happ"==config_JSON.TLSsplitslice?`&fragment=${encodeURIComponent("3,1,tlshello")}`:"";config_JSON.Fingerprint||(config_JSON.Fingerprint="chrome"),config_JSON.ECH?config_JSON.preferredsubscribegenerate.SUBUpdateTime=1:config_JSON.ECH=!1;const l=config_JSON.ECH?`&ech=${encodeURIComponent("cloudflare-ech.com+"+ECH_DOH)}`:"";config_JSON.LINK=`${config_JSON.protocoltype}://${n}@${o}:443?security=tls&type=${config_JSON.transmittransferprotocol+l}&host=${o}&fp=${config_JSON.Fingerprint}&sni=${o}&path=${encodeURIComponent(config_JSON.startuse0RTT?config_JSON.PATH+"?ed=2560":config_JSON.PATH)+c}&encryption=none${config_JSON.jumppasscertificateverify?"&insecure=1&allowInsecure=1":""}#${encodeURIComponent(config_JSON.preferredsubscribegenerate.SUBNAME)}`,config_JSON.preferredsubscribegenerate.TOKEN=await MD5MD5(t+n);const d={BotToken:null,ChatID:null};config_JSON.TG={startuse:!!config_JSON.TG.startuse&&config_JSON.TG.startuse,...d};try{const t=await e.KV.get("tg.json");if(t){const e=JSON.parse(t);config_JSON.TG.ChatID=e.ChatID?e.ChatID:null,config_JSON.TG.BotToken=e.BotToken?maskcodesensitiveinfo(e.BotToken):null}else await e.KV.put("tg.json",JSON.stringify(d,null,2))}catch(e){console.error(`readtg.jsonouterror: ${e.message}`)}const u={Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null};config_JSON.CF={...u,Usage:{success:!1,pages:0,workers:0,total:0,max:1e5}};try{const t=await e.KV.get("cf.json");if(t){const e=JSON.parse(t);if(e.UsageAPI)try{const t=await fetch(e.UsageAPI),n=await t.json();config_JSON.CF.Usage=n}catch(e){console.error(`pleaserequest CF_JSON.UsageAPI failed: ${e.message}`)}else{config_JSON.CF.Email=e.Email?e.Email:null,config_JSON.CF.GlobalAPIKey=e.GlobalAPIKey?maskcodesensitiveinfo(e.GlobalAPIKey):null,config_JSON.CF.AccountID=e.AccountID?maskcodesensitiveinfo(e.AccountID):null,config_JSON.CF.APIToken=e.APIToken?maskcodesensitiveinfo(e.APIToken):null,config_JSON.CF.UsageAPI=null;const t=await getCloudflareUsage(e.Email,e.GlobalAPIKey,e.AccountID,e.APIToken);config_JSON.CF.Usage=t}}else await e.KV.put("cf.json",JSON.stringify(u,null,2))}catch(e){console.error(`readcf.jsonouterror: ${e.message}`)}return config_JSON.plusloadtime=(performance.now()-a).toFixed(2)+"ms",config_JSON}async function generaterandomIP(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:"CFmovemovepreferred",4837:"CFconnectthroughpreferred",4134:"CFtelecompreferred"}[r]||"CFofficialmethodpreferred",i=[443,2053,2083,2087,2096,8443];let c=[];try{const e=await fetch(o);c=e.ok?await parseToArray(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 parseToArray(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(",")}function isValidBase64(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}}function base64Decode(e){const t=new Uint8Array(atob(e).split("").map(e=>e.charCodeAt(0)));return new TextDecoder("utf-8").decode(t)}async function pleaserequestpreferredAPI(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=isValidBase64(c)?base64Decode(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("IPplaceaddress")&&n.includes("port")&&n.includes("dataincenter")){const e=n.indexOf("IPplaceaddress"),t=n.indexOf("port"),o=n.indexOf("country")>-1?n.indexOf("country"):n.indexOf("city")>-1?n.indexOf("city"):n.indexOf("dataincenter"),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("delay"))&&n.some(e=>e.includes("downloadspeed"))){const o=n.findIndex(e=>e.includes("IP")),a=n.findIndex(e=>e.includes("delay")),i=n.findIndex(e=>e.includes("downloadspeed")),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}#CFpreferred ${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 reversedelegateparamsget(e){const t=new URL(e.url),{pathname:n,searchParams:s}=t,r=n.toLowerCase();mySocks5Account=s.get("socks5")||s.get("http")||null,enableGlobalSocks5=s.has("globalproxy")||!1;const o=r.match(/\/(proxyip[.=]|pyip=|ip=)(.+)/);if(s.has("proxyip")){const e=s.get("proxyip");return proxyIP=e.includes(",")?e.split(",")[Math.floor(Math.random()*e.split(",").length)]:e,void(enableProxyFallback=!1)}if(o){const e="proxyip."===o[1]?`proxyip.${o[2]}`:o[2];return proxyIP=e.includes(",")?e.split(",")[Math.floor(Math.random()*e.split(",").length)]:e,void(enableProxyFallback=!1)}let a;if(a=n.match(/\/(socks5?|http):\/?\/?(.+)/i)){if(enableSocks5Proxy="http"===a[1].toLowerCase()?"http":"socks5",mySocks5Account=a[2].split("#")[0],enableGlobalSocks5=!0,mySocks5Account.includes("@")){const e=mySocks5Account.lastIndexOf("@");let t=mySocks5Account.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)),mySocks5Account=`${t}@${mySocks5Account.substring(e+1)}`}}else if(a=n.match(/\/(g?s5|socks5|g?http)=(.+)/i)){const e=a[1].toLowerCase();mySocks5Account=a[2],enableSocks5Proxy=e.includes("http")?"http":"socks5",enableGlobalSocks5=e.startsWith("g")||enableGlobalSocks5}if(mySocks5Account)try{parsedSocks5Address=await getSOCKS5accountid(mySocks5Account),enableSocks5Proxy=s.get("http")?"http":enableSocks5Proxy}catch(e){console.error("parseSOCKS5placeaddressfailed:",e.message),enableSocks5Proxy=null}else enableSocks5Proxy=null}async function getSOCKS5accountid(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 placeaddressformatconfirmcertpartsplitmustis "username:password" formstyle');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 placeaddressformatportidmustisnumberchar");if(a.includes(":")&&!/^\[.*\]$/.test(a))throw new Error("invalid SOCKS placeaddressformatIPv6 placeaddressmustusemethodbracketidbracketupif [2001:db8::1]");return{username:r,password:o,hostname:a,port:i}}async function getCloudflareUsage(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(`accountusergetfailed: ${s.status}`);const o=await s.json();if(!o?.result?.length)throw new Error("notfindtoaccountuser");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("notfindtoaccountuserdata");const p=o(u.pagesFunctionsInvocationsAdaptiveGroups),f=o(u.workersInvocationsAdaptive),h=p+f,g=1e5;return console.log(`statsresult - Pages: ${p}, Workers: ${f}, totalcount: ${h}, uplimit: 100000`),{success:!0,pages:p,workers:f,total:h,max:g}}catch(e){return console.error("getmakeuseamounterror:",e.message),{success:!1,pages:0,workers:0,total:0,max:1e5}}}function sha224(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;for(e+=String.fromCharCode(128);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,f]=r;for(let e=0;e<64;e++){const r=f+(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;f=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:f)>>>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}async function parseplaceaddressport(e,t="dash.cloudflare.com",n="00000000-0000-4000-8000-000000000000"){if(cacheproxyIP&&cachedProxyArray&&cacheproxyIP===e)console.log(`[reversedelegateparse] readcache totalnumber: ${cachedProxyArray.length}one\n${cachedProxyArray.map(([e,t],n)=>`${n+1}. ${e}:${t}`).join("\n")}`);else{async function s(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 r(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 o=[];if((e=e.toLowerCase()).includes(".william"))try{const d=(await s(e,"TXT")).filter(e=>16===e.type).map(e=>e.data);if(d.length>0){let u=d[0];u.startsWith('"')&&u.endsWith('"')&&(u=u.slice(1,-1));o=u.replace(/\\010/g,",").replace(/\n/g,",").split(",").map(e=>e.trim()).filter(Boolean).map(e=>r(e))}}catch(p){console.error("parseWilliamdomainfailed:",p)}else{let[f,h]=r(e);if(e.includes(".tp")){const m=e.match(/\.tp(\d+)/);m&&(h=parseInt(m[1],10))}const g=/^\[?([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(f)||g.test(f))o=[[f,h]];else{const[y,w]=await Promise.all([s(f,"A"),s(f,"AAAA")]),b=[...y.filter(e=>1===e.type).map(e=>e.data),...w.filter(e=>28===e.type).map(e=>`[${e.data}]`)];o=b.length>0?b.map(e=>[e,h]):[[f,h]]}}const a=o.sort((e,t)=>e[0].localeCompare(t[0])),i=t.includes(".")?t.split(".").slice(-2).join("."):t;let c=[...i+n].reduce((e,t)=>e+t.charCodeAt(0),0);console.log(`[reversedelegateparse] randomseed: ${c}\ntargetstationpoint: ${i}`);const l=[...a].sort(()=>(c=1103515245*c+12345&2147483647)/2147483647-.5);cachedProxyArray=l.slice(0,8),console.log(`[reversedelegateparse] parsecomplete totalnumber: ${cachedProxyArray.length}one\n${cachedProxyArray.map(([e,t],n)=>`${n+1}. ${e}:${t}`).join("\n")}`),cacheproxyIP=e}return cachedProxyArray}async function SOCKS5canuseabilityverify(e="socks5",t){const n=Date.now();try{parsedSocks5Address=await getSOCKS5accountid(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}=parsedSocks5Address,i=s&&r?`${s}:${r}@${o}:${a}`:`${o}:${a}`;try{const t=new Uint8Array(0),s="socks5"==e?await socks5Connect("check.socks5.090227.xyz",80,t):await httpConnect("check.socks5.090227.xyz",80,t);if(!s)return{success:!1,error:"nonemethodconnectiontoproxyservicehandler",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("closeconnectionwhenouterror:",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}}}async function nginx(){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'}async function html1101(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} &bull; ${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">&bull;</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">&bull;</span>\n </span>\n <span class="cf-footer-item sm:block sm:mb-1"><span>Performance &amp; 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>`}