@jjlmoya/utils-audiovisual 1.6.0 → 1.8.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 (175) hide show
  1. package/package.json +59 -58
  2. package/src/category/i18n/de.ts +198 -0
  3. package/src/category/i18n/fr.ts +1 -1
  4. package/src/category/i18n/id.ts +198 -0
  5. package/src/category/i18n/it.ts +198 -0
  6. package/src/category/i18n/ja.ts +198 -0
  7. package/src/category/i18n/ko.ts +198 -0
  8. package/src/category/i18n/nl.ts +198 -0
  9. package/src/category/i18n/pl.ts +198 -0
  10. package/src/category/i18n/pt.ts +198 -0
  11. package/src/category/i18n/ru.ts +198 -0
  12. package/src/category/i18n/sv.ts +198 -0
  13. package/src/category/i18n/tr.ts +198 -0
  14. package/src/category/i18n/zh.ts +198 -0
  15. package/src/category/index.ts +31 -3
  16. package/src/tests/i18n_coverage.test.ts +36 -0
  17. package/src/tests/schemas_fulfillment.test.ts +23 -0
  18. package/src/tests/title_quality.test.ts +55 -0
  19. package/src/tool/chromaticLens/i18n/de.ts +246 -0
  20. package/src/tool/chromaticLens/i18n/en.ts +1 -1
  21. package/src/tool/chromaticLens/i18n/es.ts +1 -1
  22. package/src/tool/chromaticLens/i18n/fr.ts +1 -1
  23. package/src/tool/chromaticLens/i18n/id.ts +246 -0
  24. package/src/tool/chromaticLens/i18n/it.ts +246 -0
  25. package/src/tool/chromaticLens/i18n/ja.ts +246 -0
  26. package/src/tool/chromaticLens/i18n/ko.ts +246 -0
  27. package/src/tool/chromaticLens/i18n/nl.ts +246 -0
  28. package/src/tool/chromaticLens/i18n/pl.ts +246 -0
  29. package/src/tool/chromaticLens/i18n/pt.ts +246 -0
  30. package/src/tool/chromaticLens/i18n/ru.ts +246 -0
  31. package/src/tool/chromaticLens/i18n/sv.ts +246 -0
  32. package/src/tool/chromaticLens/i18n/tr.ts +246 -0
  33. package/src/tool/chromaticLens/i18n/zh.ts +246 -0
  34. package/src/tool/chromaticLens/index.ts +15 -7
  35. package/src/tool/collageMaker/i18n/de.ts +233 -0
  36. package/src/tool/collageMaker/i18n/en.ts +1 -1
  37. package/src/tool/collageMaker/i18n/es.ts +1 -1
  38. package/src/tool/collageMaker/i18n/fr.ts +1 -1
  39. package/src/tool/collageMaker/i18n/id.ts +233 -0
  40. package/src/tool/collageMaker/i18n/it.ts +233 -0
  41. package/src/tool/collageMaker/i18n/ja.ts +233 -0
  42. package/src/tool/collageMaker/i18n/ko.ts +233 -0
  43. package/src/tool/collageMaker/i18n/nl.ts +233 -0
  44. package/src/tool/collageMaker/i18n/pl.ts +233 -0
  45. package/src/tool/collageMaker/i18n/pt.ts +233 -0
  46. package/src/tool/collageMaker/i18n/ru.ts +233 -0
  47. package/src/tool/collageMaker/i18n/sv.ts +233 -0
  48. package/src/tool/collageMaker/i18n/tr.ts +233 -0
  49. package/src/tool/collageMaker/i18n/zh.ts +233 -0
  50. package/src/tool/collageMaker/index.ts +15 -6
  51. package/src/tool/exifCleaner/i18n/de.ts +277 -0
  52. package/src/tool/exifCleaner/i18n/en.ts +2 -2
  53. package/src/tool/exifCleaner/i18n/es.ts +2 -2
  54. package/src/tool/exifCleaner/i18n/fr.ts +4 -4
  55. package/src/tool/exifCleaner/i18n/id.ts +277 -0
  56. package/src/tool/exifCleaner/i18n/it.ts +277 -0
  57. package/src/tool/exifCleaner/i18n/ja.ts +277 -0
  58. package/src/tool/exifCleaner/i18n/ko.ts +277 -0
  59. package/src/tool/exifCleaner/i18n/nl.ts +277 -0
  60. package/src/tool/exifCleaner/i18n/pl.ts +277 -0
  61. package/src/tool/exifCleaner/i18n/pt.ts +277 -0
  62. package/src/tool/exifCleaner/i18n/ru.ts +277 -0
  63. package/src/tool/exifCleaner/i18n/sv.ts +277 -0
  64. package/src/tool/exifCleaner/i18n/tr.ts +277 -0
  65. package/src/tool/exifCleaner/i18n/zh.ts +277 -0
  66. package/src/tool/exifCleaner/index.ts +16 -8
  67. package/src/tool/imageCompressor/i18n/de.ts +242 -0
  68. package/src/tool/imageCompressor/i18n/en.ts +2 -2
  69. package/src/tool/imageCompressor/i18n/es.ts +2 -2
  70. package/src/tool/imageCompressor/i18n/id.ts +242 -0
  71. package/src/tool/imageCompressor/i18n/it.ts +242 -0
  72. package/src/tool/imageCompressor/i18n/ja.ts +242 -0
  73. package/src/tool/imageCompressor/i18n/ko.ts +242 -0
  74. package/src/tool/imageCompressor/i18n/nl.ts +242 -0
  75. package/src/tool/imageCompressor/i18n/pl.ts +242 -0
  76. package/src/tool/imageCompressor/i18n/pt.ts +242 -0
  77. package/src/tool/imageCompressor/i18n/ru.ts +242 -0
  78. package/src/tool/imageCompressor/i18n/sv.ts +242 -0
  79. package/src/tool/imageCompressor/i18n/tr.ts +242 -0
  80. package/src/tool/imageCompressor/i18n/zh.ts +244 -0
  81. package/src/tool/imageCompressor/index.ts +15 -7
  82. package/src/tool/printQualityCalculator/i18n/de.ts +261 -0
  83. package/src/tool/printQualityCalculator/i18n/en.ts +2 -2
  84. package/src/tool/printQualityCalculator/i18n/es.ts +3 -3
  85. package/src/tool/printQualityCalculator/i18n/fr.ts +3 -3
  86. package/src/tool/printQualityCalculator/i18n/id.ts +261 -0
  87. package/src/tool/printQualityCalculator/i18n/it.ts +261 -0
  88. package/src/tool/printQualityCalculator/i18n/ja.ts +261 -0
  89. package/src/tool/printQualityCalculator/i18n/ko.ts +261 -0
  90. package/src/tool/printQualityCalculator/i18n/nl.ts +261 -0
  91. package/src/tool/printQualityCalculator/i18n/pl.ts +261 -0
  92. package/src/tool/printQualityCalculator/i18n/pt.ts +261 -0
  93. package/src/tool/printQualityCalculator/i18n/ru.ts +261 -0
  94. package/src/tool/printQualityCalculator/i18n/sv.ts +261 -0
  95. package/src/tool/printQualityCalculator/i18n/tr.ts +261 -0
  96. package/src/tool/printQualityCalculator/i18n/zh.ts +261 -0
  97. package/src/tool/printQualityCalculator/index.ts +15 -7
  98. package/src/tool/privacyBlur/i18n/de.ts +238 -0
  99. package/src/tool/privacyBlur/i18n/en.ts +1 -1
  100. package/src/tool/privacyBlur/i18n/es.ts +1 -1
  101. package/src/tool/privacyBlur/i18n/fr.ts +1 -1
  102. package/src/tool/privacyBlur/i18n/id.ts +238 -0
  103. package/src/tool/privacyBlur/i18n/it.ts +238 -0
  104. package/src/tool/privacyBlur/i18n/ja.ts +238 -0
  105. package/src/tool/privacyBlur/i18n/ko.ts +238 -0
  106. package/src/tool/privacyBlur/i18n/nl.ts +238 -0
  107. package/src/tool/privacyBlur/i18n/pl.ts +238 -0
  108. package/src/tool/privacyBlur/i18n/pt.ts +238 -0
  109. package/src/tool/privacyBlur/i18n/ru.ts +238 -0
  110. package/src/tool/privacyBlur/i18n/sv.ts +238 -0
  111. package/src/tool/privacyBlur/i18n/tr.ts +238 -0
  112. package/src/tool/privacyBlur/i18n/zh.ts +238 -0
  113. package/src/tool/privacyBlur/index.ts +15 -7
  114. package/src/tool/subtitleSync/i18n/de.ts +241 -0
  115. package/src/tool/subtitleSync/i18n/en.ts +1 -1
  116. package/src/tool/subtitleSync/i18n/es.ts +1 -1
  117. package/src/tool/subtitleSync/i18n/fr.ts +8 -8
  118. package/src/tool/subtitleSync/i18n/id.ts +241 -0
  119. package/src/tool/subtitleSync/i18n/it.ts +241 -0
  120. package/src/tool/subtitleSync/i18n/ja.ts +241 -0
  121. package/src/tool/subtitleSync/i18n/ko.ts +241 -0
  122. package/src/tool/subtitleSync/i18n/nl.ts +241 -0
  123. package/src/tool/subtitleSync/i18n/pl.ts +241 -0
  124. package/src/tool/subtitleSync/i18n/pt.ts +241 -0
  125. package/src/tool/subtitleSync/i18n/ru.ts +241 -0
  126. package/src/tool/subtitleSync/i18n/sv.ts +241 -0
  127. package/src/tool/subtitleSync/i18n/tr.ts +241 -0
  128. package/src/tool/subtitleSync/i18n/zh.ts +241 -0
  129. package/src/tool/subtitleSync/index.ts +15 -7
  130. package/src/tool/timelapseCalculator/i18n/de.ts +169 -0
  131. package/src/tool/timelapseCalculator/i18n/fr.ts +2 -2
  132. package/src/tool/timelapseCalculator/i18n/id.ts +169 -0
  133. package/src/tool/timelapseCalculator/i18n/it.ts +169 -0
  134. package/src/tool/timelapseCalculator/i18n/ja.ts +169 -0
  135. package/src/tool/timelapseCalculator/i18n/ko.ts +169 -0
  136. package/src/tool/timelapseCalculator/i18n/nl.ts +169 -0
  137. package/src/tool/timelapseCalculator/i18n/pl.ts +169 -0
  138. package/src/tool/timelapseCalculator/i18n/pt.ts +169 -0
  139. package/src/tool/timelapseCalculator/i18n/ru.ts +169 -0
  140. package/src/tool/timelapseCalculator/i18n/sv.ts +169 -0
  141. package/src/tool/timelapseCalculator/i18n/tr.ts +169 -0
  142. package/src/tool/timelapseCalculator/i18n/zh.ts +169 -0
  143. package/src/tool/timelapseCalculator/index.ts +16 -8
  144. package/src/tool/tvDistance/i18n/de.ts +223 -0
  145. package/src/tool/tvDistance/i18n/en.ts +1 -1
  146. package/src/tool/tvDistance/i18n/es.ts +1 -1
  147. package/src/tool/tvDistance/i18n/fr.ts +1 -1
  148. package/src/tool/tvDistance/i18n/id.ts +223 -0
  149. package/src/tool/tvDistance/i18n/it.ts +223 -0
  150. package/src/tool/tvDistance/i18n/ja.ts +223 -0
  151. package/src/tool/tvDistance/i18n/ko.ts +223 -0
  152. package/src/tool/tvDistance/i18n/nl.ts +223 -0
  153. package/src/tool/tvDistance/i18n/pl.ts +223 -0
  154. package/src/tool/tvDistance/i18n/pt.ts +223 -0
  155. package/src/tool/tvDistance/i18n/ru.ts +223 -0
  156. package/src/tool/tvDistance/i18n/sv.ts +223 -0
  157. package/src/tool/tvDistance/i18n/tr.ts +223 -0
  158. package/src/tool/tvDistance/i18n/zh.ts +223 -0
  159. package/src/tool/tvDistance/index.ts +15 -7
  160. package/src/tool/videoFrameExtractor/i18n/de.ts +235 -0
  161. package/src/tool/videoFrameExtractor/i18n/en.ts +1 -1
  162. package/src/tool/videoFrameExtractor/i18n/es.ts +1 -1
  163. package/src/tool/videoFrameExtractor/i18n/fr.ts +1 -1
  164. package/src/tool/videoFrameExtractor/i18n/id.ts +235 -0
  165. package/src/tool/videoFrameExtractor/i18n/it.ts +235 -0
  166. package/src/tool/videoFrameExtractor/i18n/ja.ts +235 -0
  167. package/src/tool/videoFrameExtractor/i18n/ko.ts +235 -0
  168. package/src/tool/videoFrameExtractor/i18n/nl.ts +235 -0
  169. package/src/tool/videoFrameExtractor/i18n/pl.ts +235 -0
  170. package/src/tool/videoFrameExtractor/i18n/pt.ts +235 -0
  171. package/src/tool/videoFrameExtractor/i18n/ru.ts +235 -0
  172. package/src/tool/videoFrameExtractor/i18n/sv.ts +235 -0
  173. package/src/tool/videoFrameExtractor/i18n/tr.ts +235 -0
  174. package/src/tool/videoFrameExtractor/i18n/zh.ts +235 -0
  175. package/src/tool/videoFrameExtractor/index.ts +16 -8
@@ -0,0 +1,238 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { PrivacyBlurUI, PrivacyBlurLocaleContent } from '../index';
3
+
4
+ const slug = 'online-privacy-editor-pixelate-blur-faces-photos';
5
+ const title = '在线隐私编辑器:在照片中对脸部进行马赛克和隐藏';
6
+ const description = '通过审查照片中的敏感区域来保护您的身份。在本地 100% 完成对脸部的像素化、文档的模糊或隐私信息的覆盖。';
7
+
8
+ const ui: PrivacyBlurUI = {
9
+ toolPixel: "马赛克",
10
+ toolBlur: "模糊",
11
+ toolSolid: "色块",
12
+ intensityLabel: "强度",
13
+ undoButton: "撤销",
14
+ downloadButton: "保存",
15
+ dropTitle: "隐私编辑器",
16
+ dropSubtitle: "将您的图像拖到此处或点击开始",
17
+ privacySecureLabel: "100% 本地",
18
+ offlineLabel: "离线",
19
+ autoDetectFaces: "自动检测",
20
+ loadingModels: "正在加载模型...",
21
+ noFacesDetected: "未自动检测到脸部。",
22
+ faqTitle: "常见问题",
23
+ bibliographyTitle: "参考资料"
24
+ };
25
+
26
+ const faq: PrivacyBlurLocaleContent['faq'] = [
27
+ {
28
+ question: "我的照片会被上传到任何服务器吗?",
29
+ answer: "不会。隐私编辑器完全在您的浏览器中运行。像素在本地修改,不会向您的设备外部发送任何内容。",
30
+ },
31
+ {
32
+ question: "自动脸部检测是如何工作的?",
33
+ answer: "我们使用在您的浏览器中运行的轻量级神经网络 (TinyFaceDetector) 来识别面部特征,无需外部连接。",
34
+ },
35
+ ];
36
+
37
+ const howTo: PrivacyBlurLocaleContent['howTo'] = [
38
+ {
39
+ name: "上传您的照片",
40
+ text: "拖动或选择包含您希望隐藏的敏感信息的图像。",
41
+ },
42
+ {
43
+ name: "选择工具",
44
+ text: "根据您需要的隐私级别,在马赛克、模糊或色块覆盖之间进行选择。",
45
+ },
46
+ {
47
+ name: "标记区域",
48
+ text: "在您想要保护的区域(脸部、车牌、姓名等)上点击并拖动。",
49
+ },
50
+ {
51
+ name: "保存结果",
52
+ text: "在确保原始数据无法访问的情况下,下载处理后的图像。",
53
+ },
54
+ ];
55
+
56
+ const bibliography: PrivacyBlurLocaleContent['bibliography'] = [
57
+ {
58
+ name: "隐私设计 (PbD) - AGPD",
59
+ url: "https://www.aepd.es/es/guias-y-herramientas/guias/guia-de-privacidad-desde-el-diseno",
60
+ },
61
+ ];
62
+
63
+ const seo: PrivacyBlurLocaleContent['seo'] = [
64
+ {
65
+ type: 'summary',
66
+ title: '隐私编辑器:马赛克、模糊和隐藏',
67
+ items: [
68
+ '三种编辑工具:马赛克、模糊、色块覆盖',
69
+ '使用 AI 进行自动脸部检测 (TinyFaceDetector)',
70
+ '100% 本地处理 - 您的照片永远不会离开浏览器',
71
+ '无水印,无限制,完全免费'
72
+ ]
73
+ },
74
+ { type: 'title', text: '数字隐私:如何保护您的视觉数据', level: 2 },
75
+ { type: 'paragraph', html: '在社交媒体时代,不受控制地分享照片可能会暴露敏感的个人数据。我们的工具允许您在将照片上传到互联网之前隐藏关键信息(脸部、车牌、姓名、地址),确保您的隐私始终处于您的完全控制之下。' },
76
+
77
+ { type: 'stats', items: [
78
+ { value: '3', label: '隐藏方法', icon: 'mdi:tools' },
79
+ { value: '100%', label: '本地隐私', icon: 'mdi:shield-check' },
80
+ { value: 'AI', label: '脸部检测', icon: 'mdi:brain' }
81
+ ], columns: 3 },
82
+
83
+ { type: 'title', text: '三种隐藏方法说明', level: 3 },
84
+ { type: 'comparative', items: [
85
+ {
86
+ title: '马赛克 (Pixelate)',
87
+ description: '将区域划分成方块,无法识别',
88
+ icon: 'mdi:blur',
89
+ points: [
90
+ '最大程度的不可逆模糊',
91
+ '对人脸识别更安全',
92
+ '可见,清晰表明某些内容已被隐藏',
93
+ '理想场景:公开照片中的脸部'
94
+ ]
95
+ },
96
+ {
97
+ title: '模糊 (Blur)',
98
+ description: '高斯平滑 - 看起来更自然',
99
+ icon: 'mdi:blur-off',
100
+ points: [
101
+ '更优雅的视觉外观',
102
+ '保持一定的色调一致性',
103
+ '数学上可逆(理论上)',
104
+ '理想场景:不那么敏感的信息'
105
+ ],
106
+ highlight: true
107
+ },
108
+ {
109
+ title: '色块覆盖 (Solid)',
110
+ description: '不透明色块 - 最高隐私级别',
111
+ icon: 'mdi:rectangle',
112
+ points: [
113
+ '可见、明显的隐藏',
114
+ '最高的法律安全性/隐私性',
115
+ '改变视觉构图',
116
+ '理想场景:文档、敏感数据'
117
+ ]
118
+ }
119
+ ], columns: 3 },
120
+
121
+ { type: 'title', text: '使用 AI 进行自动脸部检测', level: 3 },
122
+ { type: 'paragraph', html: '我们的工具使用 TinyFaceDetector,这是一个直接在您的浏览器中运行的小型神经网络,用于自动识别脸部:' },
123
+ { type: 'list', items: [
124
+ '<strong>100% 本地:</strong> AI 模型在您的 GPU/CPU 上运行,而不是在远程服务器上。',
125
+ '<strong>无需互联网:</strong> 在初始下载后,它完全离线工作。',
126
+ '<strong>隐私保证:</strong> 没有人能看到这些脸:不论是 Google、OpenAI 还是我们。',
127
+ '<strong>自动一键操作:</strong> 检测脸部并允许您通过一键选择隐藏。'
128
+ ], icon: 'mdi:check' },
129
+
130
+ { type: 'card', title: '隐私设计 (Privacy by Design)', html: '通过使用您浏览器的本地 GPU 和 CPU 处理图像,我们保证原始照片永远不会离开您的设备。即使您改变主意,也不会传输任何内容。这是数字隐私的最高标准。' },
131
+
132
+ { type: 'title', text: '隐私应用案例', level: 3 },
133
+ { type: 'table', headers: ['敏感信息', '推荐方法', '紧急程度'], rows: [
134
+ ['人物脸部', '马赛克或模糊', '关键'],
135
+ ['车辆车牌', '马赛克 (不可逆)', '关键'],
136
+ ['身份证明文档', '色块覆盖或马赛克', '关键'],
137
+ ['书写的姓名/地址', '色块覆盖或马赛克', '高'],
138
+ ['电话号码', '马赛克或色块', '高'],
139
+ ['医疗信息', '色块覆盖', '关键'],
140
+ ['可见的 WiFi 信号', '马赛克', '中']
141
+ ] },
142
+
143
+ { type: 'proscons', items: [
144
+ {
145
+ pro: '完全隐私:100% 本地处理,无服务器,无存储',
146
+ con: '需要支持 Canvas 和 WebGL 的现代浏览器'
147
+ },
148
+ {
149
+ pro: '自动脸部检测节省手动时间',
150
+ con: 'AI 并不完美 - 侧脸或部分脸部可能无法被检测到'
151
+ },
152
+ {
153
+ pro: '三种方法允许在安全性与美观之间进行选择',
154
+ con: '没有高级选项(智能扭曲、上下文填充)'
155
+ },
156
+ {
157
+ pro: '完全免费,无广告,无限制',
158
+ con: '不等同于像 Photoshop 这样的专业软件'
159
+ }
160
+ ], proTitle: '优点', conTitle: '局限性' },
161
+
162
+ { type: 'diagnostic', variant: 'warning', title: '警示:模糊并非 100% 安全', icon: 'mdi:alert', badge: '安全性', html: '高斯模糊在数学上可以通过复杂的逆算法进行还原。如果信息至关重要(法律文件、身份),请使用<strong>马赛克或色块覆盖</strong>。模糊在美学上更好,但安全性较低。' },
163
+
164
+ { type: 'glossary', items: [
165
+ {
166
+ term: '马赛克',
167
+ definition: '通过将区域划分为统一的颜色块来降低分辨率。不可逆。针对 AI 人脸识别的最大安全性。'
168
+ },
169
+ {
170
+ term: '高斯模糊',
171
+ definition: '基于正态分布的数学平滑。理论上可以通过反卷积还原,但实际上非常困难。'
172
+ },
173
+ {
174
+ term: '色块覆盖',
175
+ definition: '均匀颜色的不透明块。最高的安全性,最高的法律隐私性,视觉上不够雅致。'
176
+ },
177
+ {
178
+ term: 'TinyFaceDetector',
179
+ definition: '用于检测脸部的轻量级卷积神经网络 (CNN)。在浏览器中本地运行,无需外部服务器。'
180
+ },
181
+ {
182
+ term: '隐私设计 (PbD)',
183
+ definition: '一种在系统设计之初就整合隐私的方法,而不是后来才添加。我们的本地处理方法正是隐私设计。'
184
+ }
185
+ ] },
186
+
187
+ { type: 'message', title: '隐私由您掌控', ariaLabel: '关于隐私保护的信息', html: '我们不在远程服务器上存储或处理您的照片。没有跟踪 Cookie。没有编辑历史记录。我们不知道您隐藏了什么,因为我们从未看到您的图像。完全控制、完全隐私、完全自由。' },
188
+
189
+ { type: 'title', text: '在社交网络上安全分享', level: 3 },
190
+ { type: 'paragraph', html: '在互联网上发布任何照片之前,请问自己:是否有我不希望公开的信息?孩子的脸详细、车牌、地址、证件号码。现在进行 2 分钟的隐私处理可以避免数年的麻烦。' }
191
+ ];
192
+
193
+ const faqSchema: WithContext<FAQPage> = {
194
+ '@context': 'https://schema.org',
195
+ '@type': 'FAQPage',
196
+ mainEntity: faq.map((item) => ({
197
+ '@type': 'Question',
198
+ name: item.question,
199
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
200
+ })),
201
+ };
202
+
203
+ const howToSchema: WithContext<HowTo> = {
204
+ '@context': 'https://schema.org',
205
+ '@type': 'HowTo',
206
+ name: title,
207
+ description,
208
+ step: howTo.map((step) => ({
209
+ '@type': 'HowToStep',
210
+ name: step.name,
211
+ text: step.text,
212
+ })),
213
+ };
214
+
215
+ const appSchema: WithContext<SoftwareApplication> = {
216
+ '@context': 'https://schema.org',
217
+ '@type': 'SoftwareApplication',
218
+ name: title,
219
+ description,
220
+ applicationCategory: 'UtilitiesApplication',
221
+ operatingSystem: 'Web',
222
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
223
+ inLanguage: 'zh',
224
+ };
225
+
226
+ export const content: PrivacyBlurLocaleContent = {
227
+ slug,
228
+ title,
229
+ description,
230
+ ui,
231
+ seo,
232
+ faqTitle: "常见问题",
233
+ faq,
234
+ bibliographyTitle: "参考资料",
235
+ bibliography,
236
+ howTo,
237
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
238
+ };
@@ -22,10 +22,6 @@ export interface PrivacyBlurUI {
22
22
 
23
23
  export type PrivacyBlurLocaleContent = ToolLocaleContent<PrivacyBlurUI>;
24
24
 
25
- import { content as es } from './i18n/es';
26
- import { content as en } from './i18n/en';
27
- import { content as fr } from './i18n/fr';
28
-
29
25
  export const privacyBlur: AudiovisualToolEntry<PrivacyBlurUI> = {
30
26
  id: 'editor-privacidad',
31
27
  icons: {
@@ -33,9 +29,21 @@ export const privacyBlur: AudiovisualToolEntry<PrivacyBlurUI> = {
33
29
  fg: 'mdi:blur',
34
30
  },
35
31
  i18n: {
36
- es: async () => es as unknown as PrivacyBlurLocaleContent,
37
- en: async () => en as unknown as PrivacyBlurLocaleContent,
38
- fr: async () => fr as unknown as PrivacyBlurLocaleContent,
32
+ es: async () => (await import('./i18n/es')).content as unknown as PrivacyBlurLocaleContent,
33
+ en: async () => (await import('./i18n/en')).content as unknown as PrivacyBlurLocaleContent,
34
+ fr: async () => (await import('./i18n/fr')).content as unknown as PrivacyBlurLocaleContent,
35
+ de: async () => (await import('./i18n/de')).content as unknown as PrivacyBlurLocaleContent,
36
+ it: async () => (await import('./i18n/it')).content as unknown as PrivacyBlurLocaleContent,
37
+ pt: async () => (await import('./i18n/pt')).content as unknown as PrivacyBlurLocaleContent,
38
+ id: async () => (await import('./i18n/id')).content as unknown as PrivacyBlurLocaleContent,
39
+ ja: async () => (await import('./i18n/ja')).content as unknown as PrivacyBlurLocaleContent,
40
+ ko: async () => (await import('./i18n/ko')).content as unknown as PrivacyBlurLocaleContent,
41
+ nl: async () => (await import('./i18n/nl')).content as unknown as PrivacyBlurLocaleContent,
42
+ pl: async () => (await import('./i18n/pl')).content as unknown as PrivacyBlurLocaleContent,
43
+ ru: async () => (await import('./i18n/ru')).content as unknown as PrivacyBlurLocaleContent,
44
+ sv: async () => (await import('./i18n/sv')).content as unknown as PrivacyBlurLocaleContent,
45
+ tr: async () => (await import('./i18n/tr')).content as unknown as PrivacyBlurLocaleContent,
46
+ zh: async () => (await import('./i18n/zh')).content as unknown as PrivacyBlurLocaleContent,
39
47
  },
40
48
  };
41
49
 
@@ -0,0 +1,241 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { SubtitleSyncUI, SubtitleSyncLocaleContent } from '../index';
3
+
4
+ const slug = 'srt-untertitel-online-synchronisieren-timing-anpassen-kostenlos';
5
+ const title = 'SRT Untertitel online synchronisieren: Timing kostenlos anpassen';
6
+ const description = 'Online-Tool zum Vorziehen oder Verzögern von SRT-Untertiteln. Korrigieren Sie den Zeitversatz ganz einfach und laden Sie die synchronisierte Datei sofort herunter.';
7
+
8
+ const ui: SubtitleSyncUI = {
9
+ dropTitle: "Ziehen Sie Ihre .SRT-Datei hierher",
10
+ dropSubtitle: "oder klicken Sie zum Durchsuchen",
11
+ adjustTitle: "Zeit anpassen",
12
+ offsetLabel: "Versatz (Sekunden)",
13
+ offsetHelp: "Negative Werte zum Vorziehen (z. B. -1.5) und positive Werte zum Verzögern verwenden.",
14
+ linesStat: "Zeilen",
15
+ firstStat: "Erster Untertitel",
16
+ lastStat: "Letzter Untertitel",
17
+ originalLabel: "ORIGINAL",
18
+ resultLabel: "ERGEBNIS",
19
+ downloadButton: "Korrigierte Version herunterladen",
20
+ previewBadge: "VORSCHAU",
21
+ unitSeconds: "Sek."
22
+ };
23
+
24
+ const faq: SubtitleSyncLocaleContent['faq'] = [
25
+ {
26
+ question: "Wie kann ich meine Untertitel synchronisieren, wenn der Ton früher kommt?",
27
+ answer: "Wenn der Ton vor dem Text erscheint, müssen Sie die Untertitel verzögern. Geben Sie einen positiven Wert in den Rechner ein (z. B. 2.0, um sie um 2 Sekunden zu verzögern).",
28
+ },
29
+ {
30
+ question: "Welche Dateiformate akzeptiert dieses Tool?",
31
+ answer: "Derzeit ist das Tool für .SRT-Dateien (SubRip) optimiert, den am weitesten verbreiteten Standard in Videoplayern und Streaming-Plattformen.",
32
+ },
33
+ {
34
+ question: "Ist es sicher, meine Untertiteldateien hochzuladen?",
35
+ answer: "Ja, da die Verarbeitung zu 100 % lokal auf Ihrem Gerät erfolgt. Ihre Dateien werden an keinen Server gesendet; die Synchronisierung erfolgt direkt in Ihrem Browser.",
36
+ },
37
+ {
38
+ question: "Kann ich nur einen Teil der Datei synchronisieren?",
39
+ answer: "Nein, dieses Tool wendet einen konstanten Versatz auf die gesamte Datei an. Wenn der Versatz progressiv ist, benötigen Sie möglicherweise fortgeschrittenere Bearbeitungsmöglichkeiten.",
40
+ },
41
+ ];
42
+
43
+ const howTo: SubtitleSyncLocaleContent['howTo'] = [
44
+ {
45
+ name: "SRT-Datei hochladen",
46
+ text: "Ziehen Sie die zu korrigierende Untertiteldatei in den Upload Bereich.",
47
+ },
48
+ {
49
+ name: "Versatz bestimmen",
50
+ text: "Messen Sie in Ihrem Player, wie hoch die Verzögerung oder der Vorlauf der Untertitel im Vergleich zum Ton ist.",
51
+ },
52
+ {
53
+ name: "Versatz anpassen",
54
+ text: "Geben Sie positive (Verzögerung) oder negative (Vorlauf) Sekunden im Bedienfeld ein.",
55
+ },
56
+ {
57
+ name: "Datei herunterladen",
58
+ text: "Überprüfen Sie in der Vorschau, ob die Zeiten stimmen, und klicken Sie auf Herunterladen, um Ihre neue SRT Datei zu erhalten.",
59
+ },
60
+ ];
61
+
62
+ const bibliography: SubtitleSyncLocaleContent['bibliography'] = [
63
+ {
64
+ name: "SubRip (SRT) Format-Spezifikation",
65
+ url: "https://matroska.org/technical/subtitles.html#srt-subtitles",
66
+ },
67
+ {
68
+ name: "MDN Web Docs - FileReader API",
69
+ url: "https://developer.mozilla.org/en-US/docs/Web/API/FileReader",
70
+ },
71
+ ];
72
+
73
+ const seo: SubtitleSyncLocaleContent['seo'] = [
74
+ {
75
+ type: 'summary',
76
+ title: 'Professionelle Untertitel Synchronisation',
77
+ items: [
78
+ 'Sofortige Korrektur von Ton-Untertitel-Versätzen',
79
+ 'Unterstützt Standard-SRT-Dateien (SubRip)',
80
+ '100 % lokale Verarbeitung – maximale Privatsphäre',
81
+ 'Keine Installation, kein Abonnement, völlig kostenlos'
82
+ ]
83
+ },
84
+ { type: 'title', text: 'Perfekte SRT Untertitel Synchronisation', level: 2 },
85
+ { type: 'paragraph', html: 'Es gibt für Zuschauer kaum etwas Frustrierenderes als Dialoge, die nicht zu den Stimmen passen. Untertitel-Versätze entstehen meist durch Unterschiede zwischen Videoversionen: Abweichungen in der Framerate, Werbeunterbrechungen, Produktionsintros oder Änderungen in der Kompression. Mit diesem Tool beheben Sie das Problem in Sekunden.' },
86
+
87
+ { type: 'stats', items: [
88
+ { value: '100 %', label: 'Lokale Verarbeitung', icon: 'mdi:shield' },
89
+ { value: 'Millisekunden', label: 'Präzision', icon: 'mdi:clock-outline' },
90
+ { value: 'Beliebig', label: 'KEIN Dateilimit', icon: 'mdi:file-document' }
91
+ ], columns: 3 },
92
+
93
+ { type: 'title', text: 'Vorziehen vs. Verzögern: Praxisleitfaden', level: 3 },
94
+ { type: 'paragraph', html: 'Der erste Schritt besteht darin, den Typ des Versatzes korrekt zu identifizieren. Hier ist die Logik:' },
95
+ { type: 'list', items: [
96
+ '<strong>Verzögerung (Positiver Wert):</strong> Wenn der Text ERSCHEINT, BEVOR der Ton zu hören ist. Die Untertitel sind zu früh. Beispiel: +2.0 Sekunden.',
97
+ '<strong>Vorziehen (Negativer Wert):</strong> Wenn der Text ERSCHEINT, NACHDEM der Ton zu hören war. Die Untertitel sind zu spät. Beispiel: -2.0 Sekunden.',
98
+ '<strong>Testen und Anpassen:</strong> Beginnen Sie mit kleinen Schritten (0,5 Sek.) und nutzen Sie die Vorschau zur Validierung.'
99
+ ], icon: 'mdi:arrow-right' },
100
+
101
+ { type: 'card', title: 'Privatsphäre auf professionellem Niveau', html: 'Durch die Verarbeitung der Datei mittels clientseitigem JavaScript garantieren wir, dass der Inhalt Ihrer Untertitel niemals Ihren Computer verlässt. Essenziell für Übersetzer und Profis, die vertrauliches Material bearbeiten oder unter Vertraulichkeitsvereinbarungen (NDA) stehen.' },
102
+
103
+ { type: 'title', text: 'Häufige Anwendungsfälle', level: 3 },
104
+ { type: 'comparative', items: [
105
+ {
106
+ title: 'Übersetzer und Untertitler',
107
+ description: 'Synchronisieren von Übersetzungen nach der Arbeit mit mehreren Videoversionen',
108
+ icon: 'mdi:translate',
109
+ points: [
110
+ 'SRT-Dateien aus verschiedenen Quellen',
111
+ 'Inhaltsversionierung (Kino vs. Streaming)',
112
+ 'Schnelle Lieferung ohne Werkzeugwechsel'
113
+ ]
114
+ },
115
+ {
116
+ title: 'Content Ersteller',
117
+ description: 'Wiederherstellung von Untertiteln, wenn das Video mit einer anderen Framerate verarbeitet wurde',
118
+ icon: 'mdi:video',
119
+ points: [
120
+ 'Wiederverwendung vorhandener Untertitel',
121
+ 'Formatänderungen (720p zu 1080p)',
122
+ 'Vermeidung von manuellem Retiming tausender Zeilen'
123
+ ],
124
+ highlight: true
125
+ },
126
+ {
127
+ title: 'Hobby Nutzer',
128
+ description: 'Korrigieren heruntergeladener Untertitel, die nicht perfekt passen',
129
+ icon: 'mdi:account',
130
+ points: [
131
+ 'Generische asynchrone Untertitel',
132
+ 'Filme aus verschiedenen Regionen (PAL vs. NTSC)',
133
+ 'Streaming mit bearbeiteten Versionen'
134
+ ]
135
+ }
136
+ ], columns: 3 },
137
+
138
+ { type: 'title', text: 'Warum Untertitel asynchron werden', level: 3 },
139
+ { type: 'table', headers: ['Häufige Ursache', 'Technische Beschreibung', 'Lösung'], rows: [
140
+ ['Framerate-Unterschied', '23.976 fps vs. 25 fps - kumulierter Unterschied', 'Einmalige Versatzanpassung (dieses Tool)'],
141
+ ['Editoriale Änderungen', 'Werbeschnitte oder entfernter/hinzugefügter Inhalt', 'Manuelle Berechnung + Synchronisation'],
142
+ ['Region-Version', 'PAL (25 fps Europa) vs. NTSC (29.97 fps USA)', 'Einfacher mathematischer Versatz'],
143
+ ['Auflösungsänderung', 'Neu-Enkodierung mit anderer Verarbeitungsgeschwindigkeit', 'Neuberechnung der Originaldatei']
144
+ ] },
145
+
146
+ { type: 'diagnostic', variant: 'info', title: 'Technische Einschränkungen', icon: 'mdi:information', badge: 'Wichtig', html: 'Dieses Tool wendet einen <strong>konstanten</strong> Versatz auf die gesamte Datei an. Wenn der Versatz <strong>progressiv</strong> ist (am Anfang passend, wird aber allmählich asynchron), deutet dies auf einen dauerhaften Framerate-Unterschied hin. In diesem Fall muss die Originaldatei in einer professionellen Videoschnittsoftware neu verarbeitet werden.' },
147
+
148
+ { type: 'proscons', items: [
149
+ {
150
+ pro: 'Extreme Geschwindigkeit - verarbeitet große Dateien in Millisekunden',
151
+ con: 'Passt nur fixen Versatz an, keinen progressiven'
152
+ },
153
+ {
154
+ pro: 'Volle Privatsphäre - Inhalt verlässt nie den Browser',
155
+ con: 'Erfordert modernen Browser mit aktiviertem JavaScript'
156
+ },
157
+ {
158
+ pro: 'Universelles Format - funktioniert mit jeder Standard-SRT',
159
+ con: 'Unterstützt keine anderen Formate (ASS, VTT, SCC usw.)'
160
+ },
161
+ {
162
+ pro: 'Völlig kostenlos, keine Werbung, kein Tracking',
163
+ con: 'Keine Änderungshistorie oder Versionierung'
164
+ }
165
+ ], proTitle: 'Vorteile', conTitle: 'Einschränkungen' },
166
+
167
+ { type: 'glossary', items: [
168
+ {
169
+ term: 'SRT (SubRip)',
170
+ definition: 'Das universellste Untertitelformat: Textdatei mit Sequenznummern, Zeiten (hh:mm:ss,mmm) und Text. De-facto-Standard in Playern und Plattformen.'
171
+ },
172
+ {
173
+ term: 'Versatz (Offset)',
174
+ definition: 'Fester Zeitbetrag, der zu allen Zeiten in der Datei addiert oder subtrahiert wird. Kann positive Sekunden (Verzögerung) oder negative (Vorziehen) sein.'
175
+ },
176
+ {
177
+ term: 'Framerate (fps)',
178
+ definition: 'Bilder pro Sekunde. 24p (Kino), 25p (PAL/Europa), 29.97p (NTSC/USA), 60p (flüssiges Video). Unterschiede führen zu kumulativen Versätzen.'
179
+ },
180
+ {
181
+ term: 'NTSC vs. PAL',
182
+ definition: 'Regionale TV-Standards: PAL (25 fps) in Europa; NTSC (29.97 fps) in den USA. Ca. 4 % Geschwindigkeitsunterschied.'
183
+ },
184
+ {
185
+ term: 'Progressiver Versatz',
186
+ definition: 'Wenn die Synchronisation am Anfang stimmt, sich aber allmählich verschlechtert. Deutet auf Framerate-Unterschiede hin, erfordert Neuverarbeitung.'
187
+ }
188
+ ] },
189
+
190
+ { type: 'message', title: 'Professionelle Bearbeitung mit voller Kontrolle', ariaLabel: 'Technische Informationen zur Synchronisation', html: 'Unser Ansatz ist einfach, aber leistungsstark: ein einziger Versatz, sofort angewendet, zu 100 % in Ihrem Browser verarbeitet. Keine Cloud, keine Speicherung, kein Tracking. Einfach hochladen, anpassen, herunterladen. Volle Kontrolle über Ihren Inhalt.' },
191
+
192
+ { type: 'title', text: 'Fazit: Filme ohne Unterbrechungen', level: 3 },
193
+ { type: 'paragraph', html: 'Eine perfekte Untertitel-Synchronisation ist entscheidend für ein hochwertiges audiovisuelles Erlebnis. Mit diesem Tool verwandeln Sie eine frustrierende Erfahrung in einen perfekten Filmabend, ohne die Notwendigkeit für teure oder komplizierte Software.' }
194
+ ];
195
+
196
+ const faqSchema: WithContext<FAQPage> = {
197
+ '@context': 'https://schema.org',
198
+ '@type': 'FAQPage',
199
+ mainEntity: faq.map((item) => ({
200
+ '@type': 'Question',
201
+ name: item.question,
202
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
203
+ })),
204
+ };
205
+
206
+ const howToSchema: WithContext<HowTo> = {
207
+ '@context': 'https://schema.org',
208
+ '@type': 'HowTo',
209
+ name: title,
210
+ description,
211
+ step: howTo.map((step) => ({
212
+ '@type': 'HowToStep',
213
+ name: step.name,
214
+ text: step.text,
215
+ })),
216
+ };
217
+
218
+ const appSchema: WithContext<SoftwareApplication> = {
219
+ '@context': 'https://schema.org',
220
+ '@type': 'SoftwareApplication',
221
+ name: title,
222
+ description,
223
+ applicationCategory: 'UtilitiesApplication',
224
+ operatingSystem: 'Web',
225
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
226
+ inLanguage: 'de',
227
+ };
228
+
229
+ export const content: SubtitleSyncLocaleContent = {
230
+ slug,
231
+ title,
232
+ description,
233
+ ui,
234
+ seo,
235
+ faq,
236
+ faqTitle: 'Häufig gestellte Fragen zur Untertitel Synchronisation',
237
+ bibliography,
238
+ bibliographyTitle: 'Technische Ressourcen zu Untertitelformaten',
239
+ howTo,
240
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
241
+ };
@@ -2,7 +2,7 @@ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dt
2
2
  import type { SubtitleSyncUI, SubtitleSyncLocaleContent } from '../index';
3
3
 
4
4
  const slug = 'synchronize-srt-subtitles-online-adjust-timing-free';
5
- const title = 'Synchronize SRT Subtitles Online - Adjust Timing for Free';
5
+ const title = 'Synchronize SRT Subtitles Online: Adjust Timing for Free';
6
6
  const description = 'Online tool to advance or delay SRT subtitles. Correct timing offset easily and download the synchronized file instantly.';
7
7
 
8
8
  const ui: SubtitleSyncUI = {
@@ -2,7 +2,7 @@ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dt
2
2
  import type { SubtitleSyncUI, SubtitleSyncLocaleContent } from '../index';
3
3
 
4
4
  const slug = 'sincronizar-subtitulos';
5
- const title = 'Sincronizar Subtítulos SRT Online - Ajusta el Tiempo Gratis';
5
+ const title = 'Sincronizar Subtítulos SRT Online: Ajusta el Tiempo Gratis';
6
6
  const description = 'Herramienta online para adelantar o retrasar subtítulos SRT. Corrige el desfase de tiempo de forma sencilla y descarga el archivo sincronizado al instante.';
7
7
 
8
8
  const ui: SubtitleSyncUI = {
@@ -2,7 +2,7 @@ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dt
2
2
  import type { SubtitleSyncUI, SubtitleSyncLocaleContent } from '../index';
3
3
 
4
4
  const slug = 'synchroniser-sous-titres-srt-en-ligne-ajuster-temps-gratuit';
5
- const title = 'Synchroniser les Sous-titres SRT en Ligne - Ajustez le Temps Gratuitement';
5
+ const title = 'Synchronisation SRT en Ligne: Ajustez le Temps Gratuitement';
6
6
  const description = 'Outil en ligne pour avancer ou retarder les sous-titres SRT. Corrigez le décalage de temps simplement et téléchargez le fichier synchronisé instantanément.';
7
7
 
8
8
  const ui: SubtitleSyncUI = {
@@ -43,7 +43,7 @@ const faq: SubtitleSyncLocaleContent['faq'] = [
43
43
  const howTo: SubtitleSyncLocaleContent['howTo'] = [
44
44
  {
45
45
  name: "Importez votre fichier SRT",
46
- text: "Faites glisser le fichier de sous-titres que vous souhaitez corriger dans la zone de téléchargement.",
46
+ text: "Faites glisser le fichier de sous titres que vous souhaitez corriger dans la zone de téléchargement.",
47
47
  },
48
48
  {
49
49
  name: "Identifiez le décalage",
@@ -73,7 +73,7 @@ const bibliography: SubtitleSyncLocaleContent['bibliography'] = [
73
73
  const seo: SubtitleSyncLocaleContent['seo'] = [
74
74
  {
75
75
  type: 'summary',
76
- title: 'Synchronisation de Sous-titres Professionnelle',
76
+ title: 'Synchronisation SRT Professionnelle',
77
77
  items: [
78
78
  'Correction instantanée des décalages audio-sous-titres',
79
79
  'Supporte les fichiers SRT (SubRip) standards',
@@ -81,7 +81,7 @@ const seo: SubtitleSyncLocaleContent['seo'] = [
81
81
  'Sans installation, sans abonnement, complètement gratuit'
82
82
  ]
83
83
  },
84
- { type: 'title', text: 'Synchronisation Parfaite de Sous-titres SRT', level: 2 },
84
+ { type: 'title', text: 'Synchronisation Parfaite de Sous titres SRT', level: 2 },
85
85
  { type: 'paragraph', html: 'Il n\'y a rien de plus frustrant que de voir des dialogues qui ne correspondent pas aux voix. Le décalage des sous-titres survient souvent à cause de différences entre les versions vidéo : variations de fréquence d\'images, coupures publicitaires, intros de production ou changements de compression. Avec cet outil, vous réglez le problème en quelques secondes.' },
86
86
 
87
87
  { type: 'stats', items: [
@@ -103,7 +103,7 @@ const seo: SubtitleSyncLocaleContent['seo'] = [
103
103
  { type: 'title', text: 'Cas d\'Utilisation Courants', level: 3 },
104
104
  { type: 'comparative', items: [
105
105
  {
106
- title: 'Traducteurs et Sous-titreurs',
106
+ title: 'Traducteurs et Professionnels SRT',
107
107
  description: 'Synchroniser des traductions après avoir travaillé avec plusieurs versions vidéo',
108
108
  icon: 'mdi:translate',
109
109
  points: [
@@ -135,7 +135,7 @@ const seo: SubtitleSyncLocaleContent['seo'] = [
135
135
  }
136
136
  ], columns: 3 },
137
137
 
138
- { type: 'title', text: 'Pourquoi les Sous-titres se Désynchronisent', level: 3 },
138
+ { type: 'title', text: 'Pourquoi les Sous titres se Désynchronisent', level: 3 },
139
139
  { type: 'table', headers: ['Cause Commune', 'Description Technique', 'Solution'], rows: [
140
140
  ['Différence de Framerate', '23,976 fps vs 25 fps - accumulation de différence', 'Ajustement du décalage unique (cet outil)'],
141
141
  ['Éditorialisation', 'Coupures publicitaires ou contenu supprimé', 'Calcul manuel + synchronisation'],
@@ -233,9 +233,9 @@ export const content: SubtitleSyncLocaleContent = {
233
233
  ui,
234
234
  seo,
235
235
  faq,
236
- faqTitle: 'Foire Aux Questions sur la Synchronisation des Sous-titres',
236
+ faqTitle: 'Foire Aux Questions sur la Synchronisation des Sous titres',
237
237
  bibliography,
238
- bibliographyTitle: 'Ressources Techniques sur les Formats de Sous-titres',
238
+ bibliographyTitle: 'Ressources Techniques sur les Formats de Sous titres',
239
239
  howTo,
240
240
  schemas: [faqSchema as any, howToSchema as any, appSchema],
241
241
  };