--- // The localness device (design system: "one map, framed by country"). It renders in a same-origin // iframe because it needs d3 + topojson at runtime; keeping it out of the main bundle means the // heavy map libs load only when the map scrolls into view (loading="lazy"). All deps are // self-hosted under /public/map/vendor — no third-party runtime requests. // // Build-time values (cc, accent, member dots, and on .eu the active communities) go in the src // query string; the iframe resolves light/dark itself so the map follows the page theme. import { getScope } from '../config/scopes'; import { existingCommunities } from '../data/communities'; interface Props { /** Member dots as "lon:lat:n,lon:lat:n". Empty renders the country outline with no members yet. */ dots?: string; class?: string; title?: string; /** Internal frame size. Larger + landscape = a denser character grid, for the background use. */ w?: number; h?: number; /** 'cover' fills the frame (no letterbox) for the full-bleed background; default keeps the whole map. */ fit?: 'cover' | 'meet'; } const { dots = '', class: cls, title, w, h, fit } = Astro.props; const scope = getScope(import.meta.env.PUBLIC_SITE_SCOPE); // Cache-bust: /public map assets are served without a content hash, so browsers keep the old // locality-map.js after a deploy. Bump this when the map renderer changes; it versions both the // iframe URL (fresh HTML) and the script it loads (fresh JS). const MAP_VERSION = '6'; const params = new URLSearchParams({ cc: scope.cc, accent: scope.accent }); if (dots) params.set('dots', dots); if (w) params.set('w', String(w)); if (h) params.set('h', String(h)); if (fit) params.set('fit', fit); params.set('v', MAP_VERSION); // On the aggregate, light the EU members and mark countries that actually have a community (from // the directory: national + city). Data-driven so it stays true as communities are added — e.g. // FR (atproto.fr + Lille), DE (Berlin/Frankfurt), ES (Barcelona), PL (Kraków), AT (Vienna). if (scope.aggregate) { const active = [...new Set(existingCommunities.map((c) => c.country))].join(','); params.set('active', active); } const src = `/map/locality-map.html?${params.toString()}`; ---