@jjlmoya/utils-science 1.25.0 → 1.27.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 (57) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +3 -1
  3. package/src/entries.ts +5 -1
  4. package/src/index.ts +2 -1
  5. package/src/tests/locale_completeness.test.ts +2 -3
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/natural-selection-drift/bibliography.astro +14 -0
  8. package/src/tool/natural-selection-drift/bibliography.ts +16 -0
  9. package/src/tool/natural-selection-drift/component.astro +104 -0
  10. package/src/tool/natural-selection-drift/entry.ts +29 -0
  11. package/src/tool/natural-selection-drift/i18n/de.ts +65 -0
  12. package/src/tool/natural-selection-drift/i18n/en.ts +180 -0
  13. package/src/tool/natural-selection-drift/i18n/es.ts +64 -0
  14. package/src/tool/natural-selection-drift/i18n/fr.ts +204 -0
  15. package/src/tool/natural-selection-drift/i18n/id.ts +48 -0
  16. package/src/tool/natural-selection-drift/i18n/it.ts +203 -0
  17. package/src/tool/natural-selection-drift/i18n/ja.ts +48 -0
  18. package/src/tool/natural-selection-drift/i18n/ko.ts +48 -0
  19. package/src/tool/natural-selection-drift/i18n/nl.ts +53 -0
  20. package/src/tool/natural-selection-drift/i18n/pl.ts +48 -0
  21. package/src/tool/natural-selection-drift/i18n/pt.ts +52 -0
  22. package/src/tool/natural-selection-drift/i18n/ru.ts +48 -0
  23. package/src/tool/natural-selection-drift/i18n/sv.ts +48 -0
  24. package/src/tool/natural-selection-drift/i18n/tr.ts +48 -0
  25. package/src/tool/natural-selection-drift/i18n/zh.ts +48 -0
  26. package/src/tool/natural-selection-drift/index.ts +9 -0
  27. package/src/tool/natural-selection-drift/logic.ts +114 -0
  28. package/src/tool/natural-selection-drift/natural-selection-drift.css +429 -0
  29. package/src/tool/natural-selection-drift/render.ts +219 -0
  30. package/src/tool/natural-selection-drift/runtime.ts +89 -0
  31. package/src/tool/natural-selection-drift/seo.astro +15 -0
  32. package/src/tool/natural-selection-drift/simulation.ts +161 -0
  33. package/src/tool/radioactive-decay/bibliography.astro +15 -0
  34. package/src/tool/radioactive-decay/bibliography.ts +17 -0
  35. package/src/tool/radioactive-decay/component.astro +346 -0
  36. package/src/tool/radioactive-decay/entry.ts +26 -0
  37. package/src/tool/radioactive-decay/i18n/de.ts +78 -0
  38. package/src/tool/radioactive-decay/i18n/en.ts +223 -0
  39. package/src/tool/radioactive-decay/i18n/es.ts +106 -0
  40. package/src/tool/radioactive-decay/i18n/fr.ts +78 -0
  41. package/src/tool/radioactive-decay/i18n/id.ts +66 -0
  42. package/src/tool/radioactive-decay/i18n/it.ts +79 -0
  43. package/src/tool/radioactive-decay/i18n/ja.ts +65 -0
  44. package/src/tool/radioactive-decay/i18n/ko.ts +65 -0
  45. package/src/tool/radioactive-decay/i18n/nl.ts +72 -0
  46. package/src/tool/radioactive-decay/i18n/pl.ts +65 -0
  47. package/src/tool/radioactive-decay/i18n/pt.ts +78 -0
  48. package/src/tool/radioactive-decay/i18n/ru.ts +66 -0
  49. package/src/tool/radioactive-decay/i18n/sv.ts +66 -0
  50. package/src/tool/radioactive-decay/i18n/tr.ts +66 -0
  51. package/src/tool/radioactive-decay/i18n/zh.ts +65 -0
  52. package/src/tool/radioactive-decay/index.ts +12 -0
  53. package/src/tool/radioactive-decay/logic.test.ts +20 -0
  54. package/src/tool/radioactive-decay/logic.ts +120 -0
  55. package/src/tool/radioactive-decay/radioactive-decay-half-life-calculator.css +435 -0
  56. package/src/tool/radioactive-decay/seo.astro +16 -0
  57. package/src/tools.ts +4 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-science",
3
- "version": "1.25.0",
3
+ "version": "1.27.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -8,10 +8,12 @@ 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
10
  import { stellarHabitabilityZone } from '../tool/stellar-habitability-zone/index';
11
+ import { radioactiveDecay } from '../tool/radioactive-decay/index';
12
+ import { naturalSelectionDrift } from '../tool/natural-selection-drift/index';
11
13
 
12
14
  export const scienceCategory: ScienceCategoryEntry = {
13
15
  icon: 'mdi:flask',
14
- tools: [colonyCounter, asteroidImpact, microwaveDetector, simulationProbability, cellularRenewal, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone],
16
+ tools: [colonyCounter, asteroidImpact, microwaveDetector, simulationProbability, cellularRenewal, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone, radioactiveDecay, naturalSelectionDrift],
15
17
  i18n: {
16
18
  es: () => import('./i18n/es').then((m) => m.content),
17
19
  en: () => import('./i18n/en').then((m) => m.content),
package/src/entries.ts CHANGED
@@ -8,6 +8,8 @@ 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
10
  export { stellarHabitabilityZone } from './tool/stellar-habitability-zone/entry';
11
+ export { radioactiveDecay } from './tool/radioactive-decay/entry';
12
+ export { naturalSelectionDrift } from './tool/natural-selection-drift/entry';
11
13
  export { scienceCategory } from './category';
12
14
  import { asteroidImpact } from './tool/asteroid-impact/entry';
13
15
  import { cellularRenewal } from './tool/cellular-renewal/entry';
@@ -18,4 +20,6 @@ import { cosmicInflation } from './tool/cosmic-inflation/entry';
18
20
  import { temperatureTimeline } from './tool/temperature-timeline/entry';
19
21
  import { lorenzAttractor } from './tool/lorenz-attractor/entry';
20
22
  import { stellarHabitabilityZone } from './tool/stellar-habitability-zone/entry';
21
- export const ALL_ENTRIES = [asteroidImpact, cellularRenewal, colonyCounter, microwaveDetector, simulationProbability, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone];
23
+ import { radioactiveDecay } from './tool/radioactive-decay/entry';
24
+ import { naturalSelectionDrift } from './tool/natural-selection-drift/entry';
25
+ export const ALL_ENTRIES = [asteroidImpact, cellularRenewal, colonyCounter, microwaveDetector, simulationProbability, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone, radioactiveDecay, naturalSelectionDrift];
package/src/index.ts CHANGED
@@ -9,6 +9,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
11
  export { STELLAR_HABITABILITY_ZONE_TOOL } from './tool/stellar-habitability-zone/index';
12
+ export { RADIOACTIVE_DECAY_TOOL } from './tool/radioactive-decay/index';
13
+ export { NATURAL_SELECTION_DRIFT_TOOL } from './tool/natural-selection-drift/index';
12
14
 
13
15
  export type {
14
16
  KnownLocale,
@@ -25,4 +27,3 @@ export type {
25
27
  } from './types';
26
28
 
27
29
  export { ALL_ENTRIES, ALL_TOOLS } from './tools';
28
-
@@ -18,8 +18,7 @@ describe('Locale Completeness Validation', () => {
18
18
  });
19
19
  });
20
20
 
21
- it('all 9 tools registered', () => {
22
- expect(ALL_TOOLS.length).toBe(9);
21
+ it('all 11 tools registered', () => {
22
+ expect(ALL_TOOLS.length).toBe(11);
23
23
  });
24
24
  });
25
-
@@ -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 9 tools in ALL_TOOLS', () => {
8
- expect(ALL_TOOLS.length).toBe(9);
7
+ it('should have 11 tools in ALL_TOOLS', () => {
8
+ expect(ALL_TOOLS.length).toBe(11);
9
9
  });
10
10
 
11
11
  it('scienceCategory should be defined', () => {
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
+ import { naturalSelectionDrift } 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 naturalSelectionDrift.i18n[locale]?.();
12
+ ---
13
+
14
+ {content && <SharedBibliography links={content.bibliography} />}
@@ -0,0 +1,16 @@
1
+ import type { BibliographyEntry } from '../../types';
2
+
3
+ export const bibliography: BibliographyEntry[] = [
4
+ {
5
+ name: 'Darwin, C. (1859). On the Origin of Species.',
6
+ url: 'https://www.gutenberg.org/ebooks/1228',
7
+ },
8
+ {
9
+ name: 'Futuyma, D. J. (2017). Evolution.',
10
+ url: 'https://www.scirp.org/reference/referencespapers?referenceid=2347977',
11
+ },
12
+ {
13
+ name: 'Nature Education - Genetic drift',
14
+ url: 'https://www.nature.com/scitable/definition/genetic-drift-201/',
15
+ },
16
+ ];
@@ -0,0 +1,104 @@
1
+ ---
2
+ import "./natural-selection-drift.css";
3
+
4
+ interface Props {
5
+ ui: Record<string, string>;
6
+ }
7
+
8
+ const { ui } = Astro.props;
9
+ ---
10
+
11
+ <div class="ns-app">
12
+ <section class="ns-card">
13
+ <canvas id="simulation-canvas" class="ns-canvas"></canvas>
14
+ <div class="ns-canvas-badge" id="alive-badge">0 {ui.aliveLabel}</div>
15
+ <header class="ns-top-hud">
16
+ <div class="ns-top-hud-item">
17
+ <span>{ui.dominantTrait}</span>
18
+ <strong id="dominant-trait">{ui.alleleDefault}</strong>
19
+ </div>
20
+ <div class="ns-top-hud-item">
21
+ <span>{ui.diversity}</span>
22
+ <strong id="diversity-score">0%</strong>
23
+ </div>
24
+ </header>
25
+
26
+ <section class="ns-alleles" id="allele-ranking" aria-label={ui.alleleCountsLabel}></section>
27
+
28
+ <aside class="ns-console" aria-label="Simulation controls">
29
+ <div class="ns-console-header">
30
+ <span class="ns-console-kicker">{ui.evolutionConsole}</span>
31
+ <h3>{ui.title}</h3>
32
+ </div>
33
+
34
+ <div class="ns-slider-row">
35
+ <label for="population"><span>{ui.population}</span><span id="population-value" class="ns-slider-value">120</span></label>
36
+ <input id="population" type="range" min="20" max="500" value="120" />
37
+ </div>
38
+ <div class="ns-slider-row">
39
+ <label for="generations"><span>{ui.generations}</span><span id="generations-value" class="ns-slider-value">60</span></label>
40
+ <input id="generations" type="range" min="10" max="200" value="60" />
41
+ </div>
42
+ <div class="ns-slider-row">
43
+ <label for="mutation"><span>{ui.mutationRate}</span><span id="mutation-value" class="ns-slider-value">12%</span></label>
44
+ <input id="mutation" type="range" min="0" max="100" value="12" />
45
+ </div>
46
+ <div class="ns-slider-row">
47
+ <label for="pressure"><span>{ui.selectionPressure}</span><span id="pressure-value" class="ns-slider-value">55%</span></label>
48
+ <input id="pressure" type="range" min="0" max="100" value="55" />
49
+ </div>
50
+ <div class="ns-slider-row">
51
+ <label for="drift"><span>{ui.driftIntensity}</span><span id="drift-value" class="ns-slider-value">28%</span></label>
52
+ <input id="drift" type="range" min="0" max="100" value="28" />
53
+ </div>
54
+ <div class="ns-slider-row">
55
+ <label for="alleles"><span>{ui.alleleCount}</span><span id="alleles-value" class="ns-slider-value">3</span></label>
56
+ <input id="alleles" type="range" min="2" max="8" value="3" />
57
+ </div>
58
+ <div class="ns-slider-row">
59
+ <label for="innovation"><span>{ui.innovationRate}</span><span id="innovation-value" class="ns-slider-value">2%</span></label>
60
+ <input id="innovation" type="range" min="0" max="20" value="2" />
61
+ </div>
62
+ </aside>
63
+
64
+ <footer class="ns-hud">
65
+ <div class="ns-hud-item">
66
+ <span>{ui.fitness}</span>
67
+ <strong id="fitness-score">0%</strong>
68
+ </div>
69
+ <div class="ns-hud-item">
70
+ <span>{ui.populationLabel}</span>
71
+ <strong id="population-score">0</strong>
72
+ </div>
73
+ </footer>
74
+ </section>
75
+ </div>
76
+
77
+ <script type="module" define:vars={{ ui }}>
78
+ import { createNaturalSelectionRuntime } from '/src/tool/natural-selection-drift/runtime';
79
+
80
+ createNaturalSelectionRuntime({
81
+ populationInput: document.getElementById('population'),
82
+ generationsInput: document.getElementById('generations'),
83
+ mutationInput: document.getElementById('mutation'),
84
+ pressureInput: document.getElementById('pressure'),
85
+ driftInput: document.getElementById('drift'),
86
+ allelesInput: document.getElementById('alleles'),
87
+ innovationInput: document.getElementById('innovation'),
88
+ populationValue: document.getElementById('population-value'),
89
+ generationsValue: document.getElementById('generations-value'),
90
+ mutationValue: document.getElementById('mutation-value'),
91
+ pressureValue: document.getElementById('pressure-value'),
92
+ driftValue: document.getElementById('drift-value'),
93
+ allelesValue: document.getElementById('alleles-value'),
94
+ innovationValue: document.getElementById('innovation-value'),
95
+ canvas: document.getElementById('simulation-canvas'),
96
+ aliveBadge: document.getElementById('alive-badge'),
97
+ dominantTrait: document.getElementById('dominant-trait'),
98
+ fitnessScore: document.getElementById('fitness-score'),
99
+ diversityScore: document.getElementById('diversity-score'),
100
+ populationScore: document.getElementById('population-score'),
101
+ alleleRanking: document.getElementById('allele-ranking'),
102
+ ui: { ...ui },
103
+ });
104
+ </script>
@@ -0,0 +1,29 @@
1
+ import type { ScienceToolEntry, ToolLocaleContent } from '../../types';
2
+
3
+ export interface NaturalSelectionUI {
4
+ [key: string]: string;
5
+ }
6
+
7
+ export type NaturalSelectionLocaleContent = ToolLocaleContent<NaturalSelectionUI>;
8
+
9
+ export const naturalSelectionDrift: ScienceToolEntry<NaturalSelectionUI> = {
10
+ id: 'natural-selection-drift',
11
+ icons: { bg: 'mdi:alpha-n-box-outline', fg: 'mdi:leaf' },
12
+ i18n: {
13
+ en: () => import('./i18n/en').then((m) => m.content),
14
+ es: () => import('./i18n/es').then((m) => m.content),
15
+ fr: () => import('./i18n/fr').then((m) => m.content),
16
+ de: () => import('./i18n/de').then((m) => m.content),
17
+ nl: () => import('./i18n/nl').then((m) => m.content),
18
+ it: () => import('./i18n/it').then((m) => m.content),
19
+ pt: () => import('./i18n/pt').then((m) => m.content),
20
+ pl: () => import('./i18n/pl').then((m) => m.content),
21
+ ru: () => import('./i18n/ru').then((m) => m.content),
22
+ tr: () => import('./i18n/tr').then((m) => m.content),
23
+ sv: () => import('./i18n/sv').then((m) => m.content),
24
+ id: () => import('./i18n/id').then((m) => m.content),
25
+ ja: () => import('./i18n/ja').then((m) => m.content),
26
+ ko: () => import('./i18n/ko').then((m) => m.content),
27
+ zh: () => import('./i18n/zh').then((m) => m.content),
28
+ },
29
+ };
@@ -0,0 +1,65 @@
1
+ import { bibliography } from '../bibliography';
2
+ import type { NaturalSelectionLocaleContent } from '../entry';
3
+
4
+ const slug = 'simulator-natuerliche-selektion-genetische-drift';
5
+ const title = 'Simulator fur naturliche Selektion und genetische Drift';
6
+ const description =
7
+ 'Beobachte in Echtzeit, wie Selektionsdruck, Mutation, Drift und Fortpflanzung die Allelfrequenzen verandern.';
8
+
9
+ const howTo = [
10
+ { name: 'Population festlegen', text: 'Wahle eine kleine oder große Population, um den Einfluss der Stichprobe zu sehen.' },
11
+ { name: 'Selektion und Drift einstellen', text: 'Erhohe den Selektionsdruck oder die Drift, um andere Evolutionsverlaufe zu sehen.' },
12
+ { name: 'Generationen beobachten', text: 'Starte die Simulation und vergleiche dominantes Merkmal, Fitness und Vielfalt uber die Zeit.' },
13
+ { name: 'Ergebnisse deuten', text: 'Nutze die Metriken, um zu verstehen, wann Anpassung gewinnt und wann Zufall dominiert.' },
14
+ ];
15
+
16
+ const faq = [
17
+ { question: 'Was ist der Unterschied zwischen naturlicher Selektion und genetischer Drift?', answer: 'Naturliche Selektion ist nicht zufallig. Vorteilhafte Merkmale werden haufiger. Genetische Drift ist eine zufallige Veranderung der Allelfrequenzen, besonders stark in kleinen Populationen.' },
18
+ { question: 'Warum verandern sich kleine Populationen schneller?', answer: 'Bei wenigen Individuen hat Zufall einen großeren Einfluss auf die nachste Generation.' },
19
+ { question: 'Kann Drift Selektion ubertreffen?', answer: 'Ja. Ein vorteilhaftes Merkmal kann durch Zufall verschwinden, wenn die Drift stark genug ist.' },
20
+ { question: 'Was bedeutet Fitness in diesem Simulator?', answer: 'Fitness ist eine vereinfachte Kennzahl dafur, wie gut die Population an die Umgebung angepasst ist.' },
21
+ { question: 'Warum ist die Populationsgroße so wichtig?', answer: 'Sie bestimmt, wie stark Zufall die Allelfrequenzen beeinflusst.' },
22
+ { question: 'Wann sollte ich diesen Simulator benutzen?', answer: 'Wenn du die Intuition hinter Evolution verstehen willst, besonders den Unterschied zwischen Selektion und Drift.' },
23
+ ];
24
+
25
+ export const content: NaturalSelectionLocaleContent = {
26
+ slug,
27
+ title,
28
+ description,
29
+ ui: {
30
+ population: 'Populationsgroße',
31
+ generations: 'Generationen',
32
+ mutationRate: 'Mutationsrate',
33
+ selectionPressure: 'Selektionsdruck',
34
+ driftIntensity: 'Driftintensitat',
35
+ alleleCount: 'Startallele',
36
+ innovationRate: 'Innovationsrate',
37
+ run: 'Simulation starten',
38
+ dominantTrait: 'Dominantes Merkmal',
39
+ fitness: 'Endfitness',
40
+ diversity: 'Genetische Vielfalt',
41
+ evolutionConsole: 'Evolution-Konsole',
42
+ populationLabel: 'Population',
43
+ aliveLabel: 'lebend',
44
+ alleleCountsLabel: 'Allelzahlen',
45
+ alleleDefault: 'Allel 1',
46
+ populationValueLabel: 'Population',
47
+ },
48
+ seo: [
49
+ { type: 'title', text: 'Naturliche Selektion vs genetische Drift: Evolution mit einer lebenden Population verstehen', level: 2 },
50
+ { type: 'paragraph', html: 'Wenn du naturliche Selektion vs genetische Drift verstehen willst, liefert dir dieser Simulator die fehlende visuelle Ebene.' },
51
+ { type: 'title', text: 'Was die Regler bedeuten', level: 3 },
52
+ { type: 'paragraph', html: 'Naturliche Selektion erhoht die Haufigkeit vorteilhafter Merkmale. Genetische Drift verandert Allelfrequenzen zufallig.' },
53
+ { type: 'paragraph', html: 'Beide Krafte wirken gleichzeitig. In großen Populationen dominiert oft Selektion; in kleinen kann Zufall nutzliche Merkmale auslosen.' },
54
+ { type: 'title', text: 'Wie man die Ergebnisse liest', level: 3 },
55
+ { type: 'paragraph', html: 'Die Live-Metriken zeigen das dominante Allel, die genetische Vielfalt, die Endfitness und ob die Population wachst oder kollabiert.' },
56
+ ],
57
+ faq,
58
+ bibliography,
59
+ howTo,
60
+ schemas: [
61
+ { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'EducationalApplication', operatingSystem: 'Any' },
62
+ { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) },
63
+ { '@context': 'https://schema.org', '@type': 'HowTo', name: title, step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) },
64
+ ],
65
+ };
@@ -0,0 +1,180 @@
1
+ import { bibliography } from '../bibliography';
2
+ import type { NaturalSelectionLocaleContent } from '../entry';
3
+
4
+ const slug = 'natural-selection-drift';
5
+ const title = 'Natural Selection and Genetic Drift Simulator';
6
+ const description = 'See how selection pressure, mutation, drift, and reproduction change allele frequencies over time with an interactive evolution simulator that explains why populations adapt, diversify, or collapse.';
7
+ const howTo = [
8
+ {
9
+ name: 'Set the population',
10
+ text: 'Choose a small or large population to see how sample size changes evolutionary stability and how easily chance can dominate the outcome.',
11
+ },
12
+ {
13
+ name: 'Tune selection and drift',
14
+ text: 'Increase selection pressure to favor one trait, or raise drift intensity to make chance dominate the outcome when populations are small or fluctuating.',
15
+ },
16
+ {
17
+ name: 'Watch generations unfold',
18
+ text: 'Run the simulation and compare dominant traits, fitness, and diversity across time so you can see whether adaptation or randomness wins.',
19
+ },
20
+ {
21
+ name: 'Interpret the balance',
22
+ text: 'Use the final metrics to understand when adaptation wins, when random fluctuation takes over, and why the same starting point can lead to different outcomes.',
23
+ },
24
+ ];
25
+ const faq = [
26
+ {
27
+ question: 'What is the difference between natural selection and genetic drift?',
28
+ answer: 'Natural selection is a non-random process where traits that improve survival or reproduction become more common. Genetic drift is random change in allele frequencies, and it is strongest in small populations.',
29
+ },
30
+ {
31
+ question: 'Why do small populations change faster?',
32
+ answer: 'With fewer individuals, random sampling has a larger effect. That means chance events can move trait frequencies more dramatically from one generation to the next.',
33
+ },
34
+ {
35
+ question: 'Can drift overpower selection?',
36
+ answer: 'Yes. If drift is strong enough, a beneficial trait may still disappear by chance, especially when the population is small or selection pressure is weak.',
37
+ },
38
+ {
39
+ question: 'What does fitness mean in this simulator?',
40
+ answer: 'Fitness is a simplified score representing how well the current population is adapted to the chosen environment. It is a teaching metric, not a laboratory measurement.',
41
+ },
42
+ {
43
+ question: 'Why does population size matter so much?',
44
+ answer: 'Population size determines how strongly random sampling affects allele frequencies. In large populations, selection is easier to see because random noise averages out. In small populations, chance can overpower a seemingly beneficial trait.',
45
+ },
46
+ {
47
+ question: 'When should I use this simulator instead of a textbook explanation?',
48
+ answer: 'Use it when you want to understand the intuition behind evolution, especially the difference between a directional force like selection and a stochastic force like drift. It is useful for students, teachers, and anyone trying to connect the concept to real population behavior.',
49
+ },
50
+ ];
51
+
52
+ export const content: NaturalSelectionLocaleContent = {
53
+ slug,
54
+ title,
55
+ description,
56
+ ui: {
57
+ population: 'Population size',
58
+ generations: 'Generations',
59
+ mutationRate: 'Mutation rate',
60
+ selectionPressure: 'Selection pressure',
61
+ driftIntensity: 'Drift intensity',
62
+ alleleCount: 'Initial alleles',
63
+ innovationRate: 'Innovation rate',
64
+ run: 'Run simulation',
65
+ dominantTrait: 'Dominant trait',
66
+ fitness: 'Final fitness',
67
+ diversity: 'Genetic diversity',
68
+ evolutionConsole: 'Evolution console',
69
+ populationLabel: 'Population',
70
+ aliveLabel: 'alive',
71
+ alleleCountsLabel: 'Allele counts',
72
+ alleleDefault: 'Allele 1',
73
+ populationValueLabel: 'Population',
74
+ },
75
+ seo: [
76
+ {
77
+ type: 'title',
78
+ text: 'Natural Selection vs Genetic Drift: Understand Evolution Through a Live Population Simulator',
79
+ level: 2,
80
+ },
81
+ {
82
+ type: 'paragraph',
83
+ html: 'If you are trying to understand natural selection vs genetic drift, this simulator gives you the missing visual layer. Instead of reading a static definition, you can watch a population change in real time as selection pressure, mutation rate, drift intensity, and reproduction interact. That makes it much easier to connect the textbook idea of evolution with the actual behavior of alleles inside a living system.',
84
+ },
85
+ {
86
+ type: 'title',
87
+ text: 'What the Controls Mean and Why They Matter',
88
+ level: 3,
89
+ },
90
+ {
91
+ type: 'paragraph',
92
+ html: 'Natural selection is the non-random part of evolution. It increases the frequency of traits that improve survival or reproduction in a given environment. Genetic drift is the random part. It changes allele frequencies because not every individual contributes equally to the next generation, and those fluctuations become especially important when the population is small.',
93
+ },
94
+ {
95
+ type: 'paragraph',
96
+ html: 'The key idea is that both forces are always present. Selection tries to push the population in one direction, while drift can pull it somewhere else entirely. In a large population, selection usually has the stronger voice. In a small population, randomness can erase a useful trait, fix a neutral trait, or completely change the evolutionary outcome.',
97
+ },
98
+ {
99
+ type: 'title',
100
+ text: 'How to Read the Simulation Results',
101
+ level: 3,
102
+ },
103
+ {
104
+ type: 'paragraph',
105
+ html: 'The live metrics help you read the system as it changes. Dominant trait tells you which allele currently leads. Genetic diversity shows how much variation is still present. Final fitness gives a quick summary of how well the population is adapted to the selected environment. Alive and population show whether the lineage is expanding or collapsing.',
106
+ },
107
+ {
108
+ type: 'title',
109
+ text: 'Why Population Size Changes the Story',
110
+ level: 3,
111
+ },
112
+ {
113
+ type: 'list',
114
+ items: [
115
+ '<strong>Selection pressure:</strong> How strongly the environment rewards one trait over another and how quickly that advantage can spread.',
116
+ '<strong>Drift intensity:</strong> How much random sampling noise changes the population each generation, even when no trait is objectively better.',
117
+ '<strong>Mutation rate:</strong> How often new variation enters the system and prevents the population from becoming completely static.',
118
+ '<strong>Allele count:</strong> How many explicit alleles are present at the start and how quickly new variants appear once innovation is enabled.',
119
+ '<strong>Genetic diversity:</strong> Why variation is the raw material of evolution and why losing it makes populations more vulnerable.',
120
+ ],
121
+ },
122
+ {
123
+ type: 'paragraph',
124
+ html: 'The result is a fast, practical way to understand evolution without needing to guess how the abstract terms interact. If you want a simulator that explains natural selection, genetic drift, mutation, reproduction, and why the same starting conditions can end in different outcomes, this tool is built for that exact search intent.',
125
+ },
126
+ {
127
+ type: 'title',
128
+ text: 'Quick Examples of What to Try',
129
+ level: 3,
130
+ },
131
+ {
132
+ type: 'table',
133
+ headers: ['Goal', 'What to change', 'What you should see'],
134
+ rows: [
135
+ ['Show selection winning', 'Raise selection pressure and keep drift low', 'One allele should dominate over time and diversity should drop more slowly'],
136
+ ['Show randomness taking over', 'Lower population size and increase drift', 'Allele counts should swing unpredictably, even without a clear fitness advantage'],
137
+ ['Show mutation creating new variation', 'Increase mutation and innovation rate', 'New alleles should appear and the ranking should reshuffle more often'],
138
+ ],
139
+ },
140
+ {
141
+ type: 'paragraph',
142
+ html: 'That combination of live visuals, explicit allele ranking, and real-time metrics makes the simulator useful both as a teaching tool and as a quick way to explain evolutionary tradeoffs without hand-waving.',
143
+ },
144
+ ],
145
+ faq,
146
+ bibliography,
147
+ howTo,
148
+ schemas: [
149
+ {
150
+ '@context': 'https://schema.org',
151
+ '@type': 'SoftwareApplication',
152
+ name: title,
153
+ description: description,
154
+ applicationCategory: 'EducationalApplication',
155
+ operatingSystem: 'Any',
156
+ },
157
+ {
158
+ '@context': 'https://schema.org',
159
+ '@type': 'FAQPage',
160
+ mainEntity: faq.map((item) => ({
161
+ '@type': 'Question',
162
+ name: item.question,
163
+ acceptedAnswer: {
164
+ '@type': 'Answer',
165
+ text: item.answer,
166
+ },
167
+ })),
168
+ },
169
+ {
170
+ '@context': 'https://schema.org',
171
+ '@type': 'HowTo',
172
+ name: title,
173
+ step: howTo.map((step) => ({
174
+ '@type': 'HowToStep',
175
+ name: step.name,
176
+ text: step.text,
177
+ })),
178
+ },
179
+ ],
180
+ };
@@ -0,0 +1,64 @@
1
+ import { bibliography } from '../bibliography';
2
+ import type { NaturalSelectionLocaleContent } from '../entry';
3
+
4
+ const slug = 'simulador-seleccion-natural-deriva-genetica';
5
+ const title = 'Simulador de Selección Natural y Deriva Genética';
6
+ const description = 'Observa cómo la presión de selección, la mutación, la deriva y la reproducción cambian las frecuencias alélicas en tiempo real con un simulador evolutivo interactivo.';
7
+ const howTo = [
8
+ { name: 'Ajusta la población', text: 'Elige una población pequeña o grande para ver cómo el tamaño muestral cambia la estabilidad evolutiva y cuánto puede dominar el azar.' },
9
+ { name: 'Regula selección y deriva', text: 'Sube la presión de selección para favorecer un rasgo o aumenta la deriva para que el azar domine cuando la población es pequeña o fluctúa.' },
10
+ { name: 'Observa las generaciones', text: 'Ejecuta la simulación y compara rasgos dominantes, aptitud y diversidad a lo largo del tiempo para ver si gana la adaptación o la aleatoriedad.' },
11
+ { name: 'Interpreta el balance', text: 'Usa las métricas finales para entender cuándo gana la adaptación, cuándo toma el control la fluctuación aleatoria y por qué un mismo inicio puede acabar distinto.' },
12
+ ];
13
+ const faq = [
14
+ { question: '¿Cuál es la diferencia entre selección natural y deriva genética?', answer: 'La selección natural es un proceso no aleatorio en el que los rasgos que mejoran la supervivencia o la reproducción se vuelven más comunes. La deriva genética es un cambio aleatorio en las frecuencias alélicas y se nota más en poblaciones pequeñas.' },
15
+ { question: '¿Por qué las poblaciones pequeñas cambian más rápido?', answer: 'Con menos individuos, el muestreo aleatorio tiene un efecto mayor. Eso hace que los eventos fortuitos muevan las frecuencias de rasgos con mucha más intensidad de una generación a la siguiente.' },
16
+ { question: '¿Puede la deriva imponerse a la selección?', answer: 'Sí. Si la deriva es lo bastante fuerte, un rasgo beneficioso puede desaparecer por azar, sobre todo cuando la población es pequeña o la presión de selección es débil.' },
17
+ { question: '¿Qué significa fitness en este simulador?', answer: 'Fitness es una puntuación simplificada que representa lo bien adaptada que está la población al entorno elegido. Es una métrica didáctica, no una medida de laboratorio.' },
18
+ { question: '¿Por qué importa tanto el tamaño de la población?', answer: 'El tamaño de la población determina cuánto afectan las fluctuaciones aleatorias a las frecuencias alélicas. En poblaciones grandes, la selección se ve mejor porque el ruido se compensa. En poblaciones pequeñas, el azar puede superar a un rasgo aparentemente ventajoso.' },
19
+ { question: '¿Cuándo debería usar este simulador en vez de una explicación de libro?', answer: 'Úsalo cuando quieras entender la intuición detrás de la evolución, especialmente la diferencia entre una fuerza direccional como la selección y una fuerza estocástica como la deriva.' },
20
+ ];
21
+
22
+ export const content: NaturalSelectionLocaleContent = {
23
+ slug, title, description,
24
+ ui: {
25
+ population: 'Tamaño de la población',
26
+ generations: 'Generaciones',
27
+ mutationRate: 'Tasa de mutación',
28
+ selectionPressure: 'Presión de selección',
29
+ driftIntensity: 'Intensidad de deriva',
30
+ alleleCount: 'Alelos iniciales',
31
+ innovationRate: 'Tasa de innovación',
32
+ run: 'Ejecutar simulación',
33
+ dominantTrait: 'Rasgo dominante',
34
+ fitness: 'Aptitud final',
35
+ diversity: 'Diversidad genética',
36
+ evolutionConsole: 'Consola evolutiva',
37
+ populationLabel: 'Población',
38
+ aliveLabel: 'vivos',
39
+ alleleCountsLabel: 'Conteo de alelos',
40
+ alleleDefault: 'Alelo 1',
41
+ populationValueLabel: 'Población',
42
+ },
43
+ seo: [
44
+ { type: 'title', text: 'Selección Natural vs Deriva Genética: entiende la evolución con una población viva', level: 2 },
45
+ { type: 'paragraph', html: 'Si quieres entender selección natural vs deriva genética, este simulador te da la capa visual que faltaba. En lugar de leer una definición estática, puedes ver cómo cambia una población en tiempo real mientras interactúan la presión de selección, la tasa de mutación, la intensidad de deriva y la reproducción.' },
46
+ { type: 'title', text: 'Qué significan los controles y por qué importan', level: 3 },
47
+ { type: 'paragraph', html: 'La selección natural es la parte no aleatoria de la evolución. Aumenta la frecuencia de los rasgos que mejoran la supervivencia o la reproducción. La deriva genética es la parte aleatoria. Cambia las frecuencias alélicas porque no todos los individuos contribuyen por igual a la siguiente generación.' },
48
+ { type: 'paragraph', html: 'La idea clave es que ambas fuerzas actúan a la vez. La selección intenta empujar a la población en una dirección; la deriva puede llevarla a otra completamente distinta. En poblaciones grandes, la selección suele dominar. En poblaciones pequeñas, el azar puede borrar un rasgo útil o fijar uno neutral.' },
49
+ { type: 'title', text: 'Cómo leer los resultados de la simulación', level: 3 },
50
+ { type: 'paragraph', html: 'Las métricas en vivo te ayudan a interpretar el sistema mientras cambia. El rasgo dominante indica qué alelo lidera. La diversidad genética muestra cuánta variación queda. La aptitud final resume qué tan adaptada está la población. Y los contadores de vivos y población muestran si la línea evolutiva crece o colapsa.' },
51
+ { type: 'title', text: 'Por qué el tamaño de la población cambia la historia', level: 3 },
52
+ { type: 'list', items: ['<strong>Presión de selección:</strong> cuánto recompensa el entorno un rasgo frente a otro y con qué rapidez se extiende esa ventaja.', '<strong>Intensidad de deriva:</strong> cuánta variación aleatoria afecta a la población en cada generación, incluso cuando ningún rasgo es objetivamente mejor.', '<strong>Tasa de mutación:</strong> con qué frecuencia entra nueva variación en el sistema.', '<strong>Número de alelos:</strong> cuántos alelos explícitos hay al inicio y cuántas variantes nuevas pueden aparecer.', '<strong>Diversidad genética:</strong> por qué la variación es la materia prima de la evolución.'] },
53
+ { type: 'paragraph', html: 'El resultado es una forma rápida y útil de entender la evolución sin depender sólo de definiciones abstractas. Si buscas un simulador que explique selección natural, deriva genética, mutación, reproducción y por qué un mismo punto de partida puede acabar de forma distinta, esta herramienta está hecha para eso.' },
54
+ { type: 'title', text: 'Ejemplos rápidos de uso', level: 3 },
55
+ { type: 'table', headers: ['Objetivo', 'Qué cambiar', 'Qué deberías ver'], rows: [['Mostrar victoria de la selección', 'Sube la presión de selección y baja la deriva', 'Un alelo debe dominar con el tiempo y la diversidad caerá más despacio'], ['Mostrar el azar tomando el control', 'Baja la población y sube la deriva', 'Las frecuencias deben oscilar de forma impredecible'], ['Mostrar nuevas mutaciones', 'Sube mutación e innovación', 'Aparecerán nuevos alelos y el ranking cambiará más a menudo']] },
56
+ { type: 'paragraph', html: 'Esa combinación de visuales en vivo, ranking explícito de alelos y métricas en tiempo real hace que el simulador sea útil tanto para enseñar como para explicar trade-offs evolutivos sin rodeos.' },
57
+ ],
58
+ faq, bibliography, howTo,
59
+ schemas: [
60
+ { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'EducationalApplication', operatingSystem: 'Any' },
61
+ { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) },
62
+ { '@context': 'https://schema.org', '@type': 'HowTo', name: title, step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) },
63
+ ],
64
+ };