From 8be3e0480361a42930eacec0d5395a8e059cff6d Mon Sep 17 00:00:00 2001 From: "(jenkins)" <(jenkins)> Date: Mon, 16 Mar 2026 23:19:40 +0000 Subject: [PATCH] Implement 3D globe fly-over animation using MapLibre FreeCamera and Turf.js --- backend/app/server.js | 2 +- backend/scripts/import_cities.js | 120 +- frontend/package-lock.json | 2162 ++++++++++++++++++++++++++++++ frontend/package.json | 1 + frontend/src/App.jsx | 121 +- frontend/src/styles/App.css | 44 + 6 files changed, 2373 insertions(+), 77 deletions(-) diff --git a/backend/app/server.js b/backend/app/server.js index 3cd62b7..867b87a 100644 --- a/backend/app/server.js +++ b/backend/app/server.js @@ -81,7 +81,7 @@ app.get('/api/line-of-sight', async (req, res) => { FROM cities WHERE ST_DWithin(geom, (SELECT route FROM path), $2 * 1000) ORDER BY pos_on_line ASC - LIMIT 100; + LIMIT 200; `; const result = await pool.query(query, [lineWKT, toleranceKm, startLon, startLat]); diff --git a/backend/scripts/import_cities.js b/backend/scripts/import_cities.js index c4279df..7cf53ae 100644 --- a/backend/scripts/import_cities.js +++ b/backend/scripts/import_cities.js @@ -1,75 +1,95 @@ -const { Client } = require('pg'); -const axios = require('axios'); +const { Pool } = require('pg'); +const { execSync } = require('child_process'); +const fs = require('fs'); +const readline = require('readline'); require('dotenv').config(); -const DATA_URL = 'https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_10m_populated_places_simple.geojson'; +const DATA_URL = 'https://download.geonames.org/export/dump/cities5000.zip'; +const ZIP_FILE = '/tmp/cities.zip'; +const TXT_FILE = '/tmp/cities5000.txt'; -async function importCities() { - const client = new Client({ +async function importGeoNames() { + const pool = new Pool({ connectionString: process.env.DATABASE_URL || 'postgresql://line_of_sight:line_of_sight_pass@postgres:5432/line_of_sight' }); try { + console.log('Downloading GeoNames cities5000 (Pop > 5000)...'); + execSync(`wget -q ${DATA_URL} -O ${ZIP_FILE}`); + + console.log('Extracting data...'); + execSync(`unzip -o ${ZIP_FILE} -d /tmp`); + console.log('Connecting to database...'); - await client.connect(); + const client = await pool.connect(); - console.log('Downloading Natural Earth data (GeoJSON)...'); - const response = await axios.get(DATA_URL); - const data = response.data; - - console.log(`Downloaded ${data.features.length} features. Preparing database...`); - - // Sample properties to verify structure - if (data.features.length > 0) { - console.log('Sample properties:', data.features[0].properties); - } - - // Ensure table exists and is clean + // Ensure table is clean await client.query('TRUNCATE TABLE cities'); + console.log('Starting stream import...'); + + const fileStream = fs.createReadStream(TXT_FILE); + const rl = readline.createInterface({ + input: fileStream, + crlfDelay: Infinity + }); + + let batch = []; + const batchSize = 500; let count = 0; - const batchSize = 100; - for (let i = 0; i < data.features.length; i += batchSize) { - const batch = data.features.slice(i, i + batchSize); - - const queryParts = []; - const values = []; - - batch.forEach((feature, index) => { - const p = feature.properties; - const c = feature.geometry.coordinates; - - // Map properties - Natural Earth simple GeoJSON usually has name, pop_max, adm0name - const name = p.name || p.NAME || 'Unknown'; - const pop = p.pop_max || p.POP_MAX || 0; - const country = p.adm0name || p.ADM0NAME || 'Unknown'; - const lon = c[0]; - const lat = c[1]; + for await (const line of rl) { + const parts = line.split('\t'); + if (parts.length < 15) continue; - const base = index * 5; - queryParts.push(`($${base + 1}, $${base + 2}, $${base + 3}, ST_SetSRID(ST_MakePoint($${base + 4}, $${base + 5}), 4326)::geography)`); - values.push(name, pop, country, lon, lat); - }); + const name = parts[1]; // name + const lat = parseFloat(parts[4]); + const lon = parseFloat(parts[5]); + const country = parts[8]; // country code + const population = parseInt(parts[14]) || 0; - await client.query( - `INSERT INTO cities (name, population, country, geom) VALUES ${queryParts.join(',')}`, - values - ); - - count += batch.length; - if (count % 1000 === 0 || count === data.features.length) { - console.log(`Imported ${count}/${data.features.length} cities...`); + batch.push({ name, lat, lon, country, population }); + + if (batch.length >= batchSize) { + await insertBatch(client, batch); + count += batch.length; + if (count % 5000 === 0) console.log(`Imported ${count} cities...`); + batch = []; } } - console.log('SUCCESS: Natural Earth data import complete.'); + if (batch.length > 0) { + await insertBatch(client, batch); + count += batch.length; + } + + console.log(`SUCCESS: Imported ${count} cities and towns.`); + client.release(); } catch (err) { console.error('ERROR during import:', err); } finally { - await client.end(); + // Cleanup + if (fs.existsSync(ZIP_FILE)) fs.unlinkSync(ZIP_FILE); + if (fs.existsSync(TXT_FILE)) fs.unlinkSync(TXT_FILE); + await pool.end(); } } -importCities(); +async function insertBatch(client, batch) { + const queryParts = []; + const values = []; + + batch.forEach((city, index) => { + const base = index * 5; + queryParts.push(`($${base + 1}, $${base + 2}, $${base + 3}, ST_SetSRID(ST_MakePoint($${base + 4}, $${base + 5}), 4326)::geography)`); + values.push(city.name, city.population, city.country, city.lon, city.lat); + }); + + await client.query( + `INSERT INTO cities (name, population, country, geom) VALUES ${queryParts.join(',')}`, + values + ); +} + +importGeoNames(); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index dcade21..4c991a5 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "line-of-sight-frontend", "version": "1.0.0", "dependencies": { + "@turf/turf": "^7.3.4", "axios": "^1.7.9", "maplibre-gl": "^5.20.1", "react": "^19.2.1", @@ -1478,6 +1479,1937 @@ } } }, + "node_modules/@turf/along": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/along/-/along-7.3.4.tgz", + "integrity": "sha512-PvIoXin0I1t3nRwJz7uqR6fsxDMqdGwJq90qGOeqkNwlZqlF+5o2wKHPwYwi0RXZhLvxRP5qlbNIvV8ADdbWxw==", + "dependencies": { + "@turf/bearing": "7.3.4", + "@turf/destination": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/angle": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/angle/-/angle-7.3.4.tgz", + "integrity": "sha512-235JAfbrNMjHQXQfd/p+fYnlfCHsQsKHda5Eeyc+/jIY0s5mKvhcxgFaOEnigA2q1n+PrVOExs3BViGTKnWhAg==", + "dependencies": { + "@turf/bearing": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/rhumb-bearing": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/area": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/area/-/area-7.3.4.tgz", + "integrity": "sha512-UEQQFw2XwHpozSBAMEtZI3jDsAad4NnHL/poF7/S6zeDCjEBCkt3MYd6DSGH/cvgcOozxH/ky3/rIVSMZdx4vA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-7.3.4.tgz", + "integrity": "sha512-D5ErVWtfQbEPh11yzI69uxqrcJmbPU/9Y59f1uTapgwAwQHQztDWgsYpnL3ns8r1GmPWLP8sGJLVTIk2TZSiYA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox-clip": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/bbox-clip/-/bbox-clip-7.3.4.tgz", + "integrity": "sha512-HCn0q/WPVEE9Dztg7tCvClOPrrh9MoxNUk73byHvcZLBcvziN6F84f/ZbFcbQSh8hgOeVMs/keeqWMqsICcNLg==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox-polygon": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/bbox-polygon/-/bbox-polygon-7.3.4.tgz", + "integrity": "sha512-XCDYQwCA41Bum3R1xX0Na1nR4ozoe/pCYy5bxqrzyMs87kPJUIfBrD5IWxjnZyLqFpfEpolMHJz5ed1uA2PanQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bearing": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/bearing/-/bearing-7.3.4.tgz", + "integrity": "sha512-zvFjapyFaOrM8nBtAND7f4yb0BJV0jyj6cyoXyTYqLY+3Hn0eHgL0M8lwxDLbTom5KfqYDHDVDQC3+VSfypoEA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bezier-spline": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/bezier-spline/-/bezier-spline-7.3.4.tgz", + "integrity": "sha512-+iDUeiBKByIs/6K5WW8pG6IDxrRLJHFLM80zSpzk2xBtgy3mq36NZwwt67Pu7EJAkc9GUXKIm9SkspoKue9aYQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-clockwise": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-clockwise/-/boolean-clockwise-7.3.4.tgz", + "integrity": "sha512-X/O+u/OsoJ99mujhlqviuB7HX0tdJ5931TBjNSseps43XtROVuB5PwBDgwKfu5lY1B4DSGAxbbxJ795RmPnguQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-concave": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-concave/-/boolean-concave-7.3.4.tgz", + "integrity": "sha512-SHuAzjqaAes6ELDZcN/FKZWCQZsqwYv3gMosoLRFWTwKyBQe8i29e4y6XnXakDr1uklVUeRRcdhZ5oKtX9ABPQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-contains": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-contains/-/boolean-contains-7.3.4.tgz", + "integrity": "sha512-AJMGbtC6HiXgHvq0RNlTfsDB58Qf9Js45MP/APbhGTH4AiLZ8VMDISywVFNd7qN6oppNlDd3xApVR28+ti8bNg==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/boolean-point-on-line": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/line-split": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-crosses": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-crosses/-/boolean-crosses-7.3.4.tgz", + "integrity": "sha512-v/U3SuGdkexfLTMhho6Vj0OjqPUeYdThxp8zggGJ1VHow27fvLLez0DjUR3AftHjjHM6bRzZoNsu2qUlEe5hjw==", + "dependencies": { + "@turf/boolean-equal": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/line-intersect": "7.3.4", + "@turf/polygon-to-line": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-disjoint": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-disjoint/-/boolean-disjoint-7.3.4.tgz", + "integrity": "sha512-Dl4O27ygi2NqskGQuvSlDLJYlJ2SPkHb3A9T/v6eAudjlMiKdEY6bMxKUfU5y+Px1WiCZxd+9rXGXJgGC3WiQg==", + "dependencies": { + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/line-intersect": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/polygon-to-line": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-equal": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-equal/-/boolean-equal-7.3.4.tgz", + "integrity": "sha512-AhWqe7D1o0wp3d3QQRSqgWDI8s1JfTFKFe9rU5mrSxYPGlmaQsJC07RCaYfFiGym9lACd1lxBJiPidCbLaPOfw==", + "dependencies": { + "@turf/clean-coords": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "geojson-equality-ts": "^1.0.2", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-intersects": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-intersects/-/boolean-intersects-7.3.4.tgz", + "integrity": "sha512-sxi41NXkb5hrJgOvpm32hyBLhW8fem0vn2XxR4+jyRg1rM/v3ziF10/VqC9KDZuDNZkt9JjL9B0825Cf7AN6Lg==", + "dependencies": { + "@turf/boolean-disjoint": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-overlap": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-overlap/-/boolean-overlap-7.3.4.tgz", + "integrity": "sha512-Q3dlswIuqffSiMfln7xa36YDnN1TWtERMF/155rzjglm4NTUG/6S+gNsb8s6qpLjc+hN6btCq1ZjxAWurPf8Vg==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/line-intersect": "7.3.4", + "@turf/line-overlap": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "geojson-equality-ts": "^1.0.2", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-parallel": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-parallel/-/boolean-parallel-7.3.4.tgz", + "integrity": "sha512-sTNMqsUkLPnSJEqc2IZ5ig3nHRoubyOH2HW1LILqOybCJI630FEM9UoYP1pZniF5nwTyCjQWnXA1FxusVILuFQ==", + "dependencies": { + "@turf/clean-coords": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/line-segment": "7.3.4", + "@turf/rhumb-bearing": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-point-in-polygon": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-7.3.4.tgz", + "integrity": "sha512-v/4hfyY90Vz9cDgs2GwjQf+Lft8o7mNCLJOTz/iv8SHAIgMMX0czEoIaNVOJr7tBqPqwin1CGwsncrkf5C9n8Q==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "point-in-polygon-hao": "^1.1.0", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-point-on-line": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-point-on-line/-/boolean-point-on-line-7.3.4.tgz", + "integrity": "sha512-70gm5x6YQOZKcw0b/O4jjMwVWnFj+Zb6TXozLgZFDZShc8pgTQtZku7K+HKZ7Eya+7usHIB4IimZauomOMa+iw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-touches": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-touches/-/boolean-touches-7.3.4.tgz", + "integrity": "sha512-XOwhjc0oCWhnBUB+l4drpXcg7mkNXPX3SuSz/Xv7gvLH/yRrBwzVGllzK1AHlGU9BVkGVBJIZGYX7jgTM681NQ==", + "dependencies": { + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/boolean-point-on-line": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-valid": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-valid/-/boolean-valid-7.3.4.tgz", + "integrity": "sha512-P6M9BtRvzFF2N5g+1/DTIbYGpEbwQ2sv/Pw+uj11P3NYAA9VE8mvrxFYf+CowFdSfY6bY4ejhuqKhrTmAMv7wA==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/boolean-crosses": "7.3.4", + "@turf/boolean-disjoint": "7.3.4", + "@turf/boolean-overlap": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/boolean-point-on-line": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/line-intersect": "7.3.4", + "@types/geojson": "^7946.0.10", + "geojson-polygon-self-intersections": "^1.2.1", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-within": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/boolean-within/-/boolean-within-7.3.4.tgz", + "integrity": "sha512-eLgi803gz0KcYkyxnnqnz9Vd6tw2/0eAExe/Rq8sO0dqypaSiomSumxjqu89d/yo24Qz8gW7c0kJ6YihNbMYxA==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/boolean-point-on-line": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/line-split": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/buffer": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/buffer/-/buffer-7.3.4.tgz", + "integrity": "sha512-MVOCBDuOl3KGDsh2stW12RmiFaFeSkVjeUbZ+ADUtIVnv+jlFsmjBpFtsEw8s9YQn5g0667QppOshm0FBHA57Q==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/center": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/jsts": "^2.7.1", + "@turf/meta": "7.3.4", + "@turf/projection": "7.3.4", + "@types/geojson": "^7946.0.10", + "d3-geo": "1.7.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/center": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/center/-/center-7.3.4.tgz", + "integrity": "sha512-4SsLMDHWthXbyIHsczgFCo4fx+8tC8w2+B5HdEuY+P+cSOOL4T+6QQzd7WWjuN/Y3ndowFssUmwRrvXuwVRxQA==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/center-mean": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/center-mean/-/center-mean-7.3.4.tgz", + "integrity": "sha512-6foVk5HLjlSPr48EI686Eis6/bYrJiHjKQlwY/7YlJc1uDitsIjPw2LjUCGIUZDEd6PdNUgg1+LgI7klXYvW3A==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/center-median": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/center-median/-/center-median-7.3.4.tgz", + "integrity": "sha512-Bz6rDr0plQOGSXgT3X3t941pYd44a5vIY8OEt4Y11H1BsgpmzFc6g7L5mr7FXW/uiYGxOewAfNcVUYUdJf9kMg==", + "dependencies": { + "@turf/center-mean": "7.3.4", + "@turf/centroid": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/center-of-mass": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/center-of-mass/-/center-of-mass-7.3.4.tgz", + "integrity": "sha512-mOSupDF5qxQTA/kOWYletHcBJQ3S2gVl/IRgrBH/YY9yiFq6UGRpZ0sNcIML4H06u/1DY/jqqG+d1nc/1yIA6Q==", + "dependencies": { + "@turf/centroid": "7.3.4", + "@turf/convex": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/centroid": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/centroid/-/centroid-7.3.4.tgz", + "integrity": "sha512-6c3kyTSKBrmiPMe75UkHw6MgedroZ6eR5usEvdlDhXgA3MudFPXIZkMFmMd1h9XeJ9xFfkmq+HPCdF0cOzvztA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/circle": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/circle/-/circle-7.3.4.tgz", + "integrity": "sha512-6ccr5iT51/XONF+pbpkqoRxKX4ZVWLubXb1frGCnClv2suo1UIY9SIlINNctVDupXd2P9PpqZCbrXATrcrokPg==", + "dependencies": { + "@turf/destination": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clean-coords": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/clean-coords/-/clean-coords-7.3.4.tgz", + "integrity": "sha512-S61aJXLvPN/uZHtjzmJbLv7xhi28Sq3PshCIZSvno4Mo45bvl79Vg4aZskrG05AaSSbipplqfH+MZrkW9Xboeg==", + "dependencies": { + "@turf/boolean-point-on-line": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clone": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-7.3.4.tgz", + "integrity": "sha512-pwQ+RyQw986uu7IulY/18NRAebwZZScb084bvVqVkTrllwLSv4oVBqUxmUMiwtp+PNdiRGRFOvNyZqtRsiD+Jw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clusters": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/clusters/-/clusters-7.3.4.tgz", + "integrity": "sha512-+zoSyiF0LilXy4Tr0/lC7IgqbTMZZ2wwP3iSrqre58b61pUtdhCnBcjA2r8FkcW7z3GMbGf5XkIWhO+b+vDSsw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clusters-dbscan": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/clusters-dbscan/-/clusters-dbscan-7.3.4.tgz", + "integrity": "sha512-RkuXf767Shk0AfY+fh0PASVw8YR4H8zYR7XQrCgWd/bCuh6CXs7rWZ6UTLu/PiA6y6WsIhyAQv4LhNH5kCzpbA==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "@types/geokdbush": "^1.1.5", + "geokdbush": "^2.0.1", + "kdbush": "^4.0.2", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clusters-kmeans": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/clusters-kmeans/-/clusters-kmeans-7.3.4.tgz", + "integrity": "sha512-89mlwhcb+vyZAKX0eBa3LQ8VyIKLayrzJpKGb90sEkIu0hDua9JCE+zlbaPoUAvAqflEiX+poFFuh7pngtsBMg==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "skmeans": "0.9.7", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/collect": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/collect/-/collect-7.3.4.tgz", + "integrity": "sha512-fG28oDZK4HCXC/AhF0pmHKLtI9DWwdJr/ktuWolrqzA5b1G7eawrXwDu8B5I3sXhdWonNRMcuLbIuz+XQscHKw==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "rbush": "^3.0.1", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/combine": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/combine/-/combine-7.3.4.tgz", + "integrity": "sha512-wNp9ar4FfpTfQXLZWXQ/jUBBoUFOwRN/mmlv5xrhoYFpP/F5SNy7GVDMZXaBfHdUUplfJUPF5hIKQlCUR8+k3A==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/concave": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/concave/-/concave-7.3.4.tgz", + "integrity": "sha512-HZa1CV2pv4Xpcoe3t5S3ZW6j9jVbc27exzKwZWF7MlFxSz4BKRirWiME8Fku8nvQcGafpfLc+Lwpma+nGvg06w==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/tin": "7.3.4", + "@types/geojson": "^7946.0.10", + "topojson-client": "3.x", + "topojson-server": "3.x", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/convex": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/convex/-/convex-7.3.4.tgz", + "integrity": "sha512-zeNv0fFdOoHuOQB7nl6OLb0DyjvzDvm0e3zlFkph50GF9pEKOmkCSmlniw681aWL2aRBdWZBnON3rRzOS+9C7Q==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "concaveman": "^1.2.1", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/destination": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/destination/-/destination-7.3.4.tgz", + "integrity": "sha512-YxoUJwkKmTHiRFQxMQOP0tz8Vy+ga5EXl+C+F/WubjDLwT1AJu5y8CNIjLvWyjPWckj/vZG4u/1js5bx6MLADA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/difference": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/difference/-/difference-7.3.4.tgz", + "integrity": "sha512-kIxizNQrYLO2rtqUIeed0tPycicrXoipy/g9d4mjv91kzBEbwpyojz9zi8U9G1ISBfCEgA7wsViQD0r+8qzxXw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "polyclip-ts": "^0.16.8", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/dissolve": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/dissolve/-/dissolve-7.3.4.tgz", + "integrity": "sha512-xjGY1gQ4icWhDgsW0YfU2KQtij1+ru34AfvtkVMQEgI86O9EwjW2r9Jq5DJY2PMKPbor3kz9yM/RTOiDP7f3Jg==", + "dependencies": { + "@turf/flatten": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "polyclip-ts": "^0.16.8", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/distance": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-7.3.4.tgz", + "integrity": "sha512-9drWgd46uHPPyzgrcRQLgSvdS/SjVlQ6ZIBoRQagS5P2kSjUbcOXHIMeOSPwfxwlKhEtobLyr+IiR2ns1TfF8w==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/distance-weight": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/distance-weight/-/distance-weight-7.3.4.tgz", + "integrity": "sha512-dVMNEmIluKgn7iQTmzJJOe0UASRNmmSdFX1boAev5MISaW3AvPiURCCOV+lTIeoaQbWRpEAESbAp6JIimXFr8Q==", + "dependencies": { + "@turf/centroid": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/ellipse": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/ellipse/-/ellipse-7.3.4.tgz", + "integrity": "sha512-SMgbERZl12j7H8YaIofmnf0NwAvdF5Wly4tjI/eUhj/sFOKrKXOS1lvCSBJ6uSV9tFijl3ecGOVOlTpURdZ30g==", + "dependencies": { + "@turf/destination": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/transform-rotate": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/envelope": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/envelope/-/envelope-7.3.4.tgz", + "integrity": "sha512-anXSjYMXGAyXT7rpO74VyRI0q/rPAbKE/MYvou+QvG0U/Oa7el0yF4JNNi9wKEAxXg/10aWm9kHp8s2caeLg6A==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/bbox-polygon": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/explode": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/explode/-/explode-7.3.4.tgz", + "integrity": "sha512-7QWhp3f8jhrWjvArhJ74hXBFHMaiJr/2Y1PzHCWue2/pC5MbbTV0o7peehwrrrJC/1uD6CVb3hlcb77IxtMQkw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/flatten": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/flatten/-/flatten-7.3.4.tgz", + "integrity": "sha512-Yt3HCh/qeNaXS4LYhXczFhBfTeaKlTBoxEw1OICb9RT3SiGU0XCxuK7H0W26OLo7XxB0qP7GPs2L3FZbiri6wQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/flip": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/flip/-/flip-7.3.4.tgz", + "integrity": "sha512-HME+kVMTyvcsYVY6dC6DTvuzq8vvDpw+C7PviEqpuT3KcVlBCoGPAqlWRdyWYOb9MDciOqNxvvJF/okpb/GQcg==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/geojson-rbush": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/geojson-rbush/-/geojson-rbush-7.3.4.tgz", + "integrity": "sha512-aDG/5mMCgKduqBwZ3XpLOdlE2hizV3fM+5dHCWyrBepCQLeM/QRvvpBDCdQKDWKpoIBmrGGYDNiOofnf3QmGhg==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "rbush": "^3.0.1", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/great-circle": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/great-circle/-/great-circle-7.3.4.tgz", + "integrity": "sha512-JvfzWFL9efP+xKtOnKzGvwEIXfaN0CLZoPPxNnWa/cVisLs9FVMlC9PWnuL3/3aqH5VhBHPddmU8ipzNE6KIIA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "arc": "^0.2.0", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/helpers": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-7.3.4.tgz", + "integrity": "sha512-U/S5qyqgx3WTvg4twaH0WxF3EixoTCfDsmk98g1E3/5e2YKp7JKYZdz0vivsS5/UZLJeZDEElOSFH4pUgp+l7g==", + "dependencies": { + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/hex-grid": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/hex-grid/-/hex-grid-7.3.4.tgz", + "integrity": "sha512-TDCgBykFdsrP3IOOfToiiLpYkbUb3eEEhM9riIqWht0ubKUY61LN7qVs9bxZD83hG6XaDB6uY7SWkxK1zIEopQ==", + "dependencies": { + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/intersect": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/interpolate": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/interpolate/-/interpolate-7.3.4.tgz", + "integrity": "sha512-lwYSMbHxsXYEWObv0tyBCjwTLXyfsTvOLn/NFhlsGrNCYEXn8I1VPtLGwuxbSdF3hVRgurn8qftkB1npHrNs6Q==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/centroid": "7.3.4", + "@turf/clone": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/hex-grid": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/point-grid": "7.3.4", + "@turf/square-grid": "7.3.4", + "@turf/triangle-grid": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/intersect": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/intersect/-/intersect-7.3.4.tgz", + "integrity": "sha512-VsqMEMeRWWs2mjwI7sTlUgH1cEfugTGhQ0nF8ncHG7YKd9HUUTzIKpn9FJeoguPWIYITcy1ar4yJEOU/hteBVw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "polyclip-ts": "^0.16.8", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/invariant": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-7.3.4.tgz", + "integrity": "sha512-88Eo4va4rce9sNZs6XiMJowWkikM3cS2TBhaCKlU+GFHdNf8PFEpiU42VDU8q5tOF6/fu21Rvlke5odgOGW4AQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/isobands": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/isobands/-/isobands-7.3.4.tgz", + "integrity": "sha512-SFYefwjQdQfF0MV0zfaSwNg9J1wD7mfPP8scGcScKGM3admbwS2A3V8rqPADBfYLD2eCPBDFnySxcl9SHbPung==", + "dependencies": { + "@turf/area": "7.3.4", + "@turf/bbox": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/explode": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/isolines": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/isolines/-/isolines-7.3.4.tgz", + "integrity": "sha512-UFRIULkIgkZOmrhLxExWvguixbzfoCgVcXIqo2Cp68do4v+nwc3pTM7MTt4DBVFloIdX0Usrn4K44LQ/V05gxg==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/jsts": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@turf/jsts/-/jsts-2.7.2.tgz", + "integrity": "sha512-zAezGlwWHPyU0zxwcX2wQY3RkRpwuoBmhhNE9HY9kWhFDkCxZ3aWK5URKwa/SWKJbj9aztO+8vtdiBA28KVJFg==", + "dependencies": { + "jsts": "2.7.1" + } + }, + "node_modules/@turf/kinks": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/kinks/-/kinks-7.3.4.tgz", + "integrity": "sha512-LZTKELWxvXl0vc9ZxVgi0v07fO9+2FrZOam2B10fz/eGjy3oKNazU5gjggbnc499wEIcJS4hN+VyjQZrmsJAdQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/length": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/length/-/length-7.3.4.tgz", + "integrity": "sha512-Dg1GnQ/B2go5NIWXt91N4L7XTjIgIWCftBSYIXkrpIM7QGjItzglek0Z5caytvb8ZRWXzZOGs8//+Q5we91WuQ==", + "dependencies": { + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-arc": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-arc/-/line-arc-7.3.4.tgz", + "integrity": "sha512-nqZ+JKjDVIrvREFHgtJIP9Ps4WbWw3eStqdIzAPolrzoXyAZnpIKquyfRTxpJFYUUjDmf+uQ/SFWsPP4SOWAqQ==", + "dependencies": { + "@turf/circle": "7.3.4", + "@turf/destination": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-chunk": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-chunk/-/line-chunk-7.3.4.tgz", + "integrity": "sha512-xWEHR99EpUO5ZPEZhMfa0QvnFZC0W+QLxB1GcJcSeJAQ5ZMXUXY8doKF1Nztk0eppawMprEEO3nQWLvQoR4z2g==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/length": "7.3.4", + "@turf/line-slice-along": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-intersect": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-intersect/-/line-intersect-7.3.4.tgz", + "integrity": "sha512-XygbTvHa6A+v6l2ZKYtS8AAWxwmrPxKxfBbdH75uED1JvdytSLWYTKGlcU3soxd9sYb4x/g9sDvRIVyU6Lucrg==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "sweepline-intersections": "^1.5.0", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-offset": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-offset/-/line-offset-7.3.4.tgz", + "integrity": "sha512-CSrg3njde9Tx+C0oL+BHUpZYpgD+PEmzp0ldDNis5ZQiTe5tUrwiIyG7A/QXf9eDnGhtV1WhCAycX0Wjged4pg==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-overlap": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-overlap/-/line-overlap-7.3.4.tgz", + "integrity": "sha512-3GBECiwNAQ2MmSwiqAHMweIl+EiePK0Jx4fXxF1KFE+NGCDv/MbGcEYfAbmsTg8mg6oRI9D8fJZzrT44DHpHXA==", + "dependencies": { + "@turf/boolean-point-on-line": "7.3.4", + "@turf/geojson-rbush": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/line-segment": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/nearest-point-on-line": "7.3.4", + "@types/geojson": "^7946.0.10", + "fast-deep-equal": "^3.1.3", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-segment": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-segment/-/line-segment-7.3.4.tgz", + "integrity": "sha512-UeISzf/JHoWEY5yeoyvKwA5epWcvJMCpCwbIMolvfTC5pp+IVozjHPVCRvRWuzmbmAvetcW0unL5bjqi0ADmuQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-slice": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-slice/-/line-slice-7.3.4.tgz", + "integrity": "sha512-6Vt4Eptdr2C5T+jtpbo8D4v8b6X7KqYonPPyMB6huv+Kcg3nz4JRI9OQCDCaon9rWvU3ffWwjsjcbJCQS9o0sA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/nearest-point-on-line": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-slice-along": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-slice-along/-/line-slice-along-7.3.4.tgz", + "integrity": "sha512-RT5HydNy8+m9Y3u39USeYZauG2EyMqCYoLnTpWcAxbZGdq9WjIwdzAwYir3d8eJkOzjlR6Khz071VM4Ufqs0Kg==", + "dependencies": { + "@turf/bearing": "7.3.4", + "@turf/destination": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-split": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-split/-/line-split-7.3.4.tgz", + "integrity": "sha512-l1zmCSUnGsiN4gf22Aw91a2VnYs5DZS67FdkYqKgr+wPEAL/gpQgIBBWSTmhwY8zb3NEqty+f/gMEe8EJAWYng==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/geojson-rbush": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/line-intersect": "7.3.4", + "@turf/line-segment": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/nearest-point-on-line": "7.3.4", + "@turf/truncate": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-to-polygon": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/line-to-polygon/-/line-to-polygon-7.3.4.tgz", + "integrity": "sha512-vRnDHjzwOroC74/fsJEU+dUeGhiR/B2bG0/HeEWRBplAjmwVPptRBmDGtXKTz8sbA6or17/XtOITp3zTU0lBZw==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/mask": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/mask/-/mask-7.3.4.tgz", + "integrity": "sha512-FJIlSk8m0AiqzNoLSMdYuhDRif6aeOYVdW/WxjEjpUoMalwy2w5MMlZqJB9zxt/xSrMq6lvTWJgZfZfGL2s4ZQ==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "polyclip-ts": "^0.16.8", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/meta": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-7.3.4.tgz", + "integrity": "sha512-tlmw9/Hs1p2n0uoHVm1w3ugw1I6L8jv9YZrcdQa4SH5FX5UY0ATrKeIvfA55FlL//PGuYppJp+eyg/0eb4goqw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/midpoint": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/midpoint/-/midpoint-7.3.4.tgz", + "integrity": "sha512-/XAeGvsz8l5HaqcP7TUlexzGfibqXozQgBZ8rH7az6op2Dfm3pL/Z7bKLHoVavM0ccBg0Pt7g6j9NM54kZWdKA==", + "dependencies": { + "@turf/bearing": "7.3.4", + "@turf/destination": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/moran-index": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/moran-index/-/moran-index-7.3.4.tgz", + "integrity": "sha512-SNb16szwEG0OiyNn3z9zvSnk3M3tfwvvN8i//9UIC32APEApI+MRXCl93H/qZkKMhhh/cHA0pF0pjYZwl5z8Ow==", + "dependencies": { + "@turf/distance-weight": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/nearest-neighbor-analysis": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/nearest-neighbor-analysis/-/nearest-neighbor-analysis-7.3.4.tgz", + "integrity": "sha512-8EZlDy5poU0t7BDy8KTzOmfiGsAs2kWuB3/kgI4sMdbThKVk2P4hHKuToCSGvqAzwSy3B2qKYM1N6JeVWytu+w==", + "dependencies": { + "@turf/area": "7.3.4", + "@turf/bbox": "7.3.4", + "@turf/bbox-polygon": "7.3.4", + "@turf/centroid": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/nearest-point": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/nearest-point": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/nearest-point/-/nearest-point-7.3.4.tgz", + "integrity": "sha512-WfI09f2bX0nKx/jkO7zCt3tUrJulyAlUYQtZHP7lWYMCOmZ6Pq26D6lKWjpfs2it0OHbhlx1XF/UupEUaz830w==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/nearest-point-on-line": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/nearest-point-on-line/-/nearest-point-on-line-7.3.4.tgz", + "integrity": "sha512-DQrP3lRju83rIXFN68tUEpc7ki/eRwdwBkK2CTT4RAcyCxbcH2NGJPQv8dYiww/Ar77u1WLVn+aINXZH904dWw==", + "dependencies": { + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/nearest-point-to-line": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/nearest-point-to-line/-/nearest-point-to-line-7.3.4.tgz", + "integrity": "sha512-Nzp3ojQt0gDACNYG+oNWymRXAUCey0LzdiSezYtRwdA0/+FQCtuxP8Lbc8FftV10JL8D78/CRlmt7omaXLLXCg==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/point-to-line-distance": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/planepoint": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/planepoint/-/planepoint-7.3.4.tgz", + "integrity": "sha512-KAhMAnddbuWIEZuk2bK//g+xTeKn8aV9N2AaE27x6JMJyV/wqvatIuVVqEIXI3SkAFbhiVBpVuarvPYhrJ+fhg==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/point-grid": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/point-grid/-/point-grid-7.3.4.tgz", + "integrity": "sha512-9CL3OJ4dEt266+fxYlOQeRFqAY3XtsAuak2Gpk+K8k+Y3yGv8pvyn3QaAQ6P2npbiKt0zfG8Md/+HBAPOMPQ0A==", + "dependencies": { + "@turf/boolean-within": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/point-on-feature": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/point-on-feature/-/point-on-feature-7.3.4.tgz", + "integrity": "sha512-tQfIxsJUxZqyO7OeJC25y3DqN9i4fmrAt4TBrPvZcIIwymgN7aMrElJKlg/dfi7JDihKp3h/CkWMjtMQA14Vwg==", + "dependencies": { + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/center": "7.3.4", + "@turf/explode": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/nearest-point": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/point-to-line-distance": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/point-to-line-distance/-/point-to-line-distance-7.3.4.tgz", + "integrity": "sha512-IdPAxlAQZj7FCZg+ObyVHlNdqwLL/oxYoQjpxMNJ511gNxokCtEv0aeRZQjYOYIxr9Ss97v3yo3ILJaF9V2kPw==", + "dependencies": { + "@turf/bearing": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/nearest-point-on-line": "7.3.4", + "@turf/projection": "7.3.4", + "@turf/rhumb-bearing": "7.3.4", + "@turf/rhumb-distance": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/point-to-polygon-distance": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/point-to-polygon-distance/-/point-to-polygon-distance-7.3.4.tgz", + "integrity": "sha512-VxbkgHyzCkYWSxirqSUqw+lzbYmTf2qFhVZ/T5dprhwyXWcgalpupvgRzmZmjKkgsoJ017vrvCNKZRaCCn+Z7Q==", + "dependencies": { + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/point-to-line-distance": "7.3.4", + "@turf/polygon-to-line": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/points-within-polygon": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/points-within-polygon/-/points-within-polygon-7.3.4.tgz", + "integrity": "sha512-HfT83Iw99zywDfCp+nJwS+JDzH+GdNug0sut9WDjGEznHKoZyAcOk+hGKL/ja8TeCLx9VsZHOiVCQFm+NTgvgA==", + "dependencies": { + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/polygon-smooth": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/polygon-smooth/-/polygon-smooth-7.3.4.tgz", + "integrity": "sha512-AnpaGgNYVvP/dfz10id3AotDrUh9O+4unXCk3es1ff51VrpUhVgH3H+zyTSbVL4zAXN/ejPb8UnKCxDvNOQs4g==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/polygon-tangents": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/polygon-tangents/-/polygon-tangents-7.3.4.tgz", + "integrity": "sha512-D1IFocXJYF8PUMZ+BmnOstyRrzklqC86FgakYVk9O61F9Ki8LhMGaRfF+6reKMD473KvHvEf1M2EgmGt+OHDRw==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/boolean-within": "7.3.4", + "@turf/explode": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/nearest-point": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/polygon-to-line": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/polygon-to-line/-/polygon-to-line-7.3.4.tgz", + "integrity": "sha512-xhmOZ5rHZAKLUDLeYKWMsX84ip8CCGOcGLBHtPPYOjdIDHddMV6Sxt5kVgkmlZpK6NEWEmOD6lYR4obxHcHlGA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/polygonize": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/polygonize/-/polygonize-7.3.4.tgz", + "integrity": "sha512-kmj05rkJ4tE8LvbQ4GVsL5GOrRiX/F5W4RIdxo8gPGTw1Y5oLG/1vFk6Hg6x63L1WcdNtF0sq6AdEI0G9BXWXA==", + "dependencies": { + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/envelope": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/projection": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/projection/-/projection-7.3.4.tgz", + "integrity": "sha512-p91zOaLmzoBHzU/2H6Ot1tOhTmAom85n1P7I4Oo0V9xU8hmJXWfNnomLFf/6rnkKDIFZkncLQIBz4iIecZ61sA==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/quadrat-analysis": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/quadrat-analysis/-/quadrat-analysis-7.3.4.tgz", + "integrity": "sha512-Yxqq8wgrDiXIX+s0uOZ2exmYfRwTIcUX8J7j4P+sbyLVbyN8W3AjN2s5ZX21P0aFf3v24FBd2fNWlm5VmMUAdg==", + "dependencies": { + "@turf/area": "7.3.4", + "@turf/bbox": "7.3.4", + "@turf/bbox-polygon": "7.3.4", + "@turf/centroid": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/point-grid": "7.3.4", + "@turf/random": "7.3.4", + "@turf/square-grid": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/random": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/random/-/random-7.3.4.tgz", + "integrity": "sha512-CXMS5XDoI5x0zc1aCYbn3t603k8hjaFHNsSOvGBW20z68cwP0UwMQQr0KLqFPqI4J1O7dMX+urn8IHH27RXFYg==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rectangle-grid": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/rectangle-grid/-/rectangle-grid-7.3.4.tgz", + "integrity": "sha512-qM7vujJ4wndB4MKZlEcnUSawgvs5wXpSEFf4f+LWRIfmGhtv6serzDqFzWcmy8kF8hg5J465PMktRmAFWq/a+w==", + "dependencies": { + "@turf/boolean-intersects": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rewind": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-7.3.4.tgz", + "integrity": "sha512-4BZ8MHMujl4NAT7XnIs7JoOuDhpR96oDTB0RtqTeIP4onioIedVnw1ZA3Uq08sILGpR0qKLuDsvdz4x9jtbptg==", + "dependencies": { + "@turf/boolean-clockwise": "7.3.4", + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rhumb-bearing": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/rhumb-bearing/-/rhumb-bearing-7.3.4.tgz", + "integrity": "sha512-tvX1toSo80q0iL0cUMMXpSKsCCfOjRqDGCmOdR6B9shhk6xP1ZM2PLQDr+MFPBFeGyQuyY4CNFkV2+3DF49vYw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rhumb-destination": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/rhumb-destination/-/rhumb-destination-7.3.4.tgz", + "integrity": "sha512-6HikEb5nm2A18FQWk6vVLMQkc099I/7c69j47RYM27xQK8J8uBCNk1zLYyMPcZTh24xcNSbZ1iPHDsDOqw6wWQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rhumb-distance": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/rhumb-distance/-/rhumb-distance-7.3.4.tgz", + "integrity": "sha512-phwskeijdgYMsR3qDQmytfsg2iZcp3uWK7UFc76wKTEpxozbDGFI4enX5gXvZPpyI1iD7gsktGqHsO33AjnFDA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/sample": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/sample/-/sample-7.3.4.tgz", + "integrity": "sha512-XzAATg09c2XYAXkIBbg8lktSrU1tXNjJYXtbVwF6jLp1q2wTRpwb+mZpTEPAwzZwVF81uR5c0CsdQyr5UHINVw==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/sector": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/sector/-/sector-7.3.4.tgz", + "integrity": "sha512-x2tNAXl21HRcF302ghU5ohE/vmmfDcXpQKgoWHyi7o5Q9kDRBwy7kbvr5YxbT3vwW/kAWUDYM7FoXNH42bXgCw==", + "dependencies": { + "@turf/circle": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/line-arc": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/shortest-path": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/shortest-path/-/shortest-path-7.3.4.tgz", + "integrity": "sha512-xbK/oM+JRL+lJCHkAdZ3QPgoivT40J9WKJ0d1Ddt8LXTpzX2YeJVgcwOZaBPG9ncZUzHfHIWS1rUjc54clnZcg==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/bbox-polygon": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/clean-coords": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/transform-scale": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/simplify": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/simplify/-/simplify-7.3.4.tgz", + "integrity": "sha512-OoSwu3vI0H9P+GzLDaOJIL9v0V8ubeP8wQjM8GeMEZrq6U2uh9JWQnAU+jviT3ODcKF5H+88snpiMik585L0wA==", + "dependencies": { + "@turf/clean-coords": "7.3.4", + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/square": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/square/-/square-7.3.4.tgz", + "integrity": "sha512-vJ+NeiEaOVsb8YiUExtyIgvH+ZybthHszl2TASZn5q340ioKHPb2JeHGlbgrB2x8pEMh3MVhoqxAbXDuND/cnw==", + "dependencies": { + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/square-grid": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/square-grid/-/square-grid-7.3.4.tgz", + "integrity": "sha512-MgjlVRklQYFfQm9yJNha9kXothLPliVdeycNdmn4lWLH3SOZe1rqJPB5Z9+dhmJELT3BJraDq3W5ik5taEpKyQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/rectangle-grid": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/standard-deviational-ellipse": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/standard-deviational-ellipse/-/standard-deviational-ellipse-7.3.4.tgz", + "integrity": "sha512-+BaetOKN8zA2mQCVTcRWMcfidNR3JkjmYj0r5iGRncK0J+pdxIjX2q6sF6yBMOOxMoEMy393P7j07HdBIPbibw==", + "dependencies": { + "@turf/center-mean": "7.3.4", + "@turf/ellipse": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/points-within-polygon": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/tag": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/tag/-/tag-7.3.4.tgz", + "integrity": "sha512-ienLhLzBLeChtKhbJMmU3/vGg0hWzi6Wh/q0n39W4CmdNb+yAoGQhlYjcCbPOJT4IcdFlWE3OhbP9EmH/xPgfg==", + "dependencies": { + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/tesselate": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/tesselate/-/tesselate-7.3.4.tgz", + "integrity": "sha512-NnDgVb5ZchJEhEpq1je2hktS5UhnHMfeeumxZQgnIoMeGILpJtcOL//b/1biBBUVSJ0ZZg5zxiHdQc1PgK2gxA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "earcut": "^2.2.4", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/tesselate/node_modules/earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" + }, + "node_modules/@turf/tin": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/tin/-/tin-7.3.4.tgz", + "integrity": "sha512-tuegrGlbKPp6Dm8r5SuYDtQ2EVzdXVVxelqI1agnzj9N+l8oTBIKLRxRbBkLsizeVIDnlmVHCQB6cRc3v+u8JQ==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/transform-rotate": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/transform-rotate/-/transform-rotate-7.3.4.tgz", + "integrity": "sha512-pbUG6QLwyJvvitq4aAq4IQH79X8T0NmEPUGDUEEP69yW7t4+UZjDBAVbCKwpOc8gtsK0K5yvxlZ0e2CdtpNmEw==", + "dependencies": { + "@turf/centroid": "7.3.4", + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/rhumb-bearing": "7.3.4", + "@turf/rhumb-destination": "7.3.4", + "@turf/rhumb-distance": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/transform-scale": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/transform-scale/-/transform-scale-7.3.4.tgz", + "integrity": "sha512-7gUIFFHaU3Ewj3rCzIu5Yo7Zjfv4R2ypjh6UWiMJnDavb7RQ8fn0AKKcNMA/vF/yxuncp2l3zoa2gygv4AKM8A==", + "dependencies": { + "@turf/bbox": "7.3.4", + "@turf/center": "7.3.4", + "@turf/centroid": "7.3.4", + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/rhumb-bearing": "7.3.4", + "@turf/rhumb-destination": "7.3.4", + "@turf/rhumb-distance": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/transform-translate": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/transform-translate/-/transform-translate-7.3.4.tgz", + "integrity": "sha512-qbSIEueOR8mNB7p4EB88vHvUAyuSBM8zxP68UiiTNV3Gh+OZF2VXTFiu3EFYMTaD9sE6Lxmzvv3fjW8N2q82pw==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/rhumb-destination": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/triangle-grid": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/triangle-grid/-/triangle-grid-7.3.4.tgz", + "integrity": "sha512-0bki10XwYvNcPzDcSs5kUh3niOogdVeFtawJEz5FdlyTAUohbNlC+Vb40K//OqEyTrGII+q1/dE4q+1J6ZCmDA==", + "dependencies": { + "@turf/distance": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/intersect": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/truncate": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/truncate/-/truncate-7.3.4.tgz", + "integrity": "sha512-VPXdae9+RLLM19FMrJgt7QANBikm7DxPbfp/dXgzE4Ca7v+mJ4T1fYc7gCZDaqOrWMccHKbvv4iSuW7YZWdIIA==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/turf": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/turf/-/turf-7.3.4.tgz", + "integrity": "sha512-uMAKLYt2tWJj8xIepq4vExF1r8fzJviP/5l/elDHuRyauI2mASy/Gox6kSFlrN0t0p8AT4Cs8o//4GuJTXyC+Q==", + "dependencies": { + "@turf/along": "7.3.4", + "@turf/angle": "7.3.4", + "@turf/area": "7.3.4", + "@turf/bbox": "7.3.4", + "@turf/bbox-clip": "7.3.4", + "@turf/bbox-polygon": "7.3.4", + "@turf/bearing": "7.3.4", + "@turf/bezier-spline": "7.3.4", + "@turf/boolean-clockwise": "7.3.4", + "@turf/boolean-concave": "7.3.4", + "@turf/boolean-contains": "7.3.4", + "@turf/boolean-crosses": "7.3.4", + "@turf/boolean-disjoint": "7.3.4", + "@turf/boolean-equal": "7.3.4", + "@turf/boolean-intersects": "7.3.4", + "@turf/boolean-overlap": "7.3.4", + "@turf/boolean-parallel": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/boolean-point-on-line": "7.3.4", + "@turf/boolean-touches": "7.3.4", + "@turf/boolean-valid": "7.3.4", + "@turf/boolean-within": "7.3.4", + "@turf/buffer": "7.3.4", + "@turf/center": "7.3.4", + "@turf/center-mean": "7.3.4", + "@turf/center-median": "7.3.4", + "@turf/center-of-mass": "7.3.4", + "@turf/centroid": "7.3.4", + "@turf/circle": "7.3.4", + "@turf/clean-coords": "7.3.4", + "@turf/clone": "7.3.4", + "@turf/clusters": "7.3.4", + "@turf/clusters-dbscan": "7.3.4", + "@turf/clusters-kmeans": "7.3.4", + "@turf/collect": "7.3.4", + "@turf/combine": "7.3.4", + "@turf/concave": "7.3.4", + "@turf/convex": "7.3.4", + "@turf/destination": "7.3.4", + "@turf/difference": "7.3.4", + "@turf/dissolve": "7.3.4", + "@turf/distance": "7.3.4", + "@turf/distance-weight": "7.3.4", + "@turf/ellipse": "7.3.4", + "@turf/envelope": "7.3.4", + "@turf/explode": "7.3.4", + "@turf/flatten": "7.3.4", + "@turf/flip": "7.3.4", + "@turf/geojson-rbush": "7.3.4", + "@turf/great-circle": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/hex-grid": "7.3.4", + "@turf/interpolate": "7.3.4", + "@turf/intersect": "7.3.4", + "@turf/invariant": "7.3.4", + "@turf/isobands": "7.3.4", + "@turf/isolines": "7.3.4", + "@turf/kinks": "7.3.4", + "@turf/length": "7.3.4", + "@turf/line-arc": "7.3.4", + "@turf/line-chunk": "7.3.4", + "@turf/line-intersect": "7.3.4", + "@turf/line-offset": "7.3.4", + "@turf/line-overlap": "7.3.4", + "@turf/line-segment": "7.3.4", + "@turf/line-slice": "7.3.4", + "@turf/line-slice-along": "7.3.4", + "@turf/line-split": "7.3.4", + "@turf/line-to-polygon": "7.3.4", + "@turf/mask": "7.3.4", + "@turf/meta": "7.3.4", + "@turf/midpoint": "7.3.4", + "@turf/moran-index": "7.3.4", + "@turf/nearest-neighbor-analysis": "7.3.4", + "@turf/nearest-point": "7.3.4", + "@turf/nearest-point-on-line": "7.3.4", + "@turf/nearest-point-to-line": "7.3.4", + "@turf/planepoint": "7.3.4", + "@turf/point-grid": "7.3.4", + "@turf/point-on-feature": "7.3.4", + "@turf/point-to-line-distance": "7.3.4", + "@turf/point-to-polygon-distance": "7.3.4", + "@turf/points-within-polygon": "7.3.4", + "@turf/polygon-smooth": "7.3.4", + "@turf/polygon-tangents": "7.3.4", + "@turf/polygon-to-line": "7.3.4", + "@turf/polygonize": "7.3.4", + "@turf/projection": "7.3.4", + "@turf/quadrat-analysis": "7.3.4", + "@turf/random": "7.3.4", + "@turf/rectangle-grid": "7.3.4", + "@turf/rewind": "7.3.4", + "@turf/rhumb-bearing": "7.3.4", + "@turf/rhumb-destination": "7.3.4", + "@turf/rhumb-distance": "7.3.4", + "@turf/sample": "7.3.4", + "@turf/sector": "7.3.4", + "@turf/shortest-path": "7.3.4", + "@turf/simplify": "7.3.4", + "@turf/square": "7.3.4", + "@turf/square-grid": "7.3.4", + "@turf/standard-deviational-ellipse": "7.3.4", + "@turf/tag": "7.3.4", + "@turf/tesselate": "7.3.4", + "@turf/tin": "7.3.4", + "@turf/transform-rotate": "7.3.4", + "@turf/transform-scale": "7.3.4", + "@turf/transform-translate": "7.3.4", + "@turf/triangle-grid": "7.3.4", + "@turf/truncate": "7.3.4", + "@turf/union": "7.3.4", + "@turf/unkink-polygon": "7.3.4", + "@turf/voronoi": "7.3.4", + "@types/geojson": "^7946.0.10", + "@types/kdbush": "^3.0.5", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/union": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/union/-/union-7.3.4.tgz", + "integrity": "sha512-JJYyPMmGcrTa9sPv2ief2QU9Hb//cEAU1zgKu/OfoCMa9a8Imp5QVm9UTAkhGlc+4qm/N/X16iJ+cvVWaxPjkg==", + "dependencies": { + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "polyclip-ts": "^0.16.8", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/unkink-polygon": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/unkink-polygon/-/unkink-polygon-7.3.4.tgz", + "integrity": "sha512-dFIqTLAnLL5D3OANPJtRb5OvmOM81GlNCjwgjlLQy0xdpYgKwGdE+gNXjygDrPUUXNc22xnaj3EfAfC3Pq7W4Q==", + "dependencies": { + "@turf/area": "7.3.4", + "@turf/boolean-point-in-polygon": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/meta": "7.3.4", + "@types/geojson": "^7946.0.10", + "rbush": "^3.0.1", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/voronoi": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@turf/voronoi/-/voronoi-7.3.4.tgz", + "integrity": "sha512-cwKSiDzDHRnA7yafQ1zOhWxRuMzp+fYFFzadCdByBAG1jAD7UlFwKhS1fjNPBNs67Fl5X3LL5ahCLW5gEdFgmg==", + "dependencies": { + "@turf/clone": "7.3.4", + "@turf/helpers": "7.3.4", + "@turf/invariant": "7.3.4", + "@types/d3-voronoi": "^1.1.12", + "@types/geojson": "^7946.0.10", + "d3-voronoi": "1.1.2", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", @@ -1536,6 +3468,11 @@ "assertion-error": "^2.0.1" } }, + "node_modules/@types/d3-voronoi": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.12.tgz", + "integrity": "sha512-DauBl25PKZZ0WVJr42a6CNvI6efsdzofl9sajqZr2Gf5Gu733WkDdUGiPkUHXiUvYGzNNlFQde2wdZdfQPG+yw==" + }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", @@ -1553,6 +3490,24 @@ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==" }, + "node_modules/@types/geokdbush": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@types/geokdbush/-/geokdbush-1.1.5.tgz", + "integrity": "sha512-jIsYnXY+RQ/YCyBqeEHxYN9mh+7PqKJUJUp84wLfZ7T2kqyVPNaXwZuvf1A2uQUkrvVqEbsG94ff8jH32AlLvA==", + "dependencies": { + "@types/kdbush": "^1" + } + }, + "node_modules/@types/geokdbush/node_modules/@types/kdbush": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/kdbush/-/kdbush-1.0.7.tgz", + "integrity": "sha512-QM5iB8m/0mnGOjUKshErIZQ0LseyTieRSYc3yaOpmrRM0xbWiOuJUWlduJx+TPNK7/VFMWphUGwx3nus7eT1Wg==" + }, + "node_modules/@types/kdbush": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/kdbush/-/kdbush-3.0.5.tgz", + "integrity": "sha512-tdJz7jaWFu4nR+8b2B+CdPZ6811ighYylWsu2hpsivapzW058yP0KdfZuNY89IiRe5jbKvBGXN3LQdN2KPXVdQ==" + }, "node_modules/@types/supercluster": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", @@ -1712,6 +3667,14 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/arc": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/arc/-/arc-0.2.0.tgz", + "integrity": "sha512-8NFOo126uYKQJyXNSLY/jSklgfLQL+XWAcPXGo876JwEQ8nSOPXWNI3TV2jLZMN8QEw8uksJ1ZwS4npjBca8MA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", @@ -1766,6 +3729,14 @@ "require-from-string": "^2.0.2" } }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "engines": { + "node": "*" + } + }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -1876,6 +3847,27 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/concaveman": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/concaveman/-/concaveman-1.2.1.tgz", + "integrity": "sha512-PwZYKaM/ckQSa8peP5JpVr7IMJ4Nn/MHIaWUjP4be+KoZ7Botgs8seAZGpmaOM+UZXawcdYRao/px9ycrCihHw==", + "dependencies": { + "point-in-polygon": "^1.1.0", + "rbush": "^3.0.1", + "robust-predicates": "^2.0.4", + "tinyqueue": "^2.0.3" + } + }, + "node_modules/concaveman/node_modules/tinyqueue": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", + "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -1901,6 +3893,24 @@ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, + "node_modules/d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "node_modules/d3-geo": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.7.1.tgz", + "integrity": "sha512-O4AempWAr+P5qbk2bC2FuN/sDW4z+dN2wDf9QV3bxQt4M5HfOEeXLgJ/UKQW0+o1Dj8BE+L5kiDbdWUMjsmQpw==", + "dependencies": { + "d3-array": "1" + } + }, + "node_modules/d3-voronoi": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", + "integrity": "sha512-RhGS1u2vavcO7ay7ZNAPo4xeDh/VYeGof3x5ZLJBQgYhLegxr3s5IykvWmJ94FTU6mcbtp4sloqZ54mP6R4Utw==" + }, "node_modules/data-urls": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", @@ -2121,6 +4131,11 @@ "node": ">=12.0.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -2203,6 +4218,48 @@ "node": ">=6.9.0" } }, + "node_modules/geojson-equality-ts": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/geojson-equality-ts/-/geojson-equality-ts-1.0.2.tgz", + "integrity": "sha512-h3Ryq+0mCSN/7yLs0eDgrZhvc9af23o/QuC4aTiuuzP/MRCtd6mf5rLsLRY44jX0RPUfM8c4GqERQmlUxPGPoQ==", + "dependencies": { + "@types/geojson": "^7946.0.14" + } + }, + "node_modules/geojson-polygon-self-intersections": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/geojson-polygon-self-intersections/-/geojson-polygon-self-intersections-1.2.2.tgz", + "integrity": "sha512-6XRNF4CsRHYmR9z5YuIk5f/aOototnDf0dgMqYGcS7y1l57ttt6MAIAxl3rXyas6lq1HEbTuLMh4PgvO+OV42w==", + "dependencies": { + "rbush": "^2.0.1" + } + }, + "node_modules/geojson-polygon-self-intersections/node_modules/quickselect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-1.1.1.tgz", + "integrity": "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ==" + }, + "node_modules/geojson-polygon-self-intersections/node_modules/rbush": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-2.0.2.tgz", + "integrity": "sha512-XBOuALcTm+O/H8G90b6pzu6nX6v2zCKiFG4BJho8a+bY6AER6t8uQUZdi5bomQc0AprCWhEGa7ncAbbRap0bRA==", + "dependencies": { + "quickselect": "^1.0.1" + } + }, + "node_modules/geokdbush": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/geokdbush/-/geokdbush-2.0.1.tgz", + "integrity": "sha512-0M8so1Qx6+jJ1xpirpCNrgUsWAzIcQ3LrLmh0KJPBYI3gH7vy70nY5zEEjSp9Tn0nBt6Q2Fh922oL08lfib4Zg==", + "dependencies": { + "tinyqueue": "^2.0.3" + } + }, + "node_modules/geokdbush/node_modules/tinyqueue": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", + "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -2401,6 +4458,14 @@ "node": ">=6" } }, + "node_modules/jsts": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/jsts/-/jsts-2.7.1.tgz", + "integrity": "sha512-x2wSZHEBK20CY+Wy+BPE7MrFQHW6sIsdaGUMEqmGAio+3gFzQaBYPwLRonUfQf9Ak8pBieqj9tUofX1+WtAEIg==", + "engines": { + "node": ">= 12" + } + }, "node_modules/kdbush": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", @@ -2614,6 +4679,33 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/point-in-polygon": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", + "integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==" + }, + "node_modules/point-in-polygon-hao": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/point-in-polygon-hao/-/point-in-polygon-hao-1.2.4.tgz", + "integrity": "sha512-x2pcvXeqhRHlNRdhLs/tgFapAbSSe86wa/eqmj1G6pWftbEs5aVRJhRGM6FYSUERKu0PjekJzMq0gsI2XyiclQ==", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/point-in-polygon-hao/node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, + "node_modules/polyclip-ts": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/polyclip-ts/-/polyclip-ts-0.16.8.tgz", + "integrity": "sha512-JPtKbDRuPEuAjuTdhR62Gph7Is2BS1Szx69CFOO3g71lpJDFo78k4tFyi+qFOMVPePEzdSKkpGU3NBXPHHjvKQ==", + "dependencies": { + "bignumber.js": "^9.1.0", + "splaytree-ts": "^1.0.2" + } + }, "node_modules/postcss": { "version": "8.5.8", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", @@ -2686,6 +4778,19 @@ "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==" }, + "node_modules/rbush": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", + "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", + "dependencies": { + "quickselect": "^2.0.0" + } + }, + "node_modules/rbush/node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + }, "node_modules/react": { "version": "19.2.4", "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", @@ -2751,6 +4856,11 @@ "protocol-buffers-schema": "^3.3.1" } }, + "node_modules/robust-predicates": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", + "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==" + }, "node_modules/rollup": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", @@ -2832,6 +4942,11 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, + "node_modules/skmeans": { + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/skmeans/-/skmeans-0.9.7.tgz", + "integrity": "sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg==" + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2841,6 +4956,11 @@ "node": ">=0.10.0" } }, + "node_modules/splaytree-ts": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/splaytree-ts/-/splaytree-ts-1.0.2.tgz", + "integrity": "sha512-0kGecIZNIReCSiznK3uheYB8sbstLjCZLiwcQwbmLhgHJj2gz6OnSPkVzJQCMnmEz1BQ4gPK59ylhBoEWOhGNA==" + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -2891,6 +5011,19 @@ "kdbush": "^4.0.2" } }, + "node_modules/sweepline-intersections": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sweepline-intersections/-/sweepline-intersections-1.5.0.tgz", + "integrity": "sha512-AoVmx72QHpKtItPu72TzFL+kcYjd67BPLDoR0LarIk+xyaRg+pDTMFXndIEvZf9xEKnJv6JdhgRMnocoG0D3AQ==", + "dependencies": { + "tinyqueue": "^2.0.0" + } + }, + "node_modules/sweepline-intersections/node_modules/tinyqueue": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", + "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -2975,6 +5108,30 @@ "integrity": "sha512-5WJ2SqFsv4G2Dwi7ZFVRnz6b2H1od39QME1lc2y5Ew3eWiZMAeqOAfWpRP9jHvhUl881406QtZTODvjttJs+ew==", "dev": true }, + "node_modules/topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "dependencies": { + "commander": "2" + }, + "bin": { + "topo2geo": "bin/topo2geo", + "topomerge": "bin/topomerge", + "topoquantize": "bin/topoquantize" + } + }, + "node_modules/topojson-server": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/topojson-server/-/topojson-server-3.0.1.tgz", + "integrity": "sha512-/VS9j/ffKr2XAOjlZ9CgyyeLmgJ9dMwq6Y0YEON8O7p/tGGk+dCWnrE03zEdu7i4L7YsFZLEPZPzCvcB7lEEXw==", + "dependencies": { + "commander": "2" + }, + "bin": { + "geo2topo": "bin/geo2topo" + } + }, "node_modules/tough-cookie": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", @@ -2999,6 +5156,11 @@ "node": ">=20" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, "node_modules/undici": { "version": "7.24.4", "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.4.tgz", diff --git a/frontend/package.json b/frontend/package.json index 7d67f60..af076f1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "private": true, "dependencies": { + "@turf/turf": "^7.3.4", "axios": "^1.7.9", "maplibre-gl": "^5.20.1", "react": "^19.2.1", diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index d0acf89..b230706 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -16,20 +16,32 @@ const APP = () => { const [mapStyle, setMapStyle] = useState('light'); // 'light' or 'dark' const [tolerance, setTolerance] = useState(50); const [selectedCity, setSelectedCity] = useState(null); + const [isLocked, setIsLocked] = useState(false); useEffect(() => { - // Initialize MapLibre map + // Initialize MapLibre map - ONLY ONCE mapRef.current = new maplibregl.Map({ container: mapContainerRef.current, style: getMapStyle(mapStyle), center: [-0.1278, 51.5074], // London - zoom: 3, - pitch: 0 + zoom: 2, + pitch: 0, + projection: 'globe' // Enable 3D Globe }); mapRef.current.on('load', () => { console.log('Map loaded successfully'); + // Add atmosphere/sky effects (MapLibre v5 uses setSky) + mapRef.current.setSky({ + 'sky-color': '#199EF3', + 'sky-horizon-blend': 0.5, + 'horizon-color': '#ffffff', + 'horizon-fog-blend': 0.5, + 'fog-color': '#add8e6', + 'fog-ground-blend': 0.5 + }); + // Initialize start marker startMarkerRef.current = new maplibregl.Marker({ color: '#FF6B6B' }) .setLngLat([selectedPoint.lon, selectedPoint.lat]) @@ -61,7 +73,19 @@ const APP = () => { updatePreviewLine(selectedPoint, direction); }); - mapRef.current.on('click', (e) => { + return () => { + if (mapRef.current) mapRef.current.remove(); + }; + }, []); // Run only once + + // Separate effect for the click listener that respects isLocked + useEffect(() => { + if (!mapRef.current) return; + + const handleClick = (e) => { + // Don't allow moving start point if locked + if (isLocked) return; + const { lng, lat } = e.lngLat; setSelectedPoint({ lat, lon: lng }); @@ -75,12 +99,31 @@ const APP = () => { mapRef.current.removeLayer('line-of-sight'); mapRef.current.removeSource('line-of-sight'); } - }); - - return () => { - mapRef.current.remove(); }; - }, []); + + mapRef.current.on('click', handleClick); + return () => { + if (mapRef.current) mapRef.current.off('click', handleClick); + }; + }, [isLocked]); + + const handleStartAgain = () => { + setIsLocked(false); + setLineOfSightData(null); + setSelectedCity(null); + clearCityMarkers(); + + if (mapRef.current) { + if (mapRef.current.getSource('line-of-sight')) { + mapRef.current.removeLayer('line-of-sight'); + mapRef.current.removeSource('line-of-sight'); + } + // Re-enable preview line if it was hidden + if (mapRef.current.getLayer('preview-line')) { + mapRef.current.setLayoutProperty('preview-line', 'visibility', 'visible'); + } + } + }; const clearCityMarkers = () => { if (cityMarkersRef.current) { @@ -100,10 +143,10 @@ const APP = () => { const map = mapRef.current; if (!map || !map.getSource('preview-line')) return; - // Generate 50 points along a 5000km great circle path for a smooth curve + // Generate 50 points along a 20,000km great circle path for a smooth curve const path = []; const steps = 50; - const totalDistance = 5000; + const totalDistance = 20000; for (let i = 0; i <= steps; i++) { const dist = (totalDistance * i) / steps; @@ -169,6 +212,13 @@ const APP = () => { ); setLineOfSightData(response.data.data); + setIsLocked(true); // Lock the map after showing results + + // Hide the preview line when showing final results + if (mapRef.current && mapRef.current.getLayer('preview-line')) { + mapRef.current.setLayoutProperty('preview-line', 'visibility', 'none'); + } + renderLineOnMap(response.data.data); } catch (error) { console.error('Error fetching line of sight:', error); @@ -234,11 +284,13 @@ const APP = () => { // Add marker to map const marker = new maplibregl.Marker(el) .setLngLat([city.lon, city.lat]) - .setPopup(new maplibregl.Popup().setHTML( - `${city.name}
Population: ${city.population.toLocaleString()}
Distance: ${city.distance_km} km` - )) .addTo(map); + el.addEventListener('click', (e) => { + e.stopPropagation(); // Prevent map click + setSelectedCity(city); + }); + cityMarkersRef.current.push(marker); }); @@ -291,7 +343,7 @@ const APP = () => {
-
+

Line of Sight Settings

@@ -306,6 +358,7 @@ const APP = () => { min="0" max="360" value={direction} + disabled={isLocked} onChange={(e) => setDirection(parseInt(e.target.value))} /> {direction}° @@ -316,6 +369,7 @@ const APP = () => { setTolerance(parseInt(e.target.value))} min="10" max="200" @@ -329,13 +383,31 @@ const APP = () => {
- + {!isLocked ? ( + + ) : ( + <> + + + + )}
{lineOfSightData && ( @@ -352,7 +424,7 @@ const APP = () => { - {lineOfSightData.conurbations.slice(0, 50).map((city, index) => ( + {lineOfSightData.conurbations.map((city, index) => ( setSelectedCity(city)} @@ -366,9 +438,6 @@ const APP = () => { ))} - {lineOfSightData.conurbations.length > 50 && ( -

... and {lineOfSightData.conurbations.length - 50} more

- )}
)} diff --git a/frontend/src/styles/App.css b/frontend/src/styles/App.css index 302b60e..893a0c2 100644 --- a/frontend/src/styles/App.css +++ b/frontend/src/styles/App.css @@ -104,11 +104,55 @@ cursor: not-allowed; } +.action-btn-secondary { + width: 100%; + padding: 12px; + background: #34495e; + color: white; + border: none; + border-radius: 6px; + font-size: 16px; + font-weight: bold; + cursor: pointer; + transition: background 0.3s; + margin-top: 10px; +} + +.action-btn-secondary:hover { + background: #2c3e50; +} + +.disabled-controls { + opacity: 0.8; +} + +.disabled-controls input, .disabled-controls .action-btn { + pointer-events: none; + cursor: not-allowed; +} + +.action-btn-secondary { + pointer-events: auto !important; +} + +.setting-row button { + pointer-events: auto !important; +} + +.results-panel table thead { + position: sticky; + top: 0; + z-index: 1; +} + .results-panel { background: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 20px; + max-height: 450px; + overflow-y: auto; + border: 1px solid #eee; } .results-panel h3 {