@jjlmoya/utils-textiles 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/category/i18n/de.ts +2 -2
- package/src/category/i18n/en.ts +2 -2
- package/src/category/i18n/es.ts +2 -2
- package/src/category/i18n/fr.ts +9 -9
- package/src/category/i18n/id.ts +2 -2
- package/src/category/i18n/it.ts +2 -2
- package/src/category/i18n/nl.ts +2 -2
- package/src/category/i18n/pl.ts +3 -3
- package/src/category/i18n/pt.ts +2 -2
- package/src/category/i18n/ru.ts +5 -5
- package/src/category/i18n/sv.ts +3 -3
- package/src/category/i18n/zh.ts +2 -2
- package/src/layouts/PreviewLayout.astro +1 -0
- package/src/pages/[locale]/[slug].astro +30 -14
- package/src/tests/diacritics_density.test.ts +118 -0
- package/src/tests/inverted_punctuation.test.ts +84 -0
- package/src/tests/locale_completeness.test.ts +0 -33
- package/src/tests/no_en_dash.test.ts +70 -0
- package/src/tests/script_density.test.ts +94 -0
- package/src/tests/shared-test-helpers.ts +56 -0
- package/src/tests/tool_exports.test.ts +34 -0
- package/src/tool/burnTest/bibliography.astro +2 -10
- package/src/tool/burnTest/bibliography.ts +16 -0
- package/src/tool/burnTest/i18n/de.ts +5 -19
- package/src/tool/burnTest/i18n/en.ts +2 -16
- package/src/tool/burnTest/i18n/es.ts +2 -16
- package/src/tool/burnTest/i18n/fr.ts +5 -19
- package/src/tool/burnTest/i18n/id.ts +2 -16
- package/src/tool/burnTest/i18n/it.ts +2 -16
- package/src/tool/burnTest/i18n/ja.ts +2 -16
- package/src/tool/burnTest/i18n/ko.ts +2 -16
- package/src/tool/burnTest/i18n/nl.ts +2 -16
- package/src/tool/burnTest/i18n/pl.ts +5 -19
- package/src/tool/burnTest/i18n/pt.ts +2 -16
- package/src/tool/burnTest/i18n/ru.ts +8 -22
- package/src/tool/burnTest/i18n/sv.ts +2 -16
- package/src/tool/burnTest/i18n/tr.ts +2 -16
- package/src/tool/burnTest/i18n/zh.ts +5 -19
- package/src/tool/burnTest/index.ts +1 -0
- package/src/tool/burnTest/seo.astro +2 -27
- package/src/tool/clothingSizeConverter/bibliography.astro +2 -10
- package/src/tool/clothingSizeConverter/bibliography.ts +10 -0
- package/src/tool/clothingSizeConverter/i18n/de.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/en.ts +3 -11
- package/src/tool/clothingSizeConverter/i18n/es.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/fr.ts +8 -16
- package/src/tool/clothingSizeConverter/i18n/id.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/it.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/ja.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/ko.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/nl.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/pl.ts +3 -11
- package/src/tool/clothingSizeConverter/i18n/pt.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/ru.ts +4 -12
- package/src/tool/clothingSizeConverter/i18n/sv.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/tr.ts +2 -10
- package/src/tool/clothingSizeConverter/i18n/zh.ts +3 -11
- package/src/tool/clothingSizeConverter/index.ts +1 -0
- package/src/tool/clothingSizeConverter/seo.astro +2 -27
- package/src/tool/fabricProjectCalculator/bibliography.astro +2 -10
- package/src/tool/fabricProjectCalculator/bibliography.ts +16 -0
- package/src/tool/fabricProjectCalculator/component.astro +2 -3
- package/src/tool/fabricProjectCalculator/fabric-project-calculator.css +63 -1
- package/src/tool/fabricProjectCalculator/i18n/de.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/en.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/es.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/fr.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/id.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/it.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/ja.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/ko.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/nl.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/pl.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/pt.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/ru.ts +4 -18
- package/src/tool/fabricProjectCalculator/i18n/sv.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/tr.ts +2 -16
- package/src/tool/fabricProjectCalculator/i18n/zh.ts +3 -17
- package/src/tool/fabricProjectCalculator/index.ts +1 -0
- package/src/tool/fabricProjectCalculator/seo.astro +2 -27
- package/src/tool/fabricTruth/bibliography.astro +2 -10
- package/src/tool/fabricTruth/bibliography.ts +16 -0
- package/src/tool/fabricTruth/i18n/de.ts +3 -17
- package/src/tool/fabricTruth/i18n/en.ts +3 -17
- package/src/tool/fabricTruth/i18n/es.ts +3 -17
- package/src/tool/fabricTruth/i18n/fr.ts +15 -29
- package/src/tool/fabricTruth/i18n/id.ts +3 -17
- package/src/tool/fabricTruth/i18n/it.ts +3 -17
- package/src/tool/fabricTruth/i18n/ja.ts +3 -17
- package/src/tool/fabricTruth/i18n/ko.ts +3 -17
- package/src/tool/fabricTruth/i18n/nl.ts +3 -17
- package/src/tool/fabricTruth/i18n/pl.ts +3 -17
- package/src/tool/fabricTruth/i18n/pt.ts +3 -17
- package/src/tool/fabricTruth/i18n/ru.ts +13 -27
- package/src/tool/fabricTruth/i18n/sv.ts +3 -17
- package/src/tool/fabricTruth/i18n/tr.ts +3 -17
- package/src/tool/fabricTruth/i18n/zh.ts +11 -25
- package/src/tool/fabricTruth/index.ts +1 -0
- package/src/tool/fabricTruth/seo.astro +2 -27
- package/src/tool/fiberPrep/bibliography.astro +2 -10
- package/src/tool/fiberPrep/bibliography.ts +12 -0
- package/src/tool/fiberPrep/fiber-preparation-natural-dyeing.css +130 -11
- package/src/tool/fiberPrep/i18n/de.ts +2 -12
- package/src/tool/fiberPrep/i18n/en.ts +2 -12
- package/src/tool/fiberPrep/i18n/es.ts +2 -12
- package/src/tool/fiberPrep/i18n/fr.ts +6 -16
- package/src/tool/fiberPrep/i18n/id.ts +2 -12
- package/src/tool/fiberPrep/i18n/it.ts +2 -12
- package/src/tool/fiberPrep/i18n/ja.ts +2 -12
- package/src/tool/fiberPrep/i18n/ko.ts +2 -12
- package/src/tool/fiberPrep/i18n/nl.ts +2 -12
- package/src/tool/fiberPrep/i18n/pl.ts +2 -12
- package/src/tool/fiberPrep/i18n/pt.ts +2 -12
- package/src/tool/fiberPrep/i18n/ru.ts +5 -15
- package/src/tool/fiberPrep/i18n/sv.ts +2 -12
- package/src/tool/fiberPrep/i18n/tr.ts +2 -12
- package/src/tool/fiberPrep/i18n/zh.ts +4 -14
- package/src/tool/fiberPrep/index.ts +1 -0
- package/src/tool/fiberPrep/seo.astro +2 -27
- package/src/tool/knittingGauge/bibliography.astro +2 -10
- package/src/tool/knittingGauge/bibliography.ts +12 -0
- package/src/tool/knittingGauge/i18n/de.ts +2 -12
- package/src/tool/knittingGauge/i18n/en.ts +2 -12
- package/src/tool/knittingGauge/i18n/es.ts +2 -12
- package/src/tool/knittingGauge/i18n/fr.ts +2 -12
- package/src/tool/knittingGauge/i18n/id.ts +2 -12
- package/src/tool/knittingGauge/i18n/it.ts +2 -12
- package/src/tool/knittingGauge/i18n/ja.ts +2 -12
- package/src/tool/knittingGauge/i18n/ko.ts +2 -12
- package/src/tool/knittingGauge/i18n/nl.ts +2 -12
- package/src/tool/knittingGauge/i18n/pl.ts +2 -12
- package/src/tool/knittingGauge/i18n/pt.ts +2 -12
- package/src/tool/knittingGauge/i18n/ru.ts +8 -18
- package/src/tool/knittingGauge/i18n/sv.ts +2 -12
- package/src/tool/knittingGauge/i18n/tr.ts +2 -12
- package/src/tool/knittingGauge/i18n/zh.ts +3 -13
- package/src/tool/knittingGauge/index.ts +1 -0
- package/src/tool/knittingGauge/seo.astro +2 -27
- package/src/tool/laundryGuide/bibliography.astro +2 -10
- package/src/tool/laundryGuide/bibliography.ts +6 -0
- package/src/tool/laundryGuide/i18n/de.ts +3 -7
- package/src/tool/laundryGuide/i18n/en.ts +3 -7
- package/src/tool/laundryGuide/i18n/es.ts +3 -7
- package/src/tool/laundryGuide/i18n/fr.ts +14 -18
- package/src/tool/laundryGuide/i18n/id.ts +3 -7
- package/src/tool/laundryGuide/i18n/it.ts +3 -7
- package/src/tool/laundryGuide/i18n/ja.ts +2 -6
- package/src/tool/laundryGuide/i18n/ko.ts +2 -6
- package/src/tool/laundryGuide/i18n/nl.ts +3 -7
- package/src/tool/laundryGuide/i18n/pl.ts +4 -8
- package/src/tool/laundryGuide/i18n/pt.ts +3 -7
- package/src/tool/laundryGuide/i18n/ru.ts +8 -12
- package/src/tool/laundryGuide/i18n/sv.ts +3 -7
- package/src/tool/laundryGuide/i18n/tr.ts +2 -6
- package/src/tool/laundryGuide/i18n/zh.ts +4 -8
- package/src/tool/laundryGuide/index.ts +1 -0
- package/src/tool/laundryGuide/seo.astro +2 -27
- package/src/tool/needleConverter/bibliography.astro +2 -10
- package/src/tool/needleConverter/bibliography.ts +12 -0
- package/src/tool/needleConverter/i18n/de.ts +2 -12
- package/src/tool/needleConverter/i18n/en.ts +2 -12
- package/src/tool/needleConverter/i18n/es.ts +2 -12
- package/src/tool/needleConverter/i18n/fr.ts +7 -17
- package/src/tool/needleConverter/i18n/id.ts +2 -12
- package/src/tool/needleConverter/i18n/it.ts +2 -12
- package/src/tool/needleConverter/i18n/ja.ts +2 -12
- package/src/tool/needleConverter/i18n/ko.ts +2 -12
- package/src/tool/needleConverter/i18n/nl.ts +2 -12
- package/src/tool/needleConverter/i18n/pl.ts +2 -12
- package/src/tool/needleConverter/i18n/pt.ts +2 -12
- package/src/tool/needleConverter/i18n/ru.ts +6 -16
- package/src/tool/needleConverter/i18n/sv.ts +2 -12
- package/src/tool/needleConverter/i18n/tr.ts +2 -12
- package/src/tool/needleConverter/i18n/zh.ts +2 -12
- package/src/tool/needleConverter/index.ts +1 -0
- package/src/tool/needleConverter/seo.astro +1 -1
- package/src/tool/sewingPatternScaler/bibliography.astro +2 -10
- package/src/tool/sewingPatternScaler/bibliography.ts +12 -0
- package/src/tool/sewingPatternScaler/i18n/de.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/en.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/es.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/fr.ts +4 -14
- package/src/tool/sewingPatternScaler/i18n/id.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/it.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/ja.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/ko.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/nl.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/pl.ts +4 -14
- package/src/tool/sewingPatternScaler/i18n/pt.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/ru.ts +9 -19
- package/src/tool/sewingPatternScaler/i18n/sv.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/tr.ts +2 -12
- package/src/tool/sewingPatternScaler/i18n/zh.ts +5 -15
- package/src/tool/sewingPatternScaler/index.ts +1 -0
- package/src/tool/sewingPatternScaler/seo.astro +2 -36
- package/src/tool/shoeSizeConverter/bibliography.astro +2 -10
- package/src/tool/shoeSizeConverter/bibliography.ts +7 -0
- package/src/tool/shoeSizeConverter/i18n/de.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/en.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/es.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/fr.ts +3 -8
- package/src/tool/shoeSizeConverter/i18n/id.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/it.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/ja.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/ko.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/nl.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/pl.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/pt.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/ru.ts +6 -11
- package/src/tool/shoeSizeConverter/i18n/sv.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/tr.ts +2 -7
- package/src/tool/shoeSizeConverter/i18n/zh.ts +5 -10
- package/src/tool/shoeSizeConverter/index.ts +1 -0
- package/src/tool/shoeSizeConverter/seo.astro +2 -27
- package/src/tool/stainChemistry/bibliography.astro +2 -10
- package/src/tool/stainChemistry/bibliography.ts +16 -0
- package/src/tool/stainChemistry/i18n/de.ts +5 -19
- package/src/tool/stainChemistry/i18n/en.ts +5 -19
- package/src/tool/stainChemistry/i18n/es.ts +5 -19
- package/src/tool/stainChemistry/i18n/fr.ts +8 -22
- package/src/tool/stainChemistry/i18n/id.ts +5 -19
- package/src/tool/stainChemistry/i18n/it.ts +5 -19
- package/src/tool/stainChemistry/i18n/ja.ts +5 -19
- package/src/tool/stainChemistry/i18n/ko.ts +5 -19
- package/src/tool/stainChemistry/i18n/nl.ts +5 -19
- package/src/tool/stainChemistry/i18n/pl.ts +5 -19
- package/src/tool/stainChemistry/i18n/pt.ts +5 -19
- package/src/tool/stainChemistry/i18n/ru.ts +9 -23
- package/src/tool/stainChemistry/i18n/sv.ts +5 -19
- package/src/tool/stainChemistry/i18n/tr.ts +5 -19
- package/src/tool/stainChemistry/i18n/zh.ts +9 -23
- package/src/tool/stainChemistry/index.ts +1 -0
- package/src/tool/stainChemistry/seo.astro +2 -27
- package/src/tool/yarnCalculator/bibliography.astro +2 -10
- package/src/tool/yarnCalculator/bibliography.ts +16 -0
- package/src/tool/yarnCalculator/i18n/de.ts +2 -16
- package/src/tool/yarnCalculator/i18n/en.ts +2 -16
- package/src/tool/yarnCalculator/i18n/es.ts +2 -16
- package/src/tool/yarnCalculator/i18n/fr.ts +6 -20
- package/src/tool/yarnCalculator/i18n/id.ts +2 -16
- package/src/tool/yarnCalculator/i18n/it.ts +2 -16
- package/src/tool/yarnCalculator/i18n/ja.ts +2 -16
- package/src/tool/yarnCalculator/i18n/ko.ts +2 -16
- package/src/tool/yarnCalculator/i18n/nl.ts +2 -16
- package/src/tool/yarnCalculator/i18n/pl.ts +2 -16
- package/src/tool/yarnCalculator/i18n/pt.ts +2 -16
- package/src/tool/yarnCalculator/i18n/ru.ts +9 -23
- package/src/tool/yarnCalculator/i18n/sv.ts +2 -16
- package/src/tool/yarnCalculator/i18n/tr.ts +2 -16
- package/src/tool/yarnCalculator/i18n/zh.ts +7 -21
- package/src/tool/yarnCalculator/index.ts +1 -0
- package/src/tool/yarnCalculator/seo.astro +2 -1
- package/src/types.ts +2 -4
|
@@ -1,40 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { ALL_TOOLS } from '../tools';
|
|
3
|
-
import type { ToolLocaleContent } from '../types';
|
|
4
3
|
|
|
5
4
|
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
|
-
|
|
22
|
-
it('bibliographyTitle should be defined when bibliography items exist', async () => {
|
|
23
|
-
const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
|
|
24
|
-
const content = (await loader?.()) as ToolLocaleContent;
|
|
25
|
-
|
|
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
|
-
|
|
38
5
|
it('should have at least 1 tool registered', () => {
|
|
39
6
|
expect(ALL_TOOLS.length).toBeGreaterThan(0);
|
|
40
7
|
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
function getFiles(dir: string): string[] {
|
|
6
|
+
const results: string[] = [];
|
|
7
|
+
if (!fs.existsSync(dir)) {
|
|
8
|
+
return results;
|
|
9
|
+
}
|
|
10
|
+
const list = fs.readdirSync(dir);
|
|
11
|
+
for (const file of list) {
|
|
12
|
+
const fullPath = path.join(dir, file);
|
|
13
|
+
const stat = fs.statSync(fullPath);
|
|
14
|
+
if (stat && stat.isDirectory()) {
|
|
15
|
+
if (file !== 'tests' && file !== 'node_modules' && file !== '.astro') {
|
|
16
|
+
results.push(...getFiles(fullPath));
|
|
17
|
+
}
|
|
18
|
+
} else {
|
|
19
|
+
results.push(fullPath);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return results;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isContentFile(filePath: string): boolean {
|
|
26
|
+
return /\\i18n\\/.test(filePath) || filePath.endsWith('bibliography.ts');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const srcDir = path.join(process.cwd(), 'src');
|
|
30
|
+
const scriptsDir = path.join(process.cwd(), 'scripts');
|
|
31
|
+
const filesToTest = [
|
|
32
|
+
...getFiles(srcDir).filter(isContentFile),
|
|
33
|
+
...getFiles(scriptsDir).filter(isContentFile),
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const aiTypographyGarbage = [
|
|
37
|
+
'\u2013',
|
|
38
|
+
'\u2014',
|
|
39
|
+
'\u2026',
|
|
40
|
+
'\u201C',
|
|
41
|
+
'\u201D',
|
|
42
|
+
'\u2018',
|
|
43
|
+
'\u2019',
|
|
44
|
+
'\u00AB',
|
|
45
|
+
'\u00BB',
|
|
46
|
+
'\u200B',
|
|
47
|
+
'\u201E',
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
describe('Typography Garbage Character Validation', () => {
|
|
51
|
+
filesToTest.forEach((filePath) => {
|
|
52
|
+
const relativePath = path.relative(process.cwd(), filePath);
|
|
53
|
+
it(`should not contain typography garbage characters in ${relativePath}`, () => {
|
|
54
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
55
|
+
const hasAiPatterns = aiTypographyGarbage.some(char => content.includes(char));
|
|
56
|
+
expect(hasAiPatterns).toBe(false);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it(`should not contain space before colon in ${relativePath}`, () => {
|
|
60
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
61
|
+
const spaceBeforeColon = / : /.test(content);
|
|
62
|
+
expect(spaceBeforeColon).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it(`should not contain double hyphen in ${relativePath}`, () => {
|
|
66
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
67
|
+
expect(content).not.toContain('--');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { ALL_TOOLS } from '../tools';
|
|
3
|
+
|
|
4
|
+
type ScriptLocale = keyof typeof SCRIPT_RULES;
|
|
5
|
+
|
|
6
|
+
const SCRIPT_RULES = {
|
|
7
|
+
ja: {
|
|
8
|
+
language: 'Japanese',
|
|
9
|
+
scriptName: 'kana/kanji',
|
|
10
|
+
scriptCharacters: /[\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}]/gu,
|
|
11
|
+
minScriptRatio: 0.45,
|
|
12
|
+
},
|
|
13
|
+
ko: {
|
|
14
|
+
language: 'Korean',
|
|
15
|
+
scriptName: 'hangul',
|
|
16
|
+
scriptCharacters: /\p{Script=Hangul}/gu,
|
|
17
|
+
minScriptRatio: 0.55,
|
|
18
|
+
},
|
|
19
|
+
ru: {
|
|
20
|
+
language: 'Russian',
|
|
21
|
+
scriptName: 'cyrillic',
|
|
22
|
+
scriptCharacters: /\p{Script=Cyrillic}/gu,
|
|
23
|
+
minScriptRatio: 0.65,
|
|
24
|
+
},
|
|
25
|
+
zh: {
|
|
26
|
+
language: 'Chinese',
|
|
27
|
+
scriptName: 'han',
|
|
28
|
+
scriptCharacters: /\p{Script=Han}/gu,
|
|
29
|
+
minScriptRatio: 0.45,
|
|
30
|
+
},
|
|
31
|
+
} as const;
|
|
32
|
+
|
|
33
|
+
const LETTERS = /\p{L}/gu;
|
|
34
|
+
const TRANSLATABLE_KEYS = ['title', 'description', 'ui', 'seo', 'faq', 'howTo'] as const;
|
|
35
|
+
|
|
36
|
+
function collectStrings(value: unknown): string[] {
|
|
37
|
+
if (typeof value === 'string') return [value];
|
|
38
|
+
if (!value || typeof value !== 'object') return [];
|
|
39
|
+
if (Array.isArray(value)) return value.flatMap(collectStrings);
|
|
40
|
+
return Object.values(value).flatMap(collectStrings);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function normalizeText(value: unknown): string {
|
|
44
|
+
return collectStrings(value).join(' ').normalize('NFC');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function translatableContent(content: Record<string, unknown>) {
|
|
48
|
+
return TRANSLATABLE_KEYS.map((key) => content[key]);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function letterCount(text: string): number {
|
|
52
|
+
return text.match(LETTERS)?.length ?? 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function scriptCount(text: string, locale: ScriptLocale): number {
|
|
56
|
+
return text.match(SCRIPT_RULES[locale].scriptCharacters)?.length ?? 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function scriptRatio(text: string, locale: ScriptLocale): number {
|
|
60
|
+
const letters = letterCount(text);
|
|
61
|
+
if (letters === 0) return 0;
|
|
62
|
+
return scriptCount(text, locale) / letters;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
describe('Native script density validation', () => {
|
|
66
|
+
ALL_TOOLS.forEach((tool) => {
|
|
67
|
+
describe(`Tool: ${tool.entry.id}`, () => {
|
|
68
|
+
Object.keys(SCRIPT_RULES).forEach((locale) => {
|
|
69
|
+
it(`${locale} keeps most translated text in its native script`, async () => {
|
|
70
|
+
const typedLocale = locale as ScriptLocale;
|
|
71
|
+
const loader = tool.entry.i18n[typedLocale];
|
|
72
|
+
if (!loader) return;
|
|
73
|
+
|
|
74
|
+
const content = await loader();
|
|
75
|
+
const rule = SCRIPT_RULES[typedLocale];
|
|
76
|
+
const text = normalizeText(translatableContent(content as Record<string, unknown>));
|
|
77
|
+
const letters = letterCount(text);
|
|
78
|
+
const matches = scriptCount(text, typedLocale);
|
|
79
|
+
const ratio = scriptRatio(text, typedLocale);
|
|
80
|
+
|
|
81
|
+
expect(
|
|
82
|
+
ratio,
|
|
83
|
+
[
|
|
84
|
+
`Possible broken translation detected in ${tool.entry.id}/${typedLocale} (${rule.language}).`,
|
|
85
|
+
`The text has ${matches} ${rule.scriptName} characters out of ${letters} analyzed letters (${(ratio * 100).toFixed(1)}%).`,
|
|
86
|
+
`Most translatable content should be written in ${rule.scriptName} script.`,
|
|
87
|
+
'Non-translatable fields such as slug, bibliography, and schemas are ignored to avoid false positives.',
|
|
88
|
+
].join(' '),
|
|
89
|
+
).toBeGreaterThanOrEqual(rule.minScriptRatio);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -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
|
+
});
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
|
|
3
|
-
import {
|
|
4
|
-
import type { KnownLocale } from '../../types';
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
locale?: KnownLocale;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const { locale = 'es' } = Astro.props;
|
|
11
|
-
const content = await burnTest.i18n[locale]?.();
|
|
3
|
+
import { bibliography } from './bibliography';
|
|
12
4
|
---
|
|
13
5
|
|
|
14
|
-
|
|
6
|
+
<SharedBibliography links={bibliography} />
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BibliographyEntry } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const bibliography: BibliographyEntry[] = [
|
|
4
|
+
{
|
|
5
|
+
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
6
|
+
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
10
|
+
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
14
|
+
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
15
|
+
},
|
|
16
|
+
];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'textilien-brennprobe';
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: 'Häufig gestellte Fragen',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|
|
@@ -168,7 +154,7 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
168
154
|
},
|
|
169
155
|
{
|
|
170
156
|
type: 'paragraph',
|
|
171
|
-
html: 'Eine präzise Analyse erfordert den Abgleich von mindestens drei Beweisstücken. Der Geruch ist der zuverlässigste Indikator zur Identifizierung von Mischgeweben: Wenn ein
|
|
157
|
+
html: 'Eine präzise Analyse erfordert den Abgleich von mindestens drei Beweisstücken. Der Geruch ist der zuverlässigste Indikator zur Identifizierung von Mischgeweben: Wenn ein "Leinen"-Stoff ein leichtes Kunststoffaroma verströmt und harte Rückstände hinterlässt, deutet dies auf eine nicht deklarierte Polyestermischung hin.',
|
|
172
158
|
},
|
|
173
159
|
{
|
|
174
160
|
type: 'tip',
|
|
@@ -201,8 +187,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
201
187
|
wool: { name: 'Wolle / Merino', icon: 'mdi:sheep', color: '#FCD34D', description: 'Tierische Proteinfaser, hervorragender Wärmeisolator und elastisch.' },
|
|
202
188
|
silk: { name: 'Seide', icon: 'mdi:ticket-percent', color: '#F472B6', description: 'Tierische Endlosfaser. Natürlicher Glanz und trockener Griff.' },
|
|
203
189
|
cashmere: { name: 'Kaschmir', icon: 'mdi:crown', color: '#F59E0B', description: 'Luxuriöse Kaschmirziegenfaser. Extrem weich, leicht und warm.' },
|
|
204
|
-
mohair: { name: 'Mohair', icon: 'mdi:shimmer', color: '#14B8A6', description: 'Die
|
|
205
|
-
angora: { name: 'Angora', icon: 'mdi:rabbit', color: '#F9FAFB', description: 'Haar des Angora-Kaninchens. Bekannt für seinen flauschigen
|
|
190
|
+
mohair: { name: 'Mohair', icon: 'mdi:shimmer', color: '#14B8A6', description: 'Die "Diamantfaser" der Angora-Ziege. Natürlicher Glanz, sehr widerstandsfähig.' },
|
|
191
|
+
angora: { name: 'Angora', icon: 'mdi:rabbit', color: '#F9FAFB', description: 'Haar des Angora-Kaninchens. Bekannt für seinen flauschigen "Halo"-Effekt und extreme Leichtigkeit.' },
|
|
206
192
|
alpaca: { name: 'Alpaka', icon: 'mdi:image-filter-hdr', color: '#9F7AEA', description: 'Schatz der Anden. Hohle, thermische, hypoallergene und seidige Faser.' },
|
|
207
193
|
polyester: { name: 'Polyester', icon: 'mdi:oil', color: '#94A3B8', description: 'Synthetische Faser auf Erdölbasis. Widerstandsfähig, knitterfrei, nicht atmungsaktiv.' },
|
|
208
194
|
nylon: { name: 'Nylon (Polyamid)', icon: 'mdi:parachute', color: '#2DD4BF', description: 'Hochwiderstandsfähige Kunstfaser für Zugkraft und Abrieb.' },
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'textile-burn-test';
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: 'Frequently Asked Questions',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'identificador-fibras-combustion';
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: 'Preguntas Frecuentes',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'test-combustion-textile';
|
|
@@ -11,7 +12,7 @@ const faqData = [
|
|
|
11
12
|
{
|
|
12
13
|
question: 'Est-il sûr d\'effectuer un test de combustion à la maison?',
|
|
13
14
|
answer:
|
|
14
|
-
"Oui, à condition de prendre des précautions extrêmes
|
|
15
|
+
"Oui, à condition de prendre des précautions extrêmes: utilisez des pinces métalliques, travaillez sur une surface ignifuge (céramique ou métal), gardez de l'eau à portée et effectuez le test dans un endroit ventilé. Vous n'avez besoin que d'un petit échantillon de 1x1 cm ou de quelques fils.",
|
|
15
16
|
},
|
|
16
17
|
{
|
|
17
18
|
question: 'Comment sent le coton quand il brûle?',
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: 'Questions Fréquentes',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|
|
@@ -141,7 +127,7 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
141
127
|
},
|
|
142
128
|
{
|
|
143
129
|
type: 'paragraph',
|
|
144
|
-
html: "Le test de combustion est la méthode analytique la plus rapide et précise pour différencier les polymères naturels des synthétiques sans recourir au microscope électronique. En soumettant une fibre à la chaleur, son comportement moléculaire révèle son origine
|
|
130
|
+
html: "Le test de combustion est la méthode analytique la plus rapide et précise pour différencier les polymères naturels des synthétiques sans recourir au microscope électronique. En soumettant une fibre à la chaleur, son comportement moléculaire révèle son origine: depuis la cellulose végétale jusqu'aux protéines animales ou aux dérivés du pétrole.",
|
|
145
131
|
},
|
|
146
132
|
{
|
|
147
133
|
type: 'card',
|
|
@@ -168,7 +154,7 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
168
154
|
},
|
|
169
155
|
{
|
|
170
156
|
type: 'paragraph',
|
|
171
|
-
html: "Une analyse précise nécessite de croiser au moins trois preuves. L'odeur est l'indicateur le plus fiable pour identifier les mélanges
|
|
157
|
+
html: "Une analyse précise nécessite de croiser au moins trois preuves. L'odeur est l'indicateur le plus fiable pour identifier les mélanges: si un tissu de \"lin\" dégage un léger arôme plastique et laisse des résidus durs, cela indique un mélange polyester non déclaré.",
|
|
172
158
|
},
|
|
173
159
|
{
|
|
174
160
|
type: 'tip',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'uji-bakar-tekstil';
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: 'Pertanyaan yang Sering Diajukan',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'test-combustione-tessile';
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: 'Domande Frequenti',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'textile-burn-test';
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: 'よくある質問',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'textile-burn-test';
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: '자주 묻는 질문',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
2
|
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
3
4
|
import type { BurnTestUI } from '../ui';
|
|
4
5
|
|
|
5
6
|
const slug = 'textiel-brandproef';
|
|
@@ -114,23 +115,8 @@ export const content: ToolLocaleContent<BurnTestUI> = {
|
|
|
114
115
|
slug,
|
|
115
116
|
title,
|
|
116
117
|
description,
|
|
117
|
-
faqTitle: 'Veelgestelde Vragen',
|
|
118
118
|
faq: faqData,
|
|
119
|
-
|
|
120
|
-
bibliography: [
|
|
121
|
-
{
|
|
122
|
-
name: 'AATCC TM20: Fiber Analysis - Qualitative',
|
|
123
|
-
url: 'https://members.aatcc.org/store/tm20/485/',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'Textile Fibers: Identification and Testing - NIST',
|
|
127
|
-
url: 'https://nvlpubs.nist.gov/nistpubs/Legacy/circ/nbscircular41e3.pdf',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Burn Test Chart for Fiber Identification - Fabric Mart',
|
|
131
|
-
url: 'https://fabricmartfabrics.com/pages/burn-test-chart',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
119
|
+
bibliography: bibliography,
|
|
134
120
|
howTo: howToData,
|
|
135
121
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
136
122
|
seo: [
|