@jjlmoya/utils-nature 1.12.0 → 1.14.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/pages/[locale]/[slug].astro +32 -14
- package/src/tests/locale_completeness.test.ts +1 -31
- package/src/tests/shared-test-helpers.ts +56 -0
- package/src/tests/tool_exports.test.ts +34 -0
- package/src/tool/cricketThermometer/bibliography.ts +12 -0
- package/src/tool/cricketThermometer/cricket-thermometer.css +4 -4
- package/src/tool/cricketThermometer/i18n/de.ts +2 -14
- package/src/tool/cricketThermometer/i18n/en.ts +2 -14
- package/src/tool/cricketThermometer/i18n/es.ts +2 -14
- package/src/tool/cricketThermometer/i18n/fr.ts +2 -14
- package/src/tool/cricketThermometer/i18n/id.ts +2 -14
- package/src/tool/cricketThermometer/i18n/it.ts +2 -14
- package/src/tool/cricketThermometer/i18n/ja.ts +2 -14
- package/src/tool/cricketThermometer/i18n/ko.ts +2 -14
- package/src/tool/cricketThermometer/i18n/nl.ts +2 -14
- package/src/tool/cricketThermometer/i18n/pl.ts +2 -14
- package/src/tool/cricketThermometer/i18n/pt.ts +2 -14
- package/src/tool/cricketThermometer/i18n/ru.ts +2 -14
- package/src/tool/cricketThermometer/i18n/sv.ts +2 -14
- package/src/tool/cricketThermometer/i18n/tr.ts +2 -14
- package/src/tool/cricketThermometer/i18n/zh.ts +2 -14
- package/src/tool/cricketThermometer/seo.astro +1 -1
- package/src/tool/cricketThermometer/ui.ts +0 -2
- package/src/tool/digitalCarbon/bibliography.ts +8 -0
- package/src/tool/digitalCarbon/digital-carbon-footprint-calculator.css +11 -11
- package/src/tool/digitalCarbon/i18n/de.ts +2 -8
- package/src/tool/digitalCarbon/i18n/en.ts +2 -8
- package/src/tool/digitalCarbon/i18n/es.ts +2 -8
- package/src/tool/digitalCarbon/i18n/fr.ts +2 -8
- package/src/tool/digitalCarbon/i18n/id.ts +2 -8
- package/src/tool/digitalCarbon/i18n/it.ts +2 -8
- package/src/tool/digitalCarbon/i18n/ja.ts +2 -8
- package/src/tool/digitalCarbon/i18n/ko.ts +2 -8
- package/src/tool/digitalCarbon/i18n/nl.ts +2 -8
- package/src/tool/digitalCarbon/i18n/pl.ts +2 -8
- package/src/tool/digitalCarbon/i18n/pt.ts +2 -8
- package/src/tool/digitalCarbon/i18n/ru.ts +2 -8
- package/src/tool/digitalCarbon/i18n/sv.ts +2 -8
- package/src/tool/digitalCarbon/i18n/tr.ts +2 -8
- package/src/tool/digitalCarbon/i18n/zh.ts +2 -8
- package/src/tool/digitalCarbon/seo.astro +1 -1
- package/src/tool/rainHarvester/bibliography.ts +20 -0
- package/src/tool/rainHarvester/i18n/de.ts +2 -20
- package/src/tool/rainHarvester/i18n/en.ts +2 -20
- package/src/tool/rainHarvester/i18n/es.ts +2 -20
- package/src/tool/rainHarvester/i18n/fr.ts +2 -20
- package/src/tool/rainHarvester/i18n/id.ts +2 -20
- package/src/tool/rainHarvester/i18n/it.ts +2 -20
- package/src/tool/rainHarvester/i18n/ja.ts +2 -20
- package/src/tool/rainHarvester/i18n/ko.ts +2 -20
- package/src/tool/rainHarvester/i18n/nl.ts +2 -20
- package/src/tool/rainHarvester/i18n/pl.ts +2 -20
- package/src/tool/rainHarvester/i18n/pt.ts +2 -20
- package/src/tool/rainHarvester/i18n/ru.ts +2 -20
- package/src/tool/rainHarvester/i18n/sv.ts +2 -20
- package/src/tool/rainHarvester/i18n/tr.ts +2 -20
- package/src/tool/rainHarvester/i18n/zh.ts +2 -20
- package/src/tool/rainHarvester/rainwater-calculator.css +1 -1
- package/src/tool/rainHarvester/seo.astro +1 -1
- package/src/tool/seedCalculator/bibliography.ts +16 -0
- package/src/tool/seedCalculator/i18n/de.ts +2 -18
- package/src/tool/seedCalculator/i18n/en.ts +2 -18
- package/src/tool/seedCalculator/i18n/es.ts +2 -18
- package/src/tool/seedCalculator/i18n/fr.ts +2 -18
- package/src/tool/seedCalculator/i18n/id.ts +2 -18
- package/src/tool/seedCalculator/i18n/it.ts +2 -18
- package/src/tool/seedCalculator/i18n/ja.ts +2 -18
- package/src/tool/seedCalculator/i18n/ko.ts +2 -18
- package/src/tool/seedCalculator/i18n/nl.ts +2 -18
- package/src/tool/seedCalculator/i18n/pl.ts +2 -18
- package/src/tool/seedCalculator/i18n/pt.ts +2 -18
- package/src/tool/seedCalculator/i18n/ru.ts +2 -18
- package/src/tool/seedCalculator/i18n/sv.ts +2 -18
- package/src/tool/seedCalculator/i18n/tr.ts +2 -18
- package/src/tool/seedCalculator/i18n/zh.ts +2 -18
- package/src/tool/seedCalculator/seed-calculator.css +11 -11
- package/src/tool/seedCalculator/seo.astro +8 -2
- package/src/tool/seedCalculator/ui.ts +0 -2
- package/src/types.ts +0 -2
package/package.json
CHANGED
|
@@ -34,18 +34,28 @@ export async function getStaticPaths() {
|
|
|
34
34
|
]),
|
|
35
35
|
) as Partial<Record<KnownLocale, string>>;
|
|
36
36
|
|
|
37
|
+
const firstLoader = entry.i18n.en ?? Object.values(entry.i18n)[0];
|
|
38
|
+
const englishSlug = firstLoader ? (await firstLoader()).slug : entry.id;
|
|
39
|
+
|
|
37
40
|
for (const { locale, content } of localeContents) {
|
|
38
|
-
const allToolsNav =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
const allToolsNav = (
|
|
42
|
+
await Promise.all(
|
|
43
|
+
ALL_TOOLS.map(async ({ entry: navEntry }) => {
|
|
44
|
+
const loader = navEntry.i18n[locale] ?? navEntry.i18n.en;
|
|
45
|
+
if (!loader) return null;
|
|
46
|
+
const navContent = await loader();
|
|
47
|
+
return {
|
|
48
|
+
id: navEntry.id,
|
|
49
|
+
title: navContent.title,
|
|
50
|
+
href: `/${locale}/${navContent.slug}`,
|
|
51
|
+
isActive: navEntry.id === entry.id,
|
|
52
|
+
};
|
|
53
|
+
}),
|
|
54
|
+
)
|
|
55
|
+
).filter(Boolean) as NavItem[];
|
|
46
56
|
paths.push({
|
|
47
57
|
params: { locale, slug: content.slug },
|
|
48
|
-
props: { Component, locale, content, localeUrls, allToolsNav },
|
|
58
|
+
props: { Component, locale, content, localeUrls, allToolsNav, englishSlug },
|
|
49
59
|
});
|
|
50
60
|
}
|
|
51
61
|
}
|
|
@@ -66,11 +76,16 @@ interface Props {
|
|
|
66
76
|
content: ToolLocaleContent;
|
|
67
77
|
localeUrls: Partial<Record<KnownLocale, string>>;
|
|
68
78
|
allToolsNav: NavItem[];
|
|
79
|
+
englishSlug: string;
|
|
69
80
|
}
|
|
70
81
|
|
|
71
|
-
const { Component, locale, content, localeUrls, allToolsNav } = Astro.props;
|
|
82
|
+
const { Component, locale, content, localeUrls, allToolsNav, englishSlug } = Astro.props;
|
|
83
|
+
|
|
84
|
+
const cssFiles = import.meta.glob("../../tool/**/*.css", { query: "?raw", import: "default" });
|
|
85
|
+
const cssKey = Object.keys(cssFiles).find((k) => k.endsWith(`/${englishSlug}.css`));
|
|
86
|
+
const toolCss = cssKey ? await cssFiles[cssKey]() as string : "";
|
|
72
87
|
|
|
73
|
-
const seoContent: UtilitySEOContent = { locale, sections: content.seo };
|
|
88
|
+
const seoContent: UtilitySEOContent = { locale, sections: content.seo ?? [] };
|
|
74
89
|
|
|
75
90
|
const words = content.title.split(" ");
|
|
76
91
|
const titleHighlight = words[0] || "";
|
|
@@ -89,8 +104,9 @@ const titleBase = words.slice(1).join(" ") || "";
|
|
|
89
104
|
tools={allToolsNav}
|
|
90
105
|
/>
|
|
91
106
|
<Fragment slot="head">
|
|
107
|
+
{toolCss && <style set:html={toolCss} />}
|
|
92
108
|
{
|
|
93
|
-
content.schemas.map((schema
|
|
109
|
+
( content.schemas ?? []).map((schema) => (
|
|
94
110
|
<script
|
|
95
111
|
is:inline
|
|
96
112
|
type="application/ld+json"
|
|
@@ -116,11 +132,11 @@ const titleBase = words.slice(1).join(" ") || "";
|
|
|
116
132
|
</section>
|
|
117
133
|
|
|
118
134
|
<section class="section-faq">
|
|
119
|
-
<FAQSection items={content.faq}
|
|
135
|
+
<FAQSection items={content.faq} inLanguage={locale} />
|
|
120
136
|
</section>
|
|
121
137
|
|
|
122
138
|
<section class="section-bibliography">
|
|
123
|
-
<Bibliography links={content.bibliography}
|
|
139
|
+
<Bibliography links={content.bibliography} />
|
|
124
140
|
</section>
|
|
125
141
|
</div>
|
|
126
142
|
</PreviewLayout>
|
|
@@ -131,11 +147,13 @@ const titleBase = words.slice(1).join(" ") || "";
|
|
|
131
147
|
flex-direction: column;
|
|
132
148
|
gap: 2rem;
|
|
133
149
|
}
|
|
150
|
+
|
|
134
151
|
.section-tool {
|
|
135
152
|
max-width: 1200px;
|
|
136
153
|
margin: 0 auto;
|
|
137
154
|
width: 100%;
|
|
138
155
|
}
|
|
156
|
+
|
|
139
157
|
.section-seo,
|
|
140
158
|
.section-faq,
|
|
141
159
|
.section-bibliography {
|
|
@@ -1,39 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { ALL_TOOLS } from '../tools';
|
|
3
|
-
import type { ToolLocaleContent } from '../types';
|
|
4
3
|
|
|
5
|
-
describe('Locale Completeness Validation', () => {
|
|
6
|
-
ALL_TOOLS.forEach((tool) => {
|
|
7
|
-
describe(`Tool: ${tool.entry.id}`, () => {
|
|
8
|
-
Object.keys(tool.entry.i18n).forEach((locale) => {
|
|
9
|
-
describe(`Locale: ${locale}`, () => {
|
|
10
|
-
it('faqTitle should be defined when faq items exist', async () => {
|
|
11
|
-
const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
|
|
12
|
-
const content = (await loader?.()) as ToolLocaleContent;
|
|
13
|
-
|
|
14
|
-
if (content.faq.length > 0) {
|
|
15
|
-
expect(
|
|
16
|
-
content.faqTitle,
|
|
17
|
-
`Tool "${tool.entry.id}" locale "${locale}" has ${content.faq.length} FAQ items but is missing faqTitle`,
|
|
18
|
-
).toBeTruthy();
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
4
|
|
|
22
|
-
|
|
23
|
-
const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
|
|
24
|
-
const content = (await loader?.()) as ToolLocaleContent;
|
|
5
|
+
describe('Locale Completeness Validation', () => {
|
|
25
6
|
|
|
26
|
-
if (content.bibliography.length > 0) {
|
|
27
|
-
expect(
|
|
28
|
-
content.bibliographyTitle,
|
|
29
|
-
`Tool "${tool.entry.id}" locale "${locale}" has ${content.bibliography.length} bibliography items but is missing bibliographyTitle`,
|
|
30
|
-
).toBeTruthy();
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
7
|
|
|
38
8
|
it('should have at least 1 tool registered', () => {
|
|
39
9
|
expect(ALL_TOOLS.length).toBeGreaterThan(0);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ToolDefinition } from '../types';
|
|
2
|
+
|
|
3
|
+
export interface ToolExportValidationResult {
|
|
4
|
+
passed: boolean;
|
|
5
|
+
failures: string[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function validateComponentType(
|
|
9
|
+
toolId: string,
|
|
10
|
+
componentName: string,
|
|
11
|
+
component: unknown,
|
|
12
|
+
failures: string[],
|
|
13
|
+
): void {
|
|
14
|
+
if (typeof component !== 'function') {
|
|
15
|
+
failures.push(`${toolId}: ${componentName} is not a function (${typeof component})`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function validateComponentExecution(
|
|
20
|
+
toolId: string,
|
|
21
|
+
componentName: string,
|
|
22
|
+
fn: () => Promise<unknown>,
|
|
23
|
+
failures: string[],
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
try {
|
|
26
|
+
const result = await fn();
|
|
27
|
+
if (!result || typeof result !== 'object') {
|
|
28
|
+
failures.push(`${toolId}: ${componentName} import returned invalid result`);
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
failures.push(`${toolId}: ${componentName} execution error - ${error instanceof Error ? error.message : 'unknown'}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function validateToolExports(tools: ToolDefinition[]): Promise<ToolExportValidationResult> {
|
|
36
|
+
const failures: string[] = [];
|
|
37
|
+
|
|
38
|
+
for (const tool of tools) {
|
|
39
|
+
validateComponentType(tool.entry.id, 'Component', tool.Component, failures);
|
|
40
|
+
validateComponentType(tool.entry.id, 'SEOComponent', tool.SEOComponent, failures);
|
|
41
|
+
validateComponentType(tool.entry.id, 'BibliographyComponent', tool.BibliographyComponent, failures);
|
|
42
|
+
|
|
43
|
+
const componentFn = tool.Component as () => Promise<unknown>;
|
|
44
|
+
const seoFn = tool.SEOComponent as () => Promise<unknown>;
|
|
45
|
+
const bibFn = tool.BibliographyComponent as () => Promise<unknown>;
|
|
46
|
+
|
|
47
|
+
await validateComponentExecution(tool.entry.id, 'Component', componentFn, failures);
|
|
48
|
+
await validateComponentExecution(tool.entry.id, 'SEOComponent', seoFn, failures);
|
|
49
|
+
await validateComponentExecution(tool.entry.id, 'BibliographyComponent', bibFn, failures);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
passed: failures.length === 0,
|
|
54
|
+
failures,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { ALL_TOOLS } from '../tools';
|
|
3
|
+
import { validateToolExports } from './shared-test-helpers';
|
|
4
|
+
|
|
5
|
+
describe('Tool Exports Pattern Validation', () => {
|
|
6
|
+
describe('Component Exports Format', () => {
|
|
7
|
+
ALL_TOOLS.forEach((tool) => {
|
|
8
|
+
it(`${tool.entry.id}: Component should be a lazy-loaded function`, () => {
|
|
9
|
+
expect(typeof tool.Component).toBe('function');
|
|
10
|
+
expect(tool.Component).toBeInstanceOf(Function);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it(`${tool.entry.id}: SEOComponent should be a lazy-loaded function`, () => {
|
|
14
|
+
expect(typeof tool.SEOComponent).toBe('function');
|
|
15
|
+
expect(tool.SEOComponent).toBeInstanceOf(Function);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it(`${tool.entry.id}: BibliographyComponent should be a lazy-loaded function`, () => {
|
|
19
|
+
expect(typeof tool.BibliographyComponent).toBe('function');
|
|
20
|
+
expect(tool.BibliographyComponent).toBeInstanceOf(Function);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('Dynamic Import Validation', () => {
|
|
26
|
+
it('all tools must have functional dynamic imports', async () => {
|
|
27
|
+
const result = await validateToolExports(ALL_TOOLS);
|
|
28
|
+
if (!result.passed) {
|
|
29
|
+
throw new Error(`Tool export validation failed:\n${result.failures.join('\n')}`);
|
|
30
|
+
}
|
|
31
|
+
expect(result.passed).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BibliographyEntry } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const bibliography: BibliographyEntry[] = [
|
|
4
|
+
{
|
|
5
|
+
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
6
|
+
url: 'https://www.jstor.org/stable/2453256',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: 'Wikipedia - Dolbear\'s Law',
|
|
10
|
+
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
11
|
+
},
|
|
12
|
+
];
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
.theme-dark .ct-card {
|
|
39
39
|
--ct-bg-card: #0f172a;
|
|
40
40
|
--ct-bg-image: #1e293b;
|
|
41
41
|
--ct-gradient-from: #0f172a;
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
pointer-events: none;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
.ct-display-wrapper.has-value .ct-glow {
|
|
109
109
|
opacity: 1;
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
transform: scale(0.95);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
|
|
198
|
+
.ct-tap-btn.ct-tap-pressed {
|
|
199
199
|
transform: scale(0.95);
|
|
200
200
|
}
|
|
201
201
|
|
|
@@ -249,6 +249,6 @@
|
|
|
249
249
|
gap: 0.5rem;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
.ct-audio-btn.audio-active {
|
|
253
253
|
color: var(--ct-audio-active);
|
|
254
254
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Häufig gestellte Fragen',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - Die Grille als Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbearsches Gesetz',
|
|
100
|
-
url: 'https://de.wikipedia.org/wiki/Dolbearsches_Gesetz',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Ton: Ein',
|
|
176
166
|
btnSoundOff: 'Ton: Aus',
|
|
177
167
|
unitChirpsMin: 'Zirp/Min',
|
|
178
|
-
faqTitle: 'Häufig gestellte Fragen',
|
|
179
|
-
bibliographyTitle: 'Wissenschaftliche Referenzen',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Frequently Asked Questions',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Sound: On',
|
|
176
166
|
btnSoundOff: 'Sound: Off',
|
|
177
167
|
unitChirpsMin: 'chirps/min',
|
|
178
|
-
faqTitle: 'Frequently Asked Questions',
|
|
179
|
-
bibliographyTitle: 'Scientific References',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Preguntas Frecuentes',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Sonido: On',
|
|
176
166
|
btnSoundOff: 'Sonido: Off',
|
|
177
167
|
unitChirpsMin: 'chirridos/min',
|
|
178
|
-
faqTitle: 'Preguntas Frecuentes',
|
|
179
|
-
bibliographyTitle: 'Referencias Científicas',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Questions Fréquentes',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Son : On',
|
|
176
166
|
btnSoundOff: 'Son : Off',
|
|
177
167
|
unitChirpsMin: 'strid./min',
|
|
178
|
-
faqTitle: 'Questions Fréquentes',
|
|
179
|
-
bibliographyTitle: 'Références Scientifiques',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Pertanyaan yang Sering Diajukan',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Suara: Aktif',
|
|
176
166
|
btnSoundOff: 'Suara: Nonaktif',
|
|
177
167
|
unitChirpsMin: 'kerikan/menit',
|
|
178
|
-
faqTitle: 'Pertanyaan yang Sering Diajukan',
|
|
179
|
-
bibliographyTitle: 'Referensi Ilmiah',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Domande Frequenti',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Suono: On',
|
|
176
166
|
btnSoundOff: 'Suono: Off',
|
|
177
167
|
unitChirpsMin: 'friniti/min',
|
|
178
|
-
faqTitle: 'Domande Frequenti',
|
|
179
|
-
bibliographyTitle: 'Riferimenti Scientifici',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'よくある質問',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'サウンド:ON',
|
|
176
166
|
btnSoundOff: 'サウンド:OFF',
|
|
177
167
|
unitChirpsMin: '回/分',
|
|
178
|
-
faqTitle: 'よくある質問',
|
|
179
|
-
bibliographyTitle: '科学的参考文献',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: '자주 묻는 질문',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: '소리: 켜짐',
|
|
176
166
|
btnSoundOff: '소리: 꺼짐',
|
|
177
167
|
unitChirpsMin: '회/분',
|
|
178
|
-
faqTitle: '자주 묻는 질문',
|
|
179
|
-
bibliographyTitle: '과학적 참고 문헌',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Veelgestelde Vragen',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Geluid: Aan',
|
|
176
166
|
btnSoundOff: 'Geluid: Uit',
|
|
177
167
|
unitChirpsMin: 'tsjirpen/min',
|
|
178
|
-
faqTitle: 'Veelgestelde Vragen',
|
|
179
|
-
bibliographyTitle: 'Wetenschappelijke Bronnen',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Często zadawane pytania',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Dźwięk: Wł.',
|
|
176
166
|
btnSoundOff: 'Dźwięk: Wył.',
|
|
177
167
|
unitChirpsMin: 'cyknięć/min',
|
|
178
|
-
faqTitle: 'Często zadawane pytania',
|
|
179
|
-
bibliographyTitle: 'Źródła naukowe',
|
|
180
168
|
},
|
|
181
169
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import { bibliography } from '../bibliography';
|
|
2
3
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
4
|
import type { CricketThermometerUI } from '../ui';
|
|
4
5
|
|
|
@@ -87,19 +88,8 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
87
88
|
slug,
|
|
88
89
|
title,
|
|
89
90
|
description,
|
|
90
|
-
faqTitle: 'Perguntas Frequentes',
|
|
91
91
|
faq: faqData,
|
|
92
|
-
|
|
93
|
-
bibliography: [
|
|
94
|
-
{
|
|
95
|
-
name: 'The American Naturalist - The Cricket as a Thermometer',
|
|
96
|
-
url: 'https://www.jstor.org/stable/2453256',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'Wikipedia - Dolbear\'s Law',
|
|
100
|
-
url: 'https://en.wikipedia.org/wiki/Dolbear%27s_law',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
92
|
+
bibliography,
|
|
103
93
|
howTo: howToData,
|
|
104
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
105
95
|
seo: [
|
|
@@ -175,7 +165,5 @@ export const content: ToolLocaleContent<CricketThermometerUI> = {
|
|
|
175
165
|
btnSoundOn: 'Som: Ligado',
|
|
176
166
|
btnSoundOff: 'Som: Desligado',
|
|
177
167
|
unitChirpsMin: 'cantos/min',
|
|
178
|
-
faqTitle: 'Perguntas Frequentes',
|
|
179
|
-
bibliographyTitle: 'Referências Científicas',
|
|
180
168
|
},
|
|
181
169
|
};
|