@jjlmoya/utils-pets 1.22.0 → 1.23.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 +2 -2
- package/src/category/i18n/de.ts +1 -1
- package/src/category/i18n/en.ts +2 -2
- package/src/category/i18n/es.ts +1 -1
- package/src/category/i18n/fr.ts +1 -1
- package/src/category/i18n/pt.ts +1 -1
- package/src/category/i18n/tr.ts +1 -1
- package/src/category/index.ts +26 -26
- package/src/entries.ts +12 -12
- package/src/tests/bibliography_wellformed_export.test.ts +46 -0
- package/src/tests/category_seo_quality.test.ts +74 -0
- package/src/tests/faq_count.test.ts +22 -22
- package/src/tests/locale_completeness.test.ts +30 -30
- package/src/tests/no_h1_in_components.test.ts +1 -1
- package/src/tests/pet_logic.test.ts +49 -0
- package/src/tests/seo_length.test.ts +54 -54
- package/src/tests/seo_parity.test.ts +2 -2
- package/src/tests/seo_wellformed_export.test.ts +65 -0
- package/src/tests/spanish_leakage.test.ts +175 -175
- package/src/tests/tool_validation.test.ts +137 -137
- package/src/tool/petAge/component.astro +3 -3
- package/src/tool/petAge/i18n/de.ts +184 -184
- package/src/tool/petAge/i18n/en.ts +184 -184
- package/src/tool/petAge/i18n/es.ts +184 -184
- package/src/tool/petAge/i18n/fr.ts +184 -184
- package/src/tool/petAge/i18n/id.ts +184 -184
- package/src/tool/petAge/i18n/it.ts +184 -184
- package/src/tool/petAge/i18n/ja.ts +184 -184
- package/src/tool/petAge/i18n/ko.ts +184 -184
- package/src/tool/petAge/i18n/nl.ts +184 -184
- package/src/tool/petAge/i18n/pl.ts +184 -184
- package/src/tool/petAge/i18n/pt.ts +184 -184
- package/src/tool/petAge/i18n/ru.ts +184 -184
- package/src/tool/petAge/i18n/sv.ts +184 -184
- package/src/tool/petAge/i18n/tr.ts +185 -185
- package/src/tool/petAge/i18n/zh.ts +184 -184
- package/src/tool/petAge/seo.astro +15 -15
- package/src/tool/petGestation/i18n/de.ts +0 -2
- package/src/tool/petGestation/i18n/en.ts +0 -2
- package/src/tool/petGestation/i18n/es.ts +0 -2
- package/src/tool/petGestation/i18n/fr.ts +0 -2
- package/src/tool/petGestation/i18n/id.ts +0 -2
- package/src/tool/petGestation/i18n/it.ts +0 -2
- package/src/tool/petGestation/i18n/ja.ts +0 -2
- package/src/tool/petGestation/i18n/ko.ts +0 -2
- package/src/tool/petGestation/i18n/nl.ts +0 -2
- package/src/tool/petGestation/i18n/pl.ts +0 -2
- package/src/tool/petGestation/i18n/pt.ts +0 -2
- package/src/tool/petGestation/i18n/ru.ts +0 -2
- package/src/tool/petGestation/i18n/sv.ts +0 -2
- package/src/tool/petGestation/i18n/tr.ts +0 -2
- package/src/tool/petGestation/i18n/zh.ts +0 -2
- package/src/tool/petGestation/ui.ts +0 -2
- package/src/tool/petRation/i18n/de.ts +181 -181
- package/src/tool/petRation/i18n/en.ts +181 -181
- package/src/tool/petRation/i18n/es.ts +181 -181
- package/src/tool/petRation/i18n/fr.ts +181 -181
- package/src/tool/petRation/i18n/id.ts +181 -181
- package/src/tool/petRation/i18n/it.ts +181 -181
- package/src/tool/petRation/i18n/ja.ts +181 -181
- package/src/tool/petRation/i18n/ko.ts +181 -181
- package/src/tool/petRation/i18n/nl.ts +181 -181
- package/src/tool/petRation/i18n/pl.ts +181 -181
- package/src/tool/petRation/i18n/pt.ts +181 -181
- package/src/tool/petRation/i18n/ru.ts +181 -181
- package/src/tool/petRation/i18n/sv.ts +181 -181
- package/src/tool/petRation/i18n/tr.ts +181 -181
- package/src/tool/petRation/i18n/zh.ts +181 -181
- package/src/tool/petRation/seo.astro +15 -15
- package/src/tool/petToxicity/i18n/de.ts +0 -2
- package/src/tool/petToxicity/i18n/en.ts +0 -2
- package/src/tool/petToxicity/i18n/es.ts +2 -4
- package/src/tool/petToxicity/i18n/fr.ts +0 -2
- package/src/tool/petToxicity/i18n/id.ts +0 -2
- package/src/tool/petToxicity/i18n/it.ts +0 -2
- package/src/tool/petToxicity/i18n/ja.ts +0 -2
- package/src/tool/petToxicity/i18n/ko.ts +0 -2
- package/src/tool/petToxicity/i18n/nl.ts +0 -2
- package/src/tool/petToxicity/i18n/pl.ts +0 -2
- package/src/tool/petToxicity/i18n/pt.ts +0 -2
- package/src/tool/petToxicity/i18n/ru.ts +0 -2
- package/src/tool/petToxicity/i18n/sv.ts +0 -2
- package/src/tool/petToxicity/i18n/tr.ts +0 -2
- package/src/tool/petToxicity/i18n/zh.ts +0 -2
- package/src/tool/petToxicity/ui.ts +0 -2
- package/src/tool/petWaterIntake/i18n/de.ts +0 -15
- package/src/tool/petWaterIntake/i18n/en.ts +0 -15
- package/src/tool/petWaterIntake/i18n/es.ts +2 -17
- package/src/tool/petWaterIntake/i18n/fr.ts +0 -15
- package/src/tool/petWaterIntake/i18n/id.ts +0 -15
- package/src/tool/petWaterIntake/i18n/it.ts +0 -15
- package/src/tool/petWaterIntake/i18n/ja.ts +0 -15
- package/src/tool/petWaterIntake/i18n/ko.ts +0 -15
- package/src/tool/petWaterIntake/i18n/nl.ts +0 -15
- package/src/tool/petWaterIntake/i18n/pl.ts +0 -15
- package/src/tool/petWaterIntake/i18n/pt.ts +0 -15
- package/src/tool/petWaterIntake/i18n/ru.ts +0 -15
- package/src/tool/petWaterIntake/i18n/sv.ts +0 -15
- package/src/tool/petWaterIntake/i18n/tr.ts +0 -15
- package/src/tool/petWaterIntake/i18n/zh.ts +0 -15
- package/src/tool/petWaterIntake/ui.ts +0 -15
- package/src/tools.ts +19 -19
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import * as fs from 'fs';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import { ALL_TOOLS } from '../tools';
|
|
5
|
-
import { petsCategory } from '../data';
|
|
6
|
-
import type { ToolDefinition } from '../types';
|
|
7
|
-
|
|
8
|
-
function extractSeoText(sections: any[]): string {
|
|
9
|
-
return sections
|
|
10
|
-
.map((section) => extractSectionText(section))
|
|
11
|
-
.join(' ');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function extractHtmlOrText(section: any): string {
|
|
15
|
-
const hasContent = 'html' in section || 'text' in section;
|
|
16
|
-
const isNotTable = section.type !== 'table';
|
|
17
|
-
return hasContent && isNotTable ? (section.html || section.text || '') : '';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function extractListItems(section: any): string {
|
|
21
|
-
return 'items' in section && Array.isArray(section.items) ? section.items.join(' ') : '';
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function extractTableRows(section: any): string {
|
|
25
|
-
return 'rows' in section && Array.isArray(section.rows) ? section.rows.flat().join(' ') : '';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function extractSectionText(section: any): string {
|
|
29
|
-
let text = '';
|
|
30
|
-
text += extractHtmlOrText(section);
|
|
31
|
-
text += extractListItems(section);
|
|
32
|
-
text += extractTableRows(section);
|
|
33
|
-
return text;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function countWords(text: string): number {
|
|
37
|
-
return text
|
|
38
|
-
.replace(/<[^>]*>/g, '')
|
|
39
|
-
.trim()
|
|
40
|
-
.split(/\s+/)
|
|
41
|
-
.filter((w) => w.length > 0).length;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
describe('Tool Validation Suite', () => {
|
|
45
|
-
describe('Strict Tool Definition Validation', () => {
|
|
46
|
-
ALL_TOOLS.forEach((tool: ToolDefinition) => {
|
|
47
|
-
const { entry } = tool;
|
|
48
|
-
|
|
49
|
-
describe(`${entry.id} structure`, () => {
|
|
50
|
-
it('should fulfill ToolDefinition interface', () => {
|
|
51
|
-
expect(tool.entry).toBeDefined();
|
|
52
|
-
expect(tool.Component).toBeDefined();
|
|
53
|
-
expect(tool.SEOComponent).toBeDefined();
|
|
54
|
-
expect(tool.BibliographyComponent).toBeDefined();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should have valid ID in kebab-case', () => {
|
|
58
|
-
expect(entry.id).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should have valid icons with bg and fg', () => {
|
|
62
|
-
expect(entry.icons.bg).toMatch(/^mdi:/);
|
|
63
|
-
expect(entry.icons.fg).toMatch(/^mdi:/);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
describe('i18n Content Validation', () => {
|
|
67
|
-
Object.entries(entry.i18n).forEach(([locale, loader]) => {
|
|
68
|
-
it(`should load ${locale} content and follow slug rules`, async () => {
|
|
69
|
-
const content = await loader();
|
|
70
|
-
expect(content.slug).toBeDefined();
|
|
71
|
-
expect(content.slug).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
|
|
72
|
-
|
|
73
|
-
if (locale === 'es') {
|
|
74
|
-
const validSlugs = ['calculadora-edad-mascotas', 'calculadora-racion-diaria-mascotas', 'calculadora-gestacion-mascotas', 'buscador-alimentos-toxicos-perros-gatos', 'calculadora-agua-diaria-perros-gatos', 'planificador-dimensiones-transportin-mascotas'];
|
|
75
|
-
expect(validSlugs).toContain(content.slug);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it(`should have valid basic content in ${locale}`, async () => {
|
|
80
|
-
const content = await loader();
|
|
81
|
-
expect(content.title.length).toBeGreaterThan(0);
|
|
82
|
-
expect(content.description.length).toBeGreaterThan(0);
|
|
83
|
-
expect(Object.keys(content.ui).length).toBeGreaterThan(0);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it(`should have SEO content with > 300 words in ${locale}`, async () => {
|
|
87
|
-
const content = await loader();
|
|
88
|
-
const seoText = extractSeoText(content.seo);
|
|
89
|
-
const wordCount = countWords(seoText);
|
|
90
|
-
expect(wordCount).toBeGreaterThanOrEqual(300);
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe('Library Registration', () => {
|
|
99
|
-
it('should have 5 tools in ALL_TOOLS', () => {
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { ALL_TOOLS } from '../tools';
|
|
5
|
+
import { petsCategory } from '../data';
|
|
6
|
+
import type { ToolDefinition } from '../types';
|
|
7
|
+
|
|
8
|
+
function extractSeoText(sections: any[]): string {
|
|
9
|
+
return sections
|
|
10
|
+
.map((section) => extractSectionText(section))
|
|
11
|
+
.join(' ');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function extractHtmlOrText(section: any): string {
|
|
15
|
+
const hasContent = 'html' in section || 'text' in section;
|
|
16
|
+
const isNotTable = section.type !== 'table';
|
|
17
|
+
return hasContent && isNotTable ? (section.html || section.text || '') : '';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function extractListItems(section: any): string {
|
|
21
|
+
return 'items' in section && Array.isArray(section.items) ? section.items.join(' ') : '';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function extractTableRows(section: any): string {
|
|
25
|
+
return 'rows' in section && Array.isArray(section.rows) ? section.rows.flat().join(' ') : '';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function extractSectionText(section: any): string {
|
|
29
|
+
let text = '';
|
|
30
|
+
text += extractHtmlOrText(section);
|
|
31
|
+
text += extractListItems(section);
|
|
32
|
+
text += extractTableRows(section);
|
|
33
|
+
return text;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function countWords(text: string): number {
|
|
37
|
+
return text
|
|
38
|
+
.replace(/<[^>]*>/g, '')
|
|
39
|
+
.trim()
|
|
40
|
+
.split(/\s+/)
|
|
41
|
+
.filter((w) => w.length > 0).length;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
describe('Tool Validation Suite', () => {
|
|
45
|
+
describe('Strict Tool Definition Validation', () => {
|
|
46
|
+
ALL_TOOLS.forEach((tool: ToolDefinition) => {
|
|
47
|
+
const { entry } = tool;
|
|
48
|
+
|
|
49
|
+
describe(`${entry.id} structure`, () => {
|
|
50
|
+
it('should fulfill ToolDefinition interface', () => {
|
|
51
|
+
expect(tool.entry).toBeDefined();
|
|
52
|
+
expect(tool.Component).toBeDefined();
|
|
53
|
+
expect(tool.SEOComponent).toBeDefined();
|
|
54
|
+
expect(tool.BibliographyComponent).toBeDefined();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should have valid ID in kebab-case', () => {
|
|
58
|
+
expect(entry.id).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should have valid icons with bg and fg', () => {
|
|
62
|
+
expect(entry.icons.bg).toMatch(/^mdi:/);
|
|
63
|
+
expect(entry.icons.fg).toMatch(/^mdi:/);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('i18n Content Validation', () => {
|
|
67
|
+
Object.entries(entry.i18n).forEach(([locale, loader]) => {
|
|
68
|
+
it(`should load ${locale} content and follow slug rules`, async () => {
|
|
69
|
+
const content = await loader();
|
|
70
|
+
expect(content.slug).toBeDefined();
|
|
71
|
+
expect(content.slug).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
|
|
72
|
+
|
|
73
|
+
if (locale === 'es') {
|
|
74
|
+
const validSlugs = ['calculadora-edad-mascotas', 'calculadora-racion-diaria-mascotas', 'calculadora-gestacion-mascotas', 'buscador-alimentos-toxicos-perros-gatos', 'calculadora-agua-diaria-perros-gatos', 'planificador-dimensiones-transportin-mascotas'];
|
|
75
|
+
expect(validSlugs).toContain(content.slug);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it(`should have valid basic content in ${locale}`, async () => {
|
|
80
|
+
const content = await loader();
|
|
81
|
+
expect(content.title.length).toBeGreaterThan(0);
|
|
82
|
+
expect(content.description.length).toBeGreaterThan(0);
|
|
83
|
+
expect(Object.keys(content.ui).length).toBeGreaterThan(0);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it(`should have SEO content with > 300 words in ${locale}`, async () => {
|
|
87
|
+
const content = await loader();
|
|
88
|
+
const seoText = extractSeoText(content.seo);
|
|
89
|
+
const wordCount = countWords(seoText);
|
|
90
|
+
expect(wordCount).toBeGreaterThanOrEqual(300);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe('Library Registration', () => {
|
|
99
|
+
it('should have 5 tools in ALL_TOOLS', () => {
|
|
100
100
|
expect(ALL_TOOLS.length).toBe(6);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should have all tools in petsCategory', () => {
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should have all tools in petsCategory', () => {
|
|
104
104
|
expect(petsCategory.tools.length).toBe(6);
|
|
105
|
-
ALL_TOOLS.forEach(({ entry }) => {
|
|
106
|
-
const exists = petsCategory.tools.some((t: any) => t.id === entry.id);
|
|
107
|
-
expect(exists).toBe(true);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('Binary Consistency', () => {
|
|
113
|
-
ALL_TOOLS.forEach(({ entry }) => {
|
|
114
|
-
it(`${entry.id} files should exist in the tool folder`, () => {
|
|
115
|
-
const toolVarName = (entry.id ?? '').replace(/-([a-z])/g, (_: string, g: string) => g.toUpperCase());
|
|
116
|
-
const toolDir = path.join('src', 'tool', toolVarName);
|
|
117
|
-
|
|
118
|
-
expect(fs.existsSync(path.join(toolDir, 'component.astro'))).toBe(true);
|
|
119
|
-
expect(fs.existsSync(path.join(toolDir, 'seo.astro'))).toBe(true);
|
|
120
|
-
expect(fs.existsSync(path.join(toolDir, 'bibliography.astro'))).toBe(true);
|
|
121
|
-
expect(fs.existsSync(path.join(toolDir, 'index.ts'))).toBe(true);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
describe('Bibliography Components Structure', () => {
|
|
127
|
-
ALL_TOOLS.forEach(({ entry }) => {
|
|
128
|
-
it(`${entry.id} should have a standard bibliography structure`, () => {
|
|
129
|
-
const toolVarName = (entry.id ?? '').replace(/-([a-z])/g, (_: string, g: string) => g.toUpperCase());
|
|
130
|
-
const componentPath = path.join('src', 'tool', toolVarName, 'bibliography.astro');
|
|
131
|
-
const content = fs.readFileSync(componentPath, 'utf-8');
|
|
132
|
-
|
|
133
|
-
expect(content).toContain("import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared'");
|
|
134
|
-
expect(content).toContain("import { bibliography } from './bibliography'");
|
|
135
|
-
expect(content).toContain('<SharedBibliography links={bibliography} />');
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
});
|
|
105
|
+
ALL_TOOLS.forEach(({ entry }) => {
|
|
106
|
+
const exists = petsCategory.tools.some((t: any) => t.id === entry.id);
|
|
107
|
+
expect(exists).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('Binary Consistency', () => {
|
|
113
|
+
ALL_TOOLS.forEach(({ entry }) => {
|
|
114
|
+
it(`${entry.id} files should exist in the tool folder`, () => {
|
|
115
|
+
const toolVarName = (entry.id ?? '').replace(/-([a-z])/g, (_: string, g: string) => g.toUpperCase());
|
|
116
|
+
const toolDir = path.join('src', 'tool', toolVarName);
|
|
117
|
+
|
|
118
|
+
expect(fs.existsSync(path.join(toolDir, 'component.astro'))).toBe(true);
|
|
119
|
+
expect(fs.existsSync(path.join(toolDir, 'seo.astro'))).toBe(true);
|
|
120
|
+
expect(fs.existsSync(path.join(toolDir, 'bibliography.astro'))).toBe(true);
|
|
121
|
+
expect(fs.existsSync(path.join(toolDir, 'index.ts'))).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('Bibliography Components Structure', () => {
|
|
127
|
+
ALL_TOOLS.forEach(({ entry }) => {
|
|
128
|
+
it(`${entry.id} should have a standard bibliography structure`, () => {
|
|
129
|
+
const toolVarName = (entry.id ?? '').replace(/-([a-z])/g, (_: string, g: string) => g.toUpperCase());
|
|
130
|
+
const componentPath = path.join('src', 'tool', toolVarName, 'bibliography.astro');
|
|
131
|
+
const content = fs.readFileSync(componentPath, 'utf-8');
|
|
132
|
+
|
|
133
|
+
expect(content).toContain("import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared'");
|
|
134
|
+
expect(content).toContain("import { bibliography } from './bibliography'");
|
|
135
|
+
expect(content).toContain('<SharedBibliography links={bibliography} />');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -238,6 +238,7 @@ const { ui } = Astro.props;
|
|
|
238
238
|
state: PetAgeState,
|
|
239
239
|
els: Required<ReturnType<typeof getElements>>,
|
|
240
240
|
birthYearInput: HTMLInputElement,
|
|
241
|
+
uiData: Record<string, string>,
|
|
241
242
|
) {
|
|
242
243
|
els.shareBtn?.addEventListener("click", async () => {
|
|
243
244
|
if (!state.birthYear) {
|
|
@@ -253,7 +254,7 @@ const { ui } = Astro.props;
|
|
|
253
254
|
const url = generateShareUrl(state);
|
|
254
255
|
try {
|
|
255
256
|
await navigator.clipboard.writeText(url);
|
|
256
|
-
if (els.shareText) els.shareText.textContent =
|
|
257
|
+
if (els.shareText) els.shareText.textContent = uiData.shareSuccess;
|
|
257
258
|
if (els.shareBtn) els.shareBtn.classList.add("age-btn-success");
|
|
258
259
|
setTimeout(() => (window.location.href = url), 800);
|
|
259
260
|
} catch {
|
|
@@ -292,7 +293,7 @@ const { ui } = Astro.props;
|
|
|
292
293
|
setupPetTypeListener(state, els, onUpdate);
|
|
293
294
|
setupSizeListener(state, els, onUpdate);
|
|
294
295
|
setupBirthYearListener(state, birthYearInput, currentYear, onUpdate);
|
|
295
|
-
setupShareListener(state, els, birthYearInput);
|
|
296
|
+
setupShareListener(state, els, birthYearInput, uiData);
|
|
296
297
|
|
|
297
298
|
onUpdate();
|
|
298
299
|
setTimeout(() => els.loader?.classList.add("hidden"), 50);
|
|
@@ -305,4 +306,3 @@ const { ui } = Astro.props;
|
|
|
305
306
|
}
|
|
306
307
|
document.addEventListener("astro:page-load", initPetAge);
|
|
307
308
|
</script>
|
|
308
|
-
|