@jjlmoya/utils-nautical 1.2.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 +75 -0
- package/src/category/i18n/en.ts +79 -0
- package/src/category/i18n/es.ts +79 -0
- package/src/category/i18n/fr.ts +79 -0
- package/src/category/index.ts +13 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +12 -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 +249 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +30 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/seo_length.test.ts +29 -0
- package/src/tests/tool_validation.test.ts +51 -0
- package/src/tool/endurance/bibliography.astro +14 -0
- package/src/tool/endurance/component.astro +310 -0
- package/src/tool/endurance/i18n/en.ts +243 -0
- package/src/tool/endurance/i18n/es.ts +249 -0
- package/src/tool/endurance/i18n/fr.ts +217 -0
- package/src/tool/endurance/index.ts +56 -0
- package/src/tool/endurance/logic.ts +36 -0
- package/src/tool/endurance/seo.astro +55 -0
- package/src/tool/endurance/style.css +333 -0
- package/src/tool/nauticalConverter/bibliography.astro +14 -0
- package/src/tool/nauticalConverter/component.astro +481 -0
- package/src/tool/nauticalConverter/i18n/en.ts +239 -0
- package/src/tool/nauticalConverter/i18n/es.ts +239 -0
- package/src/tool/nauticalConverter/i18n/fr.ts +239 -0
- package/src/tool/nauticalConverter/index.ts +57 -0
- package/src/tool/nauticalConverter/logic.ts +52 -0
- package/src/tool/nauticalConverter/seo.astro +52 -0
- package/src/tool/nauticalConverter/style.css +205 -0
- package/src/tool/sailArea/bibliography.astro +14 -0
- package/src/tool/sailArea/component.astro +418 -0
- package/src/tool/sailArea/i18n/en.ts +275 -0
- package/src/tool/sailArea/i18n/es.ts +275 -0
- package/src/tool/sailArea/i18n/fr.ts +275 -0
- package/src/tool/sailArea/index.ts +53 -0
- package/src/tool/sailArea/logic.ts +55 -0
- package/src/tool/sailArea/seo.astro +52 -0
- package/src/tool/sailArea/style.css +351 -0
- package/src/tool/speedConverter/bibliography.astro +14 -0
- package/src/tool/speedConverter/component.astro +125 -0
- package/src/tool/speedConverter/i18n/en.ts +271 -0
- package/src/tool/speedConverter/i18n/es.ts +271 -0
- package/src/tool/speedConverter/i18n/fr.ts +271 -0
- package/src/tool/speedConverter/index.ts +46 -0
- package/src/tool/speedConverter/logic.ts +48 -0
- package/src/tool/speedConverter/seo.astro +43 -0
- package/src/tool/speedConverter/style.css +239 -0
- package/src/tool/tideCalculator/bibliography.astro +14 -0
- package/src/tool/tideCalculator/component.astro +314 -0
- package/src/tool/tideCalculator/i18n/en.ts +203 -0
- package/src/tool/tideCalculator/i18n/es.ts +225 -0
- package/src/tool/tideCalculator/i18n/fr.ts +190 -0
- package/src/tool/tideCalculator/index.ts +50 -0
- package/src/tool/tideCalculator/logic.ts +73 -0
- package/src/tool/tideCalculator/seo.astro +61 -0
- package/src/tool/tideCalculator/style.css +310 -0
- package/src/tool/underKeel/bibliography.astro +14 -0
- package/src/tool/underKeel/component.astro +240 -0
- package/src/tool/underKeel/i18n/en.ts +193 -0
- package/src/tool/underKeel/i18n/es.ts +206 -0
- package/src/tool/underKeel/i18n/fr.ts +193 -0
- package/src/tool/underKeel/index.ts +49 -0
- package/src/tool/underKeel/logic.ts +83 -0
- package/src/tool/underKeel/seo.astro +46 -0
- package/src/tool/underKeel/style.css +312 -0
- package/src/tools.ts +25 -0
- package/src/types.ts +69 -0
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jjlmoya/utils-nautical",
|
|
3
|
+
"version": "1.2.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
|
+
"chart.js": "^4.5.1"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"html2canvas": ">=1.4.0",
|
|
47
|
+
"jspdf": ">=2.0.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"html2canvas": {
|
|
51
|
+
"optional": true
|
|
52
|
+
},
|
|
53
|
+
"jspdf": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@astrojs/check": "^0.9.8",
|
|
59
|
+
"eslint": "^9.39.4",
|
|
60
|
+
"eslint-plugin-astro": "^1.6.0",
|
|
61
|
+
"eslint-plugin-no-comments": "^1.1.10",
|
|
62
|
+
"html2canvas": "^1.4.1",
|
|
63
|
+
"husky": "^9.1.7",
|
|
64
|
+
"jspdf": "^4.2.1",
|
|
65
|
+
"lint-staged": "^16.4.0",
|
|
66
|
+
"postcss-html": "^1.8.1",
|
|
67
|
+
"schema-dts": "^1.1.2",
|
|
68
|
+
"stylelint": "^17.6.0",
|
|
69
|
+
"stylelint-config-standard": "^40.0.0",
|
|
70
|
+
"stylelint-declaration-strict-value": "^1.11.1",
|
|
71
|
+
"typescript": "^5.4.0",
|
|
72
|
+
"typescript-eslint": "^8.58.0",
|
|
73
|
+
"vitest": "^4.1.2"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../index';
|
|
2
|
+
|
|
3
|
+
const slug = 'sailing-and-nautical';
|
|
4
|
+
const title = 'Sailing & Nautical';
|
|
5
|
+
const description =
|
|
6
|
+
'Nautical calculation tools for sailors: tides, endurance, sail area, unit converters and speed. Ideal for RYA and Yachtmaster exam study.';
|
|
7
|
+
|
|
8
|
+
const seo: CategoryLocaleContent['seo'] = [
|
|
9
|
+
{
|
|
10
|
+
type: 'title',
|
|
11
|
+
text: 'Why use digital tools in sailing and navigation?',
|
|
12
|
+
level: 2,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
type: 'paragraph',
|
|
16
|
+
html: 'Modern navigation has undergone a radical transformation with the advent of digital tools. Whether you are on a small recreational craft or at the helm of a cruising yacht, the ability to process position, wind and current data instantly is not just a matter of convenience — it is a fundamental pillar of safety at sea.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'paragraph',
|
|
20
|
+
html: 'Historically, the mariner depended exclusively on the sextant, the marine chronometer and reduction tables to determine position on the vast ocean. Today, although the romanticism of the sextant persists, operational reality demands a speed of response that only digital calculation tools can provide.',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: 'title',
|
|
24
|
+
text: 'Key Aspects for the Modern Navigator',
|
|
25
|
+
level: 2,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'title',
|
|
29
|
+
text: 'Geolocation and High-Precision Digital Cartography',
|
|
30
|
+
level: 3,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'paragraph',
|
|
34
|
+
html: 'Digital cartography has democratised navigation, giving even small boats access to information previously limited to large commercial vessels. A responsible skipper uses digital tools to validate their judgement, not to replace it.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'list',
|
|
38
|
+
items: [
|
|
39
|
+
'Data entry precision: Minimal typographical errors can take you miles from your destination.',
|
|
40
|
+
'Cross-device compatibility: Synchronise passage planning on a tablet with bridge instruments.',
|
|
41
|
+
'Hardware failure backup: Lightweight web apps are insurance if the onboard plotter crashes.',
|
|
42
|
+
'Passage Planning: Nautical calculators allow accurate estimation of fuel consumption and distances.',
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'title',
|
|
47
|
+
text: 'Marine Meteorology and Route Optimisation',
|
|
48
|
+
level: 3,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'paragraph',
|
|
52
|
+
html: 'Wind and sea state are the true sovereigns of sailing. Correct interpretation of wind scales (such as the Beaufort scale) and their conversion to practical units like knots is the day-to-day reality of any navigator.',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: 'tip',
|
|
56
|
+
title: 'The importance of redundancy and the Plan B',
|
|
57
|
+
html: 'Never trust all your navigation to a single electronic system. Always keep a backup of your critical waypoints on paper. Web tools are excellent for pre-passage planning, but a good sailor always has an emergency plan that requires no screen.',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: 'title',
|
|
61
|
+
text: 'Nautical Training and the Use of Calculators',
|
|
62
|
+
level: 2,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'paragraph',
|
|
66
|
+
html: 'Even in official examinations for nautical qualifications (such as the RYA Dayskipper or Yachtmaster), chart calculations remain mandatory. Digital tools serve as the perfect study companion, allowing candidates to verify their dead reckoning exercises, tidal calculations and compass corrections.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'paragraph',
|
|
70
|
+
html: 'Our collection of utilities aims to be that bridge between the academic rigour of paper charts and the immediacy of modern navigation. We want every skipper, enthusiast or professional to find here the quick and accurate data they need before casting off.',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
export const content: CategoryLocaleContent = {
|
|
75
|
+
slug,
|
|
76
|
+
title,
|
|
77
|
+
description,
|
|
78
|
+
seo,
|
|
79
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../index';
|
|
2
|
+
|
|
3
|
+
const slug = 'vela-y-nautica';
|
|
4
|
+
const title = 'Vela y Nautica';
|
|
5
|
+
const description =
|
|
6
|
+
'Herramientas de calculo nautico para navegantes: mareas, autonomia, superficie velica, conversores de unidades y velocidad. Ideales para el estudio del PER y Patron de Yate.';
|
|
7
|
+
|
|
8
|
+
const seo: CategoryLocaleContent['seo'] = [
|
|
9
|
+
{
|
|
10
|
+
type: 'title',
|
|
11
|
+
text: '¿Por que usar herramientas digitales en navegacion y vela?',
|
|
12
|
+
level: 2,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
type: 'paragraph',
|
|
16
|
+
html: 'La navegacion moderna ha experimentado una transformacion radical con la llegada de las herramientas digitales. Ya sea que te encuentres en una pequeña embarcacion de recreo o al mando de un velero de crucero, la capacidad de procesar datos de posicion, viento y corriente de forma instantanea no es solo una cuestion de comodidad, sino un pilar fundamental de la seguridad en el mar.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'paragraph',
|
|
20
|
+
html: 'Historicamente, el marino dependia exclusivamente del sextante, el cronometro de marina y las tablas de reduccion para determinar su posicion en el vasto oceano. Hoy, aunque el romanticismo del sextante persiste, la realidad operativa exige una velocidad de respuesta que solo las herramientas de calculo digital pueden proporcionar.',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: 'title',
|
|
24
|
+
text: 'Aspectos Clave para el Navegante Moderno',
|
|
25
|
+
level: 2,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'title',
|
|
29
|
+
text: 'Geolocalización y Cartografia Digital de Alta Precision',
|
|
30
|
+
level: 3,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'paragraph',
|
|
34
|
+
html: 'La cartografia digital ha democratizado la navegacion, permitiendo que incluso barcos pequeños tengan acceso a informacion que antes estaba limitada a buques comerciales de gran calado. Un patron responsable utiliza las herramientas digitales para validar su juicio, no para sustituirlo.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'list',
|
|
38
|
+
items: [
|
|
39
|
+
'Precision en la entrada de datos: Errores tipograficos minimos pueden alejarte kilometros de tu destino.',
|
|
40
|
+
'Compatibilidad entre dispositivos: Permite sincronizar la planificacion en tablet con los sistemas del puente de mando.',
|
|
41
|
+
'Respaldo ante fallos de hardware: Las apps web ligeras son un seguro si el plotter de abordo falla.',
|
|
42
|
+
'Planificacion de travesias (Passage Planning): Las calculadoras nauticas permiten estimar consumos y distancias con precision matematica.',
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'title',
|
|
47
|
+
text: 'Meteorologia Marina y Optimizacion de la Ruta',
|
|
48
|
+
level: 3,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'paragraph',
|
|
52
|
+
html: 'El viento y el estado del mar son los verdaderos soberanos de la navegacion a vela. La interpretacion correcta de las escalas de viento (como la escala Beaufort) y su conversion a unidades practicas como nudos es el dia a dia de cualquier navegante.',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: 'tip',
|
|
56
|
+
title: 'La importancia de la redundancia y el Plan B',
|
|
57
|
+
html: 'Nunca confies toda tu navegacion a un solo sistema electronico. Mantén siempre una copia de seguridad de tus coordenadas criticas en papel. Las herramientas web son excelentes para la planificacion previa, pero el buen marinero siempre tiene un plan de emergencia.',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: 'title',
|
|
61
|
+
text: 'Formacion Nautica y el uso de Calculadoras',
|
|
62
|
+
level: 2,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'paragraph',
|
|
66
|
+
html: 'Incluso en los examenes oficiales para obtener los titulos nauticos (como el PER en España), el uso de calculos sobre la carta sigue siendo obligatorio. Las herramientas digitales sirven como el compañero de estudio perfecto, permitiendo a los aspirantes verificar sus ejercicios de estima, calculos de marea o correcciones de aguja magnetica.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'paragraph',
|
|
70
|
+
html: 'Nuestra coleccion de utilidades busca ser ese puente entre la rigurosidad academica de las cartas de papel y la inmediatez de la navegacion moderna. Queremos que cada patron, aficionado o profesional, encuentre aqui el dato rapido y preciso que necesita antes de soltar amarras.',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
export const content: CategoryLocaleContent = {
|
|
75
|
+
slug,
|
|
76
|
+
title,
|
|
77
|
+
description,
|
|
78
|
+
seo,
|
|
79
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../index';
|
|
2
|
+
|
|
3
|
+
const slug = 'voile-et-nautisme';
|
|
4
|
+
const title = 'Voile et Nautisme';
|
|
5
|
+
const description =
|
|
6
|
+
"Outils de calcul nautique pour les navigateurs : marees, autonomie, surface velique, convertisseurs d'unites et de vitesse. Ideaux pour la preparation aux examens de plaisance.";
|
|
7
|
+
|
|
8
|
+
const seo: CategoryLocaleContent['seo'] = [
|
|
9
|
+
{
|
|
10
|
+
type: 'title',
|
|
11
|
+
text: 'Pourquoi utiliser des outils numeriques en voile et navigation ?',
|
|
12
|
+
level: 2,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
type: 'paragraph',
|
|
16
|
+
html: "La navigation moderne a connu une transformation radicale avec l'avenement des outils numeriques. Que vous soyez a bord d'une petite embarcation de plaisance ou aux commandes d'un voilier de croisiere, la capacite de traiter des donnees de position, de vent et de courant instantanement est non seulement une question de commodite, mais un pilier fondamental de la securite en mer.",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'paragraph',
|
|
20
|
+
html: "Historiquement, le marin dependait exclusivement du sextant, du chronometre de marine et des tables de reduction pour determiner sa position sur le vaste ocean. Aujourd'hui, bien que le romantisme du sextant persiste, la realite operationnelle exige une rapidite de reponse que seuls les outils de calcul numeriques peuvent fournir.",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: 'title',
|
|
24
|
+
text: 'Aspects cles pour le navigateur moderne',
|
|
25
|
+
level: 2,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'title',
|
|
29
|
+
text: 'Geolocalisation et cartographie numerique de haute precision',
|
|
30
|
+
level: 3,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'paragraph',
|
|
34
|
+
html: "La cartographie numerique a democratise la navigation, permettant meme aux petits bateaux d'acceder a des informations autrefois reservees aux grands navires commerciaux. Un skipper responsable utilise les outils numeriques pour valider son jugement, non pour le remplacer.",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'list',
|
|
38
|
+
items: [
|
|
39
|
+
"Precision de saisie des donnees : De petites erreurs typographiques peuvent vous eloigner de kilometres de votre destination.",
|
|
40
|
+
"Compatibilite entre appareils : Synchronisez la planification sur tablette avec les instruments de bord.",
|
|
41
|
+
"Sauvegarde en cas de panne materielle : Les applications web legeres sont une assurance si le traceur de bord tombe en panne.",
|
|
42
|
+
"Planification de traversees : Les calculateurs nautiques permettent d'estimer avec precision les consommations et les distances.",
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'title',
|
|
47
|
+
text: 'Meteorologie marine et optimisation de la route',
|
|
48
|
+
level: 3,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'paragraph',
|
|
52
|
+
html: "Le vent et l'etat de la mer sont les veritables souverains de la navigation a voile. L'interpretation correcte des echelles de vent (comme l'echelle Beaufort) et leur conversion en unites pratiques comme les noeuds est le quotidien de tout navigateur.",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: 'tip',
|
|
56
|
+
title: "L'importance de la redondance et du Plan B",
|
|
57
|
+
html: "Ne confiez jamais toute votre navigation a un seul systeme electronique. Conservez toujours une copie de sauvegarde de vos coordonnees critiques sur papier. Les outils web sont excellents pour la planification prealable, mais le bon marin a toujours un plan d'urgence.",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: 'title',
|
|
61
|
+
text: 'Formation nautique et utilisation des calculateurs',
|
|
62
|
+
level: 2,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'paragraph',
|
|
66
|
+
html: "Meme dans les examens officiels pour l'obtention des titres nautiques, les calculs sur carte restent obligatoires. Les outils numeriques servent de compagnon d'etude ideal, permettant aux candidats de verifier leurs exercices d'estime, calculs de maree et corrections de compas.",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'paragraph',
|
|
70
|
+
html: "Notre collection d'utilitaires vise a etre ce pont entre la rigueur academique des cartes papier et l'imediatete de la navigation moderne. Nous souhaitons que chaque skipper, amateur ou professionnel, trouve ici la donnee rapide et precise dont il a besoin avant de larguer les amarres.",
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
export const content: CategoryLocaleContent = {
|
|
75
|
+
slug,
|
|
76
|
+
title,
|
|
77
|
+
description,
|
|
78
|
+
seo,
|
|
79
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NauticalCategoryEntry, CategoryLocaleContent } from '../types';
|
|
2
|
+
|
|
3
|
+
export type { CategoryLocaleContent };
|
|
4
|
+
|
|
5
|
+
export const nauticalCategory: NauticalCategoryEntry = {
|
|
6
|
+
icon: 'mdi:sail-boat',
|
|
7
|
+
tools: [],
|
|
8
|
+
i18n: {
|
|
9
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
10
|
+
en: () => import('./i18n/en').then((m) => m.content),
|
|
11
|
+
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
@@ -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,12 @@
|
|
|
1
|
+
export { tideCalculator } from './tool/tideCalculator';
|
|
2
|
+
|
|
3
|
+
export type { TideCalculatorUI, TideCalculatorLocaleContent } from './tool/tideCalculator';
|
|
4
|
+
|
|
5
|
+
export type {
|
|
6
|
+
KnownLocale,
|
|
7
|
+
ToolLocaleContent,
|
|
8
|
+
CategoryLocaleContent,
|
|
9
|
+
LocaleMap,
|
|
10
|
+
NauticalToolEntry,
|
|
11
|
+
NauticalCategoryEntry,
|
|
12
|
+
} from './types';
|
package/src/env.d.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from './tool/tideCalculator';
|
|
2
|
+
export * from './tool/underKeel';
|
|
3
|
+
export * from './tool/nauticalConverter';
|
|
4
|
+
export * from './tool/sailArea';
|
|
5
|
+
export * from './tool/speedConverter';
|
|
6
|
+
export * from './tool/endurance';
|
|
7
|
+
export * from './category';
|
|
8
|
+
|
|
9
|
+
export type {
|
|
10
|
+
KnownLocale,
|
|
11
|
+
FAQItem,
|
|
12
|
+
BibliographyEntry,
|
|
13
|
+
HowToStep,
|
|
14
|
+
ToolLocaleContent,
|
|
15
|
+
CategoryLocaleContent,
|
|
16
|
+
LocaleLoader,
|
|
17
|
+
LocaleMap,
|
|
18
|
+
NauticalToolEntry,
|
|
19
|
+
NauticalCategoryEntry,
|
|
20
|
+
} from './types';
|
|
21
|
+
|
|
22
|
+
export { ALL_TOOLS } from './tools';
|