print("""i need a way to confirm the positions of the planets relative to past data from official sources


=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/index.ts ===

"export { default as SolarSystem } from './src';\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/index.tsx ===

'import React, { useRef, useEffect, useState } from \'react\';\nimport {\n    bodies,\n    checkCapture,\n    DT,\n    calculatePairwiseAcceleration,\n    updateProbe,\n    updatePlanets,\n    launchFromPlanet,\n    initializeSimulationElapsed,\n    computeSpecificEnergy,\n    getBody,\n    getBodyRadiusPx,\n    getBodyEccentricity,\n    getBodyName,\n    getBodyRadius,\n    getBodyMu,\n    isBodyData,\n    getVCirc,\n    derivePositionAndVelocityVector,\n    getBodyIndex,\n    getBodyN,\n    getCurrentStateRef,\n    velocityFromMs,\n    velocityToMs\n} from \'./utils\';\nimport type { BodyData } from \'./interfaces\'\n\nexport function getPositionAndVelocityVector(\n    body: string | BodyData | number | undefined,\n    timeElapsed: number,\n    M0: number = 0,\n    muCentral: number | null = null\n) {\n    body = getBody(body)\n    if (body) {\n        return derivePositionAndVelocityVector(body, timeElapsed, M0, muCentral)\n    }\n}\n\n\nconst SolarSystem = () => {\n    const canvasRef = useRef<HTMLCanvasElement>(null);\n    const runningRef = useRef(true);\n    const speedRef = useRef(1);\n    const zoomRef = useRef(1);\n    const [running, setRunning] = useState(true);\n    const [speed, setSpeed] = useState(50);\n    // Reference start date (user-set) and simulation time offset (in seconds)\n    const [startDate, setStartDate] = useState<Date>(new Date());\n    const [refDate, setRefDate] = useState<Date>(new Date(\'2000-01-01T12:00:00Z\'));\n    const [simTime, setSimTime] = useState(0); // Always start at 0 seconds elapsed\n    const [simOffset, setSimOffset] = useState(startDate - refDate); // Initialize to 0; add UI if needed\n    const [zoom, setZoom] = useState(7);\n    const [velocityUnit, setVelocityUnit] = useState<\'m/s\' | \'km/s\' | \'mph\' | \'ft/s\'>(\'m/s\');\n    const [pan, setPan] = useState({ x: 0, y: 0 });\n    const panStartRef = useRef<{ x: number; y: number } | null>(null);\n    const [autoIdeal, setAutoIdeal] = useState(true);\n    // Refs for probe integration\n    const stateRef = useRef<{ x: number; y: number; vx: number; vy: number }[]>([]);\n    const probeRef = useRef<{ x: number; y: number; vx: number; vy: number }>({ x: 2e11, y: 0, vx: 0, vy: 3e4 });\n    const trailRef = useRef<{ x: number; y: number }[]>([]);\n    const lastTimeRef = useRef(performance.now());\n    const [scale, setScale] = useState(1);\n    const [probeAccels, setProbeAccels] = useState<Array<{ name: string; ax: number; ay: number; mag: number }>>([]);\n    const [selectedPlanet, setSelectedPlanet] = useState<string>(\'Earth\');\n    const [launchSpeed, setLaunchSpeed] = useState(11200);\n    const [launchAngle, setLaunchAngle] = useState(90);\n    const [orbitType, setOrbitType] = useState<\'circular\' | \'elliptical\'>(\'circular\');\n    const [probeEnergy, setProbeEnergy] = useState<number | null>(null);\n    const [showVectors, setShowVectors] = useState<{ [name: string]: boolean }>(\n        bodies.reduce((acc, b) => ({ ...acc, [b.name]: false }), {})\n    );\n    const [lockPlanet, setLockPlanet] = useState(false);\n    const [lockProbe, setLockProbe] = useState(false);\n    const [cursor, setCursor] = useState<\'grab\' | \'grabbing\'>(\'grab\');\n    const panStart = useRef<{ x: number; y: number } | null>(null);\n    const handleMouseDown = (e: React.MouseEvent) => { if (e.button === 0) { panStart.current = { x: e.clientX, y: e.clientY }; setCursor(\'grabbing\'); } };\n    const handleMouseMove = (e: React.MouseEvent) => { if (panStart.current) { const dx = e.clientX - panStart.current.x, dy = e.clientY - panStart.current.y; setPan(p => ({ x: p.x + dx, y: p.y + dy })); panStart.current = { x: e.clientX, y: e.clientY }; } };\n    const handleMouseUp = () => { panStart.current = null; setCursor(\'grab\'); };\n    const handleWheel = (e: React.WheelEvent) => { e.preventDefault(); const factor = 1 - e.deltaY * 0.001; setZoom(z => Math.max(0.01, Math.min(100, z * factor))); };\n    // Update launch speed when planet or orbit type changes\n    useEffect(() => {\n        const vCirc = getVCirc(selectedPlanet);\n        if (vCirc) {\n            setLaunchSpeed(orbitType === \'circular\' ? vCirc : vCirc * 1.2);\n        }\n    }, [selectedPlanet, orbitType]);\n    // Sync refs with state\n    useEffect(() => {\n        runningRef.current = running;\n        speedRef.current = speed;\n        zoomRef.current = zoom;\n    }, [running, speed, zoom]);\n    // Initialize canvas scale\n    useEffect(() => {\n        const c = canvasRef.current;\n        if (c) {\n            c.width = window.innerWidth;\n            c.height = window.innerHeight - 60; // Adjust for navbar\n            const margin = 40;\n            const maxA = Math.max(...bodies.slice(1).map(b => b.a));\n            const s = (Math.min(c.width, c.height) / 2 - margin) / maxA;\n            setScale(s);\n        }\n    }, []);\n    useEffect(() => {\n        if (autoIdeal) {  // Only auto-set if checkbox is checked\n            const vCirc = getVCirc(selectedPlanet);\n            if (vCirc) {\n                setLaunchSpeed(orbitType === \'circular\' ? vCirc : vCirc * 1.2);\n            }\n        }\n    }, [selectedPlanet, orbitType, autoIdeal]);\n    // Compute initial probe state once\n    useEffect(() => {\n        // leave stateRef empty; planets will be computed analytically every frame\n        const defaultProbe = { x: 2e11, y: 0, vx: 0, vy: 3e4 };\n        probeRef.current = defaultProbe;\n        trailRef.current = [];\n    }, []);\n    // Initialize simulation state with real-time positions and stable velocities\n    useEffect(() => {\n        initializeSimulationElapsed(\n            startDate,\n            simOffset,\n            stateRef,\n            setSimTime,\n            probeRef,\n            trailRef,\n            lastTimeRef\n        );\n    }, [startDate, simOffset]);\n    // Draw the simulation\n    const drawSimulation = () => {\n        const c = canvasRef.current;\n        if (!c) return;\n        const ctx = c.getContext(\'2d\');\n        if (!ctx) return;\n        const W = c.width, H = c.height;\n        const ds = scale * zoomRef.current;\n        ctx.setTransform(1, 0, 0, 1, 0, 0);\n        ctx.clearRect(0, 0, W, H);\n        ctx.translate(pan.x + W / 2, pan.y + H / 2);\n        ctx.scale(ds, ds);\n        // Draw orbits\n        bodies.slice(1).forEach(b => {\n            ctx.beginPath();\n            ctx.arc(0, 0, b.a, 0, 2 * Math.PI);\n            ctx.strokeStyle = \'#555\';\n            ctx.lineWidth = 1 / ds;\n            ctx.stroke();\n        });\n        // Draw probe trail\n        if (trailRef.current.length > 1) {\n            ctx.beginPath();\n            trailRef.current.forEach((p, i) => {\n                i === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y);\n            });\n            ctx.strokeStyle = \'rgba(255,255,255,0.5)\';\n            ctx.lineWidth = 1 / ds;\n            ctx.stroke();\n        }\n        // Draw bodies and velocity vectors\n        stateRef.current.forEach((s, i) => {\n            const b = bodies[i];\n            // Draw velocity vectors\n            if (showVectors[b.name]) {\n                const vx = s.vx;\n                const vy = s.vy;\n                const vMag = Math.hypot(vx, vy);\n                if (vMag > 0) {\n                    const vectorLenPx = 50; // Fixed length in pixels for visibility\n                    const headLenPx = 10; // Arrowhead size in pixels\n                    const len = vectorLenPx / ds; // Convert to simulation units\n                    const headLen = headLenPx / ds;\n                    ctx.strokeStyle = b.color;\n                    ctx.lineWidth = 1 / ds;\n                    ctx.beginPath();\n                    ctx.moveTo(s.x, s.y);\n                    ctx.lineTo(s.x + (vx / vMag) * len, s.y + (vy / vMag) * len);\n                    ctx.stroke();\n                    // Arrowhead\n                    const angle = Math.atan2(vy, vx);\n                    [-Math.PI / 6, Math.PI / 6].forEach(theta => {\n                        ctx.beginPath();\n                        ctx.moveTo(\n                            s.x + (vx / vMag) * len,\n                            s.y + (vy / vMag) * len\n                        );\n                        ctx.lineTo(\n                            s.x + (vx / vMag) * len - headLen * Math.cos(angle + theta),\n                            s.y + (vy / vMag) * len - headLen * Math.sin(angle + theta)\n                        );\n                        ctx.stroke();\n                    });\n                }\n            }\n            // Draw bodies\n            ctx.beginPath();\n            ctx.arc(s.x, s.y, b.radiusPx / ds, 0, 2 * Math.PI);\n            ctx.fillStyle = b.color;\n            ctx.fill();\n        });\n        // Draw probe\n        ctx.beginPath();\n        ctx.arc(probeRef.current.x, probeRef.current.y, 5 / ds, 0, 2 * Math.PI);\n        ctx.fillStyle = \'white\';\n        ctx.fill();\n        // Draw acceleration vectors on probe\n        if (probeAccels.length > 0) {\n            ctx.strokeStyle = \'red\';\n            ctx.lineWidth = 2 / ds;\n            const maxMag = Math.max(...probeAccels.map(a => a.mag));\n            probeAccels.forEach(a => {\n                if (a.mag === 0) return;\n                const scaleLen = (a.mag / maxMag) * 50;\n                const dirX = a.ax / a.mag;\n                const dirY = a.ay / a.mag;\n                const dirX_sim = dirX * (scaleLen / ds);\n                const dirY_sim = dirY * (scaleLen / ds);\n                const endX = probeRef.current.x + dirX_sim;\n                const endY = probeRef.current.y + dirY_sim;\n                ctx.beginPath();\n                ctx.moveTo(probeRef.current.x, probeRef.current.y);\n                ctx.lineTo(endX, endY);\n                ctx.stroke();\n                const headLen = 5 / ds;\n                const angle = Math.atan2(dirY_sim, dirX_sim);\n                ctx.beginPath();\n                ctx.moveTo(endX, endY);\n                ctx.lineTo(endX - headLen * Math.cos(angle - Math.PI / 6), endY - headLen * Math.sin(angle - Math.PI / 6));\n                ctx.moveTo(endX, endY);\n                ctx.lineTo(endX - headLen * Math.cos(angle + Math.PI / 6), endY - headLen * Math.sin(angle + Math.PI / 6));\n                ctx.stroke();\n            });\n        }\n    };\n    // Main animation loop\n    useEffect(() => {\n        let rafId: number;\n        function animate(now: number) {\n            lastTimeRef.current = now;\n            const physicsDt = runningRef.current ? DT * speedRef.current : 0;\n            if (runningRef.current) {\n                updateProbe(stateRef, probeRef, physicsDt, runningRef, trailRef);\n                checkCapture(probeRef, stateRef, runningRef);\n                updatePlanets(stateRef, physicsDt);\n                setSimTime(t => t + physicsDt);\n                const accels: Array<{ name: string; ax: number; ay: number; mag: number }> = [];\n                for (let j = 0; j < bodies.length; j++) {\n                    const acc = calculatePairwiseAcceleration(\n                        probeRef.current,\n                        stateRef.current[j],\n                        bodies[j].mu,\n                        bodies[j]\n                    );\n                    const mag = Math.hypot(acc.ax, acc.ay);\n                    accels.push({ name: bodies[j].name, ax: acc.ax, ay: acc.ay, mag });\n                }\n                setProbeAccels(accels);\n                const body = getBody(selectedPlanet) as BodyData;\n                const ε = computeSpecificEnergy(probeRef, stateRef, body);\n                setProbeEnergy(ε);\n            }\n            // Follow lock\n            const ds = scale * zoomRef.current;\n            if (lockPlanet) {\n                const s = getCurrentStateRef(stateRef, selectedPlanet);\n                setPan({ x: -s.x * ds, y: -s.y * ds });\n            } else if (lockProbe) {\n                const pr = probeRef.current;\n                setPan({ x: -pr.x * ds, y: -pr.y * ds });\n            }\n            drawSimulation();\n            rafId = requestAnimationFrame(animate);\n        }\n        lastTimeRef.current = performance.now();\n        rafId = requestAnimationFrame(animate);\n        return () => cancelAnimationFrame(rafId);\n    }, [scale, pan, lockPlanet, lockProbe, selectedPlanet, showVectors]);\n\n    // Launch from planet\n    const handleLaunchPlanet = () => {\n        const θ = (launchAngle * Math.PI) / 180;\n        const vCirc = getVCirc(selectedPlanet)\n        const vLaunch = orbitType === \'circular\' ? vCirc : launchSpeed;\n        launchFromPlanet(probeRef, stateRef, selectedPlanet, vLaunch, θ);\n        trailRef.current = [];\n    };\n    // Launch from arbitrary point\n    const launchFromPoint = (\n        pos: { x: number; y: number },\n        speed: number,\n        angleRad: number\n    ) => {\n        probeRef.current.x = pos.x;\n        probeRef.current.y = pos.y;\n        probeRef.current.vx = speed * Math.cos(angleRad);\n        probeRef.current.vy = speed * Math.sin(angleRad);\n    };\n    const handleUserLaunch = (e: React.MouseEvent) => {\n        e.preventDefault();\n        const pos = screenToSim(e);\n        const θ = (launchAngle * Math.PI) / 180;\n        launchFromPoint(pos, launchSpeed, θ);\n        trailRef.current = [];\n    };\n    // Convert screen to simulation coords\n    const screenToSim = (e: React.MouseEvent) => {\n        const c = canvasRef.current!;\n        const r = c.getBoundingClientRect();\n        const ds = scale * zoomRef.current;\n        const x = (e.clientX - r.left - c.width / 2 - pan.x) / ds;\n        const y = (e.clientY - r.top - c.height / 2 - pan.y - 60) / ds;\n        return { x, y };\n    };\n    // Center on selected planet (one-time)\n    const handleCenterPlanet = () => {\n        if (lockPlanet || lockProbe) return;\n        const s = getCurrentStateRef(stateRef, selectedPlanet);\n        const ds = scale * zoom;\n        setPan({ x: -s.x * ds, y: -s.y * ds });\n    };\n    // Center on probe (one-time)\n    const handleCenterProbe = () => {\n        if (lockPlanet || lockProbe) return;\n        const pr = probeRef.current;\n        const ds = scale * zoom;\n        setPan({ x: -pr.x * ds, y: -pr.y * ds });\n    };\n    // Zoom to planet (make planet radius ~50px on screen)\n    const handleZoomToPlanet = () => {\n        const r = getBodyRadiusPx(selectedPlanet) as number;\n        const desired_px = 50;\n        const ds_desired = desired_px / r;\n        const newZoom = ds_desired / scale;\n        setZoom(newZoom);\n        const s = getCurrentStateRef(stateRef, selectedPlanet);\n        setPan({ x: -s.x * ds_desired, y: -s.y * ds_desired });\n    };\n    // Format simulation time\n    const formatSimTime = () => {\n        const years = Math.floor(simTime / (365.25 * 86400));\n        const t = Math.floor(simTime % (365.25 * 86400));\n        const days = Math.floor(t / 86400);\n        return `${years}y ${days}d`;\n    };\n    const currentSimDate = new Date(startDate.getTime() + simTime * 1000);\n    const formatDate = (d: Date) => d.toISOString().replace(\'T\', \' \').split(\'.\')[0] + \' UTC\';\n    return (\n        <div style={{\n            width: \'100vw\',\n            height: \'calc(100vh - 60px)\',\n            position: \'fixed\',\n            overflow: \'hidden\',\n            background: \'#000\'\n        }}>\n            <canvas\n                ref={canvasRef}\n                width={window.innerWidth}\n                height={window.innerHeight - 60}\n                onContextMenu={handleUserLaunch}\n                onMouseDown={handleMouseDown}\n                onMouseMove={handleMouseMove}\n                onMouseUp={handleMouseUp}\n                onWheel={handleWheel}\n                style={{ display: \'block\', cursor: \'grab\', userSelect: \'none\' }}\n            />\n            {/* Controls Panel */}\n            <div style={{\n                position: \'absolute\',\n                top: 10,\n                left: 10,\n                color: \'#fff\',\n                fontFamily: \'sans-serif\',\n                userSelect: \'none\',\n                WebkitUserSelect: \'none\',\n                MozUserSelect: \'none\',\n                msUserSelect: \'none\'\n            }}>\n                <button onClick={() => setRunning(true)} disabled={running}>Start</button>\n                <button onClick={() => setRunning(false)} disabled={!running}>Pause</button>\n                <button onClick={handleLaunchPlanet}>Launch Planet</button>\n                <button onClick={() => setZoom(z => z * 1.2)}>Zoom In</button>\n                <button onClick={() => setZoom(z => Math.max(0.1, z / 1.2))}>Zoom Out</button>\n                <button onClick={handleCenterPlanet} disabled={lockPlanet || lockProbe}>Center on Planet</button>\n                <label>\n                    <input\n                        type="checkbox"\n                        checked={lockPlanet}\n                        onChange={e => { setLockPlanet(e.target.checked); if (e.target.checked) setLockProbe(false); }}\n                    />\n                    Lock on Planet\n                </label>\n                <button onClick={handleCenterProbe} disabled={lockPlanet || lockProbe}>Center on Probe</button>\n                <label>\n                    <input\n                        type="checkbox"\n                        checked={lockProbe}\n                        onChange={e => { setLockProbe(e.target.checked); if (e.target.checked) setLockPlanet(false); }}\n                    />\n                    Lock on Probe\n                </label>\n                <button onClick={handleZoomToPlanet}>Zoom to Planet</button>\n                <div>Speed: <input type="range" min="0.01" max="100" step="0.01" value={speed} onChange={e => setSpeed(parseFloat(e.target.value))} onWheel={e => setSpeed(parseFloat(e.target.value))} /></div>\n                <label>\n                    Zoom:\n                    <input\n                        type="range"\n                        min="0.01"\n                        max="100"\n                        step="0.01"\n                        value={zoom}\n                        onChange={e => setZoom(parseFloat(e.target.value))}\n                        style={{ verticalAlign: \'middle\', marginLeft: \'8px\' }}\n                    />\n                </label>\n                <div>\n                    <label>\n                        Start Date:\n                        <input\n                            type="date"\n                            value={startDate.toISOString().substr(0, 10)}\n                            onChange={e => setStartDate(new Date(e.target.value + \'T00:00:00Z\'))}\n                            style={{ marginLeft: \'8px\' }}\n                        />\n                    </label>\n                </div>\n                <div>Sim Time: {formatDate(currentSimDate)}</div>\n                <div>Probe Energy: {probeEnergy?.toExponential(2) ?? \'N/A\'} ({probeEnergy !== null ? (probeEnergy < 0 ? \'bound orbit\' : \'escape trajectory\') : \'\'})</div>\n                <div>\n                    <label>\n                        Planet:\n                        <select value={selectedPlanet} onChange={e => setSelectedPlanet(e.target.value)}>\n                            {bodies.slice(1).map(b => (\n                                <option key={b.name} value={b.name}>{b.name}</option>\n                            ))}\n                        </select>\n                    </label>\n                </div>\n                <div>\n                    <label>\n                        Orbit:\n                        <select value={orbitType} onChange={e => setOrbitType(e.target.value as \'circular\' | \'elliptical\')}>\n                            <option value="circular">Circular</option>\n                            <option value="elliptical">Elliptical</option>\n                        </select>\n                    </label>\n                </div>\n                <div>\n\n                    <label>\n                        Launch Speed:\n                        <input\n                            type="number"\n                            value={velocityFromMs(launchSpeed, velocityUnit).toFixed(2)}\n                            onChange={e => setLaunchSpeed(velocityToMs(Number(e.target.value), velocityUnit))}\n                            disabled={autoIdeal}  // Disable manual input when auto is on\n                        />\n                        <select value={velocityUnit} onChange={e => setVelocityUnit(e.target.value as \'m/s\' | \'km/s\' | \'mph\' | \'ft/s\')}>\n                            <option value="m/s">m/s</option>\n                            <option value="km/s">km/s</option>\n                            <option value="mph">mph</option>\n                            <option value="ft/s">ft/s</option>\n                        </select>\n                        <label>\n                            <input\n                                type="checkbox"\n                                checked={autoIdeal}\n                                onChange={e => setAutoIdeal(e.target.checked)}\n                            />\n                            Auto Ideal\n                        </label>\n                    </label>\n                </div>\n                <div>\n                    <label>\n                        Angle:\n                        <input\n                            type="number"\n                            value={launchAngle}\n                            onChange={e => setLaunchAngle(Number(e.target.value))}\n                        />\n                    </label>\n                </div>\n                <h4>Show Vectors</h4>\n                {bodies.slice(1).map(b => (\n                    <label key={b.name} style={{ display: \'block\' }}>\n                        <input\n                            type="checkbox"\n                            checked={showVectors[b.name]}\n                            onChange={e =>\n                                setShowVectors(prev => ({\n                                    ...prev,\n                                    [b.name]: e.target.checked\n                                }))\n                            }\n                        />\n                        {b.name}\n                    </label>\n                ))}\n                <h4>Accelerations</h4>\n                <table style={{ color: \'#fff\', borderCollapse: \'collapse\' }}>\n                    <thead>\n                        <tr>\n                            <th>Body</th>\n                            <th>Ax</th>\n                            <th>Ay</th>\n                            <th>Mag</th>\n                        </tr>\n                    </thead>\n                    <tbody>\n                        {probeAccels.map(a => (\n                            <tr key={a.name}>\n                                <td style={{ padding: \'2px 4px\' }}>{a.name}</td>\n                                <td style={{ padding: \'2px 4px\' }}>{a.ax.toExponential(2)}</td>\n                                <td style={{ padding: \'2px 4px\' }}>{a.ay.toExponential(2)}</td>\n                                <td style={{ padding: \'2px 4px\' }}>{a.mag.toExponential(2)}</td>\n                            </tr>\n                        ))}\n                    </tbody>\n                </table>\n            </div>\n        </div>\n    );\n};\n\nexport default SolarSystem;'


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/interfaces/orbitInterfaces.ts ===

'export interface BodyInit {\n  name: string;\n  color: string;\n  radiusPx: number;\n  orbitRadiusM: number;\n}\n\nexport interface OrbitState {\n  x: number;\n  y: number;\n  vx: number;\n  vy: number;\n}\nexport interface BodyData {\n  name: string;\n  m0_deg: number;\n  mu: number;        // G·M (m³/s²)\n  a: number;         // semi-major axis (m)\n  e: number;         // eccentricity (m)\n  radiusPx: number;  // draw radius (px)\n  color: string;\n  radius: number;\n  escapeVel: number;\n  n: number;\n}\nexport type State = { x: number; y: number; vx: number; vy: number };\nexport type Accel = { ax: number; ay: number };\n// Orbital mechanics calculations (from ellipse.js)\nexport interface OrbitParams {\n  a: number;\n  e: number;\n  p: number;\n  n: number;\n  M0: number;\n}\n\nexport interface PositionAndVelocity {\n  r: number;\n  theta: number;\n  v: number;\n  dist_to_apo: number | null;\n}\n'


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/interfaces/index.ts ===

"export type { OrbitParams, PositionAndVelocity, BodyData, BodyInit, OrbitState, Accel, State } from './orbitInterfaces';\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/index.ts ===

"export * from './constants';\nexport * from './utilities';\nexport * from './functions';"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/utilities/canvas_utils.ts ===

"export const drawSun = (\n  ctx: CanvasRenderingContext2D,\n  cx: number,\n  cy: number\n) => {\n  ctx.beginPath();\n  ctx.arc(cx, cy, 20, 0, 2 * Math.PI);\n  ctx.fillStyle = 'yellow';\n  ctx.fill();\n};\n\nexport const drawBody = (\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  radiusPx: number,\n  color: string\n) => {\n  ctx.beginPath();\n  ctx.arc(x, y, radiusPx, 0, 2 * Math.PI);\n  ctx.fillStyle = color;\n  ctx.fill();\n};\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/utilities/index.ts ===

"export * from './canvas_utils';\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/constants/index.ts ===

"export * from './planets';\nexport * from './satellites';\nexport * from './scale_utils';\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/constants/scale_utils.ts ===

"import {\n    MU_SUN,\n    AU_EARTH,\n    MU_EARTH\n} from './planets';\n//time\nexport const SECOND: number = 1\nexport const MINUTE: number = SECOND * 60;\nexport const HOUR: number = MINUTE * 60;\nexport const DAY: number = HOUR * 24;\nexport const YEAR: number = DAY * 365;\nexport const MONTH: number = YEAR / 12;\n\n//scale\nexport const TIME_SCALE: number = MONTH;\nexport const T_MERCURY: number = 88 * DAY;\n\n//steps\nexport const STEPS_PER_ORBIT: number = 1000;\nexport const DT: number = MINUTE; // e.g. 60 s per step\n\n//length\nexport const MAX_TRAIL_LENGTH: number = 2000;\n\n//surface softening\nexport const SOFTENING: number = 1e8; // Reduced for surface launches\n\n\nexport const toMeters = (v: number, unit: string): number => {\n    switch (unit) {\n        case 'km': return v * 1000;\n        case 'mi': return v * 1609.34;\n        case 'ft': return v * 0.3048;\n        default: return v;\n    }\n};\n\nexport const toSeconds = (v: number, unit: string): number => {\n    switch (unit) {\n        case 'min': return v * 60;\n        case 'h': return v * 3600;\n        case 'day': return v * 86400;\n        default: return v;\n    }\n};\n\nexport const fromMeters = (d: number, unit: string): number => {\n    switch (unit) {\n        case 'km': return d / 1000;\n        case 'mi': return d / 1609.34;\n        case 'ft': return d / 0.3048;\n        default: return d;\n    }\n};\nexport const velocityToMs = (value: number, unit: string): number => {\n    switch (unit) {\n        case 'km/s': return value * 1000;\n        case 'mph': return value * 0.44704;  // 1 mph = 0.44704 m/s\n        case 'ft/s': return value * 0.3048;  // 1 ft/s = 0.3048 m/s\n        default: return value;  // m/s\n    }\n};\n\nexport const velocityFromMs = (value: number, unit: string): number => {\n    switch (unit) {\n        case 'km/s': return value / 1000;\n        case 'mph': return value / 0.44704;\n        case 'ft/s': return value / 0.3048;\n        default: return value;\n    }\n};\nexport const fromMps = (v: number, dist_unit: string, time_unit: string): number => {\n    const dist_conv: number = toMeters(1, dist_unit);\n    const time_conv: number = toSeconds(1, time_unit);\n    return v * (time_conv / dist_conv);\n};\n\n\n/**\n * Convert meters to pixels, based on Earth’s semi-major axis as 1 AU.\n * @param meters - distance in meters\n * @returns equivalent length in pixels\n */\nexport function toPixels(meters: number): number {\n    return (meters / AU_EARTH) * PIXELS_PER_AU;\n}\n\n/**\n * Convert gravitational parameter (m³/s²) to px³/s².\n * @param mu - gravitational parameter in m³/s²\n * @returns equivalent in px³/s²\n */\nexport function mu_m3(mu: number): number {\n    return mu * Math.pow(PIXELS_PER_METER, 3);\n}\n// Unit conversion constants\nexport const PIXELS_PER_AU: number = 130;                // px in 1 AU\nexport const METERS_PER_AU: number = AU_EARTH;\nexport const PIXELS_PER_METER: number = PIXELS_PER_AU / METERS_PER_AU;\nexport const MU_PER_PX: number = mu_m3(MU_SUN);\n\n\n\nexport const getObjUnits = (\n    sm_axis: number,\n    eccentricity: number\n) => {\n    const p: number = sm_axis * (1 - eccentricity ** 2);\n    const T: number = 2 * Math.PI * Math.sqrt(sm_axis ** 3 / MU_EARTH);\n    const n: number = 2 * Math.PI / T;\n    const apo: number = sm_axis * (1 + eccentricity);\n    return { p, T, n, apo };\n};\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/constants/planets.ts ===

'import type { BodyData } from \'./../../interfaces\';\n// Celestial bodies data\nexport const bodies: BodyData[] = [\n    { name: \'Sun\', m0_deg: 0, mu: 1.32712440018e20, a: 0, e: 0, radiusPx: 20, color: \'yellow\', radius: 696000000, escapeVel: 61770, n: 0 },\n    { name: \'Mercury\', m0_deg: 174.79253, mu: 2.20320e13, a: 5.79e10, e: 0.2056, radiusPx: 4, color: \'#a6a6a6\', radius: 2440000, escapeVel: 4300, n: 1 },\n    { name: \'Venus\', m0_deg: 50.37663, mu: 3.24859e14, a: 1.082e11, e: 0.0067, radiusPx: 7, color: \'#e0c16b\', radius: 6052000, escapeVel: 10400, n: 2 },\n    { name: \'Earth\', m0_deg: 357.54, mu: 3.98600e14, a: 1.496e11, e: 0.0167, radiusPx: 8, color: \'#4e6ef2\', radius: 6371000, escapeVel: 11200, n: 3 },\n    { name: \'Mars\', m0_deg: 19.39020, mu: 4.28284e13, a: 2.279e11, e: 0.0934, radiusPx: 6, color: \'#c1440e\', radius: 3390000, escapeVel: 5030, n: 4 },\n    { name: \'Jupiter\', m0_deg: 19.66796, mu: 1.26687e17, a: 7.785e11, e: 0.0489, radiusPx: 14, color: \'#d2a679\', radius: 71492000, escapeVel: 59500, n: 5 },\n    { name: \'Saturn\', m0_deg: 317.35537, mu: 3.79312e16, a: 1.434e12, e: 0.0555, radiusPx: 12, color: \'#e3c168\', radius: 60268000, escapeVel: 35500, n: 6 },\n    { name: \'Uranus\', m0_deg: 142.28383, mu: 5.79394e15, a: 2.872e12, e: 0.0464, radiusPx: 10, color: \'#7fbde8\', radius: 25559000, escapeVel: 21300, n: 7 },\n    { name: \'Neptune\', m0_deg: 259.91521, mu: 6.83653e15, a: 4.495e12, e: 0.0086, radiusPx: 10, color: \'#4363d8\', radius: 24764000, escapeVel: 23500, n: 8 }\n];\n\n// Fast lookup by name (case-insensitive)\nexport const bodyMap: { [key: string]: BodyData } = Object.fromEntries(\n    bodies.map(b => [b.name.toLowerCase(), b])\n);\nexport function isBodyData(x: any): x is BodyData {\n    return (\n        !!x &&\n        typeof x.name === \'string\' &&\n        typeof x.m0_deg === \'number\' &&\n        typeof x.mu === \'number\' &&\n        typeof x.a === \'number\' &&\n        typeof x.e === \'number\' &&\n        typeof x.radiusPx === \'number\' &&\n        typeof x.color === \'string\' &&\n        typeof x.radius === \'number\' &&\n        typeof x.escapeVel === \'number\' &&\n        typeof x.n === \'number\'\n    );\n}\n/**\n * Get a BodyData object by name (case-insensitive).\n * @param name - name of the body (e.g. \'earth\')\n * @returns BodyData or undefined if not found\n */\nexport function getBody(body: string | BodyData | number | undefined): BodyData | undefined {\n    if (typeof body === \'string\') {\n        body = bodyMap[body.toLowerCase()] as BodyData;\n    }\n    if (typeof body === \'number\' && body < bodies.length) {\n        body = bodies[body] as BodyData;\n    }\n    if (isBodyData(body)) {\n        return body as BodyData;\n    }\n\n}\nexport function getBodyIndex(name: string): number {\n    const idx = bodies.findIndex(b => b.name.toLowerCase() === name.toLowerCase());\n    if (idx < 0) throw new Error(`No body named "${name}"`);\n    return idx;\n}\nexport function getBodyMu(body: string | BodyData | number | undefined) {\n    let mu: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        mu = body.mu\n    }\n    return mu;\n}\nexport function getBodyRadius(body: string | BodyData | number | undefined) {\n    let radius: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        radius = body.radius\n    }\n    return radius\n}\nexport function getBodyName(body: string | BodyData | number | undefined) {\n    let name: string = \'\'\n    body = getBody(body) as BodyData;\n    if (body) {\n        name = body.name\n    }\n    return name;\n}\nexport function getBodyEccentricity(body: string | BodyData | number | undefined) {\n    let e: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        e = body.e\n    }\n    return e;\n}\nexport function getBodyRadiusPx(body: string | BodyData | number | undefined) {\n    let radius: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        radius = body.radiusPx\n    }\n    return radius;\n}\nexport function getBodyN(body: string | BodyData | number | undefined) {\n    let n: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        n = body.n\n    }\n    return n\n}\nexport function getVCirc(body: string | BodyData | number | undefined) {\n    let vCirc: any\n    const r = getBodyRadius(body);  // Change to physical radius\n    const mu = getBodyMu(body);\n    if (mu && r) {\n        vCirc = Math.sqrt(mu / r);\n    }\n    return vCirc\n}\n\n//sun\nexport const SUN_BODY: BodyData = getBody(\'sun\')!;\nexport const MU_SUN: number = SUN_BODY.mu;\nexport const AU_SUN: number = SUN_BODY.a;\n\n//earth\nexport const EARTH_BODY: BodyData = getBody(\'earth\')!;\nexport const MU_EARTH: number = EARTH_BODY.mu;\nexport const AU_EARTH: number = EARTH_BODY.a;        // meters in 1 AU\n\n\n\n'


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/constants/satellites.ts ===

"// satellites.ts\nimport { MU_EARTH } from './planets';\nimport type { BodyData } from './../../interfaces';\nimport { getObjUnits } from './scale_utils';\nexport const satellites: BodyData[] = [\n    {\n        name: 'Moon',\n        m0_deg: 0,           // pick your epoch\n        mu: MU_EARTH,        // still Earth’s GM\n        a: 3.844e8,          // m from Earth\n        e: 0.0549,\n        radiusPx: 5,\n        color: 'lightgray',\n        radius: 1.737e6,     // Moon’s physical radius\n        escapeVel: 2380,\n        n: 9\n    },\n    {\n        name: 'ISS',\n        m0_deg: 0,\n        mu: MU_EARTH,\n        a: (6.371e6 + 417e3),\n        e: (422e3 - 413e3) / (422e3 + 413e3),\n        radiusPx: 2,\n        color: 'white',\n        radius: 0,           // negligible\n        escapeVel: 0,\n        n: 10\n    }\n];\n//moon\nexport const a_moon: number = 3.844e8;\nexport const e_moon: number = 0.0549;\nexport const {\n    p: p_moon,\n    T: T_moon,\n    n: n_moon,\n    apo: apo_moon\n} = getObjUnits(\n    a_moon,\n    e_moon);\n\n//iss\nexport const R_e: number = 6.371e6;\nexport const perigee: number = R_e + 413e3;\nexport const apogee: number = R_e + 422e3;\nexport const a_iss: number = (perigee + apogee) / 2;\nexport const e_iss: number = (apogee - perigee) / (perigee + apogee);\nexport const v_iss_mph: number = 17000;\nexport const {\n    p: p_iss,\n    T: T_iss,\n    n: n_iss,\n    apo: apo_iss\n} = getObjUnits(\n    a_iss,\n    e_iss\n);\n\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/functions/orbit_utils.ts ===

"import React from 'react';\nimport type { BodyInit, OrbitState, BodyData, Accel, OrbitParams, State } from './../../interfaces';\nimport { MU_PER_PX, METERS_PER_AU, MU_SUN, MU_EARTH, bodies, SOFTENING, MAX_TRAIL_LENGTH, toMeters, toSeconds, R_e, getBodyN, getBody, getBodyMu } from './../constants';\n\n\nexport function initOrbit(\n  body: BodyInit,\n  cx: number,\n  cy: number\n): OrbitState {\n  const r_px = body.orbitRadiusM * METERS_PER_AU;\n  const v_px_s = Math.sqrt(MU_PER_PX / r_px);\n  return {\n    x: cx + r_px,\n    y: cy,\n    vx: 0,\n    vy: v_px_s\n  };\n}\n\nexport function stepOrbit(\n  state: OrbitState,\n  cx: number,\n  cy: number,\n  dt: number\n): OrbitState {\n  const dx = state.x - cx;\n  const dy = state.y - cy;\n  const dist = Math.hypot(dx, dy);\n  const a = -MU_PER_PX / (dist * dist);\n  const ax = a * (dx / dist);\n  const ay = a * (dy / dist);\n\n  const vx = state.vx + ax * dt;\n  const vy = state.vy + ay * dt;\n  const x = state.x + vx * dt;\n  const y = state.y + vy * dt;\n\n  return { x, y, vx, vy };\n}\nexport function hillRadius(planet) {\n  const a = planet.a;\n  const muP = planet.mu;\n  return a * Math.pow(muP / (3 * MU_SUN), 1 / 3);\n}\n\nexport function checkCapture(probeRef, stateRef, runningRef) {\n  const pr = probeRef.current;\n  bodies.slice(1).forEach((planet, idx) => {\n    const s = stateRef.current[idx + 1];\n    const dx = pr.x - s.x, dy = pr.y - s.y;\n    const r = Math.hypot(dx, dy);\n    const Rsoi = hillRadius(planet);\n    if (r < Rsoi) {\n      const dvx = pr.vx - s.vx, dvy = pr.vy - s.vy;\n      const vRel2 = dvx * dvx + dvy * dvy;\n      const escape2 = 2 * planet.mu / r;\n      if (vRel2 < escape2) {\n        console.log(`🚀 Probe captured by ${planet.name}`);\n\n      }\n    }\n  });\n}\nexport function getMuList() {\n  return bodies.map(b => b.mu)\n}\nexport function calculateHalfDrift(pr, acc, physicsDt) {\n  pr.vx += 0.5 * acc.ax * physicsDt;\n  pr.vy += 0.5 * acc.ay * physicsDt;\n  return pr\n}\n\nexport function calculateDrift(pr, physicsDt) {\n  pr.x += pr.vx * physicsDt;\n  pr.y += pr.vy * physicsDt;\n  return pr\n}\n// Calculate gravitational acceleration between two bodies\nexport const calculatePairwiseAcceleration = (target, other, mu, body?: BodyData) => {\n  const dx = other.x - target.x;\n  const dy = other.y - target.y;\n  const d2 = dx * dx + dy * dy + SOFTENING;\n  const r = Math.sqrt(d2 - SOFTENING);\n\n  if (body && body.a > 0 && r > hillRadius(body)) {\n    return { ax: 0, ay: 0 };\n  }\n\n  const invR3 = 1 / (d2 * Math.sqrt(d2));\n  return { ax: mu * dx * invR3, ay: mu * dy * invR3 };\n};\n// Calculate total acceleration on a target due to all other bodies\nexport const calculateAcceleration = (target, others, bodiesList) => {  // Change muList to bodiesList: BodyData[]\n  let ax = 0, ay = 0;\n  for (let j = 0; j < others.length; j++) {\n    const acc = calculatePairwiseAcceleration(target, others[j], bodiesList[j].mu, bodiesList[j]);\n    ax += acc.ax;\n    ay += acc.ay;\n  }\n  return { ax, ay };\n};\n\n// Update probe using leapfrog integration\nexport const updateProbe = (stateRef, probeRef, physicsDt, runningRef, trailRef) => {\n  const pr = probeRef.current;\n  const acc1 = calculateAcceleration(pr, stateRef.current, bodies);  // Pass bodies array instead of map(b => b.mu)\n  calculateHalfDrift(pr, acc1, physicsDt)\n  calculateDrift(pr, physicsDt)\n  const acc2 = calculateAcceleration(pr, stateRef.current, bodies);  // Pass bodies array instead of map(b => b.mu)\n  calculateHalfDrift(pr, acc2, physicsDt)\n\n  if (runningRef.current) {\n    trailRef.current.push({ x: pr.x, y: pr.y });\n    if (trailRef.current.length > MAX_TRAIL_LENGTH) trailRef.current.shift();\n  }\n};\n\nexport function getN(stateRef) {\n  return stateRef.current.length;\n\n}\nexport function getPr(probeRef) {\n  return probeRef.current;\n}\nexport function getAcc(stateRef) {\n  const n = getN(stateRef)\n  const acc: Accel[] = Array(n).fill(0).map(_ => ({ ax: 0, ay: 0 }));\n  return acc\n}\n\n\n// Update planets using leapfrog integration\nexport const updatePlanets = (\n  stateRef: React.MutableRefObject<\n    Array<{ x: number; y: number; vx: number; vy: number; ax?: number; ay?: number }>\n  >,\n  physicsDt: number\n) => {\n  const S = stateRef.current;\n\n  // Zero out accelerations\n  S.forEach(s => {\n    s.ax = 0;\n    s.ay = 0;\n  });\n\n  // Accumulate pairwise gravitational acceleration\n  for (let i = 0; i < S.length; i++) {\n    for (let j = 0; j < S.length; j++) {\n      if (i === j) continue;\n      const si = S[i];\n      const sj = S[j];\n      const mu = bodies[j].mu;             // use gravitational parameter directly\n\n      const dx = sj.x - si.x;\n      const dy = sj.y - si.y;\n      const r2 = dx * dx + dy * dy;\n      if (r2 < 1e-6) continue;\n      const invR = 1 / Math.sqrt(r2);\n      const aMag = mu / r2;                // mu / r²\n\n      si.ax! += aMag * dx * invR;\n      si.ay! += aMag * dy * invR;\n    }\n  }\n\n  // Integrate velocities and positions (Euler)\n  S.forEach(s => {\n    s.vx += s.ax! * physicsDt;\n    s.vy += s.ay! * physicsDt;\n    s.x += s.vx * physicsDt;\n    s.y += s.vy * physicsDt;\n  });\n};\n\n\n\n\nexport function getCurrentStateRef(stateRef: any, body: string | BodyData | number | undefined) {\n  let s: any\n  const planetIdx = getBodyN(body);\n  if (planetIdx) {\n    s = stateRef.current[planetIdx];\n  }\n  return s\n}\n\n/**\n * Compute the probe’s specific orbital energy relative to body at `bodyIdx`:\n *   ε = ½ v_rel² − μ / r\n * If ε < 0 → bound; ε = 0 → parabolic; ε > 0 → unbound.\n */\nexport function computeSpecificEnergy(\n  probeRef: React.MutableRefObject<State>,\n  stateRef: React.MutableRefObject<State[]>,\n  body: BodyData\n): number {\n  const pr = probeRef.current;\n  const bs = getCurrentStateRef(stateRef, body);\n\n  const μ = getBodyMu(body);\n\n  const dx = pr.x - bs.x;\n  const dy = pr.y - bs.y;\n  const dvx = pr.vx - bs.vx;\n  const dvy = pr.vy - bs.vy;\n\n  const r = Math.hypot(dx, dy);\n  const v2 = dvx * dvx + dvy * dvy;\n\n  return 0.5 * v2 - μ / r;\n}\n/**\n * Place the probe on the surface of `planetIdx` at angle `theta` (rad),\n * then give it a purely tangential kick of magnitude vLaunch (m/s).\n */\nexport function launchFromPlanet(\n  probeRef: React.MutableRefObject<State>,\n  stateRef: React.MutableRefObject<State[]>,\n  planet: string | BodyData | number,\n  vLaunch: number,\n  theta: number\n) {\n  const body = getBody(planet);\n  if (!body) return;\n  const idx = getBodyN(body);\n  const planetState = stateRef.current[idx];\n  const R = body.radius;\n\n  const x0 = planetState.x + R * Math.cos(theta);\n  const y0 = planetState.y + R * Math.sin(theta);\n\n  const ux = -Math.sin(theta);\n  const uy = Math.cos(theta);\n\n  const { vx: pvx, vy: pvy } = planetState;\n\n  probeRef.current = {\n    x: x0,\n    y: y0,\n    vx: pvx + vLaunch * ux,\n    vy: pvy + vLaunch * uy,\n  };\n}\nexport const computeUserOrbit = ({\n  angleDeg,\n  targetAlt,\n  altUnit,\n  targetVel,\n  velDistUnit,\n  velTimeUnit,\n}: {\n  angleDeg: number;\n  targetAlt: number;\n  altUnit: string;\n  targetVel: number;\n  velDistUnit: string;\n  velTimeUnit: string;\n}): OrbitParams => {\n  const φ = angleDeg * Math.PI / 180;\n  const r0 = R_e + toMeters(targetAlt, altUnit);\n  const v0 = toMeters(targetVel, velDistUnit) / toSeconds(1, velTimeUnit);\n  const hSpec = r0 * v0 * Math.cos(φ);\n  const ε = v0 * v0 / 2 - MU_EARTH / r0;\n\n  let a, e, p, n, M0;\n  if (ε < 0) {\n    a = -MU_EARTH / (2 * ε);\n    e = Math.sqrt(1 - hSpec * hSpec / (MU_EARTH * a));\n    p = a * (1 - e * e);\n    n = Math.sqrt(MU_EARTH / (a * a * a));\n    const θ0 = φ + Math.asin(Math.sin(φ) / e);\n    const E0 = 2 * Math.atan(Math.sqrt((1 - e) / (1 + e)) * Math.tan(θ0 / 2));\n    M0 = E0 - e * Math.sin(E0);\n  } else {\n    a = -MU_EARTH / (2 * ε);\n    e = Math.sqrt(1 + hSpec * hSpec / (MU_EARTH * Math.abs(a)));\n    p = a * (1 - e * e);\n    n = Math.sqrt(MU_EARTH / (-a * a * a));\n    const θ0 = φ + Math.asin(Math.sin(φ) / e);\n    const coshH0 = (e + Math.cos(θ0)) / (1 + e * Math.cos(θ0));\n    const H0 = Math.acosh(coshH0);\n    M0 = e * Math.sinh(H0) - H0;\n  }\n\n  return { a, e, p, n, M0 };\n};\n\nexport const computeMoonTransfer = (r1: number, r2: number, μ: number, v0: number) => {\n  const eps = v0 * v0 / 2 - μ / r1;\n  const a = -μ / (2 * eps);\n  const h = r1 * v0;\n  const e = Math.sqrt(1 - h * h / (μ * a));\n  const p = a * (1 - e * e);\n  const n = Math.sqrt(μ / Math.abs(a * a * a));\n  const cosθ2 = (p / r2 - 1) / e;\n\n  if (cosθ2 < -1 || cosθ2 > 1) {\n    return { timeSec: null, distMeters: 0, pivotRad: null };\n  }\n\n  const θ2 = Math.acos(cosθ2);\n  let M2;\n  if (eps < 0) {\n    const E2 = 2 * Math.atan(Math.sqrt((1 - e) / (1 + e)) * Math.tan(θ2 / 2));\n    M2 = E2 - e * Math.sin(E2);\n  } else {\n    const H2 = Math.log(\n      (Math.sqrt(e + 1) + Math.sqrt(e - 1) * Math.tan(θ2 / 2)) /\n      (Math.sqrt(e + 1) - Math.sqrt(e - 1) * Math.tan(θ2 / 2))\n    );\n    M2 = e * Math.sinh(H2) - H2;\n  }\n\n  const timeSec = M2 / n;\n  let distMeters = 0;\n  const steps = 200;\n  for (let i = 0; i <= steps; i++) {\n    const θ = θ2 * (i / steps);\n    const r = p / (1 + e * Math.cos(θ));\n    const drdθ = p * e * Math.sin(θ) / ((1 + e * Math.cos(θ)) ** 2);\n    const ds = Math.hypot(r, drdθ) * (θ2 / steps);\n    distMeters += ds;\n  }\n\n  const vCirc = Math.sqrt(μ / r1);\n  const ratio = Math.min(1, Math.max(-1, vCirc / v0));\n  const pivotRad = Math.acos(ratio);\n\n  return { timeSec, distMeters, pivotRad };\n};\n\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/functions/utilities.ts ===

"import React, { useEffect } from 'react'\nimport { bodies, MU_SUN } from './../constants';\nimport type { PositionAndVelocity } from './../../interfaces';\nimport { BodyData } from '../../interfaces';\n\n// Initialize simulation state with real-time positions and stable velocities\nexport function computeThetas(theta: number) {\n    const cosTheta = Math.cos(theta);\n    const sinTheta = Math.sin(theta);\n    return { cosTheta, sinTheta }\n}\nexport function computeTheta(\n    e: number,\n    E: number\n) {\n    const θ = 2 * Math.atan2(\n        Math.sqrt(1 + e) * Math.sin(E / 2),\n        Math.sqrt(1 - e) * Math.cos(E / 2)\n    );\n    return θ\n}\nexport function computeInstantaneousOrbitalRadius(\n    p: number,\n    e: number,\n    θ: number\n) {\n    const r = p / (1 + e * Math.cos(θ));\n    return r\n}\nexport function computeCurrentMeanAnomaly(\n    n: number,\n    time: number,\n    M0: number\n) {\n    const M = (n * time + M0) % (2 * Math.PI);\n    return M\n}\nexport function computeNewtonRaphsonCorrection(\n    M: number,\n    e: number,\n    E: number\n) {\n    const dE = (M - E + e * Math.sin(E)) / (1 - e * Math.cos(E));\n    return dE;\n}\nexport function computeEccentricAnomaly(\n    M: number,\n    e: number\n) {\n    let E = M;\n    for (let i = 0; i < 50; i++) {\n        const dE = computeNewtonRaphsonCorrection(M, e, E)\n        E += dE;\n        if (Math.abs(dE) < 1e-9) break;\n    }\n    return E\n}\nexport function computeDistanceToApogee(\n    e: number,\n    a: number,\n    r: number\n) {\n    let dist_to_apo = 0;\n    if (e < 1) {\n        dist_to_apo = a * (1 + e) - r;\n    }\n    return dist_to_apo\n}\n\n//PositionAndVelocity\nexport const computePositionAndVelocity = (\n    a: number,\n    e: number,\n    p: number,\n    n: number,\n    time: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n): PositionAndVelocity => {\n    M0 = M0 || 0\n    const M = computeCurrentMeanAnomaly(n, time, M0)\n    let E = computeEccentricAnomaly(M, e)\n    const θ = computeTheta(e, E)\n    const r = computeInstantaneousOrbitalRadius(p, e, θ)\n    const v = computeOrbitalSpeed(r, a, muCentral)\n    const dist_to_apo = computeDistanceToApogee(e, a, r)\n    return { r, theta: θ, v, dist_to_apo };\n};\n\nexport function derivePositionAndVelocity(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const a = body.a;\n    const e = body.e || 0;\n    const p = deriveSemiLatusRectum(body)\n    const n = deriveMeanMotion(body, muCentral)\n    const { r, theta } = computePositionAndVelocity(a, e, p, n, timeElapsed, M0);\n    return { r, theta }\n}\n\n\n\n//OrbitalPeriod\nexport function computeOrbitalPeriod(\n    a: number,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    const T = 2 * Math.PI * Math.sqrt((a ** 3) / muCentral);\n    return T\n}\nexport function deriveOrbitalPeriod(\n    body: BodyData,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    const a = body.a\n    const T = computeOrbitalPeriod(a, muCentral)\n    return T\n}\n\n//MeanMotion\nexport function computeMeanMotion(\n    a: number,\n    muCentral: number | null = null\n) {\n    const T = computeOrbitalPeriod(a, muCentral)\n    const n = 2 * Math.PI / T;\n    return n\n}\nexport function deriveMeanMotion(\n    body: BodyData,\n    muCentral: number | null = null\n) {\n    const T = deriveOrbitalPeriod(body, muCentral)\n    const n = 2 * Math.PI / T;\n    return n\n}\n\n\n//Position\nexport function computePosition(\n    a: number,\n    e: number,\n    p: number,\n    n: number,\n    timeElapsed: number,\n    M0: number | null = 0\n) {\n    const { r, theta } = computePositionAndVelocity(a, e, p, n, timeElapsed, M0)\n    const { cosTheta, sinTheta } = computeThetas(theta)\n    const x = r * cosTheta;\n    const y = r * sinTheta;\n    return { x, y }\n\n}\nexport function derivePosition(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const { r, theta } = derivePositionAndVelocity(body, timeElapsed, M0, muCentral)\n    const { cosTheta, sinTheta } = computeThetas(theta)\n    const x = r * cosTheta;\n    const y = r * sinTheta;\n    return { x, y }\n\n}\n\n//SemiLatusRectum\nexport function computeSemiLatusRectum(\n    a: number,\n    e: number\n) {\n    const p = a * (1 - e * e); // a(1−e2)a(1−e2), the semi-latus rectum.\n    return p\n}\nexport function deriveSemiLatusRectum(\n    body: BodyData,\n) {\n    const a = body.a; //is its semi-major axis aa,\n    const e = body.e; // is its eccentricity ee.\n    const p = computeSemiLatusRectum(a, e)\n    return p\n}\n\n//OrbitalSpeed\nexport function computeOrbitalSpeed(\n    r: number,\n    a: number,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    const v = Math.sqrt(muCentral * (2 / r - 1 / a)); //v = μ(2r−1a)μ(r2\u200b−a1\u200b) , the orbital speed from the vis-viva equation\n    return v\n}\nexport function deriveOrbitalSpeed(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const a = body.a; //is its semi-major axis aa,\n    muCentral = muCentral || MU_SUN\n    M0 = M0 || 0\n    const { r, theta } = derivePositionAndVelocity(body, timeElapsed, M0, muCentral)\n    const v = computeOrbitalSpeed(r, a, muCentral)\n    return v\n}\n\n//SpecificAngularMomentum\nexport function computeSpecificAngularMomentum(\n    p: number,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    const h = Math.sqrt(muCentral * p); // μ\u2009pμp \u200b, the specific angular momentum.\n    return h\n}\nexport function deriveSpecificAngularMomentum(\n    body: any,\n    muCentral: number | null = null\n) {\n    const p = deriveSemiLatusRectum(body)\n    const h = computeSpecificAngularMomentum(p, muCentral)\n    return h\n}\n\n//VelocityVector\nexport function computeVelocityVector(\n    a: number,\n    e: number,\n    p: number,\n    n: number,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    M0 = M0 || 0\n    const { r, theta } = computePositionAndVelocity(a, e, p, n, timeElapsed, M0);\n    const h = computeSpecificAngularMomentum(p, muCentral)\n    const { cosTheta, sinTheta } = computeThetas(theta)\n    const vx = -(h / r) * sinTheta; // components of the velocity vector in the orbital plane, given by vx=−hr\u2009sin\u2061θ\n    const vy = (h / r) * (e + cosTheta); // components of the velocity vector in the orbital plane, given by vy=hr\u2009(e+cos\u2061θ).\n    return { vx, vy }\n}\nexport function deriveVelocityVector(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const a = body.a; //is its semi-major axis aa,\n    const e = body.e; // is its eccentricity ee.\n    const p = deriveSemiLatusRectum(body)\n    //const v = deriveOrbitalSpeed(body, timeElapsed, muCentral, M0)\n    //const h = deriveSpecificAngularMomentum(body,muCentral)\n    const n = deriveMeanMotion(body, muCentral)\n    const { vx, vy } = computeVelocityVector(a, e, p, n, timeElapsed, M0, muCentral)\n    return { vx, vy }\n}\n\n//PositionAndVelocityVector\nexport function computePositionAndVelocityVector(\n    a: number,\n    e: number,\n    p: number,\n    n: number,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const { x, y } = computePosition(a, e, p, n, timeElapsed, M0)\n    // Compute velocity using vis-viva equation and correct orientation\n    const { vx, vy } = computeVelocityVector(a, e, p, n, timeElapsed, M0, muCentral)\n    return { x, y, vx, vy };\n}\nexport function derivePositionAndVelocityVector(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number = 0,\n    muCentral: number | null = null\n) {\n    const { x, y } = derivePosition(body, timeElapsed, M0, muCentral)\n    // Compute velocity using vis-viva equation and correct orientation\n    const { vx, vy } = deriveVelocityVector(body, timeElapsed, M0, muCentral)\n    return { x, y, vx, vy };\n}\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/functions/index.ts ===

"export * from './initialize_utils';\nexport * from './orbit_utils';\nexport * from './utilities';\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/orbitSimulator/src/utils/functions/initialize_utils.ts ===

"import React from 'react';\nimport { bodies } from './../constants'\nimport { derivePositionAndVelocityVector } from './utilities';\n// Initialize simulation state\nexport const initializeSimulation = (\n  startDate,\n  simOffset,\n  stateRef,\n  setSimTime,\n  probeRef,\n  trailRef,\n  lastTimeRef) => {\n  if (stateRef?.current) {\n    stateRef.current = bodies.map((b, i) => {\n      if (i === 0) return { x: 0, y: 0, vx: 0, vy: 0 };\n      const ω = Math.sqrt(bodies[0].mu / (b.a ** 3));\n      return { x: b.a, y: 0, vx: 0, vy: ω * b.a };\n    });\n    probeRef.current = { x: 2e11, y: 0, vx: 0, vy: 3e4 };\n    trailRef.current = [];\n    setSimTime(0);\n    lastTimeRef.current = performance.now();\n  }\n};\n/**\n * Re-initializes all planet & probe state at the chosen start date + offset.\n *\n * @param startDate  The calendar date chosen by the user\n * @param simOffset  Seconds of extra offset (can be negative) from startDate\n * @param stateRef   React ref for planet state array\n * @param setSimTime Setter for simTime (resets to zero)\n * @param probeRef   React ref for your probe object\n * @param trailRef   React ref for your probe trail\n * @param lastTimeRef React ref for performance.now() baseline\n */\nexport function initializeSimulationElapsed(\n  startDate: Date,\n  simOffset: number,\n  stateRef: React.MutableRefObject<any[]>,\n  setSimTime: React.Dispatch<React.SetStateAction<number>>,\n  probeRef: React.MutableRefObject<any>,\n  trailRef: React.MutableRefObject<any[]>,\n  lastTimeRef: React.MutableRefObject<number>\n) {\n  // 1) compute epoch of J2000 in seconds\n  const epochJ2000 = new Date('2000-01-01T12:00:00Z').getTime() / 1000;\n\n  // 2) compute your chosen start instant in seconds\n  const startEpochSec = (startDate.getTime() / 1000) + simOffset;\n\n  // 3) elapsed seconds since J2000\n  const timeElapsed = startEpochSec - epochJ2000;\n\n  stateRef.current = bodies.map((b, i) => {\n    if (i === 0) return { x: 0, y: 0, vx: 0, vy: 0 };\n    const { x, y, vx, vy } = derivePositionAndVelocityVector(\n      b,\n      timeElapsed,\n      (b.m0_deg ?? 0) * Math.PI / 180,\n      bodies[0].mu\n    );\n    return { x, y, vx, vy };\n  });\n\n  // 5) reset probe & trail\n  probeRef.current = { x: 2e11, y: 0, vx: 0, vy: 3e4 };\n  trailRef.current = [];\n\n  // 6) reset simTime counter and timestamp\n  setSimTime(0);\n  lastTimeRef.current = performance.now();\n}\n"


――――――――――――――――――
""")
