/* eslint-disable */ // ───────────────────────────────────────────────────────────── // searchgg · 메인 홈 (레트로 구조형 · 올리브 포인트 · 각진 패널 레이아웃) // 공지/업데이트/이벤트 전면 · 이벤트 카드 이미지 슬롯 // window.Home // ───────────────────────────────────────────────────────────── const { useState: useStateH } = React; const PT = '#48515f'; // 올리브/카키 포인트 const PT_SOFT = 'rgba(72,81,95,.12)'; const HEAD = '#f1f3f5'; // 패널 헤더바 배경 const CH = "'Chakra Petch',sans-serif"; const panel = { border: '1px solid var(--line2)', background: '#fff', borderRadius: 5 }; // 패널 (채워진 헤더바 + 보더) function Panel({ title, en, right, children, bodyPad = '8px 14px 12px' }) { return (
{title} {en && {en}}
{right}
{children}
); } // 세그먼트 탭 (각진) function Seg({ tabs, value, onChange }) { return (
{tabs.map((t, i) => { const on = value === t; return ( ); })}
); } // ── 상단 유틸 바 ── function TopBar() { return (
{['로그인', '회원가입', '쿠폰등록', '고객센터'].map((t, i) => ( {i > 0 && } {t} ))}
); } // ── 메인 네비(GNB) ── function Nav({ onLogin, onClan, onCommunity, active = '홈' }) { const items = ['홈', '전적검색', '커뮤니티', '클랜']; return (
); } // ── 검색 히어로(구조형 밴드) ── function Hero({ onPick }) { const SA = window.SA, me = SA.me; return (
SUDDEN ATTACK RECORD SEARCH

전적 검색

어서와요, {me.name}
); } // ── 섹션 헤더(채워진 바) ── function BarHead({ title, en, more }) { return (
{title} {en && {en}}
{more && 전체보기 +}
); } // ── 진행중인 이벤트 (캐러셀) ── function EventStrip() { const SA = window.SA; const PER = 4; const pages = Math.ceil(SA.events.length / PER); const [page, setPage] = useStateH(0); const [hover, setHover] = useStateH(false); React.useEffect(() => { if (hover || pages <= 1) return; const t = setInterval(() => setPage((p) => (p + 1) % pages), 5000); return () => clearInterval(t); }, [hover, pages]); const go = (d) => setPage((p) => (p + d + pages) % pages); const arrow = (dir) => ( ); return (
setHover(true)} onMouseLeave={() => setHover(false)}>
진행중인 이벤트 ON-GOING EVENT
{page + 1} / {pages} {arrow('L')}{arrow('R')}
{Array.from({ length: pages }).map((_, pi) => (
{SA.events.slice(pi * PER, pi * PER + PER).map((e, i) => { const gi = pi * PER + i; const urgent = e.dday.startsWith('D-') && +e.dday.slice(2) <= 3; return (
{e.tag} {e.dday}
{e.title}
{e.sub}
{e.period}
); })}
))}
{Array.from({ length: pages }).map((_, i) => (
); } const rowDiv = (i, n) => ({ borderBottom: i < n - 1 ? '1px solid #eaecef' : 'none' }); // ── 지금 방송 중 LIVE (치지직 / 숲 / 유튜브) ── function StreamLive({ onPick }) { const SA = window.SA; const [tab, setTab] = useStateH('전체'); const list = tab === '전체' ? SA.streams : SA.streams.filter((s) => s.platform === tab); const totalView = SA.streams.reduce((a, s) => a + s.viewers, 0); return ( }>
LIVE {list.length}개 방송 · 시청자 {SA.fmt(totalView)}
{list.map((s, i) => { const pf = SA.streamPlatforms[s.platform]; const player = SA.allPlayers.find((p) => p.name === s.streamer); return ( ); })}
); } // ── SA 소식 ── function SANews() { const SA = window.SA; const [tab, setTab] = useStateH('공지사항'); const rows = SA.news[tab]; return ( } bodyPad="2px 14px 6px"> {rows.map((r, i) => (
{r.date} {r.title}
))}
); } // ── 커뮤니티 ── function Community({ onAll }) { const SA = window.SA; const rows = [...SA.community['자유'], ...SA.community['공략']] .sort((a, b) => (b.hot ? 1 : 0) - (a.hot ? 1 : 0)) .slice(0, 6); return ( 전체 보기 } bodyPad="2px 14px 6px"> {rows.map((p, i) => (
{p.tag} {p.title} {p.hot && HOT} {p.cmt} {p.time}
))}
); } // ── 내 전적 요약 ── function MeCard({ onPick }) { const SA = window.SA, me = SA.me; const [scope, setScope] = useStateH('통합'); const rankNo = scope === '통합' ? me.rankNoTotal : me.rankNoSeason; const selRank = scope === '통합' ? me.rankTotal : me.rankSeason; return ( }>
{me.name} {me.clan}
{scope} 랭킹 {SA.fmt(rankNo)}
{[['승·패', `${me.wins}/${me.losses}`], ['승률', me.wr + '%'], ['킬뎃', SA.kdPct(me.kda) + '%']].map(([k, v], i) => (
{k}
{v}
))}
); } // ── SA 랭킹 (5종 · 각 top10) ── const SA_CATS = ['통합 계급', '시즌 계급', '랭크전', '공식 클랜', '클랜']; function RankRow({ i, onClick, badge, name, tag, sub, value, unit }) { return ( ); } // ── 즐겨찾기 (페이지네이션) ── function Favorites({ onPick }) { const SA = window.SA; const all = SA.favorites; const PER = 5; const pages = Math.ceil(all.length / PER); const [page, setPage] = useStateH(0); const start = page * PER; const view = all.slice(start, start + PER); return ( {all.length}명} bodyPad="0">
{view.map((f, i) => ( ))}
{Array.from({ length: pages }).map((_, i) => ( ))}
); } function pgBtn(disabled) { return { width: 26, height: 26, borderRadius: 4, border: '1px solid var(--line2)', background: '#fff', color: disabled ? 'var(--line2)' : 'var(--t2)', cursor: disabled ? 'default' : 'pointer', fontFamily: "'Chakra Petch',sans-serif", fontWeight: 700, fontSize: 14 }; } function SARanking({ onPick, onClan }) { const SA = window.SA; const [cat, setCat] = useStateH('통합 계급'); const [mode, setMode] = useStateH('솔로'); const tcol = Object.fromEntries(SA.tiers.map((t) => [t.name, t.color])); const isClass = cat === '시즌 계급' || cat === '통합 계급'; const isRanked = cat === '랭크전'; const isRankedUser = isRanked && mode !== '클랜'; const isRankedClan = isRanked && mode === '클랜'; const isClan = cat === '공식 클랜' || cat === '클랜'; const classList = cat === '시즌 계급' ? SA.seasonClassRanking : SA.totalClassRanking; const contentList = mode === '솔로' ? SA.soloRpRanking : SA.partyRpRanking; const clanList = cat === '공식 클랜' ? SA.officialClanRanking : SA.generalClanRanking; return ( TOP 10} bodyPad="11px 0 0"> {/* 카테고리 선택 */}
{SA_CATS.map((c) => { const on = c === cat; return ( ); })}
{/* 랭크전 하위 토글 */} {isRanked && (
{['솔로', '파티', '클랜'].map((t, i) => { const on = mode === t; return ( ); })}
)} {/* 계급 랭킹 */} {isClass && classList.map((e, i) => { const p = SA.allPlayers.find((x) => x.name === e.name); return ( p && onPick(p)} badge={p ? : null} tag={p && p.clan} name={e.name} sub={p && p.rank.name} value={SA.fmt(e.score)} unit="점" /> ); })} {/* 랭크전(솔로/파티) 랭킹 */} {isRankedUser && contentList.map((e, i) => { const p = SA.allPlayers.find((x) => x.name === e.name); const col = tcol[e.tier] || PT; return ( p && onPick(p)} badge={
{e.tier[0]}
} tag={p && p.clan} name={e.name} sub={{e.tier}} value={SA.fmt(e.rp)} unit="RP" /> ); })} {/* 랭크전(클랜) 랭킹 — 클랜 정보 */} {isRankedClan && SA.clanRpRanking.map((c, i) => ( onClan && onClan(c.name)} badge={
{c.tag}
} name={c.name} sub={`${c.members}명`} value={SA.fmt(c.rp)} unit="RP" /> ))} {/* 클랜 랭킹 */} {isClan && clanList.map((c, i) => ( onClan && onClan(c.name)} badge={
{c.tag}
} name={{c.name}{cat === '공식 클랜' && 인증}} sub={`${c.members}명`} value={SA.fmt(c.rp)} unit="RP" /> ))}
); } // ── 인기 검색 랭킹(가장 많이 조회된 유저) ── function SearchRank({ onPick }) { const SA = window.SA; const trend = (m) => { if (m === 'new') return NEW; if (m === 0) return ; const up = m > 0; return {up ? '▲' : '▼'}{Math.abs(m)}; }; return ( 최근 24시간} bodyPad="4px 0 0"> {SA.searchTrending.map((s, i) => { const p = SA.allPlayers.find((x) => x.name === s.name); return ( ); })} ); } // ── 시즌 현황 ── function SeasonCard() { const SA = window.SA, s = SA.season; const [mapTab, setMapTab] = useStateH('5vs5'); const maps = mapTab === '5vs5' ? s.maps5v5 : s.maps3v3; return ( {s.dday}} bodyPad="14px 14px">
S2
{s.name}
{s.period} 종료
시즌 진행{s.progress}%
시즌 맵
{['5vs5', '3vs3'].map((t, i) => { const on = mapTab === t; return ( ); })}
{maps.map((m) => {m})}
); } // ── 폼 좋은 유저 (연승 / 승률 / 킬뎃 탭) ── function HotStreak({ onPick }) { const SA = window.SA; const [tab, setTab] = useStateH('연승'); let rows; if (tab === '연승') { rows = SA.hotStreak.map((e) => ({ p: SA.allPlayers.find((x) => x.name === e.name), streak: e.streak })); } else if (tab === '승률') { rows = [...SA.allPlayers].sort((a, b) => b.wr - a.wr).slice(0, 6).map((p) => ({ p })); } else { rows = [...SA.allPlayers].sort((a, b) => b.kda - a.kda).slice(0, 6).map((p) => ({ p })); } const metric = (p, streak) => { if (tab === '연승') return ( {streak}연승 ); if (tab === '승률') return {p.wr}%; return {SA.kdPct(p.kda)}%; }; return ( } bodyPad="12px 14px 14px">
{rows.map(({ p, streak }, i) => p && ( ))}
); } // ── 오늘의 전장 ── function LiveStats() { const SA = window.SA, L = SA.liveStats; return (
{SA.fmt(L.totalMatches)} 매치 ▲ {L.prevDelta}%
{L.matchModes.map(({ name, count }) => (
{name} {SA.fmt(count)}
))}
오늘 제재 {L.bannedToday}명
); } function Footer() { return (
searchgg는 서든어택 전적 조회를 위한 비공식 팬 사이트입니다. 본 페이지의 데이터는 데모용 예시입니다.
© 2026 searchgg
); } // ── 모집 중인 클랜 (포스터) ── function RecruitPosters({ onPlaza, onOpenClan }) { let pool = window.ClanRecruits ? window.ClanRecruits() : []; try { if (localStorage.getItem('sa-my-recruit-active') === '0') pool = pool.filter((c) => c.name !== (window.SA.me.clan || '')); } catch (e) {} const list = pool.slice().sort((a, b) => b.hot - a.hot).slice(0, 4); if (!list.length) return null; return ( 전체 보기 } bodyPad="14px 14px">
{list.map((rc) => (
{rc.name}
랭킹 {rc.rank}위 · {rc.openings}명 모집
))}
); } function Home() { const [sel, setSel] = useStateH(null); const [login, setLogin] = useStateH(false); const [clan, setClan] = useStateH(null); const [plaza, setPlaza] = useStateH(false); const [community, setCommunity] = useStateH(false); return (
); } Object.assign(window, { Home, TopBar, Nav, Footer, Panel, Seg, PT, CH });