Bygga
Type the product name from the box. Bygga shows every assembly step in 3D, with the parts, screws and tools for each one, and reads it out loud.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Eats Ranked: landing page for a family of free state restaurant apps built from public inspection records. Static site, generated by Python.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗The landing page for Eats Ranked: free restaurant apps, one state at a time, built from public records.
It links each state's app and website (the live states are the "status": "live" entries in tools/site-data.json),
shows a hex-tile U.S. map of where we're live, explains how the apps work, answers common questions, and has a short
"Eating out, by the numbers" section from the Bureau of Labor Statistics.
The site is one static page served by GitHub Pages from docs/ at https://eatsranked.com/.
It makes no requests to other hosts (no fonts, CDNs or analytics), sets no cookies and needs no build
step on the server: styles, script, map and chart are inline in docs/index.html.
docs/ what GitHub Pages serves
index.html generated by tools/build.py (don't edit by hand)
404.html, sitemap.xml, robots.txt, CNAME, site.webmanifest, .nojekyll, .well-known/security.txt also written by build.py
icons/ each state app's icon (256x256 PNG) and the WebP copy of it that the page loads (make_images.py)
favicon.svg, favicon.ico, favicon-32.png, apple-touch-icon.png, icon-192.png, icon-512.png, og.png from make_images.py
tools/
site-data.json the single source of truth: states, taglines, links, App Store status, colours, icons, BLS prices
us-states-paths.json state names and codes (the map itself is a hex-tile layout, HEX_ROWS in build.py)
template.html, app.js, template-404.html the page template and its script
build.py site-data.json + template -> docs/
update_prices.py refreshes the BLS series in site-data.json, then rebuilds
make_images.py favicons, the 1200x630 share image and the WebP icons
verify.py recomputes every number from site-data.json and checks the page
browser_check.mjs headless-Chrome checks (layout 360-1600 px, map keyboard/hover/tap, no outside requests)
tools/site-data.json is the canonical copy of the site data from now on. It started as a copy of the
hub's site-data.json (the two were identical at hand-off, including Illinois' "region": "Chicago + Illinois");
edit this one, not the old hub file.
python3 tools/build.py # Python 3.9+, standard library only
python3 tools/build.py --data some.json --dry-run # does the page build from this data? writes nothing
python3 tools/verify.py # static checks, then serves docs/ locally and fetches every link
python3 tools/verify.py --browser # also runs tools/browser_check.mjs (Node 22+ and Google Chrome)
build.py only moves the sitemap's lastmod when index.html actually changes. Every number on the page
(the three stats, the $20 comparison, the chart, its table and hover readout) is computed from the BLS
series in site-data.json; verify.py recomputes them independently and fails if any number on the page
isn't one of them, a year, or a number that is in site-data.json itself.
To look at it locally: python3 -m http.server 8741 --directory docs and open http://127.0.0.1:8741/.
Put the app icon in docs/icons/ (256x256 PNG, e.g. docs/icons/texas.png).
Add an entry to states in tools/site-data.json:
| field | used for |
|---|---|
abbr | two-letter code; must match tools/us-states-paths.json |
status | "live" puts it on the page and fills it on the map; anything else counts as coming soon |
app, tagline | card title and text |
tagline_short | optional shorter text for the map's pop-up card |
region | optional eyebrow label (e.g. "Chicago + Illinois"); defaults to the state name |
site, how | website button; "How it works" link (left out when it's the same URL as site) |
web_app, web_app_label | optional web app link (e.g. "Search on the web") |
guides | optional list of {"label", "url"}: the state's best guide pages (e.g. a fish fry guide), shown as links on its card so the hub links deeper than each home page; plain https:// like every link |
app_store | App Store URL once the app is approved; null shows "Coming soon to the App Store" (not a link) |
app_store_note | hover text on the coming-soon badge; keep it true (e.g. add "(in review)" only once the build has actually been submitted to App Review) |
platforms | e.g. "iPhone & iPad, free" (shown as "iPhone & iPad · Free") |
colors.bg, colors.accent, colors.text | card colours; bg fills the state on the map, accent fills it in dark mode. If accent reads below 4.5:1 on bg, the card's label, button and focus ring use the nearest same-hue shade that passes (build.py prints a note); verify.py fails if text doesn't pass |
The map's icon position, the "Now in …" lines, the legend swatch, the meta description and the
JSON-LD all follow from the data; nothing else needs editing. If a card names MICHELIN (or Bib Gourmand) or
James Beard, the footer adds the trademark line for it by itself (and drops it when none does); verify.py checks.
Each page carries a Content-Security-Policy <meta> that allows only its own inline scripts and <style> blocks, by
hash: no script files, no 'unsafe-inline'. build.py turns every style="…" attribute into a generated class
(zs0, zs1, …) whose rule goes in one more hashed <style> block (hoist_styles), so templates may still use style
attributes; app.js sets positions through element.style, which the policy allows. build.py recomputes the hashes on
every build, so never edit docs/index.html by hand: a stale hash stops the script or the styles (verify.py checks
them, and that no style attribute is left in the markup). docs/.well-known/security.txt expires on the date in build.py
(SECURITY_TXT_EXPIRES); verify.py fails once it has passed, so move it on a year and rebuild.
While any live app still has app_store: null, the page says On the web now (section label, map legend,
map labels) and "Now in Illinois and Wisconsin". Once every live app has its App Store URL it switches to
Live now by itself. The meta description never claims the apps can be installed.
python3 tools/update_prices.py
Pulls every series listed under prices.series from the BLS public API v1
(https://api.bls.gov/publicAPI/v1/timeseries/data/, one POST, the last 10 years, no key), writes them
into site-data.json, regenerates the source line ("through . BLS did not publish data.")
and rebuilds. Months BLS didn't publish (value -, e.g. October 2025) are kept as null and drawn as a
gap. It writes nothing if a series comes back empty, short, or older than what's already there, or if
the page wouldn't build from the new data (it runs build.py --data <new file> --dry-run first), so
site-data.json and docs/index.html never disagree.
The Chicago/Midwest/U.S. 12-month stat needs the same month a year earlier. BLS skipped October 2025, so when
the latest month is October 2026 that stat uses September 2026 (the stat names its month; build.py prints a
note). Everything else uses the latest month.
The keyless API allows 25 queries a day, so run it once after each monthly CPI release (around mid-month),
then python3 tools/verify.py and commit. --out some.json fetches without touching site-data.json.
If the copy's claims stop being true (for example restaurants no longer outpacing overall prices, or groceries falling), the wording switches automatically ("outpacing" -> "compared with", "rose" -> "fell", chart title) rather than stating something false.
../chi-eats/.venv/bin/python tools/make_images.py # needs Pillow and Google Chrome
Draws the Eats Ranked mark (three bars, the last in the accent colour) into the favicons and renders
og.png (wordmark, "Restaurants, ranked state by state.", each live app's icon) with headless Chrome.
It also saves each state's icon PNG as a WebP of the same 256x256 size (quality 85, about a fifth of the bytes:
the 9 icons went from 121 KB to 26 KB), named after the PNG's SHA-256: icons/texas.<first 10 hex digits>.webp.
build.py (standard library only) works out the same name and loads the WebP when it's there for that exact PNG,
otherwise the PNG, so a replaced PNG never shows its old WebP; run build.py after make_images.py. The PNGs stay:
they're what og.png and the README's add-a-state step use. make_images.py --icons writes only the WebP icons.
verify.py warns when a live state's icon still loads as its PNG, and fails if a state's icon loads as a WebP made from another version of its PNG, or as a WebP that isn't on disk.
nickstrom5/eatsranked and push main.main, folder /docs. Custom domain eatsranked.com
(already in docs/CNAME); once the DNS check passes, tick Enforce HTTPS.https://eatsranked.com/ loads, https://eatsranked.com/nope shows the 404 page, www redirects,
and a link preview (iMessage, Slack) shows og.png.https://eatsranked.com/sitemap.xml in Google Search Console and Bing Webmaster Tools.When an app is approved on the App Store: set its app_store to the listing URL
(https://apps.apple.com/app/id<APP_ID>; Chicago Restaurants: Ranked is app_store_id 6816931379), run
build.py and verify.py, commit. The badge becomes a "Download on the App Store" link, on the state's card and on
its map pop-up; verify.py checks each of them (so the page has two App Store links per app). To use Apple's
official badge artwork instead, download it from Apple's marketing tools and commit it under docs/
(never hotlink it). When chicago.eatsranked.com is live, point Illinois's site and how at it
(future_site).
states-albers-10m, ISC License,
Copyright 2013-2019 Mike Bostock (full text in tools/us-atlas-LICENSE.txt), derived from U.S. Census
Bureau cartographic boundary files.Not affiliated with any government agency. Official inspection results are shown as published; grades of our own are labeled as ours. Contact: [email protected]
iconpath under docs/, e.g. "icons/texas.png"; keep pointing it at the PNG. The page loads make_images.py's WebP of it (icons/texas.<hash>.webp) once that exists |
pin | optional [x, y] for the state's map icon and label, in the units of tools/us-states-paths.json (viewBox 0 0 975 610; Connecticut's icon sits at about [888, 189]); it must lie inside the state. Leave it out and the icon goes to the point deepest inside the state. Set it when that point puts the icon over a neighbour's: verify.py --browser fails if two map icons overlap at 320-1600 px |
Every link (site, how, web_app, app_store) must be a plain https:// URL: build.py stops on any
other scheme or on spaces, backslashes and control characters, and verify.py checks every link on the built pages.
Run …/python tools/make_images.py (so the share image shows the new icon and the icon gets its WebP), then
python3 tools/build.py, then python3 tools/verify.py --browser, and look at the page at phone and desktop width.