@jjlmoya/utils-pets 1.19.0 → 1.20.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 (33) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -1
  3. package/src/entries.ts +4 -1
  4. package/src/tests/locale_completeness.test.ts +1 -1
  5. package/src/tests/tool_validation.test.ts +5 -5
  6. package/src/tool/petWaterIntake/bibliography.astro +6 -0
  7. package/src/tool/petWaterIntake/bibliography.ts +16 -0
  8. package/src/tool/petWaterIntake/component.astro +103 -0
  9. package/src/tool/petWaterIntake/controller.ts +47 -0
  10. package/src/tool/petWaterIntake/dom-views.ts +54 -0
  11. package/src/tool/petWaterIntake/entry.ts +33 -0
  12. package/src/tool/petWaterIntake/i18n/de.ts +205 -0
  13. package/src/tool/petWaterIntake/i18n/en.ts +205 -0
  14. package/src/tool/petWaterIntake/i18n/es.ts +205 -0
  15. package/src/tool/petWaterIntake/i18n/fr.ts +205 -0
  16. package/src/tool/petWaterIntake/i18n/id.ts +237 -0
  17. package/src/tool/petWaterIntake/i18n/it.ts +237 -0
  18. package/src/tool/petWaterIntake/i18n/ja.ts +237 -0
  19. package/src/tool/petWaterIntake/i18n/ko.ts +237 -0
  20. package/src/tool/petWaterIntake/i18n/nl.ts +237 -0
  21. package/src/tool/petWaterIntake/i18n/pl.ts +237 -0
  22. package/src/tool/petWaterIntake/i18n/pt.ts +237 -0
  23. package/src/tool/petWaterIntake/i18n/ru.ts +237 -0
  24. package/src/tool/petWaterIntake/i18n/sv.ts +237 -0
  25. package/src/tool/petWaterIntake/i18n/tr.ts +237 -0
  26. package/src/tool/petWaterIntake/i18n/zh.ts +237 -0
  27. package/src/tool/petWaterIntake/index.ts +11 -0
  28. package/src/tool/petWaterIntake/logic.test.ts +52 -0
  29. package/src/tool/petWaterIntake/logic.ts +84 -0
  30. package/src/tool/petWaterIntake/pet-water-intake.css +144 -0
  31. package/src/tool/petWaterIntake/seo.astro +15 -0
  32. package/src/tool/petWaterIntake/ui.ts +55 -0
  33. package/src/tools.ts +3 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-pets",
3
- "version": "1.19.0",
3
+ "version": "1.20.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -3,10 +3,11 @@ import { petAge } from '../tool/petAge/entry';
3
3
  import { petRation } from '../tool/petRation/entry';
4
4
  import { petGestation } from '../tool/petGestation/entry';
5
5
  import { petToxicity } from '../tool/petToxicity/entry';
6
+ import { petWaterIntake } from '../tool/petWaterIntake/entry';
6
7
 
7
8
  export const petsCategory: PetCategoryEntry = {
8
9
  icon: 'mdi:paw',
9
- tools: [petAge, petRation, petGestation, petToxicity],
10
+ tools: [petAge, petRation, petGestation, petToxicity, petWaterIntake],
10
11
  i18n: {
11
12
  en: () => import('./i18n/en').then((m) => m.content),
12
13
  es: () => import('./i18n/es').then((m) => m.content),
package/src/entries.ts CHANGED
@@ -4,9 +4,12 @@ export { petRation } from './tool/petRation/entry';
4
4
  export type { PetRationUI, PetRationLocaleContent } from './tool/petRation/entry';
5
5
  export { petToxicity } from './tool/petToxicity/entry';
6
6
  export type { PetToxicityUI, PetToxicityLocaleContent } from './tool/petToxicity/entry';
7
+ export { petWaterIntake } from './tool/petWaterIntake/entry';
8
+ export type { PetWaterIntakeUI, PetWaterIntakeLocaleContent } from './tool/petWaterIntake/entry';
7
9
  export { petsCategory } from './category';
8
10
  import { petAge } from './tool/petAge/entry';
9
11
  import { petRation } from './tool/petRation/entry';
10
12
  import { petGestation } from './tool/petGestation/entry';
11
13
  import { petToxicity } from './tool/petToxicity/entry';
12
- export const ALL_ENTRIES = [petAge, petRation, petGestation, petToxicity];
14
+ import { petWaterIntake } from './tool/petWaterIntake/entry';
15
+ export const ALL_ENTRIES = [petAge, petRation, petGestation, petToxicity, petWaterIntake];
@@ -26,6 +26,6 @@ describe('Locale Completeness Validation', () => {
26
26
  });
27
27
 
28
28
  it('all tools registered', () => {
29
- expect(ALL_TOOLS.length).toBe(4);
29
+ expect(ALL_TOOLS.length).toBe(5);
30
30
  });
31
31
  });
@@ -55,7 +55,7 @@ describe('Tool Validation Suite', () => {
55
55
  });
56
56
 
57
57
  it('should have valid ID in kebab-case', () => {
58
- expect(entry.id).toMatch(/^[a-z0-9]+-?[a-z0-9]*$/);
58
+ expect(entry.id).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
59
59
  });
60
60
 
61
61
  it('should have valid icons with bg and fg', () => {
@@ -71,7 +71,7 @@ describe('Tool Validation Suite', () => {
71
71
  expect(content.slug).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
72
72
 
73
73
  if (locale === 'es') {
74
- const validSlugs = ['calculadora-edad-mascotas', 'calculadora-racion-diaria-mascotas', 'calculadora-gestacion-mascotas', 'buscador-alimentos-toxicos-perros-gatos'];
74
+ const validSlugs = ['calculadora-edad-mascotas', 'calculadora-racion-diaria-mascotas', 'calculadora-gestacion-mascotas', 'buscador-alimentos-toxicos-perros-gatos', 'calculadora-agua-diaria-perros-gatos'];
75
75
  expect(validSlugs).toContain(content.slug);
76
76
  }
77
77
  });
@@ -96,12 +96,12 @@ describe('Tool Validation Suite', () => {
96
96
  });
97
97
 
98
98
  describe('Library Registration', () => {
99
- it('should have 4 tools in ALL_TOOLS', () => {
100
- expect(ALL_TOOLS.length).toBe(4);
99
+ it('should have 5 tools in ALL_TOOLS', () => {
100
+ expect(ALL_TOOLS.length).toBe(5);
101
101
  });
102
102
 
103
103
  it('should have all tools in petsCategory', () => {
104
- expect(petsCategory.tools.length).toBe(4);
104
+ expect(petsCategory.tools.length).toBe(5);
105
105
  ALL_TOOLS.forEach(({ entry }) => {
106
106
  const exists = petsCategory.tools.some((t: any) => t.id === entry.id);
107
107
  expect(exists).toBe(true);
@@ -0,0 +1,6 @@
1
+ ---
2
+ import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
+ import { bibliography } from './bibliography';
4
+ ---
5
+
6
+ <SharedBibliography links={bibliography} />
@@ -0,0 +1,16 @@
1
+ import type { BibliographyEntry } from '../../types';
2
+
3
+ export const bibliography: BibliographyEntry[] = [
4
+ {
5
+ name: 'AAHA Anesthesia and Monitoring Guidelines for Dogs and Cats: Fluid Therapy and Maintenance Guidelines',
6
+ url: 'https://www.aaha.org/resources/fluid-therapy-guidelines/',
7
+ },
8
+ {
9
+ name: 'Merck Veterinary Manual: Management of Fluid Therapy in Dogs and Cats',
10
+ url: 'https://www.merckvetmanual.com/emergency-medicine-and-critical-care/fluid-therapy/fluid-therapy-in-animals',
11
+ },
12
+ {
13
+ name: 'WSAVA Global Nutrition Committee: Recommendations for Water Needs in Companion Animals',
14
+ url: 'https://wsava.org/global-guidelines/global-nutrition-guidelines/',
15
+ },
16
+ ];
@@ -0,0 +1,103 @@
1
+ ---
2
+ import './pet-water-intake.css';
3
+ import { calculatePetWaterIntake } from './logic';
4
+ import { renderResult, renderScene } from './dom-views';
5
+ import { petWaterIntake } from './entry';
6
+
7
+ const content = await petWaterIntake.i18n.en?.();
8
+ if (!content) return null;
9
+ const { ui } = content;
10
+
11
+ const defaultSpecies = 'dog';
12
+ const defaultWeight = 10;
13
+ const defaultDiet = 'dry';
14
+ const defaultActivity = 'typical';
15
+ const defaultHeat = 'normal';
16
+
17
+ const initialRes = calculatePetWaterIntake({
18
+ species: defaultSpecies,
19
+ weightKg: defaultWeight,
20
+ diet: defaultDiet,
21
+ activity: defaultActivity,
22
+ heat: defaultHeat,
23
+ });
24
+
25
+ const config = { ui };
26
+ ---
27
+
28
+ <section class="pet-water-intake" data-pet-water-root aria-label={content.title}>
29
+ <div class="pet-water-journey">
30
+ <span class="pet-water-journey-mark" aria-hidden="true">
31
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
32
+ <path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z"></path>
33
+ </svg>
34
+ </span>
35
+ <p>{ui.journeyHint}</p>
36
+ </div>
37
+ <div class="pet-water-workbench">
38
+ <form class="pet-water-controls" data-water-form onsubmit="return false;">
39
+ <div class="pet-water-control">
40
+ <span class="pet-water-label">{ui.speciesLegend}</span>
41
+ <div class="pet-water-radio-group">
42
+ <label>
43
+ <input type="radio" name="species" value="dog" checked />
44
+ {ui.speciesDog}
45
+ </label>
46
+ <label>
47
+ <input type="radio" name="species" value="cat" />
48
+ {ui.speciesCat}
49
+ </label>
50
+ </div>
51
+ </div>
52
+ <div class="pet-water-control">
53
+ <label for="pet-water-weight-input" class="pet-water-label">{ui.weightLabel} ({ui.weightKg})</label>
54
+ <input
55
+ id="pet-water-weight-input"
56
+ type="number"
57
+ name="weight"
58
+ class="pet-water-input"
59
+ value={defaultWeight}
60
+ min="0.5"
61
+ max="100"
62
+ step="0.5"
63
+ />
64
+ <small>{ui.weightHint}</small>
65
+ </div>
66
+ <div class="pet-water-control">
67
+ <label for="pet-water-diet-select" class="pet-water-label">{ui.dietLegend}</label>
68
+ <select id="pet-water-diet-select" name="diet" class="pet-water-select">
69
+ <option value="dry" selected>{ui.dietDry}</option>
70
+ <option value="mixed">{ui.dietMixed}</option>
71
+ <option value="wet">{ui.dietWet}</option>
72
+ </select>
73
+ </div>
74
+ <div class="pet-water-control">
75
+ <label for="pet-water-activity-select" class="pet-water-label">{ui.activityLegend}</label>
76
+ <select id="pet-water-activity-select" name="activity" class="pet-water-select">
77
+ <option value="calm">{ui.activityCalm}</option>
78
+ <option value="typical" selected>{ui.activityTypical}</option>
79
+ <option value="active">{ui.activityActive}</option>
80
+ </select>
81
+ </div>
82
+ <div class="pet-water-control">
83
+ <label for="pet-water-heat-select" class="pet-water-label">{ui.heatLegend}</label>
84
+ <select id="pet-water-heat-select" name="heat" class="pet-water-select">
85
+ <option value="normal" selected>{ui.heatNormal}</option>
86
+ <option value="warm">{ui.heatWarm}</option>
87
+ <option value="hot">{ui.heatHot}</option>
88
+ </select>
89
+ </div>
90
+ </form>
91
+ <div class="pet-water-visual" data-scene set:html={renderScene(initialRes, ui)}></div>
92
+ </div>
93
+ <div class="pet-water-result" data-result aria-live="polite" set:html={renderResult(initialRes, ui)}></div>
94
+ </section>
95
+
96
+ <script is:inline type="application/json" data-pet-water-config set:html={JSON.stringify(config)}></script>
97
+ <script>
98
+ import { mountPetWaterIntake } from './controller';
99
+
100
+ const root = document.querySelector<HTMLElement>('[data-pet-water-root]');
101
+ const configElement = document.querySelector<HTMLScriptElement>('[data-pet-water-config]');
102
+ if (root && configElement?.textContent) mountPetWaterIntake(root, JSON.parse(configElement.textContent));
103
+ </script>
@@ -0,0 +1,47 @@
1
+ import type { WaterCalculationInput } from './logic';
2
+ import { calculatePetWaterIntake } from './logic';
3
+ import { renderResult, renderScene } from './dom-views';
4
+ import type { PetWaterIntakeUI } from './ui';
5
+
6
+ export interface PetWaterIntakeConfig {
7
+ ui: PetWaterIntakeUI;
8
+ }
9
+
10
+ function parseFormString(data: FormData, key: string, fallback: string): string {
11
+ const val = data.get(key);
12
+ return typeof val === 'string' && val.length > 0 ? val : fallback;
13
+ }
14
+
15
+ function getWaterInput(form: HTMLFormElement): WaterCalculationInput | null {
16
+ const data = new FormData(form);
17
+ const weightVal = parseFloat(parseFormString(data, 'weight', '0'));
18
+ if (isNaN(weightVal) || weightVal <= 0 || weightVal > 100) return null;
19
+
20
+ return {
21
+ species: parseFormString(data, 'species', 'dog') as WaterCalculationInput['species'],
22
+ weightKg: weightVal,
23
+ diet: parseFormString(data, 'diet', 'dry') as WaterCalculationInput['diet'],
24
+ activity: parseFormString(data, 'activity', 'typical') as WaterCalculationInput['activity'],
25
+ heat: parseFormString(data, 'heat', 'normal') as WaterCalculationInput['heat'],
26
+ };
27
+ }
28
+
29
+ export function mountPetWaterIntake(root: HTMLElement, config: PetWaterIntakeConfig): void {
30
+ const { ui } = config;
31
+ const form = root.querySelector<HTMLFormElement>('[data-water-form]');
32
+ const sceneEl = root.querySelector<HTMLElement>('[data-scene]');
33
+ const resultEl = root.querySelector<HTMLElement>('[data-result]');
34
+
35
+ if (!form || !sceneEl || !resultEl) return;
36
+
37
+ function update(): void {
38
+ const input = getWaterInput(form!);
39
+ const res = input ? calculatePetWaterIntake(input) : null;
40
+ sceneEl!.innerHTML = renderScene(res, ui);
41
+ resultEl!.innerHTML = renderResult(res, ui);
42
+ }
43
+
44
+ form.addEventListener('input', update);
45
+ form.addEventListener('change', update);
46
+ update();
47
+ }
@@ -0,0 +1,54 @@
1
+ import type { WaterCalculationResult } from './logic';
2
+ import type { PetWaterIntakeUI } from './ui';
3
+
4
+ export function renderScene(res: WaterCalculationResult | null, ui: PetWaterIntakeUI): string {
5
+ if (!res) {
6
+ return `<div class="pet-water-scene-empty">${ui.resultEmpty}</div>`;
7
+ }
8
+ const pct = Math.min(100, Math.max(15, Math.round((res.totalMlMax / 1500) * 100)));
9
+ return `
10
+ <div class="pet-water-scene" aria-label="${ui.sceneAria}">
11
+ <div class="pet-water-reservoir">
12
+ <div class="pet-water-fill" style="height: ${pct}%">
13
+ <div class="pet-water-wave"></div>
14
+ </div>
15
+ </div>
16
+ <div class="pet-water-badge">
17
+ <span class="pet-water-badge-label">${ui.sceneTotal}</span>
18
+ <span class="pet-water-badge-value">${res.totalMlMin} - ${res.totalMlMax} mL</span>
19
+ </div>
20
+ </div>
21
+ `;
22
+ }
23
+
24
+ export function renderResult(res: WaterCalculationResult | null, ui: PetWaterIntakeUI): string {
25
+ if (!res) return `<div class="pet-water-result-placeholder">${ui.resultEmpty}</div>`;
26
+
27
+ const metrics = `
28
+ <div class="pet-water-metrics">
29
+ <div class="pet-water-metric">
30
+ <span class="pet-water-metric-label">${ui.totalRangeLabel}</span>
31
+ <span class="pet-water-metric-value">${res.totalMlMin} - ${res.totalMlMax} mL/día</span>
32
+ <small>${ui.totalRangeHint}</small>
33
+ </div>
34
+ <div class="pet-water-metric">
35
+ <span class="pet-water-metric-label">${ui.drinkingRangeLabel}</span>
36
+ <span class="pet-water-metric-value">${res.bowlMlMin} - ${res.bowlMlMax} mL/día</span>
37
+ <small>${ui.drinkingRangeHint}</small>
38
+ </div>
39
+ </div>`;
40
+
41
+ return `
42
+ <div class="pet-water-result-card">
43
+ <span class="pet-water-eyebrow">${ui.resultEyebrow}</span>
44
+ ${metrics}
45
+ <div class="pet-water-status">
46
+ <strong>${ui[res.statusKey] || ''}</strong>
47
+ <p>${ui[res.statusDetailKey] || ''}</p>
48
+ </div>
49
+ <div class="pet-water-notes">
50
+ <h4>${ui.noteTitle}</h4>
51
+ <p>${ui.noteText}</p>
52
+ </div>
53
+ </div>`;
54
+ }
@@ -0,0 +1,33 @@
1
+ import type { PetToolEntry, ToolLocaleContent } from '../../types';
2
+ import type { PetWaterIntakeUI } from './ui';
3
+
4
+ export type { PetWaterIntakeUI } from './ui';
5
+
6
+ export type PetWaterIntakeLocaleContent = ToolLocaleContent<PetWaterIntakeUI>;
7
+
8
+ export const petWaterIntake: PetToolEntry<PetWaterIntakeUI> = {
9
+ id: 'pet-water-intake',
10
+ icons: {
11
+ bg: 'mdi:paw',
12
+ fg: 'mdi:water',
13
+ },
14
+ i18n: {
15
+ de: () => import('./i18n/de').then((module) => module.content),
16
+ en: () => import('./i18n/en').then((module) => module.content),
17
+ es: () => import('./i18n/es').then((module) => module.content),
18
+ fr: () => import('./i18n/fr').then((module) => module.content),
19
+ id: () => import('./i18n/id').then((module) => module.content),
20
+ it: () => import('./i18n/it').then((module) => module.content),
21
+ ja: () => import('./i18n/ja').then((module) => module.content),
22
+ ko: () => import('./i18n/ko').then((module) => module.content),
23
+ nl: () => import('./i18n/nl').then((module) => module.content),
24
+ pl: () => import('./i18n/pl').then((module) => module.content),
25
+ pt: () => import('./i18n/pt').then((module) => module.content),
26
+ ru: () => import('./i18n/ru').then((module) => module.content),
27
+ sv: () => import('./i18n/sv').then((module) => module.content),
28
+ tr: () => import('./i18n/tr').then((module) => module.content),
29
+ zh: () => import('./i18n/zh').then((module) => module.content),
30
+ },
31
+ };
32
+
33
+ export { bibliography } from './bibliography';
@@ -0,0 +1,205 @@
1
+ import { bibliography } from '../bibliography';
2
+ import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
3
+ import type { PetWaterIntakeLocaleContent, PetWaterIntakeUI } from '../entry';
4
+
5
+ const slug = 'wasserbedarf-rechner-hunde-katzen';
6
+ const title = 'Täglicher Wasserbedarf Rechner für Hunde und Katzen';
7
+ const description = 'Berechnen Sie den täglichen Wasserbedarf Ihres Hundes oder Ihrer Katze basierend auf Gewicht, Fütterung, Aktivität und Umgebungstemperatur.';
8
+
9
+ const ui: PetWaterIntakeUI = {
10
+ journeyHint: 'Wählen Sie das Tier aus, geben Sie das Körpergewicht ein und stellen Sie Futterart und Klima ein.',
11
+ instantHint: 'Jede Option passt den Wasserstand sofort an. Es handelt sich um eine Richtlinie.',
12
+ unitLegend: 'Einheiten',
13
+ metricUnit: 'Metrisch',
14
+ imperialUnit: 'Imperial',
15
+ speciesLegend: 'Für wen ist der Wassernapf?',
16
+ speciesDog: 'Hund',
17
+ speciesCat: 'Katze',
18
+ speciesDogMeta: 'Richtwert 60 mL pro kg',
19
+ speciesCatMeta: 'Richtwert 40 mL pro kg',
20
+ weightLabel: 'Körpergewicht',
21
+ weightHint: 'Geben Sie das aktuelle gesunde Gewicht an.',
22
+ weightKg: 'kg',
23
+ weightLb: 'lb',
24
+ dietLegend: 'Wie viel Wasser liefert das Futter?',
25
+ dietDry: 'Überwiegend Trockenfutter',
26
+ dietDryMeta: 'Der Großteil des Wassers wird getrunken',
27
+ dietMixed: 'Mischfütterung',
28
+ dietMixedMeta: 'Ein Teil des Wassers stammt aus den Mahlzeiten',
29
+ dietWet: 'Überwiegend Nassfutter',
30
+ dietWetMeta: 'Nassfutter liefert einen großen Teil der Feuchtigkeit',
31
+ activityLegend: 'Aktivität heute',
32
+ activityCalm: 'Ruhig',
33
+ activityTypical: 'Normal',
34
+ activityActive: 'Sehr aktiv',
35
+ heatLegend: 'Wetter und Temperatur',
36
+ heatNormal: 'Normal',
37
+ heatWarm: 'Warm',
38
+ heatHot: 'Sehr heiß',
39
+ resultEyebrow: 'Wasserstandsanzeige',
40
+ totalRangeLabel: 'Gesamter Wasserbedarf (alle Quellen)',
41
+ drinkingRangeLabel: 'Richtwert für den Wassernapf',
42
+ totalRangeHint: 'Täglicher Zielbereich inklusive Futterfeuchtigkeit.',
43
+ drinkingRangeHint: 'Geschätzter Anteil, der getrunken werden sollte.',
44
+ statusEveryday: 'Standardbedingungen',
45
+ statusActive: 'Aktiver Tag',
46
+ statusWarm: 'Warmes Wetter',
47
+ statusDemanding: 'Hohe Anforderungen',
48
+ statusDetailEveryday: 'Nutzt den Grundbedarf ohne zusätzliche Hitze- oder Aktivitätsfaktoren.',
49
+ statusDetailActive: 'Bewegung erhöht den Bedarf. Stellen Sie stets frisches Wasser bereit.',
50
+ statusDetailWarm: 'Hitze steigert den Verlust durch Hecheln. Schatten hat Priorität.',
51
+ statusDetailDemanding: 'Kombination aus hoher Aktivität und Hitze. Beobachten Sie das Tier genau.',
52
+ resultEmpty: 'Geben Sie ein gültiges Gewicht ein, um den Wasserbedarf anzuzeigen.',
53
+ sceneAria: 'Wasserbehälter für das ausgewählte Tier',
54
+ sceneTotal: 'GESAMTWASSER',
55
+ sceneBowl: 'Mitte des täglichen Bereichs',
56
+ methodTitle: 'Berechnungsmethode',
57
+ methodText: 'Basiert auf den AAHA-Richtwerten von 60 mL/kg für Hunde und 40 mL/kg für Katzen mit Anpassung an Futter und Wetter.',
58
+ noteTitle: 'Wassernäpfe ersetzen keine Diagnostik',
59
+ noteText: 'Halten Sie immer frisches Wasser bereit. Bei plötzlichen Veränderungen der Trinkmenge suchen Sie einen Tierarzt auf.',
60
+ invalidWeight: 'Bitte geben Sie ein gültiges Körpergewicht ein.',
61
+ weightRange: 'Das Gewicht muss zwischen 0.5 kg und 100 kg liegen.',
62
+ };
63
+
64
+ const faq: PetWaterIntakeLocaleContent['faq'] = [
65
+ {
66
+ question: 'Wie viel Wasser sollte ein Hund oder eine Katze am Tag trinken?',
67
+ answer: 'Tierärztliche Richtlinien der AAHA empfehlen einen Erhaltungsbedarf von ca. 60 mL pro kg Körpergewicht bei Hunden und 40 mL pro kg bei Katzen pro Tag. Die tatsächliche Trinkmenge schwankt je nach Futterart, Temperatur und Bewegung.',
68
+ },
69
+ {
70
+ question: 'Reduziert Nassfutter die Trinkmenge aus dem Napf?',
71
+ answer: 'Ja, Nassfutter besteht zu 75% bis 82% aus Feuchtigkeit und deckt einen Großteil des Tagesbedarfs ab. Tiere bei Nassfütterung trinken daher deutlich seltener zusätzlich aus der Wasserschale.',
72
+ },
73
+ {
74
+ question: 'Wann sollte ich mir wegen des Trinkverhaltens Sorgen machen?',
75
+ answer: 'Suchen Sie einen Tierarzt auf, wenn Sie plötzlichen extremen Durst (Polydipsie) oder völlige Wasserverweigerung (Adipsia) bemerken. Dies können Anzeichen für Diabetes oder Nierenerkrankungen sein.',
76
+ },
77
+ {
78
+ question: 'Können Hitze und Bewegung den Wasserbedarf verdoppeln?',
79
+ answer: 'Ja. Hohe Temperaturen und Bewegung erhöhen den Verdunstungsverlust durch Hecheln erheblich. Schattige Ruheplätze und kühles Trinkwasser sind dann essenziell.',
80
+ },
81
+ ];
82
+
83
+ const howTo: PetWaterIntakeLocaleContent['howTo'] = [
84
+ { name: 'Tierart und Gewicht wählen', text: 'Wählen Sie Hund oder Katze und tragen Sie das aktuelle gesunde Körpergewicht in kg oder lb ein.' },
85
+ { name: 'Futterart angeben', text: 'Wählen Sie Trockenfutter, Mischfütterung oder Nassfutter, um die Feuchtigkeit aus den Mahlzeiten einzurechnen.' },
86
+ { name: 'Aktivität und Klima anpassen', text: 'Stellen Sie das Bewegungslevel und die Temperatur ein, um den Verlust durch Hecheln zu berücksichtigen.' },
87
+ { name: 'Empfehlungen ablesen', text: 'Prüfen Sie den Gesamtwasserbedarf sowie den geschätzten Richtwert für die reine Trinkmenge aus dem Napf.' },
88
+ ];
89
+
90
+ const seo: PetWaterIntakeLocaleContent['seo'] = [
91
+ {
92
+ type: 'summary',
93
+ title: 'Wichtige Richtlinien für den täglichen Wasserbedarf von Haustieren',
94
+ items: [
95
+ 'Grundlegende Erhaltung: Hunde benötigen täglich ca. 60 mL/kg Körpergewicht; Katzen benötigen ca. 40 mL/kg gemäß AAHA-Empfehlungen.',
96
+ 'Einfluss der Ernährung: Feuchtfutter liefert 70-80% Feuchtigkeit und reduziert die Besuche am Wassernapf erheblich.',
97
+ 'Hitze & Bewegung: Durch Hecheln steigt der Verdunstungsverlust, was den täglichen Hydratationsbedarf spürbar erhöht.',
98
+ 'Gesundheitliche Warnzeichen: Plötzlicher starker Durst oder Verweigerung von Wasser erfordert sofortige tierärztliche Abklärung.',
99
+ 'Zugang zu Frischwasser: Mehrere saubere Wassernäpfe an ruhigen Orten fördern ein gesundes und regelmäßiges Trinkverhalten.',
100
+ ],
101
+ },
102
+ {
103
+ type: 'title',
104
+ text: 'Tägliche Flüssigkeitsberechnung und Hydratation für Hunde und Katzen',
105
+ level: 2,
106
+ },
107
+ {
108
+ type: 'paragraph',
109
+ html: 'Eine ausreichende und kontinuierliche Hydratation von Hunden und Katzen ist eine grundlegende Voraussetzung für den Stoffwechsel, die Verdauung, die Gelenkschmierung, die Thermoregulation und die langfristige Nierenfunktion. Wasser macht etwa 60% bis 70% des gesamten Körpergewichts eines ausgewachsenen Haustieres aus, und selbst ein geringfügiges Flüssigkeitsdefizit kann lebenswichtige physiologische Prozesse beeinträchtigen. Die veterinärmedizinische Fachliteratur der American Animal Hospital Association (AAHA) legt den täglichen Grundbedarf auf ca. 60 mL pro Kilogramm Körpergewicht bei Hunden und 40 mL pro Kilogramm bei Katzen fest.',
110
+ },
111
+ {
112
+ type: 'paragraph',
113
+ html: 'Diese wissenschaftlichen Orientierungswerte stellen jedoch den Gesamtwasserbedarf dar und nicht die reine Trinkmenge aus der Wasserschale. Die tägliche Flüssigkeitsaufnahme eines Tieres setzt sich aus drei Hauptquellen zusammen: dem direkt getrunkenen Wasser, der im kommerziellen oder selbst zubereiteten Futter enthaltenen Feuchtigkeit sowie einer kleineren Menge an Stoffwechselwasser, das bei der zellulären Atmung entsteht. Dieses Verständnis hilft Haltern, das Trinkverhalten realistisch einzuschätzen und unnötige Sorgen bei Fütterung feuchter Nahrung zu vermeiden.',
114
+ },
115
+ {
116
+ type: 'title',
117
+ text: 'Gesamtwasserbedarf versus reine Trinkmenge aus dem Wassernapf',
118
+ level: 2,
119
+ },
120
+ {
121
+ type: 'paragraph',
122
+ html: 'Die Futterform spielt eine entscheidende Rolle bei der Bestimmung, wie viel Wasser ein Haustier aktiv aus dem Napf aufnehmen muss. Herkömmliches Trockenfutter enthält meist nur 6% bis 10% Feuchtigkeit, weshalb das Tier fast seinen gesamten täglichen Flüssigkeitsbedarf über den Wassernapf decken muss. Nassfutter aus Dosen oder Beuteln hingegen besteht zu 75% bis 82% aus Wasser. Eine Katze oder ein Hund bei reiner Nassfütterung deckt somit bereits den Großteil des Tagesbedarfs über die Mahlzeiten ab, wodurch zusätzliche Trinkversuche selten werden.',
123
+ },
124
+ {
125
+ type: 'table',
126
+ headers: ['Einflussfaktor', 'Wirkung auf Hydratation', 'Wichtiger klinischer Kernaspekt'],
127
+ rows: [
128
+ ['Tierart & Rasse', 'Bestimmt den Grundbedarf pro kg', 'Hunde-Basis ~60 mL/kg; Katzen-Basis ~40 mL/kg'],
129
+ ['Körpergewicht', 'Skaliert die benötigte Gesamtmenge', 'Bei Übergewicht das gesundes Zielgewicht als Basis nutzen'],
130
+ ['Futterfeuchtigkeit', 'Verändert die Wasserzufuhr über Mahlzeiten', 'Nassfutter deckt bis zu 80% des täglichen Flüssigkeitsbedarfs'],
131
+ ['Klima & Aktivität', 'Erhöht den Verlust durch Atmung & Hecheln', 'Höhere Temperaturen erfordern deutlich mehr frisches Trinkwasser'],
132
+ ],
133
+ },
134
+ {
135
+ type: 'title',
136
+ text: 'Praktische Empfehlungen für das tägliche Hydratationsmanagement',
137
+ level: 2,
138
+ },
139
+ {
140
+ type: 'paragraph',
141
+ html: 'Tierhalter sollten sich darauf konzentrieren, stets freien und uneingeschränkten Zugang zu sauberem, frischem Wasser zu gewährleisten, anstatt zu versuchen, eine starre numerische Zielmenge zu erzwingen. Wassernäpfe sollten täglich gründlich gereinigt und mit neuem Wasser befüllt werden. Insbesondere bei Katzen, die von wüstenbewohnenden Vorfahren abstammen und oft ein geringes Durstgefühl zeigen, können Trinkbrunnen, breite flache Schalen gegen Schnurrhaarreizung und mehrere Trinkstationen im Haus das freiwillige Trinken wirksam fördern.',
142
+ },
143
+ {
144
+ type: 'card',
145
+ title: 'Management bei Trockenfütterung',
146
+ icon: 'mdi:food-drumstick',
147
+ html: 'Tiere bei Trockenfütterung sind vollständig auf das Trinken aus der Wasserschale angewiesen. Sorgen Sie dafür, dass die Näpfe an ruhigen, gut zugänglichen Orten abseits von Katzentoiletten stehen.',
148
+ },
149
+ {
150
+ type: 'card',
151
+ title: 'Management bei Nassfütterung',
152
+ icon: 'mdi:food-drumstick',
153
+ html: 'Nassfutter bietet eine hervorragende kontinuierliche Hydratation. Auch wenn die Tiere seltener am Napf trinken, muss rund um die Uhr frisches Trinkwasser zur Verfügung stehen.',
154
+ },
155
+ {
156
+ type: 'card',
157
+ title: 'Hitze und sportliche Aktivität',
158
+ icon: 'mdi:weather-sunny',
159
+ html: 'Bei hohen Sommerwerten oder intensiver Bewegung steigt der Flüssigkeitsverlust durch Hecheln rasch an. Stellen Sie schattige Ruheplätze und kühles Wasser bereit.',
160
+ },
161
+ {
162
+ type: 'tip',
163
+ title: 'Tierärztliche Warnsignale und Symptome',
164
+ html: 'Eine plötzliche Veränderung des Trinkverhaltens - sei es stark gesteigerter Durst (Polydipsie) oder völlige Wasserverweigerung - ist ein wichtiges klinisches Symptom. Erkrankungen wie Niereninsuffizienz, Diabetes mellitus oder Schilddrüsenüberfunktion äußern sich häufig über den Durst. Suchen Sie bei anhaltenden Auffälligkeiten sofort einen Tierarzt auf.',
165
+ },
166
+ ];
167
+
168
+ const schemas: PetWaterIntakeLocaleContent['schemas'] = [
169
+ {
170
+ '@context': 'https://schema.org',
171
+ '@type': 'SoftwareApplication',
172
+ name: title,
173
+ description,
174
+ applicationCategory: 'HealthApplication',
175
+ operatingSystem: 'Web',
176
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
177
+ } as WithContext<SoftwareApplication>,
178
+ {
179
+ '@context': 'https://schema.org',
180
+ '@type': 'FAQPage',
181
+ mainEntity: faq.map((item) => ({
182
+ '@type': 'Question',
183
+ name: item.question,
184
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
185
+ })),
186
+ } as WithContext<FAQPage>,
187
+ {
188
+ '@context': 'https://schema.org',
189
+ '@type': 'HowTo',
190
+ name: title,
191
+ step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })),
192
+ } as WithContext<HowTo>,
193
+ ];
194
+
195
+ export const content: PetWaterIntakeLocaleContent = {
196
+ slug,
197
+ title,
198
+ description,
199
+ ui,
200
+ seo,
201
+ faq,
202
+ bibliography,
203
+ howTo,
204
+ schemas,
205
+ };