BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2,或任何藍牙控制器搭配 MyWhoosh、Rouvy、Zwift 等。可於 iOS、Android、Windows 與 macOS 免費試用。
AI 翻譯
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證chrismiller2022-collab/YCPR
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
import { useMemo } from "react"; import ConfLink from "../components/ConfLink"; import TeamLogo from "../components/TeamLogo"; import { BracketGame } from "./BracketPage"; import { buildFCS24Field, pairFirstRoundNoConfConflict, playGame, reseedAndPair } from "../lib/bracket24"; import { useWeeklyStats } from "../lib/api/weeklyStats"; export default function FCSBracketPage({ onNavigateTeam, onNavigateConference, onHome }: any) { const field = useMemo(() => buildFCS24Field(), []); const { byTeam: liveByTeam } = useWeeklyStats("latest"); FCS FCS PLAYOFF BRACKET檢視完整 README ↗
import { useMemo } from "react"; import ConfLink from "../components/ConfLink"; import TeamLogo from "../components/TeamLogo"; import { BracketGame } from "./BracketPage"; import { buildFCS24Field, pairFirstRoundNoConfConflict, playGame, reseedAndPair } from "../lib/bracket24"; import { useWeeklyStats } from "../lib/api/weeklyStats";
export default function FCSBracketPage({ onNavigateTeam, onNavigateConference, onHome }: any) { const field = useMemo(() => buildFCS24Field(), []); const { byTeam: liveByTeam } = useWeeklyStats("latest");
if (field.length < 24) { return ( ‹ All rankings FCS FCS PLAYOFF BRACKET Not enough FCS teams yet to build a full 24-team field. ); }
const byes = field.slice(0, 8); const firstRoundField = field.slice(8, 24);
const r1Pairs = pairFirstRoundNoConfConflict(firstRoundField); const r1Winners = r1Pairs.map((p) => playGame(p.host, p.away, false, liveByTeam));
const r2Pool = [...byes, ...r1Winners]; const r2Pairs = reseedAndPair(r2Pool); const r2Winners = r2Pairs.map((p) => playGame(p.host, p.away, false, liveByTeam));
const qfPairs = reseedAndPair(r2Winners); const qfWinners = qfPairs.map((p) => playGame(p.host, p.away, false, liveByTeam));
const sfPairs = reseedAndPair(qfWinners); const sfWinners = sfPairs.map((p) => playGame(p.host, p.away, false, liveByTeam));
const champPair = reseedAndPair(sfWinners)[0]; const champion = playGame(champPair.host, champPair.away, true, liveByTeam);
return ( ‹ All rankings FCS FCS PLAYOFF BRACKET Top 24 FCS teams seeded purely by Power Rating (conference auto-bids and resume-based at-large selection aren't modeled for FCS yet). Top 8 seeds get a bye; the better seed hosts every round except a neutral-site championship. Projected champion:{" "} <strong style={{ color: "var(--gold)" }}>{champion.team.team}.
<div className="bracket-body">
<div className="bracket-columns">
<div className="bracket-col">
<div className="section-label bracket-round-label">First Round</div>
<div className="bracket-col-games">
{r1Pairs.map((p) => (
<BracketGame
key={p.host.seed}
seedA={p.host.seed}
teamA={p.host.team}
seedB={p.away.seed}
teamB={p.away.team}
onNavigateTeam={onNavigateTeam}
/>
))}
</div>
</div>
<div className="bracket-col">
<div className="section-label bracket-round-label">Second Round</div>
<div className="bracket-col-games">
{r2Pairs.map((p) => (
<BracketGame
key={p.host.seed}
seedA={p.host.seed}
teamA={p.host.team}
seedB={p.away.seed}
teamB={p.away.team}
onNavigateTeam={onNavigateTeam}
/>
))}
</div>
</div>
<div className="bracket-col">
<div className="section-label bracket-round-label">Quarterfinals</div>
<div className="bracket-col-games">
{qfPairs.map((p) => (
<BracketGame
key={p.host.seed}
seedA={p.host.seed}
teamA={p.host.team}
seedB={p.away.seed}
teamB={p.away.team}
onNavigateTeam={onNavigateTeam}
/>
))}
</div>
</div>
<div className="bracket-col">
<div className="section-label bracket-round-label">Semifinals</div>
<div className="bracket-col-games">
{sfPairs.map((p) => (
<BracketGame
key={p.host.seed}
seedA={p.host.seed}
teamA={p.host.team}
seedB={p.away.seed}
teamB={p.away.team}
onNavigateTeam={onNavigateTeam}
/>
))}
</div>
</div>
<div className="bracket-col">
<div className="section-label bracket-round-label">Championship</div>
<div className="bracket-col-games">
<BracketGame
seedA={champPair.host.seed}
teamA={champPair.host.team}
seedB={champPair.away.seed}
teamB={champPair.away.team}
neutral
onNavigateTeam={onNavigateTeam}
/>
</div>
</div>
</div>
<div className="section-label bracket-round-label">The Field</div>
<div className="table-wrap bracket-natty-wrap playoff24-field-wrap">
<div className="table-scroll">
<table>
<thead>
<tr>
<th className="th">Seed</th>
<th className="th">Team</th>
<th className="th">Conference</th>
<th className="th">Bid</th>
<th className="th th-right">Power Rating</th>
</tr>
</thead>
<tbody>
{field.map((f) => (
<tr key={f.team.team}>
<td>
<span
className={`rank-flag ${f.seed <= 8 ? "top4" : f.seed <= 16 ? "top12" : ""}`}
>
{f.seed}
</span>
</td>
<td>
<button
className="team-link"
onClick={() => onNavigateTeam(f.team)}
>
<TeamLogo team={f.team} />
{f.team.team}
</button>
</td>
<td className="conf-cell">
<ConfLink conf={f.team.conf} onNavigateConference={onNavigateConference} />
</td>
<td className="futures-bet-cell">{f.bid}</td>
<td className={`rating-cell ${f.team.rating < 0 ? "rating-good" : "rating-bad"}`}>
{f.team.rating > 0 ? "+" : ""}
{f.team.rating.toFixed(2)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
<div className="footer-note">
Seeding is by Power Rating alone for now — conference auto-bids and
resume-based at-large selection will be added once FCS resume
ratings and conference futures data are wired up. First round
pairings avoid same-conference matchups where possible; every later
round reseeds the remaining field, pairing the best seed against the
worst, with the better seed hosting until a neutral-site
championship.
</div>
</div>
); }