@jjlmoya/utils-science 1.19.0 → 1.21.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 (164) hide show
  1. package/package.json +2 -1
  2. package/src/category/i18n/de.ts +1 -1
  3. package/src/category/i18n/fr.ts +6 -6
  4. package/src/category/i18n/ru.ts +1 -1
  5. package/src/category/index.ts +3 -1
  6. package/src/category/seo.astro +2 -2
  7. package/src/entries.ts +5 -1
  8. package/src/index.ts +2 -0
  9. package/src/pages/[locale]/[slug].astro +32 -15
  10. package/src/tests/locale_completeness.test.ts +5 -22
  11. package/src/tests/no_en_dash.test.ts +70 -0
  12. package/src/tests/seo_length.test.ts +5 -3
  13. package/src/tests/shared-test-helpers.ts +56 -0
  14. package/src/tests/title_quality.test.ts +1 -1
  15. package/src/tests/tool_exports.test.ts +34 -0
  16. package/src/tests/tool_validation.test.ts +2 -2
  17. package/src/tool/asteroid-impact/bibliography.astro +2 -2
  18. package/src/tool/asteroid-impact/bibliography.ts +24 -0
  19. package/src/tool/asteroid-impact/component.astro +16 -9
  20. package/src/tool/asteroid-impact/i18n/de.ts +4 -24
  21. package/src/tool/asteroid-impact/i18n/en.ts +4 -24
  22. package/src/tool/asteroid-impact/i18n/es.ts +4 -24
  23. package/src/tool/asteroid-impact/i18n/fr.ts +10 -30
  24. package/src/tool/asteroid-impact/i18n/id.ts +4 -24
  25. package/src/tool/asteroid-impact/i18n/it.ts +4 -24
  26. package/src/tool/asteroid-impact/i18n/ja.ts +4 -24
  27. package/src/tool/asteroid-impact/i18n/ko.ts +4 -24
  28. package/src/tool/asteroid-impact/i18n/nl.ts +4 -24
  29. package/src/tool/asteroid-impact/i18n/pl.ts +4 -24
  30. package/src/tool/asteroid-impact/i18n/pt.ts +4 -24
  31. package/src/tool/asteroid-impact/i18n/ru.ts +8 -28
  32. package/src/tool/asteroid-impact/i18n/sv.ts +4 -24
  33. package/src/tool/asteroid-impact/i18n/tr.ts +4 -24
  34. package/src/tool/asteroid-impact/i18n/zh.ts +4 -24
  35. package/src/tool/asteroid-impact/index.ts +1 -0
  36. package/src/tool/asteroid-impact/script.ts +13 -7
  37. package/src/tool/asteroid-impact/seo.astro +1 -1
  38. package/src/tool/cellular-renewal/bibliography.astro +2 -2
  39. package/src/tool/cellular-renewal/bibliography.ts +24 -0
  40. package/src/tool/cellular-renewal/i18n/de.ts +3 -24
  41. package/src/tool/cellular-renewal/i18n/en.ts +3 -24
  42. package/src/tool/cellular-renewal/i18n/es.ts +3 -24
  43. package/src/tool/cellular-renewal/i18n/fr.ts +16 -37
  44. package/src/tool/cellular-renewal/i18n/id.ts +3 -24
  45. package/src/tool/cellular-renewal/i18n/it.ts +3 -24
  46. package/src/tool/cellular-renewal/i18n/ja.ts +3 -24
  47. package/src/tool/cellular-renewal/i18n/ko.ts +3 -24
  48. package/src/tool/cellular-renewal/i18n/nl.ts +3 -24
  49. package/src/tool/cellular-renewal/i18n/pl.ts +3 -24
  50. package/src/tool/cellular-renewal/i18n/pt.ts +3 -24
  51. package/src/tool/cellular-renewal/i18n/ru.ts +20 -41
  52. package/src/tool/cellular-renewal/i18n/sv.ts +3 -24
  53. package/src/tool/cellular-renewal/i18n/tr.ts +3 -24
  54. package/src/tool/cellular-renewal/i18n/zh.ts +12 -33
  55. package/src/tool/cellular-renewal/index.ts +1 -0
  56. package/src/tool/cellular-renewal/seo.astro +2 -1
  57. package/src/tool/colony-counter/bibliography.astro +2 -2
  58. package/src/tool/colony-counter/bibliography.ts +12 -0
  59. package/src/tool/colony-counter/i18n/de.ts +3 -12
  60. package/src/tool/colony-counter/i18n/en.ts +3 -12
  61. package/src/tool/colony-counter/i18n/es.ts +3 -12
  62. package/src/tool/colony-counter/i18n/fr.ts +3 -12
  63. package/src/tool/colony-counter/i18n/id.ts +3 -12
  64. package/src/tool/colony-counter/i18n/it.ts +3 -12
  65. package/src/tool/colony-counter/i18n/ja.ts +3 -12
  66. package/src/tool/colony-counter/i18n/ko.ts +3 -12
  67. package/src/tool/colony-counter/i18n/nl.ts +3 -12
  68. package/src/tool/colony-counter/i18n/pl.ts +3 -12
  69. package/src/tool/colony-counter/i18n/pt.ts +3 -12
  70. package/src/tool/colony-counter/i18n/ru.ts +8 -17
  71. package/src/tool/colony-counter/i18n/sv.ts +3 -12
  72. package/src/tool/colony-counter/i18n/tr.ts +3 -12
  73. package/src/tool/colony-counter/i18n/zh.ts +5 -14
  74. package/src/tool/colony-counter/index.ts +1 -0
  75. package/src/tool/colony-counter/seo.astro +1 -1
  76. package/src/tool/cosmic-inflation/bibliography.astro +14 -0
  77. package/src/tool/cosmic-inflation/bibliography.ts +12 -0
  78. package/src/tool/cosmic-inflation/component.astro +270 -0
  79. package/src/tool/cosmic-inflation/cosmic-inflation-calculator.css +277 -0
  80. package/src/tool/cosmic-inflation/entry.ts +26 -0
  81. package/src/tool/cosmic-inflation/i18n/de.ts +188 -0
  82. package/src/tool/cosmic-inflation/i18n/en.ts +188 -0
  83. package/src/tool/cosmic-inflation/i18n/es.ts +168 -0
  84. package/src/tool/cosmic-inflation/i18n/fr.ts +188 -0
  85. package/src/tool/cosmic-inflation/i18n/id.ts +188 -0
  86. package/src/tool/cosmic-inflation/i18n/it.ts +188 -0
  87. package/src/tool/cosmic-inflation/i18n/ja.ts +188 -0
  88. package/src/tool/cosmic-inflation/i18n/ko.ts +188 -0
  89. package/src/tool/cosmic-inflation/i18n/nl.ts +188 -0
  90. package/src/tool/cosmic-inflation/i18n/pl.ts +188 -0
  91. package/src/tool/cosmic-inflation/i18n/pt.ts +188 -0
  92. package/src/tool/cosmic-inflation/i18n/ru.ts +188 -0
  93. package/src/tool/cosmic-inflation/i18n/sv.ts +188 -0
  94. package/src/tool/cosmic-inflation/i18n/tr.ts +188 -0
  95. package/src/tool/cosmic-inflation/i18n/zh.ts +188 -0
  96. package/src/tool/cosmic-inflation/index.ts +11 -0
  97. package/src/tool/cosmic-inflation/logic/CosmicInflationEngine.ts +21 -0
  98. package/src/tool/cosmic-inflation/seo.astro +15 -0
  99. package/src/tool/microwave-detector/bibliography.astro +2 -2
  100. package/src/tool/microwave-detector/bibliography.ts +16 -0
  101. package/src/tool/microwave-detector/component.astro +9 -7
  102. package/src/tool/microwave-detector/i18n/de.ts +3 -16
  103. package/src/tool/microwave-detector/i18n/en.ts +3 -16
  104. package/src/tool/microwave-detector/i18n/es.ts +3 -16
  105. package/src/tool/microwave-detector/i18n/fr.ts +7 -20
  106. package/src/tool/microwave-detector/i18n/id.ts +3 -16
  107. package/src/tool/microwave-detector/i18n/it.ts +3 -16
  108. package/src/tool/microwave-detector/i18n/ja.ts +3 -16
  109. package/src/tool/microwave-detector/i18n/ko.ts +3 -16
  110. package/src/tool/microwave-detector/i18n/nl.ts +3 -16
  111. package/src/tool/microwave-detector/i18n/pl.ts +3 -16
  112. package/src/tool/microwave-detector/i18n/pt.ts +3 -16
  113. package/src/tool/microwave-detector/i18n/ru.ts +21 -34
  114. package/src/tool/microwave-detector/i18n/sv.ts +3 -16
  115. package/src/tool/microwave-detector/i18n/tr.ts +3 -16
  116. package/src/tool/microwave-detector/i18n/zh.ts +13 -26
  117. package/src/tool/microwave-detector/index.ts +1 -0
  118. package/src/tool/microwave-detector/logic/MicrowaveEngine.ts +5 -1
  119. package/src/tool/microwave-detector/microwave-leak-detector.css +22 -25
  120. package/src/tool/microwave-detector/seo.astro +2 -1
  121. package/src/tool/simulation-probability/bibliography.astro +2 -2
  122. package/src/tool/simulation-probability/bibliography.ts +24 -0
  123. package/src/tool/simulation-probability/i18n/de.ts +3 -24
  124. package/src/tool/simulation-probability/i18n/en.ts +3 -24
  125. package/src/tool/simulation-probability/i18n/es.ts +3 -24
  126. package/src/tool/simulation-probability/i18n/fr.ts +8 -29
  127. package/src/tool/simulation-probability/i18n/id.ts +3 -24
  128. package/src/tool/simulation-probability/i18n/it.ts +3 -24
  129. package/src/tool/simulation-probability/i18n/ja.ts +3 -24
  130. package/src/tool/simulation-probability/i18n/ko.ts +3 -24
  131. package/src/tool/simulation-probability/i18n/nl.ts +3 -24
  132. package/src/tool/simulation-probability/i18n/pl.ts +3 -24
  133. package/src/tool/simulation-probability/i18n/pt.ts +3 -24
  134. package/src/tool/simulation-probability/i18n/ru.ts +10 -31
  135. package/src/tool/simulation-probability/i18n/sv.ts +3 -24
  136. package/src/tool/simulation-probability/i18n/tr.ts +3 -24
  137. package/src/tool/simulation-probability/i18n/zh.ts +7 -28
  138. package/src/tool/simulation-probability/index.ts +1 -0
  139. package/src/tool/simulation-probability/seo.astro +2 -1
  140. package/src/tool/temperature-timeline/bibliography.astro +14 -0
  141. package/src/tool/temperature-timeline/bibliography.ts +12 -0
  142. package/src/tool/temperature-timeline/component.astro +289 -0
  143. package/src/tool/temperature-timeline/entry.ts +26 -0
  144. package/src/tool/temperature-timeline/i18n/de.ts +213 -0
  145. package/src/tool/temperature-timeline/i18n/en.ts +213 -0
  146. package/src/tool/temperature-timeline/i18n/es.ts +178 -0
  147. package/src/tool/temperature-timeline/i18n/fr.ts +213 -0
  148. package/src/tool/temperature-timeline/i18n/id.ts +213 -0
  149. package/src/tool/temperature-timeline/i18n/it.ts +213 -0
  150. package/src/tool/temperature-timeline/i18n/ja.ts +213 -0
  151. package/src/tool/temperature-timeline/i18n/ko.ts +213 -0
  152. package/src/tool/temperature-timeline/i18n/nl.ts +213 -0
  153. package/src/tool/temperature-timeline/i18n/pl.ts +213 -0
  154. package/src/tool/temperature-timeline/i18n/pt.ts +213 -0
  155. package/src/tool/temperature-timeline/i18n/ru.ts +213 -0
  156. package/src/tool/temperature-timeline/i18n/sv.ts +213 -0
  157. package/src/tool/temperature-timeline/i18n/tr.ts +213 -0
  158. package/src/tool/temperature-timeline/i18n/zh.ts +213 -0
  159. package/src/tool/temperature-timeline/index.ts +11 -0
  160. package/src/tool/temperature-timeline/logic/TemperatureTimelineEngine.ts +58 -0
  161. package/src/tool/temperature-timeline/planet-temperature-timeline.css +158 -0
  162. package/src/tool/temperature-timeline/seo.astro +15 -0
  163. package/src/tools.ts +4 -0
  164. package/src/types.ts +1 -3
@@ -0,0 +1,58 @@
1
+ export interface GeologicEpoch {
2
+ id: string;
3
+ name: string;
4
+ ageRange: string;
5
+ avgTemp: number;
6
+ description: string;
7
+ }
8
+
9
+ export class TemperatureTimelineEngine {
10
+ private epochs: GeologicEpoch[] = [
11
+ {
12
+ id: 'archean',
13
+ name: 'Archean Eon',
14
+ ageRange: '4.0 to 2.5 billion years ago',
15
+ avgTemp: 30,
16
+ description: 'Extremely hot earth with a methane and carbon dioxide rich atmosphere. Liquid oceans existed despite a faint young sun due to greenhouse effect.',
17
+ },
18
+ {
19
+ id: 'proterozoic',
20
+ name: 'Proterozoic Eon',
21
+ ageRange: '2.5 billion to 541 million years ago',
22
+ avgTemp: 12,
23
+ description: 'Rise of oxygen causes the Huronian glaciation, leading to one of the first Snowball Earth periods, followed by stabilization.',
24
+ },
25
+ {
26
+ id: 'paleozoic',
27
+ name: 'Paleozoic Era',
28
+ ageRange: '541 to 252 million years ago',
29
+ avgTemp: 20,
30
+ description: 'Explosion of life in oceans and migration to land. Ended with the Permian-Triassic extinction, the warmest phase of this era.',
31
+ },
32
+ {
33
+ id: 'mesozoic',
34
+ name: 'Mesozoic Era',
35
+ ageRange: '252 to 66 million years ago',
36
+ avgTemp: 22,
37
+ description: 'The age of dinosaurs. Greenhouse conditions prevailed worldwide with no polar ice caps, resulting in high ocean levels and warm climates.',
38
+ },
39
+ {
40
+ id: 'cenozoic',
41
+ name: 'Cenozoic Era',
42
+ ageRange: '66 million years ago to Present',
43
+ avgTemp: 14,
44
+ description: 'Gradual cooling trend culminating in the Quaternary glaciations (Ice Ages) and the modern Holocene epoch.',
45
+ },
46
+ {
47
+ id: 'anthropocene',
48
+ name: 'Anthropocene Epoch',
49
+ ageRange: 'Present Day and Future',
50
+ avgTemp: 15.2,
51
+ description: 'Rapid warming driven by greenhouse gas emissions, deviating from the long term natural cooling trend of the late Cenozoic.',
52
+ },
53
+ ];
54
+
55
+ public getEpochs(): GeologicEpoch[] {
56
+ return this.epochs;
57
+ }
58
+ }
@@ -0,0 +1,158 @@
1
+ :root {
2
+ --timeline-bg: #fff;
3
+ --timeline-border: rgba(0, 0, 0, 0.08);
4
+ --timeline-text: #0f172a;
5
+ --timeline-text-muted: #4b5563;
6
+ --timeline-divider: rgba(0, 0, 0, 0.1);
7
+ --timeline-highlight: #ea580c;
8
+ --timeline-ruler-text: #6b7280;
9
+ }
10
+
11
+ .theme-dark {
12
+ --timeline-bg: #030712;
13
+ --timeline-border: rgba(255, 255, 255, 0.05);
14
+ --timeline-text: #f3f4f6;
15
+ --timeline-text-muted: #9ca3af;
16
+ --timeline-divider: rgba(255, 255, 255, 0.1);
17
+ --timeline-highlight: #fb923c;
18
+ --timeline-ruler-text: #9ca3af;
19
+ }
20
+
21
+ .timeline-root {
22
+ position: relative;
23
+ display: flex;
24
+ flex-direction: column;
25
+ justify-content: center;
26
+ align-items: center;
27
+ padding: 3rem;
28
+ background: var(--timeline-bg);
29
+ color: var(--timeline-text);
30
+ border-radius: 2rem;
31
+ border: 1px solid var(--timeline-border);
32
+ max-width: 800px;
33
+ margin: 0 auto;
34
+ min-height: 580px;
35
+ overflow: hidden;
36
+ user-select: none;
37
+ transition: box-shadow 0.5s ease;
38
+ }
39
+
40
+ .timeline-canvas-container {
41
+ position: absolute;
42
+ inset: 0;
43
+ z-index: 1;
44
+ cursor: ns-resize;
45
+ pointer-events: auto;
46
+ }
47
+
48
+ .timeline-canvas-container canvas {
49
+ width: 100%;
50
+ height: 100%;
51
+ display: block;
52
+ }
53
+
54
+ .timeline-info-panel {
55
+ position: relative;
56
+ z-index: 2;
57
+ display: flex;
58
+ flex-direction: column;
59
+ align-items: center;
60
+ text-align: center;
61
+ gap: 1.5rem;
62
+ pointer-events: none;
63
+ }
64
+
65
+ .timeline-meta-header {
66
+ display: flex;
67
+ flex-direction: column;
68
+ gap: 0.25rem;
69
+ }
70
+
71
+ .timeline-age {
72
+ font-size: 0.75rem;
73
+ font-weight: 600;
74
+ text-transform: uppercase;
75
+ letter-spacing: 0.2em;
76
+ color: var(--timeline-text-muted);
77
+ }
78
+
79
+ .timeline-era-name {
80
+ font-size: clamp(2rem, 5vw, 3rem);
81
+ font-weight: 300;
82
+ margin: 0;
83
+ letter-spacing: -0.01em;
84
+ color: var(--timeline-text);
85
+ }
86
+
87
+ .timeline-temp {
88
+ font-size: clamp(5rem, 16vw, 8.5rem);
89
+ font-weight: 100;
90
+ line-height: 1;
91
+ letter-spacing: -0.05em;
92
+ color: var(--timeline-text);
93
+ margin: 0;
94
+ }
95
+
96
+ .timeline-temp-unit {
97
+ font-size: 2.5rem;
98
+ font-weight: 200;
99
+ vertical-align: super;
100
+ margin-left: 0.25rem;
101
+ }
102
+
103
+ .timeline-ruler-container {
104
+ position: absolute;
105
+ right: 1.5rem;
106
+ top: 50%;
107
+ transform: translateY(-50%);
108
+ display: flex;
109
+ flex-direction: column;
110
+ justify-content: space-between;
111
+ height: 280px;
112
+ align-items: flex-end;
113
+ z-index: 3;
114
+ }
115
+
116
+ .timeline-ruler-track {
117
+ position: absolute;
118
+ right: 8px;
119
+ top: 0;
120
+ bottom: 0;
121
+ width: 2px;
122
+ background: var(--timeline-divider);
123
+ }
124
+
125
+ .timeline-ruler-notch {
126
+ display: flex;
127
+ align-items: center;
128
+ gap: 0.5rem;
129
+ cursor: pointer;
130
+ padding: 0.25rem 0.5rem;
131
+ transition: transform 0.2s;
132
+ }
133
+
134
+ .timeline-notch-label {
135
+ font-size: 0.75rem;
136
+ font-weight: 700;
137
+ color: var(--timeline-ruler-text);
138
+ opacity: 0.5;
139
+ transition: opacity 0.2s, color 0.2s, text-shadow 0.2s;
140
+ letter-spacing: 0.05em;
141
+ }
142
+
143
+ .timeline-notch-line {
144
+ width: 12px;
145
+ height: 2px;
146
+ background: var(--timeline-divider);
147
+ transition: width 0.2s, background-color 0.2s;
148
+ }
149
+
150
+ .timeline-ruler-notch.active .timeline-notch-label {
151
+ opacity: 1;
152
+ color: var(--timeline-highlight);
153
+ }
154
+
155
+ .timeline-ruler-notch.active .timeline-notch-line {
156
+ width: 24px;
157
+ background: var(--timeline-highlight);
158
+ }
@@ -0,0 +1,15 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { temperatureTimeline } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'en' } = Astro.props;
11
+ const content = await temperatureTimeline.i18n[locale]?.();
12
+ if (!content) return null;
13
+ ---
14
+
15
+ {content.seo?.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}
package/src/tools.ts CHANGED
@@ -5,6 +5,8 @@ import { ASTEROID_IMPACT_TOOL } from './tool/asteroid-impact/index';
5
5
  import { MICROWAVE_DETECTOR_TOOL } from './tool/microwave-detector/index';
6
6
  import { SIMULATION_PROBABILITY_TOOL } from './tool/simulation-probability/index';
7
7
  import { CELLULAR_RENEWAL_TOOL } from './tool/cellular-renewal/index';
8
+ import { COSMIC_INFLATION_TOOL } from './tool/cosmic-inflation/index';
9
+ import { TEMPERATURE_TIMELINE_TOOL } from './tool/temperature-timeline/index';
8
10
 
9
11
  export const ALL_TOOLS: ToolDefinition[] = [
10
12
  COLONY_COUNTER_TOOL,
@@ -12,6 +14,8 @@ export const ALL_TOOLS: ToolDefinition[] = [
12
14
  MICROWAVE_DETECTOR_TOOL,
13
15
  SIMULATION_PROBABILITY_TOOL,
14
16
  CELLULAR_RENEWAL_TOOL,
17
+ COSMIC_INFLATION_TOOL,
18
+ TEMPERATURE_TIMELINE_TOOL,
15
19
  ];
16
20
 
17
21
 
package/src/types.ts CHANGED
@@ -5,7 +5,7 @@ export type { SEOSection };
5
5
 
6
6
  export type KnownLocale =
7
7
  | 'ar' | 'da' | 'de' | 'en' | 'es' | 'fi'
8
- | 'fr' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
8
+ | 'fr' | 'id' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
9
9
  | 'pl' | 'pt' | 'ru' | 'sv' | 'tr' | 'zh';
10
10
 
11
11
  export interface FAQItem {
@@ -29,9 +29,7 @@ export interface ToolLocaleContent<TUI extends Record<string, string> = Record<s
29
29
  description: string;
30
30
  ui: TUI;
31
31
  seo: SEOSection[];
32
- faqTitle?: string;
33
32
  faq: FAQItem[];
34
- bibliographyTitle?: string;
35
33
  bibliography: BibliographyEntry[];
36
34
  howTo: HowToStep[];
37
35
  schemas: WithContext<Thing>[];