diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de9ee66 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local +coverage + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/i18n/en.js b/i18n/en.js new file mode 100644 index 0000000..3807763 --- /dev/null +++ b/i18n/en.js @@ -0,0 +1,474 @@ +// i18n/en.js - English Translations + +export const en = { + // UI Controls and Buttons + ui: { + controls: { + missionControl: "Mission Control", + speed: "Speed (Earth Time)", + pause: "Pause", + resume: "Resume", + reset: "Reset", + hideUI: "Hide UI", + showUI: "Show UI", + cameraControl: "Camera Control", + atmosphere: "Atmosphere", + music: "🎵 Music", + mute: "🔇 Mute", + toggle: "Toggle", + orbits: "Orbits", + moons: "Moons", + bloom: "Bloom", + realAsteroids: "Real Asteroids", + comets: "Comets", + asteroidBelts: "Asteroid Belts", + allBelts: "All Belts", + mainBelt: "Main Belt", + trojans: "Trojans", + kuiper: "Kuiper", + scattered: "Scattered", + autoBloom: "Auto Bloom", + manualBloom: "Manual Bloom", + language: "Language" + }, + labels: { + realearthtime: "0x Real Earth Time", + slowearthtime: "x Slow", + fastearthtime: "x Fast", + discovered: "Discovered", + distance: "Distance", + size: "Size", + unknown: "Unknown", + planetRadii: 'planet radii', + follow: "Follow" + }, + + celestialBodies: "Celestial Bodies", + showPlanetNames: "Show Planet Names", + hidePlanetNames: "Hide Planet Names", + showMoonNames: "Show Moon Names", + hideMoonNames: "Hide Moon Names", + + categories: { + planets: "🪐 PLANETS", + dwarfPlanets: "🌍 DWARF PLANETS", + majorAsteroids: "☄️ MAJOR ASTEROIDS", + transNeptunianObjects: "🌌 TRANS-NEPTUNIAN OBJECTS" + }, + + categoriesNoEmoji: { + planets: "PLANETS", + dwarfPlanets: "DWARF PLANETS", + majorAsteroids: "MAJOR ASTEROIDS", + transNeptunianObjects: "TRANS-NEPTUNIAN OBJECTS", + celestialBody: "CELESTIAL BODY" + }, + + planetInfo: { + orbitalPeriod: "Orbital Period", + sizeRelative: "Size (Relative to Earth)", + distanceFromSun: "Distance from Sun", + discoveryYear: "Discovery Year", + controls: "🎮 Controls", + followPlanet: "🎯 FOLLOW PLANET", + stopFollowing: "🛑 STOP FOLLOWING", + followSun: "☀️ Follow Sun", + + controlsInfo: { + mouse: "Mouse: Orbit around object", + scroll: "Scroll: Zoom in/out", + reset: "R key or Reset: Stop following", + orbits: "O key: Toggle glowing orbits" + } + } + }, + + // Planet and celestial body information + planets: { + sun: { + name: "Sun", + info: "The Sun is the star at the center of the Solar System." + }, + + mercury: { + name: "Mercury", + info: "Closest planet to the Sun. Surface temperatures range from -173°C to 427°C. Has no atmosphere and no moons." + }, + + venus: { + name: "Venus", + info: "Hottest planet in our solar system with surface temperatures of 462°C. Has a thick, toxic atmosphere of carbon dioxide." + }, + + earth: { + name: "Earth", + info: "The only known planet with life. 71% of surface covered by water. Has one natural satellite." + }, + + mars: { + name: "Mars", + info: "The Red Planet. Has the largest volcano (Olympus Mons) and canyon (Valles Marineris) in the solar system." + }, + + jupiter: { + name: "Jupiter", + info: "Largest planet in our solar system. Great Red Spot is a storm larger than Earth. Has 95 known moons." + }, + + saturn: { + name: "Saturn", + info: "Famous for its prominent ring system. Less dense than water. Has 146 known moons." + }, + + uranus: { + name: "Uranus", + info: "Ice giant tilted on its side (98° axial tilt). Has faint rings and 28 known moons." + }, + + neptune: { + name: "Neptune", + info: "Windiest planet with speeds up to 2,100 km/h. Deep blue color from methane in atmosphere." + }, + + // Dwarf Planets + ceres: { + name: "Ceres", + info: "Largest object in asteroid belt. Has water ice and possible subsurface ocean. Visited by Dawn spacecraft." + }, + + pluto: { + name: "Pluto", + info: "Former ninth planet. Has heart-shaped nitrogen plains. Binary system with Charon." + }, + + eris: { + name: "Eris", + info: "Most massive dwarf planet. Discovery led to Pluto's reclassification. Very reflective surface." + }, + + makemake: { + name: "Makemake", + info: "Third-largest dwarf planet. Reddish surface likely due to organic compounds. No atmosphere." + }, + + haumea: { + name: "Haumea", + info: "Elongated dwarf planet that spins every 4 hours. Has ring system and crystalline water ice surface." + }, + + sedna: { + name: "Sedna", + info: "Extremely distant object in extended scattered disk. Takes 11,400 years to orbit the Sun." + }, + + quaoar: { + name: "Quaoar", + info: "Classical Kuiper Belt object. Has ring system and one known moon." + }, + + orcus: { + name: "Orcus", + info: "Plutino in 2:3 resonance with Neptune. Sometimes called 'anti-Pluto'." + }, + + gonggong: { + name: "Gonggong", + info: "Red-colored scattered disk object. Has slow rotation period of 22 hours." + }, + + varuna: { + name: "Varuna", + info: "Large classical Kuiper Belt object. Elongated shape with rapid rotation." + }, + + ixion: { + name: "Ixion", + info: "Plutino with very red surface. May have experienced thermal evolution." + }, + + salacia: { + name: "Salacia", + info: "Large trans-Neptunian object with a known moon." + }, + + or10: { + name: "2007 OR10", + info: "One of the largest known dwarf planets, very red in color." + }, + + vesta: { + name: "Vesta", + info: "Second-largest asteroid. Has a differentiated interior with basaltic surface. Visited by Dawn spacecraft." + }, + + pallas: { + name: "Pallas", + info: "Third-largest asteroid. Highly inclined orbit. Possibly a protoplanet." + } + }, + + // Moon information + moons: { + moon: { + name: "Moon", + info: "Earth's only natural satellite. Formed 4.5 billion years ago." + }, + + phobos: { + name: "Phobos", + info: "Largest moon of Mars. Orbits Mars 3 times per day." + }, + + deimos: { + name: "Deimos", + info: "Smaller, outer moon of Mars. Takes 30 hours to orbit Mars." + }, + + io: { + name: "Io", + info: "Most volcanically active body in the solar system." + }, + + europa: { + name: "Europa", + info: "Ice-covered moon with subsurface ocean. Potential for life." + }, + + ganymede: { + name: "Ganymede", + info: "Largest moon in the solar system. Has its own magnetic field." + }, + + callisto: { + name: "Callisto", + info: "Most heavily cratered body in the solar system." + }, + + amalthea: { + name: "Amalthea", + info: "Fifth largest moon of Jupiter. Irregular potato shape." + }, + + himalia: { + name: "Himalia", + info: "Largest irregular moon of Jupiter." + }, + + lysithea: { + name: "Lysithea", + info: "Small irregular moon in Jupiter's prograde group." + }, + + elara: { + name: "Elara", + info: "Irregular moon discovered in 1905." + }, + + mimas: { + name: "Mimas", + info: "Death Star-like appearance with giant Herschel crater." + }, + + titan: { + name: "Titan", + info: "Has thick atmosphere and liquid methane lakes." + }, + + enceladus: { + name: "Enceladus", + info: "Ice geysers from south pole. Subsurface ocean." + }, + + tethys: { + name: "Tethys", + info: "Heavily cratered icy moon with large Odysseus crater." + }, + + dione: { + name: "Dione", + info: "Ice cliffs and wispy terrain on trailing hemisphere." + }, + + rhea: { + name: "Rhea", + info: "Second largest moon of Saturn with thin oxygen atmosphere." + }, + + hyperion: { + name: "Hyperion", + info: "Chaotic rotation and sponge-like appearance." + }, + + iapetus: { + name: "Iapetus", + info: "Two-tone coloration, dark leading hemisphere." + }, + + phoebe: { + name: "Phoebe", + info: "Retrograde irregular moon, likely captured asteroid." + }, + + ariel: { + name: "Ariel", + info: "Youngest surface among Uranian moons with fault valleys." + }, + + umbriel: { + name: "Umbriel", + info: "Darkest of Uranus's major moons." + }, + + titania: { + name: "Titania", + info: "Largest moon of Uranus with deep canyons." + }, + + oberon: { + name: "Oberon", + info: "Outermost major moon with ancient cratered surface." + }, + + miranda: { + name: "Miranda", + info: "Most unusual moon with extreme geological features." + }, + + puck: { + name: "Puck", + info: "Small irregular moon discovered by Voyager 2." + }, + + triton: { + name: "Triton", + info: "Largest moon of Neptune. Orbits retrograde. Nitrogen geysers." + }, + + nereid: { + name: "Nereid", + info: "Highly eccentric orbit, likely captured Kuiper Belt object." + }, + + proteus: { + name: "Proteus", + info: "Largest irregular-shaped moon of Neptune." + }, + + larissa: { + name: "Larissa", + info: "Small inner moon discovered by Voyager 2." + }, + + charon: { + name: "Charon", + info: "Largest moon relative to its parent planet. Tidally locked to Pluto." + }, + + dysnomia: { + name: "Dysnomia", + info: "Only known moon of Eris." + }, + + mk2: { + name: "MK 2", + info: "Small, dark moon of Makemake." + }, + + hiiaka: { + name: "Hi'iaka", + info: "Larger moon of Haumea." + }, + + namaka: { + name: "Namaka", + info: "Smaller, inner moon of Haumea." + }, + + weywot: { + name: "Weywot", + info: "Moon of Quaoar." + }, + + vanth: { + name: "Vanth", + info: "Large moon of Orcus." + }, + + xiangliu: { + name: "Xiangliu", + info: "Moon of Gonggong." + }, + + actaea: { + name: "Actaea", + info: "Moon of Salacia, discovered in 2006." + }, + + s2016: { + name: "S/2016 (225088) 1", + info: "Small moon of 2007 OR10." + } + }, + + // Units and measurements + units: { + au: "AU", + years: "years", + days: "days", + period: "period", + earthMass: "Earth", + volume: "Volume" + }, + + // Messages and notifications + messages: { + allTexturesLoaded: "All textures loaded!", + errorLoadingTexture: "Error loading texture:", + neoApiError: "NEO API error:", + sentryApiError: "Sentry API error:", + cometApiError: "Comet API error:", + musicStarted: "Interstellar soundtrack started", + musicStopped: "Music stopped", + atmosphericAudioStarted: "Atmospheric audio started", + nowFollowing: "Now following {planet}", + stoppedFollowing: "Stopped following and reset view", + followingSun: "Now following the Sun (zoom enabled)", + audioNotAvailable: "🎵 Audio not available\n\nFor the best experience, try:\n• Check your browser audio settings\n• Ensure audio is not blocked\n• Try a different browser" + }, + + // Keyboard shortcuts + keyboard: { + spacebar: "Spacebar to pause/resume", + r: "R to reset view", + f: "F to stop following planet", + o: "O to toggle orbits", + a: "A to cycle through asteroid belt types", + m: "M to toggle moons", + h: "H to toggle UI visibility", + p: "P to toggle music", + plus: "+ to increase speed", + minus: "- to decrease speed", + b: "B to toggle bloom mode" + }, + + // Info panel + info: { + title: "NASA SOLAR EXPLORER", + stats: { + planets: "🪐 8 Planets", + dwarfPlanets: "🌍 11 Dwarf Planets", + asteroidBelts: "☄️ 4 Asteroid Belts", + transNeptunianObjects: "🌌 Trans-Neptunian Objects", + moons: "🌙 50+ Moons", + glowingOrbits: "✨ Glowing Orbit Rings", + atmosphericMusic: "🎵 Atmospheric Music", + realTimeData: "🛰️ Real-time NASA Data" + } + }, + + // Footer + footer: { + madeWith: "Made With 💙 By", + developers: "Soumya X Subarna" + } +}; \ No newline at end of file diff --git a/i18n/fr.js b/i18n/fr.js new file mode 100644 index 0000000..2a112ea --- /dev/null +++ b/i18n/fr.js @@ -0,0 +1,474 @@ +// i18n/fr.js - French Translations + +export const fr = { + // UI Controls and Buttons + ui: { + controls: { + missionControl: "Contrôle Mission", + speed: "Vitesse (Temps Terrestre)", + pause: "Pause", + resume: "Reprendre", + reset: "Réinitialiser", + hideUI: "Masquer Interface", + showUI: "Afficher Interface", + cameraControl: "Contrôle Caméra", + atmosphere: "Atmosphère", + music: "🎵 Musique", + mute: "🔇 Muet", + toggle: "Basculer", + orbits: "Orbites", + moons: "Lunes", + bloom: "Luminosité", + realAsteroids: "Astéroïdes Réels", + comets: "Comètes", + asteroidBelts: "Ceintures d'Astéroïdes", + allBelts: "Toutes les Ceintures", + mainBelt: "Ceinture Principale", + trojans: "Troyens", + kuiper: "Kuiper", + scattered: "Dispersés", + autoBloom: "Luminosité Auto", + manualBloom: "Luminosité Manuelle", + language: "Langue" + }, + labels: { + realearthtime: "0x Temps Terrestre Réel", + slowearthtime: "x Lent", + fastearthtime: "x Rapide", + discovered: "Découvert", + distance: "Distance", + size: "Taille", + unknown: "Inconnu", + planetRadii: 'rayon de planète', + follow: "Suivre" + }, + + celestialBodies: "Corps Célestes", + showPlanetNames: "Afficher Noms Planètes", + hidePlanetNames: "Masquer Noms Planètes", + showMoonNames: "Afficher Noms Lunes", + hideMoonNames: "Masquer Noms Lunes", + + categories: { + planets: "🪐 PLANÈTES", + dwarfPlanets: "🌍 PLANÈTES NAINES", + majorAsteroids: "☄️ ASTÉROÏDES MAJEURS", + transNeptunianObjects: "🌌 OBJETS TRANS-NEPTUNIENS" + }, + + categoriesNoEmoji: { + planets: "PLANÈTES", + dwarfPlanets: "PLANÈTES NAINES", + majorAsteroids: "ASTÉROÏDES PRINCIPAUX", + transNeptunianObjects: "OBJETS TRANS-NEPTUNIENS", + celestialBody: "OBJET CELESTE" + }, + + planetInfo: { + orbitalPeriod: "Période Orbitale", + sizeRelative: "Taille (Relative à la Terre)", + distanceFromSun: "Distance du Soleil", + discoveryYear: "Année de Découverte", + controls: "🎮 Contrôles", + followPlanet: "🎯 SUIVRE PLANÈTE", + stopFollowing: "🛑 ARRÊTER SUIVI", + followSun: "☀️ Suivre Soleil", + + controlsInfo: { + mouse: "Souris : Tourner autour de l'objet", + scroll: "Molette : Zoomer/Dézoomer", + reset: "Touche R ou Reset : Arrêter le suivi", + orbits: "Touche O : Basculer orbites lumineuses" + } + } + }, + + // Planet and celestial body information + planets: { + sun: { + name: "Soleil", + info: "Le Soleil est l'étoile au centre du système solaire." + }, + + mercury: { + name: "Mercure", + info: "Planète la plus proche du Soleil. Températures de surface de -173°C à 427°C. N'a pas d'atmosphère ni de lunes." + }, + + venus: { + name: "Vénus", + info: "Planète la plus chaude de notre système solaire avec des températures de 462°C. Possède une atmosphère épaisse et toxique de dioxyde de carbone." + }, + + earth: { + name: "Terre", + info: "La seule planète connue avec la vie. 71% de la surface couverte d'eau. Possède un satellite naturel." + }, + + mars: { + name: "Mars", + info: "La Planète Rouge. Possède le plus grand volcan (Olympus Mons) et canyon (Valles Marineris) du système solaire." + }, + + jupiter: { + name: "Jupiter", + info: "Plus grande planète de notre système solaire. La Grande Tache Rouge est une tempête plus grande que la Terre. Possède 95 lunes connues." + }, + + saturn: { + name: "Saturne", + info: "Célèbre pour son système d'anneaux proéminent. Moins dense que l'eau. Possède 146 lunes connues." + }, + + uranus: { + name: "Uranus", + info: "Géante de glace inclinée sur le côté (inclinaison axiale de 98°). Possède des anneaux faibles et 28 lunes connues." + }, + + neptune: { + name: "Neptune", + info: "Planète la plus venteuse avec des vitesses jusqu'à 2 100 km/h. Couleur bleu profond due au méthane dans l'atmosphère." + }, + + // Dwarf Planets + ceres: { + name: "Cérès", + info: "Plus gros objet de la ceinture d'astéroïdes. Possède de la glace d'eau et possiblement un océan souterrain. Visitée par la sonde Dawn." + }, + + pluto: { + name: "Pluton", + info: "Ancienne neuvième planète. Possède des plaines d'azote en forme de cœur. Système binaire avec Charon." + }, + + eris: { + name: "Éris", + info: "Planète naine la plus massive. Sa découverte a mené à la reclassification de Pluton. Surface très réfléchissante." + }, + + makemake: { + name: "Makemake", + info: "Troisième plus grande planète naine. Surface rougeâtre probablement due aux composés organiques. Pas d'atmosphère." + }, + + haumea: { + name: "Haumea", + info: "Planète naine allongée qui tourne toutes les 4 heures. Possède un système d'anneaux et une surface de glace d'eau cristalline." + }, + + sedna: { + name: "Sedna", + info: "Extremely distant object in extended scattered disk. Takes 11,400 years to orbit the Sun." + }, + + quaoar: { + name: "Quaoar", + info: "Classical Kuiper Belt object. Has ring system and one known moon." + }, + + orcus: { + name: "Orcus", + info: "Plutino in 2:3 resonance with Neptune. Sometimes called 'anti-Pluto'." + }, + + gonggong: { + name: "Gonggong", + info: "Red-colored scattered disk object. Has slow rotation period of 22 hours." + }, + + varuna: { + name: "Varuna", + info: "Large classical Kuiper Belt object. Elongated shape with rapid rotation." + }, + + ixion: { + name: "Ixion", + info: "Plutino with very red surface. May have experienced thermal evolution." + }, + + salacia: { + name: "Salacia", + info: "Large trans-Neptunian object with a known moon." + }, + + or10: { + name: "2007 OR10", + info: "One of the largest known dwarf planets, very red in color." + }, + + vesta: { + name: "Vesta", + info: "Second-largest asteroid. Has a differentiated interior with basaltic surface. Visited by Dawn spacecraft." + }, + + pallas: { + name: "Pallas", + info: "Third-largest asteroid. Highly inclined orbit. Possibly a protoplanet." + }, + }, + + // Moon information + moons: { + moon: { + name: "Lune", + info: "Seul satellite naturel de la Terre. Formée il y a 4,5 milliards d'années." + }, + + phobos: { + name: "Phobos", + info: "Plus grande lune de Mars. Orbite Mars 3 fois par jour." + }, + + deimos: { + name: "Déimos", + info: "Lune plus petite et extérieure de Mars. Prend 30 heures pour orbiter Mars." + }, + + io: { + name: "Io", + info: "Corps le plus volcaniquement actif du système solaire." + }, + + europa: { + name: "Europe", + info: "Lune couverte de glace avec océan souterrain. Potentiel pour la vie." + }, + + ganymede: { + name: "Ganymède", + info: "Plus grande lune du système solaire. Possède son propre champ magnétique." + }, + + callisto: { + name: "Callisto", + info: "Corps le plus criblé de cratères du système solaire." + }, + + amalthea: { + name: "Amalthea", + info: "Fifth largest moon of Jupiter. Irregular potato shape." + }, + + himalia: { + name: "Himalia", + info: "Largest irregular moon of Jupiter." + }, + + lysithea: { + name: "Lysithea", + info: "Small irregular moon in Jupiter's prograde group." + }, + + elara: { + name: "Elara", + info: "Irregular moon discovered in 1905." + }, + + mimas: { + name: "Mimas", + info: "Death Star-like appearance with giant Herschel crater." + }, + + titan: { + name: "Titan", + info: "Possède une atmosphère épaisse et des lacs de méthane liquide." + }, + + enceladus: { + name: "Encelade", + info: "Geysers de glace du pôle sud. Océan souterrain." + }, + + tethys: { + name: "Tethys", + info: "Heavily cratered icy moon with large Odysseus crater." + }, + + dione: { + name: "Dione", + info: "Ice cliffs and wispy terrain on trailing hemisphere." + }, + + rhea: { + name: "Rhea", + info: "Second largest moon of Saturn with thin oxygen atmosphere." + }, + + hyperion: { + name: "Hyperion", + info: "Chaotic rotation and sponge-like appearance." + }, + + iapetus: { + name: "Iapetus", + info: "Two-tone coloration, dark leading hemisphere." + }, + + phoebe: { + name: "Phoebe", + info: "Retrograde irregular moon, likely captured asteroid." + }, + + ariel: { + name: "Ariel", + info: "Youngest surface among Uranian moons with fault valleys." + }, + + umbriel: { + name: "Umbriel", + info: "Darkest of Uranus's major moons." + }, + + titania: { + name: "Titania", + info: "Largest moon of Uranus with deep canyons." + }, + + oberon: { + name: "Oberon", + info: "Outermost major moon with ancient cratered surface." + }, + + miranda: { + name: "Miranda", + info: "Most unusual moon with extreme geological features." + }, + + puck: { + name: "Puck", + info: "Small irregular moon discovered by Voyager 2." + }, + + triton: { + name: "Triton", + info: "Plus grande lune de Neptune. Orbite rétrograde. Geysers d'azote." + }, + + nereid: { + name: "Nereid", + info: "Highly eccentric orbit, likely captured Kuiper Belt object." + }, + + proteus: { + name: "Proteus", + info: "Largest irregular-shaped moon of Neptune." + }, + + larissa: { + name: "Larissa", + info: "Small inner moon discovered by Voyager 2." + }, + + charon: { + name: "Charon", + info: "Largest moon relative to its parent planet. Tidally locked to Pluto." + }, + + dysnomia: { + name: "Dysnomia", + info: "Only known moon of Eris." + }, + + mk2: { + name: "MK 2", + info: "Small, dark moon of Makemake." + }, + + hiiaka: { + name: "Hi'iaka", + info: "Larger moon of Haumea." + }, + + namaka: { + name: "Namaka", + info: "Smaller, inner moon of Haumea." + }, + + weywot: { + name: "Weywot", + info: "Moon of Quaoar." + }, + + vanth: { + name: "Vanth", + info: "Large moon of Orcus." + }, + + xiangliu: { + name: "Xiangliu", + info: "Moon of Gonggong." + }, + + actaea: { + name: "Actaea", + info: "Moon of Salacia, discovered in 2006." + }, + + s2016: { + name: "S/2016 (225088) 1", + info: "Small moon of 2007 OR10." + } + }, + + // Units and measurements + units: { + au: "UA", + years: "années", + days: "jours", + period: "période", + earthMass: "Terre", + volume: "Volume" + }, + + // Messages and notifications + messages: { + allTexturesLoaded: "Toutes les textures chargées !", + errorLoadingTexture: "Erreur lors du chargement de la texture :", + neoApiError: "Erreur API NEO :", + sentryApiError: "Erreur API Sentry :", + cometApiError: "Erreur API comète :", + musicStarted: "Bande sonore Interstellar démarrée", + musicStopped: "Musique arrêtée", + atmosphericAudioStarted: "Audio atmosphérique démarré", + nowFollowing: "Maintenant en train de suivre {planet}", + stoppedFollowing: "Arrêt du suivi et réinitialisation de la vue", + followingSun: "Maintenant en train de suivre le Soleil (zoom activé)", + audioNotAvailable: "🎵 Audio non disponible\n\nPour une meilleure expérience, essayez :\n• Vérifiez les paramètres audio de votre navigateur\n• Assurez-vous que l'audio n'est pas bloqué\n• Essayez un autre navigateur" + }, + + // Keyboard shortcuts + keyboard: { + spacebar: "Barre d'espace pour pause/reprendre", + r: "R pour réinitialiser la vue", + f: "F pour arrêter de suivre la planète", + o: "O pour basculer les orbites", + a: "A pour parcourir les types de ceintures d'astéroïdes", + m: "M pour basculer les lunes", + h: "H pour basculer la visibilité de l'interface", + p: "P pour basculer la musique", + plus: "+ pour augmenter la vitesse", + minus: "- pour diminuer la vitesse", + b: "B pour basculer le mode luminosité" + }, + + // Info panel + info: { + title: "EXPLORATEUR SOLAIRE NASA", + stats: { + planets: "🪐 8 Planètes", + dwarfPlanets: "🌍 11 Planètes Naines", + asteroidBelts: "☄️ 4 Ceintures d'Astéroïdes", + transNeptunianObjects: "🌌 Objets Trans-Neptuniens", + moons: "🌙 50+ Lunes", + glowingOrbits: "✨ Anneaux d'Orbite Lumineux", + atmosphericMusic: "🎵 Musique Atmosphérique", + realTimeData: "🛰️ Données NASA en Temps Réel" + } + }, + + // Footer + footer: { + madeWith: "Crée avec 💙 Par", + developers: "Soumya X Subarna" + } +}; \ No newline at end of file diff --git a/i18n/index.js b/i18n/index.js new file mode 100644 index 0000000..230a297 --- /dev/null +++ b/i18n/index.js @@ -0,0 +1,89 @@ +// i18n/index.js - Main Internationalization Logic + +let currentLanguage = 'en'; +let translations = {}; + +// Load translation files +import { en } from './en.js'; +import { fr } from './fr.js'; + +// Initialize translations +translations = { en, fr }; + +// Get current language from localStorage or default to English +export function getCurrentLanguage() { + return localStorage.getItem('solarSystemLanguage') || 'en'; +} + +// Set language and save to localStorage +export function setLanguage(lang) { + if (translations[lang]) { + currentLanguage = lang; + localStorage.setItem('solarSystemLanguage', lang); + document.documentElement.lang = lang; + return true; + } + return false; +} + +// Get nested translation by key path (e.g., 'ui.controls.pause') +export function t(key, params = {}) { + //console.log('t() called with key:', key, 'current language:', currentLanguage); + const keys = key.split('.'); + let value = translations[currentLanguage]; + + for (const k of keys) { + if (value && typeof value === 'object' && k in value) { + value = value[k]; + } else { + // Fallback to English if key not found + value = translations['en']; + for (const fallbackKey of keys) { + if (value && typeof value === 'object' && fallbackKey in value) { + value = value[fallbackKey]; + } else { + console.warn(`Translation key "${key}" not found in ${currentLanguage} or English`); + return key; // Return key as fallback + } + } + break; + } + } + + // Handle parameter substitution + if (typeof value === 'string' && Object.keys(params).length > 0) { + return value.replace(/\{(\w+)\}/g, (match, param) => { + return params[param] !== undefined ? params[param] : match; + }); + } + + return value || key; +} + +// Format numbers according to locale +export function formatNumber(number, decimals = 0) { + const locale = currentLanguage === 'fr' ? 'fr-FR' : 'en-US'; + return new Intl.NumberFormat(locale, { + minimumFractionDigits: decimals, + maximumFractionDigits: decimals + }).format(number); +} + +// Format time periods with proper pluralization +export function formatTimePeriod(value, unit) { + const rounded = Math.round(value); + const yearsText = t('units.years'); + const daysText = t('units.days'); + + if (unit === 'years') { + return `${formatNumber(rounded)} ${yearsText}`; + } else if (unit === 'days') { + return `${formatNumber(rounded)} ${daysText}`; + } + + return `${formatNumber(rounded)} ${unit}`; +} + +// Initialize language on load +currentLanguage = getCurrentLanguage(); +setLanguage(currentLanguage); \ No newline at end of file diff --git a/index.html b/index.html index dc40e32..fb8c33e 100644 --- a/index.html +++ b/index.html @@ -401,6 +401,81 @@ opacity: 0.8; } + /* Language Selector Styles */ + .language-selector { + position: absolute; + top: 15px; + left: 50%; + transform: translateX(-50%); + background: var(--panel-bg); + color: var(--nasa-white); + border-radius: 8px; + border: 1px solid var(--panel-border); + backdrop-filter: blur(10px); + box-shadow: 0 4px 20px rgba(11, 61, 145, 0.3); + padding: 8px; + font-family: 'Titillium Web', sans-serif; + z-index: 1002; + display: flex; + align-items: center; + gap: 8px; + } + + .language-selector label { + font-size: 10px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--star-gold); + margin: 0; + } + + .language-buttons { + display: flex; + gap: 4px; + } + + .lang-btn { + background: var(--button-secondary); + color: var(--nasa-white); + border: 1px solid rgba(255, 255, 255, 0.2); + padding: 4px 8px; + border-radius: 4px; + cursor: pointer; + font-size: 9px; + font-family: 'Orbitron', monospace; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + transition: all 0.3s ease; + min-width: 30px; + text-align: center; + } + + .lang-btn:hover { + background: var(--button-hover); + box-shadow: 0 0 8px rgba(11, 61, 145, 0.5); + transform: translateY(-1px); + } + + .lang-btn.active { + background: linear-gradient(135deg, var(--star-gold), #ffa000); + color: var(--nasa-black); + border-color: var(--star-gold); + box-shadow: 0 0 10px rgba(255, 214, 10, 0.5); + } + + .lang-btn.active:hover { + background: linear-gradient(135deg, #ffa000, var(--star-gold)); + transform: translateY(-1px); + } + + /* Globe icon for language selector */ + .language-icon { + font-size: 12px; + margin-right: 2px; + } + /* Planet name labels in 3D space */ .planet-label { position: absolute; @@ -549,6 +624,32 @@ height: 45px; font-size: 16px; } + + .language-selector { + top: 10px; + left: 50%; + transform: translateX(-50%); + padding: 6px; + gap: 6px; + } + + .lang-btn { + padding: 3px 6px; + font-size: 8px; + min-width: 25px; + } + + .controls { + top: 60px; + left: 10px; + min-width: 160px; + } + + .celestial-panel { + top: 60px; + right: 10px; + min-width: 160px; + } } #showUIBtn { @@ -1054,6 +1155,16 @@ + +
+ 🌐 + +
+ + +
+
+