@jjlmoya/utils-science 1.24.0 → 1.25.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 +1 -1
- package/src/category/index.ts +2 -1
- package/src/entries.ts +3 -1
- package/src/index.ts +1 -0
- package/src/tests/locale_completeness.test.ts +2 -2
- package/src/tests/tool_validation.test.ts +2 -2
- package/src/tool/lorenz-attractor/i18n/es.ts +12 -4
- package/src/tool/lorenz-attractor/lorenz-attractor.css +56 -25
- package/src/tool/stellar-habitability-zone/bibliography.astro +14 -0
- package/src/tool/stellar-habitability-zone/bibliography.ts +12 -0
- package/src/tool/stellar-habitability-zone/component.astro +123 -0
- package/src/tool/stellar-habitability-zone/dom-updater.ts +94 -0
- package/src/tool/stellar-habitability-zone/entry.ts +26 -0
- package/src/tool/stellar-habitability-zone/i18n/de.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/en.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/es.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/fr.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/id.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/it.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/ja.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/ko.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/nl.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/pl.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/pt.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/ru.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/sv.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/tr.ts +189 -0
- package/src/tool/stellar-habitability-zone/i18n/zh.ts +189 -0
- package/src/tool/stellar-habitability-zone/index.ts +11 -0
- package/src/tool/stellar-habitability-zone/interaction.ts +45 -0
- package/src/tool/stellar-habitability-zone/logic/StellarHabitabilityEngine.ts +158 -0
- package/src/tool/stellar-habitability-zone/renderer.ts +241 -0
- package/src/tool/stellar-habitability-zone/script.ts +273 -0
- package/src/tool/stellar-habitability-zone/seo.astro +15 -0
- package/src/tool/stellar-habitability-zone/stellar-habitability-zone.css +375 -0
- package/src/tools.ts +2 -0
package/package.json
CHANGED
package/src/category/index.ts
CHANGED
|
@@ -7,10 +7,11 @@ import { cellularRenewal } from '../tool/cellular-renewal/index';
|
|
|
7
7
|
import { cosmicInflation } from '../tool/cosmic-inflation/index';
|
|
8
8
|
import { temperatureTimeline } from '../tool/temperature-timeline/index';
|
|
9
9
|
import { lorenzAttractor } from '../tool/lorenz-attractor/index';
|
|
10
|
+
import { stellarHabitabilityZone } from '../tool/stellar-habitability-zone/index';
|
|
10
11
|
|
|
11
12
|
export const scienceCategory: ScienceCategoryEntry = {
|
|
12
13
|
icon: 'mdi:flask',
|
|
13
|
-
tools: [colonyCounter, asteroidImpact, microwaveDetector, simulationProbability, cellularRenewal, cosmicInflation, temperatureTimeline, lorenzAttractor],
|
|
14
|
+
tools: [colonyCounter, asteroidImpact, microwaveDetector, simulationProbability, cellularRenewal, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone],
|
|
14
15
|
i18n: {
|
|
15
16
|
es: () => import('./i18n/es').then((m) => m.content),
|
|
16
17
|
en: () => import('./i18n/en').then((m) => m.content),
|
package/src/entries.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { simulationProbability } from './tool/simulation-probability/entry';
|
|
|
7
7
|
export { cosmicInflation } from './tool/cosmic-inflation/entry';
|
|
8
8
|
export { temperatureTimeline } from './tool/temperature-timeline/entry';
|
|
9
9
|
export { lorenzAttractor } from './tool/lorenz-attractor/entry';
|
|
10
|
+
export { stellarHabitabilityZone } from './tool/stellar-habitability-zone/entry';
|
|
10
11
|
export { scienceCategory } from './category';
|
|
11
12
|
import { asteroidImpact } from './tool/asteroid-impact/entry';
|
|
12
13
|
import { cellularRenewal } from './tool/cellular-renewal/entry';
|
|
@@ -16,4 +17,5 @@ import { simulationProbability } from './tool/simulation-probability/entry';
|
|
|
16
17
|
import { cosmicInflation } from './tool/cosmic-inflation/entry';
|
|
17
18
|
import { temperatureTimeline } from './tool/temperature-timeline/entry';
|
|
18
19
|
import { lorenzAttractor } from './tool/lorenz-attractor/entry';
|
|
19
|
-
|
|
20
|
+
import { stellarHabitabilityZone } from './tool/stellar-habitability-zone/entry';
|
|
21
|
+
export const ALL_ENTRIES = [asteroidImpact, cellularRenewal, colonyCounter, microwaveDetector, simulationProbability, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone];
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { CELLULAR_RENEWAL_TOOL } from './tool/cellular-renewal/index';
|
|
|
8
8
|
export { COSMIC_INFLATION_TOOL } from './tool/cosmic-inflation/index';
|
|
9
9
|
export { TEMPERATURE_TIMELINE_TOOL } from './tool/temperature-timeline/index';
|
|
10
10
|
export { LORENZ_ATTRACTOR_TOOL } from './tool/lorenz-attractor/index';
|
|
11
|
+
export { STELLAR_HABITABILITY_ZONE_TOOL } from './tool/stellar-habitability-zone/index';
|
|
11
12
|
|
|
12
13
|
export type {
|
|
13
14
|
KnownLocale,
|
|
@@ -4,8 +4,8 @@ import { scienceCategory } from '../data';
|
|
|
4
4
|
|
|
5
5
|
describe('Tool Validation Suite', () => {
|
|
6
6
|
describe('Library Registration', () => {
|
|
7
|
-
it('should have
|
|
8
|
-
expect(ALL_TOOLS.length).toBe(
|
|
7
|
+
it('should have 9 tools in ALL_TOOLS', () => {
|
|
8
|
+
expect(ALL_TOOLS.length).toBe(9);
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
it('scienceCategory should be defined', () => {
|
|
@@ -33,6 +33,14 @@ const faq = [
|
|
|
33
33
|
{
|
|
34
34
|
"question": "Que representan Sigma, Rho y Beta?",
|
|
35
35
|
"answer": "Sigma es el numero de Prandtl, Rho es el numero de Rayleigh y Beta es la relacion de aspecto geometrico del sistema."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"question": "Por que la forma del atractor parece una mariposa?",
|
|
39
|
+
"answer": "La iconica forma de alas dobles de mariposa surge porque el sistema tiene dos puntos de equilibrio inestables. La trayectoria orbita alrededor de un ala y luego transita de forma impredecible para orbitar la otra, creando la estructura distintiva en el espacio de fases tridimensional."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"question": "Es el Atractor de Lorenz verdaderamente aleatorio?",
|
|
43
|
+
"answer": "No. El sistema de Lorenz es completamente deterministico, lo que significa que su estado futuro esta totalmente definido por su estado actual y sus ecuaciones. Sin embargo, como es caotico, es completamente impredecible a largo plazo sin una precision infinita de las condiciones iniciales."
|
|
36
44
|
}
|
|
37
45
|
];
|
|
38
46
|
|
|
@@ -56,10 +64,10 @@ export const content: ToolLocaleContent = {
|
|
|
56
64
|
"trajectories": "Trayectorias",
|
|
57
65
|
"distance": "Distancia de Divergencia",
|
|
58
66
|
"exponentialGrowth": "Divergencia Exponencial",
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
"resetDefault": "Reiniciar",
|
|
68
|
+
"clearPath": "Limpiar",
|
|
69
|
+
"play": "Reanudar",
|
|
70
|
+
"pause": "Pausar",
|
|
63
71
|
"coords": "Coordenadas",
|
|
64
72
|
"divergenceExplanation": "El grafico de divergencia muestra la distancia euclidiana entre las dos trayectorias a lo largo del tiempo. Observa como aumenta exponencialmente."
|
|
65
73
|
},
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
--lorenz-text-muted: #64748b;
|
|
12
12
|
--lorenz-slider-track: #cbd5e1;
|
|
13
13
|
--lorenz-shadow-color: rgba(0, 0, 0, 0.04);
|
|
14
|
-
--lorenz-font-mono: consolas, monaco, 'Courier New', monospace;
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
.theme-dark {
|
|
@@ -33,7 +32,7 @@
|
|
|
33
32
|
width: 100%;
|
|
34
33
|
max-width: 1200px;
|
|
35
34
|
margin: 0 auto;
|
|
36
|
-
font: 14px
|
|
35
|
+
font-size: 14px;
|
|
37
36
|
color: var(--lorenz-text);
|
|
38
37
|
box-sizing: border-box;
|
|
39
38
|
}
|
|
@@ -60,13 +59,12 @@
|
|
|
60
59
|
@media (min-width: 992px) {
|
|
61
60
|
.lorenz-grid {
|
|
62
61
|
grid-template-columns: 1.5fr 1fr;
|
|
63
|
-
align-items:
|
|
62
|
+
align-items: start;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
.lorenz-canvas-container {
|
|
67
|
-
aspect-ratio:
|
|
66
|
+
aspect-ratio: 4 / 3;
|
|
68
67
|
min-height: 520px;
|
|
69
|
-
height: 100%;
|
|
70
68
|
}
|
|
71
69
|
|
|
72
70
|
.lorenz-controls-section {
|
|
@@ -160,12 +158,13 @@
|
|
|
160
158
|
}
|
|
161
159
|
|
|
162
160
|
.lorenz-slider-label {
|
|
163
|
-
font: 700
|
|
161
|
+
font-weight: 700;
|
|
162
|
+
font-size: 12px;
|
|
164
163
|
}
|
|
165
164
|
|
|
166
165
|
.lorenz-slider-val {
|
|
167
166
|
color: var(--lorenz-primary);
|
|
168
|
-
font: 13px
|
|
167
|
+
font-size: 13px;
|
|
169
168
|
font-variant-numeric: tabular-nums;
|
|
170
169
|
}
|
|
171
170
|
|
|
@@ -261,12 +260,13 @@
|
|
|
261
260
|
}
|
|
262
261
|
|
|
263
262
|
.lorenz-coord-item {
|
|
264
|
-
font: 12px
|
|
263
|
+
font-size: 12px;
|
|
265
264
|
color: var(--lorenz-text-muted);
|
|
266
265
|
}
|
|
267
266
|
|
|
268
267
|
.lorenz-coord-val {
|
|
269
|
-
font: 600
|
|
268
|
+
font-weight: 600;
|
|
269
|
+
font-size: 14px;
|
|
270
270
|
font-variant-numeric: tabular-nums;
|
|
271
271
|
}
|
|
272
272
|
|
|
@@ -279,7 +279,8 @@
|
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
.lorenz-divergence-title {
|
|
282
|
-
font: 700
|
|
282
|
+
font-weight: 700;
|
|
283
|
+
font-size: 12px;
|
|
283
284
|
text-transform: uppercase;
|
|
284
285
|
letter-spacing: 0.05em;
|
|
285
286
|
color: var(--lorenz-text-muted);
|
|
@@ -292,7 +293,8 @@
|
|
|
292
293
|
}
|
|
293
294
|
|
|
294
295
|
.lorenz-divergence-num {
|
|
295
|
-
font: 750
|
|
296
|
+
font-weight: 750;
|
|
297
|
+
font-size: 2.8rem;
|
|
296
298
|
line-height: 1;
|
|
297
299
|
color: var(--lorenz-accent);
|
|
298
300
|
font-variant-numeric: tabular-nums;
|
|
@@ -300,7 +302,8 @@
|
|
|
300
302
|
}
|
|
301
303
|
|
|
302
304
|
.lorenz-divergence-delta {
|
|
303
|
-
font: 700
|
|
305
|
+
font-weight: 700;
|
|
306
|
+
font-size: 14px;
|
|
304
307
|
color: var(--lorenz-text-muted);
|
|
305
308
|
font-variant-numeric: tabular-nums;
|
|
306
309
|
}
|
|
@@ -316,7 +319,8 @@
|
|
|
316
319
|
.lorenz-chart-header {
|
|
317
320
|
display: flex;
|
|
318
321
|
align-items: center;
|
|
319
|
-
font: 700
|
|
322
|
+
font-weight: 700;
|
|
323
|
+
font-size: 12px;
|
|
320
324
|
text-transform: uppercase;
|
|
321
325
|
letter-spacing: 0.05em;
|
|
322
326
|
color: var(--lorenz-text-muted);
|
|
@@ -337,7 +341,8 @@
|
|
|
337
341
|
height: 14px;
|
|
338
342
|
border-radius: 50%;
|
|
339
343
|
border: 1px solid var(--lorenz-text-muted);
|
|
340
|
-
font: bold
|
|
344
|
+
font-weight: bold;
|
|
345
|
+
font-size: 9px;
|
|
341
346
|
color: var(--lorenz-text-muted);
|
|
342
347
|
}
|
|
343
348
|
|
|
@@ -352,7 +357,7 @@
|
|
|
352
357
|
text-align: center;
|
|
353
358
|
padding: 8px 12px;
|
|
354
359
|
border-radius: 8px;
|
|
355
|
-
font: 12px
|
|
360
|
+
font-size: 12px;
|
|
356
361
|
line-height: 1.3;
|
|
357
362
|
width: 200px;
|
|
358
363
|
z-index: 10;
|
|
@@ -400,32 +405,39 @@
|
|
|
400
405
|
display: flex;
|
|
401
406
|
flex-direction: column;
|
|
402
407
|
height: 100%;
|
|
403
|
-
gap:
|
|
408
|
+
gap: 12px;
|
|
409
|
+
overflow: hidden;
|
|
404
410
|
}
|
|
405
411
|
|
|
406
412
|
.lorenz-canvas-container {
|
|
407
|
-
height:
|
|
413
|
+
height: 28%;
|
|
408
414
|
flex-shrink: 0;
|
|
409
415
|
aspect-ratio: auto;
|
|
416
|
+
min-height: 0;
|
|
410
417
|
}
|
|
411
418
|
|
|
412
419
|
.lorenz-controls-section {
|
|
413
|
-
|
|
414
|
-
overflow-y: auto;
|
|
420
|
+
flex: 1;
|
|
415
421
|
display: flex;
|
|
416
422
|
flex-direction: column;
|
|
417
|
-
gap:
|
|
423
|
+
gap: 6px;
|
|
424
|
+
overflow: hidden;
|
|
418
425
|
padding-right: 4px;
|
|
426
|
+
min-height: 0;
|
|
419
427
|
}
|
|
420
428
|
|
|
421
429
|
.lorenz-slider-group {
|
|
422
|
-
padding-left:
|
|
423
|
-
padding-right:
|
|
430
|
+
padding-left: 12px;
|
|
431
|
+
padding-right: 12px;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.lorenz-slider {
|
|
435
|
+
height: 28px;
|
|
424
436
|
}
|
|
425
437
|
|
|
426
438
|
.lorenz-button-row {
|
|
427
439
|
grid-template-columns: 2fr 1fr 1fr;
|
|
428
|
-
gap:
|
|
440
|
+
gap: 6px;
|
|
429
441
|
order: 4;
|
|
430
442
|
}
|
|
431
443
|
|
|
@@ -433,21 +445,40 @@
|
|
|
433
445
|
order: 1;
|
|
434
446
|
border-top: none;
|
|
435
447
|
padding-top: 0;
|
|
448
|
+
gap: 4px;
|
|
436
449
|
}
|
|
437
450
|
|
|
438
451
|
.lorenz-chart-block {
|
|
439
452
|
order: 2;
|
|
440
453
|
border-top: none;
|
|
441
454
|
padding-top: 0;
|
|
455
|
+
gap: 4px;
|
|
442
456
|
}
|
|
443
457
|
|
|
444
458
|
.lorenz-chart-canvas-wrapper {
|
|
445
|
-
height:
|
|
459
|
+
height: 40px;
|
|
446
460
|
}
|
|
447
461
|
|
|
448
462
|
.lorenz-sliders-block {
|
|
449
463
|
order: 3;
|
|
464
|
+
display: grid;
|
|
465
|
+
grid-template-columns: 1fr 1fr;
|
|
466
|
+
gap: 4px;
|
|
450
467
|
border-top: 1px solid var(--lorenz-border);
|
|
451
|
-
padding-top:
|
|
468
|
+
padding-top: 8px;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.lorenz-slider-group:nth-child(5) {
|
|
472
|
+
grid-column: 1 / -1;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.lorenz-divergence-display {
|
|
476
|
+
margin-top: 6px;
|
|
477
|
+
margin-bottom: 6px;
|
|
478
|
+
gap: 4px;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.lorenz-divergence-num {
|
|
482
|
+
font-size: 1.5rem;
|
|
452
483
|
}
|
|
453
484
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { stellarHabitabilityZone } 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 stellarHabitabilityZone.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <SharedBibliography links={content.bibliography} />}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BibliographyEntry } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const bibliography: BibliographyEntry[] = [
|
|
4
|
+
{
|
|
5
|
+
name: 'Habitable Zones Around Main-Sequence Stars: New Estimates',
|
|
6
|
+
url: 'https://arxiv.org/abs/1301.6674',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: 'Habitable Zones Around Main-Sequence Stars: Dependence on Planetary Mass',
|
|
10
|
+
url: 'https://iopscience.iop.org/article/10.1088/2041-8205/787/2/L29',
|
|
11
|
+
},
|
|
12
|
+
];
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './stellar-habitability-zone.css';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
ui: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { ui } = Astro.props;
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<div class="hz-calculator-root" id="hz-simulator-root">
|
|
12
|
+
<div class="hz-presets-container">
|
|
13
|
+
<div class="hz-presets">
|
|
14
|
+
<button class="hz-preset-btn active" data-type="G">G-Type (Sun-like)</button>
|
|
15
|
+
<button class="hz-preset-btn" data-type="M">M-Type (Red Dwarf)</button>
|
|
16
|
+
<button class="hz-preset-btn" data-type="K">K-Type (Orange Dwarf)</button>
|
|
17
|
+
<button class="hz-preset-btn" data-type="F">F-Type (Procyon-like)</button>
|
|
18
|
+
<button class="hz-preset-btn" data-type="A">A-Type (Sirius-like)</button>
|
|
19
|
+
<button class="hz-preset-btn" data-type="B">B-Type (Blue Giant)</button>
|
|
20
|
+
<button class="hz-preset-btn" data-type="O">O-Type (Blue Hypergiant)</button>
|
|
21
|
+
<div style="flex-grow: 1;"></div>
|
|
22
|
+
<button class="hz-preset-btn" id="hz-unit-toggle" style="opacity: 0.8; border-bottom: none;"></button>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div class="hz-controls-section">
|
|
27
|
+
<div class="hz-input-group">
|
|
28
|
+
<label for="hz-temperature">{ui.starTemperature}</label>
|
|
29
|
+
<input type="range" id="hz-temperature" class="hz-slider" min="2000" max="50000" value="5778" step="100" />
|
|
30
|
+
<span id="hz-temperature-val" class="hz-input-val">5,778</span>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="hz-input-group">
|
|
34
|
+
<label for="hz-luminosity">{ui.starLuminosity}</label>
|
|
35
|
+
<input type="range" id="hz-luminosity" class="hz-slider" min="-4" max="6" value="0" step="0.1" />
|
|
36
|
+
<span id="hz-luminosity-val" class="hz-input-val">1.0</span>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div class="hz-input-group">
|
|
40
|
+
<label for="hz-mass">{ui.starMass}</label>
|
|
41
|
+
<input type="range" id="hz-mass" class="hz-slider" min="0.05" max="100" value="1.0" step="0.05" />
|
|
42
|
+
<span id="hz-mass-val" class="hz-input-val">1.0</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div class="hz-input-group">
|
|
46
|
+
<label for="hz-radius">{ui.starRadius}</label>
|
|
47
|
+
<input type="range" id="hz-radius" class="hz-slider" min="0.05" max="30" value="1.0" step="0.05" />
|
|
48
|
+
<span id="hz-radius-val" class="hz-input-val">1.0</span>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div class="hz-input-group">
|
|
52
|
+
<label for="hz-distance">{ui.planetDistance}</label>
|
|
53
|
+
<input type="range" id="hz-distance" class="hz-slider" min="-2" max="3" value="0" step="0.01" />
|
|
54
|
+
<span id="hz-distance-val" class="hz-input-val">1.00</span>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div class="hz-input-group">
|
|
58
|
+
<label for="hz-albedo">{ui.planetAlbedo}</label>
|
|
59
|
+
<input type="range" id="hz-albedo" class="hz-slider" min="0.00" max="0.95" value="0.30" step="0.01" />
|
|
60
|
+
<span id="hz-albedo-val" class="hz-input-val">0.30</span>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="hz-input-group">
|
|
64
|
+
<label for="hz-greenhouse">{ui.greenhouseDelta}</label>
|
|
65
|
+
<input type="range" id="hz-greenhouse" class="hz-slider" min="0" max="500" value="33" step="1" />
|
|
66
|
+
<span id="hz-greenhouse-val" class="hz-input-val">33</span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div class="hz-viewport-container">
|
|
71
|
+
<canvas id="hz-orbit-canvas"></canvas>
|
|
72
|
+
<div class="hz-canvas-section">
|
|
73
|
+
<h3>{ui.orbitCanvasTitle}</h3>
|
|
74
|
+
<div class="hz-canvas-container" id="hz-canvas-placeholder">
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div class="hz-results-section">
|
|
79
|
+
<div class="hz-result-grid">
|
|
80
|
+
<div class="hz-result-block">
|
|
81
|
+
<span class="hz-result-label">{ui.equilibriumTemperature}</span>
|
|
82
|
+
<span id="hz-eq-temp" class="hz-result-number">---</span>
|
|
83
|
+
</div>
|
|
84
|
+
<div class="hz-result-block">
|
|
85
|
+
<span class="hz-result-label">{ui.estimatedSurfaceTemp || ui.surfTempResult}</span>
|
|
86
|
+
<span id="hz-surf-temp" class="hz-result-number">---</span>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="hz-result-block">
|
|
89
|
+
<span class="hz-result-label">{ui.stellarFluxResult}</span>
|
|
90
|
+
<span id="hz-stellar-flux" class="hz-result-number">---</span>
|
|
91
|
+
</div>
|
|
92
|
+
<div class="hz-result-block">
|
|
93
|
+
<span class="hz-result-label">{ui.orbitPeriodResult}</span>
|
|
94
|
+
<span id="hz-orbit-period" class="hz-result-number">---</span>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="hz-result-block">
|
|
97
|
+
<span class="hz-result-label">{ui.orbitVelocityResult}</span>
|
|
98
|
+
<span id="hz-orbit-velocity" class="hz-result-number">---</span>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="hz-result-block">
|
|
101
|
+
<span class="hz-result-label">{ui.innerLimit}</span>
|
|
102
|
+
<span id="hz-inner-limit" class="hz-result-number">---</span>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="hz-result-block">
|
|
105
|
+
<span class="hz-result-label">{ui.outerLimit}</span>
|
|
106
|
+
<span id="hz-outer-limit" class="hz-result-number">---</span>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div>
|
|
111
|
+
<div class="hz-status-box habitable" id="hz-status-box">
|
|
112
|
+
<div class="hz-status-title" id="hz-status-title">---</div>
|
|
113
|
+
<div class="hz-status-desc">{ui.statusExplanation}</div>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<script>
|
|
121
|
+
import { initStellarSimulator } from './script';
|
|
122
|
+
initStellarSimulator();
|
|
123
|
+
</script>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { SimulationResult } from './logic/StellarHabitabilityEngine';
|
|
2
|
+
|
|
3
|
+
export interface UpdateValTextsParams {
|
|
4
|
+
temp: number;
|
|
5
|
+
luminosity: number;
|
|
6
|
+
mass: number;
|
|
7
|
+
radius: number;
|
|
8
|
+
distanceAu: number;
|
|
9
|
+
albedo: number;
|
|
10
|
+
greenhouse: number;
|
|
11
|
+
isImperial: boolean;
|
|
12
|
+
tempVal: HTMLElement | null;
|
|
13
|
+
lumVal: HTMLElement | null;
|
|
14
|
+
massVal: HTMLElement | null;
|
|
15
|
+
radVal: HTMLElement | null;
|
|
16
|
+
distVal: HTMLElement | null;
|
|
17
|
+
albedoVal: HTMLElement | null;
|
|
18
|
+
greenVal: HTMLElement | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface UpdateResultsParams {
|
|
22
|
+
result: SimulationResult;
|
|
23
|
+
isImperial: boolean;
|
|
24
|
+
eqTempResult: HTMLElement | null;
|
|
25
|
+
surfTempResult: HTMLElement | null;
|
|
26
|
+
fluxResult: HTMLElement | null;
|
|
27
|
+
periodResult: HTMLElement | null;
|
|
28
|
+
velocityResult: HTMLElement | null;
|
|
29
|
+
innerResult: HTMLElement | null;
|
|
30
|
+
outerResult: HTMLElement | null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function setText(el: HTMLElement | null, text: string) {
|
|
34
|
+
if (el) {
|
|
35
|
+
el.textContent = text;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function updateSliderFill(slider: HTMLInputElement | null) {
|
|
40
|
+
if (!slider) return;
|
|
41
|
+
const min = parseFloat(slider.min) || 0;
|
|
42
|
+
const max = parseFloat(slider.max) || 100;
|
|
43
|
+
const val = parseFloat(slider.value) || 0;
|
|
44
|
+
const percentage = ((val - min) / (max - min)) * 100;
|
|
45
|
+
slider.style.setProperty('--percent', `${percentage}%`);
|
|
46
|
+
slider.style.background = `linear-gradient(to right, var(--hz-slider-active) 0%, var(--hz-slider-active) ${percentage}%, var(--hz-slider-track) ${percentage}%, var(--hz-slider-track) 100%)`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function updateValTexts(p: UpdateValTextsParams) {
|
|
50
|
+
setText(p.tempVal, p.temp.toLocaleString());
|
|
51
|
+
setText(p.lumVal, p.luminosity >= 100 || p.luminosity <= 0.01 ? p.luminosity.toExponential(2) : p.luminosity.toFixed(2));
|
|
52
|
+
setText(p.massVal, p.mass.toFixed(2));
|
|
53
|
+
setText(p.radVal, p.radius.toFixed(2));
|
|
54
|
+
const dist = p.isImperial ? `${(p.distanceAu * 92.9558).toFixed(1)} Mmi` : `${p.distanceAu.toFixed(2)} AU`;
|
|
55
|
+
setText(p.distVal, dist);
|
|
56
|
+
setText(p.albedoVal, p.albedo.toFixed(2));
|
|
57
|
+
setText(p.greenVal, p.greenhouse.toString());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function updateResults(p: UpdateResultsParams) {
|
|
61
|
+
const isImp = p.isImperial;
|
|
62
|
+
const res = p.result;
|
|
63
|
+
const eq = isImp
|
|
64
|
+
? `${Math.round((res.equilibriumTemperature - 273.15) * 1.8 + 32)}°F`
|
|
65
|
+
: `${Math.round(res.equilibriumTemperature - 273.15)}°C (${Math.round(res.equilibriumTemperature)}K)`;
|
|
66
|
+
setText(p.eqTempResult, eq);
|
|
67
|
+
|
|
68
|
+
const surf = isImp
|
|
69
|
+
? `${Math.round((res.surfaceTemperature - 273.15) * 1.8 + 32)}°F`
|
|
70
|
+
: `${Math.round(res.surfaceTemperature - 273.15)}°C (${Math.round(res.surfaceTemperature)}K)`;
|
|
71
|
+
setText(p.surfTempResult, surf);
|
|
72
|
+
|
|
73
|
+
setText(p.fluxResult, `${res.stellarFlux.toFixed(2)} S⊕`);
|
|
74
|
+
|
|
75
|
+
const period = res.orbitalPeriod >= 365
|
|
76
|
+
? `${(res.orbitalPeriod / 365.255).toFixed(1)} yr`
|
|
77
|
+
: `${Math.round(res.orbitalPeriod)} d`;
|
|
78
|
+
setText(p.periodResult, period);
|
|
79
|
+
|
|
80
|
+
const vel = isImp
|
|
81
|
+
? `${Math.round(res.orbitalVelocity * 2236.936).toLocaleString()} mph`
|
|
82
|
+
: `${res.orbitalVelocity.toFixed(1)} km/s`;
|
|
83
|
+
setText(p.velocityResult, vel);
|
|
84
|
+
|
|
85
|
+
const inner = isImp
|
|
86
|
+
? `${(res.hzLimits.runawayGreenhouse * 92.9558).toFixed(1)} Mmi`
|
|
87
|
+
: `${res.hzLimits.runawayGreenhouse.toFixed(2)} AU`;
|
|
88
|
+
setText(p.innerResult, inner);
|
|
89
|
+
|
|
90
|
+
const outer = isImp
|
|
91
|
+
? `${(res.hzLimits.maximumGreenhouse * 92.9558).toFixed(1)} Mmi`
|
|
92
|
+
: `${res.hzLimits.maximumGreenhouse.toFixed(2)} AU`;
|
|
93
|
+
setText(p.outerResult, outer);
|
|
94
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ScienceToolEntry } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const stellarHabitabilityZone: ScienceToolEntry = {
|
|
4
|
+
id: 'stellar-habitability-zone',
|
|
5
|
+
icons: {
|
|
6
|
+
bg: 'mdi:star-circle-outline',
|
|
7
|
+
fg: 'mdi:orbit',
|
|
8
|
+
},
|
|
9
|
+
i18n: {
|
|
10
|
+
de: () => import('./i18n/de').then((m) => m.content),
|
|
11
|
+
en: () => import('./i18n/en').then((m) => m.content),
|
|
12
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
13
|
+
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
14
|
+
id: () => import('./i18n/id').then((m) => m.content),
|
|
15
|
+
it: () => import('./i18n/it').then((m) => m.content),
|
|
16
|
+
ja: () => import('./i18n/ja').then((m) => m.content),
|
|
17
|
+
ko: () => import('./i18n/ko').then((m) => m.content),
|
|
18
|
+
nl: () => import('./i18n/nl').then((m) => m.content),
|
|
19
|
+
pl: () => import('./i18n/pl').then((m) => m.content),
|
|
20
|
+
pt: () => import('./i18n/pt').then((m) => m.content),
|
|
21
|
+
ru: () => import('./i18n/ru').then((m) => m.content),
|
|
22
|
+
sv: () => import('./i18n/sv').then((m) => m.content),
|
|
23
|
+
tr: () => import('./i18n/tr').then((m) => m.content),
|
|
24
|
+
zh: () => import('./i18n/zh').then((m) => m.content),
|
|
25
|
+
},
|
|
26
|
+
};
|