@jjlmoya/utils-astronomy 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +60 -0
- package/src/category/i18n/en.ts +57 -0
- package/src/category/i18n/es.ts +57 -0
- package/src/category/i18n/fr.ts +58 -0
- package/src/category/index.ts +16 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +19 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +22 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +24 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/seo_length.test.ts +57 -0
- package/src/tests/tool_validation.test.ts +145 -0
- package/src/tool/bortleVisualizer/bibliography.astro +14 -0
- package/src/tool/bortleVisualizer/component.astro +491 -0
- package/src/tool/bortleVisualizer/i18n/en.ts +153 -0
- package/src/tool/bortleVisualizer/i18n/es.ts +161 -0
- package/src/tool/bortleVisualizer/i18n/fr.ts +153 -0
- package/src/tool/bortleVisualizer/index.ts +41 -0
- package/src/tool/bortleVisualizer/logic.ts +118 -0
- package/src/tool/bortleVisualizer/seo.astro +61 -0
- package/src/tool/bortleVisualizer/style.css +5 -0
- package/src/tool/deepSpaceScope/bibliography.astro +14 -0
- package/src/tool/deepSpaceScope/component.astro +849 -0
- package/src/tool/deepSpaceScope/i18n/en.ts +157 -0
- package/src/tool/deepSpaceScope/i18n/es.ts +157 -0
- package/src/tool/deepSpaceScope/i18n/fr.ts +157 -0
- package/src/tool/deepSpaceScope/index.ts +48 -0
- package/src/tool/deepSpaceScope/logic.ts +41 -0
- package/src/tool/deepSpaceScope/seo.astro +61 -0
- package/src/tool/deepSpaceScope/style.css +5 -0
- package/src/tool/starExposureCalculator/bibliography.astro +14 -0
- package/src/tool/starExposureCalculator/component.astro +562 -0
- package/src/tool/starExposureCalculator/i18n/en.ts +163 -0
- package/src/tool/starExposureCalculator/i18n/es.ts +163 -0
- package/src/tool/starExposureCalculator/i18n/fr.ts +158 -0
- package/src/tool/starExposureCalculator/index.ts +53 -0
- package/src/tool/starExposureCalculator/logic.ts +49 -0
- package/src/tool/starExposureCalculator/seo.astro +61 -0
- package/src/tool/starExposureCalculator/style.css +5 -0
- package/src/tool/telescopeResolution/bibliography.astro +14 -0
- package/src/tool/telescopeResolution/component.astro +556 -0
- package/src/tool/telescopeResolution/i18n/en.ts +168 -0
- package/src/tool/telescopeResolution/i18n/es.ts +163 -0
- package/src/tool/telescopeResolution/i18n/fr.ts +168 -0
- package/src/tool/telescopeResolution/index.ts +52 -0
- package/src/tool/telescopeResolution/logic.ts +39 -0
- package/src/tool/telescopeResolution/seo.astro +61 -0
- package/src/tool/telescopeResolution/style.css +5 -0
- package/src/tools.ts +19 -0
- package/src/types.ts +71 -0
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jjlmoya/utils-astronomy",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.ts",
|
|
9
|
+
"./data": "./src/data.ts"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "astro dev",
|
|
19
|
+
"start": "astro dev",
|
|
20
|
+
"build": "astro build",
|
|
21
|
+
"preview": "astro preview",
|
|
22
|
+
"astro": "astro",
|
|
23
|
+
"lint": "eslint src/ --max-warnings 0 && stylelint \"src/**/*.{css,astro}\"",
|
|
24
|
+
"check": "astro check",
|
|
25
|
+
"type-check": "astro check",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"preversion": "npm run lint && npm run test",
|
|
28
|
+
"postversion": "git push && git push --tags",
|
|
29
|
+
"patch": "npm version patch",
|
|
30
|
+
"minor": "npm version minor",
|
|
31
|
+
"major": "npm version major"
|
|
32
|
+
},
|
|
33
|
+
"lint-staged": {
|
|
34
|
+
"*.{ts,tsx,astro}": [
|
|
35
|
+
"eslint --fix"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@iconify-json/mdi": "^1.2.3",
|
|
40
|
+
"@jjlmoya/utils-shared": "1.0.2",
|
|
41
|
+
"astro": "^6.1.2",
|
|
42
|
+
"astro-icon": "^1.1.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@astrojs/check": "^0.9.8",
|
|
46
|
+
"eslint": "^9.39.4",
|
|
47
|
+
"eslint-plugin-astro": "^1.6.0",
|
|
48
|
+
"eslint-plugin-no-comments": "^1.1.10",
|
|
49
|
+
"husky": "^9.1.7",
|
|
50
|
+
"lint-staged": "^16.4.0",
|
|
51
|
+
"postcss-html": "^1.8.1",
|
|
52
|
+
"schema-dts": "^1.1.2",
|
|
53
|
+
"stylelint": "^17.6.0",
|
|
54
|
+
"stylelint-config-standard": "^40.0.0",
|
|
55
|
+
"stylelint-declaration-strict-value": "^1.11.1",
|
|
56
|
+
"typescript": "^5.4.0",
|
|
57
|
+
"typescript-eslint": "^8.58.0",
|
|
58
|
+
"vitest": "^4.1.2"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'astronomy',
|
|
5
|
+
title: 'Astronomy Tools',
|
|
6
|
+
description: 'Free calculators and simulators for amateur astronomers. Plan your observation sessions and astrophotography.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Amateur Astronomy: Tools to Explore the Universe', level: 2 },
|
|
9
|
+
{
|
|
10
|
+
type: 'paragraph',
|
|
11
|
+
html: 'Amateur astronomy is one of the most exciting citizen sciences in the world. With the right equipment and the correct planning tools, anyone can explore galaxies millions of light-years away, contemplate nebulae where new stars are born, or study the surface of planets in our solar system. This suite of <strong>free astronomical calculators</strong> is designed to elevate your experience as an observer.',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
type: 'paragraph',
|
|
15
|
+
html: 'From evaluating sky quality with the Bortle scale to precisely calculating the optical resolution of your telescope, each tool applies formulas validated by the international astronomical community so that every night you spend under the stars is productive and memorable.',
|
|
16
|
+
},
|
|
17
|
+
{ type: 'title', text: 'Light Pollution: The Astronomer\'s Number One Enemy', level: 2 },
|
|
18
|
+
{
|
|
19
|
+
type: 'paragraph',
|
|
20
|
+
html: 'We live in an increasingly illuminated world. <strong>Light pollution</strong> grows at a rate of 10% per year and erases the night sky for more than 80% of the world\'s population. The Bortle scale, with its 9 levels, is the international standard for quantifying this loss. Our dark sky simulator lets you interactively visualize how artificial light transforms the firmament, from the absolute black of a remote desert to the oppressive orange of a metropolis.',
|
|
21
|
+
},
|
|
22
|
+
{ type: 'title', text: 'Your Telescope: Understanding its Real Capabilities', level: 2 },
|
|
23
|
+
{
|
|
24
|
+
type: 'paragraph',
|
|
25
|
+
html: 'The market is full of telescopes that promise to "see Saturn with its rings" with any aperture. The reality is that the <strong>objective aperture</strong> is the most critical parameter. It determines how much light it collects (limiting magnitude) and how much detail it can resolve (resolving power). The reach and resolution calculators in this section give you concrete numbers: which object catalogs are within your reach and how much detail you can expect on planetary surfaces.',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'list',
|
|
29
|
+
items: [
|
|
30
|
+
'<strong>Bortle Scale:</strong> Evaluate your sky quality before traveling to an observation site.',
|
|
31
|
+
'<strong>Telescope Reach:</strong> Calculate the limiting magnitude of your equipment based on aperture and sky conditions.',
|
|
32
|
+
'<strong>500 Rule / NPF:</strong> Determine maximum exposure time for astrophotography without star trails.',
|
|
33
|
+
'<strong>Optical Resolution:</strong> Know the Dawes and Rayleigh limit of your telescope.',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'tip',
|
|
38
|
+
title: 'The First Step: Know Your Sky',
|
|
39
|
+
html: 'Before investing in a larger telescope, consider traveling to a darker sky. A 150mm telescope under a Bortle 3 sky far outperforms a 300mm instrument under a Bortle 7. Sky darkness multiplies the performance of any equipment.',
|
|
40
|
+
},
|
|
41
|
+
{ type: 'title', text: 'Deep Sky Astrophotography: Capture the Cosmos', level: 2 },
|
|
42
|
+
{
|
|
43
|
+
type: 'paragraph',
|
|
44
|
+
html: 'Astrophotography has democratized access to the universe. With a standard DSLR camera and a wide-angle lens, you can capture the Milky Way in its splendor. With a telescope and an equatorial tracker, you can photograph nebulae and galaxies that surpass what the best observatories could see just decades ago. The key is in the <strong>exposure time</strong>: too short and you lose faint details; too long and you get star trails from Earth\'s rotation.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'stats',
|
|
48
|
+
columns: 2,
|
|
49
|
+
items: [
|
|
50
|
+
{ label: 'Bortle Scale', value: '9 Levels', icon: 'mdi:weather-night' },
|
|
51
|
+
{ label: 'Limiting Magnitude', value: 'Calculable', icon: 'mdi:telescope' },
|
|
52
|
+
{ label: '500/NPF Rule', value: 'Precision', icon: 'mdi:timer-sand' },
|
|
53
|
+
{ label: 'Dawes Power', value: 'Resolution', icon: 'mdi:flare' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'astronomia',
|
|
5
|
+
title: 'Herramientas de Astronomía',
|
|
6
|
+
description: 'Calculadoras y simuladores gratuitos para astrónomos aficionados. Planifica tus sesiones de observación y astrofotografía.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Astronomía Amateur: Herramientas para Explorar el Universo', level: 2 },
|
|
9
|
+
{
|
|
10
|
+
type: 'paragraph',
|
|
11
|
+
html: 'La astronomía aficionada es una de las ciencias ciudadanas más apasionantes del mundo. Con el equipo adecuado y las herramientas correctas para planificar, cualquier persona puede explorar galaxias a millones de años luz, contemplar nebulosas donde nacen nuevas estrellas o estudiar la superficie de planetas de nuestro sistema solar. Esta suite de <strong>calculadoras astronómicas gratuitas</strong> está diseñada para elevar tu experiencia como observador.',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
type: 'paragraph',
|
|
15
|
+
html: 'Desde la evaluación de la calidad de tu cielo con la escala de Bortle hasta el cálculo preciso de la resolución óptica de tu telescopio, cada herramienta aplica fórmulas validadas por la comunidad astronómica internacional para que cada noche que pases bajo las estrellas sea productiva y memorable.',
|
|
16
|
+
},
|
|
17
|
+
{ type: 'title', text: 'Contaminación Lumínica: El Enemigo Número Uno del Astrónomo', level: 2 },
|
|
18
|
+
{
|
|
19
|
+
type: 'paragraph',
|
|
20
|
+
html: 'Vivimos en un mundo cada vez más iluminado. La <strong>contaminación lumínica</strong> crece a un ritmo del 10% anual y borra el cielo nocturno para más del 80% de la población mundial. La escala de Bortle, con sus 9 niveles, es el estándar internacional para cuantificar esta pérdida. Nuestro simulador de cielo oscuro te permite visualizar interactivamente cómo la luz artificial transforma el firmamento, desde el negro absoluto de un desierto remoto hasta el naranja opresivo de una metrópolis.',
|
|
21
|
+
},
|
|
22
|
+
{ type: 'title', text: 'Tu Telescopio: Entender sus Capacidades Reales', level: 2 },
|
|
23
|
+
{
|
|
24
|
+
type: 'paragraph',
|
|
25
|
+
html: 'El mercado está lleno de telescopios que prometen "ver Saturno con sus anillos" con cualquier apertura. La realidad es que la <strong>apertura del objetivo</strong> es el parámetro más crítico. Determina cuánta luz recolecta (magnitud límite) y cuánto detalle puede resolver (poder de resolución). Las calculadoras de alcance y resolución de esta sección te dan números concretos: qué catálogos de objetos están a tu alcance y cuánto detalle puedes esperar en las superficies planetarias.',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'list',
|
|
29
|
+
items: [
|
|
30
|
+
'<strong>Escala de Bortle:</strong> Evalúa la calidad de tu cielo antes de desplazarte a un lugar de observación.',
|
|
31
|
+
'<strong>Alcance del Telescopio:</strong> Calcula la magnitud límite de tu equipo en función de la apertura y el cielo.',
|
|
32
|
+
'<strong>Regla de los 500 / NPF:</strong> Determina el tiempo de exposición máximo para astrofotografía sin trazas.',
|
|
33
|
+
'<strong>Resolución Óptica:</strong> Conoce el límite de Dawes y Rayleigh de tu telescopio.',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'tip',
|
|
38
|
+
title: 'El Primer Paso: Conoce tu Cielo',
|
|
39
|
+
html: 'Antes de invertir en un telescopio más grande, considera desplazarte a un cielo más oscuro. Un telescopio de 150mm bajo un cielo Bortle 3 supera ampliamente a un instrumento de 300mm bajo un Bortle 7. La oscuridad del cielo multiplica el rendimiento de cualquier equipo.',
|
|
40
|
+
},
|
|
41
|
+
{ type: 'title', text: 'Astrofotografía de Cielo Profundo: Captura el Cosmos', level: 2 },
|
|
42
|
+
{
|
|
43
|
+
type: 'paragraph',
|
|
44
|
+
html: 'La astrofotografía ha democratizado el acceso al universo. Con una cámara DSLR estándar y un objetivo gran angular, puedes capturar la Vía Láctea en su esplendor. Con un telescopio y un seguidor ecuatorial, puedes fotografiar nebulosas y galaxias que superan lo que los mejores observatorios podían ver hace solo décadas. La clave está en el <strong>tiempo de exposición</strong>: demasiado corto y pierdes detalles tenues; demasiado largo y obtienes trazos de estrella por la rotación terrestre.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'stats',
|
|
48
|
+
columns: 2,
|
|
49
|
+
items: [
|
|
50
|
+
{ label: 'Escala Bortle', value: '9 Niveles', icon: 'mdi:weather-night' },
|
|
51
|
+
{ label: 'Magnitud Límite', value: 'Calculable', icon: 'mdi:telescope' },
|
|
52
|
+
{ label: 'Regla 500/NPF', value: 'Precisión', icon: 'mdi:timer-sand' },
|
|
53
|
+
{ label: 'Poder Dawes', value: 'Resolución', icon: 'mdi:flare' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'astronomie',
|
|
5
|
+
title: 'Outils d\'Astronomie',
|
|
6
|
+
description: 'Calculatrices et simulateurs gratuits pour les astronomes amateurs. Planifiez vos sessions d\'observation et d\'astrophotographie.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Astronomie Amateur: Outils pour Explorer l\'Univers', level: 2 },
|
|
9
|
+
{
|
|
10
|
+
type: 'paragraph',
|
|
11
|
+
html: 'L\'astronomie amateur est l\'une des sciences citoyennes les plus passionnantes au monde. Avec le bon équipement et les bons outils de planification, n\'importe qui peut explorer des galaxies à des millions d\'années-lumière, contempler des nébuleuses où naissent de nouvelles étoiles ou étudier la surface des planètes de notre système solaire. Cette suite de <strong>calculatrices astronomiques gratuites</strong> est conçue pour élever votre expérience en tant qu\'observateur.',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
type: 'paragraph',
|
|
15
|
+
html: 'De l\'évaluation de la qualité de votre ciel avec l\'échelle de Bortle au calcul précis de la résolution optique de votre télescope, chaque outil applique des formules validées par la communauté astronomique internationale pour que chaque nuit passée sous les étoiles soit productive et mémorable.',
|
|
16
|
+
},
|
|
17
|
+
{ type: 'title', text: 'La Pollution Lumineuse: L\'Ennemi Numéro Un de l\'Astronome', level: 2 },
|
|
18
|
+
{
|
|
19
|
+
type: 'paragraph',
|
|
20
|
+
html: 'Nous vivons dans un monde de plus en plus éclairé. La <strong>pollution lumineuse</strong> croît à un rythme de 10% par an et efface le ciel nocturne pour plus de 80% de la population mondiale. L\'échelle de Bortle, avec ses 9 niveaux, est le standard international pour quantifier cette perte. Notre simulateur de ciel sombre vous permet de visualiser interactivement comment la lumière artificielle transforme le firmament, du noir absolu d\'un désert isolé à l\'orange oppressant d\'une métropole.',
|
|
21
|
+
},
|
|
22
|
+
{ type: 'title', text: 'Votre Télescope: Comprendre ses Capacités Réelles', level: 2 },
|
|
23
|
+
{
|
|
24
|
+
type: 'paragraph',
|
|
25
|
+
html: 'Le marché est plein de télescopes qui promettent de "voir Saturne avec ses anneaux" avec n\'importe quelle ouverture. La réalité est que <strong>l\'ouverture de l\'objectif</strong> est le paramètre le plus critique. Elle détermine la quantité de lumière collectée (magnitude limite) et la quantité de détails qu\'elle peut résoudre. Les calculatrices de portée et de résolution de cette section vous donnent des chiffres concrets.',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'list',
|
|
29
|
+
items: [
|
|
30
|
+
'<strong>Échelle de Bortle:</strong> Évaluez la qualité de votre ciel avant de vous déplacer sur un site d\'observation.',
|
|
31
|
+
'<strong>Portée du Télescope:</strong> Calculez la magnitude limite de votre équipement en fonction de l\'ouverture et du ciel.',
|
|
32
|
+
'<strong>Règle des 500 / NPF:</strong> Déterminez le temps d\'exposition maximum pour l\'astrophotographie sans traînées d\'étoiles.',
|
|
33
|
+
'<strong>Résolution Optique:</strong> Connaissez la limite de Dawes et de Rayleigh de votre télescope.',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'tip',
|
|
38
|
+
title: 'La Première Étape: Connaître votre Ciel',
|
|
39
|
+
html: 'Avant d\'investir dans un télescope plus grand, envisagez de vous déplacer sous un ciel plus sombre. Un télescope de 150mm sous un ciel Bortle 3 surpasse largement un instrument de 300mm sous un Bortle 7. L\'obscurité du ciel multiplie les performances de tout équipement.',
|
|
40
|
+
},
|
|
41
|
+
{ type: 'title', text: 'Astrophotographie du Ciel Profond: Capturez le Cosmos', level: 2 },
|
|
42
|
+
{
|
|
43
|
+
type: 'paragraph',
|
|
44
|
+
html: 'L\'astrophotographie a démocratisé l\'accès à l\'univers. Avec un appareil photo DSLR standard et un objectif grand-angle, vous pouvez capturer la Voie Lactée dans toute sa splendeur. Avec un télescope et un suiveur équatorial, vous pouvez photographier des nébuleuses et des galaxies dépassant ce que les meilleurs observatoires pouvaient voir il y a quelques décennies. La clé est dans le <strong>temps d\'exposition</strong>: trop court et vous perdez des détails faibles; trop long et vous obtenez des traînées d\'étoiles.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'stats',
|
|
48
|
+
columns: 2,
|
|
49
|
+
items: [
|
|
50
|
+
{ label: 'Échelle Bortle', value: '9 Niveaux', icon: 'mdi:weather-night' },
|
|
51
|
+
{ label: 'Magnitude Limite', value: 'Calculable', icon: 'mdi:telescope' },
|
|
52
|
+
{ label: 'Règle 500/NPF', value: 'Précision', icon: 'mdi:timer-sand' },
|
|
53
|
+
{ label: 'Pouvoir Dawes', value: 'Résolution', icon: 'mdi:flare' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AstronomyCategoryEntry } from '../types';
|
|
2
|
+
import { bortleVisualizer } from '../tool/bortleVisualizer';
|
|
3
|
+
import { deepSpaceScope } from '../tool/deepSpaceScope';
|
|
4
|
+
import { starExposureCalculator } from '../tool/starExposureCalculator';
|
|
5
|
+
import { telescopeResolution } from '../tool/telescopeResolution';
|
|
6
|
+
|
|
7
|
+
export const astronomyCategory: AstronomyCategoryEntry = {
|
|
8
|
+
icon: 'mdi:telescope',
|
|
9
|
+
tools: [bortleVisualizer, deepSpaceScope, starExposureCalculator, telescopeResolution],
|
|
10
|
+
i18n: {
|
|
11
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
12
|
+
en: () => import('./i18n/en').then((m) => m.content),
|
|
13
|
+
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { SEORenderer } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { astronomyCategory } from './index';
|
|
4
|
+
import type { KnownLocale } from '../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await astronomyCategory.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <SEORenderer content={{ locale, sections: content.seo }} />}
|
|
15
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface NavItem {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
href: string;
|
|
6
|
+
isActive?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
categoryTitle: string;
|
|
11
|
+
tools?: NavItem[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { categoryTitle, tools = [] } = Astro.props;
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<nav class="preview-nav-sidebar">
|
|
18
|
+
<div class="sidebar-header">
|
|
19
|
+
<h3>{categoryTitle}</h3>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<ul class="tools-list">
|
|
23
|
+
{tools.map((tool) => (
|
|
24
|
+
<li>
|
|
25
|
+
<a
|
|
26
|
+
href={tool.href}
|
|
27
|
+
class:list={['tool-link', { active: tool.isActive }]}
|
|
28
|
+
>
|
|
29
|
+
<span class="tool-title">{tool.title}</span>
|
|
30
|
+
</a>
|
|
31
|
+
</li>
|
|
32
|
+
))}
|
|
33
|
+
</ul>
|
|
34
|
+
</nav>
|
|
35
|
+
|
|
36
|
+
<style>
|
|
37
|
+
.preview-nav-sidebar {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
height: 100%;
|
|
41
|
+
background: var(--bg-surface, #0f172a);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.sidebar-header {
|
|
45
|
+
padding: 2rem 1.5rem 1.5rem;
|
|
46
|
+
border-bottom: 1px solid var(--border-color, #1e293b);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.sidebar-header h3 {
|
|
50
|
+
margin: 0;
|
|
51
|
+
font-size: 0.75rem;
|
|
52
|
+
font-weight: 900;
|
|
53
|
+
text-transform: uppercase;
|
|
54
|
+
letter-spacing: 0.1em;
|
|
55
|
+
color: var(--text-muted, #94a3b8);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.tools-list {
|
|
59
|
+
list-style: none;
|
|
60
|
+
margin: 0;
|
|
61
|
+
padding: 0.5rem 0;
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-direction: column;
|
|
64
|
+
gap: 0.25rem;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.tools-list li {
|
|
68
|
+
margin: 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.tool-link {
|
|
72
|
+
display: flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
padding: 0.75rem 1.5rem;
|
|
75
|
+
color: var(--text-muted, #94a3b8);
|
|
76
|
+
text-decoration: none;
|
|
77
|
+
font-size: 0.9375rem;
|
|
78
|
+
font-weight: 500;
|
|
79
|
+
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
|
80
|
+
border-left: 3px solid transparent;
|
|
81
|
+
position: relative;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.tool-link:hover {
|
|
85
|
+
color: var(--text-base, #f1f5f9);
|
|
86
|
+
background: rgba(255, 255, 255, 0.08);
|
|
87
|
+
padding-left: 1.75rem;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.tool-link.active {
|
|
91
|
+
color: var(--accent, #f43f5e);
|
|
92
|
+
background: rgba(244, 63, 94, 0.15);
|
|
93
|
+
border-left-color: var(--accent, #f43f5e);
|
|
94
|
+
font-weight: 600;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.tool-link.active::before {
|
|
98
|
+
content: '';
|
|
99
|
+
position: absolute;
|
|
100
|
+
left: 0;
|
|
101
|
+
top: 50%;
|
|
102
|
+
transform: translateY(-50%);
|
|
103
|
+
width: 3px;
|
|
104
|
+
height: 24px;
|
|
105
|
+
background: var(--accent, #f43f5e);
|
|
106
|
+
border-radius: 0 2px 2px 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.tool-title {
|
|
110
|
+
display: block;
|
|
111
|
+
overflow: hidden;
|
|
112
|
+
text-overflow: ellipsis;
|
|
113
|
+
white-space: nowrap;
|
|
114
|
+
}
|
|
115
|
+
</style>
|
|
116
|
+
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { KnownLocale } from '../types';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
currentLocale: KnownLocale;
|
|
6
|
+
localeUrls?: Partial<Record<KnownLocale, string>>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { currentLocale, localeUrls = {} } = Astro.props;
|
|
10
|
+
|
|
11
|
+
const otherLocales = Object.entries(localeUrls).filter(([l]) => l !== currentLocale) as [
|
|
12
|
+
KnownLocale,
|
|
13
|
+
string,
|
|
14
|
+
][];
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<nav class="preview-toolbar">
|
|
18
|
+
{
|
|
19
|
+
otherLocales.length > 0 && (
|
|
20
|
+
<div class="locale-group">
|
|
21
|
+
<span class="locale-current">{currentLocale.toUpperCase()}</span>
|
|
22
|
+
{otherLocales.map(([locale, url]) => (
|
|
23
|
+
<a href={url} class="btn-locale">
|
|
24
|
+
{locale.toUpperCase()}
|
|
25
|
+
</a>
|
|
26
|
+
))}
|
|
27
|
+
</div>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
<button id="theme-toggle" class="btn-theme" aria-label="Toggle theme" title="Toggle theme">
|
|
32
|
+
<span class="theme-icon"></span>
|
|
33
|
+
</button>
|
|
34
|
+
</nav>
|
|
35
|
+
|
|
36
|
+
<script>
|
|
37
|
+
function initToolbar() {
|
|
38
|
+
const btn = document.getElementById('theme-toggle');
|
|
39
|
+
if (!btn) return;
|
|
40
|
+
|
|
41
|
+
const applyTheme = (theme: string) => {
|
|
42
|
+
document.documentElement.classList.remove('theme-light', 'theme-dark');
|
|
43
|
+
document.documentElement.classList.add(theme);
|
|
44
|
+
localStorage.setItem('theme', theme);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
btn.addEventListener('click', () => {
|
|
48
|
+
const next = document.documentElement.classList.contains('theme-dark')
|
|
49
|
+
? 'theme-light'
|
|
50
|
+
: 'theme-dark';
|
|
51
|
+
applyTheme(next);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
initToolbar();
|
|
56
|
+
document.addEventListener('astro:after-swap', initToolbar);
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<style>
|
|
60
|
+
.preview-toolbar {
|
|
61
|
+
position: fixed;
|
|
62
|
+
top: 1rem;
|
|
63
|
+
right: 1.5rem;
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
gap: 0.5rem;
|
|
67
|
+
z-index: 1000;
|
|
68
|
+
background: var(--bg-surface);
|
|
69
|
+
padding: 0.4rem;
|
|
70
|
+
border-radius: 1rem;
|
|
71
|
+
border: 1px solid var(--border-color);
|
|
72
|
+
backdrop-filter: blur(12px);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.locale-group {
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
gap: 0.25rem;
|
|
79
|
+
padding-right: 0.5rem;
|
|
80
|
+
border-right: 1px solid var(--border-color);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.locale-current {
|
|
84
|
+
font-size: 0.7rem;
|
|
85
|
+
font-weight: 900;
|
|
86
|
+
color: var(--text-muted);
|
|
87
|
+
padding: 0.4rem 0.6rem;
|
|
88
|
+
letter-spacing: 0.08em;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.btn-locale {
|
|
92
|
+
background: transparent;
|
|
93
|
+
border: 1px solid var(--border-color);
|
|
94
|
+
color: var(--text-main);
|
|
95
|
+
cursor: pointer;
|
|
96
|
+
padding: 0.4rem 0.7rem;
|
|
97
|
+
border-radius: 0.5rem;
|
|
98
|
+
font-weight: 700;
|
|
99
|
+
font-size: 0.7rem;
|
|
100
|
+
text-decoration: none;
|
|
101
|
+
letter-spacing: 0.08em;
|
|
102
|
+
transition: all 0.2s ease;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.btn-locale:hover {
|
|
106
|
+
border-color: var(--accent);
|
|
107
|
+
color: var(--accent);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.btn-theme {
|
|
111
|
+
background: transparent;
|
|
112
|
+
border: none;
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
padding: 0.5rem;
|
|
115
|
+
border-radius: 0.6rem;
|
|
116
|
+
display: flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
justify-content: center;
|
|
119
|
+
transition: background 0.2s ease;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.btn-theme:hover {
|
|
123
|
+
background: rgba(255, 255, 255, 0.08);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.theme-icon {
|
|
127
|
+
display: block;
|
|
128
|
+
width: 16px;
|
|
129
|
+
height: 16px;
|
|
130
|
+
border-radius: 50%;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
:global(.theme-light) .theme-icon {
|
|
134
|
+
background: #f59e0b;
|
|
135
|
+
box-shadow: 0 0 8px #fbbf24;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:global(.theme-dark) .theme-icon {
|
|
139
|
+
background: #94a3b8;
|
|
140
|
+
box-shadow: inset -4px -2px 0 #1e293b;
|
|
141
|
+
}
|
|
142
|
+
</style>
|
|
143
|
+
|
package/src/data.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { bortleVisualizer } from './tool/bortleVisualizer';
|
|
2
|
+
export { deepSpaceScope } from './tool/deepSpaceScope';
|
|
3
|
+
export { starExposureCalculator } from './tool/starExposureCalculator';
|
|
4
|
+
export { telescopeResolution } from './tool/telescopeResolution';
|
|
5
|
+
export { astronomyCategory } from './category';
|
|
6
|
+
|
|
7
|
+
export type { BortleVisualizerUI, BortleVisualizerLocaleContent } from './tool/bortleVisualizer';
|
|
8
|
+
export type { DeepSpaceScopeUI, DeepSpaceScopeLocaleContent } from './tool/deepSpaceScope';
|
|
9
|
+
export type { StarExposureCalculatorUI, StarExposureCalculatorLocaleContent } from './tool/starExposureCalculator';
|
|
10
|
+
export type { TelescopeResolutionUI, TelescopeResolutionLocaleContent } from './tool/telescopeResolution';
|
|
11
|
+
|
|
12
|
+
export type {
|
|
13
|
+
KnownLocale,
|
|
14
|
+
ToolLocaleContent,
|
|
15
|
+
CategoryLocaleContent,
|
|
16
|
+
LocaleMap,
|
|
17
|
+
AstronomyToolEntry,
|
|
18
|
+
AstronomyCategoryEntry,
|
|
19
|
+
} from './types';
|
package/src/env.d.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from './tool/bortleVisualizer';
|
|
2
|
+
export * from './tool/deepSpaceScope';
|
|
3
|
+
export * from './tool/starExposureCalculator';
|
|
4
|
+
export * from './tool/telescopeResolution';
|
|
5
|
+
|
|
6
|
+
export { astronomyCategory } from './category';
|
|
7
|
+
export { default as AstronomyCategorySEO } from './category/seo.astro';
|
|
8
|
+
|
|
9
|
+
export type {
|
|
10
|
+
KnownLocale,
|
|
11
|
+
FAQItem,
|
|
12
|
+
BibliographyEntry,
|
|
13
|
+
HowToStep,
|
|
14
|
+
ToolLocaleContent,
|
|
15
|
+
CategoryLocaleContent,
|
|
16
|
+
LocaleLoader,
|
|
17
|
+
LocaleMap,
|
|
18
|
+
AstronomyToolEntry,
|
|
19
|
+
AstronomyCategoryEntry,
|
|
20
|
+
} from './types';
|
|
21
|
+
|
|
22
|
+
export { ALL_TOOLS } from './tools';
|