@jjlmoya/utils-health 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.
Files changed (155) hide show
  1. package/package.json +60 -0
  2. package/src/category/i18n/en.ts +60 -0
  3. package/src/category/i18n/es.ts +60 -0
  4. package/src/category/i18n/fr.ts +60 -0
  5. package/src/category/index.ts +22 -0
  6. package/src/category/seo.astro +15 -0
  7. package/src/components/PreviewNavSidebar.astro +116 -0
  8. package/src/components/PreviewToolbar.astro +143 -0
  9. package/src/data.ts +28 -0
  10. package/src/env.d.ts +5 -0
  11. package/src/index.ts +36 -0
  12. package/src/layouts/PreviewLayout.astro +117 -0
  13. package/src/pages/[locale]/[slug].astro +146 -0
  14. package/src/pages/[locale].astro +251 -0
  15. package/src/pages/index.astro +4 -0
  16. package/src/tests/faq_count.test.ts +19 -0
  17. package/src/tests/locale_completeness.test.ts +42 -0
  18. package/src/tests/mocks/astro_mock.js +2 -0
  19. package/src/tests/no_h1_in_components.test.ts +48 -0
  20. package/src/tests/schemas_fulfillment.test.ts +23 -0
  21. package/src/tests/seo_length.test.ts +22 -0
  22. package/src/tests/title_quality.test.ts +55 -0
  23. package/src/tests/tool_validation.test.ts +17 -0
  24. package/src/tool/binauralTuner/bibliography.astro +14 -0
  25. package/src/tool/binauralTuner/component.astro +687 -0
  26. package/src/tool/binauralTuner/i18n/en.ts +187 -0
  27. package/src/tool/binauralTuner/i18n/es.ts +187 -0
  28. package/src/tool/binauralTuner/i18n/fr.ts +187 -0
  29. package/src/tool/binauralTuner/index.ts +27 -0
  30. package/src/tool/binauralTuner/seo.astro +14 -0
  31. package/src/tool/binauralTuner/ui.ts +18 -0
  32. package/src/tool/bloodUnitConverter/bibliography.astro +14 -0
  33. package/src/tool/bloodUnitConverter/component.astro +915 -0
  34. package/src/tool/bloodUnitConverter/i18n/en.ts +227 -0
  35. package/src/tool/bloodUnitConverter/i18n/es.ts +250 -0
  36. package/src/tool/bloodUnitConverter/i18n/fr.ts +218 -0
  37. package/src/tool/bloodUnitConverter/index.ts +27 -0
  38. package/src/tool/bloodUnitConverter/seo.astro +14 -0
  39. package/src/tool/bloodUnitConverter/ui.ts +38 -0
  40. package/src/tool/bmiCalculator/bibliography.astro +14 -0
  41. package/src/tool/bmiCalculator/component.astro +415 -0
  42. package/src/tool/bmiCalculator/i18n/en.ts +217 -0
  43. package/src/tool/bmiCalculator/i18n/es.ts +221 -0
  44. package/src/tool/bmiCalculator/i18n/fr.ts +217 -0
  45. package/src/tool/bmiCalculator/index.ts +27 -0
  46. package/src/tool/bmiCalculator/seo.astro +14 -0
  47. package/src/tool/bmiCalculator/ui.ts +21 -0
  48. package/src/tool/breathingVisualizer/bibliography.astro +14 -0
  49. package/src/tool/breathingVisualizer/component.astro +636 -0
  50. package/src/tool/breathingVisualizer/i18n/en.ts +206 -0
  51. package/src/tool/breathingVisualizer/i18n/es.ts +206 -0
  52. package/src/tool/breathingVisualizer/i18n/fr.ts +206 -0
  53. package/src/tool/breathingVisualizer/index.ts +27 -0
  54. package/src/tool/breathingVisualizer/seo.astro +14 -0
  55. package/src/tool/breathingVisualizer/ui.ts +31 -0
  56. package/src/tool/caffeineTracker/bibliography.astro +14 -0
  57. package/src/tool/caffeineTracker/component.astro +1210 -0
  58. package/src/tool/caffeineTracker/i18n/en.ts +198 -0
  59. package/src/tool/caffeineTracker/i18n/es.ts +198 -0
  60. package/src/tool/caffeineTracker/i18n/fr.ts +198 -0
  61. package/src/tool/caffeineTracker/index.ts +27 -0
  62. package/src/tool/caffeineTracker/logic.ts +31 -0
  63. package/src/tool/caffeineTracker/seo.astro +14 -0
  64. package/src/tool/caffeineTracker/ui.ts +36 -0
  65. package/src/tool/daltonismSimulator/bibliography.astro +14 -0
  66. package/src/tool/daltonismSimulator/component.astro +383 -0
  67. package/src/tool/daltonismSimulator/i18n/en.ts +188 -0
  68. package/src/tool/daltonismSimulator/i18n/es.ts +218 -0
  69. package/src/tool/daltonismSimulator/i18n/fr.ts +168 -0
  70. package/src/tool/daltonismSimulator/index.ts +27 -0
  71. package/src/tool/daltonismSimulator/seo.astro +14 -0
  72. package/src/tool/daltonismSimulator/ui.ts +20 -0
  73. package/src/tool/digestionStopwatch/bibliography.astro +14 -0
  74. package/src/tool/digestionStopwatch/component.astro +627 -0
  75. package/src/tool/digestionStopwatch/i18n/en.ts +173 -0
  76. package/src/tool/digestionStopwatch/i18n/es.ts +173 -0
  77. package/src/tool/digestionStopwatch/i18n/fr.ts +173 -0
  78. package/src/tool/digestionStopwatch/index.ts +27 -0
  79. package/src/tool/digestionStopwatch/logic.ts +63 -0
  80. package/src/tool/digestionStopwatch/seo.astro +14 -0
  81. package/src/tool/digestionStopwatch/ui.ts +20 -0
  82. package/src/tool/epworthSleepinessScale/bibliography.astro +14 -0
  83. package/src/tool/epworthSleepinessScale/component.astro +528 -0
  84. package/src/tool/epworthSleepinessScale/i18n/en.ts +217 -0
  85. package/src/tool/epworthSleepinessScale/i18n/es.ts +217 -0
  86. package/src/tool/epworthSleepinessScale/i18n/fr.ts +217 -0
  87. package/src/tool/epworthSleepinessScale/index.ts +27 -0
  88. package/src/tool/epworthSleepinessScale/seo.astro +14 -0
  89. package/src/tool/epworthSleepinessScale/ui.ts +27 -0
  90. package/src/tool/hydrationCalculator/bibliography.astro +14 -0
  91. package/src/tool/hydrationCalculator/component.astro +694 -0
  92. package/src/tool/hydrationCalculator/i18n/en.ts +217 -0
  93. package/src/tool/hydrationCalculator/i18n/es.ts +222 -0
  94. package/src/tool/hydrationCalculator/i18n/fr.ts +199 -0
  95. package/src/tool/hydrationCalculator/index.ts +27 -0
  96. package/src/tool/hydrationCalculator/seo.astro +14 -0
  97. package/src/tool/hydrationCalculator/ui.ts +28 -0
  98. package/src/tool/pelliRobsonTest/bibliography.astro +14 -0
  99. package/src/tool/pelliRobsonTest/component.astro +653 -0
  100. package/src/tool/pelliRobsonTest/i18n/en.ts +205 -0
  101. package/src/tool/pelliRobsonTest/i18n/es.ts +205 -0
  102. package/src/tool/pelliRobsonTest/i18n/fr.ts +205 -0
  103. package/src/tool/pelliRobsonTest/index.ts +27 -0
  104. package/src/tool/pelliRobsonTest/seo.astro +14 -0
  105. package/src/tool/pelliRobsonTest/ui.ts +21 -0
  106. package/src/tool/peripheralVisionTrainer/bibliography.astro +14 -0
  107. package/src/tool/peripheralVisionTrainer/component.astro +678 -0
  108. package/src/tool/peripheralVisionTrainer/i18n/en.ts +224 -0
  109. package/src/tool/peripheralVisionTrainer/i18n/es.ts +224 -0
  110. package/src/tool/peripheralVisionTrainer/i18n/fr.ts +211 -0
  111. package/src/tool/peripheralVisionTrainer/index.ts +27 -0
  112. package/src/tool/peripheralVisionTrainer/seo.astro +14 -0
  113. package/src/tool/peripheralVisionTrainer/ui.ts +26 -0
  114. package/src/tool/readingDistanceCalculator/bibliography.astro +14 -0
  115. package/src/tool/readingDistanceCalculator/component.astro +588 -0
  116. package/src/tool/readingDistanceCalculator/i18n/en.ts +202 -0
  117. package/src/tool/readingDistanceCalculator/i18n/es.ts +215 -0
  118. package/src/tool/readingDistanceCalculator/i18n/fr.ts +193 -0
  119. package/src/tool/readingDistanceCalculator/index.ts +31 -0
  120. package/src/tool/readingDistanceCalculator/seo.astro +14 -0
  121. package/src/tool/readingDistanceCalculator/ui.ts +18 -0
  122. package/src/tool/screenDecompressionTime/bibliography.astro +14 -0
  123. package/src/tool/screenDecompressionTime/component.astro +671 -0
  124. package/src/tool/screenDecompressionTime/i18n/en.ts +225 -0
  125. package/src/tool/screenDecompressionTime/i18n/es.ts +247 -0
  126. package/src/tool/screenDecompressionTime/i18n/fr.ts +225 -0
  127. package/src/tool/screenDecompressionTime/index.ts +27 -0
  128. package/src/tool/screenDecompressionTime/seo.astro +14 -0
  129. package/src/tool/screenDecompressionTime/ui.ts +32 -0
  130. package/src/tool/tinnitusReliever/bibliography.astro +14 -0
  131. package/src/tool/tinnitusReliever/component.astro +581 -0
  132. package/src/tool/tinnitusReliever/i18n/en.ts +161 -0
  133. package/src/tool/tinnitusReliever/i18n/es.ts +161 -0
  134. package/src/tool/tinnitusReliever/i18n/fr.ts +161 -0
  135. package/src/tool/tinnitusReliever/index.ts +27 -0
  136. package/src/tool/tinnitusReliever/seo.astro +14 -0
  137. package/src/tool/tinnitusReliever/ui.ts +9 -0
  138. package/src/tool/ubeCalculator/bibliography.astro +14 -0
  139. package/src/tool/ubeCalculator/component.astro +683 -0
  140. package/src/tool/ubeCalculator/i18n/en.ts +200 -0
  141. package/src/tool/ubeCalculator/i18n/es.ts +200 -0
  142. package/src/tool/ubeCalculator/i18n/fr.ts +196 -0
  143. package/src/tool/ubeCalculator/index.ts +27 -0
  144. package/src/tool/ubeCalculator/seo.astro +14 -0
  145. package/src/tool/ubeCalculator/ui.ts +26 -0
  146. package/src/tool/waterPurifier/bibliography.astro +14 -0
  147. package/src/tool/waterPurifier/component.astro +628 -0
  148. package/src/tool/waterPurifier/i18n/en.ts +167 -0
  149. package/src/tool/waterPurifier/i18n/es.ts +167 -0
  150. package/src/tool/waterPurifier/i18n/fr.ts +167 -0
  151. package/src/tool/waterPurifier/index.ts +27 -0
  152. package/src/tool/waterPurifier/seo.astro +14 -0
  153. package/src/tool/waterPurifier/ui.ts +18 -0
  154. package/src/tools.ts +19 -0
  155. package/src/types.ts +72 -0
@@ -0,0 +1,167 @@
1
+ import type { WithContext, SoftwareApplication, FAQPage, HowToThing } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { WaterPurifierUI } from '../ui';
4
+
5
+ const slug = 'water-purifier';
6
+ const title = 'Emergency Water Purifier';
7
+ const description =
8
+ 'Bleach dosage calculator to purify emergency water. Survival tool based on WHO and CDC guidelines.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Can I use any type of bleach to purify water?',
13
+ answer:
14
+ 'No. It must be bleach suitable for drinking water disinfection (labeled as such), without fragrances, dyes or detergents. The concentration of sodium hypochlorite is usually between 4% and 6%.',
15
+ },
16
+ {
17
+ question: 'How long should I wait before drinking the water?',
18
+ answer:
19
+ 'You must wait at least 30 minutes after adding the bleach. If the water is very cold or cloudy, it is recommended to double the waiting time to 60 minutes or double the dose if it cannot be filtered beforehand.',
20
+ },
21
+ {
22
+ question: 'What do I do if the water smells strongly of chlorine?',
23
+ answer:
24
+ 'A slight smell of chlorine is a sign that the disinfection has worked. If the smell is very strong, you can pour the water from one container to another several times (aeration) or let it sit uncovered for a few hours for the chlorine to evaporate.',
25
+ },
26
+ {
27
+ question: 'Is it better to boil water or use bleach?',
28
+ answer:
29
+ 'Boiling water (at least 1 minute of strong boiling) is the safest method, as it kills all pathogens. Bleach is an excellent alternative in emergency situations where making fire is not possible.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Filter cloudy water',
36
+ text: 'If the water has sediment, filter it using a clean cloth or coffee filter before disinfecting.',
37
+ },
38
+ {
39
+ name: 'Calculate the volume',
40
+ text: 'Measure how many liters of water you will treat (e.g. a 2L bottle or a 10L container).',
41
+ },
42
+ {
43
+ name: 'Add the exact dose',
44
+ text: 'Use our calculator to find out how many drops of bleach you need based on volume and water clarity.',
45
+ },
46
+ {
47
+ name: 'Shake and rest',
48
+ text: 'Mix well and let the closed container rest for 30 minutes before consuming.',
49
+ },
50
+ ];
51
+
52
+ const faqSchema: WithContext<FAQPage> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'FAQPage',
55
+ mainEntity: faqData.map((item) => ({
56
+ '@type': 'Question',
57
+ name: item.question,
58
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
59
+ })),
60
+ };
61
+
62
+ const howToSchema: WithContext<HowToThing> = {
63
+ '@context': 'https://schema.org',
64
+ '@type': 'HowTo',
65
+ name: title,
66
+ description,
67
+ step: howToData.map((step, i) => ({
68
+ '@type': 'HowToStep',
69
+ position: i + 1,
70
+ name: step.name,
71
+ text: step.text,
72
+ })),
73
+ };
74
+
75
+ const appSchema: WithContext<SoftwareApplication> = {
76
+ '@context': 'https://schema.org',
77
+ '@type': 'SoftwareApplication',
78
+ name: title,
79
+ description,
80
+ applicationCategory: 'HealthApplication',
81
+ operatingSystem: 'Web',
82
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
83
+ };
84
+
85
+ export const content: ToolLocaleContent<WaterPurifierUI> = {
86
+ slug,
87
+ title,
88
+ description,
89
+ faqTitle: 'Frequently asked questions about water purification',
90
+ faq: faqData,
91
+ bibliographyTitle: 'References and International Organizations',
92
+ bibliography: [
93
+ {
94
+ name: 'World Health Organization (WHO) - Water Sanitation and Health',
95
+ url: 'https://www.who.int/docs/default-source/coronaviruse/care-cleaning-disinfection-and-sterilization-es.pdf',
96
+ },
97
+ {
98
+ name: 'Centers for Disease Control and Prevention (CDC) - Making Water Safe in an Emergency',
99
+ url: 'https://www.cdc.gov/water-emergency/about/index.html',
100
+ },
101
+ {
102
+ name: 'Red Cross - Water Treatment',
103
+ url: 'https://www.redcross.org/get-help/how-to-prepare-for-emergencies/types-of-emergencies/water-safety/water-treatment.html',
104
+ },
105
+ ],
106
+ howTo: howToData,
107
+ schemas: [faqSchema, howToSchema, appSchema],
108
+ ui: {
109
+ disclaimerTitle: 'CRITICAL WARNING',
110
+ disclaimerText1: 'This tool calculates doses for',
111
+ disclaimerHighlight: 'COMMON BLEACH (Sodium Hypochlorite 5-6%)',
112
+ disclaimerText2:
113
+ 'Never use bleach with fragrances, soaps, or labeled "No Splash". Only plain bleach suitable for disinfection.',
114
+ disclaimerBtn: 'I Understand and Accept',
115
+ paramsSectionTitle: 'Water Parameters',
116
+ conditionLabel: 'Water Condition',
117
+ conditionClear: 'Clear / Warm',
118
+ conditionCloudy: 'Cloudy / Cold',
119
+ litersLabel: 'Amount of Water (Liters)',
120
+ resultLabel: 'Recommended Dose',
121
+ resultUnit: 'drops',
122
+ waitTitle: 'Waiting Time',
123
+ waitBefore: 'You must wait',
124
+ waitDuration: '30 minutes',
125
+ waitAfter: 'before drinking.',
126
+ },
127
+ seo: [
128
+ {
129
+ type: 'summary',
130
+ title: 'Emergency Water Purifier',
131
+ items: [
132
+ '<strong>Drop calculator</strong>: get the exact dose based on water volume and clarity.',
133
+ '<strong>Clear or warm water</strong>: 2 drops of bleach per liter (sodium hypochlorite 5-6%).',
134
+ '<strong>Cloudy or cold water</strong>: 4 drops per liter, filter first with cloth or coffee filter.',
135
+ '<strong>Waiting time</strong>: minimum 30 minutes before consuming.',
136
+ ],
137
+ },
138
+ { type: 'title', text: 'Water Purification in Emergencies', level: 2 },
139
+ {
140
+ type: 'paragraph',
141
+ html: 'Access to drinking water is the number one priority in any survival or emergency situation. When boiling water is not a viable option, chemical disinfection with <strong>common household bleach (sodium hypochlorite)</strong> is an effective method endorsed by global organizations such as the WHO and CDC.',
142
+ },
143
+ {
144
+ type: 'paragraph',
145
+ html: 'This tool provides the exact and safe dose of chlorine needed to eliminate most harmful bacteria and viruses found in untreated water sources.',
146
+ },
147
+ {
148
+ type: 'tip',
149
+ title: 'Important Notice: Unscented Bleach Only',
150
+ html: 'Verify that your bleach contains between <strong>5% and 6% sodium hypochlorite</strong>. Do NOT use scented bleach, "no-splash" bleach (gel), or bleach with added soap. These additives can be toxic if ingested.',
151
+ },
152
+ { type: 'title', text: 'Steps to Purify Water with Bleach', level: 2 },
153
+ {
154
+ type: 'list',
155
+ items: [
156
+ '<strong>Filter:</strong> If the water is cloudy, filter it through a clean cloth, towel or coffee filter. Organic matter reduces the effectiveness of chlorine.',
157
+ '<strong>Dose:</strong> Add the exact number of calculated drops. Shake or stir well to distribute the disinfectant throughout the volume.',
158
+ '<strong>Wait:</strong> Let the water rest for at least 30 minutes before drinking. It should have a faint smell of chlorine as confirmation.',
159
+ ],
160
+ },
161
+ { type: 'title', text: 'How Long Does Treated Water Last', level: 2 },
162
+ {
163
+ type: 'paragraph',
164
+ html: 'If stored in a clean, closed container in a cool, dark place, treated water can last up to <strong>6 months</strong>. It is recommended to label containers with the treatment date. For small quantities (1-5 liters), always use a dropper for precise measurement.',
165
+ },
166
+ ],
167
+ };
@@ -0,0 +1,167 @@
1
+ import type { WithContext, SoftwareApplication, FAQPage, HowToThing } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { WaterPurifierUI } from '../ui';
4
+
5
+ const slug = 'purificador-agua';
6
+ const title = 'Purificador de Agua de Emergencia';
7
+ const description =
8
+ 'Calculadora de dosis de lejía para potabilizar agua de emergencia. Herramienta de supervivencia basada en guías de la OMS y CDC.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: '¿Puedo usar cualquier tipo de lejía para potabilizar agua?',
13
+ answer:
14
+ 'No. Debe ser lejía apta para la desinfección de agua de bebida (etiquetada como tal), sin perfumes, colorantes ni detergentes. La concentración de hipoclorito de sodio suele estar entre el 4% y el 6%.',
15
+ },
16
+ {
17
+ question: '¿Cuánto tiempo debo esperar antes de beber el agua?',
18
+ answer:
19
+ 'Debes esperar al menos 30 minutos después de añadir la lejía. Si el agua está muy fría o turbia, se recomienda duplicar el tiempo de espera a 60 minutos o doblar la dosis si no se puede filtrar previamente.',
20
+ },
21
+ {
22
+ question: '¿Qué hago si el agua huele mucho a cloro?',
23
+ answer:
24
+ 'Un ligero olor a cloro es señal de que la desinfección ha funcionado. Si el olor es muy fuerte, puedes pasar el agua de un recipiente a otro varias veces (aireación) o dejarla reposar destapada unas horas para que el cloro se evapore.',
25
+ },
26
+ {
27
+ question: '¿Es mejor hervir el agua o usar lejía?',
28
+ answer:
29
+ 'Hervir el agua (al menos 1 minuto de ebullición fuerte) es el método más seguro, ya que mata a todos los patógenos. La lejía es una excelente alternativa en situaciones de emergencia donde no es posible hacer fuego.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Filtrar el agua turbia',
36
+ text: 'Si el agua tiene sedimentos, fíltrala usando una tela limpia o un filtro de café antes de desinfectarla.',
37
+ },
38
+ {
39
+ name: 'Calcular el volumen',
40
+ text: 'Mide cuántos litros de agua vas a tratar (ej. una botella de 2L o un bidón de 10L).',
41
+ },
42
+ {
43
+ name: 'Añadir la dosis exacta',
44
+ text: 'Usa nuestra calculadora para saber cuántas gotas de lejía necesitas según el volumen y la claridad del agua.',
45
+ },
46
+ {
47
+ name: 'Agitar y reposar',
48
+ text: 'Mezcla bien y deja reposar el recipiente cerrado durante 30 minutos antes de consumir.',
49
+ },
50
+ ];
51
+
52
+ const faqSchema: WithContext<FAQPage> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'FAQPage',
55
+ mainEntity: faqData.map((item) => ({
56
+ '@type': 'Question',
57
+ name: item.question,
58
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
59
+ })),
60
+ };
61
+
62
+ const howToSchema: WithContext<HowToThing> = {
63
+ '@context': 'https://schema.org',
64
+ '@type': 'HowTo',
65
+ name: title,
66
+ description,
67
+ step: howToData.map((step, i) => ({
68
+ '@type': 'HowToStep',
69
+ position: i + 1,
70
+ name: step.name,
71
+ text: step.text,
72
+ })),
73
+ };
74
+
75
+ const appSchema: WithContext<SoftwareApplication> = {
76
+ '@context': 'https://schema.org',
77
+ '@type': 'SoftwareApplication',
78
+ name: title,
79
+ description,
80
+ applicationCategory: 'HealthApplication',
81
+ operatingSystem: 'Web',
82
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
83
+ };
84
+
85
+ export const content: ToolLocaleContent<WaterPurifierUI> = {
86
+ slug,
87
+ title,
88
+ description,
89
+ faqTitle: 'Preguntas frecuentes sobre potabilización de agua',
90
+ faq: faqData,
91
+ bibliographyTitle: 'Referencias y Organismos Internacionales',
92
+ bibliography: [
93
+ {
94
+ name: 'World Health Organization (WHO) - Water Sanitation and Health',
95
+ url: 'https://www.who.int/docs/default-source/coronaviruse/care-cleaning-disinfection-and-sterilization-es.pdf',
96
+ },
97
+ {
98
+ name: 'Centers for Disease Control and Prevention (CDC) - Making Water Safe in an Emergency',
99
+ url: 'https://www.cdc.gov/water-emergency/about/index.html',
100
+ },
101
+ {
102
+ name: 'Red Cross - Water Treatment',
103
+ url: 'https://www.redcross.org/get-help/how-to-prepare-for-emergencies/types-of-emergencies/water-safety/water-treatment.html',
104
+ },
105
+ ],
106
+ howTo: howToData,
107
+ schemas: [faqSchema, howToSchema, appSchema],
108
+ ui: {
109
+ disclaimerTitle: 'ADVERTENCIA CRÍTICA',
110
+ disclaimerText1: 'Esta herramienta calcula dosis para',
111
+ disclaimerHighlight: 'LEJÍA COMÚN (Hipoclorito de Sodio al 5-6%)',
112
+ disclaimerText2:
113
+ 'Nunca utilices lejía con perfumes, jabones, ni la etiqueta "No salpica". Solo lejía pura apta para desinfección.',
114
+ disclaimerBtn: 'Entiendo y Acepto',
115
+ paramsSectionTitle: 'Parámetros del Agua',
116
+ conditionLabel: 'Estado del Agua',
117
+ conditionClear: 'Clara / Tibia',
118
+ conditionCloudy: 'Turbia / Fría',
119
+ litersLabel: 'Cantidad de Agua (Litros)',
120
+ resultLabel: 'Dosis Recomendada',
121
+ resultUnit: 'gotas',
122
+ waitTitle: 'Tiempo de Espera',
123
+ waitBefore: 'Debes esperar',
124
+ waitDuration: '30 minutos',
125
+ waitAfter: 'antes de beber.',
126
+ },
127
+ seo: [
128
+ {
129
+ type: 'summary',
130
+ title: 'Purificador de Agua de Emergencia',
131
+ items: [
132
+ '<strong>Calculadora de gotas</strong>: obtén la dosis exacta según el volumen y claridad del agua.',
133
+ '<strong>Agua clara o tibia</strong>: 2 gotas de lejía por litro (hipoclorito de sodio 5-6%).',
134
+ '<strong>Agua turbia o fría</strong>: 4 gotas por litro, filtrar previamente con tela o filtro de café.',
135
+ '<strong>Tiempo de espera</strong>: mínimo 30 minutos antes de consumir.',
136
+ ],
137
+ },
138
+ { type: 'title', text: 'Potabilización de Agua en Emergencias', level: 2 },
139
+ {
140
+ type: 'paragraph',
141
+ html: 'El acceso a agua potable es la prioridad número uno en cualquier situación de supervivencia o emergencia. Cuando hervir el agua no es una opción viable, la desinfección química con <strong>lejía doméstica común (hipoclorito de sodio)</strong> es un método efectivo y avalado por organizaciones globales como la OMS y los CDC.',
142
+ },
143
+ {
144
+ type: 'paragraph',
145
+ html: 'Esta herramienta proporciona la dosis exacta y segura de cloro necesaria para eliminar la mayoría de bacterias y virus dañinos presentes en fuentes de agua no tratada.',
146
+ },
147
+ {
148
+ type: 'tip',
149
+ title: 'Aviso Importante: Solo Lejía Sin Perfume',
150
+ html: 'Verifica que tu lejía contenga entre el <strong>5% y 6% de hipoclorito de sodio</strong>. NO uses lejía con aroma, lejía "ante-salpicaduras" (gel), ni lejía con jabón añadido. Estos aditivos pueden ser tóxicos si se ingieren.',
151
+ },
152
+ { type: 'title', text: 'Pasos para Potabilizar Agua con Lejía', level: 2 },
153
+ {
154
+ type: 'list',
155
+ items: [
156
+ '<strong>Filtrar:</strong> Si el agua está turbia, fíltrala a través de un paño limpio, toalla o filtro de café. La materia orgánica reduce la efectividad del cloro.',
157
+ '<strong>Dosificar:</strong> Añade la cantidad exacta de gotas calculada. Agita o mezcla bien para distribuir el desinfectante por todo el volumen.',
158
+ '<strong>Esperar:</strong> Deja reposar el agua durante al menos 30 minutos antes de beberla. Debe tener un ligero olor a cloro como confirmación.',
159
+ ],
160
+ },
161
+ { type: 'title', text: 'Cuánto Dura el Agua Tratada', level: 2 },
162
+ {
163
+ type: 'paragraph',
164
+ html: 'Si se almacena en un recipiente limpio y cerrado, en un lugar fresco y oscuro, el agua tratada puede durar hasta <strong>6 meses</strong>. Es recomendable etiquetar los recipientes con la fecha de tratamiento. Para cantidades pequeñas (1-5 litros), usa siempre un gotero para una medición precisa.',
165
+ },
166
+ ],
167
+ };
@@ -0,0 +1,167 @@
1
+ import type { WithContext, SoftwareApplication, FAQPage, HowToThing } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { WaterPurifierUI } from '../ui';
4
+
5
+ const slug = 'purificateur-eau';
6
+ const title = "Purificateur d'Eau d'Urgence";
7
+ const description =
8
+ "Calculateur de doses de javel pour potabiliser l'eau en situation d'urgence. Outil de survie basé sur les recommandations de l'OMS et des CDC.";
9
+
10
+ const faqData = [
11
+ {
12
+ question: "Puis-je utiliser n'importe quel type d'eau de javel pour purifier l'eau?",
13
+ answer:
14
+ "Non. Il doit s'agir d'eau de javel adaptée à la désinfection de l'eau potable (étiquetée comme telle), sans parfums, colorants ni détergents. La concentration en hypochlorite de sodium est généralement comprise entre 4% et 6%.",
15
+ },
16
+ {
17
+ question: "Combien de temps dois-je attendre avant de boire l'eau?",
18
+ answer:
19
+ "Vous devez attendre au moins 30 minutes après avoir ajouté l'eau de javel. Si l'eau est très froide ou trouble, il est recommandé de doubler le temps d'attente à 60 minutes ou de doubler la dose si elle ne peut pas être filtrée au préalable.",
20
+ },
21
+ {
22
+ question: "Que faire si l'eau sent fortement le chlore?",
23
+ answer:
24
+ "Une légère odeur de chlore est le signe que la désinfection a fonctionné. Si l'odeur est très forte, vous pouvez transvaser l'eau d'un récipient à l'autre plusieurs fois (aération) ou la laisser reposer à découvert quelques heures pour que le chlore s'évapore.",
25
+ },
26
+ {
27
+ question: "Vaut-il mieux faire bouillir l'eau ou utiliser de la javel?",
28
+ answer:
29
+ "Faire bouillir l'eau (au moins 1 minute d'ébullition vigoureuse) est la méthode la plus sûre car elle tue tous les agents pathogènes. L'eau de javel est une excellente alternative dans les situations d'urgence où il n'est pas possible de faire du feu.",
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: "Filtrer l'eau trouble",
36
+ text: "Si l'eau contient des sédiments, filtrez-la à l'aide d'un chiffon propre ou d'un filtre à café avant de la désinfecter.",
37
+ },
38
+ {
39
+ name: 'Calculer le volume',
40
+ text: "Mesurez combien de litres d'eau vous allez traiter (ex. une bouteille de 2L ou un bidon de 10L).",
41
+ },
42
+ {
43
+ name: 'Ajouter la dose exacte',
44
+ text: "Utilisez notre calculateur pour savoir combien de gouttes de javel vous avez besoin selon le volume et la clarté de l'eau.",
45
+ },
46
+ {
47
+ name: 'Agiter et laisser reposer',
48
+ text: 'Mélangez bien et laissez reposer le récipient fermé pendant 30 minutes avant de consommer.',
49
+ },
50
+ ];
51
+
52
+ const faqSchema: WithContext<FAQPage> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'FAQPage',
55
+ mainEntity: faqData.map((item) => ({
56
+ '@type': 'Question',
57
+ name: item.question,
58
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
59
+ })),
60
+ };
61
+
62
+ const howToSchema: WithContext<HowToThing> = {
63
+ '@context': 'https://schema.org',
64
+ '@type': 'HowTo',
65
+ name: title,
66
+ description,
67
+ step: howToData.map((step, i) => ({
68
+ '@type': 'HowToStep',
69
+ position: i + 1,
70
+ name: step.name,
71
+ text: step.text,
72
+ })),
73
+ };
74
+
75
+ const appSchema: WithContext<SoftwareApplication> = {
76
+ '@context': 'https://schema.org',
77
+ '@type': 'SoftwareApplication',
78
+ name: title,
79
+ description,
80
+ applicationCategory: 'HealthApplication',
81
+ operatingSystem: 'Web',
82
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
83
+ };
84
+
85
+ export const content: ToolLocaleContent<WaterPurifierUI> = {
86
+ slug,
87
+ title,
88
+ description,
89
+ faqTitle: "Questions fréquentes sur la potabilisation de l'eau",
90
+ faq: faqData,
91
+ bibliographyTitle: 'Références et Organismes Internationaux',
92
+ bibliography: [
93
+ {
94
+ name: 'World Health Organization (WHO) - Water Sanitation and Health',
95
+ url: 'https://www.who.int/docs/default-source/coronaviruse/care-cleaning-disinfection-and-sterilization-es.pdf',
96
+ },
97
+ {
98
+ name: 'Centers for Disease Control and Prevention (CDC) - Making Water Safe in an Emergency',
99
+ url: 'https://www.cdc.gov/water-emergency/about/index.html',
100
+ },
101
+ {
102
+ name: 'Red Cross - Water Treatment',
103
+ url: 'https://www.redcross.org/get-help/how-to-prepare-for-emergencies/types-of-emergencies/water-safety/water-treatment.html',
104
+ },
105
+ ],
106
+ howTo: howToData,
107
+ schemas: [faqSchema, howToSchema, appSchema],
108
+ ui: {
109
+ disclaimerTitle: 'AVERTISSEMENT CRITIQUE',
110
+ disclaimerText1: 'Cet outil calcule des doses pour',
111
+ disclaimerHighlight: "EAU DE JAVEL COMMUNE (Hypochlorite de Sodium 5-6%)",
112
+ disclaimerText2:
113
+ 'N\'utilisez jamais d\'eau de javel parfumée, savonneuse ou étiquetée "Sans éclaboussures". Uniquement de la javel pure adaptée à la désinfection.',
114
+ disclaimerBtn: 'Je Comprends et J\'Accepte',
115
+ paramsSectionTitle: "Paramètres de l'Eau",
116
+ conditionLabel: "État de l'Eau",
117
+ conditionClear: 'Claire / Tiède',
118
+ conditionCloudy: 'Trouble / Froide',
119
+ litersLabel: "Quantité d'Eau (Litres)",
120
+ resultLabel: 'Dose Recommandée',
121
+ resultUnit: 'gouttes',
122
+ waitTitle: "Temps d'Attente",
123
+ waitBefore: 'Vous devez attendre',
124
+ waitDuration: '30 minutes',
125
+ waitAfter: 'avant de boire.',
126
+ },
127
+ seo: [
128
+ {
129
+ type: 'summary',
130
+ title: "Purificateur d'Eau d'Urgence",
131
+ items: [
132
+ '<strong>Calculateur de gouttes</strong>: obtenez la dose exacte selon le volume et la clarté de l\'eau.',
133
+ '<strong>Eau claire ou tiède</strong>: 2 gouttes de javel par litre (hypochlorite de sodium 5-6%).',
134
+ '<strong>Eau trouble ou froide</strong>: 4 gouttes par litre, filtrer au préalable avec un chiffon ou filtre à café.',
135
+ '<strong>Temps d\'attente</strong>: minimum 30 minutes avant de consommer.',
136
+ ],
137
+ },
138
+ { type: 'title', text: "Potabilisation de l'Eau en Situation d'Urgence", level: 2 },
139
+ {
140
+ type: 'paragraph',
141
+ html: "L'accès à l'eau potable est la priorité numéro un dans toute situation de survie ou d'urgence. Lorsque faire bouillir l'eau n'est pas une option viable, la désinfection chimique avec <strong>l'eau de javel ménagère commune (hypochlorite de sodium)</strong> est une méthode efficace approuvée par des organisations mondiales comme l'OMS et les CDC.",
142
+ },
143
+ {
144
+ type: 'paragraph',
145
+ html: "Cet outil fournit la dose exacte et sûre de chlore nécessaire pour éliminer la plupart des bactéries et virus nocifs présents dans les sources d'eau non traitée.",
146
+ },
147
+ {
148
+ type: 'tip',
149
+ title: 'Avis Important: Javel Sans Parfum Uniquement',
150
+ html: 'Vérifiez que votre eau de javel contient entre <strong>5% et 6% d\'hypochlorite de sodium</strong>. N\'utilisez PAS de javel parfumée, de javel "sans éclaboussures" (gel), ni de javel avec du savon ajouté. Ces additifs peuvent être toxiques en cas d\'ingestion.',
151
+ },
152
+ { type: 'title', text: "Étapes pour Purifier l'Eau avec de la Javel", level: 2 },
153
+ {
154
+ type: 'list',
155
+ items: [
156
+ "<strong>Filtrer:</strong> Si l'eau est trouble, filtrez-la à travers un chiffon propre, une serviette ou un filtre à café. La matière organique réduit l'efficacité du chlore.",
157
+ '<strong>Doser:</strong> Ajoutez le nombre exact de gouttes calculé. Agitez ou mélangez bien pour distribuer le désinfectant dans tout le volume.',
158
+ "<strong>Attendre:</strong> Laissez l'eau reposer pendant au moins 30 minutes avant de boire. Elle doit avoir une légère odeur de chlore comme confirmation.",
159
+ ],
160
+ },
161
+ { type: 'title', text: "Durée de Conservation de l'Eau Traitée", level: 2 },
162
+ {
163
+ type: 'paragraph',
164
+ html: "Si elle est stockée dans un récipient propre et fermé, dans un endroit frais et sombre, l'eau traitée peut se conserver jusqu'à <strong>6 mois</strong>. Il est recommandé d'étiqueter les récipients avec la date de traitement.",
165
+ },
166
+ ],
167
+ };
@@ -0,0 +1,27 @@
1
+ import type { HealthToolEntry, ToolDefinition } from '../../types';
2
+ import WaterPurifierComponent from './component.astro';
3
+ import WaterPurifierSEO from './seo.astro';
4
+ import WaterPurifierBibliography from './bibliography.astro';
5
+ import type { WaterPurifierUI } from './ui';
6
+
7
+ export const waterPurifier: HealthToolEntry<WaterPurifierUI> = {
8
+ id: 'waterPurifier',
9
+ icons: {
10
+ bg: 'mdi:water-plus',
11
+ fg: 'mdi:eyedropper',
12
+ },
13
+ i18n: {
14
+ es: () => import('./i18n/es').then((m) => m.content),
15
+ en: () => import('./i18n/en').then((m) => m.content),
16
+ fr: () => import('./i18n/fr').then((m) => m.content),
17
+ },
18
+ };
19
+
20
+ export { WaterPurifierComponent, WaterPurifierSEO, WaterPurifierBibliography };
21
+
22
+ export const WATER_PURIFIER_TOOL: ToolDefinition = {
23
+ entry: waterPurifier,
24
+ Component: WaterPurifierComponent,
25
+ SEOComponent: WaterPurifierSEO,
26
+ BibliographyComponent: WaterPurifierBibliography,
27
+ };
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { waterPurifier } 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 waterPurifier.i18n[locale]?.();
12
+ ---
13
+
14
+ {content && <SEORenderer content={{ locale, sections: content.seo }} />}
@@ -0,0 +1,18 @@
1
+ export interface WaterPurifierUI extends Record<string, string> {
2
+ disclaimerTitle: string;
3
+ disclaimerText1: string;
4
+ disclaimerHighlight: string;
5
+ disclaimerText2: string;
6
+ disclaimerBtn: string;
7
+ paramsSectionTitle: string;
8
+ conditionLabel: string;
9
+ conditionClear: string;
10
+ conditionCloudy: string;
11
+ litersLabel: string;
12
+ resultLabel: string;
13
+ resultUnit: string;
14
+ waitTitle: string;
15
+ waitBefore: string;
16
+ waitDuration: string;
17
+ waitAfter: string;
18
+ }
package/src/tools.ts ADDED
@@ -0,0 +1,19 @@
1
+ import type { ToolDefinition } from './types';
2
+ import { BMI_CALCULATOR_TOOL } from './tool/bmiCalculator';
3
+ import { DALTONISM_SIMULATOR_TOOL } from './tool/daltonismSimulator';
4
+ import { TINNITUS_RELIEVER_TOOL } from './tool/tinnitusReliever';
5
+ import { BREATHING_VISUALIZER_TOOL } from './tool/breathingVisualizer';
6
+ import { CAFFEINE_TRACKER_TOOL } from './tool/caffeineTracker';
7
+ import { WATER_PURIFIER_TOOL } from './tool/waterPurifier';
8
+ import { DIGESTION_STOPWATCH_TOOL } from './tool/digestionStopwatch';
9
+ import { BINAURAL_TUNER_TOOL } from './tool/binauralTuner';
10
+ import { PELLI_ROBSON_TEST_TOOL } from './tool/pelliRobsonTest';
11
+ import { PERIPHERAL_VISION_TRAINER_TOOL } from './tool/peripheralVisionTrainer';
12
+ import { EPWORTH_SLEEPINESS_SCALE_TOOL } from './tool/epworthSleepinessScale';
13
+ import { UBE_CALCULATOR_TOOL } from './tool/ubeCalculator';
14
+ import { SCREEN_DECOMPRESSION_TIME_TOOL } from './tool/screenDecompressionTime';
15
+ import { BLOOD_UNIT_CONVERTER_TOOL } from './tool/bloodUnitConverter';
16
+ import { READING_DISTANCE_CALCULATOR_TOOL } from './tool/readingDistanceCalculator';
17
+ import { HYDRATION_CALCULATOR_TOOL } from './tool/hydrationCalculator';
18
+
19
+ export const ALL_TOOLS: ToolDefinition[] = [BMI_CALCULATOR_TOOL, DALTONISM_SIMULATOR_TOOL, TINNITUS_RELIEVER_TOOL, BREATHING_VISUALIZER_TOOL, CAFFEINE_TRACKER_TOOL, WATER_PURIFIER_TOOL, DIGESTION_STOPWATCH_TOOL, BINAURAL_TUNER_TOOL, PELLI_ROBSON_TEST_TOOL, PERIPHERAL_VISION_TRAINER_TOOL, EPWORTH_SLEEPINESS_SCALE_TOOL, UBE_CALCULATOR_TOOL, SCREEN_DECOMPRESSION_TIME_TOOL, BLOOD_UNIT_CONVERTER_TOOL, READING_DISTANCE_CALCULATOR_TOOL, HYDRATION_CALCULATOR_TOOL];
package/src/types.ts ADDED
@@ -0,0 +1,72 @@
1
+ import type { SEOSection } from '@jjlmoya/utils-shared';
2
+ import type { WithContext, Thing } from 'schema-dts';
3
+
4
+ export type { SEOSection };
5
+
6
+ export type KnownLocale =
7
+ | 'ar' | 'da' | 'de' | 'en' | 'es' | 'fi'
8
+ | 'fr' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
9
+ | 'pl' | 'pt' | 'ru' | 'sv' | 'tr' | 'zh';
10
+
11
+ export interface FAQItem {
12
+ question: string;
13
+ answer: string;
14
+ }
15
+
16
+ export interface BibliographyEntry {
17
+ name: string;
18
+ url: string;
19
+ }
20
+
21
+ export interface HowToStep {
22
+ name: string;
23
+ text: string;
24
+ }
25
+
26
+ export interface ToolLocaleContent<TUI extends Record<string, string> = Record<string, string>> {
27
+ slug: string;
28
+ title: string;
29
+ description: string;
30
+ ui: TUI;
31
+ seo: SEOSection[];
32
+ faqTitle?: string;
33
+ faq: FAQItem[];
34
+ bibliographyTitle?: string;
35
+ bibliography: BibliographyEntry[];
36
+ howTo: HowToStep[];
37
+ schemas: WithContext<Thing>[];
38
+ }
39
+
40
+ export interface CategoryLocaleContent {
41
+ slug: string;
42
+ title: string;
43
+ description: string;
44
+ seo: SEOSection[];
45
+ }
46
+
47
+ export type LocaleLoader<T> = () => Promise<T>;
48
+
49
+ export type LocaleMap<T> = Partial<Record<KnownLocale, LocaleLoader<T>>>;
50
+
51
+ export interface HealthToolEntry<TUI extends Record<string, string> = Record<string, string>> {
52
+ id: string;
53
+ icons: {
54
+ bg: string;
55
+ fg: string;
56
+ };
57
+ i18n: LocaleMap<ToolLocaleContent<TUI>>;
58
+ }
59
+
60
+ export interface HealthCategoryEntry {
61
+ icon: string;
62
+ tools: HealthToolEntry[];
63
+ i18n: LocaleMap<CategoryLocaleContent>;
64
+ }
65
+
66
+ export interface ToolDefinition {
67
+ entry: HealthToolEntry;
68
+ Component: unknown;
69
+ SEOComponent: unknown;
70
+ BibliographyComponent: unknown;
71
+ }
72
+