Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A single-page, dependency-light web calendar showing competitive Pokémon events (TCG, VGC, GO, prereleases, community) from six public Google Calendars. Plain HTML/CSS/JS — no framework, no build step. Deployed on GitHub Pages and embedded into carrd.co pages as an auto-sizing iframe widget.查看完整 README ↗
A single-page, dependency-light web calendar showing competitive Pokémon events (TCG, VGC, GO, prereleases, community) from six public Google Calendars. Plain HTML/CSS/JS — no framework, no build step. Deployed on GitHub Pages and embedded into carrd.co pages as an auto-sizing iframe widget.
Live: https://pizzacatz.github.io/pokemon-calendar-webapp/
pokedata.ovh ICS feeds
│ (Google Apps Script sync, daily — lives in the private
│ pizzacatz/pokemon-calendar repo; copies in *.gs here)
▼
6 public Google Calendars ──Google Calendar API──▶ this app (FullCalendar 6.1.21)
│
▼
GitHub Pages ─▶ carrd.co iframes
| File | Role |
|---|---|
index.html | page shell, CDN script tags, filter panel + modal markup |
app.js | config, calendar setup, filtering, custom week view, modals, embed plumbing |
styles.css | dark theme (#1A1A1A / #1F1F1F / gold #FFD180), mobile rules |
pokemon_calendar_sync*.gs | reference copies of the Apps Script pipeline (not used by the app) |
pokemon-events-calendar-PRD.md | original spec + addendum of post-launch changes |
app.js)GOOGLE_CALENDAR_API_KEY — public by design; must stay restricted in
Google Cloud Console to the Calendar API + HTTP referrers
(pizzacatz.github.io/*, localhost:8000/*).DISPLAY_TIME_ZONE — fixed America/New_York; times are labeled "ET".CALENDARS — one entry per category (id, chip label, color, Google Calendar
ID). Add/remove categories by editing only this list.Every calendar must be public with "See all event details" — the free/busy-only sharing level strips titles/locations and events render as "(untitled)".
Important: carrd "pages" are sections of ONE HTML document, so every embed
on the site coexists in the same DOM. Never target the iframe by id (ids
collide and all height messages land on the first iframe — some embeds stay
clipped, others inflate with empty space). Match by e.source instead.
Each embed is just an iframe (vary view=/cats= per page):
<iframe
src="https://pizzacatz.github.io/pokemon-calendar-webapp/?embed=1"
style="width:100%; height:900px; border:0;"
scrolling="no"
allow="clipboard-write"
title="Pokémon Events Calendar"></iframe>
Plus this listener once anywhere on the site (per-embed duplicates are harmless — it routes each message to the iframe that sent it):
<script>
window.addEventListener('message', function (e) {
if (e.origin !== 'https://pizzacatz.github.io') return;
if (!e.data || e.data.type !== 'pokecal:height') return;
document.querySelectorAll('iframe').forEach(function (f) {
if (f.contentWindow === e.source) f.style.height = e.data.height + 'px';
});
});
</script>
The app posts its content height (pokecal:height) whenever it changes —
view switches, data loads, modals opening/closing — so each iframe grows AND
shrinks to fit and the page never double-scrolls. The 900px is only a
pre-load fallback.
| Param | Values | Effect |
|---|---|---|
embed=1 | — | bare widget: hides the app's own header/footer |
view= | month, week, list (alias agenda) | initial view; default month |
cats= | comma list of tcg-cups, tcg-challenges, vgc, go, prerelease(s), community | pre-activates those filter chips at load (visitors can still change them) |
Examples for dedicated pages:
TCG page (month): ?embed=1&view=month&cats=tcg-cups,tcg-challenges
VG/GO page (agenda): ?embed=1&view=agenda&cats=vgc,go
Prerelease page (agenda): ?embed=1&view=agenda&cats=prereleases
Everything (default): ?embed=1
Any number of widgets can coexist — the e.source-matching listener above
routes each height message to its own iframe automatically.
docs/VOCABULARY.md → "UI names".<…> so Discord shows no preview). The official link is the first non-image
URL in the description.
Uses navigator.clipboard with an execCommand('copy') fallback, so it
works inside cross-origin iframes even without allow="clipboard-write"., US, , City/US tail.Visitors submit events through a Google Form; the owner approves them in the
linked response sheet; an Apps Script (community_event_form.gs) publishes
approved rows to the Community Events calendar, which the widget already
displays. Nothing goes live without approval.
Form questions — titles must match community_event_form.gs's Q map exactly:
| Question title | Type | Required |
|---|---|---|
Game | Multiple choice (TCG / VGC / GO / Other) | no (becomes the title prefix) |
Event name | Short answer | yes |
Event Date | Date | yes |
Start Time | Time | no (blank = all-day event) |
End Time | Time | no (blank = start + 2h) |
Venue name | Short answer | yes (goes in the title: "… @ VENUE") |
Venue Address | Short answer | yes |
Description | Paragraph | no |
Event link | Short answer | no |
Image url | Short answer | no (renders in the event popup) |
Published titles follow the site convention GAME Event name @ VENUE, and
the location field is Venue name, Venue Address.
Setup: create the form → link responses to a new spreadsheet → in that
spreadsheet Extensions → Apps Script → paste community_event_form.gs →
set the project time zone to America/New_York (Project Settings) → run
setup() once and authorize. Recommended form settings: collect email
addresses (verified) to deter spam.
Moderation: each submission emails NOTIFY_EMAIL and sits at
PENDING. In the sheet, set Status to APPROVED to publish (script fills
in the Event ID and flips it to PUBLISHED), REJECTED to decline, or
REMOVE on a published row to delete the event. The sheet's
"Community events → Process all rows now" menu re-sweeps everything if a
trigger is ever missed.
python3 -m http.server 8000 # serve from the repo root
# http://localhost:8000 (localhost:8000 must be in the API key's referrer list)
Deploy = git push — the "Deploy to GitHub Pages" Actions workflow
(.github/workflows/pages.yml) publishes the repo as-is, typically in under
a minute. Check on a deploy with gh run list. (The legacy Jekyll Pages
build was abandoned in July 2026 after repeated 20-minute stalls and opaque
"Page build failed" errors.)
timeZone and no timezone plugin,
FullCalendar's event.start/end are Dates whose UTC fields hold the
Eastern wall time. Format with timeZone:'UTC' and label "ET" manually;
formatting with America/New_York double-shifts.body.scrollHeight misses the last element's collapsed
bottom margin and floors fractional heights — report +16px or the bottom
border clips. Modals are position:fixed (invisible to body height), so
they're measured separately.fixed + centered = middle of the whole
grown iframe, not the visitor's screen. The app anchors modal boxes to the
last click's Y position when embedded.isConnected.MouseEvents can lose coordinates in
iframes; only trusted input proves click-anchoring.