@jjlmoya/utils-developer 1.30.0 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/package.json +70 -70
  2. package/src/category/i18n/en.ts +1 -1
  3. package/src/category/i18n/es.ts +1 -1
  4. package/src/category/index.ts +2 -1
  5. package/src/category/seo.astro +1 -1
  6. package/src/components/PreviewNavSidebar.astro +1 -1
  7. package/src/components/PreviewToolbar.astro +1 -1
  8. package/src/data.ts +1 -1
  9. package/src/entries.ts +2 -0
  10. package/src/env.d.ts +1 -1
  11. package/src/index.ts +1 -0
  12. package/src/layouts/PreviewLayout.astro +1 -1
  13. package/src/pages/[locale]/[slug].astro +161 -161
  14. package/src/pages/index.astro +1 -1
  15. package/src/tests/bibliography_wellformed_export.test.ts +46 -0
  16. package/src/tests/category_seo_quality.test.ts +76 -0
  17. package/src/tests/entry_contract.test.ts +8 -2
  18. package/src/tests/faq_count.test.ts +1 -1
  19. package/src/tests/i18n_coverage.test.ts +2 -6
  20. package/src/tests/inverted_punctuation.test.ts +113 -113
  21. package/src/tests/locale_completeness.test.ts +1 -1
  22. package/src/tests/mocks/astro_mock.js +1 -1
  23. package/src/tests/no_h1_in_components.test.ts +1 -1
  24. package/src/tests/promote_this_website_i18n.test.ts +33 -0
  25. package/src/tests/seo_translation_completeness.test.ts +69 -0
  26. package/src/tests/seo_wellformed_export.test.ts +65 -0
  27. package/src/tests/slug_language_code_format.test.ts +25 -25
  28. package/src/tests/slug_uniqueness.test.ts +86 -86
  29. package/src/tests/tool_validation.test.ts +16 -16
  30. package/src/tool/aspectRatio/i18n/de.ts +164 -164
  31. package/src/tool/aspectRatio/i18n/ja.ts +1 -1
  32. package/src/tool/aspectRatio/i18n/ko.ts +1 -1
  33. package/src/tool/aspectRatio/i18n/pl.ts +164 -164
  34. package/src/tool/aspectRatio/i18n/ru.ts +164 -164
  35. package/src/tool/aspectRatio/i18n/zh.ts +165 -165
  36. package/src/tool/aspectRatio/seo.astro +15 -15
  37. package/src/tool/calculadoraTiempoDatos/i18n/de.ts +143 -143
  38. package/src/tool/calculadoraTiempoDatos/i18n/ja.ts +1 -1
  39. package/src/tool/calculadoraTiempoDatos/i18n/ko.ts +1 -1
  40. package/src/tool/calculadoraTiempoDatos/i18n/pl.ts +143 -143
  41. package/src/tool/calculadoraTiempoDatos/i18n/ru.ts +144 -144
  42. package/src/tool/calculadoraTiempoDatos/i18n/sv.ts +143 -143
  43. package/src/tool/calculadoraTiempoDatos/i18n/zh.ts +144 -144
  44. package/src/tool/calculadoraTiempoDatos/seo.astro +15 -15
  45. package/src/tool/colorConverter/i18n/de.ts +120 -120
  46. package/src/tool/colorConverter/i18n/ja.ts +1 -1
  47. package/src/tool/colorConverter/i18n/ko.ts +1 -1
  48. package/src/tool/colorConverter/i18n/ru.ts +120 -120
  49. package/src/tool/colorConverter/i18n/zh.ts +1 -1
  50. package/src/tool/colorConverter/seo.astro +15 -15
  51. package/src/tool/conversorExcelCsvHtml/i18n/ja.ts +1 -1
  52. package/src/tool/conversorExcelCsvHtml/i18n/ko.ts +1 -1
  53. package/src/tool/conversorExcelCsvHtml/i18n/pl.ts +124 -124
  54. package/src/tool/conversorExcelCsvHtml/i18n/ru.ts +124 -124
  55. package/src/tool/conversorExcelCsvHtml/i18n/zh.ts +125 -125
  56. package/src/tool/conversorExcelCsvHtml/seo.astro +15 -15
  57. package/src/tool/cronGenerator/i18n/ja.ts +1 -1
  58. package/src/tool/cronGenerator/i18n/ko.ts +1 -1
  59. package/src/tool/cronGenerator/i18n/zh.ts +183 -183
  60. package/src/tool/cronGenerator/seo.astro +15 -15
  61. package/src/tool/cssSpecificityCalculator/i18n/ja.ts +1 -1
  62. package/src/tool/cssSpecificityCalculator/i18n/ko.ts +1 -1
  63. package/src/tool/cssSpecificityCalculator/i18n/zh.ts +1 -1
  64. package/src/tool/cssSpecificityCalculator/seo.astro +15 -15
  65. package/src/tool/cssToInlineConverter/i18n/ja.ts +1 -1
  66. package/src/tool/cssToInlineConverter/i18n/ko.ts +1 -1
  67. package/src/tool/cssToInlineConverter/i18n/zh.ts +1 -1
  68. package/src/tool/cssToInlineConverter/seo.astro +15 -15
  69. package/src/tool/dualOsIconPreview/assets/day-check.webp +0 -0
  70. package/src/tool/dualOsIconPreview/assets/fast-task.webp +0 -0
  71. package/src/tool/dualOsIconPreview/assets/fortune-cookie.webp +0 -0
  72. package/src/tool/dualOsIconPreview/assets/lexi-crash.webp +0 -0
  73. package/src/tool/dualOsIconPreview/assets/pizzametrics.webp +0 -0
  74. package/src/tool/dualOsIconPreview/assets/sauce-lab.webp +0 -0
  75. package/src/tool/dualOsIconPreview/assets/vesp.webp +0 -0
  76. package/src/tool/dualOsIconPreview/bibliography.astro +6 -0
  77. package/src/tool/dualOsIconPreview/bibliography.ts +7 -0
  78. package/src/tool/dualOsIconPreview/component.astro +117 -0
  79. package/src/tool/dualOsIconPreview/controller.ts +157 -0
  80. package/src/tool/dualOsIconPreview/dom-views.ts +82 -0
  81. package/src/tool/dualOsIconPreview/dual-ios-android-app-icon-preview.css +861 -0
  82. package/src/tool/dualOsIconPreview/entry.ts +31 -0
  83. package/src/tool/dualOsIconPreview/evaluator.ts +20 -0
  84. package/src/tool/dualOsIconPreview/i18n/de.ts +56 -0
  85. package/src/tool/dualOsIconPreview/i18n/en.ts +46 -0
  86. package/src/tool/dualOsIconPreview/i18n/es.ts +56 -0
  87. package/src/tool/dualOsIconPreview/i18n/fr.ts +56 -0
  88. package/src/tool/dualOsIconPreview/i18n/id.ts +56 -0
  89. package/src/tool/dualOsIconPreview/i18n/it.ts +56 -0
  90. package/src/tool/dualOsIconPreview/i18n/ja.ts +56 -0
  91. package/src/tool/dualOsIconPreview/i18n/ko.ts +56 -0
  92. package/src/tool/dualOsIconPreview/i18n/nl.ts +56 -0
  93. package/src/tool/dualOsIconPreview/i18n/pl.ts +56 -0
  94. package/src/tool/dualOsIconPreview/i18n/pt.ts +56 -0
  95. package/src/tool/dualOsIconPreview/i18n/ru.ts +56 -0
  96. package/src/tool/dualOsIconPreview/i18n/sv.ts +56 -0
  97. package/src/tool/dualOsIconPreview/i18n/tr.ts +43 -0
  98. package/src/tool/dualOsIconPreview/i18n/zh.ts +43 -0
  99. package/src/tool/dualOsIconPreview/index.ts +11 -0
  100. package/src/tool/dualOsIconPreview/logic.test.ts +63 -0
  101. package/src/tool/dualOsIconPreview/logic.ts +135 -0
  102. package/src/tool/dualOsIconPreview/seo.astro +15 -0
  103. package/src/tool/dualOsIconPreview/storage.ts +18 -0
  104. package/src/tool/dualOsIconPreview/ui.ts +52 -0
  105. package/src/tool/duplicateCssRemover/i18n/ja.ts +1 -1
  106. package/src/tool/duplicateCssRemover/i18n/ko.ts +1 -1
  107. package/src/tool/duplicateCssRemover/i18n/zh.ts +1 -1
  108. package/src/tool/duplicateCssRemover/seo.astro +15 -15
  109. package/src/tool/generadorSecurityTxt/i18n/ja.ts +1 -1
  110. package/src/tool/generadorSecurityTxt/i18n/ko.ts +1 -1
  111. package/src/tool/generadorSecurityTxt/i18n/zh.ts +1 -1
  112. package/src/tool/generadorSecurityTxt/seo.astro +15 -15
  113. package/src/tool/hashGenerator/i18n/ja.ts +1 -1
  114. package/src/tool/hashGenerator/i18n/ko.ts +1 -1
  115. package/src/tool/hashGenerator/seo.astro +15 -15
  116. package/src/tool/inspectorCertificadosSsl/i18n/ja.ts +1 -1
  117. package/src/tool/inspectorCertificadosSsl/i18n/ko.ts +1 -1
  118. package/src/tool/inspectorCertificadosSsl/i18n/zh.ts +1 -1
  119. package/src/tool/inspectorCertificadosSsl/seo.astro +15 -15
  120. package/src/tool/jsonFormatter/seo.astro +15 -15
  121. package/src/tool/jwtDecoder/i18n/es.ts +248 -248
  122. package/src/tool/jwtDecoder/i18n/fr.ts +248 -248
  123. package/src/tool/jwtDecoder/i18n/tr.ts +248 -248
  124. package/src/tool/keycode/seo.astro +15 -15
  125. package/src/tool/llmCostCalculator/i18n/fr.ts +149 -149
  126. package/src/tool/llmCostCalculator/i18n/ja.ts +1 -1
  127. package/src/tool/llmCostCalculator/i18n/ko.ts +1 -1
  128. package/src/tool/llmCostCalculator/seo.astro +15 -15
  129. package/src/tool/mobileMockupGenerator/i18n/ja.ts +1 -1
  130. package/src/tool/mobileMockupGenerator/i18n/ko.ts +1 -1
  131. package/src/tool/mobileMockupGenerator/i18n/zh.ts +1 -1
  132. package/src/tool/mobileMockupGenerator/seo.astro +15 -15
  133. package/src/tool/musicalTypography/i18n/ja.ts +1 -1
  134. package/src/tool/musicalTypography/i18n/ko.ts +1 -1
  135. package/src/tool/musicalTypography/i18n/zh.ts +1 -1
  136. package/src/tool/musicalTypography/seo.astro +15 -15
  137. package/src/tool/placeholderGenerator/i18n/ja.ts +1 -1
  138. package/src/tool/placeholderGenerator/i18n/ko.ts +1 -1
  139. package/src/tool/placeholderGenerator/i18n/zh.ts +1 -1
  140. package/src/tool/placeholderGenerator/seo.astro +15 -15
  141. package/src/tool/promoteThisWebsite/entry.ts +13 -0
  142. package/src/tool/promoteThisWebsite/i18n/de.ts +95 -0
  143. package/src/tool/promoteThisWebsite/i18n/fr.ts +95 -0
  144. package/src/tool/promoteThisWebsite/i18n/id.ts +95 -0
  145. package/src/tool/promoteThisWebsite/i18n/it.ts +95 -0
  146. package/src/tool/promoteThisWebsite/i18n/ja.ts +95 -0
  147. package/src/tool/promoteThisWebsite/i18n/ko.ts +95 -0
  148. package/src/tool/promoteThisWebsite/i18n/nl.ts +95 -0
  149. package/src/tool/promoteThisWebsite/i18n/pl.ts +95 -0
  150. package/src/tool/promoteThisWebsite/i18n/pt.ts +95 -0
  151. package/src/tool/promoteThisWebsite/i18n/ru.ts +95 -0
  152. package/src/tool/promoteThisWebsite/i18n/sv.ts +95 -0
  153. package/src/tool/promoteThisWebsite/i18n/tr.ts +95 -0
  154. package/src/tool/promoteThisWebsite/i18n/zh.ts +95 -0
  155. package/src/tool/promptLibrary/i18n/ja.ts +1 -1
  156. package/src/tool/promptLibrary/i18n/ko.ts +1 -1
  157. package/src/tool/promptLibrary/i18n/zh.ts +1 -1
  158. package/src/tool/promptLibrary/seo.astro +15 -15
  159. package/src/tool/readabilityCalculator/i18n/ja.ts +1 -1
  160. package/src/tool/readabilityCalculator/i18n/ko.ts +1 -1
  161. package/src/tool/readabilityCalculator/i18n/zh.ts +1 -1
  162. package/src/tool/readabilityCalculator/seo.astro +15 -15
  163. package/src/tool/serpPixelSimulator/entry.ts +30 -30
  164. package/src/tool/serpPixelSimulator/i18n/en.ts +211 -211
  165. package/src/tool/serpPixelSimulator/i18n/fr.ts +214 -214
  166. package/src/tool/serpPixelSimulator/i18n/ru.ts +214 -214
  167. package/src/tool/serpPixelSimulator/logic.ts +18 -18
  168. package/src/tool/serpPixelSimulator/serp-pixel-simulator.css +195 -195
  169. package/src/tool/svgSanitizer/i18n/ja.ts +1 -1
  170. package/src/tool/svgSanitizer/i18n/ko.ts +1 -1
  171. package/src/tool/svgSanitizer/seo.astro +15 -15
  172. package/src/tool/svgToCss/i18n/ja.ts +1 -1
  173. package/src/tool/svgToCss/i18n/ko.ts +1 -1
  174. package/src/tool/svgToCss/seo.astro +15 -15
  175. package/src/tool/urlCleaner/i18n/ja.ts +1 -1
  176. package/src/tool/urlCleaner/i18n/ko.ts +1 -1
  177. package/src/tool/urlCleaner/i18n/zh.ts +1 -1
  178. package/src/tool/urlCleaner/seo.astro +15 -15
  179. package/src/tool/urlEncoderDecoder/i18n/es.ts +146 -146
  180. package/src/tool/urlEncoderDecoder/i18n/ko.ts +1 -1
  181. package/src/tool/urlEncoderDecoder/seo.astro +15 -15
  182. package/src/tool/utmGenerator/i18n/ja.ts +1 -1
  183. package/src/tool/utmGenerator/i18n/ko.ts +1 -1
  184. package/src/tool/utmGenerator/i18n/zh.ts +1 -1
  185. package/src/tool/utmGenerator/seo.astro +15 -15
  186. package/src/tools.ts +2 -1
  187. package/src/types.ts +1 -1
@@ -1,87 +1,87 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { ALL_TOOLS } from '../tools';
3
- import type { ToolLocaleContent } from '../types';
4
-
5
- const sharingLocales = ['ja', 'ko', 'zh'];
6
- const toolsWithSharedSpanishSlug = ['cron-generator', 'json-formatter', 'keycode'];
7
-
8
- interface ValidateParams {
9
- toolId: string;
10
- locale: string;
11
- content: ToolLocaleContent;
12
- enSlug: string;
13
- slugs: Map<string, string>;
14
- }
15
-
16
- const validateLocaleSlug = ({
17
- toolId,
18
- locale,
19
- content,
20
- enSlug,
21
- slugs,
22
- }: ValidateParams) => {
23
- expect(
24
- content.slug,
25
- `Tool "${toolId}" locale "${locale}" has an invalid slug ("${content.slug}"). Slugs must be transliterated (only a-z, 0-9, and -).`,
26
- ).toMatch(/^[a-z0-9-]+$/);
27
-
28
- if (locale === 'en') {
29
- return;
30
- }
31
-
32
- if (sharingLocales.includes(locale)) {
33
- expect(
34
- content.slug,
35
- `Tool "${toolId}" locale "${locale}" must use the same slug as "en" ("${enSlug}").`,
36
- ).toBe(enSlug);
37
- } else if (locale === 'es' && toolsWithSharedSpanishSlug.includes(toolId)) {
38
- expect(
39
- content.slug,
40
- `Tool "${toolId}" locale "${locale}" must use the same slug as "en" ("${enSlug}").`,
41
- ).toBe(enSlug);
42
- } else {
43
- expect(
44
- content.slug,
45
- `Tool "${toolId}" locale "${locale}" has the same slug as "en" ("${enSlug}"). Cada slug tiene que estar en su propia idioma`,
46
- ).not.toBe(enSlug);
47
-
48
- if (slugs.has(content.slug)) {
49
- const previousLocale = slugs.get(content.slug);
50
- expect(
51
- false,
52
- `Tool "${toolId}" locales "${locale}" and "${previousLocale}" share the same slug ("${content.slug}"). Cada slug tiene que estar en su propia idioma`,
53
- ).toBe(true);
54
- }
55
- slugs.set(content.slug, locale);
56
- }
57
- };
58
-
59
- describe('Slug Localization and Uniqueness Validation', () => {
60
- ALL_TOOLS.forEach((tool) => {
61
- describe(`Tool: ${tool.entry.id}`, () => {
62
- it('every locale should have a unique, translated slug', async () => {
63
- const slugs = new Map<string, string>();
64
- const locales = Object.keys(tool.entry.i18n);
65
-
66
- let enSlug = '';
67
- if (locales.includes('en')) {
68
- const enLoader = tool.entry.i18n['en' as keyof typeof tool.entry.i18n];
69
- const enContent = (await enLoader?.()) as ToolLocaleContent;
70
- enSlug = enContent.slug;
71
- }
72
-
73
- for (const locale of locales) {
74
- const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
75
- const content = (await loader?.()) as ToolLocaleContent;
76
- validateLocaleSlug({
77
- toolId: tool.entry.id,
78
- locale,
79
- content,
80
- enSlug,
81
- slugs,
82
- });
83
- }
84
- });
85
- });
86
- });
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_TOOLS } from '../tools';
3
+ import type { ToolLocaleContent } from '../types';
4
+
5
+ const sharingLocales = ['ja', 'ko', 'zh'];
6
+ const toolsWithSharedSpanishSlug = ['cron-generator', 'json-formatter', 'keycode'];
7
+
8
+ interface ValidateParams {
9
+ toolId: string;
10
+ locale: string;
11
+ content: ToolLocaleContent;
12
+ enSlug: string;
13
+ slugs: Map<string, string>;
14
+ }
15
+
16
+ const validateLocaleSlug = ({
17
+ toolId,
18
+ locale,
19
+ content,
20
+ enSlug,
21
+ slugs,
22
+ }: ValidateParams) => {
23
+ expect(
24
+ content.slug,
25
+ `Tool "${toolId}" locale "${locale}" has an invalid slug ("${content.slug}"). Slugs must be transliterated (only a-z, 0-9, and -).`,
26
+ ).toMatch(/^[a-z0-9-]+$/);
27
+
28
+ if (locale === 'en') {
29
+ return;
30
+ }
31
+
32
+ if (sharingLocales.includes(locale)) {
33
+ expect(
34
+ content.slug,
35
+ `Tool "${toolId}" locale "${locale}" must use the same slug as "en" ("${enSlug}").`,
36
+ ).toBe(enSlug);
37
+ } else if (locale === 'es' && toolsWithSharedSpanishSlug.includes(toolId)) {
38
+ expect(
39
+ content.slug,
40
+ `Tool "${toolId}" locale "${locale}" must use the same slug as "en" ("${enSlug}").`,
41
+ ).toBe(enSlug);
42
+ } else {
43
+ expect(
44
+ content.slug,
45
+ `Tool "${toolId}" locale "${locale}" has the same slug as "en" ("${enSlug}"). Cada slug tiene que estar en su propia idioma`,
46
+ ).not.toBe(enSlug);
47
+
48
+ if (slugs.has(content.slug)) {
49
+ const previousLocale = slugs.get(content.slug);
50
+ expect(
51
+ false,
52
+ `Tool "${toolId}" locales "${locale}" and "${previousLocale}" share the same slug ("${content.slug}"). Cada slug tiene que estar en su propia idioma`,
53
+ ).toBe(true);
54
+ }
55
+ slugs.set(content.slug, locale);
56
+ }
57
+ };
58
+
59
+ describe('Slug Localization and Uniqueness Validation', () => {
60
+ ALL_TOOLS.forEach((tool) => {
61
+ describe(`Tool: ${tool.entry.id}`, () => {
62
+ it('every locale should have a unique, translated slug', async () => {
63
+ const slugs = new Map<string, string>();
64
+ const locales = Object.keys(tool.entry.i18n);
65
+
66
+ let enSlug = '';
67
+ if (locales.includes('en')) {
68
+ const enLoader = tool.entry.i18n['en' as keyof typeof tool.entry.i18n];
69
+ const enContent = (await enLoader?.()) as ToolLocaleContent;
70
+ enSlug = enContent.slug;
71
+ }
72
+
73
+ for (const locale of locales) {
74
+ const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
75
+ const content = (await loader?.()) as ToolLocaleContent;
76
+ validateLocaleSlug({
77
+ toolId: tool.entry.id,
78
+ locale,
79
+ content,
80
+ enSlug,
81
+ slugs,
82
+ });
83
+ }
84
+ });
85
+ });
86
+ });
87
87
  });
@@ -1,17 +1,17 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { ALL_TOOLS } from '../tools';
3
- import { developerCategory } from '../data';
4
-
5
- describe('Tool Validation Suite', () => {
6
- describe('Library Registration', () => {
7
- it('should have 28 tools in ALL_TOOLS', () => {
8
- expect(ALL_TOOLS.length).toBe(29);
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_TOOLS } from '../tools';
3
+ import { developerCategory } from '../data';
4
+
5
+ describe('Tool Validation Suite', () => {
6
+ describe('Library Registration', () => {
7
+ it('should have 28 tools in ALL_TOOLS', () => {
8
+ expect(ALL_TOOLS.length).toBe(30);
9
9
  });
10
-
11
- it('developerCategory should be defined', () => {
12
- expect(developerCategory).toBeDefined();
13
- expect(developerCategory.i18n).toBeDefined();
14
- });
15
- });
16
- });
17
-
10
+
11
+ it('developerCategory should be defined', () => {
12
+ expect(developerCategory).toBeDefined();
13
+ expect(developerCategory.i18n).toBeDefined();
14
+ });
15
+ });
16
+ });
17
+
@@ -1,165 +1,165 @@
1
1
  import { bibliography } from '../bibliography';
2
- import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
3
- import type { ToolLocaleContent } from '../../../types';
4
- import type { AspectRatioUI } from '../ui';
5
-
6
- const slug = 'seitenverhaeltnis-rechner';
7
- const title = 'Seitenverhältnis Rechner in Pixeln. Online Proportionen';
8
- const description =
9
- 'Berechnen Sie neue Bild-, Video- und Webdesign-Auflösungen und behalten Sie die exakten Proportionen bei, um grafische Verzerrungen zu vermeiden. Unterstützt 16:9, 4:3, 21:9 und benutzerdefinierte Formate.';
10
-
11
- const faqData = [
12
- {
13
- question: 'Was ist das Seitenverhältnis?',
14
- answer:
15
- 'Das Seitenverhältnis (Aspect Ratio) beschreibt das geometrische Verhältnis zwischen der Breite und der Höhe eines Bildes oder Bildschirms. Es wird durch zwei Zahlen dargestellt, die durch einen Doppelpunkt getrennt sind (z. B. 16:9), und gibt an, wie sich die Höhe proportional zur Breite verändert.',
16
- },
17
- {
18
- question: 'Warum ist es wichtig, die korrekten Proportionen beizubehalten?',
19
- answer:
20
- 'Das Ignorieren des Seitenverhältnisses führt zu gestauchten oder gestreckten Bildern, unerwünschten schwarzen Balken (Letterboxing) in Videos und Webkomponenten, deren Layout bei unterschiedlichen Bildschirmgrößen zerstört wird. Die Beibehaltung korrekter Proportionen ist entscheidend für eine professionelle Darstellung.',
21
- },
22
- {
23
- question: 'Wie berechne ich die Höhe aus der Breite bei einem gegebenen Verhältnis?',
24
- answer:
25
- 'Die Formel lautet: Höhe = Breite × (Verhältnis Höhe / Verhältnis Breite). Beispiel: Bei einer Breite von 1280px mit einem Verhältnis von 16:9 wäre die Höhe: 1280 × (9/16) = 720px.',
26
- },
27
- {
28
- question: 'Was ist das Standard-Seitenverhältnis für YouTube-Videos?',
29
- answer:
30
- '16:9 ist das Standardverhältnis für YouTube und die meisten modernen Videoplattformen. Es entspricht Auflösungen wie 1280×720 (HD), 1920×1080 (Full HD) oder 3840×2160 (4K UHD).',
31
- },
32
- {
33
- question: 'Welches Seitenverhältnis nutzen vertikale Social-Media-Videos?',
34
- answer:
35
- '9:16, was genau dem Umkehrschluss des Breitbildformats entspricht. Es ist das native Verhältnis für TikTok, Instagram Reels und YouTube Shorts, bedingt durch die vertikale Nutzung von Smartphones.',
36
- },
37
- ];
38
-
39
- const howToData = [
40
- {
41
- name: 'Originalverhältnis eingeben',
42
- text: 'Geben Sie die Breiten- und Höhenwerte des Verhältnisses ein, das Sie beibehalten möchten (z. B. 16 und 9 für Breitbild), oder wählen Sie eine der Voreinstellungen.',
43
- },
44
- {
45
- name: 'Skalierung anpassen',
46
- text: 'Ändern Sie den Breiten- oder Höhenwert im Abschnitt "Echtmaßstab". Das Tool berechnet automatisch den jeweils anderen Wert, um die Proportionen zu wahren.',
47
- },
48
- {
49
- name: 'Vorschau prüfen',
50
- text: 'Das Vorschauband zeigt die resultierende Form im proportionalen Maßstab mit dem vereinfachten Verhältnis und der berechneten Auflösung.',
51
- },
52
- {
53
- name: 'In Ihr Projekt übernehmen',
54
- text: 'Kopieren Sie die berechneten Werte, um sie in Ihrem CSS (aspect-ratio: 16 / 9), beim Video-Export oder in den Einstellungen Ihres Design-Tools zu verwenden.',
55
- },
56
- ];
57
-
58
- const faqSchema: WithContext<FAQPage> = {
59
- '@context': 'https://schema.org',
60
- '@type': 'FAQPage',
61
- mainEntity: faqData.map((item) => ({
62
- '@type': 'Question',
63
- name: item.question,
64
- acceptedAnswer: { '@type': 'Answer', text: item.answer },
65
- })),
66
- };
67
-
68
- const howToSchema: WithContext<HowToThing> = {
69
- '@context': 'https://schema.org',
70
- '@type': 'HowTo',
71
- name: title,
72
- description,
73
- step: howToData.map((step, i) => ({
74
- '@type': 'HowToStep',
75
- position: i + 1,
76
- name: step.name,
77
- text: step.text,
78
- })),
79
- };
80
-
81
- const appSchema: WithContext<SoftwareApplication> = {
82
- '@context': 'https://schema.org',
83
- '@type': 'SoftwareApplication',
84
- name: title,
85
- description,
86
- applicationCategory: 'UtilityApplication',
87
- operatingSystem: 'All',
88
- offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
89
- inLanguage: 'de',
90
- };
91
-
92
- const ui: AspectRatioUI = {
93
- labelConfig: 'Konfiguration',
94
- labelRatio: 'Originalverhältnis',
95
- labelWidth: 'Breite',
96
- labelHeight: 'Höhe',
97
- labelScale: 'Echtmaßstab',
98
- labelPixelWidth: 'Pixel (Breite)',
99
- labelPixelHeight: 'Pixel (Höhe)',
100
- labelPreview: 'Proportionale Vorschau',
101
- labelStatus: 'Perfektes Verhältnis',
102
- labelOffline: '100% Offline-Tool',
103
- };
104
-
105
- export const content: ToolLocaleContent<AspectRatioUI> = {
106
- slug,
107
- title,
108
- description,
109
- ui,
110
- faqTitle: 'Häufig gestellte Fragen',
111
- faq: faqData,
112
- bibliographyTitle: 'Referenzen und Dokumentation',
113
- bibliography,
114
- howTo: howToData,
115
- schemas: [faqSchema, howToSchema, appSchema],
116
- seo: [
117
- {
118
- type: 'title',
119
- text: 'Was ist das Seitenverhältnis?',
120
- level: 2,
121
- },
122
- {
123
- type: 'paragraph',
124
- html: 'Im Grafikdesign, in der Fotografie und in der Frontend-Entwicklung beschreibt das <strong>Seitenverhältnis</strong> (Aspect Ratio) die geometrische Beziehung zwischen der Breite und der Höhe eines Bildes, eines Bildschirms oder eines Containers. Es wird üblicherweise durch zwei Zahlen dargestellt, die durch einen Doppelpunkt getrennt sind (z. B. <code>16:9</code>), und gibt an, wie die Höhe proportional zur Breite skaliert wird.',
125
- },
126
- {
127
- type: 'paragraph',
128
- html: 'Falsch gehandhabte Seitenverhältnisse sind eine häufige Ursache für gestauchte Fotos, Videos mit unerwartetem Beschnitt (Letterboxing) oder Webkomponenten, deren Layout beim Betrachten auf unterschiedlichen Geräten - vom Smartphone bis hin zu Ultra-Wide-Monitoren - fehlerhaft dargestellt wird.',
129
- },
130
- {
131
- type: 'title',
132
- text: 'Gängige Branchenverhältnisse',
133
- level: 3,
134
- },
135
- {
136
- type: 'paragraph',
137
- html: 'Je nach Fachbereich werden Sie ständig mit einer begrenzten Anzahl an globalen Standardproportionen zu tun haben:',
138
- },
139
- {
140
- type: 'list',
141
- items: [
142
- '<strong>16:9 (Widescreen):</strong> Das absolut dominante Format für moderne Monitore, Fernseher, YouTube-Aufnahmen oder Standard-HD-Auflösungen (wie 1920×1080 oder 4K).',
143
- '<strong>9:16 (Vertikal):</strong> Entstanden durch die native Nutzung von Inhalten auf Mobilgeräten (TikTok, Instagram Reels, YouTube Shorts). Exakt das gleiche Verhältnis wie Breitbildvideos, jedoch mit einer physischen Drehung des Geräts.',
144
- '<strong>4:3 (Klassisch / Vintage):</strong> Zu finden bei alten Fernsehern und Monitoren sowie bei analogen und speziellen digitalen Kameramodellen. Die fast quadratische Optik lenkt den Blick direkt auf die zentrale Bildachse.',
145
- ],
146
- },
147
- {
148
- type: 'title',
149
- text: 'Webentwicklung und die CSS-Eigenschaft aspect-ratio',
150
- level: 3,
151
- },
152
- {
153
- type: 'paragraph',
154
- html: 'Früher wurden in CSS komplexe mathematische Systeme mit einem <strong>Padding-Hack</strong> (wie <code>padding-top: 56.25%</code>) verwendet, um dynamische Platzhalter für YouTube-Iframes oder Titelbilder zu reservieren und so ein störendes Cumulative Layout Shift (CLS) beim Laden der Seite zu vermeiden.',
155
- },
156
- {
157
- type: 'paragraph',
158
- html: 'Heutzutage nutzen alle modernen Layouts direkt Eigenschaften wie <code>aspect-ratio: 16 / 9;</code>. Dies sorgt für semantischen Code und ermöglicht es dem Browser, die fehlende Dimension automatisch von der ursprünglichen, über Grid oder Flexbox definierten Breite abzuleiten.',
159
- },
160
- {
161
- type: 'paragraph',
162
- html: 'Dieser lokale Pixel-Rechner unterstützt Sie dabei, durch sofortige Skalierungsberechnungen Designfehler und katastrophale Fehlkonfigurationen zu vermeiden.',
163
- },
164
- ],
165
- };
2
+ import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
3
+ import type { ToolLocaleContent } from '../../../types';
4
+ import type { AspectRatioUI } from '../ui';
5
+
6
+ const slug = 'seitenverhaeltnis-rechner';
7
+ const title = 'Seitenverhältnis Rechner in Pixeln. Online Proportionen';
8
+ const description =
9
+ 'Berechnen Sie neue Bild-, Video- und Webdesign-Auflösungen und behalten Sie die exakten Proportionen bei, um grafische Verzerrungen zu vermeiden. Unterstützt 16:9, 4:3, 21:9 und benutzerdefinierte Formate.';
10
+
11
+ const faqData = [
12
+ {
13
+ question: 'Was ist das Seitenverhältnis?',
14
+ answer:
15
+ 'Das Seitenverhältnis (Aspect Ratio) beschreibt das geometrische Verhältnis zwischen der Breite und der Höhe eines Bildes oder Bildschirms. Es wird durch zwei Zahlen dargestellt, die durch einen Doppelpunkt getrennt sind (z. B. 16:9), und gibt an, wie sich die Höhe proportional zur Breite verändert.',
16
+ },
17
+ {
18
+ question: 'Warum ist es wichtig, die korrekten Proportionen beizubehalten?',
19
+ answer:
20
+ 'Das Ignorieren des Seitenverhältnisses führt zu gestauchten oder gestreckten Bildern, unerwünschten schwarzen Balken (Letterboxing) in Videos und Webkomponenten, deren Layout bei unterschiedlichen Bildschirmgrößen zerstört wird. Die Beibehaltung korrekter Proportionen ist entscheidend für eine professionelle Darstellung.',
21
+ },
22
+ {
23
+ question: 'Wie berechne ich die Höhe aus der Breite bei einem gegebenen Verhältnis?',
24
+ answer:
25
+ 'Die Formel lautet: Höhe = Breite × (Verhältnis Höhe / Verhältnis Breite). Beispiel: Bei einer Breite von 1280px mit einem Verhältnis von 16:9 wäre die Höhe: 1280 × (9/16) = 720px.',
26
+ },
27
+ {
28
+ question: 'Was ist das Standard-Seitenverhältnis für YouTube-Videos?',
29
+ answer:
30
+ '16:9 ist das Standardverhältnis für YouTube und die meisten modernen Videoplattformen. Es entspricht Auflösungen wie 1280×720 (HD), 1920×1080 (Full HD) oder 3840×2160 (4K UHD).',
31
+ },
32
+ {
33
+ question: 'Welches Seitenverhältnis nutzen vertikale Social-Media-Videos?',
34
+ answer:
35
+ '9:16, was genau dem Umkehrschluss des Breitbildformats entspricht. Es ist das native Verhältnis für TikTok, Instagram Reels und YouTube Shorts, bedingt durch die vertikale Nutzung von Smartphones.',
36
+ },
37
+ ];
38
+
39
+ const howToData = [
40
+ {
41
+ name: 'Originalverhältnis eingeben',
42
+ text: 'Geben Sie die Breiten- und Höhenwerte des Verhältnisses ein, das Sie beibehalten möchten (z. B. 16 und 9 für Breitbild), oder wählen Sie eine der Voreinstellungen.',
43
+ },
44
+ {
45
+ name: 'Skalierung anpassen',
46
+ text: 'Ändern Sie den Breiten- oder Höhenwert im Abschnitt "Echtmaßstab". Das Tool berechnet automatisch den jeweils anderen Wert, um die Proportionen zu wahren.',
47
+ },
48
+ {
49
+ name: 'Vorschau prüfen',
50
+ text: 'Das Vorschauband zeigt die resultierende Form im proportionalen Maßstab mit dem vereinfachten Verhältnis und der berechneten Auflösung.',
51
+ },
52
+ {
53
+ name: 'In Ihr Projekt übernehmen',
54
+ text: 'Kopieren Sie die berechneten Werte, um sie in Ihrem CSS (aspect-ratio: 16 / 9), beim Video-Export oder in den Einstellungen Ihres Design-Tools zu verwenden.',
55
+ },
56
+ ];
57
+
58
+ const faqSchema: WithContext<FAQPage> = {
59
+ '@context': 'https://schema.org',
60
+ '@type': 'FAQPage',
61
+ mainEntity: faqData.map((item) => ({
62
+ '@type': 'Question',
63
+ name: item.question,
64
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
65
+ })),
66
+ };
67
+
68
+ const howToSchema: WithContext<HowToThing> = {
69
+ '@context': 'https://schema.org',
70
+ '@type': 'HowTo',
71
+ name: title,
72
+ description,
73
+ step: howToData.map((step, i) => ({
74
+ '@type': 'HowToStep',
75
+ position: i + 1,
76
+ name: step.name,
77
+ text: step.text,
78
+ })),
79
+ };
80
+
81
+ const appSchema: WithContext<SoftwareApplication> = {
82
+ '@context': 'https://schema.org',
83
+ '@type': 'SoftwareApplication',
84
+ name: title,
85
+ description,
86
+ applicationCategory: 'UtilityApplication',
87
+ operatingSystem: 'All',
88
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
89
+ inLanguage: 'de',
90
+ };
91
+
92
+ const ui: AspectRatioUI = {
93
+ labelConfig: 'Konfiguration',
94
+ labelRatio: 'Originalverhältnis',
95
+ labelWidth: 'Breite',
96
+ labelHeight: 'Höhe',
97
+ labelScale: 'Echtmaßstab',
98
+ labelPixelWidth: 'Pixel (Breite)',
99
+ labelPixelHeight: 'Pixel (Höhe)',
100
+ labelPreview: 'Proportionale Vorschau',
101
+ labelStatus: 'Perfektes Verhältnis',
102
+ labelOffline: '100% Offline-Tool',
103
+ };
104
+
105
+ export const content: ToolLocaleContent<AspectRatioUI> = {
106
+ slug,
107
+ title,
108
+ description,
109
+ ui,
110
+ faqTitle: 'Häufig gestellte Fragen',
111
+ faq: faqData,
112
+ bibliographyTitle: 'Referenzen und Dokumentation',
113
+ bibliography,
114
+ howTo: howToData,
115
+ schemas: [faqSchema, howToSchema, appSchema],
116
+ seo: [
117
+ {
118
+ type: 'title',
119
+ text: 'Was ist das Seitenverhältnis?',
120
+ level: 2,
121
+ },
122
+ {
123
+ type: 'paragraph',
124
+ html: 'Im Grafikdesign, in der Fotografie und in der Frontend-Entwicklung beschreibt das <strong>Seitenverhältnis</strong> (Aspect Ratio) die geometrische Beziehung zwischen der Breite und der Höhe eines Bildes, eines Bildschirms oder eines Containers. Es wird üblicherweise durch zwei Zahlen dargestellt, die durch einen Doppelpunkt getrennt sind (z. B. <code>16:9</code>), und gibt an, wie die Höhe proportional zur Breite skaliert wird.',
125
+ },
126
+ {
127
+ type: 'paragraph',
128
+ html: 'Falsch gehandhabte Seitenverhältnisse sind eine häufige Ursache für gestauchte Fotos, Videos mit unerwartetem Beschnitt (Letterboxing) oder Webkomponenten, deren Layout beim Betrachten auf unterschiedlichen Geräten - vom Smartphone bis hin zu Ultra-Wide-Monitoren - fehlerhaft dargestellt wird.',
129
+ },
130
+ {
131
+ type: 'title',
132
+ text: 'Gängige Branchenverhältnisse',
133
+ level: 3,
134
+ },
135
+ {
136
+ type: 'paragraph',
137
+ html: 'Je nach Fachbereich werden Sie ständig mit einer begrenzten Anzahl an globalen Standardproportionen zu tun haben:',
138
+ },
139
+ {
140
+ type: 'list',
141
+ items: [
142
+ '<strong>16:9 (Widescreen):</strong> Das absolut dominante Format für moderne Monitore, Fernseher, YouTube-Aufnahmen oder Standard-HD-Auflösungen (wie 1920×1080 oder 4K).',
143
+ '<strong>9:16 (Vertikal):</strong> Entstanden durch die native Nutzung von Inhalten auf Mobilgeräten (TikTok, Instagram Reels, YouTube Shorts). Exakt das gleiche Verhältnis wie Breitbildvideos, jedoch mit einer physischen Drehung des Geräts.',
144
+ '<strong>4:3 (Klassisch / Vintage):</strong> Zu finden bei alten Fernsehern und Monitoren sowie bei analogen und speziellen digitalen Kameramodellen. Die fast quadratische Optik lenkt den Blick direkt auf die zentrale Bildachse.',
145
+ ],
146
+ },
147
+ {
148
+ type: 'title',
149
+ text: 'Webentwicklung und die CSS-Eigenschaft aspect-ratio',
150
+ level: 3,
151
+ },
152
+ {
153
+ type: 'paragraph',
154
+ html: 'Früher wurden in CSS komplexe mathematische Systeme mit einem <strong>Padding-Hack</strong> (wie <code>padding-top: 56.25%</code>) verwendet, um dynamische Platzhalter für YouTube-Iframes oder Titelbilder zu reservieren und so ein störendes Cumulative Layout Shift (CLS) beim Laden der Seite zu vermeiden.',
155
+ },
156
+ {
157
+ type: 'paragraph',
158
+ html: 'Heutzutage nutzen alle modernen Layouts direkt Eigenschaften wie <code>aspect-ratio: 16 / 9;</code>. Dies sorgt für semantischen Code und ermöglicht es dem Browser, die fehlende Dimension automatisch von der ursprünglichen, über Grid oder Flexbox definierten Breite abzuleiten.',
159
+ },
160
+ {
161
+ type: 'paragraph',
162
+ html: 'Dieser lokale Pixel-Rechner unterstützt Sie dabei, durch sofortige Skalierungsberechnungen Designfehler und katastrophale Fehlkonfigurationen zu vermeiden.',
163
+ },
164
+ ],
165
+ };
@@ -163,4 +163,4 @@ export const content: ToolLocaleContent<AspectRatioUI> = {
163
163
  },
164
164
  ],
165
165
  };
166
-
166
+
@@ -163,4 +163,4 @@ export const content: ToolLocaleContent<AspectRatioUI> = {
163
163
  },
164
164
  ],
165
165
  };
166
-
166
+