mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Conflicts with upstream's Street Level provider composition and share-state codec, resolved: - Street View's switch moves from its own share option (`g`) to upstream's provider-switch field (`r`, e.g. `0.r.google-1`); a link without it keeps Street View off. Docs and the browser gate follow. - createApplicationStreetLevel keeps upstream's injectable provider list; its default, once the application supplies its Street Level source, is Mapillary plus Google Street View. Without that source there are none, as upstream intends. - The coverage hint keeps upstream's empty-composition message and joins every switched-on provider's hint otherwise. - CHANGELOG, README and SECURITY keep both sides' entries. Co-Authored-By: Claude Opus 5.5 <[email protected]>
230 lines
14 KiB
Bash
230 lines
14 KiB
Bash
# Local development uses one file for browser and server keys.
|
|
# Copy to .env (ignored); this example contains names and placeholders only.
|
|
# Only explicitly selected browser keys are injected into the client bundle.
|
|
# God's Eye View — environment variables
|
|
# Copy to .env and fill in your keys. On macOS the launcher can also read keys
|
|
# from the Keychain (see README); on Linux/Windows use this file or env vars.
|
|
#
|
|
# Easiest path: don't edit anything. Run the app and paste keys into the
|
|
# in-app Provider Settings panel (the POWER UP chip, bottom-right) — it writes
|
|
# this checkout's .env for you (owner-only permissions) and restarts the dev
|
|
# server. Under the Pinokio launcher it writes pinokio/ENVIRONMENT instead.
|
|
# Keys you supply yourself (shell env, Keychain) are shown as configured
|
|
# externally and never touched. This file remains the reference for headless
|
|
# and self-hosted setups.
|
|
#
|
|
# NOTE ON CLIENT-EXPOSED KEYS: GOOGLE_MAPS_API_KEY, CESIUM_ION_TOKEN and
|
|
# MAPILLARY_CLIENT_TOKEN are injected into the browser bundle by design
|
|
# (they're used client-side) and WILL be visible in devtools. Restrict/scope them rather than trying to hide
|
|
# them (see SECURITY.md). All other keys below stay server-side.
|
|
|
|
# Optional: direct Google Photorealistic 3D Tiles, GEV place search and Street
|
|
# View (Street View also needs the Maps JavaScript API enabled for the key).
|
|
# Without it, a Cesium ion token can still load ion-hosted Google 3D; with
|
|
# neither credential, the app starts on keyless Esri World Imagery with OSM
|
|
# available in the map tray and as the automatic provider-failure fallback.
|
|
# CLIENT-EXPOSED — restrict it (HTTP referrer + API restriction) in Google Cloud.
|
|
GOOGLE_MAPS_API_KEY=
|
|
|
|
# Optional: a SEPARATE Google API key for the SERVER-SIDE Google calls — Places
|
|
# (/api/google/nearby-places, /api/google/text-search) and the CCTV Street View
|
|
# fallback (#33). It never reaches the browser, so it can be restricted by
|
|
# server IP (not HTTP referrer) and scoped to just Places API + Street View
|
|
# Static API, letting the client-exposed key above stay narrowly scoped to Map
|
|
# Tiles + Geocoding. Unset, these calls fall back to GOOGLE_MAPS_API_KEY, so a
|
|
# single shared key keeps working — splitting is opt-in.
|
|
# SERVER-SIDE ONLY.
|
|
GOOGLE_MAPS_SERVER_API_KEY=
|
|
# Per-IP rate limit for the Google Places cost endpoints
|
|
# (/api/google/nearby-places + /api/google/text-search), in requests per minute.
|
|
# DEFAULTS TO 120, the value the Pinokio build already ships. Raise or lower it
|
|
# with a positive integer; 60 is a sensible tightening whenever HOST is not
|
|
# localhost. Set it to exactly 0 to run unthrottled. An unreadable value (a
|
|
# typo, a stray unit) falls back to the default rather than to unlimited, so a
|
|
# slip cannot quietly disarm the guard. A positive value below 1 counts as 1.
|
|
# NOTE: this is a per-IP, process-local guard (in-memory, resets on restart;
|
|
# over-limit requests get a sanitized 429) — it is NOT a billing cap. For hard
|
|
# spend protection set provider-side budget alerts: Google Cloud Console ->
|
|
# Billing -> Budgets & alerts (plus per-API quotas under APIs & Services ->
|
|
# Quotas).
|
|
# GEV_RATELIMIT_GOOGLE_PER_MIN=60 # uncomment to tighten from the default 120
|
|
|
|
# Optional: Google Photorealistic 3D Tiles through Cesium ion, Bing world
|
|
# imagery, and Cesium World Terrain. The free Community plan is for eligible
|
|
# personal/non-commercial use and has quotas; check current Cesium terms. A
|
|
# direct Google key above is still required for GEV place search.
|
|
# CLIENT-EXPOSED — use a public assets:read token with URL restrictions.
|
|
CESIUM_ION_TOKEN=
|
|
|
|
# Optional: OpenAI Realtime voice control. API key is the default cloud auth.
|
|
# Provider Settings can instead opt voice into the signed-in local
|
|
# ChatGPT/Codex OAuth session; the browser still receives only a short-lived
|
|
# Realtime client secret. Do not prefix with VITE_.
|
|
OPENAI_API_KEY=
|
|
# Optional: forbid API-key voice sessions. Select ChatGPT OAuth in Provider
|
|
# Settings; missing or expired Codex sign-in then fails closed.
|
|
# GEV_PREFER_CODEX_OAUTH=true
|
|
OPENAI_REALTIME_MODEL=gpt-realtime-2
|
|
# Cheaper voice tier, used when the GEV MIC panel's MINI toggle is on.
|
|
# Model ids and prices are external facts that drift — if OpenAI moves this id,
|
|
# override it here rather than editing src/voice/voiceCost.js.
|
|
OPENAI_REALTIME_MODEL_MINI=gpt-realtime-2.1-mini
|
|
OPENAI_REALTIME_VOICE=marin
|
|
OPENAI_REALTIME_REASONING_EFFORT=low
|
|
# Keep only a short conversational window. Current map state is fetched live.
|
|
OPENAI_REALTIME_CONTEXT_TOKENS=3000
|
|
OPENAI_REALTIME_CONTEXT_RETENTION=0.5
|
|
# Voice-card captions of what you said. Billed separately by OpenAI and
|
|
# counted in the session cost meter and cap; off disables them.
|
|
OPENAI_REALTIME_TRANSCRIBE_MODEL=gpt-4o-mini-transcribe
|
|
# The voice debug log (.gev-logs/realtime-conversations.jsonl, rotated at
|
|
# 32 MB, never expired) omits transcripts, typed or spoken text, and tool
|
|
# arguments/results (including serialized outputs) by default. Set to 1 to
|
|
# keep them while debugging; delete the log when you are done.
|
|
GEV_VOICE_LOG_CONTENT=
|
|
OPENAI_HUD_SUMMARY_MODEL=gpt-5-nano
|
|
# Per-IP rate limit for the OpenAI cost endpoints
|
|
# (/api/realtime/token + /api/openai/hud-summary), in requests per minute.
|
|
# DEFAULTS TO 30, the value the Pinokio build also ships. That clears ordinary
|
|
# use several times over: an open tab asks for a HUD summary every 15s (4/min)
|
|
# and a voice session mints one token. Raise or lower it with a positive
|
|
# integer; set it to exactly 0 to run unthrottled. An unreadable value (a typo,
|
|
# a stray unit) falls back to the default rather than to unlimited, so a slip
|
|
# cannot quietly disarm the guard. A positive value below 1 counts as 1.
|
|
# NOTE: this is a per-IP, process-local guard (in-memory, resets on restart;
|
|
# over-limit requests get a sanitized 429) — it is NOT a billing cap. For hard
|
|
# spend protection set a provider-side budget: OpenAI platform -> Settings ->
|
|
# Limits (usage limits).
|
|
# GEV_RATELIMIT_OPENAI_PER_MIN=30 # the default; uncomment only to change it
|
|
|
|
# Optional: Mapillary imagery for the Street Level layer. Free client token from
|
|
# https://www.mapillary.com/dashboard/developers (register an app, copy its
|
|
# Client Token). Client-exposed by design, like GOOGLE_MAPS_API_KEY.
|
|
MAPILLARY_CLIENT_TOKEN=
|
|
|
|
# Optional: OpenSky auth mode (oauth | basic | auto | anon)
|
|
# Default: oauth — requires client credentials below
|
|
# Set to "anon" to skip aircraft auth (rate-limited but works)
|
|
OPENSKY_AUTH_MODE=oauth
|
|
|
|
# Optional: OpenSky OAuth credentials (from opensky-network.org account dashboard)
|
|
OPENSKY_CLIENT_ID=
|
|
OPENSKY_CLIENT_SECRET=
|
|
|
|
# Optional: higher Launch Library 2 request allowance. Public access works
|
|
# without a token.
|
|
LL2_API_TOKEN=
|
|
|
|
# Optional: OpenSky credentials JSON file path (alternative to above)
|
|
# OPENSKY_CREDENTIALS_FILE=/path/to/credentials.json
|
|
|
|
# Optional: dev server config
|
|
PORT=4173
|
|
# Network binding. Default is localhost — the server is reachable ONLY from
|
|
# this machine. This is the safe default: the dev server brokers your
|
|
# configured API keys, so anyone who can reach it can spend your quota.
|
|
# LAN opt-in: set HOST=0.0.0.0 to share on your local network. WARNING: that
|
|
# exposes every key-brokering proxy to everyone on the network — use only on
|
|
# networks you trust, and consider the GEV_RATELIMIT_* throttles above.
|
|
# HOST=localhost
|
|
# HOST=0.0.0.0
|
|
# Optional: comma-separated LAN hostnames to accept, in addition to localhost
|
|
# and IP addresses, for example GEV_ALLOWED_HOSTS=globe.lan,globe.internal.
|
|
# Binding HOST=0.0.0.0 alone does NOT trust every Host header; suffix and
|
|
# wildcard entries are ignored.
|
|
# GEV_ALLOWED_HOSTS=
|
|
|
|
# Optional: NASA FIRMS live active fires. SERVER-SIDE ONLY (never reaches the
|
|
# browser — the client polls the /api/firms proxy). Free key:
|
|
# https://firms.modaps.eosdis.nasa.gov/api/map_key/
|
|
# Without a key the FIRMS Active Fires layer is empty ("KEY REQUIRED").
|
|
# FIRMS_MAP_KEY=
|
|
|
|
# Optional: Live AIS vessels layer
|
|
# Browser fetch path. Keep same-origin so the private stream key stays server-side.
|
|
VITE_AIS_LIVE_API_URL=/api/vessels
|
|
# Client render cap. The server can keep a larger AISStream cache, but drawing
|
|
# every global vessel at once can overwhelm WebGL on laptops.
|
|
VITE_AIS_LIVE_MAX_ROWS=12000
|
|
# Active label cap after screen-space clustering. Labels exist for all rendered
|
|
# ships, but only clustered winners are shown to keep text readable.
|
|
VITE_AIS_LIVE_LABEL_MAX_ROWS=900
|
|
# Private AISStream key for the server-side websocket. Do not prefix with VITE_.
|
|
AISSTREAM_API_KEY=
|
|
# Optional AISStream subscription filters.
|
|
# AISSTREAM_BOUNDING_BOXES=[[[-90,-180],[90,180]]]
|
|
# AISSTREAM_MESSAGE_TYPES=PositionReport,StandardClassBPositionReport,ExtendedClassBPositionReport,ShipStaticData,StaticDataReport
|
|
# Feed watchdog: silence (ms) after which the feed is REPORTED stale; the socket
|
|
# is recycled at 2.5x that. Default 120000. The watchdog self-arms only for the
|
|
# default worldwide subscription — a narrow filter above can be legitimately
|
|
# quiet, so set this explicitly (sized for your filter) to opt back in.
|
|
# 0 disables the silence watch entirely.
|
|
# AISSTREAM_SILENCE_TIMEOUT_MS=120000
|
|
|
|
# Optional: local ADS-B decoder feeds for the Local ADS-B layer. SERVER-SIDE
|
|
# ONLY. Comma-separated band=url entries; band is 1090 or 978 (UAT). Each host
|
|
# must be loopback, a private (RFC1918) address, localhost or a *.local name;
|
|
# the path must end in aircraft.json. Invalid entries are logged and skipped.
|
|
# See docs/LOCAL-RECEIVERS.md.
|
|
# LOCAL_RECEIVER_FEEDS=1090=http://localhost:8080/data/aircraft.json,978=http://localhost:8978/data/aircraft.json
|
|
|
|
# Optional: TomTom live traffic flow (BYOK freemium — the free tier is 200,000
|
|
# Traffic Flow & Incidents tile requests per MONTH, not per day; no credit card
|
|
# required. Get a key at https://my.tomtom.com/keys). SERVER-SIDE ONLY:
|
|
# the browser fetches same-origin /api/tomtom/* and never sees the key.
|
|
# Keyless fallback: the traffic layer runs its built-in simulation (white dots,
|
|
# hardcoded per-road-class speeds) — no key required for the layer to work.
|
|
# TOMTOM_API_KEY=
|
|
# Optional soft cap on upstream tile fetches per UTC day (default 6000) — a
|
|
# configurable application safety ceiling, not a guarantee of staying within
|
|
# TomTom's free allowance (currently 200K tile requests/month:
|
|
# https://docs.tomtom.com/pricing/). 6000/day keeps a 31-day month at 186K,
|
|
# inside that allowance. Over the cap the proxy serves cached/stale tiles
|
|
# instead of hitting upstream.
|
|
# TOMTOM_DAILY_TILE_BUDGET=6000
|
|
|
|
# Optional: CCTV layer tuning (advanced). Defaults are sensible — leave unset
|
|
# unless you're customizing the camera source pack.
|
|
# CCTV_SOURCES_FILE=config/cctv_sources.austin.json # path to a source-pack JSON
|
|
# CCTV_SOURCES_JSON= # inline source-pack JSON (overrides file)
|
|
# CCTV_AUSTIN_ROWS_URL= # override the Austin Open Data catalog URL
|
|
# CCTV_AUSTIN_MAX_SOURCES=250 # cap cameras loaded from the Austin catalog
|
|
# CCTV_CALTRANS_DISTRICTS=4,7,11,3 # Caltrans districts; empty string disables Caltrans
|
|
# CCTV_CALTRANS_MAX_SOURCES=300 # cap cameras loaded from Caltrans
|
|
# CCTV_TFL_ENABLED=1 # set 0 to disable Transport for London JamCams
|
|
# CCTV_TFL_MAX_SOURCES=250 # cap cameras loaded from TfL
|
|
# CCTV_ONTARIO_ENABLED=1 # set 0 to disable Ontario 511 cameras
|
|
# CCTV_ONTARIO_MAX_SOURCES=1000 # cap cameras loaded from Ontario 511
|
|
# CCTV_FINTRAFFIC_ENABLED=1 # set 0 to drop the Fintraffic (Finland) pack
|
|
# CCTV_FINTRAFFIC_MAX_SOURCES=300 # cap cameras loaded from the Fintraffic catalog
|
|
# CCTV_DRIVEBC_MAX_SOURCES=250 # cap DriveBC (British Columbia) cameras, nearest Vancouver/Victoria first
|
|
# CCTV_DRIVEBC_ENABLED=1 # 0 turns off the DriveBC camera pack
|
|
# CCTV_TXDOT_ENABLED=1 # set 0 to disable the TxDOT (Texas) pack
|
|
# CCTV_TXDOT_DISTRICTS=AUS,SAT # TxDOT district codes (25 exist); empty disables the pack
|
|
# CCTV_TXDOT_MAX_SOURCES=500 # cap cameras loaded from the TxDOT catalogs
|
|
# CCTV_TALLINN_ENABLED=1 # set 0 to disable the Tallinn (Estonia) intersection cameras
|
|
# CCTV_TALLINN_MAX_SOURCES=255 # cap cameras loaded from the Tallinn catalog
|
|
# CCTV_TARKTEE_ENABLED=1 # set 0 to disable the Tarktee (Estonia) road-weather cameras
|
|
# CCTV_TARKTEE_MAX_SOURCES=179 # cap cameras loaded from Tarktee
|
|
# CCTV_WARENDORF_ENABLED=1 # set 0 to disable the Warendorf (Germany) municipal webcams
|
|
# CCTV_NSW_ENABLED=1 # set 0 to disable the Live Traffic NSW (Australia) cameras
|
|
# CCTV_NSW_MAX_SOURCES=250 # cap cameras loaded from Live Traffic NSW
|
|
# CCTV_CALGARY_ENABLED=1 # set 0 to disable the Open Calgary (Alberta) cameras
|
|
# CCTV_CALGARY_MAX_SOURCES=220 # cap cameras loaded from the Open Calgary catalog
|
|
# CCTV_CALGARY_ROWS_URL= # override the Open Calgary catalog URL
|
|
# CCTV_VEGVESEN_ENABLED=1 # set 0 to disable the Statens vegvesen (Norway) road cameras
|
|
# CCTV_VEGVESEN_MAX_SOURCES=900 # cap cameras loaded from Statens vegvesen (default loads all ~850 live; max 1000)
|
|
# CCTV_VEGVESEN_VIDEO=1 # set 0 to show stills instead of live HLS for Statens vegvesen video cameras
|
|
# CCTV_VEGVESEN_URL= # override the Statens vegvesen catalog URL
|
|
# CCTV_MAX_SOURCES=4000 # catalog-wide ceiling, shared round-robin across packs
|
|
# CCTV_PREFER_AUSTIN=1 # prioritize Austin cameras in the registry
|
|
# CCTV_FORCE_AUSTIN= # force live default sources when a source-pack JSON is configured
|
|
|
|
# Optional: comma-separated Overpass URLs; use only instances you run or pay for.
|
|
OVERPASS_UPSTREAMS=
|
|
|
|
# Optional: who may frame the app in embed mode (?embed=1), as CSP
|
|
# frame-ancestors sources such as "https://example.com", or * for any page.
|
|
# Unset, no page may frame it. Other pages of the app can never be framed.
|
|
# GEV_EMBED_FRAME_ANCESTORS=
|