@jjlmoya/utils-tools 1.2.0 → 1.3.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 (184) hide show
  1. package/package.json +2 -1
  2. package/src/category/i18n/de.ts +172 -0
  3. package/src/category/i18n/id.ts +172 -0
  4. package/src/category/i18n/it.ts +172 -0
  5. package/src/category/i18n/ja.ts +172 -0
  6. package/src/category/i18n/ko.ts +172 -0
  7. package/src/category/i18n/nl.ts +172 -0
  8. package/src/category/i18n/pl.ts +172 -0
  9. package/src/category/i18n/pt.ts +172 -0
  10. package/src/category/i18n/ru.ts +172 -0
  11. package/src/category/i18n/sv.ts +172 -0
  12. package/src/category/i18n/tr.ts +172 -0
  13. package/src/category/i18n/zh.ts +172 -0
  14. package/src/category/index.ts +13 -1
  15. package/src/tests/i18n_coverage.test.ts +36 -0
  16. package/src/tests/locale_completeness.test.ts +1 -1
  17. package/src/tests/slug_uniqueness.test.ts +81 -0
  18. package/src/tests/title_quality.test.ts +0 -1
  19. package/src/tool/date-diff-calculator/i18n/de.ts +132 -0
  20. package/src/tool/date-diff-calculator/i18n/fr.ts +1 -1
  21. package/src/tool/date-diff-calculator/i18n/id.ts +132 -0
  22. package/src/tool/date-diff-calculator/i18n/it.ts +132 -0
  23. package/src/tool/date-diff-calculator/i18n/ja.ts +132 -0
  24. package/src/tool/date-diff-calculator/i18n/ko.ts +132 -0
  25. package/src/tool/date-diff-calculator/i18n/nl.ts +132 -0
  26. package/src/tool/date-diff-calculator/i18n/pl.ts +132 -0
  27. package/src/tool/date-diff-calculator/i18n/pt.ts +132 -0
  28. package/src/tool/date-diff-calculator/i18n/ru.ts +132 -0
  29. package/src/tool/date-diff-calculator/i18n/sv.ts +132 -0
  30. package/src/tool/date-diff-calculator/i18n/tr.ts +132 -0
  31. package/src/tool/date-diff-calculator/i18n/zh.ts +132 -0
  32. package/src/tool/date-diff-calculator/index.ts +12 -0
  33. package/src/tool/drive-direct-link/i18n/de.ts +118 -0
  34. package/src/tool/drive-direct-link/i18n/id.ts +118 -0
  35. package/src/tool/drive-direct-link/i18n/it.ts +118 -0
  36. package/src/tool/drive-direct-link/i18n/ja.ts +118 -0
  37. package/src/tool/drive-direct-link/i18n/ko.ts +118 -0
  38. package/src/tool/drive-direct-link/i18n/nl.ts +118 -0
  39. package/src/tool/drive-direct-link/i18n/pl.ts +118 -0
  40. package/src/tool/drive-direct-link/i18n/pt.ts +118 -0
  41. package/src/tool/drive-direct-link/i18n/ru.ts +118 -0
  42. package/src/tool/drive-direct-link/i18n/sv.ts +118 -0
  43. package/src/tool/drive-direct-link/i18n/tr.ts +118 -0
  44. package/src/tool/drive-direct-link/i18n/zh.ts +118 -0
  45. package/src/tool/drive-direct-link/index.ts +12 -0
  46. package/src/tool/email-list-cleaner/i18n/de.ts +140 -0
  47. package/src/tool/email-list-cleaner/i18n/es.ts +1 -1
  48. package/src/tool/email-list-cleaner/i18n/fr.ts +1 -1
  49. package/src/tool/email-list-cleaner/i18n/id.ts +140 -0
  50. package/src/tool/email-list-cleaner/i18n/it.ts +140 -0
  51. package/src/tool/email-list-cleaner/i18n/ja.ts +140 -0
  52. package/src/tool/email-list-cleaner/i18n/ko.ts +140 -0
  53. package/src/tool/email-list-cleaner/i18n/nl.ts +140 -0
  54. package/src/tool/email-list-cleaner/i18n/pl.ts +140 -0
  55. package/src/tool/email-list-cleaner/i18n/pt.ts +140 -0
  56. package/src/tool/email-list-cleaner/i18n/ru.ts +140 -0
  57. package/src/tool/email-list-cleaner/i18n/sv.ts +140 -0
  58. package/src/tool/email-list-cleaner/i18n/tr.ts +140 -0
  59. package/src/tool/email-list-cleaner/i18n/zh.ts +140 -0
  60. package/src/tool/email-list-cleaner/index.ts +12 -0
  61. package/src/tool/env-badge-spain/i18n/de.ts +153 -0
  62. package/src/tool/env-badge-spain/i18n/es.ts +1 -1
  63. package/src/tool/env-badge-spain/i18n/fr.ts +1 -1
  64. package/src/tool/env-badge-spain/i18n/id.ts +153 -0
  65. package/src/tool/env-badge-spain/i18n/it.ts +153 -0
  66. package/src/tool/env-badge-spain/i18n/ja.ts +153 -0
  67. package/src/tool/env-badge-spain/i18n/ko.ts +153 -0
  68. package/src/tool/env-badge-spain/i18n/nl.ts +153 -0
  69. package/src/tool/env-badge-spain/i18n/pl.ts +153 -0
  70. package/src/tool/env-badge-spain/i18n/pt.ts +153 -0
  71. package/src/tool/env-badge-spain/i18n/ru.ts +153 -0
  72. package/src/tool/env-badge-spain/i18n/sv.ts +153 -0
  73. package/src/tool/env-badge-spain/i18n/tr.ts +153 -0
  74. package/src/tool/env-badge-spain/i18n/zh.ts +153 -0
  75. package/src/tool/env-badge-spain/index.ts +12 -0
  76. package/src/tool/morse-beacon/i18n/de.ts +157 -0
  77. package/src/tool/morse-beacon/i18n/es.ts +1 -1
  78. package/src/tool/morse-beacon/i18n/id.ts +157 -0
  79. package/src/tool/morse-beacon/i18n/it.ts +157 -0
  80. package/src/tool/morse-beacon/i18n/ja.ts +157 -0
  81. package/src/tool/morse-beacon/i18n/ko.ts +157 -0
  82. package/src/tool/morse-beacon/i18n/nl.ts +157 -0
  83. package/src/tool/morse-beacon/i18n/pl.ts +157 -0
  84. package/src/tool/morse-beacon/i18n/pt.ts +157 -0
  85. package/src/tool/morse-beacon/i18n/ru.ts +157 -0
  86. package/src/tool/morse-beacon/i18n/sv.ts +157 -0
  87. package/src/tool/morse-beacon/i18n/tr.ts +157 -0
  88. package/src/tool/morse-beacon/i18n/zh.ts +157 -0
  89. package/src/tool/morse-beacon/index.ts +13 -1
  90. package/src/tool/password-generator/i18n/de.ts +166 -0
  91. package/src/tool/password-generator/i18n/fr.ts +1 -1
  92. package/src/tool/password-generator/i18n/id.ts +166 -0
  93. package/src/tool/password-generator/i18n/it.ts +166 -0
  94. package/src/tool/password-generator/i18n/ja.ts +166 -0
  95. package/src/tool/password-generator/i18n/ko.ts +166 -0
  96. package/src/tool/password-generator/i18n/nl.ts +166 -0
  97. package/src/tool/password-generator/i18n/pl.ts +166 -0
  98. package/src/tool/password-generator/i18n/pt.ts +166 -0
  99. package/src/tool/password-generator/i18n/ru.ts +166 -0
  100. package/src/tool/password-generator/i18n/sv.ts +166 -0
  101. package/src/tool/password-generator/i18n/tr.ts +166 -0
  102. package/src/tool/password-generator/i18n/zh.ts +166 -0
  103. package/src/tool/password-generator/index.ts +13 -1
  104. package/src/tool/routes/i18n/de.ts +157 -0
  105. package/src/tool/routes/i18n/id.ts +157 -0
  106. package/src/tool/routes/i18n/it.ts +157 -0
  107. package/src/tool/routes/i18n/ja.ts +157 -0
  108. package/src/tool/routes/i18n/ko.ts +157 -0
  109. package/src/tool/routes/i18n/nl.ts +157 -0
  110. package/src/tool/routes/i18n/pl.ts +157 -0
  111. package/src/tool/routes/i18n/pt.ts +157 -0
  112. package/src/tool/routes/i18n/ru.ts +157 -0
  113. package/src/tool/routes/i18n/sv.ts +157 -0
  114. package/src/tool/routes/i18n/tr.ts +157 -0
  115. package/src/tool/routes/i18n/zh.ts +157 -0
  116. package/src/tool/routes/index.ts +13 -1
  117. package/src/tool/rule-of-three/i18n/de.ts +171 -0
  118. package/src/tool/rule-of-three/i18n/en.ts +1 -1
  119. package/src/tool/rule-of-three/i18n/id.ts +171 -0
  120. package/src/tool/rule-of-three/i18n/it.ts +171 -0
  121. package/src/tool/rule-of-three/i18n/ja.ts +171 -0
  122. package/src/tool/rule-of-three/i18n/ko.ts +171 -0
  123. package/src/tool/rule-of-three/i18n/nl.ts +171 -0
  124. package/src/tool/rule-of-three/i18n/pl.ts +171 -0
  125. package/src/tool/rule-of-three/i18n/pt.ts +171 -0
  126. package/src/tool/rule-of-three/i18n/ru.ts +171 -0
  127. package/src/tool/rule-of-three/i18n/sv.ts +171 -0
  128. package/src/tool/rule-of-three/i18n/tr.ts +171 -0
  129. package/src/tool/rule-of-three/i18n/zh.ts +171 -0
  130. package/src/tool/rule-of-three/index.ts +13 -1
  131. package/src/tool/seo-content-optimizer/i18n/de.ts +136 -0
  132. package/src/tool/seo-content-optimizer/i18n/id.ts +136 -0
  133. package/src/tool/seo-content-optimizer/i18n/it.ts +136 -0
  134. package/src/tool/seo-content-optimizer/i18n/ja.ts +136 -0
  135. package/src/tool/seo-content-optimizer/i18n/ko.ts +136 -0
  136. package/src/tool/seo-content-optimizer/i18n/nl.ts +136 -0
  137. package/src/tool/seo-content-optimizer/i18n/pl.ts +136 -0
  138. package/src/tool/seo-content-optimizer/i18n/pt.ts +136 -0
  139. package/src/tool/seo-content-optimizer/i18n/ru.ts +136 -0
  140. package/src/tool/seo-content-optimizer/i18n/sv.ts +136 -0
  141. package/src/tool/seo-content-optimizer/i18n/tr.ts +136 -0
  142. package/src/tool/seo-content-optimizer/i18n/zh.ts +136 -0
  143. package/src/tool/seo-content-optimizer/index.ts +12 -0
  144. package/src/tool/speed-reader/i18n/de.ts +152 -0
  145. package/src/tool/speed-reader/i18n/es.ts +1 -1
  146. package/src/tool/speed-reader/i18n/id.ts +152 -0
  147. package/src/tool/speed-reader/i18n/it.ts +152 -0
  148. package/src/tool/speed-reader/i18n/ja.ts +152 -0
  149. package/src/tool/speed-reader/i18n/ko.ts +152 -0
  150. package/src/tool/speed-reader/i18n/nl.ts +152 -0
  151. package/src/tool/speed-reader/i18n/pl.ts +152 -0
  152. package/src/tool/speed-reader/i18n/pt.ts +152 -0
  153. package/src/tool/speed-reader/i18n/ru.ts +152 -0
  154. package/src/tool/speed-reader/i18n/sv.ts +152 -0
  155. package/src/tool/speed-reader/i18n/tr.ts +152 -0
  156. package/src/tool/speed-reader/i18n/zh.ts +152 -0
  157. package/src/tool/speed-reader/index.ts +12 -0
  158. package/src/tool/text-pixel-calculator/i18n/de.ts +133 -0
  159. package/src/tool/text-pixel-calculator/i18n/id.ts +133 -0
  160. package/src/tool/text-pixel-calculator/i18n/it.ts +133 -0
  161. package/src/tool/text-pixel-calculator/i18n/ja.ts +133 -0
  162. package/src/tool/text-pixel-calculator/i18n/ko.ts +133 -0
  163. package/src/tool/text-pixel-calculator/i18n/nl.ts +133 -0
  164. package/src/tool/text-pixel-calculator/i18n/pl.ts +133 -0
  165. package/src/tool/text-pixel-calculator/i18n/pt.ts +133 -0
  166. package/src/tool/text-pixel-calculator/i18n/ru.ts +133 -0
  167. package/src/tool/text-pixel-calculator/i18n/sv.ts +133 -0
  168. package/src/tool/text-pixel-calculator/i18n/tr.ts +133 -0
  169. package/src/tool/text-pixel-calculator/i18n/zh.ts +133 -0
  170. package/src/tool/text-pixel-calculator/index.ts +12 -0
  171. package/src/tool/whatsapp-link/i18n/de.ts +128 -0
  172. package/src/tool/whatsapp-link/i18n/es.ts +1 -1
  173. package/src/tool/whatsapp-link/i18n/id.ts +128 -0
  174. package/src/tool/whatsapp-link/i18n/it.ts +128 -0
  175. package/src/tool/whatsapp-link/i18n/ja.ts +128 -0
  176. package/src/tool/whatsapp-link/i18n/ko.ts +128 -0
  177. package/src/tool/whatsapp-link/i18n/nl.ts +128 -0
  178. package/src/tool/whatsapp-link/i18n/pl.ts +128 -0
  179. package/src/tool/whatsapp-link/i18n/pt.ts +128 -0
  180. package/src/tool/whatsapp-link/i18n/ru.ts +128 -0
  181. package/src/tool/whatsapp-link/i18n/sv.ts +128 -0
  182. package/src/tool/whatsapp-link/i18n/tr.ts +128 -0
  183. package/src/tool/whatsapp-link/i18n/zh.ts +128 -0
  184. package/src/tool/whatsapp-link/index.ts +12 -0
@@ -0,0 +1,133 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
3
+ import type { TextPixelCalculatorUI } from '../ui';
4
+
5
+ const faqData = [
6
+ {
7
+ question: 'Metnin piksel genişliğini çevrimiçi olarak nasıl hesaplarım?',
8
+ answer: 'Metninizi giriş kutusuna yapıştırın, yazı tipini ve boyutunu yapılandırın; araç, tam piksel genişliğini döndürmek için otomatik olarak tarayıcı Canvas API\'sini kullanacaktır.',
9
+ },
10
+ {
11
+ question: 'Piksel genişliği neden yazı tipleri arasında değişir?',
12
+ answer: "Çoğu yazı tipi orantılıdır, yani her karakterin farklı bir genişliği vardır. Örneğin, standart bir sans-serif yazı tipinde büyük 'M' harfi her zaman küçük 'i' harfinden daha geniştir.",
13
+ },
14
+ {
15
+ question: 'Karakter ölçmekle piksel ölçmek aynı şey midir?',
16
+ answer: 'Hayır. Karakter ölçmek size dizge uzunluğunu verirken, piksel ölçmek kapladığı görsel alanı verir. Bu, bir web tasarımında metnin kapsayıcısından taşmamasını sağlamak için çok önemlidir.',
17
+ },
18
+ {
19
+ question: 'Herhangi bir Google Fonts yazı tipini kullanabilir miyim?',
20
+ answer: 'Evet, yazı tipi işletim sisteminizde yüklü olduğu veya mevcut sayfada yüklendiği sürece araç boyutlarını doğru bir şekilde ölçecektir.',
21
+ },
22
+ {
23
+ question: 'Özel metinleri veya kod parçacıklarını işlemek güvenli midir?',
24
+ answer: 'Evet. Hesaplayıcı tamamen yerel olarak çalışır. Harici sunuculara hiçbir veri gönderilmez, projeleriniz için tam gizlilik garanti edilir.',
25
+ },
26
+ ];
27
+
28
+ const howToData = [
29
+ { name: 'Metni girin', text: 'Ölçmek istediğiniz metni giriş alanına yazın veya yapıştırın.' },
30
+ { name: 'Yazı tipini yapılandırın', text: 'Yazı tipi ailesini, piksel cinsinden boyutunu, ağırlığını ve italik olup olmadığını ayarlayın.' },
31
+ { name: 'Sonucu okuyun', text: 'Piksel genişliği ve karakter sayısı gerçek zamanlı olarak güncellenir.' },
32
+ { name: 'Değeri kopyalayın', text: 'Piksel sayısını panoya kaydetmek için "Genişliği Kopyala"ya tıklayın.' },
33
+ ];
34
+
35
+ const faqSchema: WithContext<FAQPage> = {
36
+ '@context': 'https://schema.org',
37
+ '@type': 'FAQPage',
38
+ mainEntity: faqData.map((item) => ({
39
+ '@type': 'Question',
40
+ name: item.question,
41
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
42
+ })),
43
+ };
44
+
45
+ const howToSchema: WithContext<HowTo> = {
46
+ '@context': 'https://schema.org',
47
+ '@type': 'HowTo',
48
+ name: 'Metin genişliği piksel cinsinden nasıl ölçülür?',
49
+ step: howToData.map((s) => ({ '@type': 'HowToStep', name: s.name, text: s.text })),
50
+ };
51
+
52
+ const appSchema: WithContext<SoftwareApplication> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'SoftwareApplication',
55
+ name: 'Metin Piksel Genişliği Hesaplayıcı',
56
+ applicationCategory: 'UtilitiesApplication',
57
+ operatingSystem: 'Web',
58
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
59
+ description: 'Herhangi bir metnin yazı tipine, boyutuna ve stiline göre piksel genişliğini doğru bir şekilde hesaplayın.',
60
+ };
61
+
62
+ const ui: TextPixelCalculatorUI = {
63
+ textLabel: 'Ölçülecek metin',
64
+ textPlaceholder: 'Ölçmek istediğiniz metni buraya yazın veya yapıştırın...',
65
+ defaultText: 'Merhaba Dünya',
66
+ fontLabel: 'Yazı tipi ailesi',
67
+ sizeLabel: 'Boyut (px)',
68
+ weightLabel: 'Ağırlık',
69
+ italicLabel: 'İtalik',
70
+ widthLabel: 'Genişlik (piksel)',
71
+ charsLabel: 'Karakter',
72
+ previewLabel: 'Görsel önizleme',
73
+ copyBtn: 'Genişliği Kopyala',
74
+ resetBtn: 'Sıfırla',
75
+ copyDone: 'Genişlik kopyalandı',
76
+ };
77
+
78
+ export const content: ToolLocaleContent<TextPixelCalculatorUI> = {
79
+ slug: 'metin-piksel-genisligi-hesaplayici',
80
+ title: 'Metin Piksel Genişliği Hesaplayıcı',
81
+ description: 'Yazı tipi, boyut ve stile göre herhangi bir metnin kaç piksel genişliğinde olduğunu doğru bir şekilde hesaplayın. Tasarımcılar ve geliştiriciler için ücretsiz araç.',
82
+ ui,
83
+ faqTitle: 'Sıkça Sorulan Sorular',
84
+ faq: faqData,
85
+ howTo: howToData,
86
+ bibliographyTitle: 'Kaynaklar',
87
+ bibliography: [
88
+ { name: 'W3C: CSS Text Module Level 3', url: 'https://www.w3.org/TR/css-text-3/' },
89
+ { name: 'Google Fonts: Understanding variable fonts', url: 'https://fonts.google.com/knowledge/glossary/variable_fonts' },
90
+ ],
91
+ schemas: [faqSchema, howToSchema, appSchema],
92
+ seo: [
93
+ { type: 'title', level: 2, text: 'Herhangi bir metnin tam piksel genişliğini ölçün' },
94
+ {
95
+ type: 'paragraph',
96
+ html: 'Metniniz kapsayıcısından taşıyor mu? Bir başlığı oluşturmadan önce ne kadar yer kapladığını bilmeniz mi gerekiyor? <strong>Tarayıcı Canvas API\'si</strong>, herhangi bir metin dizisinin tam genişliğini DOM\'da oluşturmadan piksel hassasiyetiyle ölçmenize olanak tanır.',
97
+ },
98
+ { type: 'title', level: 3, text: 'Neden karakter sayımı yeterli değildir?' },
99
+ {
100
+ type: 'paragraph',
101
+ html: 'Modern yazı tipleri <strong>orantılıdır</strong>: her glifin farklı bir genişliği vardır. Bir "W", bir "i"den üç kat daha fazla yer kaplayabilir. Karakter sayısı size metnin kapladığı gerçek görsel alan hakkında hiçbir şey söylemez.',
102
+ },
103
+ {
104
+ type: 'list',
105
+ items: [
106
+ '<strong>Web tasarımı:</strong> Düğmelerde, etiketlerde ve tablo hücrelerinde taşmayı önleyin.',
107
+ '<strong>SEO:</strong> Arama motorları başlıkları karakter sayısına göre değil, piksellere göre kısaltır.',
108
+ '<strong>Canvas ve PDF:</strong> Programlı olarak metin çizmeden önce tam konumu hesaplayın.',
109
+ '<strong>Tooltip\'ler ve balonlar:</strong> Kapsayıcıları iç metne göre dinamik olarak boyutlandırın.',
110
+ ],
111
+ },
112
+ { type: 'title', level: 3, text: 'Canvas ile ölçüm nasıl çalışır?' },
113
+ {
114
+ type: 'paragraph',
115
+ html: 'Canvas API\'sinin <code>ctx.measureText()</code> yöntemi, o anda aktif olan yazı tipini kullanarak CSS piksel genişliğini yansıtan bir <code>width</code> özelliğine sahip bir <code>TextMetrics</code> nesnesi döndürür. Bu araç, ölçümden önce bağlamı yazı tipiniz, boyutunuz, ağırlığınız ve stilinizle yapılandırır.',
116
+ },
117
+ {
118
+ type: 'code',
119
+ ariaLabel: 'Canvas measureText örneği',
120
+ code: "const ctx = document.createElement('canvas').getContext('2d');\nctx.font = '700 16px Inter, system-ui, sans-serif';\nconst width = ctx.measureText('Merhaba Dünya').width; // örn. 74.5",
121
+ },
122
+ { type: 'title', level: 3, text: 'Gizlilik ve yerel işleme' },
123
+ {
124
+ type: 'paragraph',
125
+ html: 'Tüm hesaplamalar tarayıcınızda gerçekleşir. Cihazınızdan hiçbir metin, kod parçacığı veya özel veri çıkmaz.',
126
+ },
127
+ {
128
+ type: 'tip',
129
+ title: 'Google Fonts yazı tipleri',
130
+ html: 'Bir Google Fonts yazı tipini doğru bir şekilde ölçmek için önce sayfada yüklendiğinden veya sisteminizde yüklü olduğundan emin olun. Aksi takdirde tarayıcı yedek bir yazı tipine dönecektir ve sonuç farklı olacaktır.',
131
+ },
132
+ ],
133
+ };
@@ -0,0 +1,133 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
3
+ import type { TextPixelCalculatorUI } from '../ui';
4
+
5
+ const faqData = [
6
+ {
7
+ question: '如何在线计算文本的像素宽度?',
8
+ answer: '将您的文本粘贴到输入框中,配置字体和大小,工具将自动使用浏览器 Canvas API 返回精确的像素宽度。',
9
+ },
10
+ {
11
+ question: '为什么不同字体的像素宽度不同?',
12
+ answer: '大多数字体都是比例字体,这意味着每个字符都有不同的宽度。例如,在标准的无衬线字体中,大写字母“M”总是比小写字母“i”宽。',
13
+ },
14
+ {
15
+ question: '测量字符数和测量像素是一回事吗?',
16
+ answer: '不是。测量字符数得到的是字符串长度,而测量像素得到的是它占用的视觉空间。这对于确保网页设计中文本不会超出其容器至关重要。',
17
+ },
18
+ {
19
+ question: '我可以使用任何 Google Fonts 字体吗?',
20
+ answer: '是的,只要字体安装在您的操作系统上或加载在当前页面上,工具就能准确测量其尺寸。',
21
+ },
22
+ {
23
+ question: '处理私有文本或代码片段安全吗?',
24
+ answer: '安全。计算器完全在本地运行。没有任何数据被发送到外部服务器,保证了您项目的完全隐私。',
25
+ },
26
+ ];
27
+
28
+ const howToData = [
29
+ { name: '输入文本', text: '在输入区域键入或粘贴您想要测量的文本。' },
30
+ { name: '配置字体', text: '设置字体系列、像素大小、字重以及是否斜体。' },
31
+ { name: '读取结果', text: '像素宽度和字符计数会进行实时更新。' },
32
+ { name: '复制数值', text: '点击“复制宽度”将像素值保存到剪贴板。' },
33
+ ];
34
+
35
+ const faqSchema: WithContext<FAQPage> = {
36
+ '@context': 'https://schema.org',
37
+ '@type': 'FAQPage',
38
+ mainEntity: faqData.map((item) => ({
39
+ '@type': 'Question',
40
+ name: item.question,
41
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
42
+ })),
43
+ };
44
+
45
+ const howToSchema: WithContext<HowTo> = {
46
+ '@context': 'https://schema.org',
47
+ '@type': 'HowTo',
48
+ name: '如何测量文本的像素宽度',
49
+ step: howToData.map((s) => ({ '@type': 'HowToStep', name: s.name, text: s.text })),
50
+ };
51
+
52
+ const appSchema: WithContext<SoftwareApplication> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'SoftwareApplication',
55
+ name: '文本像素宽度计算器',
56
+ applicationCategory: 'UtilitiesApplication',
57
+ operatingSystem: 'Web',
58
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'CNY' },
59
+ description: '根据字体、大小和样式精确计算任何文本的像素宽度。',
60
+ };
61
+
62
+ const ui: TextPixelCalculatorUI = {
63
+ textLabel: '待测量文本',
64
+ textPlaceholder: '在此处键入或粘贴您想要测量的文本...',
65
+ defaultText: '你好,世界',
66
+ fontLabel: '字体系列',
67
+ sizeLabel: '大小 (px)',
68
+ weightLabel: '字重',
69
+ italicLabel: '斜体',
70
+ widthLabel: '宽度 (像素)',
71
+ charsLabel: '字符数',
72
+ previewLabel: '视觉预览',
73
+ copyBtn: '复制宽度',
74
+ resetBtn: '重置',
75
+ copyDone: '宽度已复制',
76
+ };
77
+
78
+ export const content: ToolLocaleContent<TextPixelCalculatorUI> = {
79
+ slug: 'text-pixel-width-calculator',
80
+ title: '文本像素宽度计算器',
81
+ description: '根据字体、大小和样式精确计算任何文本在像素上的宽度。专为设计师和开发者提供的免费工具。',
82
+ ui,
83
+ faqTitle: '常见问题',
84
+ faq: faqData,
85
+ howTo: howToData,
86
+ bibliographyTitle: '参考文献',
87
+ bibliography: [
88
+ { name: 'W3C: CSS 文本模块第 3 级', url: 'https://www.w3.org/TR/css-text-3/' },
89
+ { name: 'Google Fonts: 了解可变字体', url: 'https://fonts.google.com/knowledge/glossary/variable_fonts' },
90
+ ],
91
+ schemas: [faqSchema, howToSchema, appSchema],
92
+ seo: [
93
+ { type: 'title', level: 2, text: '测量任何文本的精确像素宽度' },
94
+ {
95
+ type: 'paragraph',
96
+ html: '您的文本是否超出了容器?在渲染标题之前需要知道它占用了多少空间?<strong>浏览器 Canvas API</strong> 允许您以像素级精度测量任何文本字符串的精确宽度,而无需将其渲染到 DOM 中。',
97
+ },
98
+ { type: 'title', level: 3, text: '为什么只计算字符数是不够的' },
99
+ {
100
+ type: 'paragraph',
101
+ html: '现代字体是<strong>比例字体</strong>:每个字形都有不同的宽度。一个“W”占用的空间可能是“i”的三倍。字符数无法告诉您文本实际占用的视觉空间。',
102
+ },
103
+ {
104
+ type: 'list',
105
+ items: [
106
+ '<strong>网页设计:</strong>防止按钮、标签和表格单元格中的文本溢出。',
107
+ '<strong>SEO:</strong>搜索引擎是按像素而不是字符截断标题。',
108
+ '<strong>Canvas 和 PDF:</strong>在以编程方式绘制文本之前计算精确位置。',
109
+ '<strong>工具提示和气泡:</strong>根据内部文本动态调整容器大小。',
110
+ ],
111
+ },
112
+ { type: 'title', level: 3, text: 'Canvas 测量如何工作' },
113
+ {
114
+ type: 'paragraph',
115
+ html: 'Canvas API 的 <code>ctx.measureText()</code> 方法会返回一个 <code>TextMetrics</code> 对象,其中的 <code>width</code> 属性反映了使用当前有效字体时的 CSS 像素宽度。该工具在测量之前会根据您选择的字体、大小、字重和样式配置上下文。',
116
+ },
117
+ {
118
+ type: 'code',
119
+ ariaLabel: 'Canvas measureText 示例',
120
+ code: "const ctx = document.createElement('canvas').getContext('2d');\nctx.font = '700 16px Inter, system-ui, sans-serif';\nconst width = ctx.measureText('你好,世界').width; // 例如 74.5",
121
+ },
122
+ { type: 'title', level: 3, text: '隐私和本地处理' },
123
+ {
124
+ type: 'paragraph',
125
+ html: '所有计算都在您的浏览器中进行。任何文本、代码片段或私人数据都不会离开您的设备。',
126
+ },
127
+ {
128
+ type: 'tip',
129
+ title: 'Google Fonts 字体',
130
+ html: '为了准确测量 Google Fonts 字体,请首先确保它已在页面加载或安装在您的系统中。否则,浏览器将回退到备用字体,结果会有所不同。',
131
+ },
132
+ ],
133
+ };
@@ -11,6 +11,18 @@ export const textPixelCalculator: ToolsToolEntry<TextPixelCalculatorUI> = {
11
11
  es: () => import('./i18n/es').then((m) => m.content),
12
12
  en: () => import('./i18n/en').then((m) => m.content),
13
13
  fr: () => import('./i18n/fr').then((m) => m.content),
14
+ de: () => import('./i18n/de').then((m) => m.content),
15
+ it: () => import('./i18n/it').then((m) => m.content),
16
+ pt: () => import('./i18n/pt').then((m) => m.content),
17
+ nl: () => import('./i18n/nl').then((m) => m.content),
18
+ pl: () => import('./i18n/pl').then((m) => m.content),
19
+ tr: () => import('./i18n/tr').then((m) => m.content),
20
+ id: () => import('./i18n/id').then((m) => m.content),
21
+ sv: () => import('./i18n/sv').then((m) => m.content),
22
+ ru: () => import('./i18n/ru').then((m) => m.content),
23
+ ja: () => import('./i18n/ja').then((m) => m.content),
24
+ ko: () => import('./i18n/ko').then((m) => m.content),
25
+ zh: () => import('./i18n/zh').then((m) => m.content),
14
26
  },
15
27
  };
16
28
 
@@ -0,0 +1,128 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
3
+ import type { WhatsappLinkUI } from '../ui';
4
+
5
+ const faqData = [
6
+ {
7
+ question: 'Wie erstelle ich einen WhatsApp-Link?',
8
+ answer: 'Um Ihren Link zu erstellen, geben Sie Ihre Mobilnummer einschließlich der Ländervorwahl ein. Geben Sie beispielsweise für Deutschland zuerst 49 ein, gefolgt von Ihrer lokalen Nummer. Sie können eine optionale Nachricht hinzufügen, und das Tool generiert den fertigen wa.me-Link, der zum Kopieren bereit ist.',
9
+ },
10
+ {
11
+ question: 'Kann ich eine lange vorformulierte Nachricht hinzufügen?',
12
+ answer: 'Ja. Sie können eine Nachricht anhängen, die automatisch im Chat-Feld erscheint, wenn jemand auf Ihren Link klickt. Das Tool verwendet die URL-Kodierung, um Leerzeichen, Akzente und Emojis zu unterstützen, ohne die URL zu beschädigen.',
13
+ },
14
+ {
15
+ question: 'Wie verwende ich den generierten QR-Code?',
16
+ answer: 'Sobald ein gültiger Link generiert wurde, erscheint die Schaltfläche „QR anzeigen“. Der QR-Code enthält Ihre Link-URL. Klicken Sie mit der rechten Maustaste darauf und wählen Sie „Bild speichern unter“, um eine saubere, hochauflösende Datei für Visitenkarten, Poster oder soziale Medien herunterzuladen.',
17
+ },
18
+ {
19
+ question: 'Wo landen meine Daten?',
20
+ answer: 'Der Generator verarbeitet alles auf der Client-Seite, direkt in Ihrem Browser. Ihre Telefonnummer und die vorformulierte Nachricht werden niemals an einen Server gesendet oder in einer Datenbank gespeichert.',
21
+ },
22
+ ];
23
+
24
+ const howToData = [
25
+ { name: 'Ländervorwahl auswählen', text: 'Wählen Sie Ihre Ländervorwahl aus dem Dropdown-Menü aus und geben Sie Ihre Telefonnummer ohne die Vorwahl ein.' },
26
+ { name: 'Optionale Nachricht hinzufügen', text: 'Schreiben Sie einen vorformulierten Text, der erscheint, wenn jemand den Link öffnet und auf Senden tippt.' },
27
+ { name: 'Link generieren', text: 'Drücken Sie die grüne Schaltfläche, um Ihre direkte wa.me-URL zum Teilen zu erhalten.' },
28
+ { name: 'QR-Code teilen oder drucken', text: 'Kopieren Sie den Link, testen Sie den Chat oder laden Sie den QR-Code für Karten und Drucke herunter.' },
29
+ ];
30
+
31
+ const faqSchema: WithContext<FAQPage> = {
32
+ '@context': 'https://schema.org',
33
+ '@type': 'FAQPage',
34
+ mainEntity: faqData.map((item) => ({
35
+ '@type': 'Question',
36
+ name: item.question,
37
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
38
+ })),
39
+ };
40
+
41
+ const howToSchema: WithContext<HowTo> = {
42
+ '@context': 'https://schema.org',
43
+ '@type': 'HowTo',
44
+ name: 'So erstellen Sie einen direkten WhatsApp-Link',
45
+ step: howToData.map((s) => ({ '@type': 'HowToStep', name: s.name, text: s.text })),
46
+ };
47
+
48
+ const appSchema: WithContext<SoftwareApplication> = {
49
+ '@context': 'https://schema.org',
50
+ '@type': 'SoftwareApplication',
51
+ name: 'WhatsApp Link Generator',
52
+ applicationCategory: 'UtilitiesApplication',
53
+ operatingSystem: 'Web',
54
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
55
+ description: 'Erstellen Sie direkte WhatsApp-Chat-Links mit vorformulierten Nachrichten und QR-Codes. Kostenloses Tool, keine Registrierung, 100 % privat.',
56
+ };
57
+
58
+ const ui: WhatsappLinkUI = {
59
+ phoneLabel: 'WhatsApp-Telefonnummer',
60
+ phonePlaceholder: '170 0000000',
61
+ messageLabel: 'Eröffnungsnachricht (optional)',
62
+ messagePlaceholder: 'Hallo! Ich hätte gerne mehr Informationen über Ihren Service...',
63
+ generateBtn: 'Link generieren',
64
+ resultLabel: 'Direkter Link generiert',
65
+ copyTitle: 'In Zwischenablage kopieren',
66
+ copyDone: 'Kopiert!',
67
+ testBtn: 'Chat testen',
68
+ qrShow: 'QR anzeigen',
69
+ qrHide: 'QR ausblenden',
70
+ errorPhone: 'Bitte geben Sie eine gültige Telefonnummer ein.',
71
+ defaultPrefix: '49',
72
+ };
73
+
74
+ export const content: ToolLocaleContent<WhatsappLinkUI> = {
75
+ slug: 'whatsapp-link-generator-de',
76
+ title: 'WhatsApp Link Generator mit QR',
77
+ description: 'Erstellen Sie direkte WhatsApp-Chat-Links mit vorformulierter Nachricht und QR-Code. Kostenloses Tool, keine Registrierung, 100 % privat.',
78
+ ui,
79
+ faqTitle: 'Häufig gestellte Fragen',
80
+ faq: faqData,
81
+ howTo: howToData,
82
+ bibliographyTitle: 'Referenzen',
83
+ bibliography: [
84
+ { name: 'So verwenden Sie die Funktion „Click to Chat“ — WhatsApp Hilfebereich', url: 'https://faq.whatsapp.com/591339899867293' },
85
+ { name: 'API Click to chat: Parameter und Formate — WhatsApp', url: 'https://faq.whatsapp.com/425559092497645' },
86
+ ],
87
+ schemas: [faqSchema, howToSchema, appSchema],
88
+ seo: [
89
+ { type: 'title', level: 2, text: 'Generieren Sie kurze Direktlinks für WhatsApp' },
90
+ {
91
+ type: 'paragraph',
92
+ html: 'Müssen Kunden oder Follower Sie auf WhatsApp kontaktieren, ohne Ihre Nummer zuerst zu speichern? Unser <strong>wa.me Link-Creator</strong> löst dieses Problem, indem er einen Link generiert, der sofort einen direkten Chat öffnet, ohne dass weitere Schritte erforderlich sind.',
93
+ },
94
+ { type: 'title', level: 3, text: 'Wofür ist der wa.me WhatsApp Shortener gedacht?' },
95
+ {
96
+ type: 'paragraph',
97
+ html: 'WhatsApp bietet eine API namens „Click to Chat“ an. Über eine spezielle URL kann jeder Nutzer einen neuen Chat mit Ihnen eröffnen, ohne Sie vorher als Kontakt hinzufügen zu müssen, sowohl vom Handy als auch von WhatsApp Web aus.',
98
+ },
99
+ {
100
+ type: 'list',
101
+ items: [
102
+ '<strong>Mehr Konversionen:</strong> Ein „Kontakt über WhatsApp“-Button in Ihrem Shop reduziert Hürden und steigert die Verkäufe.',
103
+ '<strong>Vorformulierte Nachricht:</strong> Der Nutzer drückt einfach auf „Senden“. Beispiel: „Hallo! Ich komme von Instagram und möchte das Angebot in Anspruch nehmen.“',
104
+ '<strong>Automatischer QR-Code:</strong> Laden Sie den QR-Code für Visitenkarten, Poster oder Social-Media-Posts herunter.',
105
+ ],
106
+ },
107
+ { type: 'title', level: 3, text: 'Wie funktioniert die Link-Generierung?' },
108
+ {
109
+ type: 'paragraph',
110
+ html: 'Das Tool verknüpft die Ländervorwahl und die bereinigte Telefonnummer und hängt sie dann zusammen mit dem über <em>URL-Kodierung</em> konvertierten Nachrichtensuchparameter an die offizielle WhatsApp-API an.',
111
+ },
112
+ {
113
+ type: 'code',
114
+ ariaLabel: 'WhatsApp URL-Format',
115
+ code: 'https://wa.me/49XXXXXXXXX\nhttps://wa.me/49XXXXXXXXX?text=%C2%A1Hallo!%20Ich%20m%C3%B6chte...',
116
+ },
117
+ { type: 'title', level: 3, text: 'Garantierte Privatsphäre und lokale Verarbeitung' },
118
+ {
119
+ type: 'paragraph',
120
+ html: 'Die gesamte Link-Erstellung findet in Ihrem Browser über JavaScript statt. Kein Server zeichnet Ihre eingegebenen Telefonnummern oder Nachrichten auf, speichert sie oder liest sie. Ihre Privatsphäre ist vollständig geschützt.',
121
+ },
122
+ {
123
+ type: 'tip',
124
+ title: 'Bedeutung der Ländervorwahl',
125
+ html: 'Damit WhatsApp die Nachricht korrekt weiterleitet, ist die Ländervorwahl zwingend erforderlich. Für Deutschland ist sie <strong>49</strong>, gefolgt von Ihrer Mobilnummer, ohne Leerzeichen oder das +-Symbol. Das Endergebnis wäre zum Beispiel <code>4917XXXXXXXX</code>.',
126
+ },
127
+ ],
128
+ };
@@ -72,7 +72,7 @@ const ui: WhatsappLinkUI = {
72
72
  };
73
73
 
74
74
  export const content: ToolLocaleContent<WhatsappLinkUI> = {
75
- slug: 'generador-enlaces-whatsapp',
75
+ slug: 'generador-enlace-whatsapp',
76
76
  title: 'Generador de Enlace WhatsApp con QR',
77
77
  description: 'Crea enlaces directos a tu chat de WhatsApp con mensaje predefinido y código QR. Herramienta gratuita, sin registro y 100% privada.',
78
78
  ui,
@@ -0,0 +1,128 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
3
+ import type { WhatsappLinkUI } from '../ui';
4
+
5
+ const faqData = [
6
+ {
7
+ question: 'Bagaimana cara membuat tautan WhatsApp?',
8
+ answer: 'Untuk membuat tautan Anda, masukkan nomor ponsel Anda termasuk kode negara. Misalnya, untuk Spanyol masukkan 34 terlebih dahulu, untuk Indonesia 62, diikuti dengan nomor lokal Anda. Anda dapat menambahkan pesan opsional dan alat ini akan menghasilkan tautan wa.me final yang siap disalin.',
9
+ },
10
+ {
11
+ question: 'Dapatkah saya menambahkan pesan panjang yang sudah diisi sebelumnya?',
12
+ answer: 'Ya. Anda dapat melampirkan pesan yang akan muncul secara otomatis di kotak obrolan saat seseorang mengklik tautan Anda. Alat ini menggunakan encoding URL untuk mendukung spasi, aksen, dan emoji tanpa merusak URL.',
13
+ },
14
+ {
15
+ question: 'Bagaimana cara menggunakan kode QR yang dihasilkan?',
16
+ answer: 'Setelah tautan valid dibuat, tombol "Tampilkan QR" muncul. Kode QR berisi URL tautan Anda. Klik kanan padanya dan pilih "Simpan gambar sebagai" untuk mengunduh file bersih beresolusi tinggi untuk kartu nama, poster, atau media sosial.',
17
+ },
18
+ {
19
+ question: 'Ke mana data saya pergi?',
20
+ answer: 'Generator memproses semuanya di sisi klien, langsung di browser Anda. Nomor telepon dan pesan yang Anda isi tidak pernah dikirim ke server mana pun atau disimpan dalam database apa pun.',
21
+ },
22
+ ];
23
+
24
+ const howToData = [
25
+ { name: 'Pilih prefiks', text: 'Pilih kode negara Anda dari dropdown dan masukkan nomor telepon Anda tanpa prefiks.' },
26
+ { name: 'Tambahkan pesan opsional', text: 'Tulis teks yang sudah diisi sebelumnya yang akan muncul saat seseorang membuka tautan dan mengetuk Kirim.' },
27
+ { name: 'Buat tautan', text: 'Tekan tombol hijau untuk mendapatkan URL wa.me langsung yang siap dibagikan.' },
28
+ { name: 'Bagikan atau cetak QR', text: 'Salin tautan, uji obrolan, atau unduh kode QR untuk kartu dan pencetakan.' },
29
+ ];
30
+
31
+ const faqSchema: WithContext<FAQPage> = {
32
+ '@context': 'https://schema.org',
33
+ '@type': 'FAQPage',
34
+ mainEntity: faqData.map((item) => ({
35
+ '@type': 'Question',
36
+ name: item.question,
37
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
38
+ })),
39
+ };
40
+
41
+ const howToSchema: WithContext<HowTo> = {
42
+ '@context': 'https://schema.org',
43
+ '@type': 'HowTo',
44
+ name: 'Cara membuat tautan WhatsApp langsung',
45
+ step: howToData.map((s) => ({ '@type': 'HowToStep', name: s.name, text: s.text })),
46
+ };
47
+
48
+ const appSchema: WithContext<SoftwareApplication> = {
49
+ '@context': 'https://schema.org',
50
+ '@type': 'SoftwareApplication',
51
+ name: 'Pembuat Tautan WhatsApp',
52
+ applicationCategory: 'UtilitiesApplication',
53
+ operatingSystem: 'Web',
54
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
55
+ description: 'Buat tautan obrolan WhatsApp langsung dengan pesan yang sudah diisi sebelumnya dan kode QR. Alat gratis, tanpa pendaftaran, 100% pribadi.',
56
+ };
57
+
58
+ const ui: WhatsappLinkUI = {
59
+ phoneLabel: 'Nomor Telepon WhatsApp',
60
+ phonePlaceholder: '0812 3456 789',
61
+ messageLabel: 'Pesan pembuka (opsional)',
62
+ messagePlaceholder: 'Halo! Saya ingin informasi lebih lanjut tentang layanan Anda...',
63
+ generateBtn: 'Buat Tautan',
64
+ resultLabel: 'Tautan Langsung Berhasil Dibuat',
65
+ copyTitle: 'Salin ke papan klip',
66
+ copyDone: 'Disalin!',
67
+ testBtn: 'Uji Obrolan',
68
+ qrShow: 'Tampilkan QR',
69
+ qrHide: 'Sembunyikan QR',
70
+ errorPhone: 'Harap masukkan nomor telepon yang valid.',
71
+ defaultPrefix: '62',
72
+ };
73
+
74
+ export const content: ToolLocaleContent<WhatsappLinkUI> = {
75
+ slug: 'pembuat-tautan-whatsapp',
76
+ title: 'Pembuat Tautan WhatsApp dengan QR',
77
+ description: 'Buat tautan obrolan WhatsApp langsung dengan pesan yang sudah diisi sebelumnya dan kode QR. Alat gratis, tanpa pendaftaran, 100% pribadi.',
78
+ ui,
79
+ faqTitle: 'Pertanyaan yang Sering Diajukan',
80
+ faq: faqData,
81
+ howTo: howToData,
82
+ bibliographyTitle: 'Referensi',
83
+ bibliography: [
84
+ { name: 'Cara menggunakan fitur klik untuk chat — Pusat Bantuan WhatsApp', url: 'https://faq.whatsapp.com/591339899867293' },
85
+ { name: 'API Klik untuk chat: parameter dan format — WhatsApp', url: 'https://faq.whatsapp.com/425559092497645' },
86
+ ],
87
+ schemas: [faqSchema, howToSchema, appSchema],
88
+ seo: [
89
+ { type: 'title', level: 2, text: 'Buat tautan langsung pendek untuk WhatsApp' },
90
+ {
91
+ type: 'paragraph',
92
+ html: 'Butuh pelanggan atau pengikut untuk menghubungi Anda di WhatsApp tanpa harus menyimpan nomor Anda terlebih dahulu? <strong>Pembuat tautan wa.me</strong> kami mengatasi hal ini dengan menghasilkan tautan yang membuka obrolan langsung secara instan, tanpa langkah awal.',
93
+ },
94
+ { type: 'title', level: 3, text: 'Untuk apa penyingkat WhatsApp wa.me?' },
95
+ {
96
+ type: 'paragraph',
97
+ html: 'WhatsApp menawarkan API yang disebut "Klik untuk Chat". Menggunakan URL khusus, setiap pengguna dapat membuka obrolan baru dengan Anda tanpa perlu menambahkan Anda sebagai kontak terlebih dahulu, baik dari ponsel maupun WhatsApp Web.',
98
+ },
99
+ {
100
+ type: 'list',
101
+ items: [
102
+ '<strong>Lebih banyak konversi:</strong> Tombol "Hubungi via WhatsApp" di toko Anda mengurangi hambatan dan meningkatkan penjualan.',
103
+ '<strong>Pesan yang sudah diisi:</strong> Pengguna hanya perlu menekan "Kirim". Contoh: "Halo! Saya datang dari Instagram dan ingin mengklaim penawarannya."',
104
+ '<strong>Kode QR otomatis:</strong> Unduh QR untuk kartu nama, poster, atau postingan media sosial.',
105
+ ],
106
+ },
107
+ { type: 'title', level: 3, text: 'Bagaimana cara kerja pembuatan tautan?' },
108
+ {
109
+ type: 'paragraph',
110
+ html: 'Alat ini menggabungkan prefiks internasional dan nomor telepon yang bersih, lalu menambahkannya ke API resmi WhatsApp bersama parameter pesan yang dikonversi melalui <em>url-encoding</em>.',
111
+ },
112
+ {
113
+ type: 'code',
114
+ ariaLabel: 'Format URL WhatsApp',
115
+ code: 'https://wa.me/62XXXXXXXXX\nhttps://wa.me/62XXXXXXXXX?text=%C2%A1Halo!%20Saya%20ingin...',
116
+ },
117
+ { type: 'title', level: 3, text: 'Privasi terjamin dan pemrosesan lokal' },
118
+ {
119
+ type: 'paragraph',
120
+ html: 'Semua pembuatan tautan terjadi di browser Anda melalui JavaScript. Tidak ada server yang mencatat, menyimpan, atau membaca nomor telepon atau pesan yang Anda masukkan. Privasi Anda sepenuhnya terlindungi.',
121
+ },
122
+ {
123
+ type: 'tip',
124
+ title: 'Pentingnya prefiks internasional',
125
+ html: 'Agar WhatsApp dapat merutekan pesan dengan benar, kode negara wajib diisi. Untuk Indonesia adalah <strong>62</strong>, diikuti oleh nomor ponsel, tanpa spasi atau simbol +. Hasil akhirnya, misalnya, adalah <code>628XXXXXXXXX</code>.',
126
+ },
127
+ ],
128
+ };