-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsnip.js
More file actions
1 lines (1 loc) · 22.6 KB
/
Copy pathsnip.js
File metadata and controls
1 lines (1 loc) · 22.6 KB
1
export default {async fetch(e){const t=e.cf||{},n=e.headers,o=n.get("cf-connecting-ip")||n.get("x-forwarded-for")||"127.0.0.1",r={ip:o,city:t.city||"Unknown",country:t.country||"Unknown",isp:t.asOrganization||"Cloudflare",asn:t.asn?`AS${t.asn}`:"N/A",colo:t.colo||"N/A",http:t.httpProtocol||"HTTP",tls:t.tlsVersion||"N/A"};return new Response(renderHtml(r),{headers:{"content-type":"text/html;charset=UTF-8"}})}};function renderHtml(e){return`<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><title>IPcheck</title><link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23F38020%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22><path d=%22M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z%22/></svg>"><script>(function(){try{var t=localStorage.getItem("theme"),e=window.matchMedia("(prefers-color-scheme: dark)").matches;"dark"===t||!t&&e?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")}catch(a){}})()</script><script src="https://cdn.tailwindcss.com"></script><link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><script src="https://unpkg.com/react@18/umd/react.production.min.js"></script><script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script><script src="https://unpkg.com/@babel/standalone/babel.min.js"></script><script>window.CF_DATA=${JSON.stringify(e)},tailwind.config={darkMode:"class",theme:{extend:{fontFamily:{sans:["Plus Jakarta Sans","sans-serif"],mono:["JetBrains Mono","monospace"]},colors:{primary:"#F38020",dark:{bg:"#0f172a",card:"rgba(30, 41, 59, 0.7)",border:"rgba(255, 255, 255, 0.1)"}},animation:{"slide-up":"slideUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards","pulse-glow":"pulseGlow 2s infinite"},keyframes:{slideUp:{"0%":{opacity:0,transform:"translateY(20px)"},"100%":{opacity:1,transform:"translateY(0)"}},pulseGlow:{"0%, 100%":{opacity:1,boxShadow:"0 0 0 0px rgba(16, 185, 129, 0.4)"},"50%":{opacity:.8,boxShadow:"0 0 0 4px rgba(16, 185, 129, 0)"}}},boxShadow:{glass:"0 8px 32px 0 rgba(31, 38, 135, 0.05)",neon:"0 0 10px rgba(243, 128, 32, 0.2)"}}}}</script><style>html{background-color:#f0f4f8}html.dark{background-color:#020617}body{background-color:#f0f4f8;background-image:linear-gradient(rgba(200,200,200,.1) 1px,transparent 1px),linear-gradient(90deg,rgba(200,200,200,.1) 1px,transparent 1px);background-size:30px 30px;min-height:100vh;color:#0f172a;transition:background-color .3s,color .3s}.dark body{background-color:#020617;background-image:linear-gradient(rgba(255,255,255,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.03) 1px,transparent 1px);color:#f8fafc}.glass-card{background:rgba(255,255,255,.8);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(255,255,255,.8);box-shadow:0 4px 6px -1px rgba(0,0,0,.02),0 2px 4px -1px rgba(0,0,0,.02),inset 0 0 0 1px rgba(255,255,255,.5);transition:background .3s,border-color .3s}.dark .glass-card{background:rgba(15,23,42,.6);border:1px solid rgba(255,255,255,.05);box-shadow:0 4px 6px -1px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.05)}.scan-line{position:absolute;top:0;left:-100%;width:50%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.4),transparent);transform:skewX(-20deg);animation:scan 6s infinite;pointer-events:none}.dark .scan-line{background:linear-gradient(90deg,transparent,rgba(255,255,255,.08),transparent)}@keyframes scan{0%,50%{left:-100%}100%{left:200%}}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}</style></head><body class="p-4 md:p-8 pb-24 antialiased selection:bg-orange-100 selection:text-orange-600 dark:selection:bg-orange-900/30 dark:selection:text-orange-400"><div id="root" class="max-w-7xl mx-auto relative z-10"></div><script type="text/babel" data-presets="react">const{useState,useEffect,useLayoutEffect}=React,{createRoot}=ReactDOM,extractScore=e=>{if(null==e)return 0;const t=String(e).match(/([0-9.]+)/);return t?Math.min(100,Math.round(100*parseFloat(t[1]))):0},Sparkline=({data:e,color:t,width:a=100,height:r=30})=>{if(e.length<2)return null;const s=Math.max(...e,100),n=Math.min(...e),o=s-n||1,l=e.map((e,t)=>{const s=t/(e.length-1)*a,l=r-(e-n)/o*r;return\`\${s},\${l}\`}).join(" "),i="green"===t?"#10b981":"yellow"===t?"#f59e0b":"#f43f5e";return<svg width="100%" height="100%" viewBox={\`0 0 \${a} \${r}\`} preserveAspectRatio="none" className="overflow-visible"><defs><linearGradient id={\`grad-\${t}\`} x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stopColor={i} stopOpacity="0.2"/><stop offset="100%" stopColor={i} stopOpacity="0"/></linearGradient></defs><path d={\`M0,\${r} \${l} \${a},\${r} Z\`} fill={\`url(#grad-\${t})\`}/><polyline points={l} fill="none" stroke={i} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/><circle cx={a} cy={r-(e[e.length-1]-n)/o*r} r="2" fill={i} className="animate-pulse"/></svg>},PingCard=({name:e,url:t,icon:a,index:r})=>{const[s,n]=useState(null),[o,l]=useState(new Array(10).fill(0));useEffect(()=>{const e=()=>{const e=Date.now(),a=new Image,r=()=>{const a=Date.now()-e;n(a),l(e=>[...e.slice(1),a])};a.onload=r,a.onerror=r,a.src=\`\${t}?t=\${Date.now()}\`},a=setTimeout(e,200*r),s=setInterval(e,2e3);return()=>{clearTimeout(a),clearInterval(s)}},[t]);const i=s?s<100?"green":s<300?"yellow":"red":"gray";return<div className="glass-card p-3 rounded-xl flex items-center justify-between gap-3 group hover:-translate-y-1 transition-transform duration-300 relative overflow-hidden" style={{animationDelay:\`\${50*r}ms\`}}><div className="flex items-center gap-3 z-10"><div className="w-8 h-8 rounded-full bg-white/50 dark:bg-slate-700/50 border border-white dark:border-white/10 flex items-center justify-center shadow-sm"><img src={a} className="w-5 h-5 object-contain"/></div><div><div className="text-[11px] font-bold text-gray-700 dark:text-gray-200 leading-tight">{e}</div><div className={\`text-[10px] font-mono font-bold \${"green"===i?"text-emerald-600 dark:text-emerald-400":"yellow"===i?"text-amber-600 dark:text-amber-400":"red"===i?"text-rose-600 dark:text-rose-400":"text-gray-400 dark:text-gray-500"}\`}>{s?\`\${s}ms\`:"Waiting..."}</div></div></div><div className="w-16 h-8 opacity-60 group-hover:opacity-100 transition-opacity z-10"><Sparkline data={o} color={i}/></div><div className={\`absolute right-0 top-0 w-16 h-full bg-gradient-to-l from-\${"green"===i?"emerald":"yellow"===i?"amber":"rose"}-50/50 dark:from-\${"green"===i?"emerald":"yellow"===i?"amber":"rose"}-900/20 to-transparent pointer-events-none\`}/></div>},RiskReport=({data:e,loading:t})=>{if(t)return<div className="mt-4 p-4 border border-dashed border-gray-200 dark:border-gray-700 rounded-xl bg-gray-50/50 dark:bg-slate-800/50 animate-pulse"><div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/4 mb-4"></div><div className="space-y-2"><div className="h-2 bg-gray-200 dark:bg-gray-700 rounded w-full"></div><div className="h-2 bg-gray-200 dark:bg-gray-700 rounded w-5/6"></div></div></div>;if(!e)return null;const a=extractScore(e.company?.abuser_score),r=extractScore(e.asn?.abuser_score),s=({label:e,value:t,sub:a})=><div className="flex flex-col py-1.5 border-b border-gray-100/50 dark:border-gray-700/50 last:border-0"><span className="text-[10px] text-gray-400 dark:text-gray-500 uppercase font-bold tracking-wider">{e}</span><span className="text-xs font-medium text-gray-700 dark:text-gray-200 break-all">{t||"N/A"}</span>{a&&<span className="text-[10px] text-gray-400 dark:text-gray-500">{a}</span>}</div>,n=({type:e,active:t,text:a})=>{if(!t)return null;return<span className={\`text-[10px] px-2 py-0.5 rounded border font-semibold \${{bad:"bg-rose-50 text-rose-600 border-rose-100 dark:bg-rose-900/20 dark:text-rose-400 dark:border-rose-900/30",good:"bg-emerald-50 text-emerald-600 border-emerald-100 dark:bg-emerald-900/20 dark:text-emerald-400 dark:border-emerald-900/30",warn:"bg-amber-50 text-amber-600 border-amber-100 dark:bg-amber-900/20 dark:text-amber-400 dark:border-amber-900/30",neutral:"bg-gray-50 text-gray-500 border-gray-100 dark:bg-slate-800 dark:text-gray-400 dark:border-slate-700"}[e]}\`}>{a}</span>},o=e=>{if(!e)return"未知";try{return new Date().toLocaleTimeString("zh-CN",{timeZone:e,hour:"2-digit",minute:"2-digit"})}catch(t){return"未知"}};return<div className="mt-5 pt-4 border-t border-gray-100 dark:border-gray-700/50"><div className="grid grid-cols-2 gap-4 mb-5"><div className="bg-white/50 dark:bg-slate-800/50 border border-gray-100 dark:border-slate-700 rounded-lg p-3 text-center relative overflow-hidden group"><div className="relative z-10"><div className="text-[10px] text-gray-400 dark:text-gray-500 uppercase font-bold">运营商信誉</div><div className={\`text-xl font-mono font-bold mt-1 \${a>20?"text-rose-500 dark:text-rose-400":"text-emerald-500 dark:text-emerald-400"}\`}>{a}%</div></div><div className={\`absolute bottom-0 left-0 h-1 bg-current w-full opacity-20 \${a>20?"text-rose-500":"text-emerald-500"}\`}></div></div><div className="bg-white/50 dark:bg-slate-800/50 border border-gray-100 dark:border-slate-700 rounded-lg p-3 text-center relative overflow-hidden group"><div className="relative z-10"><div className="text-[10px] text-gray-400 dark:text-gray-500 uppercase font-bold">ASN 信誉</div><div className={\`text-xl font-mono font-bold mt-1 \${r>20?"text-rose-500 dark:text-rose-400":"text-emerald-500 dark:text-emerald-400"}\`}>{r}%</div></div><div className={\`absolute bottom-0 left-0 h-1 bg-current w-full opacity-20 \${r>20?"text-rose-500":"text-emerald-500"}\`}></div></div></div><div className="flex flex-wrap gap-2 mb-5"><n type="bad" active={e.is_proxy} text="Proxy"/><n type="bad" active={e.is_vpn} text="VPN"/><n type="bad" active={e.is_tor} text="Tor"/><n type="bad" active={e.is_datacenter} text="Data Center"/><n type="bad" active={e.is_abuser} text="Abuser"/><n type="bad" active={e.is_bogon} text="Bogon"/><n type="good" active={e.is_mobile} text="Mobile ISP"/><n type="good" active={e.is_crawler} text="Search Engine"/><n type="neutral" active={!e.is_proxy&&!e.is_datacenter} text="Low Risk"/></div><div className="grid grid-cols-2 gap-x-4 gap-y-1"><s label="ASN 组织" value={e.asn?.org} sub={e.asn?.type}/><s label="路由段 (Route)" value={e.asn?.route}/><s label="注册局 (Registry)" value={e.asn?.registry}/><s label="所属公司" value={e.company?.name} sub={e.company?.domain}/><div className="col-span-2 mt-2 pt-2 border-t border-dashed border-gray-200 dark:border-gray-700"><div className="flex justify-between items-center mb-1"><span className="text-[10px] text-gray-400 dark:text-gray-500 uppercase font-bold">地理位置详情</span><a href={\`https://www.google.com/maps/search/?api=1&query=\${e.location?.latitude},\${e.location?.longitude}\`} target="_blank" className="text-[10px] text-blue-500 dark:text-blue-400 hover:underline">Open Map ↗</a></div><div className="grid grid-cols-2 gap-2 text-xs text-gray-600 dark:text-gray-300"><div><span className="block text-[10px] text-gray-400 dark:text-gray-500">城市/地区</span>{e.location?.city}, {e.location?.state}</div><div><span className="block text-[10px] text-gray-400 dark:text-gray-500">时区 & 时间</span>{e.location?.timezone} ({o(e.location?.timezone)})</div></div></div></div></div>},IpCard=({title:e,type:t,delay:a=0,accent:r})=>{const[s,n]=useState({ip:"Initializing...",status:"loading"}),[o,l]=useState(null),[i,d]=useState(!1);useEffect(()=>{const e=async()=>{await new Promise(e=>setTimeout(e,a));let e=null;try{if("domestic"===t)try{const t=await fetch("https://myip.ipip.net/json"),a=await t.json();e=a.data.ip}catch(r){try{const t=await fetch("https://ipapi.co/json/"),a=await t.json();e=a.ip}catch(s){e="Error"}}else if("foreign"===t){const t=await fetch("https://ipinfo.io/json"),a=await t.json();e=a.ip}else{const t=await fetch("https://api.ip.sb/jsonip"),a=await t.json();e=a.ip}n({ip:e,status:"ok"}),e&&"Error"!==e&&(d(!0),fetch(\`https://api.ipapi.is?q=\${e}\`).then(e=>e.json()).then(e=>{l(e),d(!1)}).catch(()=>d(!1)))}catch(o){n({ip:"Connection Failed",status:"error"})}};e()},[]);const c="error"===s.status,m="loading"===s.status;return<div className="glass-card rounded-2xl p-6 relative overflow-hidden animate-slide-up h-full flex flex-col" style={{animationDelay:\`\${a}ms\`}}><div className={\`absolute top-0 left-0 w-full h-1 bg-\${r}-500\`}></div><div className="scan-line"></div><div className="flex justify-between items-start mb-3"><h3 className={\`text-xs font-bold uppercase tracking-widest flex items-center gap-2 text-\${r}-600 dark:text-\${r}-400\`}> <span className={\`w-2 h-2 rounded-full bg-\${r}-500 shadow-neon\`}></span>{e}</h3>{m&&<div className="w-3 h-3 border-2 border-gray-300 dark:border-gray-600 border-t-transparent rounded-full animate-spin"></div>}</div><div className="mb-2">{m?<div className="h-8 w-3/4 bg-gray-100 dark:bg-gray-700 rounded animate-pulse"></div>:<div className={\`text-2xl font-mono font-bold tracking-tight break-all \${c?"text-rose-500 dark:text-rose-400":"text-gray-800 dark:text-gray-100"}\`}>{s.ip}</div>}</div>{!c&&!m&&<div className="flex-1"><RiskReport data={o} loading={i}/></div>}</div>},NetworkHeader=({theme:e,toggleTheme:t})=>{const[a,r]=useState(null);return useEffect(()=>{navigator.connection&&r({type:navigator.connection.effectiveType,rtt:navigator.connection.rtt,saveData:navigator.connection.saveData})},[]),<header className="mb-10 flex flex-col md:flex-row md:items-center justify-between gap-4 animate-slide-up"><div className="flex items-center gap-4"><div className="relative"><div className="w-12 h-12 bg-white dark:bg-slate-800 rounded-xl shadow-glass flex items-center justify-center text-primary relative z-10"><svg className="w-7 h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg></div><div className="absolute inset-0 bg-primary/20 blur-xl rounded-full"></div></div><div><h1 className="text-3xl font-bold text-gray-800 dark:text-white tracking-tight">IPcheck</h1><p className="text-xs text-gray-500 dark:text-gray-400 font-mono flex items-center gap-2"><span>{window.CF_DATA.colo} • {window.CF_DATA.country}</span></p></div></div><div className="flex items-center gap-3"><button onClick={t} className="glass-card w-9 h-9 flex items-center justify-center rounded-full text-gray-600 dark:text-gray-300 hover:text-primary transition-colors">{"dark"===e?<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg>:<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg>}</button><div className="glass-card px-4 py-2 rounded-full flex items-center gap-4 text-xs font-mono text-gray-600 dark:text-gray-300 shadow-sm"><div className="flex items-center gap-1.5"><span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse-glow"></span><span className="hidden sm:inline">Protocol:</span> {window.CF_DATA.http}</div><div className="w-px h-3 bg-gray-300 dark:bg-gray-600"></div><div><span className="hidden sm:inline">TLS:</span> {window.CF_DATA.tls}</div>{a&&<><div className="w-px h-3 bg-gray-300 dark:bg-gray-600"></div><div><span className="hidden sm:inline">Speed Level:</span> {a.type.toUpperCase()}</div></>}</div></div></header>},Fingerprint=()=>{const[e,t]=useState(null);if(useEffect(()=>{t({ua:navigator.userAgent,lang:navigator.language,platform:navigator.platform,cores:navigator.hardwareConcurrency||"Unknown",memory:navigator.deviceMemory?\`~\${navigator.deviceMemory}GB\`:"Unknown",cookies:navigator.cookieEnabled?"Enabled":"Disabled",screen:\`\${window.screen.width}x\${window.screen.height} (\${window.screen.colorDepth}-bit)\`,gpu:function(){try{const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl"),a=t.getExtension("WEBGL_debug_renderer_info");return a?t.getParameter(a.UNMASKED_RENDERER_WEBGL):"Unknown"}catch(r){return"Unknown"}}(),canvasHash:function(){try{const e=document.createElement("canvas"),t=e.getContext("2d");return t.fillText("Cloudflare",2,2),e.toDataURL().slice(-10)}catch(a){return"Err"}}()})},[]),!e)return null;const a=({label:e,val:t,icon:a})=><div className="bg-gray-50/50 dark:bg-slate-800/50 rounded-lg p-2.5 border border-gray-100 dark:border-slate-700 hover:bg-white dark:hover:bg-slate-800 transition-colors"><div className="text-[10px] text-gray-400 dark:text-gray-500 uppercase font-bold mb-1 flex items-center gap-1">{a&&<span>{a}</span>}{e}</div><div className="text-xs font-mono text-gray-700 dark:text-gray-300 break-words font-medium">{t}</div></div>;return<div className="glass-card rounded-2xl p-6 relative overflow-hidden animate-slide-up" style={{animationDelay:"600ms"}}><h3 className="text-sm font-bold text-gray-600 dark:text-gray-300 uppercase tracking-widest mb-4 flex items-center gap-2"><svg className="w-4 h-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 11c0 3.517-1.009 6.799-2.753 9.571m-3.44-2.04l.054-.09A13.916 13.916 0 008 11a4 4 0 118 0c0 1.017-.07 2.019-.203 3m-2.118 6.844A21.88 21.88 0 0015.171 17m3.839 1.132c.645-2.266.99-4.659.99-7.131A8 8 0 008 2.855"/></svg>指纹检测</h3><div className="grid grid-cols-2 md:grid-cols-4 gap-3"><div className="col-span-2 md:col-span-4"><a label="User Agent" val={e.ua}/></div><a label="GPU 渲染器" val={e.gpu}/><a label="系统平台" val={e.platform}/><a label="CPU 核心" val={e.cores}/><a label="设备内存" val={e.memory}/><a label="屏幕参数" val={e.screen}/><a label="系统语言" val={e.lang}/><a label="Cookies" val={e.cookies}/><a label="Canvas Hash" val={e.canvasHash}/></div></div>},App=()=>{const[e,t]=useState(()=>"undefined"!=typeof document&&document.documentElement.classList.contains("dark")?"dark":"light");return useLayoutEffect(()=>{const t=window.document.documentElement;"dark"===e?t.classList.add("dark"):t.classList.remove("dark"),localStorage.setItem("theme",e)},[e]),<div className="pt-2"><NetworkHeader theme={e} toggleTheme={()=>t(t=>"dark"===t?"light":"dark")}/><section className="mb-8 animate-slide-up" style={{animationDelay:"100ms"}}><div className="grid grid-cols-2 md:grid-cols-5 gap-3"><PingCard index={0} name="Bilibili" url="https://i0.hdslb.com/bfs/face/member/noface.jpg" icon="https://www.bilibili.com/favicon.ico"/><PingCard index={1} name="WeChat" url="https://res.wx.qq.com/a/wx_fed/assets/res/NTI4MWU5.ico" icon="https://res.wx.qq.com/a/wx_fed/assets/res/NTI4MWU5.ico"/><PingCard index={2} name="Google" url="https://www.google.com/favicon.ico" icon="https://www.google.com/favicon.ico"/><PingCard index={3} name="Cloudflare" url="https://www.cloudflare.com/favicon.ico" icon="https://www.cloudflare.com/favicon.ico"/><PingCard index={4} name="GitHub" url="https://github.github.io/janky/images/bg_hr.png" icon="https://github.com/favicon.ico"/><PingCard index={5} name="YouTube" url="https://i.ytimg.com/vi/M7lc1UVf-VE/mqdefault.jpg" icon="https://www.youtube.com/favicon.ico"/><PingCard index={6} name="OpenAI" url="https://openai.com/favicon.ico" icon="https://openai.com/favicon.ico"/><PingCard index={7} name="Telegram" url="https://telegram.org/img/t_logo.png" icon="https://telegram.org/favicon.ico"/><PingCard index={8} name="Netflix" url="https://assets.nflxext.com/us/ffe/siteui/common/icons/nficon2016.ico" icon="https://assets.nflxext.com/us/ffe/siteui/common/icons/nficon2016.ico"/><PingCard index={9} name="Apple" url="https://www.apple.com/favicon.ico" icon="https://www.apple.com/favicon.ico"/></div></section><div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8 animate-slide-up" style={{animationDelay:"200ms"}}><DualStackCard type="v4" color="blue"/><DualStackCard type="v6" color="purple"/></div><div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"><IpCard title="国内出口" type="domestic" delay={300} accent="blue"/><IpCard title="国外出口" type="foreign" delay={400} accent="amber"/><IpCard title="Cloudflare" type="cloudflare" delay={500} accent="primary"/></div><Fingerprint/><footer className="text-center text-gray-400 dark:text-gray-600 text-[10px] py-6 font-mono border-t border-gray-200/50 dark:border-gray-800 mt-12"><p className="flex justify-center items-center gap-2"><span><a href="https://github.com/jianmo250/IPcheck-workers">IPcheck-workers</a></span><span className="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></span></p></footer></div>},DualStackCard=({type:e,color:t})=>{const[a,r]=useState(null);useEffect(()=>{const t=async()=>{const t="v4"===e?[{url:"https://api.ipify.org?format=json",key:"ip"},{url:"https://api-ipv4.ip.sb/jsonip",key:"ip"},{url:"https://myip.ipip.net/json",key:"data.ip"},{url:"https://ipv4.icanhazip.com",format:"text"}]:[{url:"https://api6.ipify.org?format=json",key:"ip"},{url:"https://api-ipv6.ip.sb/jsonip",key:"ip"},{url:"https://ipv6.icanhazip.com",format:"text"}];for(const e of t)try{const t=new AbortController,s=setTimeout(()=>t.abort(),2e3),n=await fetch(e.url,{signal:t.signal});if(clearTimeout(s),n.ok){let t;"text"===e.format?t=await n.text():(t=await n.json(),t=e.key.includes(".")?e.key.split(".").reduce((e,t)=>(e||{})[t],t):t[e.key]);if(t){r(t.trim());return}}}catch(a){continue}r("N/A")};t()},[e]);const s="blue"===t?"border-blue-500":"border-purple-500",n="v4"===e?"IPv4 Connectivity":"IPv6 Connectivity";return<div className={\`glass-card border-l-[3px] \${s} rounded-r-xl p-4 flex items-center justify-between relative overflow-hidden group\`}> <div className="z-10"><div className="text-[10px] text-gray-400 dark:text-gray-500 font-bold uppercase tracking-wider mb-1">{n}</div><div className="font-mono font-bold text-gray-800 dark:text-gray-100 text-sm break-all">{a||<span className="animate-pulse bg-gray-200 dark:bg-gray-700 text-transparent rounded">Loading IP Address...</span>}</div></div><div className={\`absolute -right-4 -bottom-4 w-24 h-24 bg-\${t}-400/10 rounded-full blur-xl group-hover:scale-150 transition-transform duration-500\`}></div></div>};createRoot(document.getElementById("root")).render(<App/>)</script></body></html>`}