@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,241 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { SubtitleSyncUI, SubtitleSyncLocaleContent } from '../index';
3
+
4
+ const slug = 'online-srt-subtitle-synchronize-adjust-timing-free';
5
+ const title = '在线同步 SRT 字幕:免费调整时间轴';
6
+ const description = '在线调整 SRT 字幕提前或延迟的工具。轻松纠正时间偏差并立即下载同步后的文件。';
7
+
8
+ const ui: SubtitleSyncUI = {
9
+ dropTitle: "将您的 .SRT 文件拖到此处",
10
+ dropSubtitle: "或点击浏览文件",
11
+ adjustTitle: "调整时间",
12
+ offsetLabel: "偏移量(秒)",
13
+ offsetHelp: "使用负值表示提前(例如 -1.5),正值表示延迟。",
14
+ linesStat: "行数",
15
+ firstStat: "首条字幕",
16
+ lastStat: "末条字幕",
17
+ originalLabel: "原始时间",
18
+ resultLabel: "调整后时间",
19
+ downloadButton: "下载修正文件",
20
+ previewBadge: "预览",
21
+ unitSeconds: "秒"
22
+ };
23
+
24
+ const faq: SubtitleSyncLocaleContent['faq'] = [
25
+ {
26
+ question: "如果音频比字幕快,我该如何同步?",
27
+ answer: "如果声音出现在文字之前,您需要延迟字幕。在计算器中输入正值(例如输入 2.0 可以延迟 2 秒)。",
28
+ },
29
+ {
30
+ question: "此工具接受哪些文件格式?",
31
+ answer: "目前,该工具针对 .SRT (SubRip) 文件进行了优化,这是视频播放器和流媒体平台中最通用的标准格式。",
32
+ },
33
+ {
34
+ question: "上传我的字幕文件安全吗?",
35
+ answer: "是的,因为所有处理都在您的设备上 100% 本地完成。您的文件不会发送到任何服务器;同步直接在您的浏览器中进行。",
36
+ },
37
+ {
38
+ question: "我可以只同步文件的一部分吗?",
39
+ answer: "不可以,此工具对整个文件应用恒定的偏移量。如果偏移量是渐进式的(随时间变化),您可能需要更高级的编辑工具。",
40
+ },
41
+ ];
42
+
43
+ const howTo: SubtitleSyncLocaleContent['howTo'] = [
44
+ {
45
+ name: "上传您的 SRT 文件",
46
+ text: "将您想要纠正的字幕文件拖入上传区域。",
47
+ },
48
+ {
49
+ name: "确定偏移量",
50
+ text: "在您的播放器中测量字幕相对于音频延迟或提前了多少时间。",
51
+ },
52
+ {
53
+ name: "调整偏移量",
54
+ text: "在控制面板中输入正数(延迟)或负数(提前)的秒数。",
55
+ },
56
+ {
57
+ name: "下载文件",
58
+ text: "在预览中确认时间正确后,点击下载以获取新的 SRT 文件。",
59
+ },
60
+ ];
61
+
62
+ const bibliography: SubtitleSyncLocaleContent['bibliography'] = [
63
+ {
64
+ name: "SubRip (SRT) 格式规范",
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/zh-CN/docs/Web/API/FileReader",
70
+ },
71
+ ];
72
+
73
+ const seo: SubtitleSyncLocaleContent['seo'] = [
74
+ {
75
+ type: 'summary',
76
+ title: '专业字幕同步工具',
77
+ items: [
78
+ '即时纠正音频与字幕的时间偏差',
79
+ '支持标准 SRT (SubRip) 文件',
80
+ '100% 本地处理 - 隐私保障',
81
+ '无需安装,无需订阅,完全免费'
82
+ ]
83
+ },
84
+ { type: 'title', text: '完美的 SRT 字幕同步方案', level: 2 },
85
+ { type: 'paragraph', html: '对于观众来说,最令人沮丧的事莫过于看到的对白与声音对不上。字幕偏差通常由于视频版本差异引起:帧率变化、广告删减、片头差异或压缩方式改变。使用此工具,您可以在数秒内解决此问题。' },
86
+
87
+ { type: 'stats', items: [
88
+ { value: '100%', label: '本地处理', icon: 'mdi:shield' },
89
+ { value: '毫秒级', label: '精确度', icon: 'mdi:clock-outline' },
90
+ { value: '无限制', label: '无文件限制', icon: 'mdi:file-document' }
91
+ ], columns: 3 },
92
+
93
+ { type: 'title', text: '提前与延迟:实用指南', level: 3 },
94
+ { type: 'paragraph', html: '第一步是正确识别偏差类型。逻辑如下:' },
95
+ { type: 'list', items: [
96
+ '<strong>延迟(正值):</strong> 当您发现文字在声音出现之前就显示了(字幕过早)。例如:+2.0 秒。',
97
+ '<strong>提前(负值):</strong> 当您发现文字在声音出现之后才显示(字幕滞后)。例如:-2.0 秒。',
98
+ '<strong>测试与调整:</strong> 建议从较小增量(如 0.5s)开始,并使用预览功能进行验证。'
99
+ ], icon: 'mdi:arrow-right' },
100
+
101
+ { type: 'card', title: '专业级隐私保护', html: '通过客户端 JavaScript 处理文件,我们保证您的字幕内容永远不会离开您的电脑。对于处理机密材料或受 NDA(竞业/保密协议)约束的翻译人员和专业人士来说,这一点至关重要。' },
102
+
103
+ { type: 'title', text: '常见应用场景', level: 3 },
104
+ { type: 'comparative', items: [
105
+ {
106
+ title: '翻译人员与字幕组',
107
+ description: '在处理多个视频版本后快速同步翻译内容',
108
+ icon: 'mdi:translate',
109
+ points: [
110
+ '来自不同来源的 SRT 文件',
111
+ '内容版本管理(剧场版 vs 流媒体版)',
112
+ '无需切换工具即可快速交付'
113
+ ]
114
+ },
115
+ {
116
+ title: '内容创作者',
117
+ description: '当视频以不同帧率处理时恢复字幕同步',
118
+ icon: 'mdi:video',
119
+ points: [
120
+ '复用现有字幕',
121
+ '格式更改(从 720p 到 1080p)',
122
+ '避免对 1000 多行内容进行手动调时'
123
+ ],
124
+ highlight: true
125
+ },
126
+ {
127
+ title: '普通用户',
128
+ description: '修正下载的字幕与视频不匹配的问题',
129
+ icon: 'mdi:account',
130
+ points: [
131
+ '通用的下行同步问题',
132
+ '不同地区的电影版本(PAL vs NTSC)',
133
+ '针对剪辑版本进行微调'
134
+ ]
135
+ }
136
+ ], columns: 3 },
137
+
138
+ { type: 'title', text: '为什么字幕会不同步', level: 3 },
139
+ { type: 'table', headers: ['常见原因', '技术描述', '解决方案'], rows: [
140
+ ['帧率差异', '23.976 fps 对比 25 fps - 累积的偏差', '应用单个偏移量调整(本工具)'],
141
+ ['内容剪辑', '广告剪减或删除了额外内容', '手动计算 + 分段同步'],
142
+ ['地区版本', 'PAL(欧洲 25 fps)对比 NTSC(美国 29.97 fps)', '简单的数学偏移计算'],
143
+ ['分辨率改变', '以不同处理速度重新编码', '重新计算原始文件时间轴']
144
+ ] },
145
+
146
+ { type: 'diagnostic', variant: 'info', title: '需要注意的技术限制', icon: 'mdi:information', badge: '重要', html: '此工具对整个文件应用<strong>恒定</strong>的偏移。如果偏差是<strong>点进式</strong>的(开始是同步的,但后来逐渐不对齐),这通常意味着帧率不匹配。在这种情况下,原始文件需要在专业的剪辑软件中重新处理。' },
147
+
148
+ { type: 'proscons', items: [
149
+ {
150
+ pro: '极速体验 - 毫秒内处理大型文件',
151
+ con: '仅调整固定偏差,无法处理渐进式偏差'
152
+ },
153
+ {
154
+ pro: '极致隐私 - 内容永不离开浏览器',
155
+ con: '需要开启 JavaScript 的现代浏览器'
156
+ },
157
+ {
158
+ pro: '通用格式 - 支持任何标准 SRT 文件',
159
+ con: '不支持其他格式(ASS, VTT, SCC 等)'
160
+ },
161
+ {
162
+ pro: '完全免费,无广告,无追踪',
163
+ con: '无更改历史记录或版本管理'
164
+ }
165
+ ], proTitle: '优势', conTitle: '限制' },
166
+
167
+ { type: 'glossary', items: [
168
+ {
169
+ term: 'SRT (SubRip)',
170
+ definition: '最通用的字幕格式:包含序号、时间码 (hh:mm:ss,mmm) 和文本的纯文本文件。播放器和平台的通用标准。'
171
+ },
172
+ {
173
+ term: '偏移量 (Offset)',
174
+ definition: '对文件中所有时间码增加或减少的固定时长。可以是正数(延迟)或负数(提前)。'
175
+ },
176
+ {
177
+ term: '帧率 (fps)',
178
+ definition: '每秒帧数。常见的有 24p、PAL 25p、NTSC 29.97p 等。帧率不同会导致累积的时间轴偏差。'
179
+ },
180
+ {
181
+ term: 'NTSC 与 PAL',
182
+ definition: '地区电视标准:欧洲为 PAL (25 fps),美国为 NTSC (29.97 fps)。两者间有约 4% 的速度差异。'
183
+ },
184
+ {
185
+ term: '渐进式偏差 (Progressive Offset)',
186
+ definition: '指同步开始正确但随后逐渐偏离的现象。这通常意味着帧率不匹配,需要重新处理时间轴。'
187
+ }
188
+ ] },
189
+
190
+ { type: 'message', title: '全权掌握的专业编辑', ariaLabel: '关于同步的技术信息', html: '我们的方案简单而强大:应用即时处理的单偏移量,100% 在您的浏览器内完成。无云端,无存储,无追踪。只需上传、调整、下载。完全掌控您的内容。' },
191
+
192
+ { type: 'title', text: '总结:让观影无障碍', level: 3 },
193
+ { type: 'paragraph', html: '完美的字幕同步是高质量视听体验的基础。使用此工具,您可以将原本沮丧的体验转变为完美的电影之夜,无需昂贵或复杂的软件。' }
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: 'zh',
227
+ };
228
+
229
+ export const content: SubtitleSyncLocaleContent = {
230
+ slug,
231
+ title,
232
+ description,
233
+ ui,
234
+ seo,
235
+ faq,
236
+ faqTitle: '关于字幕同步的常见问题',
237
+ bibliography,
238
+ bibliographyTitle: '字幕格式技术资源',
239
+ howTo,
240
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
241
+ };
@@ -22,10 +22,6 @@ export interface SubtitleSyncUI {
22
22
 
23
23
  export type SubtitleSyncLocaleContent = ToolLocaleContent<SubtitleSyncUI>;
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 subtitleSync: AudiovisualToolEntry<SubtitleSyncUI> = {
30
26
  id: 'sincronizar-subtitulos',
31
27
  icons: {
@@ -33,9 +29,21 @@ export const subtitleSync: AudiovisualToolEntry<SubtitleSyncUI> = {
33
29
  fg: 'mdi:clock-time-four-outline',
34
30
  },
35
31
  i18n: {
36
- es: async () => es as unknown as SubtitleSyncLocaleContent,
37
- en: async () => en as unknown as SubtitleSyncLocaleContent,
38
- fr: async () => fr as unknown as SubtitleSyncLocaleContent,
32
+ es: async () => (await import('./i18n/es')).content as unknown as SubtitleSyncLocaleContent,
33
+ en: async () => (await import('./i18n/en')).content as unknown as SubtitleSyncLocaleContent,
34
+ fr: async () => (await import('./i18n/fr')).content as unknown as SubtitleSyncLocaleContent,
35
+ de: async () => (await import('./i18n/de')).content as unknown as SubtitleSyncLocaleContent,
36
+ it: async () => (await import('./i18n/it')).content as unknown as SubtitleSyncLocaleContent,
37
+ pt: async () => (await import('./i18n/pt')).content as unknown as SubtitleSyncLocaleContent,
38
+ id: async () => (await import('./i18n/id')).content as unknown as SubtitleSyncLocaleContent,
39
+ ja: async () => (await import('./i18n/ja')).content as unknown as SubtitleSyncLocaleContent,
40
+ ko: async () => (await import('./i18n/ko')).content as unknown as SubtitleSyncLocaleContent,
41
+ nl: async () => (await import('./i18n/nl')).content as unknown as SubtitleSyncLocaleContent,
42
+ pl: async () => (await import('./i18n/pl')).content as unknown as SubtitleSyncLocaleContent,
43
+ ru: async () => (await import('./i18n/ru')).content as unknown as SubtitleSyncLocaleContent,
44
+ sv: async () => (await import('./i18n/sv')).content as unknown as SubtitleSyncLocaleContent,
45
+ tr: async () => (await import('./i18n/tr')).content as unknown as SubtitleSyncLocaleContent,
46
+ zh: async () => (await import('./i18n/zh')).content as unknown as SubtitleSyncLocaleContent,
39
47
  },
40
48
  };
41
49
 
@@ -0,0 +1,169 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { TimelapseUI, TimelapseLocaleContent } from '../index';
3
+
4
+ const slug = 'timelapse-hyperlapse-rechner-perfekte-intervalle';
5
+ const title = 'Timelapse und Hyperlapse Rechner: Perfekte Intervalle';
6
+ const description = 'Berechnen Sie das exakte Intervall zwischen den Fotos, die Gesamtdauer und den Speicherplatz für Ihre Zeitrafferaufnahmen. Unverzichtbares Tool für Fotografen.';
7
+
8
+ const ui: TimelapseUI = {
9
+ title: "Zeitraffer Rechner",
10
+ paramsTitle: "Parameter",
11
+ eventDuration: "Wie lange dauert das reale Ereignis?",
12
+ hours: "Stunden",
13
+ minutes: "Minuten",
14
+ videoDuration: "Welches finale Video wünschen Sie?",
15
+ seconds: "Dauer (Sek.)",
16
+ fps: "FPS",
17
+ resultsTitle: "Ergebnisse",
18
+ intervalLabel: "Stellen Sie Ihr Intervallometer ein auf:",
19
+ secondsUnit: "Sekunden",
20
+ totalPhotos: "Gesamtzahl Fotos",
21
+ speed: "Geschwindigkeit",
22
+ shutterSpeed: "Verschlusszeit",
23
+ storage: "Größe (RAW)",
24
+ rule180Info: "Die 180°-Regel empfiehlt eine Verschlusszeit von der Hälfte des Intervalls für eine flüssige Bewegungsunschärfe.",
25
+ };
26
+
27
+ const faq: TimelapseLocaleContent['faq'] = [
28
+ {
29
+ question: "Wie wähle ich das richtige Intervall für meinen Zeitraffer?",
30
+ answer: "Es hängt von der Geschwindigkeit der Bewegung ab, die Sie aufnehmen. Für schnelle Wolken verwenden Sie 2-3 Sekunden. Für die Bewegung der Sonne oder Sterne 15-30 Sekunden. Für Pflanzenwachstum oder Baustellen 5-15 Minuten.",
31
+ },
32
+ {
33
+ question: "Wie viele Fotos benötige ich für ein einminütiges Video?",
34
+ answer: "Ein Standardvideo hat 24 oder 30 Bilder pro Sekunde (fps). Für eine Minute Video bei 24 fps benötigen Sie genau 1440 Fotos (60 Sekunden * 24 Fotos/Sekunde).",
35
+ },
36
+ {
37
+ question: "Was ist 'Flicker' und wie vermeide ich es?",
38
+ answer: "Es handelt sich um ein störendes Flackern, das durch kleine Belichtungsschwankungen zwischen den Fotos verursacht wird. Verwenden Sie immer den manuellen Modus (M), einen festen Weißabgleich und bevorzugen Sie Objektive mit manuellem Blendenring.",
39
+ },
40
+ {
41
+ question: "Warum ist die Verschlusszeit wichtig?",
42
+ answer: "Damit die Bewegung flüssig wirkt (180°-Regel), sollte die Verschlusszeit etwa die Hälfte des Intervalls betragen. Wenn das Intervall beispielsweise 2 Sekunden beträgt, versuchen Sie, mit 1 Sekunde zu belichten.",
43
+ },
44
+ ];
45
+
46
+ const howTo: TimelapseLocaleContent['howTo'] = [
47
+ {
48
+ name: "Dauer des finalen Videos festlegen",
49
+ text: "Geben Sie an, wie viele Sekunden oder Minuten das Ergebnisvideo dauern soll (z. B. 10 Sekunden für Instagram).",
50
+ },
51
+ {
52
+ name: "Ausgabe-FPS wählen",
53
+ text: "Wählen Sie die Flüssigkeit des Videos: 24 (Kino), 30 (Web) oder 60 (flüssige Zeitlupe).",
54
+ },
55
+ {
56
+ name: "Aufnahmeintervall anpassen",
57
+ text: "Konfigurieren Sie je nach Geschwindigkeit der Szene, alle wie viele Sekunden Ihre Kamera auslösen soll.",
58
+ },
59
+ {
60
+ name: "Speicherplatz prüfen",
61
+ text: "Der Rechner zeigt Ihnen an, wie viele Gigabyte die Sitzung beanspruchen wird. Stellen Sie sicher, dass Ihre SD Karte genügend Platz bietet.",
62
+ },
63
+ ];
64
+
65
+ const bibliography: TimelapseLocaleContent['bibliography'] = [
66
+ {
67
+ name: "Timescapes Forum - Digital Timelapse Acquisition & Processing",
68
+ url: "https://timescapes.org/phpBB3/viewforum.php?f=4",
69
+ },
70
+ {
71
+ name: "Magic Lantern - Auto ETTR & Bulb Ramping Algorithms",
72
+ url: "https://wiki.magiclantern.fm/ettr",
73
+ },
74
+ {
75
+ name: "LRTimelapse - Visual Deflicker & Holy Grail Workflow",
76
+ url: "https://lrtimelapse.com/tutorial/advanced/",
77
+ },
78
+ {
79
+ name: "PhotoPills - Advanced Timelapse Calculator & NPF Rule",
80
+ url: "https://www.photopills.com/calculators/timelapse",
81
+ },
82
+ ];
83
+
84
+ const seo: TimelapseLocaleContent['seo'] = [
85
+ { type: 'title', text: 'Der ultimative Leitfaden für Zeitraffer und Hyperlapse Intervalle', level: 2 },
86
+ { type: 'paragraph', html: 'Der Unterschied zwischen einem amateurhaften Schnelldurchlauf und einem <strong>kinoreifen Zeitraffer</strong> liegt mathematisch gesehen in einem einzigen Faktor: <strong>dem Intervall</strong>. Dieser Rechner nimmt Ihnen das Rätselraten ab und ermöglicht es Ihnen, Ihre Intervallometer-Aufnahmen präzise zu planen.' },
87
+
88
+ { type: 'title', text: 'Tabelle der empfohlenen Intervalle (Cheat Sheet)', level: 3 },
89
+ { type: 'paragraph', html: 'Nutzen Sie diese Schnellanleitung, um Ihr Intervallometer passend zum Motiv einzustellen. Ziel ist es, genug Bewegung einzufangen, damit sie wahrnehmbar, aber flüssig ist.' },
90
+ { type: 'table', headers: ['Motiv / Szene', 'Empfohlenes Intervall', 'Mindestdauer des Ereignisses'], rows: [
91
+ ['Schnelle Wolken / Gewitter', '1 - 2 Sekunden', '20 - 30 Min.'],
92
+ ['Stadtverkehr / Menschen (Blur)', '0,5 - 2 Sekunden', '15 - 20 Min.'],
93
+ ['Sonnenuntergang / Aufgang (Holy Grail)', '5 - 10 Sekunden', '1,5 - 2,5 Std.'],
94
+ ['Langsame Wolken / Schatten', '10 - 15 Sekunden', '2 - 3 Std.'],
95
+ ['Sterne / Milchstraße (Astro)', '15 - 30 Sekunden*', '3 - 5 Std.'],
96
+ ['Baustellen / Schnelle Pflanzen', '5 - 15 Minuten', 'Tage / Wochen']
97
+ ]},
98
+ { type: 'tip', title: 'Hinweis für Astro', html: 'Das Intervall wird meist durch die Belichtungszeit bestimmt (500er-Regel) + 1 oder 2 Sekunden Puffer für das Schreiben auf die Karte.' },
99
+
100
+ { type: 'title', text: 'Die 180° Regel (Bewegungsunschärfe)', level: 3 },
101
+ { type: 'paragraph', html: 'Ein häufiger Fehler bei Zeitraffern ist ein "ruckeliges" Video. Um den glatten Kino-Look zu erhalten, benötigen Sie <strong>Bewegungsunschärfe</strong>.' },
102
+ { type: 'card', title: 'Die Regel', icon: 'mdi:information', html: 'Ihre Verschlusszeit sollte die Hälfte Ihres Intervalls betragen. <br /><br /> <em>Beispiel:</em> Wenn Sie alle <strong>4 Sekunden</strong> fotografieren, sollte Ihre Belichtung <strong>2 Sekunden</strong> betragen.' },
103
+
104
+ { type: 'title', text: 'Flicker und manuelle Blende', level: 3 },
105
+ { type: 'paragraph', html: '"Flicker" ist das störende Flackern, das durch Mikroschwankungen der Blendenöffnung zwischen den Aufnahmen verursacht wird.' },
106
+ { type: 'list', items: [
107
+ '<strong>Lens Twist:</strong> Lösen Sie bei DSLRs das Objektiv leicht, um die elektronische Verbindung zu unterbrechen und die Blende mechanisch zu fixieren.',
108
+ '<strong>Alles Manuell:</strong> ISO, Weißabgleich und Fokus müssen fest eingestellt sein. Nutzen Sie niemals Automatikmodi.',
109
+ '<strong>In RAW fotografieren:</strong> Essenziell für die Korrektur von Belichtung und Farbe in der Nachbearbeitung.'
110
+ ]},
111
+
112
+ { type: 'diagnostic', variant: 'success', title: 'Fortgeschrittene Technik: Der "Heilige Gral"', icon: 'mdi:crown', badge: 'Profi-Technik', html: 'Der "Heilige Gral" bezeichnet den flüssigen Übergang von Tag zu Nacht (oder umgekehrt). Es ist eine der größten technischen Herausforderungen.' },
113
+
114
+ { type: 'stats', columns: 3, items: [
115
+ { label: 'Bulb Ramping', value: 'Gleitende Belichtung', icon: 'mdi:brightness-6' },
116
+ { label: 'Post-Pro', value: 'LRTimelapse', icon: 'mdi:television-guide' },
117
+ { label: 'Strategie', value: 'Nacht-Intervall', icon: 'mdi:weather-night' }
118
+ ]},
119
+
120
+ { type: 'title', text: 'Fazit: Die Zen der einfachen Mechanik', level: 3 },
121
+ { type: 'paragraph', html: 'Das Meistern Ihres Zeitraffers beginnt mit dem Verständnis der Mathematik hinter Ihrem Intervallometer.' }
122
+ ];
123
+
124
+ const faqSchema: WithContext<FAQPage> = {
125
+ '@context': 'https://schema.org',
126
+ '@type': 'FAQPage',
127
+ mainEntity: faq.map((item) => ({
128
+ '@type': 'Question',
129
+ name: item.question,
130
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
131
+ })),
132
+ };
133
+
134
+ const howToSchema: WithContext<HowTo> = {
135
+ '@context': 'https://schema.org',
136
+ '@type': 'HowTo',
137
+ name: title,
138
+ description,
139
+ step: howTo.map((step) => ({
140
+ '@type': 'HowToStep',
141
+ name: step.name,
142
+ text: step.text,
143
+ })),
144
+ };
145
+
146
+ const appSchema: WithContext<SoftwareApplication> = {
147
+ '@context': 'https://schema.org',
148
+ '@type': 'SoftwareApplication',
149
+ name: title,
150
+ description,
151
+ applicationCategory: 'UtilitiesApplication',
152
+ operatingSystem: 'Web',
153
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
154
+ inLanguage: 'de',
155
+ };
156
+
157
+ export const content: TimelapseLocaleContent = {
158
+ slug,
159
+ title,
160
+ description,
161
+ ui,
162
+ seo,
163
+ faq,
164
+ faqTitle: 'Häufig gestellte Fragen zur Zeitraffer Produktion',
165
+ bibliography,
166
+ bibliographyTitle: 'Zeitraffer Theorie und Ressourcen',
167
+ howTo,
168
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
169
+ };
@@ -58,7 +58,7 @@ const howTo: TimelapseLocaleContent['howTo'] = [
58
58
  },
59
59
  {
60
60
  name: "Vérifier l'espace de stockage",
61
- text: "La calculatrice vous dira combien de Gigaoctets la session occupera. Assurez-vous que votre carte SD a assez d'espace.",
61
+ text: "La calculatrice vous dira combien de Gigaoctets la session occupera. Assurez vous que votre carte SD a assez d'espace.",
62
62
  },
63
63
  ];
64
64
 
@@ -85,7 +85,7 @@ const seo: TimelapseLocaleContent['seo'] = [
85
85
  { type: 'title', text: 'Guide Ultime des Intervalles Timelapse et Hyperlapse', level: 2 },
86
86
  { type: 'paragraph', html: 'La différence entre une vidéo accélérée amateur et un <strong>timelapse cinématographique</strong> réside mathématiquement dans un seul facteur : <strong>l\'intervalle</strong>. Cette calculatrice élimine les devinettes, vous permettant de planifier avec précision la capture de levers de soleil, du trafic urbain ou de la Voie lactée.' },
87
87
 
88
- { type: 'title', text: 'Tableau des Intervalles Recommandés (Aide-mémoire)', level: 3 },
88
+ { type: 'title', text: 'Tableau des Intervalles Recommandés (Aide mémoire)', level: 3 },
89
89
  { type: 'paragraph', html: 'Utilisez ce tableau de référence rapide pour régler votre intervallomètre en fonction du sujet.' },
90
90
  { type: 'table', headers: ['Sujet / Scène', 'Intervalle Suggeré', 'Durée de l\'Événement (Minimum)'], rows: [
91
91
  ['Nuages rapides / Orages', '1 - 2 secondes', '20 - 30 min'],
@@ -0,0 +1,169 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { TimelapseUI, TimelapseLocaleContent } from '../index';
3
+
4
+ const slug = 'kalkulator-timelapse-hyperlapse-interval-sempurna';
5
+ const title = 'Kalkulator Timelapse dan Hyperlapse: Interval Sempurna';
6
+ const description = 'Hitung interval yang tepat di antara foto, durasi total, dan penyimpanan untuk timelapse Anda. Alat penting bagi fotografer.';
7
+
8
+ const ui: TimelapseUI = {
9
+ title: "Kalkulator Timelapse",
10
+ paramsTitle: "Parameter",
11
+ eventDuration: "Berapa lama durasi peristiwa aslinya?",
12
+ hours: "Jam",
13
+ minutes: "Menit",
14
+ videoDuration: "Berapa durasi video final yang Anda inginkan?",
15
+ seconds: "Durasi (detik)",
16
+ fps: "FPS",
17
+ resultsTitle: "Hasil",
18
+ intervalLabel: "Atur intervalometer Anda ke:",
19
+ secondsUnit: "detik",
20
+ totalPhotos: "Total Foto",
21
+ speed: "Kecepatan",
22
+ shutterSpeed: "Kecepatan Rana",
23
+ storage: "Ukuran (RAW)",
24
+ rule180Info: "Aturan 180° menyarankan kecepatan rana setengah dari interval untuk keburaman gerakan yang mulus.",
25
+ };
26
+
27
+ const faq: TimelapseLocaleContent['faq'] = [
28
+ {
29
+ question: "Bagaimana cara memilih interval yang benar untuk timelapse saya?",
30
+ answer: "Tergantung pada kecepatan gerakan yang Anda tangkap. Untuk awan yang bergerak cepat, gunakan 2-3 detik. Untuk pergerakan matahari atau bintang, gunakan 15-30 detik. Untuk pertumbuhan tanaman atau konstruksi bangunan, gunakan 5-15 menit.",
31
+ },
32
+ {
33
+ question: "Berapa banyak foto yang saya butuhkan untuk video berdurasi satu menit?",
34
+ answer: "Video standar memiliki 24 atau 30 bingkai per detik (fps). Untuk satu menit video pada 24fps, Anda membutuhkan tepat 1440 foto (60 detik * 24 foto/detik).",
35
+ },
36
+ {
37
+ question: "Apa itu 'Flicker' dan bagaimana cara menghindarinya?",
38
+ answer: "Flicker adalah kedipan yang mengganggu yang disebabkan oleh variasi kecil dalam pencahayaan antar foto. Untuk menghindarinya, selalu gunakan mode manual (M), white balance tetap, dan utamakan menggunakan lensa dengan cincin apertur manual.",
39
+ },
40
+ {
41
+ question: "Mengapa kecepatan rana itu penting?",
42
+ answer: "Agar gerakan terlihat mulus (aturan 180°), kecepatan rana harus sekitar setengah dari interval. Misalnya, jika intervalnya 2 detik, cobalah memotret pada 1 detik untuk membuat efek motion blur alami.",
43
+ },
44
+ ];
45
+
46
+ const howTo: TimelapseLocaleContent['howTo'] = [
47
+ {
48
+ name: "Tentukan durasi video final",
49
+ text: "Tentukan berapa detik atau menit durasi video akhir yang Anda inginkan (misalnya, 10 detik untuk Instagram).",
50
+ },
51
+ {
52
+ name: "Pilih FPS keluaran",
53
+ text: "Pilih kelancaran video: 24 (bioskop), 30 (web), atau 60 (slow motion yang mulus).",
54
+ },
55
+ {
56
+ name: "Atur interval pengambilan gambar",
57
+ text: "Konfigurasikan setiap berapa detik kamera Anda akan memotret sesuai dengan kecepatan adegan.",
58
+ },
59
+ {
60
+ name: "Verifikasi ruang penyimpanan",
61
+ text: "Kalkulator akan memberi tahu Anda berapa Gigabyte ruang yang akan digunakan sesi tersebut. Pastikan kartu SD Anda memiliki ruang yang cukup.",
62
+ },
63
+ ];
64
+
65
+ const bibliography: TimelapseLocaleContent['bibliography'] = [
66
+ {
67
+ name: "Timescapes Forum - Digital Timelapse Acquisition & Processing",
68
+ url: "https://timescapes.org/phpBB3/viewforum.php?f=4",
69
+ },
70
+ {
71
+ name: "Magic Lantern - Auto ETTR & Bulb Ramping Algorithms",
72
+ url: "https://wiki.magiclantern.fm/ettr",
73
+ },
74
+ {
75
+ name: "LRTimelapse - Visual Deflicker & Holy Grail Workflow",
76
+ url: "https://lrtimelapse.com/tutorial/advanced/",
77
+ },
78
+ {
79
+ name: "PhotoPills - Advanced Timelapse Calculator & NPF Rule",
80
+ url: "https://www.photopills.com/calculators/timelapse",
81
+ },
82
+ ];
83
+
84
+ const seo: TimelapseLocaleContent['seo'] = [
85
+ { type: 'title', text: 'Panduan Definitif untuk Interval Timelapse dan Hyperlapse', level: 2 },
86
+ { type: 'paragraph', html: 'Perbedaan antara video kecepatan tinggi amatir dan <strong>timelapse sinematik</strong> secara matematis terletak pada satu faktor tunggal: <strong>interval</strong>. Kalkulator ini menghilangkan keraguan, memungkinkan Anda merencanakan pemotretan intervalometer Anda dengan tepat.' },
87
+
88
+ { type: 'title', text: 'Tabel Interval yang Direkomendasikan (Cheat Sheet)', level: 3 },
89
+ { type: 'paragraph', html: 'Gunakan tabel referensi cepat ini untuk mengatur intervalometer Anda sesuai dengan subjeknya.' },
90
+ { type: 'table', headers: ['Subjek / Adegan', 'Saran Interval', 'Durasi Peristiwa (Minimum)'], rows: [
91
+ ['Awan Cepat / Badai', '1 - 2 detik', '20 - 30 menit'],
92
+ ['Lalu Lintas Kota / Orang (Blur)', '0.5 - 2 detik', '15 - 20 menit'],
93
+ ['Matahari Terbenam / Terbit (Holy Grail)', '5 - 10 detik', '1.5 - 2.5 jam'],
94
+ ['Awan Lambat / Bayangan', '10 - 15 detik', '2 - 3 jam'],
95
+ ['Bintang / Bima Sakti (Astro)', '15 - 30 detik*', '3 - 5 jam'],
96
+ ['Konstruksi / Pertumbuhan Tanaman', '5 - 15 menit', 'Hari / Minggu']
97
+ ]},
98
+ { type: 'tip', title: 'Catatan untuk Astro', html: 'Interval biasanya ditentukan oleh waktu pencahayaan yang dibutuhkan (aturan 500) + 1 atau 2 detik jeda untuk penulisan ke kartu memori.' },
99
+
100
+ { type: 'title', text: 'Aturan 180° (Motion Blur)', level: 3 },
101
+ { type: 'paragraph', html: 'Kesalahan umum dalam timelapse adalah mendapatkan video yang "patah-patah". Untuk mendapatkan tampilan sinematik yang mulus, Anda membutuhkan <strong>motion blur</strong>.' },
102
+ { type: 'card', title: 'Aturan', icon: 'mdi:information', html: 'Kecepatan Rana Anda harus setengah dari interval Anda. <br /><br /> <em>Contoh:</em> Jika Anda memotret setiap <strong>4 detik</strong>, pencahayaan Anda harus <strong>2 detik</strong>.' },
103
+
104
+ { type: 'title', text: 'Flicker dan Apertur Manual', level: 3 },
105
+ { type: 'paragraph', html: '"Flicker" adalah kedipan mengganggu yang disebabkan oleh variasi mikro dalam bukaan diafragma antar bidikan.' },
106
+ { type: 'list', items: [
107
+ '<strong>Lens Twist:</strong> Buka sedikit kunci lensa pada DSLR untuk memutus koneksi elektronik dan menetapkan apertur secara mekanis.',
108
+ '<strong>Semua Manual:</strong> ISO, White Balance, dan Fokus harus tetap. Jangan pernah gunakan mode otomatis.',
109
+ '<strong>Potret dalam RAW:</strong> Penting untuk mengoreksi pencahayaan dan warna di pascaproduksi.'
110
+ ]},
111
+
112
+ { type: 'diagnostic', variant: 'success', title: 'Teknik Lanjutan: "Holy Grail"', icon: 'mdi:crown', badge: 'Teknik Pro', html: '"Holy Grail" mengacu pada transisi mulus dari siang ke malam (atau sebaliknya). Ini adalah tantangan teknis tersulit dalam timelapse.' },
113
+
114
+ { type: 'stats', columns: 3, items: [
115
+ { label: 'Bulb Ramping', value: 'Exposure Bertahap', icon: 'mdi:brightness-6' },
116
+ { label: 'Post-Pro', value: 'LRTimelapse', icon: 'mdi:television-guide' },
117
+ { label: 'Strategi', value: 'Interval Malam', icon: 'mdi:weather-night' }
118
+ ]},
119
+
120
+ { type: 'title', text: 'Kesimpulan: Seni Mekanika Sederhana', level: 3 },
121
+ { type: 'paragraph', html: 'Menguasai timelapse Anda dimulai dengan memahami matematika intervalometer Anda.' }
122
+ ];
123
+
124
+ const faqSchema: WithContext<FAQPage> = {
125
+ '@context': 'https://schema.org',
126
+ '@type': 'FAQPage',
127
+ mainEntity: faq.map((item) => ({
128
+ '@type': 'Question',
129
+ name: item.question,
130
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
131
+ })),
132
+ };
133
+
134
+ const howToSchema: WithContext<HowTo> = {
135
+ '@context': 'https://schema.org',
136
+ '@type': 'HowTo',
137
+ name: title,
138
+ description,
139
+ step: howTo.map((step) => ({
140
+ '@type': 'HowToStep',
141
+ name: step.name,
142
+ text: step.text,
143
+ })),
144
+ };
145
+
146
+ const appSchema: WithContext<SoftwareApplication> = {
147
+ '@context': 'https://schema.org',
148
+ '@type': 'SoftwareApplication',
149
+ name: title,
150
+ description,
151
+ applicationCategory: 'UtilitiesApplication',
152
+ operatingSystem: 'Web',
153
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
154
+ inLanguage: 'id',
155
+ };
156
+
157
+ export const content: TimelapseLocaleContent = {
158
+ slug,
159
+ title,
160
+ description,
161
+ ui,
162
+ seo,
163
+ faq,
164
+ faqTitle: 'Pertanyaan yang Sering Diajukan tentang Produksi Timelapse',
165
+ bibliography,
166
+ bibliographyTitle: 'Teori dan Sumber Daya Timelapse',
167
+ howTo,
168
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
169
+ };