Fujimod
Try your camera firmware in the browser and build Fujimod SD boot files.
Explore famous places through their history, geography and culture before you visit.
LifestyleJavaScript · SCSSGitHub @NgocThuan130607OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Interactive cultural guide: explore famous places through history, geography and etiquette on a 3D globe
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗An interactive cultural guide for travellers. Start on a 3D globe, pick a city, then explore a landmark in three ways, each on its own page:
timetravel.html): drag a slider through the landmark's eras and watch historical photos fade into modern ones, or compare two eras side by side.stories.html): short narrated chapters on history, legends and culture, with a highlighted transcript.visit.html): opening hours with a live "Open now" badge (in the landmark's own time zone), etiquette dos and don'ts, local tips, and a filterable map.| Page | What it is |
|---|---|
index.html | Home: the 3D globe, with search, the World / Vietnam atlases and "Through time" |
city.html?id=hanoi | City or province guide with a satellite map of its landmarks |
timetravel.html?id=eiffel-tower | Landmark: Time travel (&era=2 opens a given era) |
stories.html?id=eiffel-tower | Landmark: narrated stories |
visit.html?id=eiffel-tower | Landmark: visitor guide |
landmark.html | Redirect that keeps older links (landmark.html?id=…#story) working |
The globe has two atlases, switched with the World / Vietnam buttons:
| Part | Choice |
|---|---|
| Build tool | Vite. Each page is built as a classic script so the site opens straight from disk (see below) |
| UI | Bootstrap 5 compiled from Sass with Material 3–style tokens, Roboto Flex, Material Symbols (only the icons in use are downloaded) |
| Language | Plain JavaScript (ES modules), HTML5, CSS |
| 3D globe | CesiumJS, no key needed. Its images and star map load from the jsDelivr CDN. Far away it shows Sentinel-2 cloudless imagery by EOX (true colour, CC BY-NC-SA 4.0, so non-commercial use only); close up it switches to Esri World Imagery. Esri 3D terrain and a borders/labels layer are added on top. It renders at full screen resolution with MSAA. An optional Cesium ion token or Google Maps key adds photorealistic 3D buildings. |
| Maps | Leaflet with Esri tiles: street map (light/dark) and satellite with labels |
| Narration | Each chapter's own audio/video file, or the browser's built-in text-to-speech |
| Data | Static JSON in public/data/ (no backend) |
| Images | Wikimedia Commons, credited automatically on every page |
You need Node.js 20 or newer.
npm install
npm run dev # http://localhost:5173
npm run build # production build in dist/
npm run preview # serve the production build
npm run package # check + build, then copy to submission/website/ (plus readable source)
dist/ is a static site. It works on GitHub Pages or any web server, and also straight from disk: double-click dist/index.html. An internet connection is still needed for map tiles, fonts and photos.
Browsers block three things on pages opened from disk (file://), so the build avoids them:
defer (scripts/build.mjs).fetch() of the JSON files. scripts/bundle-data.mjs packs every file in public/data into one plain script, data/atlas-data.js, and getJSON reads from it first.TaskProcessor is patched at build time to start each worker with that code inside it. See cesiumEmbeddedWorkers in vite.config.js.The site is published to GitHub Pages by .github/workflows/deploy.yml. Every push to main checks the data, builds, and deploys automatically in about 1–2 minutes.
VITE_CESIUM_ION_TOKEN or VITE_GOOGLE_MAPS_API_KEY under Settings → Secrets and variables → Actions, then re-run the workflow.The globe works without any account: satellite imagery, 3D terrain, borders and labels all come from Esri's public services.
For real 3D buildings, like Google Earth's 3D cities, add one of these to a .env file (see .env.example):
VITE_CESIUM_ION_TOKEN=... # free token from https://ion.cesium.com (also gives Cesium World Terrain)
VITE_GOOGLE_MAPS_API_KEY=... # a Google Maps Platform key with the Map Tiles API enabled
With either one, the globe loads Google Photorealistic 3D Tiles. This path hasn't been tested without a key, so check it once you have one.
The design follows Google Earth: a search box, a knowledge card on the left, map controls on the right (compass, 2D/3D tilt, zoom, whole globe), a strip of featured landmarks, and a status bar with cursor coordinates and camera height.
Clicking a city or landmark (on the globe, in the list, in search or in the strip) flies the camera there and opens its card. The card links to the full city guide or landmark page.
You can link straight to a place with index.html#kyoto or index.html#colosseum. The back arrow on the city page uses this to return to the same spot.
Museums tell the story of one place through time. This feature tells history across places: pick a year and the whole globe shows what each city was like at that moment. For example, in 1889 the Eiffel Tower has just opened, Kyoto is in the Meiji era and Hanoi is under French rule.
timetravel.html?id=eiffel-tower&era=2).index.html#year=1889. It also works on the 2D map used on devices without WebGL.index.html, city.html, page shells (the five page types)
timetravel.html, stories.html, visit.html
src/
scss/main.scss Bootstrap theme + all custom styles
js/common.js data loading, image credits, theme switch, navbar
js/cesium-base.js Cesium setup: embedded workers, CDN base URL, WebGL 1 fix
js/hours.js opening-hours / "Open now" logic (time-zone aware)
js/map.js Leaflet helpers and map categories
js/world-year.js "Through time": year scale, per-year snapshot, world timeline bar
js/pages/ globe.js, city.js, timetravel.js, stories.js, visit.js (one per page)
js/landmark/ shell.js (shared landmark header + page switcher),
timeline.js, story.js, guide.js (the three landmark views)
public/
landmark.html redirect for older landmark links
public/data/
cities.json list of cities shown on the globe
cities/<id>.json city intro, facts, etiquette, "coming soon" landmarks, timeline
world-moments.json key moments and periods for the World timeline
vietnam-moments.json key moments, periods and year scale for the Vietnam timeline
landmarks/<id>.json eras, story chapters, visitor guide
media.json generated: image URLs + credits (don't edit by hand)
atlas-data.js generated: all the JSON above in one script (not in git)
scripts/
resolve-media.mjs npm run media: looks up images on Wikimedia Commons
check-data.mjs npm run check: validates all the data files
bundle-data.mjs npm run data: builds public/data/atlas-data.js
build.mjs npm run build: builds each page as a classic script
package.mjs npm run package: copies the build + source to submission/website/
No code changes are needed.
Add the city to public/data/cities.json:
{ "id": "istanbul", "name": "Istanbul", "country": "Türkiye", "continent": "Europe",
"lat": 41.0082, "lon": 28.9784, "timezone": "Europe/Istanbul",
"tagline": "Where two continents meet", "landmarks": ["hagia-sophia"] }
timezone must be an IANA name. It drives the local clock and the "Open now" badge.
Optional fields:
collections: the atlases the place appears in, e.g. ["world"], ["vietnam"] or both. Defaults to ["world"].region: needed for atlases with groups, e.g. "North", "Central" or "South" for Vietnam.kind: "City" or "Province". Cities' names win when labels overlap on the map.formerly: older names that search should also find.The atlases themselves are defined in collections at the top of cities.json. Each has a home view (plus bounds for the 2D map), a moments file for "Through time", its groups, and "cards": "events" to show floating cards only for places with an event that year.
Create public/data/cities/istanbul.json. Copy an existing city file and change hero, facts, sections, etiquette and, optionally, planned.
Also give it a timeline for the world timeline. Use about 10–15 entries in year order:
{ "year": 1453, "text": "Ottoman Sultan Mehmed II takes Constantinople." },
{ "year": 537, "text": "Hagia Sophia is completed.", "landmark": "hagia-sophia", "era": 0 }
year is negative for BCE, and "approx": true shows it as "c. …". landmark + era (an index into that landmark's eras) link the entry to the landmark's Time travel. An optional image uses the same format as elsewhere.
Create public/data/landmarks/hagia-sophia.json. Copy an existing landmark and edit it. The key fields:
| Field | Notes |
|---|---|
eras[] |
The new city will appear on the globe, in the Cities menu and in the city list.
Opening hours, prices and map marker positions are approximate prototype data. Check official sources before travelling. Images come from Wikimedia Commons under their stated licences, and each page lists its image credits.
In chronological order. year is a number (negative for BCE) used for ordering. label is what's shown, e.g. "c. 2560 BCE" or "Today". |
eras[].image | { "file": "<Wikimedia Commons file name>", "alt": "…", "focus": "center bottom" }. focus is optional and controls cropping in the before/after view. For your own photos, use { "src": "media/my-photo.jpg", "credit": "Photo: …" } and put the file in public/media/. |
story[] | type is history, legend or culture. narration is read aloud by text-to-speech. Add "audio": "media/x.mp3", "video": "media/x.mp4" or "youtube": "<video id>" to use real recordings instead. |
guide.hours.seasons[] | months (1–12) plus days with daily or mon…sun set to [["09:00","17:00"]]. Leave a day out to mark it closed. A closing time earlier than the opening time means "after midnight". |
guide.hours.closedDates | ["12-25"] (MM-DD). |
guide.hours.open24h | true for outdoor places with no gate, such as a bay or a mountain pass. Use it instead of seasons. |
guide.pois[] | category is entrance, transport, food, sights or services. |
Run the helpers:
npm run media # fetches image URLs and credits for any new Commons files
npm run check # flags missing fields, bad times, unknown images, wrong ordering…