{"version":3,"file":"scene-boundaries-DZpkKZMh.js","sources":["../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/scene/BoundaryPreparation.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/scene/BoundaryWorkerJob.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/scene/BoundaryJobs.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/scene/GeoJsonLayer.js"],"sourcesContent":["/** Pure polygon normalization and interior anchors shared by the boundary worker and scene. */\nconst ADMIN_LABEL_INTERIOR_GRID = 5;\nconst ADMIN_LABEL_INTERIOR_REFINEMENT_STEPS = 2;\nconst clamp = (value, min, max) => Math.min(max, Math.max(min, value));\n\nexport class BoundaryPreparation {\n    _extractPolygons(geometry) {\n        if (!geometry) return [];\n        const cached = this._preparedPolygonCache?.get?.(geometry);\n        if (cached) return cached;\n\n        const type = geometry.type;\n        let polygons;\n        if (type === 'Polygon') {\n            const poly = this._preparePolygon(geometry.coordinates);\n            polygons = poly ? [poly] : [];\n        } else if (type === 'MultiPolygon') {\n            const out = [];\n            for (const polyCoords of geometry.coordinates || []) {\n                const poly = this._preparePolygon(polyCoords);\n                if (poly) out.push(poly);\n            }\n            polygons = out;\n        } else if (type === 'GeometryCollection') {\n            const out = [];\n            for (const geom of geometry.geometries || []) {\n                out.push(...this._extractPolygons(geom));\n            }\n            polygons = out;\n        } else {\n            polygons = [];\n        }\n\n        // All internal consumers treat prepared rings as immutable. Sharing\n        // them avoids keeping three separate normalized coordinate trees for\n        // the feature index, labels, and visible geometry.\n        this._preparedPolygonCache?.set?.(geometry, polygons);\n        return polygons;\n    }\n\n    _preparePolygon(rings) {\n        if (!Array.isArray(rings) || !rings.length) return null;\n        const outerRing = rings[0];\n        if (!Array.isArray(outerRing) || outerRing.length < 3) return null;\n        const wrap = this._ringCrossesDateline(outerRing);\n        const outer = this._normalizeRing(outerRing, wrap);\n        if (!outer) return null;\n        const ringData = [outer.coords];\n        for (let i = 1; i < rings.length; i++) {\n            const hole = this._normalizeRing(rings[i], wrap);\n            if (hole) ringData.push(hole.coords);\n        }\n        return {\n            wrap,\n            rings: ringData,\n            bbox: {\n                minLon: outer.minLon,\n                maxLon: outer.maxLon,\n                minLat: outer.minLat,\n                maxLat: outer.maxLat\n            }\n        };\n    }\n\n    _normalizeRing(ring, wrap) {\n        if (!Array.isArray(ring)) return null;\n        let minLon = Infinity;\n        let maxLon = -Infinity;\n        let minLat = Infinity;\n        let maxLat = -Infinity;\n\n        // Most GeoJSON rings are already valid, non-dateline lon/lat pairs.\n        // Reference those immutable source coordinates rather than making a\n        // second `[lon, lat]` object for every vertex. Country/admin data can\n        // contain millions of coordinates, so this is the difference between\n        // one active representation and several retained copies.\n        let canUseSourceRing = !wrap;\n        for (const pt of ring) {\n            if (!Array.isArray(pt) || pt.length < 2) continue;\n            const rawLon = Number(pt[0]);\n            const lat = Number(pt[1]);\n            if (!Number.isFinite(rawLon) || !Number.isFinite(lat)) {\n                canUseSourceRing = false;\n                continue;\n            }\n            // `_wrapLon180(180)` becomes -180. Keep source references only\n            // when their values already match the normalized representation.\n            if (rawLon < -180 || rawLon >= 180) canUseSourceRing = false;\n            if (rawLon < minLon) minLon = rawLon;\n            if (rawLon > maxLon) maxLon = rawLon;\n            if (lat < minLat) minLat = lat;\n            if (lat > maxLat) maxLat = lat;\n        }\n        if (ring.length < 3 || !Number.isFinite(minLon) || !Number.isFinite(minLat)) return null;\n        if (canUseSourceRing) {\n            return { coords: ring, minLon, maxLon, minLat, maxLat };\n        }\n\n        const coords = [];\n        minLon = Infinity;\n        maxLon = -Infinity;\n        minLat = Infinity;\n        maxLat = -Infinity;\n        for (const pt of ring) {\n            if (!Array.isArray(pt) || pt.length < 2) continue;\n            let lon = Number(pt[0]);\n            const lat = Number(pt[1]);\n            if (!Number.isFinite(lon) || !Number.isFinite(lat)) continue;\n            lon = this._wrapLon180(lon);\n            if (wrap && lon < 0) lon += 360;\n            coords.push([lon, lat]);\n            if (lon < minLon) minLon = lon;\n            if (lon > maxLon) maxLon = lon;\n            if (lat < minLat) minLat = lat;\n            if (lat > maxLat) maxLat = lat;\n        }\n        if (coords.length < 3) return null;\n        return { coords, minLon, maxLon, minLat, maxLat };\n    }\n\n    _ringCrossesDateline(ring) {\n        if (!Array.isArray(ring) || ring.length < 2) return false;\n        let prevLon = null;\n        for (const pt of ring) {\n            if (!Array.isArray(pt) || pt.length < 2) continue;\n            const lon = this._wrapLon180(Number(pt[0]));\n            if (!Number.isFinite(lon)) continue;\n            if (prevLon !== null && Math.abs(lon - prevLon) > 180) return true;\n            prevLon = lon;\n        }\n        if (prevLon === null) return false;\n        const first = ring[0];\n        if (Array.isArray(first) && first.length >= 2) {\n            const firstLon = this._wrapLon180(Number(first[0]));\n            if (Number.isFinite(firstLon) && Math.abs(firstLon - prevLon) > 180) return true;\n        }\n        return false;\n    }\n\n    _pointInRing(lon, lat, ring) {\n        if (!Array.isArray(ring) || ring.length < 3) return false;\n        let inside = false;\n        for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n            const xi = ring[i][0];\n            const yi = ring[i][1];\n            const xj = ring[j][0];\n            const yj = ring[j][1];\n            const intersects = ((yi > lat) !== (yj > lat)) &&\n                (lon < ((xj - xi) * (lat - yi)) / (yj - yi) + xi);\n            if (intersects) inside = !inside;\n        }\n        return inside;\n    }\n\n    _wrapLon180(lon) {\n        if (!Number.isFinite(lon)) return NaN;\n        const wrapped = ((lon + 180) % 360 + 360) % 360;\n        return wrapped - 180;\n    }\n\n\n    _readLabelLatLonFromProps(props) {\n        if (!props) return null;\n        const pairs = [\n            ['label_lat', 'label_lon'],\n            ['label_y', 'label_x'],\n            ['LABEL_Y', 'LABEL_X'],\n            ['centroid_lat', 'centroid_lon'],\n            ['CENTROID_LAT', 'CENTROID_LON'],\n            ['center_lat', 'center_lon'],\n            ['CENTER_LAT', 'CENTER_LON'],\n            ['latitude', 'longitude'],\n            ['LATITUDE', 'LONGITUDE'],\n            ['lat', 'lon'],\n            ['LAT', 'LON'],\n            ['INTPTLAT', 'INTPTLON'],\n            ['INTPTLAT10', 'INTPTLON10']\n        ];\n\n        for (const [latKey, lonKey] of pairs) {\n            if (latKey in props && lonKey in props) {\n                const lat = Number(props[latKey]);\n                const lon = Number(props[lonKey]);\n                if (Number.isFinite(lat) && Number.isFinite(lon)) {\n                    return { lat, lon };\n                }\n            }\n        }\n\n        return null;\n    }\n\n    _resolveLabelLatLon(feature) {\n        if (!feature || !feature.geometry) return null;\n        const cached = this._labelAnchorCache?.get?.(feature);\n        if (cached) return cached.value;\n        const props = feature.properties || {};\n        const fromProps = this._readLabelLatLonFromProps(props);\n        let resolved = null;\n\n        const geometry = feature.geometry;\n        const polygons = this._extractPolygons(geometry);\n        if (polygons.length) {\n            // A geometric centroid is frequently outside a concave region, and\n            // imported label/centroid properties can legally sit on an edge.\n            // Use the deepest inexpensive interior point instead; this makes a\n            // regional label read as belonging to the region rather than its\n            // boundary and works for holes and antimeridian polygons.\n            const interior = this._findInteriorLabelPoint(polygons, fromProps);\n            if (interior) resolved = interior;\n            if (!resolved) {\n                const centroid = this._computePolygonCentroid(polygons);\n                if (centroid) resolved = centroid;\n            }\n        }\n\n        if (!resolved && fromProps) resolved = fromProps;\n\n        if (!resolved && geometry.type === 'LineString') {\n            resolved = this._getLineMidpoint(geometry.coordinates);\n        } else if (!resolved && geometry.type === 'MultiLineString') {\n            resolved = this._getMultiLineMidpoint(geometry.coordinates);\n        } else if (!resolved && geometry.type === 'GeometryCollection') {\n            for (const geom of geometry.geometries || []) {\n                if (geom.type === 'LineString') {\n                    const mid = this._getLineMidpoint(geom.coordinates);\n                    if (mid) {\n                        resolved = mid;\n                        break;\n                    }\n                } else if (geom.type === 'MultiLineString') {\n                    const mid = this._getMultiLineMidpoint(geom.coordinates);\n                    if (mid) {\n                        resolved = mid;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Cache misses too: many line features never have an anchor, and a\n        // weak entry avoids repeating the geometry walk on every rebuild.\n        this._labelAnchorCache?.set?.(feature, { value: resolved });\n        return resolved;\n    }\n\n    _isPointInPreparedPolygon(lon, lat, polygon) {\n        if (!polygon || !Number.isFinite(lon) || !Number.isFinite(lat)) return false;\n        const testLon = polygon.wrap && lon < 0 ? lon + 360 : lon;\n        const bbox = polygon.bbox;\n        if (!bbox || testLon < bbox.minLon || testLon > bbox.maxLon || lat < bbox.minLat || lat > bbox.maxLat) {\n            return false;\n        }\n        if (!this._pointInRing(testLon, lat, polygon.rings?.[0])) return false;\n        for (let i = 1; i < polygon.rings.length; i++) {\n            if (this._pointInRing(testLon, lat, polygon.rings[i])) return false;\n        }\n        return true;\n    }\n\n    _distanceToRingEdgesSq(lon, lat, rings) {\n        let best = Infinity;\n        for (const ring of rings || []) {\n            if (!Array.isArray(ring) || ring.length < 2) continue;\n            for (let i = 0; i < ring.length; i++) {\n                const a = ring[i];\n                const b = ring[(i + 1) % ring.length];\n                const ax = Number(a?.[0]);\n                const ay = Number(a?.[1]);\n                const bx = Number(b?.[0]);\n                const by = Number(b?.[1]);\n                // Avoid allocating a temporary four-element array for every\n                // edge of every interior-label probe.\n                if (!Number.isFinite(ax) || !Number.isFinite(ay)\n                    || !Number.isFinite(bx) || !Number.isFinite(by)) continue;\n                const dx = bx - ax;\n                const dy = by - ay;\n                const lengthSq = dx * dx + dy * dy;\n                const t = lengthSq > 1e-12\n                    ? clamp(((lon - ax) * dx + (lat - ay) * dy) / lengthSq, 0, 1)\n                    : 0;\n                const px = ax + dx * t;\n                const py = ay + dy * t;\n                const distSq = (lon - px) * (lon - px) + (lat - py) * (lat - py);\n                if (distSq < best) best = distSq;\n            }\n        }\n        return best;\n    }\n\n    _findInteriorLabelPoint(polygons, preferred = null) {\n        let target = null;\n        let targetArea = -Infinity;\n        for (const polygon of polygons || []) {\n            const bbox = polygon?.bbox;\n            if (!bbox) continue;\n            const area = Math.max(0, bbox.maxLon - bbox.minLon) * Math.max(0, bbox.maxLat - bbox.minLat);\n            if (area > targetArea) {\n                target = polygon;\n                targetArea = area;\n            }\n        }\n        if (!target?.bbox) return null;\n\n        const { minLon, maxLon, minLat, maxLat } = target.bbox;\n        let bestLon = NaN;\n        let bestLat = NaN;\n        let bestScore = -Infinity;\n        const consider = (lon, lat) => {\n            if (!this._isPointInPreparedPolygon(lon, lat, target)) return;\n            const score = this._distanceToRingEdgesSq(lon, lat, target.rings);\n            if (score > bestScore) {\n                bestScore = score;\n                bestLon = lon;\n                bestLat = lat;\n            }\n        };\n\n        if (preferred) {\n            const preferredLon = target.wrap && this._wrapLon180(preferred.lon) < 0\n                ? this._wrapLon180(preferred.lon) + 360\n                : this._wrapLon180(preferred.lon);\n            consider(preferredLon, Number(preferred.lat));\n        }\n        const centroid = this._computeRingsCentroid(target.rings);\n        if (centroid) consider(centroid.lon, centroid.lat);\n\n        const grid = ADMIN_LABEL_INTERIOR_GRID;\n        const probe = (centerLon, centerLat, halfLon, halfLat) => {\n            for (let y = 0; y < grid; y++) {\n                const lat = centerLat - halfLat + (2 * halfLat * y) / (grid - 1);\n                for (let x = 0; x < grid; x++) {\n                    const lon = centerLon - halfLon + (2 * halfLon * x) / (grid - 1);\n                    consider(lon, lat);\n                }\n            }\n        };\n        probe((minLon + maxLon) * 0.5, (minLat + maxLat) * 0.5, (maxLon - minLon) * 0.5, (maxLat - minLat) * 0.5);\n\n        let halfLon = (maxLon - minLon) / (grid - 1);\n        let halfLat = (maxLat - minLat) / (grid - 1);\n        for (let step = 0; Number.isFinite(bestLon) && step < ADMIN_LABEL_INTERIOR_REFINEMENT_STEPS; step++) {\n            probe(bestLon, bestLat, halfLon, halfLat);\n            halfLon *= 0.5;\n            halfLat *= 0.5;\n        }\n        return Number.isFinite(bestLon) ? { lat: bestLat, lon: this._wrapLon180(bestLon) } : null;\n    }\n\n    _computePolygonCentroid(polygons) {\n        let best = null;\n        for (const polygon of polygons || []) {\n            const centroid = this._computeRingsCentroid(polygon?.rings);\n            if (!centroid) continue;\n            if (!best || Math.abs(centroid.area) > Math.abs(best.area)) {\n                best = centroid;\n            }\n        }\n        if (!best) return null;\n        return {\n            lat: best.lat,\n            lon: this._wrapLon180(best.lon)\n        };\n    }\n\n    _computeRingsCentroid(rings) {\n        if (!Array.isArray(rings) || !rings.length) return null;\n        const outer = this._ringCentroid(rings[0]);\n        if (!outer) return null;\n        let areaSum = outer.area;\n        let cx = outer.cx * outer.area;\n        let cy = outer.cy * outer.area;\n\n        for (let i = 1; i < rings.length; i++) {\n            const hole = this._ringCentroid(rings[i]);\n            if (!hole) continue;\n            const holeArea = -Math.abs(hole.area);\n            cx += hole.cx * holeArea;\n            cy += hole.cy * holeArea;\n            areaSum += holeArea;\n        }\n\n        if (!Number.isFinite(areaSum) || Math.abs(areaSum) < 1e-6) return null;\n        return {\n            lon: cx / areaSum,\n            lat: cy / areaSum,\n            area: areaSum\n        };\n    }\n\n    _ringCentroid(ring) {\n        if (!Array.isArray(ring) || ring.length < 3) return null;\n        const coords = ring.slice();\n        const first = coords[0];\n        const last = coords[coords.length - 1];\n        if (Array.isArray(first) && Array.isArray(last) &&\n            Math.abs(Number(first[0]) - Number(last[0])) < 1e-6 &&\n            Math.abs(Number(first[1]) - Number(last[1])) < 1e-6) {\n            coords.pop();\n        }\n        if (coords.length < 3) return null;\n\n        let area = 0;\n        let cx = 0;\n        let cy = 0;\n        for (let i = 0, j = coords.length - 1; i < coords.length; j = i++) {\n            const x0 = Number(coords[j][0]);\n            const y0 = Number(coords[j][1]);\n            const x1 = Number(coords[i][0]);\n            const y1 = Number(coords[i][1]);\n            if (!Number.isFinite(x0) || !Number.isFinite(y0) ||\n                !Number.isFinite(x1) || !Number.isFinite(y1)) {\n                continue;\n            }\n            const cross = x0 * y1 - x1 * y0;\n            area += cross;\n            cx += (x0 + x1) * cross;\n            cy += (y0 + y1) * cross;\n        }\n        area *= 0.5;\n        if (!Number.isFinite(area) || Math.abs(area) < 1e-9) return null;\n        const factor = 1 / (6 * area);\n        return {\n            cx: cx * factor,\n            cy: cy * factor,\n            area\n        };\n    }\n\n    _getLineMidpoint(coords) {\n        if (!Array.isArray(coords) || coords.length < 2) return null;\n        const midIndex = Math.floor(coords.length / 2);\n        const coord = coords[midIndex];\n        if (!Array.isArray(coord) || coord.length < 2) return null;\n        const lon = Number(coord[0]);\n        const lat = Number(coord[1]);\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n        return { lat, lon };\n    }\n\n    _getMultiLineMidpoint(lines) {\n        if (!Array.isArray(lines) || !lines.length) return null;\n        let best = null;\n        let bestLen = 0;\n        for (const line of lines) {\n            if (!Array.isArray(line)) continue;\n            if (line.length > bestLen) {\n                bestLen = line.length;\n                best = line;\n            }\n        }\n        return best ? this._getLineMidpoint(best) : null;\n    }\n\n}\n\n","import { BoundaryPreparation } from './BoundaryPreparation.js';\n\n/** Pure worker job. Only corrected rings return coordinate buffers; ordinary\n * rings are returned as references into the caller's immutable source tree. */\nexport function prepareBoundaryPayload({ geometry, buffer, offsets, preferred, shareable = [] }) {\n    if (!(buffer instanceof Float64Array) || buffer.length > 2000000 || offsets.length > 40000) throw new RangeError('Boundary worker input exceeds budget');\n    const rings = offsets.map(([offset, length]) => {\n        if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(length) || offset < 0 || length < 0 || offset + length * 2 > buffer.length) throw new RangeError('Invalid boundary ring offsets');\n        return Array.from({ length }, (_, i) => [buffer[offset + i * 2], buffer[offset + i * 2 + 1]]);\n    });\n    const source = new Map(rings.map((ring, index) => [ring, index]));\n    function decode(g, depth = 0) {\n        if (depth > 32) throw new RangeError('Boundary nesting limit exceeded');\n        const { type, coordinates: c } = g;\n        if (type === 'Polygon' || type === 'MultiLineString') return { type, coordinates: c.map(i => rings[i]) };\n        if (type === 'MultiPolygon') return { type, coordinates: c.map(poly => poly.map(i => rings[i])) };\n        if (type === 'LineString') return { type, coordinates: rings[c] };\n        if (type === 'GeometryCollection') return { type, geometries: g.geometries.map(child => decode(child, depth + 1)) };\n        return { type };\n    }\n    const prep = new BoundaryPreparation();\n    prep._preparedPolygonCache = new WeakMap();\n    prep._labelAnchorCache = new WeakMap();\n    const feature = { geometry: decode(geometry), properties: preferred ? { label_lat: preferred.lat, label_lon: preferred.lon } : {} };\n    const polygons = prep._extractPolygons(feature.geometry);\n    const anchor = prep._resolveLabelLatLon(feature);\n    return { anchor, polygons: polygons.map(polygon => ({ wrap: polygon.wrap, bbox: polygon.bbox,\n        rings: polygon.rings.map(ring => source.has(ring) && shareable[source.get(ring)] ? { source: source.get(ring) } : { coords: Float64Array.from(ring.flat()) }),\n    })) };\n}\n","import { getWorkerPool } from '../async/workers/WorkerPool.js';\nimport { yieldToEventLoop } from '../async/scheduler/BudgetScheduler.js';\nimport { prepareBoundaryPayload } from './BoundaryWorkerJob.js';\n\n// Verified against all 479 shipped GeoJSON files: maximum 911,422 points,\n// 35,916 rings and 10,375 features. These input bounds preserve the corpus;\n// visible geometry residency, not rejecting valid regions, reduces mesh cost.\nexport const MAX_BOUNDARY_POINTS = 1_000_000;\nexport const MAX_BOUNDARY_RINGS = 40_000;\nexport const MAX_BOUNDARY_FEATURES = 12_000;\nexport const BOUNDARY_SLICE_MS = 4;\nconst stats = { slices: 0, steps: 0, maxSliceMs: 0 };\nexport const getBoundaryWorkStats = () => ({ ...stats, budgetMs: BOUNDARY_SLICE_MS, active, waiting: waiting.length });\n\nexport function checkBoundarySignal(signal) {\n    if (signal?.aborted) throw new DOMException('Boundary generation cancelled', 'AbortError');\n}\n\nexport function waitBoundaryTask(task, signal) {\n    checkBoundarySignal(signal);\n    return new Promise((resolve, reject) => {\n        const abort = () => {\n            signal?.removeEventListener('abort', abort);\n            reject(new DOMException('Boundary generation cancelled', 'AbortError'));\n        };\n        signal?.addEventListener('abort', abort, { once: true });\n        Promise.resolve(task).then(resolve, reject).finally(() => signal?.removeEventListener('abort', abort));\n    });\n}\n\n// A step is a single coordinate/segment, never an entire coastline. A count\n// limit complements the time budget on low-resolution browser clocks.\nexport async function runBoundarySteps(steps, signal) {\n    let start = performance.now(), count = 0;\n    for (const _step of steps) {\n        stats.steps++;\n        checkBoundarySignal(signal);\n        if (++count >= 256 || performance.now() - start >= BOUNDARY_SLICE_MS) {\n            stats.slices++;\n            stats.maxSliceMs = Math.max(stats.maxSliceMs, performance.now() - start);\n            await yieldToEventLoop('background');\n            checkBoundarySignal(signal);\n            count = 0; start = performance.now();\n        }\n    }\n    checkBoundarySignal(signal);\n}\n\nexport function* boundaryLines(geometry, depth = 0) {\n    if (!geometry) return;\n    if (depth > 32) throw new RangeError('Boundary geometry nesting limit exceeded');\n    const coords = geometry.coordinates || [];\n    if (geometry.type === 'Polygon') {\n        for (const ring of coords) yield { coords: ring, close: true };\n    } else if (geometry.type === 'MultiPolygon') {\n        for (const polygon of coords) for (const ring of polygon) yield { coords: ring, close: true };\n    } else if (geometry.type === 'LineString') {\n        yield { coords, close: false };\n    } else if (geometry.type === 'MultiLineString') {\n        for (const ring of coords) yield { coords: ring, close: false };\n    } else if (geometry.type === 'GeometryCollection') {\n        for (const child of geometry.geometries || []) yield* boundaryLines(child, depth + 1);\n    }\n}\n\n// One worker lane, four admitted consumers: cancellation can terminate the\n// current synchronous geometry calculation without cancelling another layer.\nlet active = false;\nconst waiting = [];\nasync function acquire(signal) {\n    checkBoundarySignal(signal);\n    if (!active) { active = true; return; }\n    if (waiting.length >= 3) throw new RangeError('Boundary preparation admission limit reached');\n    await new Promise((resolve, reject) => {\n        const entry = { resolve, signal, abort: () => {\n            const index = waiting.indexOf(entry);\n            if (index >= 0) waiting.splice(index, 1);\n            reject(new DOMException('Boundary generation cancelled', 'AbortError'));\n        } };\n        signal?.addEventListener('abort', entry.abort, { once: true });\n        waiting.push(entry);\n    });\n}\nfunction release() {\n    const next = waiting.shift();\n    if (!next) { active = false; return; }\n    next.signal?.removeEventListener('abort', next.abort);\n    next.resolve();\n}\n\nexport async function prepareBoundaryFeature(layer, feature, budget, signal) {\n    const rings = [];\n    let points = 0;\n    await runBoundarySteps((function* () { for (const line of boundaryLines(feature.geometry)) {\n        checkBoundarySignal(signal);\n        if (!Array.isArray(line.coords)) throw new TypeError('Invalid boundary coordinates');\n        points += line.coords.length;\n        if (points > MAX_BOUNDARY_POINTS || rings.length >= MAX_BOUNDARY_RINGS) throw new RangeError('Boundary feature exceeds coordinate budget');\n        rings.push(line.coords);\n        yield;\n    } })(), signal);\n    budget.points += points;\n    budget.rings += rings.length;\n    if (budget.points > MAX_BOUNDARY_POINTS || budget.rings > MAX_BOUNDARY_RINGS) throw new RangeError('Boundary generation exceeds coordinate budget');\n    if (layer._preparedPolygonCache.has(feature.geometry) && layer._labelAnchorCache.has(feature)) return;\n    const indices = new Map(rings.map((ring, index) => [ring, index]));\n    function encode(geometry) {\n        const { type, coordinates: c } = geometry;\n        if (type === 'Polygon' || type === 'MultiLineString') return { type, coordinates: c.map(ring => indices.get(ring)) };\n        if (type === 'MultiPolygon') return { type, coordinates: c.map(poly => poly.map(ring => indices.get(ring))) };\n        if (type === 'LineString') return { type, coordinates: indices.get(c) };\n        if (type === 'GeometryCollection') return { type, geometries: (geometry.geometries || []).map(encode) };\n        return { type };\n    }\n    await acquire(signal);\n    try {\n        checkBoundarySignal(signal);\n        const buffer = new Float64Array(points * 2);\n        const offsets = [];\n        const shareable = [];\n        let offset = 0;\n        await runBoundarySteps((function* () {\n            for (const ring of rings) {\n                offsets.push([offset, ring.length]);\n                let originalNumbers = true;\n                for (const point of ring) {\n                    if (!Array.isArray(point) || !Number.isFinite(point[0]) || !Number.isFinite(point[1])) originalNumbers = false;\n                    buffer[offset++] = Number(point?.[0]);\n                    buffer[offset++] = Number(point?.[1]);\n                    yield;\n                }\n                shareable.push(originalNumbers);\n            }\n        })(), signal);\n        // Only label-coordinate properties cross the worker boundary; unrelated\n        // (potentially large) feature metadata stays with its original owner.\n        const payload = { geometry: encode(feature.geometry), buffer, offsets, shareable,\n            preferred: layer._readLabelLatLonFromProps(feature.properties) };\n        let result;\n        if (typeof Worker === 'function') {\n            const pool = getWorkerPool();\n            const abort = () => pool.terminate('boundary-worker');\n            signal?.addEventListener('abort', abort, { once: true });\n            try {\n                result = await pool.run('boundary-worker', 'prepare', payload, { transfer: [buffer.buffer], signal, timeoutMs: 30000 });\n            } catch (error) {\n                checkBoundarySignal(signal);\n                throw error;\n            } finally { signal?.removeEventListener('abort', abort); }\n        } else if (typeof window === 'undefined') {\n            // Node-only deterministic fixtures. Browser worker failure is not\n            // permission to run the expensive polygon search on the UI thread.\n            result = prepareBoundaryPayload(payload);\n        } else throw new Error('Boundary preparation requires a Web Worker');\n        checkBoundarySignal(signal);\n        const polygons = [];\n        await runBoundarySteps((function* () {\n            for (const polygon of result.polygons) {\n                const prepared = { wrap: polygon.wrap, bbox: polygon.bbox, rings: [] };\n                for (const ring of polygon.rings) {\n                    if (ring.source != null) prepared.rings.push(rings[ring.source]);\n                    else {\n                        const coords = [];\n                        for (let i = 0; i < ring.coords.length; i += 2) {\n                            coords.push([ring.coords[i], ring.coords[i + 1]]); yield;\n                        }\n                        prepared.rings.push(coords);\n                    }\n                    yield;\n                }\n                polygons.push(prepared); yield;\n            }\n        })(), signal);\n        layer._preparedPolygonCache.set(feature.geometry, polygons);\n        layer._labelAnchorCache.set(feature, { value: result.anchor });\n    } finally { release(); }\n}\n","/**\n * GeoJsonLayer\n *\n * Purpose:\n * - Render GeoJSON outlines directly onto the planet surface.\n * - Designed for wireframe mode, but can be toggled independently.\n */\nimport * as THREE from 'three';\nimport { BoundaryPreparation } from './BoundaryPreparation.js';\nimport { boundaryLines, checkBoundarySignal, MAX_BOUNDARY_FEATURES, MAX_BOUNDARY_POINTS, MAX_BOUNDARY_RINGS, prepareBoundaryFeature, runBoundarySteps, waitBoundaryTask } from './BoundaryJobs.js';\nimport { nextFrame, yieldToEventLoop } from '../async/scheduler/BudgetScheduler.js';\nimport { latLonToLocalDir, dirToLatLonLocal, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { fetchJsonResource } from '../shared/JsonResourceCache.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport {\n    SCREEN_SPACE_ORBIT_ENTER_ALTITUDE_M,\n    SCREEN_SPACE_ORBIT_EXIT_ALTITUDE_M,\n    SCREEN_SPACE_OUTLINE_POST_COMPOSITE_LAYER,\n    SCREEN_SPACE_OUTLINE_REFERENCE_HALF_WIDTH_M,\n    screenSpaceOrbitCoverageVisible,\n    updateScreenSpaceOutlineUniforms,\n} from '../render/ScreenSpaceOutline.js';\n\n// Keep scene defaults independent from the UI module. GeoJsonLayer is loaded\n// with PlanetScene, while DesignSystem belongs to the UI chunk; importing the\n// latter here made the chunk graph cyclic and could read its exports in their\n// temporal dead zone during production startup.\nconst DEFAULT_BORDER_COLOR = '#facc15';\nconst DEFAULT_HIGHLIGHT_COLOR = '#fde047';\nconst DEFAULT_HIGHLIGHT_OPACITY = 0.06;\nconst DEFAULT_WALL_DEPTH_METERS = 3000;\nconst DEFAULT_LIFT_METERS = 6000;\n// Extra safety margin sunk below the sampled surface so the spire\n// base stays buried even if a later LOD swap reveals slightly higher\n// terrain at the same coordinate. Combined with wallDepthMeters this\n// gives us depth = wallDepthMeters + SAFETY_DEPTH_M below the sample.\nconst SAFETY_DEPTH_M = 600;\nconst DEFAULT_ORBIT_LINE_OPACITY = 0.72;\n// Match the low-orbit environmental coverage outline. Native WebGL lines are\n// one physical pixel on most browsers, so administrative borders use a real\n// surface ribbon instead of relying on the unsupported `linewidth` setting.\n// Its current width at this altitude is the visual reference for the\n// screen-space extrusion used throughout orbit. Surface mode has its own\n// terrain-mated spire wall and must not render this cartographic ribbon too.\nconst BORDER_ORBIT_LIFT_METERS = DEFAULT_LIFT_METERS * 2;\nconst DEFAULT_AURORA_AMPLITUDE = 2000;\nconst DEFAULT_AURORA_FREQUENCY = 0.00003;\nconst DEFAULT_AURORA_SPEED = 0.8;\nconst DEFAULT_HIGHLIGHT_SUBDIV_DEG = 1.0;\nconst DEFAULT_HIGHLIGHT_SUBDIV_DEPTH = 4;\nconst MAX_HIGHLIGHT_TRIANGLES = 150000;\nconst DEFAULT_HIGHLIGHT_OUTLINE_WIDTH_METERS = 6000;\nconst DEFAULT_HIGHLIGHT_OUTLINE_SURFACE_RATIO = 0.5;\nconst DEFAULT_HATCH_SCALE = 45;\nconst DEFAULT_HATCH_DASH_SCALE = 18;\nconst DEFAULT_HATCH_SPACING_METERS = 100_000;\nconst DEFAULT_HATCH_DASH_SPACING_METERS = 100_000;\nconst DEFAULT_HATCH_THICKNESS = 0.015;\nconst DEFAULT_HATCH_FEATHER = 0.008;\nconst DEFAULT_HATCH_SPEED = 0.25;\nconst DEFAULT_OUTLINE_SEGMENT_METERS = 50_000;\nconst MAX_OUTLINE_SAMPLES = 4000;\nconst HIGHLIGHT_LIFT_OFFSET = 5000;\nconst HIGHLIGHT_MIN_LIFT = 5000;\nconst LABEL_MAX_DISTANCE = 2000000; // meters - hide labels beyond this\nconst LABEL_MIN_DISTANCE = 50000;   // meters - start fading labels closer than this\nconst LABEL_MAX_VISIBLE = 20;       // max labels visible at once for performance\nconst LABEL_SURFACE_LIFT_METERS = 1500;\nconst LABEL_ORBIT_LIFT_METERS = 25000;\nconst LABEL_BASE_SCALE = 0.002; // fraction of planet radius for label height\nconst LABEL_MIN_PIXEL_HEIGHT = 36;\nconst LABEL_MAX_PIXEL_HEIGHT = 48;\nconst LABEL_PIXEL_RATIO = 0.02;\nconst LABEL_SCALE_CAP_ALT_METERS = 3_000_000;\nconst LABEL_SCALE_RELEASE_ALT_METERS = 12_000_000;\nconst LABEL_BORDER_RETIRE_ALT_METERS = 3_000_000;\nconst LABEL_RAPID_MOTION_INTERVAL_MS = 50;\nconst LABEL_RAPID_MOTION_SPEED_MPS = 25;\nconst LABEL_OBJECT_RADIUS_BY_ADM = [95_000, 52_000, 30_000, 18_000];\nconst BEYOND_BORDER_LABEL_MAX_VISIBLE = 2;\nconst BEYOND_BORDER_LABEL_MAX_DISTANCE_METERS = 350_000;\nconst BEYOND_BORDER_LABEL_REFRESH_MS = 320;\nconst BEYOND_BORDER_LABEL_CAMERA_MOVE_METERS = 180;\nconst BEYOND_BORDER_LABEL_TOP_CLEARANCE_METERS = 850;\nconst BEYOND_BORDER_NEAREST_SEGMENT_LIMIT = 24;\nconst BEYOND_BORDER_PROBE_DISTANCES_METERS = [1800, 6000, 18000];\nconst METERS_PER_LATITUDE_DEGREE = 111_320;\n// Match the optical stack exercised by Three's dispersion reference while\n// keeping the very large geospatial wall thin enough to remain legible.\nconst BORDER_GLASS_TRANSMISSION = 0.94;\nconst BORDER_GLASS_DISPERSION = 1.0;\nconst BORDER_GLASS_IOR = 1.33;\nconst BORDER_GLASS_THICKNESS_METERS = 180;\nconst BORDER_GLASS_ATTENUATION_METERS = 35_000;\nconst BORDER_GLASS_ROUGHNESS = 0.08;\n// Administrative data is often global.  Keep it in modest geographic chunks so\n// an entire far-side section can be removed from the render list before the\n// renderer submits its vertices.  The shader mask below still handles the\n// narrow partially-visible strip at the horizon.\n// The former 3x6 world grid produced a 3.79 MB position buffer for one surface\n// chunk. WebGL buffer upload is synchronous and blocked the live render thread\n// for five seconds. Finer geographic ownership keeps individual uploads small;\n// horizon culling means only nearby chunks are submitted at street level.\nconst GEOJSON_CHUNK_LAT_BANDS = 12;\nconst GEOJSON_CHUNK_LON_BANDS = 24;\nconst GEOJSON_HORIZON_CHUNK_MARGIN_RAD = THREE.MathUtils.degToRad(1.5);\nconst SURFACE_SAMPLE_QUANTIZATION = 1000;\nconst SURFACE_SAMPLE_QUANTIZATION_WIDTH = SURFACE_SAMPLE_QUANTIZATION * 2 + 1;\n// This cache only exists to prevent repeat terrain raycasts while a boundary\n// geometry is built. It used to grow for every unique sampled vertex across\n// each administrative data reload. Keep it intentionally small and FIFO.\nconst MAX_SURFACE_SAMPLE_CACHE_ENTRIES = 16_384;\n\n/**\n * Resolve the CSS-variable form accepted by the GeoJSON layer without making\n * the scene depend on the UI component bundle. THREE.Color accepts the result.\n */\nfunction resolveGeoJsonColor(cssColor) {\n    if (Number.isFinite(cssColor)) {\n        return cssColor;\n    }\n    if (!cssColor || typeof cssColor !== 'string') {\n        return '#ffffff';\n    }\n\n    if (cssColor.startsWith('var(')) {\n        const match = cssColor.match(/var\\(\\s*(--[^,)]+)\\s*(?:,\\s*([^)]+))?\\)/);\n        if (match) {\n            const varName = match[1];\n            const fallback = match[2]?.trim() || '#ffffff';\n            if (typeof document !== 'undefined') {\n                const computed = getComputedStyle(document.documentElement).getPropertyValue(varName).trim();\n                if (computed) return computed;\n            }\n            return fallback;\n        }\n    }\n\n    return cssColor;\n}\n\nexport class GeoJsonLayer extends BoundaryPreparation {\n    constructor({\n        parentGroup,\n        url,\n        planetRadius = PLANET_RADIUS,\n        color = DEFAULT_BORDER_COLOR,\n        // Default border opacity at 5% — boundaries should read as a\n        // ghost reference, not a visible overlay. Callers can still\n        // pass a higher value when they want emphasis.\n        opacity = 0.05,\n        liftMeters = DEFAULT_LIFT_METERS,\n        wallDepthMeters = DEFAULT_WALL_DEPTH_METERS,\n        sceneInitializer,\n        deferUntilInteractive = false,\n    } = {}) {\n        super();\n        this.url = url;\n        this.planetRadius = planetRadius;\n        this.color = color;\n        this.opacity = opacity;\n        // Governor-driven memory pressure [0,1]. PlanetScene reads this to shift\n        // the graduated admin-border LOD coarser when JS heap is tight.\n        this._memoryPressure = 0;\n        this.liftMeters = liftMeters;\n        this.wallDepthMeters = Number.isFinite(wallDepthMeters)\n            ? Math.max(0, wallDepthMeters)\n            : DEFAULT_WALL_DEPTH_METERS;\n        this.highlightColor = DEFAULT_HIGHLIGHT_COLOR;\n        this.highlightOpacity = DEFAULT_HIGHLIGHT_OPACITY;\n        this.highlightLiftMetersSurface = Math.max(HIGHLIGHT_MIN_LIFT, this.liftMeters + HIGHLIGHT_LIFT_OFFSET);\n        this.highlightLiftMetersOrbit = Math.max(\n            this.highlightLiftMetersSurface * 2,\n            this.highlightLiftMetersSurface + HIGHLIGHT_LIFT_OFFSET\n        );\n        this.sceneInitializer = sceneInitializer || null;\n        this._interactiveReady = !deferUntilInteractive;\n        // Surface sampler — same plumbing IncidentOverlay /\n        // BuildingOverlay / InfrastructureOverlay use. Allows the\n        // spire walls to compute their top/bottom radius relative to\n        // the actual photoreal tile surface rather than the WGS84\n        // ellipsoid constant. Without this, mountainous terrain above\n        // planetRadius buries the spire and ocean trenches let it\n        // float in the air.\n        this.surfaceController = null;\n        this._surfaceSampleCache = new Map(); // quantized direction → radius (m)\n        this._surfaceSampleCacheMaxEntries = MAX_SURFACE_SAMPLE_CACHE_ENTRIES;\n        // Prepared polygon rings and interior label anchors are shared by the\n        // lookup index, label data, and render chunks. Weak keys prevent a\n        // replaced GeoJSON source from being retained by this layer.\n        this._preparedPolygonCache = new WeakMap();\n        this._labelAnchorCache = new WeakMap();\n\n        this.group = new THREE.Group();\n        this.group.name = 'GeoJsonLayer';\n        this.group.visible = false;\n        if (parentGroup) {\n            parentGroup.add(this.group);\n        }\n\n        // Register GeoJSON group to be excluded from atmosphere depth passes\n        if (this.sceneInitializer && typeof this.sceneInitializer.addDepthPassExclude === 'function') {\n            this.sceneInitializer.addDepthPassExclude(this.group);\n        }\n        // Country/admin ribbons use the same post-atmosphere cartographic pass\n        // as smoke extents and incident/hazard circles. The terrain provider\n        // is therefore never responsible for their visibility.\n        this._postCompositeLayerRegistered = this.sceneInitializer\n            ?.registerPostCompositeLayer?.(SCREEN_SPACE_OUTLINE_POST_COMPOSITE_LAYER) === true;\n\n        this._line = null;\n        this._orbitLine = null;\n        this._lineChunks = [];\n        this._orbitLineChunks = [];\n        this._lineMaterial = null;\n        this._orbitLineMaterial = null;\n        this._featureColorResolver = null;\n        this._featureColorsEnabled = true;\n        this._wallMaterialGeneration = 0;\n        this._fillMesh = null;\n        this._outlineMesh = null;\n        this._highlightFeature = null;\n        this._highlightAdminLevel = null;\n        this._highlightCenterDir = null;\n        this._highlightHatchSpacingMeters = DEFAULT_HATCH_SPACING_METERS;\n        this._highlightHatchThickness = DEFAULT_HATCH_THICKNESS;\n        this._highlightHatchFeather = DEFAULT_HATCH_FEATHER;\n        this._highlightOutlineWidthMeters = DEFAULT_HIGHLIGHT_OUTLINE_WIDTH_METERS;\n        this._sceneSelectionKeys = new Set();\n        this._loadPromise = null;\n        this._scheduledLoad = null;\n        this._loaded = false;\n        this._featureIndex = null;\n        this._loadSeq = 0;\n        this._filterIso3 = null;\n        this._filterParentName = null; // Filter by parent admin region name\n        this._filterParentLevel = null; // Which level the parent is (1 for ADM1, 2 for ADM2)\n        this._renderMode = 'orbit';\n        this._orbitRibbonVisible = false;\n        this._hatchTime = 0;\n        this._auroraTime = 0;\n        this._auroraEnabled = false;\n        this._tmpCamPos = new THREE.Vector3();\n        this._tmpCamDir = new THREE.Vector3();\n        // triTree fallback for surface sampling — elevation mesh when\n        // photoreal tiles haven't loaded yet (same pattern as RouteRibbonRenderer).\n        this.triTree = null;\n        this._lastFeatures = null;  // feature array from filtered GeoJSON\n        this._tmpWorldDir = new THREE.Vector3();\n        this._tmpGroupQuat = new THREE.Quaternion();\n\n        // Border labels\n        this._labelsEnabled = true;\n        this._labelData = [];\n        this._labelSprites = new Map();\n        this._labelPool = [];\n        this._labelTextureCache = new Map();\n        this._labelStyle = null;\n        this._labelSystem = null;\n        this._labelHandles = new Map();\n        this._labelGroup = new THREE.Group();\n        this._labelGroup.name = 'GeoJsonLabels';\n        this._labelGroup.renderOrder = 20;\n        this._labelGroup.frustumCulled = false;\n        this.group.add(this._labelGroup);\n        this._labelScaleCapAltM = LABEL_SCALE_CAP_ALT_METERS;\n        this._labelScaleReleaseAltM = LABEL_SCALE_RELEASE_ALT_METERS;\n        this._labelBorderRetireAltM = LABEL_BORDER_RETIRE_ALT_METERS;\n        this._hoveredLabelKey = null;\n        this._hoveredLabelSource = null;\n        this._labelHoverHandler = null;\n        this._nearbyBeyondBorderLabels = [];\n        this._nearbyBeyondBorderRegionKey = '';\n        this._nearbyBeyondBorderLastProbeAt = -Infinity;\n        this._nearbyBeyondBorderLastCameraDir = new THREE.Vector3();\n        this._tmpVec3 = new THREE.Vector3();\n        this._tmpVec3b = new THREE.Vector3();\n        this._tmpVec3c = new THREE.Vector3();\n        this._tmpVec3d = new THREE.Vector3();\n        this._tmpVec3e = new THREE.Vector3();\n        this._tmpGroupWorldPos = new THREE.Vector3();\n        this._tmpLineDirA = new THREE.Vector3();\n        this._tmpLineDirB = new THREE.Vector3();\n        this._tmpViewport = new THREE.Vector2(1, 1);\n        // Reversible WO-063 containment: administrative selection is static\n        // geographic work, so rapid travel may sample it at 20 Hz and run an\n        // immediate settle pass without changing label/category state.\n        this._labelPerformanceContainmentEnabled = true;\n        this._labelPresentationPoseValid = false;\n        this._labelPresentationCameraPosition = new THREE.Vector3();\n        this._labelPresentationLastRunMs = -Infinity;\n        this._labelPresentationDeferred = false;\n        this._labelPresentationCadence = {\n            fullFrames: 0,\n            rapidMotionSkippedFrames: 0,\n            settleFrames: 0,\n        };\n        this._bindLabelHoverEvents();\n    }\n\n    setVisible(visible) {\n        this.group.visible = !!visible;\n        if (!visible) {\n            this._cancelScheduledLoad();\n            this._cancelBoundaryWork();\n            this.clearHighlight();\n            this._clearHoveredAdministrativeLabel();\n            this._resetNearbyBeyondBorderLabels();\n            this._hideAllLabels();\n        }\n        if (visible) {\n            this._scheduleLoad();\n        }\n        this._applyModeVisibility();\n    }\n\n    setInteractiveReady(ready = true) {\n        const next = ready === true;\n        if (next === this._interactiveReady) return;\n        this._interactiveReady = next;\n        if (!next) {\n            this._cancelScheduledLoad();\n            return;\n        }\n        if (this.group?.visible) this._scheduleLoad();\n    }\n\n    setLabelsEnabled(enabled) {\n        this._labelsEnabled = !!enabled;\n        if (!this._labelsEnabled) {\n            this._hideAllLabels();\n        }\n        if (this._labelGroup) {\n            this._labelGroup.visible = this.group.visible && this._labelsEnabled;\n        }\n        this._labelPresentationPoseValid = false;\n    }\n\n    setLabelPerformanceContainmentEnabled(enabled) {\n        const next = enabled !== false;\n        if (next === this._labelPerformanceContainmentEnabled) return;\n        this._labelPerformanceContainmentEnabled = next;\n        this._labelPresentationPoseValid = false;\n        this._labelPresentationDeferred = false;\n    }\n\n    /**\n     * Recolor the borders at runtime without rebuilding geometry. The spire\n     * wall stores color per-vertex, so its buffer is overwritten in place; the\n     * orbit line reads a uColor uniform, so that is updated directly. Used to\n     * apply theme or relationship colors without rebuilding geometry.\n     *\n     * @param {number|string} colorValue Any CSS color accepted by THREE.Color.\n     */\n    setColor(colorValue) {\n        const resolved = resolveGeoJsonColor(colorValue);\n        let c;\n        try {\n            c = new THREE.Color(resolved);\n        } catch {\n            return;\n        }\n        this.color = resolved;\n\n        for (const chunk of this._lineChunks) {\n            const colorAttr = chunk?.mesh?.geometry?.getAttribute?.('color');\n            if (!colorAttr) continue;\n            for (let i = 0; i < colorAttr.count; i++) {\n                colorAttr.setXYZ(i, c.r, c.g, c.b);\n            }\n            colorAttr.needsUpdate = true;\n            for (const range of chunk.featureColorRanges || []) range.lastColor = resolved;\n        }\n\n        for (const chunk of this._orbitLineChunks) {\n            const colorAttr = chunk?.mesh?.geometry?.getAttribute?.('color');\n            if (!colorAttr) continue;\n            for (let i = 0; i < colorAttr.count; i++) colorAttr.setXYZ(i, c.r, c.g, c.b);\n            colorAttr.needsUpdate = true;\n            for (const range of chunk.featureColorRanges || []) range.lastColor = resolved;\n        }\n\n        // A layer with legacy single geometry has no chunk record; retain that\n        // path for callers updating while an async load is completing.\n        const singleColorAttr = this._line?.geometry?.getAttribute?.('color');\n        if (!this._lineChunks.length && singleColorAttr) {\n            for (let i = 0; i < singleColorAttr.count; i++) {\n                singleColorAttr.setXYZ(i, c.r, c.g, c.b);\n            }\n            singleColorAttr.needsUpdate = true;\n        }\n\n        const orbitColor = this._orbitLineMaterial?.uniforms?.uColor?.value\n            || this._orbitLine?.material?.uniforms?.uColor?.value;\n        if (orbitColor) orbitColor.copy(c);\n\n        const wallMaterial = this._lineMaterial || this._line?.material;\n        wallMaterial?.userData?.geoBorderUniforms?.uColor?.value?.copy?.(c);\n        wallMaterial?.attenuationColor?.copy?.(c);\n        wallMaterial?.emissive?.copy?.(c);\n        if (this._featureColorResolver && this._featureColorsEnabled) {\n            this.refreshFeatureColors({ force: true });\n        }\n    }\n\n    setFeatureColorResolver(resolver) {\n        const next = typeof resolver === 'function' ? resolver : null;\n        const changed = next !== this._featureColorResolver;\n        this._featureColorResolver = next;\n        const useFeatureColor = this._featureColorResolver && this._featureColorsEnabled ? 1 : 0;\n        for (const material of [\n            this._orbitLineMaterial || this._orbitLine?.material,\n            this._lineMaterial || this._line?.material,\n        ]) {\n            const uniforms = this._getWallUniforms(material);\n            if (uniforms?.uUseFeatureColor) uniforms.uUseFeatureColor.value = useFeatureColor;\n        }\n        this.refreshFeatureColors({ force: changed });\n    }\n\n    setFeatureColorsEnabled(enabled) {\n        const next = enabled !== false;\n        if (next === this._featureColorsEnabled) return;\n        this._featureColorsEnabled = next;\n        const useFeatureColor = this._featureColorResolver && next ? 1 : 0;\n        for (const material of [\n            this._orbitLineMaterial || this._orbitLine?.material,\n            this._lineMaterial || this._line?.material,\n        ]) {\n            const uniforms = this._getWallUniforms(material);\n            if (uniforms?.uUseFeatureColor) uniforms.uUseFeatureColor.value = useFeatureColor;\n        }\n        if (next) this.refreshFeatureColors({ force: true });\n        else this.setColor(this.color);\n    }\n\n    _resolvedFeatureColor(feature) {\n        if (!this._featureColorsEnabled || !this._featureColorResolver) {\n            return resolveGeoJsonColor(this.color);\n        }\n        try {\n            const resolved = this._featureColorResolver(feature);\n            return resolveGeoJsonColor(resolved ?? this.color);\n        } catch {\n            return resolveGeoJsonColor(this.color);\n        }\n    }\n\n    refreshFeatureColors({ force = false } = {}) {\n        const updateRanges = (chunks) => {\n            for (const chunk of chunks) {\n                const attribute = chunk?.mesh?.geometry?.getAttribute?.('color');\n                if (!attribute) continue;\n                let changed = false;\n                for (const range of chunk.featureColorRanges || []) {\n                    const value = this._resolvedFeatureColor(range.feature);\n                    if (!force && value === range.lastColor) continue;\n                    const color = new THREE.Color(value);\n                    const end = Math.min(attribute.count, range.start + range.count);\n                    for (let index = range.start; index < end; index += 1) {\n                        attribute.setXYZ(index, color.r, color.g, color.b);\n                    }\n                    range.lastColor = value;\n                    changed = true;\n                }\n                if (changed) attribute.needsUpdate = true;\n            }\n        };\n        updateRanges(this._lineChunks);\n        updateRanges(this._orbitLineChunks);\n    }\n\n    _scheduleLoad() {\n        if (!this._interactiveReady || this._loaded || this._loadPromise || !this.url) return;\n        this._cancelScheduledLoad();\n        const loadSeq = this._loadSeq;\n        const run = () => {\n            this._scheduledLoad = null;\n            if (this._loadSeq !== loadSeq) return;\n            if (!this.group?.visible) return;\n            if (this._loaded || this._loadPromise || !this.url) return;\n            this.load();\n        };\n        if (typeof requestIdleCallback === 'function') {\n            const id = requestIdleCallback(run, { timeout: 1500 });\n            this._scheduledLoad = { type: 'idle', id };\n        } else if (typeof requestAnimationFrame === 'function') {\n            const id = requestAnimationFrame(() => requestAnimationFrame(run));\n            this._scheduledLoad = { type: 'raf', id };\n        } else {\n            const id = setTimeout(run, 0);\n            this._scheduledLoad = { type: 'timeout', id };\n        }\n    }\n\n    _cancelScheduledLoad() {\n        const scheduled = this._scheduledLoad;\n        if (!scheduled) return;\n        if (scheduled.type === 'idle' && typeof cancelIdleCallback === 'function') {\n            cancelIdleCallback(scheduled.id);\n        } else if (scheduled.type === 'raf' && typeof cancelAnimationFrame === 'function') {\n            cancelAnimationFrame(scheduled.id);\n        } else if (scheduled.type === 'timeout') {\n            clearTimeout(scheduled.id);\n        }\n        this._scheduledLoad = null;\n    }\n\n    setLabelTuning({ scaleCapAltM, scaleReleaseAltM, borderRetireAltM } = {}) {\n        if (Number.isFinite(scaleCapAltM)) {\n            this._labelScaleCapAltM = Math.max(0, scaleCapAltM);\n        }\n        if (Number.isFinite(scaleReleaseAltM)) {\n            this._labelScaleReleaseAltM = Math.max(0, scaleReleaseAltM);\n        }\n        if (Number.isFinite(borderRetireAltM)) {\n            this._labelBorderRetireAltM = Math.max(0, borderRetireAltM);\n        }\n    }\n\n    _getLabelStyle() {\n        if (this._labelStyle) return this._labelStyle;\n        this._labelStyle = {\n            accent: resolveGeoJsonColor(this.color),\n            fontFamily: \"'JetBrains Mono','Fira Code','SF Mono','Consolas',monospace\",\n            fontSize: 40,\n            subFontSize: 28,\n            paddingX: 18,\n            paddingY: 12,\n            lineGap: 6,\n            bg: 'rgba(0, 0, 0, 0.55)',\n            text: '#ffffff',\n            subText: 'rgba(255, 255, 255, 0.75)',\n            borderWidth: 3\n        };\n        return this._labelStyle;\n    }\n\n    _buildLabelText(label) {\n        const displayLines = Array.isArray(label?.displayLines) ? label.displayLines : null;\n        if (displayLines && displayLines.length) {\n            const key = displayLines.join('\\n');\n            return { lines: displayLines, key };\n        }\n\n        const name = label?.name ? String(label.name) : '';\n        const lines = name ? [name] : [];\n        // No \"+\"/\"-\" selection prefix on the label text — the scene-label\n        // modal's context-add button is the single affordance for pinning a\n        // region to the agent context. Keeping a prefix here duplicated the\n        // \"+\" into the ground label, modal title, and context tag.\n        const meta = [];\n        if (label?.adminLabel) meta.push(label.adminLabel);\n        if (label?.iso && label.iso !== label.name) meta.push(label.iso);\n        if (meta.length) lines.push(meta.join(' · '));\n        const key = lines.join('\\n');\n        return { lines, key };\n    }\n\n    _getLabelTexture(label) {\n        if (typeof document === 'undefined') return null;\n        const { lines, key } = this._buildLabelText(label);\n        if (!lines.length) return null;\n\n        const style = this._getLabelStyle();\n        const cacheKey = `${style.accent}|${key}`;\n        const cached = this._labelTextureCache.get(cacheKey);\n        if (cached) return cached;\n\n        const canvas = document.createElement('canvas');\n        const ctx = canvas.getContext('2d');\n        if (!ctx) return null;\n\n        ctx.font = `600 ${style.fontSize}px ${style.fontFamily}`;\n        let maxWidth = ctx.measureText(lines[0]).width;\n        if (lines[1]) {\n            ctx.font = `500 ${style.subFontSize}px ${style.fontFamily}`;\n            maxWidth = Math.max(maxWidth, ctx.measureText(lines[1]).width);\n        }\n\n        const width = Math.ceil(maxWidth + style.paddingX * 2);\n        const height = Math.ceil(\n            style.paddingY * 2 +\n            style.fontSize +\n            (lines[1] ? style.lineGap + style.subFontSize : 0)\n        );\n\n        canvas.width = width;\n        canvas.height = height;\n        ctx.font = `600 ${style.fontSize}px ${style.fontFamily}`;\n        ctx.textBaseline = 'top';\n\n        ctx.fillStyle = style.bg;\n        ctx.fillRect(0, 0, width, height);\n\n        ctx.strokeStyle = style.accent;\n        ctx.lineWidth = style.borderWidth;\n        ctx.strokeRect(\n            style.borderWidth * 0.5,\n            style.borderWidth * 0.5,\n            width - style.borderWidth,\n            height - style.borderWidth\n        );\n\n        ctx.fillStyle = style.text;\n        ctx.fillText(lines[0], style.paddingX, style.paddingY);\n\n        if (lines[1]) {\n            ctx.font = `500 ${style.subFontSize}px ${style.fontFamily}`;\n            ctx.fillStyle = style.subText;\n            ctx.fillText(lines[1], style.paddingX, style.paddingY + style.fontSize + style.lineGap);\n        }\n\n        const texture = new THREE.CanvasTexture(canvas);\n        texture.needsUpdate = true;\n        texture.generateMipmaps = false;\n        texture.minFilter = THREE.LinearFilter;\n        texture.magFilter = THREE.LinearFilter;\n        const aspect = width / height;\n\n        const entry = { texture, aspect, key };\n        this._labelTextureCache.set(cacheKey, entry);\n        return entry;\n    }\n\n    _acquireLabelSprite(label) {\n        const entry = this._getLabelTexture(label);\n        if (!entry) return null;\n        let sprite = this._labelPool.pop();\n        if (!sprite) {\n            const material = new THREE.SpriteMaterial({\n                map: entry.texture,\n                transparent: true,\n                depthWrite: false,\n                depthTest: false\n            });\n            material.toneMapped = false;\n            sprite = new THREE.Sprite(material);\n            sprite.renderOrder = 20;\n        } else {\n            sprite.material.map = entry.texture;\n            sprite.material.needsUpdate = true;\n            sprite.material.opacity = 1;\n        }\n        sprite.userData.aspect = entry.aspect;\n        sprite.userData.labelKey = entry.key;\n        sprite.visible = true;\n        if (sprite.parent !== this._labelGroup) {\n            this._labelGroup.add(sprite);\n        }\n        return sprite;\n    }\n\n    _recycleLabelSprite(sprite) {\n        if (!sprite) return;\n        sprite.visible = false;\n        sprite.userData.labelRef = null;\n        sprite.userData.labelKey = null;\n        this._labelPool.push(sprite);\n    }\n\n    _hideAllLabels() {\n        this._clearSharedLabels();\n        for (const [, sprite] of this._labelSprites) {\n            this._recycleLabelSprite(sprite);\n        }\n        this._labelSprites.clear();\n    }\n\n    _ensureSharedLabelSystem() {\n        if (!this._labelSystem) {\n            try {\n                this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n            } catch {\n                this._labelSystem = null;\n            }\n        }\n        return this._labelSystem;\n    }\n\n    _disposeSharedLabelRecord(record) {\n        const handle = record?.handle || record;\n        if (!handle) return;\n        if (handle.group?.parent) handle.group.parent.remove(handle.group);\n        handle.dispose?.();\n    }\n\n    _clearSharedLabels() {\n        for (const record of this._labelHandles.values()) {\n            this._disposeSharedLabelRecord(record);\n        }\n        this._labelHandles.clear();\n    }\n\n    _sharedLabelPayload(label) {\n        const { lines, key } = this._buildLabelText(label);\n        const primary = lines[0] || label?.name || 'Administrative area';\n        const subText = lines.length > 1 ? lines.slice(1).join(' | ') : '';\n        return { primary, subText, key };\n    }\n\n    _sharedLabelObjectRadius(label) {\n        const level = Number.isFinite(label?.adminLevel) ? Math.max(0, Math.min(3, Math.floor(label.adminLevel))) : 0;\n        return LABEL_OBJECT_RADIUS_BY_ADM[level] || LABEL_OBJECT_RADIUS_BY_ADM[LABEL_OBJECT_RADIUS_BY_ADM.length - 1];\n    }\n\n    _sharedLabelMetadata(label) {\n        const props = label?.properties || {};\n        const pick = (...keys) => {\n            for (const key of keys) {\n                const value = props?.[key];\n                if (value !== undefined && value !== null && String(value).trim()) return String(value).trim();\n            }\n            return '';\n        };\n        const country = pick('NAME_0', 'name_0', 'SOVEREIGNT', 'ADMIN', 'COUNTRY', 'country');\n        const level = Number.isFinite(label?.adminLevel) ? label.adminLevel : null;\n        const parent = level >= 3\n            ? pick('NAME_2', 'name_2', 'NAME_1', 'name_1', 'PARENT', 'parent')\n            : (level >= 2\n                ? pick('NAME_1', 'name_1', 'PARENT', 'parent')\n                : (level >= 1 ? country : ''));\n        const isBorder = label?.kind === 'border' || label?.kind === 'border-beyond';\n        const boundaryLabel = isBorder ? 'Administrative border' : 'Administrative area';\n        return {\n            typeLabel: boundaryLabel,\n            name: label?.name || '',\n            boundaryType: isBorder ? 'Border' : 'Area',\n            boundaryRole: label?.kind === 'border-beyond' ? 'beyond-border' : '',\n            currentRegion: label?.currentRegion || '',\n            beyondRegion: label?.beyondRegion || '',\n            adminLevel: level,\n            adminLabel: label?.adminLabel || '',\n            iso: label?.iso || pick('ISO_A3', 'iso_a3', 'GID_0', 'gid_0'),\n            country,\n            parent: parent && parent !== label?.name ? parent : '',\n            source: this.url || '',\n            selectionKey: label?.selectionKey || '',\n            selectionLabel: label?.selectionLabel || '',\n            lat: label?.lat,\n            lon: label?.lon,\n        };\n    }\n\n    _upsertSharedLabel(index, label, position, { maxDistance, opacity } = {}) {\n        const ls = this._ensureSharedLabelSystem();\n        if (!ls || !label || !position) return null;\n        const payload = this._sharedLabelPayload(label);\n        const metadata = this._sharedLabelMetadata(label);\n        const color = resolveGeoJsonColor(this.color);\n        let record = this._labelHandles.get(index);\n        if (!record) {\n            const handle = ls.createLabel(payload.primary, {\n                position,\n                type: 'geojson',\n                color,\n                objectRadius: this._sharedLabelObjectRadius(label),\n                subText: payload.subText,\n                metadata,\n                maxDistance,\n                opacity,\n                adminLevel: label.adminLevel,\n                labelPriority: label.priority,\n                treeShyness: label.kind === 'feature',\n            });\n            if (handle?.group) {\n                handle.group.userData.geoJsonLabelIndex = index;\n                handle.group.userData.geoJsonLabelRef = label;\n                handle.group.traverse?.((node) => {\n                    node.userData.geoJsonLabelIndex = index;\n                    node.userData.geoJsonLabelRef = label;\n                });\n                this.group.add(handle.group);\n            }\n            record = { handle, key: payload.key };\n            this._labelHandles.set(index, record);\n        } else {\n            if (record.key !== payload.key) {\n                ls.updateText(record.handle, payload.primary, payload.subText);\n                record.key = payload.key;\n            }\n            ls.updatePosition(record.handle, position);\n        }\n        if (record.handle) {\n            ls.updateMetadata(record.handle, metadata);\n            record.handle.maxDistance = Number.isFinite(maxDistance) ? maxDistance : null;\n            record.handle.opacity = Number.isFinite(opacity) ? Math.max(0, Math.min(1, opacity)) : 1;\n            record.handle.lat = label.lat;\n            record.handle.lon = label.lon;\n            record.handle.adminLevel = Number.isFinite(label.adminLevel) ? label.adminLevel : null;\n            record.handle.labelPriority = Number.isFinite(label.priority) ? label.priority : 0;\n            record.handle.treeShyness = label.kind === 'feature';\n            record.handle.group.userData.geoJsonLabelRef = label;\n            record.handle.group.traverse?.((node) => {\n                node.userData.geoJsonLabelRef = label;\n            });\n        }\n        return record?.handle || null;\n    }\n\n    setSceneSelection(keys) {\n        const next = new Set(Array.isArray(keys) ? keys : []);\n        let changed = next.size !== this._sceneSelectionKeys.size;\n        if (!changed) {\n            for (const key of next) {\n                if (!this._sceneSelectionKeys.has(key)) {\n                    changed = true;\n                    break;\n                }\n            }\n        }\n        if (!changed) return;\n        this._sceneSelectionKeys = next;\n        this._clearLabelCache();\n        for (const sprite of this._labelSprites.values()) {\n            sprite.userData.labelKey = null;\n        }\n        for (const record of this._labelHandles.values()) {\n            record.key = null;\n        }\n    }\n\n    pickLabel(raycaster, camera = null) {\n        if (!raycaster || !this._labelGroup || !this._labelGroup.visible) return null;\n        if (camera && !raycaster.camera) raycaster.camera = camera;\n        if (!raycaster.camera) return null;\n        const sprites = [];\n        for (const sprite of this._labelSprites.values()) {\n            if (sprite.visible) sprites.push(sprite);\n        }\n        for (const record of this._labelHandles.values()) {\n            const group = record?.handle?.group;\n            if (!group || group.visible === false) continue;\n            sprites.push(...group.children);\n        }\n        if (!sprites.length) return null;\n        const hits = raycaster.intersectObjects(sprites, true);\n        if (!hits.length) return null;\n        const sprite = hits[0].object;\n        const label = sprite?.userData?.labelRef\n            || sprite?.userData?.geoJsonLabelRef\n            || sprite?.parent?.userData?.geoJsonLabelRef;\n        const entry = label ? this._buildSceneSelectionEntry(label) : null;\n        return entry ? { entry, distance: hits[0]?.distance ?? 0 } : null;\n    }\n\n    _clearLabelCache() {\n        for (const entry of this._labelTextureCache.values()) {\n            entry.texture?.dispose?.();\n        }\n        this._labelTextureCache.clear();\n        this._labelStyle = null;\n    }\n\n    _disposeLabelSprites() {\n        this._clearSharedLabels();\n        for (const sprite of this._labelSprites.values()) {\n            sprite.material?.map?.dispose?.();\n            sprite.material?.dispose?.();\n            sprite.removeFromParent();\n        }\n        for (const sprite of this._labelPool) {\n            sprite.material?.map?.dispose?.();\n            sprite.material?.dispose?.();\n            sprite.removeFromParent();\n        }\n        this._labelSprites.clear();\n        this._labelPool.length = 0;\n    }\n\n    _bindLabelHoverEvents() {\n        if (typeof document === 'undefined' || this._labelHoverHandler) return;\n        this._labelHoverHandler = (event) => this._handleSceneLabelHover(event?.detail || null);\n        document.addEventListener('noclip:scene-label-hover', this._labelHoverHandler);\n    }\n\n    _unbindLabelHoverEvents() {\n        if (typeof document === 'undefined' || !this._labelHoverHandler) return;\n        document.removeEventListener('noclip:scene-label-hover', this._labelHoverHandler);\n        this._labelHoverHandler = null;\n    }\n\n    _handleSceneLabelHover(detail) {\n        if (!detail || detail.type !== 'geojson') {\n            this._clearHoveredAdministrativeLabel();\n            return;\n        }\n        const meta = detail.metadata || {};\n        const source = typeof meta.source === 'string' ? meta.source : '';\n        if (source && this.url && source !== this.url) {\n            this._clearHoveredAdministrativeLabel();\n            return;\n        }\n        const key = typeof meta.selectionKey === 'string' ? meta.selectionKey : '';\n        if (!key) {\n            this._clearHoveredAdministrativeLabel();\n            return;\n        }\n        const label = this._labelData.find((entry) => entry?.selectionKey === key) || null;\n        if (!label || label.kind !== 'feature') {\n            this._clearHoveredAdministrativeLabel();\n            return;\n        }\n        this._setHoveredAdministrativeLabel(label);\n    }\n\n    _setHoveredAdministrativeLabel(label) {\n        const key = label?.selectionKey || null;\n        if (!key) {\n            this._clearHoveredAdministrativeLabel();\n            return;\n        }\n        if (this._hoveredLabelKey === key) return;\n        this._hoveredLabelKey = key;\n        this._hoveredLabelSource = this.url || null;\n        if (label.featureRef) {\n            this.setHighlightFeature(label.featureRef, {\n                opacity: Math.max(this.highlightOpacity, 0.11),\n                force: true,\n            });\n        }\n    }\n\n    _clearHoveredAdministrativeLabel() {\n        if (!this._hoveredLabelKey) return;\n        this._hoveredLabelKey = null;\n        this._hoveredLabelSource = null;\n        this.clearHighlight();\n    }\n\n    _applyHoverOpacity(label, opacity) {\n        if (!this._hoveredLabelKey || label?.kind !== 'feature') return opacity;\n        if (label.selectionKey === this._hoveredLabelKey) {\n            return Math.max(opacity, 0.98);\n        }\n        return opacity * 0.24;\n    }\n\n    _resetNearbyBeyondBorderLabels() {\n        this._nearbyBeyondBorderLabels = [];\n        this._nearbyBeyondBorderRegionKey = '';\n        this._nearbyBeyondBorderLastProbeAt = -Infinity;\n        this._nearbyBeyondBorderLastCameraDir.set(0, 0, 0);\n    }\n\n    _getWallUniforms(material = this._lineMaterial || this._line?.material) {\n        return material?.uniforms || material?.userData?.geoBorderUniforms || null;\n    }\n\n    setMode(mode) {\n        const nextMode = mode === 'surface' ? 'surface' : 'orbit';\n        if (this._renderMode === nextMode) return;\n        this._renderMode = nextMode;\n        const orbitUniforms = this._getWallUniforms(\n            this._orbitLineMaterial || this._orbitLine?.material\n        );\n        if (orbitUniforms?.uRadialLiftMeters) {\n            orbitUniforms.uRadialLiftMeters.value = BORDER_ORBIT_LIFT_METERS;\n        }\n        if (nextMode === 'surface') this._orbitRibbonVisible = false;\n        if (nextMode !== 'surface') this._resetNearbyBeyondBorderLabels();\n        this._applyModeVisibility();\n        if (this._highlightFeature) {\n            this.setHighlightFeature(this._highlightFeature, { force: true });\n        }\n    }\n\n    setAuroraEnabled(enabled) {\n        this._auroraEnabled = !!enabled;\n        const mat = this._lineMaterial || this._line?.material;\n        if (!mat) return;\n        const uniforms = this._getWallUniforms(mat);\n        if (uniforms?.uAuroraEnabled) {\n            uniforms.uAuroraEnabled.value = this._auroraEnabled ? 1 : 0;\n        }\n    }\n\n    getAuroraEnabled() {\n        return this._auroraEnabled;\n    }\n\n    setAuroraParams({ amplitude, frequency, speed } = {}) {\n        const mat = this._lineMaterial || this._line?.material;\n        if (!mat) return;\n        const uniforms = this._getWallUniforms(mat);\n        if (!uniforms) return;\n        if (Number.isFinite(amplitude) && uniforms.uAuroraAmplitude) {\n            uniforms.uAuroraAmplitude.value = amplitude;\n        }\n        if (Number.isFinite(frequency) && uniforms.uAuroraFrequency) {\n            uniforms.uAuroraFrequency.value = frequency;\n        }\n        if (Number.isFinite(speed) && uniforms.uAuroraSpeed) {\n            uniforms.uAuroraSpeed.value = speed;\n        }\n    }\n\n    /**\n     * Governor hook: record JS-heap memory pressure in [0,1]. PlanetScene's\n     * altitude→ADM band resolver reads getMemoryPressure() and drops one admin\n     * level when pressure is high, shedding border geometry. Never affects\n     * render resolution.\n     */\n    applyMemoryPressure(level) {\n        const p = Number.isFinite(level) ? Math.min(1, Math.max(0, level)) : 0;\n        this._memoryPressure = p;\n    }\n\n    getMemoryPressure() {\n        return this._memoryPressure || 0;\n    }\n\n    async load() {\n        if (this._loaded) return;\n        if (this._loadPromise) return this._loadPromise;\n        if (!this.url) return;\n        this._cancelScheduledLoad();\n\n        const loadSeq = ++this._loadSeq;\n        const controller = new AbortController();\n        this._boundaryAbort?.abort();\n        this._boundaryAbort = controller;\n        const signal = controller.signal;\n        const task = (async () => {\n            const geojson = await fetchJsonResource(this.url, {\n                errorMessage: 'GeoJSON load failed', signal,\n            });\n            if (this._loadSeq !== loadSeq) return;\n            const features = [];\n            const source = Array.isArray(geojson?.features) ? geojson.features :\n                (geojson?.type === 'Feature' ? [geojson] : geojson?.coordinates ? [{ geometry: geojson, properties: geojson.properties || {} }] : []);\n            const owner = this;\n            await runBoundarySteps((function* () {\n                for (const feature of source) {\n                    if ((!owner._filterIso3 || owner._featureMatchesIso3(feature, owner._filterIso3)) &&\n                        (!owner._filterParentName || owner._featureMatchesParent(feature, owner._filterParentName, owner._filterParentLevel))) {\n                        if (features.length >= MAX_BOUNDARY_FEATURES) throw new RangeError('Boundary feature limit exceeded');\n                        features.push(feature);\n                    }\n                    yield;\n                }\n            })(), signal);\n            await this._prepareFeatures(features, signal);\n            const featureIndex = [], labelData = [];\n            await runBoundarySteps((function* () {\n                for (const feature of features) {\n                    owner._pushFeatureEntry(feature, featureIndex);\n                    labelData.push(...owner._buildLabelData({ features: [feature] }));\n                    yield;\n                }\n            })(), signal);\n            await this._setRenderGeometryFromFeatures(features, { signal, prepared: true });\n            checkBoundarySignal(signal);\n            if (this._loadSeq !== loadSeq) return;\n            this._featureIndex = featureIndex;\n            this._labelData = labelData;\n            this._labelPresentationPoseValid = false;\n            this._resetNearbyBeyondBorderLabels();\n            this._hideAllLabels();\n            this._lastFeatures = features;\n            this._loaded = true;\n            this._loadError = null;\n            this._applyModeVisibility();\n        })();\n        this._loadPromise = task;\n\n        try {\n            await task;\n        } catch (error) {\n            if (!signal.aborted && this._loadSeq === loadSeq) {\n                this._loadError = error.message;\n                console.error('[GeoJsonLayer] Failed to load GeoJSON', error);\n            }\n        } finally {\n            if (this._loadPromise === task) this._loadPromise = null;\n            if (this._boundaryAbort === controller) this._boundaryAbort = null;\n        }\n    }\n\n    dispose() {\n        this._cancelBoundaryWork();\n        this._unbindLabelHoverEvents();\n        this._clearLine();\n        this.clearHighlight();\n        this._hideAllLabels();\n        this._disposeLabelSprites();\n        this._clearLabelCache();\n        if (this._postCompositeLayerRegistered) {\n            this.sceneInitializer?.unregisterPostCompositeLayer?.(\n                SCREEN_SPACE_OUTLINE_POST_COMPOSITE_LAYER\n            );\n            this._postCompositeLayerRegistered = false;\n        }\n        this._labelData = [];\n        this._resetNearbyBeyondBorderLabels();\n        this.group?.removeFromParent?.();\n        this._loaded = false;\n        this._loadPromise = null;\n        this._cancelScheduledLoad();\n        this._featureIndex = null;\n        this._lastFeatures = null;\n        this._clearSurfaceSampleCache();\n        this._loadSeq += 1;\n    }\n\n    setUrl(url, { reload = true } = {}) {\n        if (!url || url === this.url) return;\n        this._cancelBoundaryWork();\n        this.url = url;\n        this._loaded = false;\n        this._loadPromise = null;\n        this._featureIndex = null;\n        this._labelData = [];\n        this._resetNearbyBeyondBorderLabels();\n        this._lastFeatures = null;\n        this._clearSurfaceSampleCache();\n        this._hideAllLabels();\n        this._clearLabelCache();\n        this.clearHighlight();\n        this._loadSeq += 1;\n        if (reload || this.group?.visible) {\n            this._scheduleLoad();\n        }\n    }\n\n    setCountryFilter(iso3, { reload = true } = {}) {\n        const next = typeof iso3 === 'string' && iso3.length ? iso3.toUpperCase() : null;\n        if (next === this._filterIso3) return;\n        this._cancelBoundaryWork();\n        this._filterIso3 = next;\n        this._loaded = false;\n        this._loadPromise = null;\n        this._featureIndex = null;\n        this._labelData = [];\n        this._resetNearbyBeyondBorderLabels();\n        this._lastFeatures = null;\n        this._clearSurfaceSampleCache();\n        this._hideAllLabels();\n        this._clearLabelCache();\n        this.clearHighlight();\n        if (reload || this.group?.visible) {\n            this._scheduleLoad();\n        }\n    }\n\n    /**\n     * Set a parent region filter to only show subdivisions within a specific parent.\n     * For example, when showing ADM2, set parentName to the ADM1 name to only show\n     * subdivisions within that ADM1 region.\n     * @param {string|null} parentName - The parent region name to filter by\n     * @param {number|null} parentLevel - Which admin level the parent is (1, 2, etc.)\n     * @param {object} options - { reload: boolean }\n     */\n    setParentFilter(parentName, parentLevel = null, { reload = true } = {}) {\n        const nextName = typeof parentName === 'string' && parentName.length ? parentName : null;\n        const nextLevel = Number.isFinite(parentLevel) ? parentLevel : null;\n        if (nextName === this._filterParentName && nextLevel === this._filterParentLevel) return;\n        this._cancelBoundaryWork();\n        this._filterParentName = nextName;\n        this._filterParentLevel = nextLevel;\n        this._loaded = false;\n        this._loadPromise = null;\n        this._featureIndex = null;\n        this._labelData = [];\n        this._resetNearbyBeyondBorderLabels();\n        this._lastFeatures = null;\n        this._clearSurfaceSampleCache();\n        this._hideAllLabels();\n        this._clearLabelCache();\n        this.clearHighlight();\n        if (reload || this.group?.visible) {\n            this._scheduleLoad();\n        }\n    }\n\n    /**\n     * Clear the parent filter\n     */\n    clearParentFilter({ reload = true } = {}) {\n        this.setParentFilter(null, null, { reload });\n    }\n\n    setHighlightFeature(feature, { color, opacity, force = false } = {}) {\n        if (!feature) {\n            this.clearHighlight();\n            return;\n        }\n        if (!force && feature === this._highlightFeature) return;\n        this._highlightFeature = feature;\n        const props = feature?.properties || {};\n        const parsedAdminLevel = this._parseAdminLevel(props);\n        const adminLevel = Number.isFinite(parsedAdminLevel)\n            ? parsedAdminLevel\n            : (this._getIsoCode(props) ? 0 : null);\n        const style = this._getHighlightStyleForAdminLevel(adminLevel);\n        this._highlightAdminLevel = adminLevel;\n        this._highlightHatchSpacingMeters = style.hatchSpacingMeters;\n        this._highlightHatchThickness = style.hatchThickness;\n        this._highlightHatchFeather = style.hatchFeather;\n        this._highlightOutlineWidthMeters = style.outlineWidthMeters;\n        const anchor = this._resolveLabelLatLon(feature);\n        if (anchor) {\n            const dir = latLonToLocalDir(anchor.lat, anchor.lon);\n            this._highlightCenterDir = dir ? dir.normalize() : null;\n        } else {\n            this._highlightCenterDir = null;\n        }\n\n        const geometry = this._buildFillGeometry(feature);\n        if (!geometry) {\n            this.clearHighlight();\n            return;\n        }\n\n        this._clearFill();\n        const resolvedHighlightColor = Number.isFinite(color) ? color : resolveGeoJsonColor(this.highlightColor);\n        const material = this._buildHatchMaterial({\n            color: resolvedHighlightColor,\n            opacity: Number.isFinite(opacity) ? opacity : this.highlightOpacity\n        });\n        const mesh = new THREE.Mesh(geometry, material);\n        mesh.renderOrder = 7;\n        mesh.frustumCulled = false;\n        this.group.add(mesh);\n        this._fillMesh = mesh;\n\n        this._clearOutline();\n        const outline = this._buildHighlightOutlineGeometry(feature);\n        if (outline) {\n            const outlineMaterial = new THREE.MeshBasicMaterial({\n                color: resolvedHighlightColor,\n                transparent: true,\n                opacity: Number.isFinite(opacity) ? opacity : this.highlightOpacity,\n                depthWrite: false,\n                side: THREE.DoubleSide\n            });\n            outlineMaterial.toneMapped = false;\n            outlineMaterial.depthTest = true;\n            const outlineMesh = new THREE.Mesh(outline, outlineMaterial);\n            outlineMesh.renderOrder = 8;\n            outlineMesh.frustumCulled = false;\n            this.group.add(outlineMesh);\n            this._outlineMesh = outlineMesh;\n        }\n    }\n\n    clearHighlight() {\n        this._highlightFeature = null;\n        this._highlightAdminLevel = null;\n        this._highlightCenterDir = null;\n        this._highlightHatchSpacingMeters = DEFAULT_HATCH_SPACING_METERS;\n        this._highlightHatchThickness = DEFAULT_HATCH_THICKNESS;\n        this._highlightHatchFeather = DEFAULT_HATCH_FEATHER;\n        this._highlightOutlineWidthMeters = DEFAULT_HIGHLIGHT_OUTLINE_WIDTH_METERS;\n        this._clearFill();\n        this._clearOutline();\n    }\n\n    update(dt, camera = null) {\n        this._boundaryCamera = camera || this._boundaryCamera;\n        // Orientation-only motion never invalidates the geographic residency\n        // window. GPS jitter also stays inside its generous prefetch margin.\n        if (this.group.visible && this._loaded && !this._geometryAbort && this._lastFeatures?.length) {\n            this._boundaryViewProbe ||= { dir: new THREE.Vector3(), cap: 0 };\n            const nextView = this._captureBoundaryView(this._boundaryViewProbe);\n            const prior = this._geometryView;\n            if (nextView && (!prior || Math.acos(THREE.MathUtils.clamp(prior.dir.dot(nextView.dir), -1, 1))\n                + Math.max(0, nextView.cap - prior.cap) > THREE.MathUtils.degToRad(2))) {\n                this._rebuildGeometry();\n            }\n        }\n        this._updateOrbitLineScreenSpace(camera);\n        this._updateHorizonCull(camera);\n        this._boundaryStage?._updateOrbitLineScreenSpace(camera);\n        this._boundaryStage?._updateHorizonCull(camera);\n\n        const delta = Number.isFinite(dt) ? dt : 0;\n\n        // Update aurora time for wall animation\n        const wallMaterial = this._lineMaterial || this._line?.material;\n        if (this._auroraEnabled && wallMaterial) {\n            this._auroraTime += delta;\n            const uniforms = this._getWallUniforms(wallMaterial);\n            if (uniforms?.uTime) {\n                uniforms.uTime.value = this._auroraTime;\n            }\n        }\n\n        // Update border labels\n        if (this._labelsEnabled && this.group.visible && camera) {\n            this._updateLabels(camera);\n        }\n\n        if (camera) {\n            this._updateHighlightHatchUniforms(camera);\n            // Scale highlight elements inversely with camera altitude\n            // so they shrink from orbit (same approach as OpenInfraMap altitude scaling)\n            const camPos = camera.userData?.worldPosition || camera.position;\n            const altKm = Math.max(0.01, (camPos.length() - this.planetRadius) / 1000);\n            const invScale = 1 / (1 + Math.log10(1 + altKm * 0.5) * 2.5);\n            if (this._fillMesh?.material?.uniforms?.uScale) {\n                // Increase hatch scale (= tighter lines) at altitude\n                const baseScale = this._fillMesh.material.uniforms.uScale.value;\n                if (!this._baseHatchScale) this._baseHatchScale = baseScale;\n                this._fillMesh.material.uniforms.uScale.value = this._baseHatchScale / invScale;\n            }\n            if (this._fillMesh?.material?.uniforms?.uOpacity) {\n                if (!this._baseHatchOpacity) this._baseHatchOpacity = this._fillMesh.material.uniforms.uOpacity.value;\n                this._fillMesh.material.uniforms.uOpacity.value = this._baseHatchOpacity * invScale;\n            }\n            // Scale outline width with altitude too\n            if (this._outlineMesh) {\n                this._outlineMesh.scale.setScalar(invScale);\n            }\n        }\n\n        // Update hatch time for fill mesh\n        if (!this._fillMesh || !this._fillMesh.material) return;\n        const material = this._fillMesh.material;\n        if (!material.uniforms || !material.uniforms.uTime) return;\n        this._hatchTime += delta;\n        material.uniforms.uTime.value = this._hatchTime;\n    }\n\n    _normalizedRegionName(value) {\n        return value == null ? '' : String(value).trim().toLocaleLowerCase();\n    }\n\n    _regionKey(feature) {\n        if (!feature) return '';\n        const name = this._normalizedRegionName(feature.name || this._getFeatureName(feature.properties));\n        const level = this._parseAdminLevel(feature.properties);\n        return `${Number.isFinite(level) ? level : 'x'}:${name}`;\n    }\n\n    _isSameRegion(feature, currentFeature) {\n        if (!feature || !currentFeature) return false;\n        if (feature === currentFeature) return true;\n        const featureName = this._normalizedRegionName(feature.name || this._getFeatureName(feature.properties));\n        const currentName = this._normalizedRegionName(currentFeature.name || this._getFeatureName(currentFeature.properties));\n        return !!featureName && featureName === currentName;\n    }\n\n    _featureAtViewerOffset(viewerLat, viewerLon, lonScale, xMeters, yMeters) {\n        const lat = viewerLat + yMeters / METERS_PER_LATITUDE_DEGREE;\n        const lon = this._wrapLon180(\n            viewerLon + xMeters / (METERS_PER_LATITUDE_DEGREE * lonScale)\n        );\n        return this.getFeatureAtLatLon(lat, lon);\n    }\n\n    _insertNearestBoundarySegment(nearest, candidate) {\n        if (!candidate || candidate.distanceMeters > BEYOND_BORDER_LABEL_MAX_DISTANCE_METERS) return;\n        if (nearest.length < BEYOND_BORDER_NEAREST_SEGMENT_LIMIT) {\n            nearest.push(candidate);\n            return;\n        }\n        let farthestIndex = 0;\n        for (let i = 1; i < nearest.length; i++) {\n            if (nearest[i].distanceMeters > nearest[farthestIndex].distanceMeters) farthestIndex = i;\n        }\n        if (candidate.distanceMeters < nearest[farthestIndex].distanceMeters) {\n            nearest[farthestIndex] = candidate;\n        }\n    }\n\n    _nearestBoundarySegments(feature, viewerLat, viewerLon) {\n        const nearest = [];\n        const lonScale = Math.max(0.12, Math.cos(THREE.MathUtils.degToRad(viewerLat)));\n        for (const polygon of feature?.polygons || []) {\n            for (const ring of polygon?.rings || []) {\n                if (!Array.isArray(ring) || ring.length < 2) continue;\n                for (let i = 0; i < ring.length; i++) {\n                    const a = ring[i];\n                    const b = ring[(i + 1) % ring.length];\n                    if (!Array.isArray(a) || !Array.isArray(b)) continue;\n                    const latA = Number(a[1]);\n                    const latB = Number(b[1]);\n                    const lonA = Number(a[0]);\n                    const lonB = Number(b[0]);\n                    if (![latA, latB, lonA, lonB].every(Number.isFinite)) continue;\n\n                    const ax = this._wrapLon180(lonA - viewerLon) * lonScale * METERS_PER_LATITUDE_DEGREE;\n                    const ay = (latA - viewerLat) * METERS_PER_LATITUDE_DEGREE;\n                    const bx = this._wrapLon180(lonB - viewerLon) * lonScale * METERS_PER_LATITUDE_DEGREE;\n                    const by = (latB - viewerLat) * METERS_PER_LATITUDE_DEGREE;\n                    const dx = bx - ax;\n                    const dy = by - ay;\n                    const lengthSq = dx * dx + dy * dy;\n                    if (!Number.isFinite(lengthSq) || lengthSq < 1) continue;\n                    const t = THREE.MathUtils.clamp(-(ax * dx + ay * dy) / lengthSq, 0, 1);\n                    const x = ax + dx * t;\n                    const y = ay + dy * t;\n                    this._insertNearestBoundarySegment(nearest, {\n                        x,\n                        y,\n                        dx,\n                        dy,\n                        distanceMeters: Math.hypot(x, y),\n                        lat: viewerLat + y / METERS_PER_LATITUDE_DEGREE,\n                        lon: this._wrapLon180(\n                            viewerLon + x / (METERS_PER_LATITUDE_DEGREE * lonScale)\n                        ),\n                    });\n                }\n            }\n        }\n        nearest.sort((a, b) => a.distanceMeters - b.distanceMeters);\n        return { nearest, lonScale };\n    }\n\n    _findRegionBeyondSegment(segment, currentFeature, viewerLat, viewerLon, lonScale) {\n        const length = Math.hypot(segment.dx, segment.dy);\n        if (!Number.isFinite(length) || length <= 0) return null;\n        const normalX = -segment.dy / length;\n        const normalY = segment.dx / length;\n        // Choose the normal pointing toward the viewer, then probe in the\n        // opposite direction. This makes \"beyond\" relative to the user's\n        // actual side of the border rather than the source ring's winding.\n        const viewerSide = (-segment.x * normalX - segment.y * normalY) >= 0 ? 1 : -1;\n\n        for (const distance of BEYOND_BORDER_PROBE_DISTANCES_METERS) {\n            const inside = this._featureAtViewerOffset(\n                viewerLat,\n                viewerLon,\n                lonScale,\n                segment.x + normalX * viewerSide * distance,\n                segment.y + normalY * viewerSide * distance\n            );\n            const beyond = this._featureAtViewerOffset(\n                viewerLat,\n                viewerLon,\n                lonScale,\n                segment.x - normalX * viewerSide * distance,\n                segment.y - normalY * viewerSide * distance\n            );\n            const beyondName = beyond?.name || this._getFeatureName(beyond?.properties);\n            if (beyondName && !this._isSameRegion(beyond, currentFeature)) {\n                // Prefer a verified current-side sample, but allow the result\n                // at tight corners where the inward probe can land in a hole.\n                if (!inside || this._isSameRegion(inside, currentFeature)) return beyond;\n            }\n        }\n        return null;\n    }\n\n    _resolveNearbyBeyondBorderLabels(currentFeature, viewerLat, viewerLon) {\n        if (!currentFeature || !Number.isFinite(viewerLat) || !Number.isFinite(viewerLon)) return [];\n        const currentName = currentFeature.name || this._getFeatureName(currentFeature.properties);\n        if (!currentName) return [];\n        const { nearest, lonScale } = this._nearestBoundarySegments(currentFeature, viewerLat, viewerLon);\n        const byRegion = new Map();\n\n        for (const segment of nearest) {\n            const beyondFeature = this._findRegionBeyondSegment(\n                segment,\n                currentFeature,\n                viewerLat,\n                viewerLon,\n                lonScale\n            );\n            const beyondName = beyondFeature?.name || this._getFeatureName(beyondFeature?.properties);\n            const normalizedBeyond = this._normalizedRegionName(beyondName);\n            if (!normalizedBeyond || normalizedBeyond === this._normalizedRegionName(currentName)) continue;\n            const prior = byRegion.get(normalizedBeyond);\n            if (prior && prior.segment.distanceMeters <= segment.distanceMeters) continue;\n            byRegion.set(normalizedBeyond, { beyondFeature, beyondName: String(beyondName), segment });\n        }\n\n        return [...byRegion.values()]\n            .sort((a, b) => a.segment.distanceMeters - b.segment.distanceMeters)\n            .slice(0, BEYOND_BORDER_LABEL_MAX_VISIBLE)\n            .map(({ beyondFeature, beyondName, segment }) => {\n                const props = beyondFeature.properties || {};\n                const parsedLevel = this._parseAdminLevel(props);\n                const iso = this._getIsoCode(props);\n                const isCountry = parsedLevel === 0 || (!Number.isFinite(parsedLevel) && !!iso);\n                const adminLevel = isCountry && !Number.isFinite(parsedLevel) ? 0 : parsedLevel;\n                const targetDir = latLonToLocalDir(segment.lat, segment.lon);\n                const selectionKey = this._buildSceneSelectionKey({\n                    name: beyondName,\n                    iso,\n                    adminLevel,\n                    isCountry,\n                });\n                return {\n                    key: `beyond:${Number.isFinite(adminLevel) ? adminLevel : 'x'}:${this._normalizedRegionName(beyondName)}`,\n                    name: beyondName,\n                    beyondRegion: beyondName,\n                    currentRegion: String(currentName),\n                    displayLines: [beyondName, 'BEYOND THIS BORDER'],\n                    iso,\n                    adminLevel,\n                    adminLabel: Number.isFinite(adminLevel) && adminLevel > 0 ? `ADM${adminLevel}` : null,\n                    priority: 1200 - Math.min(200, segment.distanceMeters / 1000),\n                    baseScale: this.planetRadius * LABEL_BASE_SCALE * 0.9,\n                    scaleMul: 0.9,\n                    kind: 'border-beyond',\n                    selectionKey,\n                    selectionLabel: this._buildSceneSelectionLabel({\n                        name: beyondName,\n                        adminLevel,\n                        isCountry,\n                    }),\n                    localDir: targetDir?.clone?.() || null,\n                    targetDir,\n                    lat: segment.lat,\n                    lon: segment.lon,\n                    lineLat: segment.lat,\n                    lineLon: segment.lon,\n                    maxDistance: BEYOND_BORDER_LABEL_MAX_DISTANCE_METERS,\n                    distanceToBorder: segment.distanceMeters,\n                    properties: props,\n                };\n            })\n            .filter((label) => !!label.localDir);\n    }\n\n    _refreshNearbyBeyondBorderLabels(currentFeature, viewerLat, viewerLon, camDir) {\n        const now = typeof performance !== 'undefined' && performance.now\n            ? performance.now()\n            : Date.now();\n        const regionKey = this._regionKey(currentFeature);\n        const movedMeters = this._nearbyBeyondBorderLastCameraDir.lengthSq() > 0\n            ? Math.acos(THREE.MathUtils.clamp(\n                this._nearbyBeyondBorderLastCameraDir.dot(camDir),\n                -1,\n                1\n            )) * this.planetRadius\n            : Infinity;\n        if (\n            regionKey === this._nearbyBeyondBorderRegionKey\n            && now - this._nearbyBeyondBorderLastProbeAt < BEYOND_BORDER_LABEL_REFRESH_MS\n            && movedMeters < BEYOND_BORDER_LABEL_CAMERA_MOVE_METERS\n        ) {\n            return;\n        }\n\n        const previous = new Map(this._nearbyBeyondBorderLabels.map((label) => [label.key, label]));\n        const next = this._resolveNearbyBeyondBorderLabels(currentFeature, viewerLat, viewerLon);\n        for (const label of next) {\n            const prior = previous.get(label.key);\n            if (!prior?.localDir || !label.targetDir) continue;\n            const angularJump = Math.acos(THREE.MathUtils.clamp(prior.localDir.dot(label.targetDir), -1, 1));\n            if (angularJump * this.planetRadius < 50_000) {\n                label.localDir.copy(prior.localDir);\n            }\n        }\n        this._nearbyBeyondBorderLabels = next;\n        this._nearbyBeyondBorderRegionKey = regionKey;\n        this._nearbyBeyondBorderLastProbeAt = now;\n        this._nearbyBeyondBorderLastCameraDir.copy(camDir);\n    }\n\n    _updateNearbyBeyondBorderLabelMotion() {\n        for (const label of this._nearbyBeyondBorderLabels) {\n            if (!label?.localDir || !label?.targetDir) continue;\n            const angularDistance = Math.acos(THREE.MathUtils.clamp(label.localDir.dot(label.targetDir), -1, 1));\n            if (angularDistance * this.planetRadius > 50_000) {\n                label.localDir.copy(label.targetDir);\n            } else {\n                label.localDir.lerp(label.targetDir, 0.18).normalize();\n            }\n        }\n    }\n\n    _getLabelHorizonThreshold(horizon) {\n        const base = THREE.MathUtils.clamp(horizon, -1, 1);\n        const insetRatio = this._renderMode === 'surface' ? 0.035 : 0.08;\n        return Math.min(0.9999999, base + (1 - base) * insetRatio);\n    }\n\n    _getAuroraDisplacementForPosition(position) {\n        if (!this._auroraEnabled || !position) return 0;\n        const material = this._lineMaterial || this._line?.material;\n        const uniforms = this._getWallUniforms(material);\n        const amplitude = uniforms?.uAuroraAmplitude?.value ?? DEFAULT_AURORA_AMPLITUDE;\n        const frequency = uniforms?.uAuroraFrequency?.value ?? DEFAULT_AURORA_FREQUENCY;\n        const speed = uniforms?.uAuroraSpeed?.value ?? DEFAULT_AURORA_SPEED;\n        const fract = (value) => value - Math.floor(value);\n        let px = fract(position.x * 0.001 * 443.897);\n        let py = fract(position.y * 0.001 * 441.423);\n        let pz = fract(position.z * 0.001 * 437.195);\n        const mixed = px * (py + 19.19) + py * (px + 19.19) + pz * (pz + 19.19);\n        px += mixed;\n        py += mixed;\n        pz += mixed;\n        const positionHash = fract((px + py) * pz);\n        const wave1 = Math.sin(\n            (position.x + position.y * 0.7 + position.z * 0.5) * frequency\n            + this._auroraTime * speed\n            + positionHash * 6.28\n        );\n        const wave2 = Math.sin(\n            (position.x * 0.5 + position.y + position.z * 0.8) * frequency * 1.7\n            + this._auroraTime * speed * 0.7\n            + positionHash * 3.14\n        );\n        const wave3 = Math.sin(\n            (position.x * 0.8 + position.y * 0.3 + position.z) * frequency * 2.3\n            + this._auroraTime * speed * 1.3\n        );\n        return (wave1 * 0.5 + wave2 * 0.35 + wave3 * 0.15) * amplitude;\n    }\n\n    _getBorderLabelRadius(dir) {\n        const topRadius = this._sampleSurfaceRadiusForDir(dir) + this.liftMeters;\n        const topPosition = this._tmpVec3c.copy(dir).multiplyScalar(topRadius);\n        return topRadius\n            + this._getAuroraDisplacementForPosition(topPosition)\n            + BEYOND_BORDER_LABEL_TOP_CLEARANCE_METERS;\n    }\n\n    _shouldDeferRapidLabelPresentation(camera, nowMs) {\n        if (!this._labelPerformanceContainmentEnabled) return false;\n        const cameraPosition = camera?.userData?.worldPosition || camera?.position;\n        if (!cameraPosition) return false;\n        if (!this._labelPresentationPoseValid) {\n            this._labelPresentationPoseValid = true;\n            this._labelPresentationCameraPosition.copy(cameraPosition);\n            this._labelPresentationLastRunMs = nowMs;\n            this._labelPresentationCadence.fullFrames += 1;\n            return false;\n        }\n\n        const elapsedMs = Math.max(0.01, nowMs - this._labelPresentationLastRunMs);\n        const distanceMeters = this._labelPresentationCameraPosition.distanceTo(cameraPosition);\n        const speedMps = distanceMeters * 1000 / elapsedMs;\n        const rapidMotion = speedMps >= LABEL_RAPID_MOTION_SPEED_MPS;\n        if (rapidMotion && elapsedMs < LABEL_RAPID_MOTION_INTERVAL_MS) {\n            this._labelPresentationDeferred = true;\n            this._labelPresentationCadence.rapidMotionSkippedFrames += 1;\n            return true;\n        }\n        if (this._labelPresentationDeferred && !rapidMotion) {\n            this._labelPresentationCadence.settleFrames += 1;\n        }\n        this._labelPresentationDeferred = false;\n        this._labelPresentationCameraPosition.copy(cameraPosition);\n        this._labelPresentationLastRunMs = nowMs;\n        this._labelPresentationCadence.fullFrames += 1;\n        return false;\n    }\n\n    _updateLabels(camera) {\n        const nowMs = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        if (this._shouldDeferRapidLabelPresentation(camera, nowMs)) return;\n        this._updateLabelsNow(camera);\n    }\n\n    _updateLabelsNow(camera) {\n        if (!this._labelGroup) {\n            this._clearSharedLabels();\n            return;\n        }\n\n        const camPosWorld = camera.userData?.worldPosition || camera.position;\n        if (!camPosWorld) return;\n\n        const renderer = this.sceneInitializer?.renderer;\n        const domElement = renderer?.domElement;\n        const viewportHeight = domElement?.clientHeight || 0;\n        if (!viewportHeight || viewportHeight <= 0) return;\n\n        this.group?.updateMatrixWorld?.(true);\n\n        const camPosLocal = this._tmpCamPos.copy(camPosWorld);\n        this.group?.worldToLocal?.(camPosLocal);\n\n        const camDist = camPosLocal.length();\n        if (!Number.isFinite(camDist) || camDist <= 0) return;\n\n        const camDir = this._tmpCamDir.copy(camPosLocal).normalize();\n        const camRadius = ellipsoidRadiusForLocalDir(camDir);\n        const altitude = Math.max(0, camDist - camRadius);\n        const horizon = camRadius / camDist;\n        const maxDistance = Math.max(LABEL_MAX_DISTANCE, altitude + LABEL_MAX_DISTANCE);\n        const surfaceLift = Math.max(LABEL_SURFACE_LIFT_METERS, this.liftMeters * 0.25);\n        const orbitLift = Math.max(LABEL_ORBIT_LIFT_METERS, this.liftMeters * 4);\n        const targetPixelHeight = THREE.MathUtils.clamp(\n            viewportHeight * LABEL_PIXEL_RATIO,\n            LABEL_MIN_PIXEL_HEIGHT,\n            LABEL_MAX_PIXEL_HEIGHT\n        );\n        const capAlt = Number.isFinite(this._labelScaleCapAltM)\n            ? this._labelScaleCapAltM\n            : LABEL_SCALE_CAP_ALT_METERS;\n        const releaseAlt = Number.isFinite(this._labelScaleReleaseAltM)\n            ? this._labelScaleReleaseAltM\n            : LABEL_SCALE_RELEASE_ALT_METERS;\n        const retireAlt = Number.isFinite(this._labelBorderRetireAltM)\n            ? this._labelBorderRetireAltM\n            : LABEL_BORDER_RETIRE_ALT_METERS;\n        const clampLabelScale = altitude >= capAlt && altitude < releaseAlt;\n        const retireAdmBorders = altitude >= retireAlt;\n\n        let currentRegionFeature = null;\n        let currentRegionName = null;\n        if (this._renderMode === 'surface') {\n            const camDirLocal = this._tmpVec3.copy(camPosLocal).normalize();\n            const ll = dirToLatLonLocal(camDirLocal);\n            if (Number.isFinite(ll?.latDeg) && Number.isFinite(ll?.lonDeg)) {\n                currentRegionFeature = this.getFeatureAtLatLon(ll.latDeg, ll.lonDeg);\n                currentRegionName = currentRegionFeature?.name\n                    || this._getFeatureName(currentRegionFeature?.properties)\n                    || null;\n                if (currentRegionFeature) {\n                    this._refreshNearbyBeyondBorderLabels(\n                        currentRegionFeature,\n                        ll.latDeg,\n                        ll.lonDeg,\n                        camDir\n                    );\n                    this._updateNearbyBeyondBorderLabelMotion();\n                } else {\n                    this._resetNearbyBeyondBorderLabels();\n                }\n            }\n        } else if (this._nearbyBeyondBorderLabels.length) {\n            this._resetNearbyBeyondBorderLabels();\n        }\n        const currentRegionNorm = currentRegionName ? String(currentRegionName).toLowerCase().trim() : null;\n        const horizonThreshold = this._getLabelHorizonThreshold(horizon);\n\n        const scored = [];\n        const staticCount = this._labelData.length;\n        const totalCount = staticCount + this._nearbyBeyondBorderLabels.length;\n        for (let i = 0; i < totalCount; i++) {\n            const dynamicBorder = i >= staticCount;\n            const label = dynamicBorder\n                ? this._nearbyBeyondBorderLabels[i - staticCount]\n                : this._labelData[i];\n            const dir = label.localDir;\n            if (!dir) continue;\n            const isBorderLabel = label.kind === 'border' || label.kind === 'border-beyond';\n\n            if (label.kind === 'border') {\n                if (retireAdmBorders) {\n                    const level = label.adminLevel;\n                    if (Number.isFinite(level) && level >= 1 && level <= 3) continue;\n                }\n                if (this._renderMode !== 'surface') continue;\n                const left = label.neighborInfo?.left;\n                const right = label.neighborInfo?.right;\n                if (!left || !right || !currentRegionNorm) continue;\n                const leftNorm = String(left).toLowerCase().trim();\n                const rightNorm = String(right).toLowerCase().trim();\n                if (leftNorm !== currentRegionNorm && rightNorm !== currentRegionNorm) continue;\n                const beyond = leftNorm === currentRegionNorm ? right : left;\n                label.currentRegion = currentRegionName;\n                label.beyondRegion = beyond;\n                label.displayLines = [beyond, 'BEYOND THIS BORDER'];\n            } else if (label.kind !== 'border-beyond' && label.displayLines) {\n                label.displayLines = null;\n            }\n\n            const radius = this._renderMode === 'surface' && isBorderLabel\n                ? this._getBorderLabelRadius(dir)\n                : ellipsoidRadiusForLocalDir(dir)\n                    + (this._renderMode === 'orbit' ? orbitLift : surfaceLift);\n            const dist = this._tmpVec3.copy(dir).multiplyScalar(radius).distanceTo(camPosLocal);\n            const itemMaxDistance = Number.isFinite(label.maxDistance)\n                ? Math.min(maxDistance, label.maxDistance)\n                : maxDistance;\n            if (!Number.isFinite(dist) || dist > itemMaxDistance || dist <= 1e-3) continue;\n\n            const viewDot = dir.dot(camDir);\n            if (viewDot < horizonThreshold) continue;\n\n            scored.push({\n                index: dynamicBorder ? label.key : i,\n                label,\n                dist,\n                viewDot,\n                radius,\n                maxDistance: itemMaxDistance,\n                isBorderLabel,\n            });\n        }\n\n        scored.sort((a, b) => {\n            const priorityDiff = (b.label?.priority || 0) - (a.label?.priority || 0);\n            if (priorityDiff !== 0) return priorityDiff;\n            return a.dist - b.dist;\n        });\n\n        const visible = scored.slice(0, LABEL_MAX_VISIBLE);\n        const visibleIndices = new Set(visible.map(v => v.index));\n        const sharedLabelsAvailable = !!this._ensureSharedLabelSystem();\n\n        for (const [idx, record] of this._labelHandles) {\n            if (!visibleIndices.has(idx)) {\n                this._disposeSharedLabelRecord(record);\n                this._labelHandles.delete(idx);\n            }\n        }\n\n        const position = this._tmpVec3d;\n        for (const item of visible) {\n            position.copy(item.label.localDir).multiplyScalar(item.radius);\n\n            const fadeStart = item.maxDistance * 0.7;\n            const fadeDist = Math.max(1, item.maxDistance - fadeStart);\n            const distFade = item.dist > fadeStart\n                ? 1 - ((item.dist - fadeStart) / fadeDist)\n                : 1;\n\n            const closeStart = LABEL_MIN_DISTANCE * 2;\n            const closeFade = !item.isBorderLabel && item.dist < closeStart\n                ? item.dist / closeStart\n                : 1;\n\n            const horizonFadeRange = Math.max(1e-6, (1 - horizonThreshold) * 0.65);\n            const horizonFade = THREE.MathUtils.clamp(\n                (item.viewDot - horizonThreshold) / horizonFadeRange,\n                0,\n                1\n            );\n            const opacity = Math.max(0, Math.min(1, this._applyHoverOpacity(\n                item.label,\n                Math.min(distFade, closeFade, horizonFade)\n            )));\n            if (opacity <= 0.01) {\n                const record = this._labelHandles.get(item.index);\n                if (record) {\n                    this._disposeSharedLabelRecord(record);\n                    this._labelHandles.delete(item.index);\n                }\n                continue;\n            }\n            if (sharedLabelsAvailable) {\n                this._upsertSharedLabel(item.index, item.label, position, {\n                    maxDistance: item.maxDistance,\n                    opacity,\n                });\n            }\n        }\n\n        for (const [idx, sprite] of this._labelSprites) {\n            if (!visibleIndices.has(idx)) {\n                this._recycleLabelSprite(sprite);\n                this._labelSprites.delete(idx);\n            }\n        }\n\n        if (sharedLabelsAvailable) {\n            for (const sprite of this._labelSprites.values()) {\n                this._recycleLabelSprite(sprite);\n            }\n            this._labelSprites.clear();\n            return;\n        }\n\n        for (const item of visible) {\n            let sprite = this._labelSprites.get(item.index);\n            if (!sprite) {\n                sprite = this._acquireLabelSprite(item.label);\n                if (!sprite) continue;\n                this._labelSprites.set(item.index, sprite);\n            } else {\n                const entry = this._getLabelTexture(item.label);\n                if (entry && sprite.userData.labelKey !== entry.key) {\n                    sprite.material.map = entry.texture;\n                    sprite.material.needsUpdate = true;\n                    sprite.userData.aspect = entry.aspect;\n                    sprite.userData.labelKey = entry.key;\n                }\n            }\n\n            sprite.position.copy(this._tmpVec3.copy(item.label.localDir).multiplyScalar(item.radius));\n            sprite.userData.labelRef = item.label;\n\n            const unitsPerPixel = this._getWorldUnitsPerPixel(camera, item.dist, viewportHeight);\n            const scaleMul = Number.isFinite(item.label?.scaleMul) ? item.label.scaleMul : 1;\n            let scale = unitsPerPixel * targetPixelHeight * scaleMul;\n            if (clampLabelScale && Number.isFinite(altitude) && altitude > 0) {\n                const distScale = (camRadius + capAlt) / (camRadius + altitude);\n                const capUnits = unitsPerPixel * THREE.MathUtils.clamp(distScale, 0, 1);\n                const capScale = capUnits * targetPixelHeight * scaleMul;\n                if (Number.isFinite(capScale)) {\n                    scale = Math.min(scale, capScale);\n                }\n            }\n            if (!Number.isFinite(scale) || scale <= 0) {\n                scale = Number.isFinite(item.label?.baseScale)\n                    ? item.label.baseScale\n                    : (this.planetRadius * LABEL_BASE_SCALE);\n            }\n            const aspect = sprite.userData.aspect || 1;\n            sprite.scale.set(scale * aspect, scale, 1);\n\n            const fadeStart = item.maxDistance * 0.7;\n            const fadeDist = Math.max(1, item.maxDistance - fadeStart);\n            const distFade = item.dist > fadeStart\n                ? 1 - ((item.dist - fadeStart) / fadeDist)\n                : 1;\n\n            const closeStart = LABEL_MIN_DISTANCE * 2;\n            const closeFade = !item.isBorderLabel && item.dist < closeStart\n                ? item.dist / closeStart\n                : 1;\n\n            const horizonFadeRange = Math.max(1e-6, (1 - horizonThreshold) * 0.65);\n            const horizonFade = THREE.MathUtils.clamp(\n                (item.viewDot - horizonThreshold) / horizonFadeRange,\n                0,\n                1\n            );\n            const opacity = this._applyHoverOpacity(item.label, Math.min(distFade, closeFade, horizonFade));\n            sprite.material.opacity = Math.max(0, Math.min(1, opacity));\n            sprite.visible = sprite.material.opacity > 0.01;\n        }\n    }\n\n    _getWorldUnitsPerPixel(camera, distance, viewportHeight) {\n        if (!Number.isFinite(distance) || distance <= 0 || !viewportHeight) return 0;\n        if (camera?.isOrthographicCamera) {\n            const worldHeight = Math.abs(camera.top - camera.bottom);\n            return worldHeight / viewportHeight;\n        }\n        const fov = THREE.MathUtils.degToRad(camera?.fov || 60);\n        return (2 * distance * Math.tan(fov * 0.5)) / viewportHeight;\n    }\n\n    getCountryAtLatLon(lat, lon) {\n        const feature = this.getFeatureAtLatLon(lat, lon);\n        return feature?.name || null;\n    }\n\n    getFeatureAtLatLon(lat, lon) {\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n        if (!this._featureIndex || !this._featureIndex.length) {\n            if (!this._loaded && !this._loadPromise) {\n                this.load();\n            }\n            return null;\n        }\n        const lonWrapped = this._wrapLon180(lon);\n        for (const feature of this._featureIndex) {\n            for (const polygon of feature.polygons) {\n                const testLon = polygon.wrap && lonWrapped < 0 ? lonWrapped + 360 : lonWrapped;\n                if (testLon < polygon.bbox.minLon || testLon > polygon.bbox.maxLon) continue;\n                if (lat < polygon.bbox.minLat || lat > polygon.bbox.maxLat) continue;\n                if (!this._pointInRing(testLon, lat, polygon.rings[0])) continue;\n                let inHole = false;\n                for (let i = 1; i < polygon.rings.length; i++) {\n                    if (this._pointInRing(testLon, lat, polygon.rings[i])) {\n                        inHole = true;\n                        break;\n                    }\n                }\n                if (!inHole) {\n                    return feature;\n                }\n            }\n        }\n        return null;\n    }\n\n    _pushGeometryPositions(geometry, positions, colors, alphas, color, linePositions, lineColors = null) {\n        if (!geometry) return;\n        const type = geometry.type;\n        const coords = geometry.coordinates;\n\n        if (type === 'Polygon') {\n            this._pushPolygon(coords, positions, colors, alphas, color, linePositions, lineColors);\n        } else if (type === 'MultiPolygon') {\n            for (const poly of coords || []) {\n                this._pushPolygon(poly, positions, colors, alphas, color, linePositions, lineColors);\n            }\n        } else if (type === 'LineString') {\n            this._pushLine(coords, positions, colors, alphas, color, linePositions, false, lineColors);\n        } else if (type === 'MultiLineString') {\n            for (const line of coords || []) {\n                this._pushLine(line, positions, colors, alphas, color, linePositions, false, lineColors);\n            }\n        } else if (type === 'GeometryCollection') {\n            for (const geom of geometry.geometries || []) {\n                this._pushGeometryPositions(geom, positions, colors, alphas, color, linePositions, lineColors);\n            }\n        }\n    }\n\n    _pushPolygon(rings, positions, colors, alphas, color, linePositions, lineColors = null) {\n        if (!Array.isArray(rings)) return;\n        for (const ring of rings) {\n            this._pushLine(ring, positions, colors, alphas, color, linePositions, true, lineColors);\n        }\n    }\n\n    _pushLine(coords, positions, colors, alphas, color, linePositions, close, lineColors = null) {\n        if (!Array.isArray(coords) || coords.length < 2) return;\n        const count = coords.length;\n        const lastIndex = close ? count : count - 1;\n        // Spire wall radii are now PER-VERTEX rather than constants:\n        //   top    = sampledSurface + liftMeters       (extends above terrain)\n        //   bottom = sampledSurface - wallDepthMeters - SAFETY_DEPTH_M\n        //                                              (buried below terrain)\n        // This guarantees the spire base sits below the photoreal surface\n        // even on tall mountains, and the lit top stays visible above the\n        // surface even in deep ocean trenches. SAFETY_DEPTH_M absorbs LOD\n        // variance — a finer LOD swap revealing higher elevation at the\n        // same coord won't surface the buried base.\n        const orbitLift = this.liftMeters;\n        const topAlpha = 0;\n        const bottomAlpha = 1;\n        const wallDepth = this.wallDepthMeters + SAFETY_DEPTH_M;\n        const pushVertex = (dir, radius, alpha) => {\n            positions.push(dir.x * radius, dir.y * radius, dir.z * radius);\n            colors.push(color.r, color.g, color.b);\n            alphas.push(alpha);\n        };\n        for (let i = 0; i < lastIndex; i++) {\n            const a = coords[i];\n            const b = coords[(i + 1) % count];\n            const dirA = this._coordToDir(a, this._tmpLineDirA);\n            const dirB = this._coordToDir(b, this._tmpLineDirB);\n            if (!dirA || !dirB) continue;\n            if (dirA.dot(dirB) > 0.999999999999) continue;\n            const sampleA = this._sampleSurfaceRadiusForDir(dirA);\n            const sampleB = this._sampleSurfaceRadiusForDir(dirB);\n            const topRadiusA = sampleA + this.liftMeters;\n            const topRadiusB = sampleB + this.liftMeters;\n            const bottomRadiusA = Math.max(0, sampleA - wallDepth);\n            const bottomRadiusB = Math.max(0, sampleB - wallDepth);\n\n            // Write components directly. The old version allocated four\n            // Vector3s per edge (top/bottom × endpoints), which turned a\n            // routine boundary rebuild into hundreds of MB of short-lived\n            // garbage on street-level navigation.\n            pushVertex(dirA, topRadiusA, topAlpha);\n            pushVertex(dirB, topRadiusB, topAlpha);\n            pushVertex(dirB, bottomRadiusB, bottomAlpha);\n            pushVertex(dirA, topRadiusA, topAlpha);\n            pushVertex(dirB, bottomRadiusB, bottomAlpha);\n            pushVertex(dirA, bottomRadiusA, bottomAlpha);\n\n            if (linePositions) {\n                // The orbit-only ribbon is rooted at the sampled surface. Its\n                // shader applies an orbit-safe lift without rebuilding this\n                // global geometry. Surface mode renders only the spire wall.\n                const orbitRadiusA = topRadiusA - orbitLift;\n                const orbitRadiusB = topRadiusB - orbitLift;\n                linePositions.push(\n                    dirA.x * orbitRadiusA, dirA.y * orbitRadiusA, dirA.z * orbitRadiusA,\n                    dirB.x * orbitRadiusB, dirB.y * orbitRadiusB, dirB.z * orbitRadiusB\n                );\n                lineColors?.push?.(\n                    color.r, color.g, color.b,\n                    color.r, color.g, color.b,\n                );\n            }\n        }\n    }\n\n    _buildOrbitRibbonArrays(linePositions, lineColors) {\n        const positions = [];\n        const otherPositions = [];\n        const lineSides = [];\n        const colors = [];\n        const a = new THREE.Vector3();\n        const b = new THREE.Vector3();\n        const pushVertex = (point, other, side, colorOffset) => {\n            positions.push(point.x, point.y, point.z);\n            otherPositions.push(other.x, other.y, other.z);\n            lineSides.push(side);\n            colors.push(\n                lineColors[colorOffset] ?? 1,\n                lineColors[colorOffset + 1] ?? 1,\n                lineColors[colorOffset + 2] ?? 1,\n            );\n        };\n        for (let offset = 0; offset + 5 < linePositions.length; offset += 6) {\n            a.set(linePositions[offset], linePositions[offset + 1], linePositions[offset + 2]);\n            b.set(linePositions[offset + 3], linePositions[offset + 4], linePositions[offset + 5]);\n            const radiusA = a.length();\n            const radiusB = b.length();\n            if (!(radiusA > 0) || !(radiusB > 0) || a.distanceToSquared(b) < 1e-8) continue;\n            const colorOffset = offset;\n            // The B endpoint uses the opposite side sign because its local\n            // segment direction is B -> A. This keeps both ends of the quad\n            // on the same screen-space side without CPU projection work.\n            pushVertex(a, b, 1, colorOffset);\n            pushVertex(b, a, -1, colorOffset + 3);\n            pushVertex(b, a, 1, colorOffset + 3);\n            pushVertex(a, b, 1, colorOffset);\n            pushVertex(b, a, 1, colorOffset + 3);\n            pushVertex(a, b, -1, colorOffset);\n        }\n        return { positions, otherPositions, lineSides, colors };\n    }\n\n    _coordToDir(coord, target = null) {\n        if (!Array.isArray(coord) || coord.length < 2) return null;\n        const lon = Number(coord[0]);\n        const lat = Number(coord[1]);\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n        return latLonToLocalDir(lat, lon, target);\n    }\n\n    /**\n     * Late-bind a SurfaceController so spire walls can sample the\n     * photoreal surface. PlanetScene constructs GeoJsonLayer before\n     * SurfaceController, so this comes in via a setter rather than the\n     * constructor. Idempotent — calling again replaces the sampler.\n     */\n    setSurfaceController(surfaceController) {\n        this.surfaceController = surfaceController || null;\n        // Invalidate cached samples — a different controller may have\n        // a different photoreal LOD floor.\n        this._surfaceSampleCache?.clear?.();\n        // Rebuild geometry now that we have a surface sampler\n        this._rebuildGeometry();\n    }\n\n    _clearSurfaceSampleCache() {\n        this._surfaceSampleCache?.clear?.();\n    }\n\n    /**\n     * Late-bind a TriTree for elevation mesh fallback sampling.\n     * Same pattern as RouteRibbonRenderer.setTriTree.\n     */\n    setTriTree(tt) {\n        this.triTree = tt || null;\n        this._clearSurfaceSampleCache();\n    }\n\n    /**\n     * Sample the photoreal surface radius at the direction `dir`. Falls\n     * back to the WGS84 ellipsoid radius when no controller is wired\n     * yet or no photoreal hit is available. mutateCache:false so we do\n     * NOT bump the camera's terrain-clamp state (which is the SAME\n     * sampler, but a different read mode).\n     */\n    _sampleSurfaceRadiusForDir(dir) {\n        if (!dir) return this.planetRadius;\n        // Cache by ~1km direction quantization (3 decimals on a unit sphere\n        // is ≈6 km at the equator). Use a packed numeric key: formatting three\n        // strings per boundary vertex was a major allocation source.\n        const q = SURFACE_SAMPLE_QUANTIZATION;\n        const width = SURFACE_SAMPLE_QUANTIZATION_WIDTH;\n        const qx = Math.max(-q, Math.min(q, Math.round(dir.x * q))) + q;\n        const qy = Math.max(-q, Math.min(q, Math.round(dir.y * q))) + q;\n        const qz = Math.max(-q, Math.min(q, Math.round(dir.z * q))) + q;\n        const key = (qx * width + qy) * width + qz;\n        const cached = this._surfaceSampleCache.get(key);\n        if (Number.isFinite(cached)) return cached;\n\n        // Convert local-space direction to world-space for raycasting\n        // against photoreal tiles. GeoJsonLayer's group sits under\n        // triTree.group which has planet rotation — local dir is not\n        // the same as world dir.\n        this._tmpWorldDir.copy(dir);\n        if (this.group?.parent) {\n            const quat = this.group.parent.getWorldQuaternion(this._tmpGroupQuat);\n            if (quat) this._tmpWorldDir.applyQuaternion(quat);\n        }\n        this._tmpWorldDir.normalize();\n\n        let r;\n        // Prefer surfaceController — raycasts against photoreal tile geometry\n        if (this.surfaceController?.sampleTerrainRadiusForDir) {\n            r = this.surfaceController.sampleTerrainRadiusForDir(this._tmpWorldDir, {\n                mutateCache: false,\n                skipWorldMatrixUpdate: true,\n                // Photoreal mode is exclusive. Border draping must not wake or\n                // traverse hidden TriTree geometry underneath it.\n                allowTriTreeFallback: false,\n            });\n        }\n        // Fallback: triTree elevation mesh raycast\n        if (!Number.isFinite(r) || r <= 0) {\n            if (this.triTree?.sampleTerrainRadiusForDir) {\n                r = this.triTree.sampleTerrainRadiusForDir(this._tmpWorldDir);\n            }\n        }\n        // Final fallback: WGS84 ellipsoid\n        if (!Number.isFinite(r) || r <= 0) {\n            r = ellipsoidRadiusForLocalDir(dir);\n        }\n        const cache = this._surfaceSampleCache;\n        const maxEntries = Math.max(1, this._surfaceSampleCacheMaxEntries || MAX_SURFACE_SAMPLE_CACHE_ENTRIES);\n        if (cache.size >= maxEntries) {\n            // Map iteration is insertion ordered, so deleting the first key\n            // gives a predictable bounded FIFO cache without a per-entry LRU\n            // object graph.\n            const oldest = cache.keys().next().value;\n            if (oldest !== undefined) cache.delete(oldest);\n        }\n        cache.set(key, r);\n        return r;\n    }\n\n    /**\n     * Rebuild wall/line geometry from stored features. Called after\n     * surfaceController or triTree is bound (timing edge case) and\n     * periodically during update() to re-drape as photoreal tiles\n     * finish loading at finer LODs.\n     */\n    _rebuildGeometry() {\n        if (!this._lastFeatures?.length) return;\n        return this._setRenderGeometryFromFeatures(this._lastFeatures).catch(error => {\n            if (error.name !== 'AbortError') console.warn('[GeoJsonLayer] Boundary rebuild failed', error);\n        });\n    }\n\n    _cancelBoundaryWork() {\n        this._boundaryAbort?.abort();\n        this._geometryAbort?.abort();\n        this._loadSeq += 1;\n        this._loadPromise = null;\n    }\n\n    _captureBoundaryView(target = null) {\n        const camera = this._boundaryCamera || this.sceneInitializer?.camera;\n        const position = camera?.userData?.worldPosition || camera?.position;\n        if (!position || !this.group) return null;\n        target ||= { dir: new THREE.Vector3(), cap: 0 };\n        const local = this.group.worldToLocal(target.dir.copy(position));\n        const radius = local.length();\n        if (!(radius > 0)) return null;\n        const dir = local.multiplyScalar(1 / radius);\n        target.cap = Math.acos(THREE.MathUtils.clamp(ellipsoidRadiusForLocalDir(dir) / radius, -1, 1));\n        return target;\n    }\n\n    _boundarySegmentMayBeVisible(a, b, view) {\n        if (!view) return true;\n        const dirA = this._coordToDir(a, this._tmpLineDirA);\n        const dirB = this._coordToDir(b, this._tmpLineDirB);\n        if (!dirA || !dirB) return false;\n        // Conservative great-circle cap encloses both endpoints and the chord.\n        // Five extra degrees prefetch beyond the shader's existing horizon.\n        // No visible edge is simplified, clipped, or replaced by lower detail.\n        const halfAngle = Math.acos(THREE.MathUtils.clamp(dirA.dot(dirB), -1, 1)) / 2;\n        const center = this._tmpVec3c.copy(dirA).add(dirB);\n        if (center.lengthSq() < 1e-12) return true;\n        center.normalize();\n        return center.dot(view.dir) >= Math.cos(Math.min(Math.PI, view.cap + halfAngle + THREE.MathUtils.degToRad(5)));\n    }\n\n    async _prepareFeatures(features, signal) {\n        const budget = { points: 0, rings: 0 };\n        let count = 0;\n        for (const feature of features) {\n            checkBoundarySignal(signal);\n            if (++count > MAX_BOUNDARY_FEATURES) throw new RangeError('Boundary feature limit exceeded');\n            if (feature?.geometry) await prepareBoundaryFeature(this, feature, budget, signal);\n            if (count % 32 === 0) await yieldToEventLoop('background');\n        }\n    }\n\n    async _setRenderGeometryFromFeatures(features, { signal, prepared = false } = {}) {\n        this._geometryAbort?.abort();\n        const controller = new AbortController();\n        this._geometryAbort = controller;\n        const abort = () => controller.abort();\n        signal?.addEventListener('abort', abort, { once: true });\n        if (signal?.aborted) controller.abort();\n        const workSignal = controller.signal;\n        // The detached owner has independent geometry/material bookkeeping.\n        // No live arrays are mutated until the generation commits.\n        const stage = Object.assign(Object.create(this), {\n            group: new THREE.Group(), _lineChunks: [], _orbitLineChunks: [],\n            _line: null, _orbitLine: null, _lineMaterial: null, _orbitLineMaterial: null,\n            _wallMaterialGeneration: 0,\n            _boundaryStage: null,\n        });\n        this._boundaryStage = stage;\n        let committed = false;\n        const view = this._captureBoundaryView();\n        let culledSegments = 0;\n        try {\n            if (!prepared) await this._prepareFeatures(features || [], workSignal);\n            checkBoundarySignal(workSignal);\n            this.surfaceController?.prepareTerrainSamplingBatch?.();\n            const owner = this;\n            let chunk = null, segments = 0;\n            const makeChunk = () => ({ positions: [], colors: [], alphas: [], linePositions: [], lineColors: [],\n                wallFeatureRanges: [], orbitFeatureRanges: [],\n            });\n            const flush = () => {\n                if (!chunk?.positions.length) { chunk = null; return; }\n                stage._appendRenderChunk(chunk);\n                chunk = null;\n            };\n            await runBoundarySteps((function* () {\n                for (const feature of features || []) {\n                    if (!feature?.geometry) { yield; continue; }\n                    const color = owner._resolvedFeatureColor(feature);\n                    const wallColor = new THREE.Color(color);\n                    let rings = 0;\n                    for (const line of boundaryLines(feature.geometry)) {\n                        if (++rings > MAX_BOUNDARY_RINGS) throw new RangeError('Boundary ring limit exceeded');\n                        const coords = line.coords;\n                        const count = line.close ? coords.length : coords.length - 1;\n                        for (let i = 0; i < count; i++) {\n                            if (++segments > MAX_BOUNDARY_POINTS) throw new RangeError('Boundary segment limit exceeded');\n                            const a = coords[i], b = coords[(i + 1) % coords.length];\n                            if (!owner._boundarySegmentMayBeVisible(a, b, view)) { culledSegments++; yield; continue; }\n                            if (!chunk) chunk = makeChunk();\n                            let wallRange = chunk.wallFeatureRanges.at(-1);\n                            let orbitRange = chunk.orbitFeatureRanges.at(-1);\n                            if (wallRange?.feature !== feature) {\n                                wallRange = { feature, start: chunk.colors.length / 3, count: 0, lastColor: color };\n                                orbitRange = { feature, start: chunk.lineColors.length, count: 0, lastColor: color };\n                                chunk.wallFeatureRanges.push(wallRange);\n                                chunk.orbitFeatureRanges.push(orbitRange);\n                            }\n                            owner._pushLine([a, b], chunk.positions, chunk.colors,\n                                chunk.alphas, wallColor, chunk.linePositions, false, chunk.lineColors);\n                            wallRange.count = chunk.colors.length / 3 - wallRange.start;\n                            orbitRange.count = chunk.lineColors.length - orbitRange.start;\n                            // At most 512 edges / 3,072 vertices per mesh, including\n                            // a single enormous ring. Expanded JS arrays live only\n                            // until this small chunk becomes typed attributes.\n                            if (chunk.positions.length >= 512 * 18) flush();\n                            yield;\n                        }\n                        yield;\n                    }\n                    yield;\n                }\n                flush(); yield;\n            })(), workSignal);\n            checkBoundarySignal(workSignal);\n            // Shader readiness precedes paced attachment so a late compile\n            // completion cannot reveal/upload hundreds of wall chunks at once.\n            await waitBoundaryTask(stage._scheduleResponsiveWallMaterialPreparation(stage._lineMaterial), workSignal);\n            checkBoundarySignal(workSignal);\n            stage._applyModeVisibility();\n            // Attach at most one geographic chunk per rendered frame. The old\n            // boundary remains present throughout attachment; a cancelled stage\n            // is removed as a unit. No second render loop or renderer.render().\n            const meshes = [...stage._lineChunks, ...stage._orbitLineChunks];\n            stage.group.clear();\n            this.group.add(stage.group);\n            const first = this._renderMode === 'surface' ? stage._lineChunks : stage._orbitLineChunks;\n            const second = this._renderMode === 'surface' ? stage._orbitLineChunks : stage._lineChunks;\n            for (const entries of [first, second]) {\n                for (const entry of entries) {\n                    checkBoundarySignal(workSignal);\n                    stage._applyModeVisibility();\n                    stage.group.add(entry.mesh);\n                    if (typeof window !== 'undefined') await waitBoundaryTask(nextFrame(), workSignal);\n                    else await yieldToEventLoop('background');\n                }\n            }\n            checkBoundarySignal(workSignal);\n            this._clearLine();\n            for (const { mesh } of meshes) this.group.add(mesh);\n            stage.group.removeFromParent();\n            for (const key of ['_lineChunks', '_orbitLineChunks', '_line', '_orbitLine', '_lineMaterial', '_orbitLineMaterial']) this[key] = stage[key];\n            committed = true;\n            this._geometryView = view;\n            this._geometryStats = { segments, culledSegments, residentSegments: segments - culledSegments, chunks: this._lineChunks.length };\n            this._applyModeVisibility();\n        } finally {\n            signal?.removeEventListener('abort', abort);\n            if (!committed) stage._clearLine();\n            stage.group.removeFromParent();\n            if (this._boundaryStage === stage) this._boundaryStage = null;\n            if (this._geometryAbort === controller) this._geometryAbort = null;\n        }\n    }\n\n    _getGeometryChunkKey(feature) {\n        const anchor = this._resolveLabelLatLon(feature);\n        if (!anchor || !Number.isFinite(anchor.lat) || !Number.isFinite(anchor.lon)) return 'fallback';\n        const latIndex = THREE.MathUtils.clamp(\n            Math.floor(((anchor.lat + 90) / 180) * GEOJSON_CHUNK_LAT_BANDS),\n            0,\n            GEOJSON_CHUNK_LAT_BANDS - 1\n        );\n        const lonIndex = THREE.MathUtils.clamp(\n            Math.floor(((this._wrapLon180(anchor.lon) + 180) / 360) * GEOJSON_CHUNK_LON_BANDS),\n            0,\n            GEOJSON_CHUNK_LON_BANDS - 1\n        );\n        return `${latIndex}:${lonIndex}`;\n    }\n\n    _appendRenderChunk(chunk) {\n        let wallMaterial = this._lineMaterial;\n        let orbitLineMaterial = this._orbitLineMaterial;\n        let horizonData = null;\n        if (chunk.positions.length) {\n            const geometry = new THREE.BufferGeometry();\n            geometry.setAttribute('position', new THREE.Float32BufferAttribute(chunk.positions, 3));\n            geometry.setAttribute('color', new THREE.Float32BufferAttribute(chunk.colors, 3));\n            geometry.setAttribute('alpha', new THREE.Float32BufferAttribute(chunk.alphas, 1));\n            geometry.computeVertexNormals();\n            geometry.computeBoundingSphere();\n            horizonData = this._getChunkHorizonData(geometry);\n            if (!wallMaterial) wallMaterial = this._buildResponsiveWallMaterial();\n            const mesh = new THREE.Mesh(geometry, wallMaterial);\n            mesh.renderOrder = 4;\n            mesh.frustumCulled = false;\n            mesh.userData.geoBorderShaderReady = false;\n            this.group.add(mesh);\n            const entry = {\n                mesh,\n                featureColorRanges: chunk.wallFeatureRanges,\n                ...horizonData,\n            };\n            this._lineChunks.push(entry);\n            if (!this._line) this._line = mesh;\n        }\n        if (chunk.linePositions.length) {\n            const ribbon = this._buildOrbitRibbonArrays(chunk.linePositions, chunk.lineColors);\n            const geometry = new THREE.BufferGeometry();\n            geometry.setAttribute('position', new THREE.Float32BufferAttribute(ribbon.positions, 3));\n            geometry.setAttribute('otherPosition', new THREE.Float32BufferAttribute(ribbon.otherPositions, 3));\n            geometry.setAttribute('lineSide', new THREE.Float32BufferAttribute(ribbon.lineSides, 1));\n            geometry.setAttribute('color', new THREE.Float32BufferAttribute(ribbon.colors, 3));\n            geometry.computeBoundingSphere();\n            const lineHorizonData = horizonData || this._getChunkHorizonData(geometry);\n            if (!orbitLineMaterial) orbitLineMaterial = this._buildOrbitLineMaterial();\n            const line = new THREE.Mesh(geometry, orbitLineMaterial);\n            line.name = 'Thick orbital administrative border ribbons';\n            line.layers.set(SCREEN_SPACE_OUTLINE_POST_COMPOSITE_LAYER);\n            line.renderOrder = 6;\n            line.frustumCulled = false;\n            this.group.add(line);\n            const entry = {\n                mesh: line,\n                featureColorRanges: chunk.orbitFeatureRanges,\n                ...lineHorizonData,\n            };\n            this._orbitLineChunks.push(entry);\n            if (!this._orbitLine) this._orbitLine = line;\n        }\n        this._lineMaterial = wallMaterial;\n        this._orbitLineMaterial = orbitLineMaterial;\n    }\n\n    _getChunkHorizonData(geometry) {\n        const sphere = geometry?.boundingSphere;\n        const center = sphere?.center;\n        const centerLength = center?.length?.() || 0;\n        if (!center || !Number.isFinite(centerLength) || centerLength <= 1) {\n            return { centerDir: null, angularRadius: Math.PI };\n        }\n        const radiusRatio = THREE.MathUtils.clamp((sphere.radius || 0) / centerLength, 0, 1);\n        return {\n            centerDir: center.clone().multiplyScalar(1 / centerLength),\n            angularRadius: Math.min(Math.PI, Math.asin(radiusRatio) + GEOJSON_HORIZON_CHUNK_MARGIN_RAD)\n        };\n    }\n\n    _buildFeatureIndex(geojson) {\n        const entries = [];\n        if (geojson && Array.isArray(geojson.features)) {\n            for (const feature of geojson.features) {\n                this._pushFeatureEntry(feature, entries);\n            }\n        } else if (geojson && geojson.type && geojson.coordinates) {\n            this._pushFeatureEntry({ geometry: geojson, properties: geojson.properties || {} }, entries);\n        }\n        return entries;\n    }\n\n    _pushFeatureEntry(feature, entries) {\n        if (!feature || !feature.geometry) return;\n        const polygons = this._extractPolygons(feature.geometry);\n        if (!polygons.length) return;\n        const props = feature.properties || {};\n        entries.push({\n            name: this._getFeatureName(props),\n            properties: props,\n            polygons\n        });\n    }\n\n\n    _getFeatureName(props) {\n        if (!props) return null;\n        return props.name ||\n            props.admin ||\n            props.shapeName ||\n            props.name_long ||\n            props.name_en ||\n            props.sovereignt ||\n            props.brk_name ||\n            props.NAME_0 ||\n            props.NAME_1 ||\n            props.NAME_2 ||\n            props.NAME_3 ||\n            props.NAME_4 ||\n            props.NAME ||\n            null;\n    }\n\n    _getNeighborInfo(props) {\n        if (!props) return null;\n        // Try to extract neighbor/boundary information from common GeoJSON properties\n        const neighbors = [];\n        // Check for explicit neighbor properties\n        if (props.neighbors && Array.isArray(props.neighbors)) {\n            neighbors.push(...props.neighbors);\n        }\n        // Check for boundary type info\n        if (props.adm0_left && props.adm0_right) {\n            return { left: props.adm0_left, right: props.adm0_right };\n        }\n        if (props.left_name && props.right_name) {\n            return { left: props.left_name, right: props.right_name };\n        }\n        // For country polygons, the \"neighbor\" is anything outside\n        return null;\n    }\n\n    _buildLabelData(geojson) {\n        const labels = [];\n        if (!geojson) return labels;\n\n        const features = Array.isArray(geojson.features) ? geojson.features :\n            (geojson.type && geojson.coordinates ? [{ geometry: geojson, properties: geojson.properties || {} }] : []);\n\n        for (const feature of features) {\n            if (!feature || !feature.geometry) continue;\n            const props = feature.properties || {};\n            const name = this._getFeatureName(props);\n            if (!name) continue;\n            const anchor = this._resolveLabelLatLon(feature);\n            if (!anchor) continue;\n\n            // Administrative areas belong at their polygon's stable interior\n            // anchor. The former path computed that anchor above, then replaced\n            // it with the nearest outer-ring point when deriving localDir,\n            // which visibly stranded every district label on its boundary.\n            // Dynamic \"beyond this border\" labels have a separate edge-anchor\n            // path and are unaffected.\n            const dir = latLonToLocalDir(anchor.lat, anchor.lon);\n            if (!dir) continue;\n\n            const iso = this._getIsoCode(props);\n            const parsedAdminLevel = this._parseAdminLevel(props);\n            // Natural Earth country features include a generic `level` field\n            // whose value is not an ADM depth.  Only explicit admin metadata\n            // determines hierarchy; an ISO-only polygon is an ADM0 country.\n            const isCountry = parsedAdminLevel === 0 || (!Number.isFinite(parsedAdminLevel) && !!iso);\n            const adminLevel = isCountry && !Number.isFinite(parsedAdminLevel)\n                ? 0\n                : parsedAdminLevel;\n            const adminLabel = Number.isFinite(adminLevel) && adminLevel > 0 ? `ADM${adminLevel}` : null;\n            // More specific administrative labels are placed first.  This is\n            // deliberately the inverse of political hierarchy: a country\n            // label yields screen real estate to the state/county it contains.\n            const priority = Number.isFinite(adminLevel)\n                ? 100 + Math.max(0, Math.min(8, adminLevel))\n                : (isCountry ? 100 : 99);\n            const scaleMul = isCountry ? 1.25 : (adminLevel === 1 ? 1.0 : 0.85);\n            const neighborInfo = this._getNeighborInfo(props);\n            const geomType = feature.geometry?.type;\n            const isBorder = !!neighborInfo && (geomType === 'LineString' || geomType === 'MultiLineString');\n            const selectionKey = !isBorder\n                ? this._buildSceneSelectionKey({ name, iso, adminLevel, isCountry })\n                : null;\n            const selectionLabel = !isBorder\n                ? this._buildSceneSelectionLabel({ name, adminLevel, isCountry })\n                : null;\n            const polygons = !isBorder ? this._extractPolygons(feature.geometry) : [];\n            const featureRef = polygons.length\n                ? { name, properties: props, polygons }\n                : null;\n\n            labels.push({\n                name,\n                iso,\n                adminLevel,\n                adminLabel,\n                priority,\n                baseScale: this.planetRadius * LABEL_BASE_SCALE * scaleMul,\n                scaleMul,\n                kind: isBorder ? 'border' : 'feature',\n                neighborInfo,\n                selectionKey,\n                selectionLabel,\n                featureRef,\n                localDir: dir,\n                lat: anchor.lat,\n                lon: anchor.lon,\n                lineLat: anchor.lat,\n                lineLon: anchor.lon,\n                properties: props\n            });\n        }\n\n        return labels;\n    }\n\n    _buildSceneSelectionKey({ name, iso, adminLevel, isCountry }) {\n        const safeName = name ? String(name).trim() : '';\n        if (isCountry) {\n            if (iso) return `country:${String(iso).toUpperCase()}`;\n            return safeName ? `country:${safeName}` : null;\n        }\n        const level = Number.isFinite(adminLevel) ? adminLevel : 'x';\n        return safeName ? `admin:${level}:${safeName}` : null;\n    }\n\n    _buildSceneSelectionLabel({ name, adminLevel, isCountry }) {\n        const safeName = name ? String(name).trim() : '';\n        if (!safeName) return '';\n        if (isCountry) return safeName;\n        if (Number.isFinite(adminLevel)) return `${safeName} (ADM${adminLevel})`;\n        return safeName;\n    }\n\n    _buildSceneSelectionEntry(label) {\n        if (!label?.selectionKey) return null;\n        return {\n            key: label.selectionKey,\n            label: label.selectionLabel || label.name || label.selectionKey,\n            name: label.name || null,\n            iso: label.iso || null,\n            adminLevel: Number.isFinite(label.adminLevel) ? label.adminLevel : null\n        };\n    }\n\n    _parseAdminLevel(props) {\n        if (!props) return null;\n        const raw = props.admin_level ?? props.adm_level ?? props.ADMIN_LEVEL ?? props.ADM_LEVEL;\n        if (Number.isFinite(raw)) return Number(raw);\n        if (typeof raw === 'string') {\n            const direct = Number(raw);\n            if (Number.isFinite(direct)) return direct;\n            const match = raw.match(/\\d+/);\n            if (match) {\n                const parsed = Number(match[0]);\n                if (Number.isFinite(parsed)) return parsed;\n            }\n        }\n        return null;\n    }\n\n    _getIsoCode(props) {\n        if (!props) return null;\n        return props.iso_a3 || props.adm0_a3 || props.ISO_A3 || props.ISO3 || props.country_iso3 || null;\n    }\n\n\n    _clearLine() {\n        this._wallMaterialGeneration += 1;\n        const disposeMeshes = (chunks, fallback) => {\n            const meshes = chunks.length ? chunks.map((chunk) => chunk?.mesh).filter(Boolean) : (fallback ? [fallback] : []);\n            for (const mesh of meshes) {\n                mesh.geometry?.dispose?.();\n                mesh.removeFromParent();\n            }\n        };\n        disposeMeshes(this._lineChunks, this._line);\n        disposeMeshes(this._orbitLineChunks, this._orbitLine);\n        this._lineMaterial?.dispose?.();\n        this._orbitLineMaterial?.dispose?.();\n        // Legacy single meshes can exist while an old asynchronous load is\n        // being replaced; their materials are distinct from shared chunk mats.\n        if (!this._lineChunks.length && this._line?.material && this._line.material !== this._lineMaterial) {\n            this._line.material.dispose?.();\n        }\n        if (!this._orbitLineChunks.length && this._orbitLine?.material && this._orbitLine.material !== this._orbitLineMaterial) {\n            this._orbitLine.material.dispose?.();\n        }\n        this._lineChunks.length = 0;\n        this._orbitLineChunks.length = 0;\n        this._line = null;\n        this._orbitLine = null;\n        this._lineMaterial = null;\n        this._orbitLineMaterial = null;\n    }\n\n    _clearFill() {\n        if (!this._fillMesh) return;\n        this._fillMesh.geometry?.dispose?.();\n        if (this._fillMesh.material && !Array.isArray(this._fillMesh.material)) {\n            this._fillMesh.material.dispose?.();\n        }\n        this._fillMesh.removeFromParent();\n        this._fillMesh = null;\n    }\n\n    _clearOutline() {\n        if (!this._outlineMesh) return;\n        this._outlineMesh.geometry?.dispose?.();\n        if (this._outlineMesh.material && !Array.isArray(this._outlineMesh.material)) {\n            this._outlineMesh.material.dispose?.();\n        }\n        this._outlineMesh.removeFromParent();\n        this._outlineMesh = null;\n    }\n\n    _buildFillGeometry(feature) {\n        if (!feature || !feature.polygons || !feature.polygons.length) return null;\n        const positions = [];\n        const hatch = [];\n        const maxEdgeRad = THREE.MathUtils.degToRad(DEFAULT_HIGHLIGHT_SUBDIV_DEG);\n        const radius = this.planetRadius + this._getHighlightLiftMeters();\n        const invR2 = 1 / (radius * radius);\n        const invRadius = 1 / radius;\n        const state = { count: 0, limit: MAX_HIGHLIGHT_TRIANGLES };\n\n        const buildFrame = (dirs) => {\n            const center = new THREE.Vector3();\n            for (const dir of dirs) center.add(dir);\n            if (center.lengthSq() <= 1e-6) return null;\n            const up = center.normalize();\n            let east = new THREE.Vector3(0, 1, 0).cross(up);\n            if (east.lengthSq() <= 1e-6) {\n                east = new THREE.Vector3(1, 0, 0).cross(up);\n            }\n            east.normalize();\n            const north = new THREE.Vector3().crossVectors(up, east).normalize();\n            return { east, north };\n        };\n\n        const normalizeRingCoords = (ring) => {\n            if (!Array.isArray(ring) || ring.length < 3) return [];\n            const out = ring.slice();\n            const first = out[0];\n            const last = out[out.length - 1];\n            if (Array.isArray(first) && Array.isArray(last) &&\n                Math.abs(Number(first[0]) - Number(last[0])) < 1e-6 &&\n                Math.abs(Number(first[1]) - Number(last[1])) < 1e-6) {\n                out.pop();\n            }\n            return out;\n        };\n\n        const slerpDir = (a, b, t) => {\n            const dot = THREE.MathUtils.clamp(a.dot(b), -1, 1);\n            const omega = Math.acos(dot);\n            if (!Number.isFinite(omega) || omega < 1e-6) {\n                return a.clone();\n            }\n            const sinOmega = Math.sin(omega);\n            const scaleA = Math.sin((1 - t) * omega) / sinOmega;\n            const scaleB = Math.sin(t * omega) / sinOmega;\n            return a.clone().multiplyScalar(scaleA).add(b.clone().multiplyScalar(scaleB)).normalize();\n        };\n\n        const densifyDirs = (dirs, maxAngle) => {\n            if (!dirs || dirs.length < 2) return [];\n            const out = [];\n            const maxSteps = 256;\n            for (let i = 0; i < dirs.length; i++) {\n                const a = dirs[i];\n                const b = dirs[(i + 1) % dirs.length];\n                out.push(a.clone());\n                const angle = Math.acos(THREE.MathUtils.clamp(a.dot(b), -1, 1));\n                if (!Number.isFinite(angle) || angle <= maxAngle) continue;\n                const steps = Math.min(maxSteps, Math.max(1, Math.ceil(angle / maxAngle)));\n                for (let s = 1; s < steps; s++) {\n                    out.push(slerpDir(a, b, s / steps));\n                }\n            }\n            return out;\n        };\n\n        const buildRingDirs = (ring) => {\n            const coords = normalizeRingCoords(ring);\n            const dirs = [];\n            let lastDir = null;\n            for (const coord of coords) {\n                const dir = this._coordToDir(coord);\n                if (!dir) continue;\n                dir.normalize();\n                if (lastDir && dir.dot(lastDir) > 0.999999) continue;\n                dirs.push(dir);\n                lastDir = dir;\n            }\n            if (dirs.length < 3) return [];\n            return densifyDirs(dirs, maxEdgeRad);\n        };\n\n        const projectDirs = (dirs, frame) => {\n            const points2d = [];\n            const points3d = [];\n            for (const dir of dirs) {\n                const pos = dir.clone().multiplyScalar(radius);\n                points3d.push(pos);\n                points2d.push(new THREE.Vector2(\n                    dir.dot(frame.east) * radius,\n                    dir.dot(frame.north) * radius\n                ));\n            }\n            if (points2d.length < 3) return null;\n            return { points2d, points3d };\n        };\n\n        const edgeAngle = (a, b) => {\n            const dot = a.dot(b) * invR2;\n            return Math.acos(THREE.MathUtils.clamp(dot, -1, 1));\n        };\n\n        const midpointOnSphere = (a, b) => a.clone().add(b).normalize().multiplyScalar(radius);\n\n        const pushHatchUV = (pos) => {\n            const dir = pos.clone().multiplyScalar(invRadius);\n            const ll = dirToLatLonLocal(dir);\n            const u = Number.isFinite(ll?.lonDeg) ? (ll.lonDeg + 180) / 360 : 0;\n            const v = Number.isFinite(ll?.latDeg) ? (ll.latDeg + 90) / 180 : 0;\n            hatch.push(u, v);\n        };\n\n        const pushTriangle = (a, b, c) => {\n            if (state.count >= state.limit) return;\n            positions.push(\n                a.x, a.y, a.z,\n                b.x, b.y, b.z,\n                c.x, c.y, c.z\n            );\n            pushHatchUV(a);\n            pushHatchUV(b);\n            pushHatchUV(c);\n            state.count += 1;\n        };\n\n        const subdivideTriangle = (a, b, c, depth) => {\n            if (state.count >= state.limit) return;\n            const maxEdge = Math.max(edgeAngle(a, b), edgeAngle(b, c), edgeAngle(c, a));\n            if (depth <= 0 || maxEdge <= maxEdgeRad) {\n                pushTriangle(a, b, c);\n                return;\n            }\n            const ab = midpointOnSphere(a, b);\n            const bc = midpointOnSphere(b, c);\n            const ca = midpointOnSphere(c, a);\n            const nextDepth = depth - 1;\n            subdivideTriangle(a, ab, ca, nextDepth);\n            subdivideTriangle(ab, b, bc, nextDepth);\n            subdivideTriangle(ca, bc, c, nextDepth);\n            subdivideTriangle(ab, bc, ca, nextDepth);\n        };\n\n        for (const polygon of feature.polygons) {\n            const rings = polygon?.rings;\n            if (!rings || !rings.length) continue;\n            const outerDirs = buildRingDirs(rings[0]);\n            if (outerDirs.length < 3) continue;\n            const frame = buildFrame(outerDirs);\n            if (!frame) continue;\n            const outerProj = projectDirs(outerDirs, frame);\n            if (!outerProj) continue;\n            const holesProj = [];\n            const holePoints3d = [];\n            for (let i = 1; i < rings.length; i++) {\n                const holeDirs = buildRingDirs(rings[i]);\n                if (holeDirs.length < 3) continue;\n                const proj = projectDirs(holeDirs, frame);\n                if (!proj) continue;\n                holesProj.push(proj.points2d);\n                holePoints3d.push(...proj.points3d);\n            }\n\n            const points3d = outerProj.points3d.concat(holePoints3d);\n            const triangles = THREE.ShapeUtils.triangulateShape(outerProj.points2d, holesProj);\n            if (!triangles || !triangles.length) continue;\n\n            for (const tri of triangles) {\n                if (state.count >= state.limit) break;\n                const a = points3d[tri[0]];\n                const b = points3d[tri[1]];\n                const c = points3d[tri[2]];\n                if (!a || !b || !c) continue;\n                subdivideTriangle(a, b, c, DEFAULT_HIGHLIGHT_SUBDIV_DEPTH);\n            }\n        }\n\n        if (!positions.length) return null;\n\n        const geometry = new THREE.BufferGeometry();\n        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n        geometry.setAttribute('hatch', new THREE.Float32BufferAttribute(hatch, 2));\n        return geometry;\n    }\n\n    _buildResponsiveWallMaterial() {\n        const tint = new THREE.Color(resolveGeoJsonColor(this.color));\n        const uniforms = {\n            uColor: { value: tint },\n            uOpacity: { value: this.opacity },\n            uCameraDir: { value: new THREE.Vector3(0, 0, 1) },\n            uHorizon: { value: -1 },\n            uTime: { value: 0 },\n            uAuroraEnabled: { value: this._auroraEnabled ? 1 : 0 },\n            uUseFeatureColor: {\n                value: this._featureColorResolver && this._featureColorsEnabled ? 1 : 0,\n            },\n            uAuroraAmplitude: { value: DEFAULT_AURORA_AMPLITUDE },\n            uAuroraFrequency: { value: DEFAULT_AURORA_FREQUENCY },\n            uAuroraSpeed: { value: DEFAULT_AURORA_SPEED },\n        };\n        const material = new THREE.ShaderMaterial({\n            uniforms,\n            vertexColors: true,\n            transparent: true,\n            depthWrite: false,\n            depthTest: true,\n            side: THREE.DoubleSide,\n            toneMapped: false,\n            vertexShader: `\n#include <common>\n#include <logdepthbuf_pars_vertex>\nattribute float alpha;\nvarying float vLayer;\nvarying vec3 vColorOut,vWorld,vNormalOut,vView;\nuniform float uTime,uAuroraEnabled,uAuroraAmplitude,uAuroraFrequency,uAuroraSpeed;\nvoid main(){\n vec3 p=position;\n vLayer=alpha;vColorOut=color;\n if(uAuroraEnabled>.5&&alpha<.01){\n  float w=sin(dot(p,vec3(1.,.7,.5))*uAuroraFrequency+uTime*uAuroraSpeed);\n  p+=normalize(p)*w*uAuroraAmplitude;\n }\n vec4 world=modelMatrix*vec4(p,1.);vec4 view=viewMatrix*world;\n vWorld=world.xyz;vNormalOut=normalize(normalMatrix*normal);vView=-view.xyz;\n gl_Position=projectionMatrix*view;\n #include <logdepthbuf_vertex>\n}\n            `,\n            fragmentShader: `\n#include <common>\n#include <logdepthbuf_pars_fragment>\nvarying float vLayer;\nvarying vec3 vColorOut,vWorld,vNormalOut,vView;\nuniform vec3 uColor,uCameraDir;\nuniform float uOpacity,uHorizon,uUseFeatureColor;\nvoid main(){\n #include <logdepthbuf_fragment>\n if(dot(normalize(vWorld),uCameraDir)<uHorizon)discard;\n float fresnel=pow(1.-abs(dot(normalize(vNormalOut),normalize(vView))),2.);\n float edge=1.-smoothstep(0.,.16,vLayer);\n vec3 dispersion=vec3(fresnel*.10,fresnel*.035,-fresnel*.045);\n vec3 resolvedColor=mix(mix(uColor,vColorOut,.55),vColorOut,uUseFeatureColor);\n vec3 glass=clamp(resolvedColor*(.45+fresnel*1.25)+dispersion+edge*.16,0.,1.);\n float alpha=clamp(uOpacity*(.7+fresnel*1.8+edge*2.4),0.,.3);\n gl_FragColor=vec4(glass,alpha);\n}\n            `,\n        });\n        material.userData.geoBorderUniforms = uniforms;\n        material.userData.geoBorderResponsiveFallback = true;\n        material.customProgramCacheKey = () => 'noclip-geo-border-responsive-glass-v1';\n        return material;\n    }\n\n    async _scheduleResponsiveWallMaterialPreparation(material) {\n        if (!material || !this._lineChunks.length) return;\n        const renderer = this.sceneInitializer?.renderer;\n        const camera = this.sceneInitializer?.camera;\n        const generation = this._wallMaterialGeneration;\n        try {\n            if (renderer?.compileAsync && camera && renderer.extensions?.has?.('KHR_parallel_shader_compile') === true) {\n                const probe = new THREE.Mesh(this._lineChunks[0].mesh.geometry, material);\n                probe.frustumCulled = false;\n                await renderer.compileAsync(probe, camera, this.sceneInitializer?.scene);\n            }\n            // Without parallel compilation, admit the small responsive shader\n            // through the normal renderer. Do not leave every wall hidden forever.\n            if (generation !== this._wallMaterialGeneration) return;\n            for (const chunk of this._lineChunks) {\n                if (chunk.mesh.material === material) chunk.mesh.userData.geoBorderShaderReady = true;\n            }\n            this._applyModeVisibility();\n        } catch (error) {\n            if (generation === this._wallMaterialGeneration) throw error;\n        }\n    }\n\n    _buildWallMaterial() {\n        const tint = new THREE.Color(resolveGeoJsonColor(this.color));\n        const uniforms = {\n            uOpacity: { value: this.opacity },\n            uCameraDir: { value: new THREE.Vector3(0, 0, 1) },\n            uHorizon: { value: -1 },\n            uTime: { value: 0 },\n            uAuroraEnabled: { value: this._auroraEnabled ? 1 : 0 },\n            uAuroraAmplitude: { value: DEFAULT_AURORA_AMPLITUDE },\n            uAuroraFrequency: { value: DEFAULT_AURORA_FREQUENCY },\n            uAuroraSpeed: { value: DEFAULT_AURORA_SPEED },\n        };\n        const material = new THREE.MeshPhysicalMaterial({\n            color: 0xffffff,\n            vertexColors: true,\n            metalness: 0,\n            roughness: BORDER_GLASS_ROUGHNESS,\n            transmission: BORDER_GLASS_TRANSMISSION,\n            dispersion: BORDER_GLASS_DISPERSION,\n            ior: BORDER_GLASS_IOR,\n            thickness: BORDER_GLASS_THICKNESS_METERS,\n            attenuationColor: tint,\n            attenuationDistance: BORDER_GLASS_ATTENUATION_METERS,\n            emissive: tint,\n            emissiveIntensity: 0.12,\n            transparent: true,\n            opacity: 1,\n            depthWrite: false,\n            depthTest: true,\n            side: THREE.DoubleSide,\n            toneMapped: false,\n        });\n        material.forceSinglePass = true;\n        material.userData.geoBorderUniforms = uniforms;\n        material.customProgramCacheKey = () => 'noclip-geo-border-dispersion-v2';\n        material.onBeforeCompile = (shader) => {\n            Object.assign(shader.uniforms, uniforms);\n            material.userData.geoBorderShader = shader;\n\n            shader.vertexShader = shader.vertexShader\n                .replace('#include <common>', `\n                    #include <common>\n                    attribute float alpha;\n                    varying float vGeoBorderLayer;\n                    varying vec3 vGeoBorderWorldPos;\n                    uniform float uTime;\n                    uniform float uAuroraEnabled;\n                    uniform float uAuroraAmplitude;\n                    uniform float uAuroraFrequency;\n                    uniform float uAuroraSpeed;\n\n                    float geoBorderHash(vec3 p) {\n                        p = fract(p * vec3(443.897, 441.423, 437.195));\n                        p += dot(p, p.yxz + 19.19);\n                        return fract((p.x + p.y) * p.z);\n                    }\n                `)\n                .replace('#include <begin_vertex>', `\n                    #include <begin_vertex>\n                    vGeoBorderLayer = alpha;\n                    if (uAuroraEnabled > 0.5 && alpha < 0.01) {\n                        vec3 geoBorderDir = normalize(position);\n                        float geoBorderNoise = geoBorderHash(position * 0.001);\n                        float geoBorderWave1 = sin(dot(position, vec3(1.0, 0.7, 0.5)) * uAuroraFrequency + uTime * uAuroraSpeed + geoBorderNoise * 6.28);\n                        float geoBorderWave2 = sin(dot(position, vec3(0.5, 1.0, 0.8)) * uAuroraFrequency * 1.7 + uTime * uAuroraSpeed * 0.7 + geoBorderNoise * 3.14);\n                        float geoBorderWave3 = sin(dot(position, vec3(0.8, 0.3, 1.0)) * uAuroraFrequency * 2.3 + uTime * uAuroraSpeed * 1.3);\n                        float geoBorderDisplacement = (geoBorderWave1 * 0.5 + geoBorderWave2 * 0.35 + geoBorderWave3 * 0.15) * uAuroraAmplitude;\n                        transformed += geoBorderDir * geoBorderDisplacement;\n                    }\n                `)\n                .replace('#include <project_vertex>', `\n                    vGeoBorderWorldPos = (modelMatrix * vec4(transformed, 1.0)).xyz;\n                    #include <project_vertex>\n                `);\n\n            shader.fragmentShader = shader.fragmentShader\n                .replace('#include <common>', `\n                    #include <common>\n                    varying float vGeoBorderLayer;\n                    varying vec3 vGeoBorderWorldPos;\n                    uniform float uOpacity;\n                    uniform vec3 uCameraDir;\n                    uniform float uHorizon;\n                `)\n                .replace('#include <clipping_planes_fragment>', `\n                    #include <clipping_planes_fragment>\n                    float geoBorderViewDot = dot(normalize(vGeoBorderWorldPos), uCameraDir);\n                    if (geoBorderViewDot < uHorizon) discard;\n                `)\n                .replace('#include <normal_fragment_maps>', `\n                    #include <normal_fragment_maps>\n                    float geoBorderFresnel = pow(1.0 - abs(dot(normalize(normal), normalize(vViewPosition))), 2.0);\n                    float geoBorderTopEdge = 1.0 - smoothstep(0.0, 0.16, vGeoBorderLayer);\n                    float geoBorderAlpha = clamp(\n                        uOpacity * (0.55 + geoBorderFresnel * 1.7 + geoBorderTopEdge * 2.4),\n                        0.0,\n                        0.30\n                    );\n                    diffuseColor.a *= geoBorderAlpha;\n                    diffuseColor.rgb = mix(\n                        diffuseColor.rgb,\n                        vec3(1.0),\n                        clamp(geoBorderTopEdge * 0.28 + geoBorderFresnel * 0.16, 0.0, 0.42)\n                    );\n                `)\n                .replace('#include <emissivemap_fragment>', `\n                    #include <emissivemap_fragment>\n                    totalEmissiveRadiance += diffuseColor.rgb\n                        * (0.15 + (1.0 - smoothstep(0.0, 0.16, vGeoBorderLayer)) * 0.55)\n                        * uOpacity;\n                `);\n        };\n        return material;\n    }\n\n    _buildHatchMaterial({ color, opacity } = {}) {\n        const hatchColor = new THREE.Color(Number.isFinite(color) ? color : resolveGeoJsonColor(this.highlightColor));\n        const hatchOpacity = Number.isFinite(opacity) ? opacity : this.highlightOpacity;\n        const circumference = Math.max(1, 2 * Math.PI * this.planetRadius);\n        const hatchSpacing = Math.max(1, Number.isFinite(this._highlightHatchSpacingMeters)\n            ? this._highlightHatchSpacingMeters\n            : DEFAULT_HATCH_SPACING_METERS);\n        const scale = hatchSpacing > 0\n            ? (circumference / hatchSpacing)\n            : DEFAULT_HATCH_SCALE;\n        const hatchThickness = Number.isFinite(this._highlightHatchThickness)\n            ? this._highlightHatchThickness\n            : DEFAULT_HATCH_THICKNESS;\n        const hatchFeather = Number.isFinite(this._highlightHatchFeather)\n            ? this._highlightHatchFeather\n            : DEFAULT_HATCH_FEATHER;\n        const material = new THREE.ShaderMaterial({\n            uniforms: {\n                uColor: { value: hatchColor },\n                uOpacity: { value: hatchOpacity },\n                uScale: { value: scale },\n                uThickness: { value: hatchThickness },\n                uFeather: { value: hatchFeather },\n                uCameraDir: { value: new THREE.Vector3(0, 0, 1) },\n                uHorizon: { value: -1 }\n            },\n            vertexShader: `\n                #include <common>\n                #include <logdepthbuf_pars_vertex>\n                attribute vec2 hatch;\n                varying vec2 vHatch;\n                varying vec3 vWorldPos;\n                void main() {\n                    vHatch = hatch;\n                    vec4 worldPos = modelMatrix * vec4(position, 1.0);\n                    vWorldPos = worldPos.xyz;\n                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n                    #include <logdepthbuf_vertex>\n                }\n            `,\n            fragmentShader: `\n                #include <common>\n                #include <logdepthbuf_pars_fragment>\n                varying vec2 vHatch;\n                uniform vec3 uColor;\n                uniform float uOpacity;\n                uniform float uScale;\n                uniform float uThickness;\n                uniform float uFeather;\n                uniform vec3 uCameraDir;\n                uniform float uHorizon;\n                varying vec3 vWorldPos;\n\n                mat2 rot(float a) {\n                    float c = cos(a);\n                    float s = sin(a);\n                    return mat2(c, -s, s, c);\n                }\n\n                float stripe(vec2 uv) {\n                    float coord = uv.x * uScale;\n                    float line = abs(fract(coord) - 0.5);\n                    return 1.0 - smoothstep(uThickness, uThickness + uFeather, line);\n                }\n\n                void main() {\n                    #include <logdepthbuf_fragment>\n                    float viewDot = dot(normalize(vWorldPos), uCameraDir);\n                    if (viewDot < uHorizon) discard;\n                    vec2 uv = vHatch;\n                    vec2 uv1 = rot(0.785398) * uv;\n                    float hatch = stripe(uv1);\n                    if (hatch <= 0.0) discard;\n                    gl_FragColor = vec4(uColor, hatch * uOpacity);\n                }\n            `,\n            transparent: true,\n            depthWrite: false,\n            depthTest: true,\n            side: THREE.DoubleSide,\n            toneMapped: false\n        });\n        return material;\n    }\n\n    _buildOrbitLineMaterial() {\n        return new THREE.ShaderMaterial({\n            uniforms: {\n                uOpacity: { value: DEFAULT_ORBIT_LINE_OPACITY },\n                uUseFeatureColor: {\n                    value: this._featureColorResolver && this._featureColorsEnabled ? 1 : 0,\n                },\n                uCameraDir: { value: new THREE.Vector3(0, 0, 1) },\n                uHorizon: { value: -1 },\n                uViewport: { value: new THREE.Vector2(1, 1) },\n                uLineHalfWidthPx: { value: 1 },\n                uRadialLiftMeters: { value: BORDER_ORBIT_LIFT_METERS },\n            },\n            vertexShader: `\n                #include <common>\n                #include <logdepthbuf_pars_vertex>\n                attribute vec3 otherPosition;\n                attribute float lineSide;\n                uniform vec2 uViewport;\n                uniform float uLineHalfWidthPx;\n                uniform float uRadialLiftMeters;\n                varying vec3 vWorldPos;\n                varying vec3 vColor;\n                void main() {\n                    vec3 radialPosition = normalize(position)\n                        * (length(position) + uRadialLiftMeters);\n                    vec3 radialOther = normalize(otherPosition)\n                        * (length(otherPosition) + uRadialLiftMeters);\n                    vec4 worldPos = modelMatrix * vec4(radialPosition, 1.0);\n                    vWorldPos = worldPos.xyz;\n                    vColor = color;\n                    vec4 clip = projectionMatrix * modelViewMatrix * vec4(radialPosition, 1.0);\n                    vec4 otherClip = projectionMatrix * modelViewMatrix * vec4(radialOther, 1.0);\n                    vec2 safeViewport = max(uViewport, vec2(1.0));\n                    vec2 pointPx = (clip.xy / max(1e-6, clip.w)) * safeViewport * 0.5;\n                    vec2 otherPx = (otherClip.xy / max(1e-6, otherClip.w)) * safeViewport * 0.5;\n                    vec2 segmentPx = otherPx - pointPx;\n                    float segmentLength = max(length(segmentPx), 1e-4);\n                    vec2 perpendicularPx = vec2(-segmentPx.y, segmentPx.x) / segmentLength;\n                    vec2 offsetNdc = perpendicularPx\n                        * lineSide\n                        * uLineHalfWidthPx\n                        * 2.0\n                        / safeViewport;\n                    clip.xy += offsetNdc * clip.w;\n                    gl_Position = clip;\n                    #include <logdepthbuf_vertex>\n                }\n            `,\n            fragmentShader: `\n                #include <common>\n                #include <logdepthbuf_pars_fragment>\n                uniform float uOpacity;\n                uniform float uUseFeatureColor;\n                uniform vec3 uCameraDir;\n                uniform float uHorizon;\n                varying vec3 vWorldPos;\n                varying vec3 vColor;\n                void main() {\n                    #include <logdepthbuf_fragment>\n                    vec3 surfaceDir = normalize(vWorldPos);\n                    float viewDot = dot(surfaceDir, uCameraDir);\n                    if (viewDot < uHorizon) discard;\n                    // Borders are an enabled cartographic overlay, not Earth\n                    // lighting. Preserve their configured color and opacity\n                    // identically on the day side, terminator, and night side.\n                    vec3 borderColor = vColor;\n                    gl_FragColor = vec4(borderColor, uOpacity);\n                }\n            `,\n            transparent: true,\n            vertexColors: true,\n            depthWrite: false,\n            // Match environmental coverage outlines: the horizon discard owns\n            // Earth occlusion, while terrain depth must not make country/admin\n            // boundaries disappear on photoreal, TriTree, or wireframe.\n            depthTest: false,\n            // The CPU geometry is a degenerate centerline; the vertex shader\n            // gives it area only after projecting and extruding it in clip\n            // space. Its post-projection winding depends on the endpoint\n            // direction, so FrontSide culling can reject the entire ribbon.\n            // Environmental/smoke outlines use the same contract and are\n            // deliberately double-sided for this reason.\n            side: THREE.DoubleSide,\n            toneMapped: false\n        });\n    }\n\n    _updateOrbitLineScreenSpace(camera) {\n        const material = this._orbitLineMaterial || this._orbitLine?.material;\n        const uniforms = this._getWallUniforms(material);\n        updateScreenSpaceOutlineUniforms({\n            uniforms,\n            camera,\n            renderer: this.sceneInitializer?.renderer,\n            viewportTarget: this._tmpViewport,\n            referenceHalfWidthM: SCREEN_SPACE_OUTLINE_REFERENCE_HALF_WIDTH_M,\n        });\n        if (uniforms?.uRadialLiftMeters) {\n            uniforms.uRadialLiftMeters.value = BORDER_ORBIT_LIFT_METERS;\n        }\n    }\n\n    _buildHighlightOutlineGeometry(feature) {\n        if (!feature || !feature.polygons || !feature.polygons.length) return null;\n        const positions = [];\n        const radius = this.planetRadius + this._getHighlightLiftMeters();\n        const width = this._getHighlightOutlineWidth();\n        const halfWidth = width * 0.5;\n        const segmentMeters = Math.max(1, DEFAULT_OUTLINE_SEGMENT_METERS);\n        const maxSamples = Math.max(32, MAX_OUTLINE_SAMPLES);\n        const maxSegmentRad = Math.max(1e-6, segmentMeters / radius);\n        const pushQuad = (p0, p1) => {\n            const n0 = p0.clone().normalize();\n            const n1 = p1.clone().normalize();\n            const tangent = p1.clone().sub(p0);\n            if (tangent.lengthSq() < 1e-6) return;\n            tangent.normalize();\n            const left0 = new THREE.Vector3().crossVectors(tangent, n0).normalize();\n            const left1 = new THREE.Vector3().crossVectors(tangent, n1).normalize();\n            const p0a = p0.clone().add(left0.clone().multiplyScalar(halfWidth)).normalize().multiplyScalar(radius);\n            const p0b = p0.clone().add(left0.clone().multiplyScalar(-halfWidth)).normalize().multiplyScalar(radius);\n            const p1a = p1.clone().add(left1.clone().multiplyScalar(halfWidth)).normalize().multiplyScalar(radius);\n            const p1b = p1.clone().add(left1.clone().multiplyScalar(-halfWidth)).normalize().multiplyScalar(radius);\n            positions.push(\n                p0a.x, p0a.y, p0a.z,\n                p1a.x, p1a.y, p1a.z,\n                p1b.x, p1b.y, p1b.z,\n                p0a.x, p0a.y, p0a.z,\n                p1b.x, p1b.y, p1b.z,\n                p0b.x, p0b.y, p0b.z\n            );\n        };\n\n        const normalizeRingCoords = (ring) => {\n            if (!Array.isArray(ring) || ring.length < 3) return [];\n            const out = ring.slice();\n            const first = out[0];\n            const last = out[out.length - 1];\n            if (Array.isArray(first) && Array.isArray(last) &&\n                Math.abs(Number(first[0]) - Number(last[0])) < 1e-6 &&\n                Math.abs(Number(first[1]) - Number(last[1])) < 1e-6) {\n                out.pop();\n            }\n            return out;\n        };\n\n        const slerpDir = (a, b, t) => {\n            const dot = THREE.MathUtils.clamp(a.dot(b), -1, 1);\n            const omega = Math.acos(dot);\n            if (!Number.isFinite(omega) || omega < 1e-6) {\n                return a.clone();\n            }\n            const sinOmega = Math.sin(omega);\n            const scaleA = Math.sin((1 - t) * omega) / sinOmega;\n            const scaleB = Math.sin(t * omega) / sinOmega;\n            return a.clone().multiplyScalar(scaleA).add(b.clone().multiplyScalar(scaleB)).normalize();\n        };\n\n        const densifyDirs = (dirs, maxAngle) => {\n            if (!dirs || dirs.length < 2) return [];\n            const out = [];\n            const maxSteps = 256;\n            for (let i = 0; i < dirs.length; i++) {\n                const a = dirs[i];\n                const b = dirs[(i + 1) % dirs.length];\n                out.push(a.clone());\n                const angle = Math.acos(THREE.MathUtils.clamp(a.dot(b), -1, 1));\n                if (!Number.isFinite(angle) || angle <= maxAngle) continue;\n                const steps = Math.min(maxSteps, Math.max(1, Math.ceil(angle / maxAngle)));\n                for (let s = 1; s < steps; s++) {\n                    out.push(slerpDir(a, b, s / steps));\n                }\n            }\n            return out;\n        };\n\n        const buildRingDirs = (ring) => {\n            const coords = normalizeRingCoords(ring);\n            const dirs = [];\n            let lastDir = null;\n            for (const coord of coords) {\n                const dir = this._coordToDir(coord);\n                if (!dir) continue;\n                dir.normalize();\n                if (lastDir && dir.dot(lastDir) > 0.999999) continue;\n                dirs.push(dir);\n                lastDir = dir;\n            }\n            if (dirs.length < 3) return null;\n            const densified = densifyDirs(dirs, maxSegmentRad);\n            if (densified.length <= maxSamples) return densified;\n            const stride = Math.ceil(densified.length / maxSamples);\n            const sampled = [];\n            for (let i = 0; i < densified.length; i += stride) {\n                sampled.push(densified[i]);\n            }\n            return sampled.length >= 3 ? sampled : densified;\n        };\n\n        for (const polygon of feature.polygons) {\n            const rings = polygon?.rings;\n            if (!rings || !rings.length) continue;\n            for (const ring of rings) {\n                if (!Array.isArray(ring) || ring.length < 3) continue;\n                const dirs = buildRingDirs(ring);\n                if (!dirs) continue;\n                const segmentCount = dirs.length;\n                for (let i = 0; i < segmentCount; i++) {\n                    const p0 = dirs[i].clone().multiplyScalar(radius);\n                    const p1 = dirs[(i + 1) % segmentCount].clone().multiplyScalar(radius);\n                    pushQuad(p0, p1);\n                }\n            }\n        }\n\n        if (!positions.length) return null;\n        const geometry = new THREE.BufferGeometry();\n        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n        return geometry;\n    }\n\n    _getHighlightLiftMeters() {\n        return this._renderMode === 'orbit'\n            ? this.highlightLiftMetersOrbit\n            : this.highlightLiftMetersSurface;\n    }\n\n    _getHighlightOutlineWidth() {\n        const width = Number.isFinite(this._highlightOutlineWidthMeters)\n            ? this._highlightOutlineWidthMeters\n            : DEFAULT_HIGHLIGHT_OUTLINE_WIDTH_METERS;\n        return this._renderMode === 'orbit'\n            ? width\n            : width * DEFAULT_HIGHLIGHT_OUTLINE_SURFACE_RATIO;\n    }\n\n    _getHighlightStyleForAdminLevel(adminLevel) {\n        const level = Number.isFinite(adminLevel) ? Math.max(0, Math.min(4, Math.floor(adminLevel))) : 0;\n        const spacingMeters = level === 0\n            ? 120_000\n            : level === 1\n                ? 90_000\n                : level === 2\n                    ? 70_000\n                    : 55_000;\n        const hatchThickness = level === 0\n            ? 0.055\n            : level === 1\n                ? 0.045\n                : level === 2\n                    ? 0.038\n                    : 0.032;\n        const hatchFeather = Math.min(0.08, hatchThickness * 0.6);\n        const outlineWidthMeters = DEFAULT_HIGHLIGHT_OUTLINE_WIDTH_METERS * (\n            level === 0 ? 1.0 : level === 1 ? 0.75 : level === 2 ? 0.55 : 0.4\n        );\n        const pixelThickness = level === 0 ? 2.2 : level === 1 ? 1.8 : level === 2 ? 1.4 : 1.1;\n        return {\n            hatchSpacingMeters: spacingMeters,\n            hatchThickness,\n            hatchFeather,\n            outlineWidthMeters,\n            pixelThickness\n        };\n    }\n\n    _updateHighlightHatchUniforms(camera) {\n        if (!this._fillMesh || !this._fillMesh.material || !this._highlightCenterDir) return;\n        const material = this._fillMesh.material;\n        if (!material.uniforms) return;\n        const renderer = this.sceneInitializer?.renderer;\n        const viewportHeight = renderer?.domElement?.clientHeight || 0;\n        if (viewportHeight <= 0) return;\n        const camPos = camera.userData?.worldPosition || camera.position;\n        if (!camPos) return;\n\n        const surfaceRadius = ellipsoidRadiusForLocalDir(this._highlightCenterDir) || this.planetRadius;\n        const lift = this._getHighlightLiftMeters();\n        const localPos = this._tmpVec3.copy(this._highlightCenterDir).multiplyScalar(surfaceRadius + lift);\n        const worldPos = this._tmpVec3b.copy(localPos);\n        this.group?.localToWorld?.(worldPos);\n\n        const dist = worldPos.distanceTo(camPos);\n        if (!Number.isFinite(dist) || dist <= 0) return;\n        const unitsPerPixel = this._getWorldUnitsPerPixel(camera, dist, viewportHeight);\n        if (!Number.isFinite(unitsPerPixel) || unitsPerPixel <= 0) return;\n\n        const style = this._getHighlightStyleForAdminLevel(this._highlightAdminLevel);\n        const spacingMeters = Number.isFinite(this._highlightHatchSpacingMeters)\n            ? this._highlightHatchSpacingMeters\n            : style.hatchSpacingMeters;\n        const targetPixels = style.pixelThickness;\n        const thicknessMeters = unitsPerPixel * targetPixels;\n        const thickness = THREE.MathUtils.clamp(thicknessMeters / Math.max(1, spacingMeters), 0.005, 0.12);\n        const feather = THREE.MathUtils.clamp(thickness * 0.6, 0.005, 0.08);\n        const circumference = Math.max(1, 2 * Math.PI * this.planetRadius);\n        const scale = Math.max(1, circumference / Math.max(1, spacingMeters));\n\n        if (material.uniforms.uThickness && Math.abs(material.uniforms.uThickness.value - thickness) > 1e-4) {\n            material.uniforms.uThickness.value = thickness;\n        }\n        if (material.uniforms.uFeather && Math.abs(material.uniforms.uFeather.value - feather) > 1e-4) {\n            material.uniforms.uFeather.value = feather;\n        }\n        if (material.uniforms.uScale && Math.abs(material.uniforms.uScale.value - scale) > 1e-3) {\n            material.uniforms.uScale.value = scale;\n        }\n    }\n\n    _applyHorizonUniforms(material, cameraDir, horizon) {\n        if (!material) return;\n        const uniforms = this._getWallUniforms(material);\n        if (!uniforms) return;\n        const dirUniform = uniforms.uCameraDir;\n        const horizonUniform = uniforms.uHorizon;\n        if (!dirUniform || !horizonUniform) return;\n        if (dirUniform.value?.copy) {\n            dirUniform.value.copy(cameraDir);\n        } else {\n            dirUniform.value = cameraDir.clone();\n        }\n        horizonUniform.value = horizon;\n    }\n\n    _updateHorizonCull(camera) {\n        if (!camera) return;\n        const camPos = camera.userData?.worldPosition || camera.position;\n        if (!camPos) return;\n        this.group?.updateMatrixWorld?.(true);\n        const groupWorldPos = this.group?.getWorldPosition?.(this._tmpGroupWorldPos) || this._tmpGroupWorldPos.set(0, 0, 0);\n        const cameraFromCenter = this._tmpVec3e.copy(camPos).sub(groupWorldPos);\n        const worldCamRadius = cameraFromCenter.length();\n        if (!Number.isFinite(worldCamRadius) || worldCamRadius <= 0) return;\n        const worldCamDir = cameraFromCenter.multiplyScalar(1 / worldCamRadius);\n\n        const localCamPos = this._tmpCamPos.copy(camPos);\n        this.group?.worldToLocal?.(localCamPos);\n        const camRadius = localCamPos.length();\n        if (!Number.isFinite(camRadius) || camRadius <= 0) return;\n        const localCamDir = this._tmpCamDir.copy(localCamPos).normalize();\n        const baseRadius = ellipsoidRadiusForLocalDir(localCamDir) || this.planetRadius;\n        const horizon = THREE.MathUtils.clamp(baseRadius / camRadius, -1, 1);\n        const altitudeM = Math.max(0, camRadius - baseRadius);\n        const orbitThresholdM = this._orbitRibbonVisible\n            ? SCREEN_SPACE_ORBIT_EXIT_ALTITUDE_M\n            : SCREEN_SPACE_ORBIT_ENTER_ALTITUDE_M;\n        this._orbitRibbonVisible = screenSpaceOrbitCoverageVisible({\n            altitudeM,\n            surfaceMode: this._renderMode === 'surface' && !this._orbitRibbonVisible,\n            minimumAltitudeM: orbitThresholdM,\n        });\n        this._applyHorizonUniforms(this._lineMaterial || this._line?.material, worldCamDir, horizon);\n        this._applyHorizonUniforms(this._orbitLineMaterial || this._orbitLine?.material, worldCamDir, horizon);\n        if (this._fillMesh) {\n            this._applyHorizonUniforms(this._fillMesh.material, worldCamDir, horizon);\n        }\n\n        const capAngle = Math.acos(horizon);\n        const isChunkVisible = (chunk) => {\n            if (!chunk?.centerDir || chunk.angularRadius >= Math.PI) return true;\n            const threshold = Math.cos(Math.min(Math.PI, capAngle + chunk.angularRadius));\n            return chunk.centerDir.dot(localCamDir) >= threshold;\n        };\n        const wallsVisible = this.group.visible\n            && this._renderMode === 'surface'\n            && !this._orbitRibbonVisible;\n        const orbitVisible = this.group.visible && this._orbitRibbonVisible;\n        for (const chunk of this._lineChunks) {\n            chunk.mesh.visible = chunk.mesh.userData.geoBorderShaderReady === true\n                && wallsVisible\n                && isChunkVisible(chunk);\n        }\n        for (const chunk of this._orbitLineChunks) {\n            chunk.mesh.visible = orbitVisible && isChunkVisible(chunk);\n        }\n    }\n\n    _applyModeVisibility() {\n        this._boundaryStage?._applyModeVisibility();\n        const wallsVisible = this.group.visible\n            && this._renderMode === 'surface'\n            && !this._orbitRibbonVisible;\n        // The smoke-style screen-space ribbon is orbital cartography. Surface\n        // mode already has the terrain-mated spire wall; rendering both makes\n        // every boundary appear twice and leaves a floating colored line.\n        const orbitVisible = this.group.visible && this._orbitRibbonVisible;\n        if (this._lineChunks.length) {\n            for (const chunk of this._lineChunks) {\n                chunk.mesh.visible = chunk.mesh.userData.geoBorderShaderReady === true && wallsVisible;\n            }\n        } else if (this._line) {\n            this._line.visible = wallsVisible;\n        }\n        if (this._orbitLineChunks.length) {\n            for (const chunk of this._orbitLineChunks) chunk.mesh.visible = orbitVisible;\n        } else if (this._orbitLine) {\n            this._orbitLine.visible = orbitVisible;\n        }\n        if (this._labelGroup) {\n            this._labelGroup.visible = this.group.visible && this._labelsEnabled;\n        }\n    }\n\n    _applyFeatureFilter(geojson) {\n        if (!geojson || !Array.isArray(geojson.features)) return geojson;\n\n        const hasIso3Filter = !!this._filterIso3;\n        const hasParentFilter = !!this._filterParentName;\n\n        // No filters - return as-is\n        if (!hasIso3Filter && !hasParentFilter) return geojson;\n\n        const iso3 = this._filterIso3;\n        const parentName = this._filterParentName;\n        const parentLevel = this._filterParentLevel;\n\n        const filtered = geojson.features.filter((feature) => {\n            // Apply ISO3 country filter if set\n            if (hasIso3Filter && !this._featureMatchesIso3(feature, iso3)) {\n                return false;\n            }\n            // Apply parent region filter if set\n            if (hasParentFilter && !this._featureMatchesParent(feature, parentName, parentLevel)) {\n                return false;\n            }\n            return true;\n        });\n\n        return { ...geojson, features: filtered };\n    }\n\n    /**\n     * Check if a feature belongs to the given parent administrative region.\n     * GADM format uses NAME_1 property on ADM2 features, NAME_2 on ADM3 features, etc.\n     * @param {object} feature - The GeoJSON feature\n     * @param {string} parentName - The parent region name to match\n     * @param {number|null} parentLevel - The admin level of the parent (1 for ADM1, 2 for ADM2)\n     * @returns {boolean}\n     */\n    _featureMatchesParent(feature, parentName, parentLevel) {\n        if (!feature || !feature.properties || !parentName) return false;\n        const props = feature.properties;\n\n        // Normalize parent name for comparison (case-insensitive)\n        const normalizedParent = parentName.toLowerCase().trim();\n\n        // Determine which property to check based on parent level\n        // If parentLevel is 1 (ADM1), check NAME_1 (feature is ADM2, parent is ADM1)\n        // If parentLevel is 2 (ADM2), check NAME_2 (feature is ADM3, parent is ADM2)\n        // If parentLevel is null, check all NAME_n properties\n\n        const propsToCheck = [];\n\n        if (parentLevel === 1) {\n            // Feature should be ADM2, check its ADM1 parent\n            propsToCheck.push(props.NAME_1, props.name_1, props.ADM1_NAME, props.admin1_name);\n        } else if (parentLevel === 2) {\n            // Feature should be ADM3, check its ADM2 parent\n            propsToCheck.push(props.NAME_2, props.name_2, props.ADM2_NAME, props.admin2_name);\n        } else {\n            // No specific level - check all parent reference properties\n            propsToCheck.push(\n                props.NAME_1, props.name_1, props.ADM1_NAME, props.admin1_name,\n                props.NAME_2, props.name_2, props.ADM2_NAME, props.admin2_name,\n                props.NAME_3, props.name_3, props.ADM3_NAME, props.admin3_name\n            );\n        }\n\n        for (const value of propsToCheck) {\n            if (typeof value !== 'string') continue;\n            if (value.toLowerCase().trim() === normalizedParent) return true;\n        }\n\n        return false;\n    }\n\n    _featureMatchesIso3(feature, iso3) {\n        if (!feature || !feature.properties) return false;\n        const props = feature.properties;\n        const candidates = [\n            props.iso_a3,\n            props.adm0_a3,\n            props.sov_a3,\n            props.iso_a3_eh,\n            props.adm0_a3_us,\n            props.adm0_a3_un,\n            props.adm0_a3_wb,\n            props.brk_a3,\n            props.gu_a3,\n            props.su_a3\n        ];\n        for (const value of candidates) {\n            if (typeof value !== 'string') continue;\n            if (value.toUpperCase() === iso3) return true;\n        }\n        return false;\n    }\n}\n"],"names":["ADMIN_LABEL_INTERIOR_GRID","ADMIN_LABEL_INTERIOR_REFINEMENT_STEPS","clamp","value","min","max","BoundaryPreparation","geometry","cached","_b","_a","type","polygons","poly","out","polyCoords","geom","_d","_c","rings","outerRing","wrap","outer","ringData","i","hole","ring","minLon","maxLon","minLat","maxLat","canUseSourceRing","pt","rawLon","lat","coords","lon","prevLon","first","firstLon","inside","j","xi","yi","xj","yj","props","pairs","latKey","lonKey","feature","fromProps","resolved","interior","centroid","mid","polygon","testLon","bbox","best","a","b","ax","ay","bx","by","dx","dy","lengthSq","t","px","py","distSq","preferred","target","targetArea","area","bestLon","bestLat","bestScore","consider","score","preferredLon","grid","probe","centerLon","centerLat","halfLon","halfLat","y","x","step","areaSum","cx","cy","holeArea","last","x0","y0","x1","y1","cross","factor","midIndex","coord","lines","bestLen","line","prepareBoundaryPayload","buffer","offsets","shareable","offset","length","_","source","index","decode","g","depth","child","prep","MAX_BOUNDARY_POINTS","MAX_BOUNDARY_RINGS","MAX_BOUNDARY_FEATURES","BOUNDARY_SLICE_MS","stats","checkBoundarySignal","signal","waitBoundaryTask","task","resolve","reject","abort","runBoundarySteps","steps","start","count","_step","yieldToEventLoop","boundaryLines","active","waiting","acquire","entry","release","next","prepareBoundaryFeature","layer","budget","points","indices","encode","c","originalNumbers","point","payload","result","pool","getWorkerPool","error","prepared","DEFAULT_BORDER_COLOR","DEFAULT_HIGHLIGHT_COLOR","DEFAULT_HIGHLIGHT_OPACITY","DEFAULT_WALL_DEPTH_METERS","DEFAULT_LIFT_METERS","SAFETY_DEPTH_M","DEFAULT_ORBIT_LINE_OPACITY","BORDER_ORBIT_LIFT_METERS","DEFAULT_AURORA_AMPLITUDE","DEFAULT_AURORA_FREQUENCY","DEFAULT_AURORA_SPEED","DEFAULT_HIGHLIGHT_SUBDIV_DEG","DEFAULT_HIGHLIGHT_SUBDIV_DEPTH","MAX_HIGHLIGHT_TRIANGLES","DEFAULT_HIGHLIGHT_OUTLINE_WIDTH_METERS","DEFAULT_HIGHLIGHT_OUTLINE_SURFACE_RATIO","DEFAULT_HATCH_SCALE","DEFAULT_HATCH_SPACING_METERS","DEFAULT_HATCH_THICKNESS","DEFAULT_HATCH_FEATHER","DEFAULT_OUTLINE_SEGMENT_METERS","MAX_OUTLINE_SAMPLES","HIGHLIGHT_LIFT_OFFSET","HIGHLIGHT_MIN_LIFT","LABEL_MAX_DISTANCE","LABEL_MIN_DISTANCE","LABEL_MAX_VISIBLE","LABEL_SURFACE_LIFT_METERS","LABEL_ORBIT_LIFT_METERS","LABEL_BASE_SCALE","LABEL_MIN_PIXEL_HEIGHT","LABEL_MAX_PIXEL_HEIGHT","LABEL_PIXEL_RATIO","LABEL_SCALE_CAP_ALT_METERS","LABEL_SCALE_RELEASE_ALT_METERS","LABEL_BORDER_RETIRE_ALT_METERS","LABEL_RAPID_MOTION_INTERVAL_MS","LABEL_RAPID_MOTION_SPEED_MPS","LABEL_OBJECT_RADIUS_BY_ADM","BEYOND_BORDER_LABEL_MAX_VISIBLE","BEYOND_BORDER_LABEL_MAX_DISTANCE_METERS","BEYOND_BORDER_LABEL_REFRESH_MS","BEYOND_BORDER_LABEL_CAMERA_MOVE_METERS","BEYOND_BORDER_LABEL_TOP_CLEARANCE_METERS","BEYOND_BORDER_NEAREST_SEGMENT_LIMIT","BEYOND_BORDER_PROBE_DISTANCES_METERS","METERS_PER_LATITUDE_DEGREE","BORDER_GLASS_TRANSMISSION","BORDER_GLASS_DISPERSION","BORDER_GLASS_IOR","BORDER_GLASS_THICKNESS_METERS","BORDER_GLASS_ATTENUATION_METERS","BORDER_GLASS_ROUGHNESS","GEOJSON_CHUNK_LAT_BANDS","GEOJSON_CHUNK_LON_BANDS","GEOJSON_HORIZON_CHUNK_MARGIN_RAD","THREE.MathUtils","SURFACE_SAMPLE_QUANTIZATION","SURFACE_SAMPLE_QUANTIZATION_WIDTH","MAX_SURFACE_SAMPLE_CACHE_ENTRIES","resolveGeoJsonColor","cssColor","match","varName","fallback","computed","GeoJsonLayer","parentGroup","url","planetRadius","PLANET_RADIUS","color","opacity","liftMeters","wallDepthMeters","sceneInitializer","deferUntilInteractive","THREE.Group","SCREEN_SPACE_OUTLINE_POST_COMPOSITE_LAYER","THREE.Vector3","THREE.Quaternion","THREE.Vector2","visible","ready","enabled","colorValue","THREE.Color","chunk","colorAttr","range","_f","_e","singleColorAttr","_i","_h","_g","orbitColor","_l","_k","_j","_p","_o","_n","_m","wallMaterial","_q","_v","_u","_t","_s","_r","_x","_w","_z","_y","resolver","changed","useFeatureColor","material","uniforms","force","updateRanges","chunks","attribute","end","loadSeq","run","id","scheduled","scaleCapAltM","scaleReleaseAltM","borderRetireAltM","label","displayLines","key","name","meta","style","cacheKey","canvas","ctx","maxWidth","width","height","texture","THREE.CanvasTexture","THREE.LinearFilter","aspect","sprite","THREE.SpriteMaterial","THREE.Sprite","getLabelSystem","record","handle","primary","subText","level","pick","keys","country","parent","isBorder","position","maxDistance","ls","metadata","node","raycaster","camera","sprites","group","hits","event","detail","mode","nextMode","orbitUniforms","mat","amplitude","frequency","speed","p","controller","geojson","fetchJsonResource","features","owner","featureIndex","labelData","reload","iso3","parentName","parentLevel","nextName","nextLevel","parsedAdminLevel","adminLevel","anchor","dir","latLonToLocalDir","resolvedHighlightColor","mesh","THREE.Mesh","outline","outlineMaterial","THREE.MeshBasicMaterial","THREE.DoubleSide","outlineMesh","dt","nextView","prior","delta","camPos","altKm","invScale","baseScale","currentFeature","featureName","currentName","viewerLat","viewerLon","lonScale","xMeters","yMeters","nearest","candidate","farthestIndex","latA","latB","lonA","lonB","segment","normalX","normalY","viewerSide","distance","beyond","byRegion","beyondFeature","beyondName","normalizedBeyond","parsedLevel","iso","isCountry","targetDir","selectionKey","camDir","now","regionKey","movedMeters","previous","horizon","base","insetRatio","fract","pz","mixed","positionHash","wave1","wave2","wave3","topRadius","topPosition","nowMs","cameraPosition","elapsedMs","rapidMotion","camPosWorld","renderer","domElement","viewportHeight","camPosLocal","camDist","camRadius","ellipsoidRadiusForLocalDir","altitude","surfaceLift","orbitLift","targetPixelHeight","capAlt","releaseAlt","retireAlt","clampLabelScale","retireAdmBorders","currentRegionFeature","currentRegionName","camDirLocal","ll","dirToLatLonLocal","currentRegionNorm","horizonThreshold","scored","staticCount","totalCount","dynamicBorder","isBorderLabel","left","right","leftNorm","rightNorm","radius","dist","itemMaxDistance","viewDot","priorityDiff","visibleIndices","v","sharedLabelsAvailable","idx","item","fadeStart","fadeDist","distFade","closeStart","closeFade","horizonFadeRange","horizonFade","unitsPerPixel","scaleMul","scale","distScale","capScale","fov","lonWrapped","inHole","positions","colors","alphas","linePositions","lineColors","close","lastIndex","topAlpha","bottomAlpha","wallDepth","pushVertex","alpha","dirA","dirB","sampleA","sampleB","topRadiusA","topRadiusB","bottomRadiusA","bottomRadiusB","orbitRadiusA","orbitRadiusB","otherPositions","lineSides","other","side","colorOffset","radiusA","radiusB","surfaceController","tt","q","qx","qy","qz","quat","r","cache","maxEntries","oldest","local","view","halfAngle","center","workSignal","stage","committed","culledSegments","segments","makeChunk","flush","wallColor","wallRange","orbitRange","meshes","second","entries","nextFrame","latIndex","lonIndex","orbitLineMaterial","horizonData","THREE.BufferGeometry","THREE.Float32BufferAttribute","ribbon","lineHorizonData","sphere","centerLength","radiusRatio","neighbors","labels","adminLabel","priority","neighborInfo","geomType","selectionLabel","featureRef","safeName","raw","direct","parsed","disposeMeshes","hatch","maxEdgeRad","invR2","invRadius","state","buildFrame","dirs","up","east","north","normalizeRingCoords","slerpDir","dot","omega","sinOmega","scaleA","scaleB","densifyDirs","maxAngle","maxSteps","angle","s","buildRingDirs","lastDir","projectDirs","frame","points2d","points3d","pos","edgeAngle","midpointOnSphere","pushHatchUV","u","pushTriangle","subdivideTriangle","maxEdge","ab","bc","ca","nextDepth","outerDirs","outerProj","holesProj","holePoints3d","holeDirs","proj","triangles","THREE.ShapeUtils","tri","THREE.ShaderMaterial","generation","tint","THREE.MeshPhysicalMaterial","shader","hatchColor","hatchOpacity","circumference","hatchSpacing","hatchThickness","hatchFeather","updateScreenSpaceOutlineUniforms","SCREEN_SPACE_OUTLINE_REFERENCE_HALF_WIDTH_M","halfWidth","segmentMeters","maxSamples","maxSegmentRad","pushQuad","p0","p1","n0","n1","tangent","left0","left1","p0a","p0b","p1a","p1b","densified","stride","sampled","segmentCount","spacingMeters","outlineWidthMeters","surfaceRadius","lift","localPos","worldPos","targetPixels","thicknessMeters","thickness","feather","cameraDir","dirUniform","horizonUniform","groupWorldPos","cameraFromCenter","worldCamRadius","worldCamDir","localCamPos","localCamDir","baseRadius","altitudeM","orbitThresholdM","SCREEN_SPACE_ORBIT_EXIT_ALTITUDE_M","SCREEN_SPACE_ORBIT_ENTER_ALTITUDE_M","screenSpaceOrbitCoverageVisible","capAngle","isChunkVisible","threshold","wallsVisible","orbitVisible","hasIso3Filter","hasParentFilter","filtered","normalizedParent","propsToCheck","candidates"],"mappings":"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"}