import { cfg } from './config.mjs' import { writeFile, readFile } from 'fs/promises' import { existsSync } from 'fs' import { resolve, dirname } from 'path' import { fileURLToPath } from 'url' const DIR = dirname(fileURLToPath(import.meta.url)) const SHAPES_PATH = resolve(DIR, 'public', 'aircraft.js') export async function getShapes() { if (existsSync(SHAPES_PATH)) { return JSON.parse(await readFile(SHAPES_PATH, 'utf8')) } const r = await fetch('https://raw.githubusercontent.com/wiedehopf/tar1090/refs/heads/master/html/markers.js') const text = await r.text() // Rip out just the `let shapes = { ... }` block by finding the matching closing brace const start = text.indexOf('let shapes = {') if (start === -1) throw new Error('Could not find shapes definition in markers.js') let depth = 0, end = -1 for (let i = start + 'let shapes = '.length; i < text.length; i++) { if (text[i] === '{') depth++ else if (text[i] === '}') { depth--; if (depth === 0) { end = i + 1; break } } } if (end === -1) throw new Error('Could not find end of shapes definition') // Use Function to eval the JS object safely (avoids JSON.parse issues with unquoted keys, comments etc) const shapes = new Function(`return ${text.slice(start + 'let shapes = '.length, end)}`)() await writeFile(SHAPES_PATH, JSON.stringify(shapes)) return shapes } export async function getAirTraffic() { const { ADSB_URL } = cfg() if (!ADSB_URL) return { data: [] } const r = await fetch(`${ADSB_URL}/re-api/?all`) const j = await r.json() return { data: j.aircraft || [] } } export async function getAirTrafficHistory(icao) { const { ADSB_URL } = cfg() if (!ADSB_URL) return { history: [] } const r = await fetch(`${ADSB_URL}/re-api/?trace&icao=${icao}`) const j = await r.json() const history = (j.trace || []).map(t => ({ latitude: t[1], longitude: t[2], altitude: t[3] || 0, })) return { history } }