@jjlmoya/utils-chrono 1.2.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 (277) hide show
  1. package/package.json +65 -0
  2. package/scripts/postinstall.mjs +27 -0
  3. package/src/category/ChronoCategorySEO.astro +8 -0
  4. package/src/category/i18n/de.ts +23 -0
  5. package/src/category/i18n/en.ts +23 -0
  6. package/src/category/i18n/es.ts +23 -0
  7. package/src/category/i18n/fr.ts +23 -0
  8. package/src/category/i18n/id.ts +23 -0
  9. package/src/category/i18n/it.ts +23 -0
  10. package/src/category/i18n/ja.ts +23 -0
  11. package/src/category/i18n/ko.ts +23 -0
  12. package/src/category/i18n/nl.ts +23 -0
  13. package/src/category/i18n/pl.ts +23 -0
  14. package/src/category/i18n/pt.ts +23 -0
  15. package/src/category/i18n/ru.ts +23 -0
  16. package/src/category/i18n/sv.ts +23 -0
  17. package/src/category/i18n/tr.ts +23 -0
  18. package/src/category/i18n/zh.ts +23 -0
  19. package/src/category/index.ts +42 -0
  20. package/src/components/PreviewNavSidebar.astro +116 -0
  21. package/src/components/PreviewToolbar.astro +143 -0
  22. package/src/data.ts +11 -0
  23. package/src/entries.ts +32 -0
  24. package/src/env.d.ts +5 -0
  25. package/src/index.ts +28 -0
  26. package/src/layouts/PreviewLayout.astro +117 -0
  27. package/src/pages/[locale]/[slug].astro +161 -0
  28. package/src/pages/[locale].astro +251 -0
  29. package/src/pages/index.astro +4 -0
  30. package/src/tests/faq_count.test.ts +19 -0
  31. package/src/tests/i18n_coverage.test.ts +36 -0
  32. package/src/tests/locale_completeness.test.ts +29 -0
  33. package/src/tests/mocks/astro_mock.js +2 -0
  34. package/src/tests/no_h1_in_components.test.ts +48 -0
  35. package/src/tests/schemas_fulfillment.test.ts +23 -0
  36. package/src/tests/seo_length.test.ts +22 -0
  37. package/src/tests/shared-test-helpers.ts +56 -0
  38. package/src/tests/slug_language_code_format.test.ts +23 -0
  39. package/src/tests/slug_uniqueness.test.ts +81 -0
  40. package/src/tests/title_quality.test.ts +55 -0
  41. package/src/tests/tool_exports.test.ts +34 -0
  42. package/src/tests/tool_validation.test.ts +18 -0
  43. package/src/tool/beat-rate-converter/beat-rate-converter.css +301 -0
  44. package/src/tool/beat-rate-converter/bibliography.astro +16 -0
  45. package/src/tool/beat-rate-converter/bibliography.ts +12 -0
  46. package/src/tool/beat-rate-converter/client.ts +46 -0
  47. package/src/tool/beat-rate-converter/component.astro +15 -0
  48. package/src/tool/beat-rate-converter/components/ConverterPanel.astro +87 -0
  49. package/src/tool/beat-rate-converter/entry.ts +42 -0
  50. package/src/tool/beat-rate-converter/i18n/de.ts +138 -0
  51. package/src/tool/beat-rate-converter/i18n/en.ts +138 -0
  52. package/src/tool/beat-rate-converter/i18n/es.ts +138 -0
  53. package/src/tool/beat-rate-converter/i18n/fr.ts +138 -0
  54. package/src/tool/beat-rate-converter/i18n/id.ts +138 -0
  55. package/src/tool/beat-rate-converter/i18n/it.ts +138 -0
  56. package/src/tool/beat-rate-converter/i18n/ja.ts +138 -0
  57. package/src/tool/beat-rate-converter/i18n/ko.ts +138 -0
  58. package/src/tool/beat-rate-converter/i18n/nl.ts +138 -0
  59. package/src/tool/beat-rate-converter/i18n/pl.ts +138 -0
  60. package/src/tool/beat-rate-converter/i18n/pt.ts +138 -0
  61. package/src/tool/beat-rate-converter/i18n/ru.ts +138 -0
  62. package/src/tool/beat-rate-converter/i18n/sv.ts +138 -0
  63. package/src/tool/beat-rate-converter/i18n/tr.ts +138 -0
  64. package/src/tool/beat-rate-converter/i18n/zh.ts +138 -0
  65. package/src/tool/beat-rate-converter/index.ts +11 -0
  66. package/src/tool/beat-rate-converter/seo.astro +16 -0
  67. package/src/tool/crown-reference-guide/bibliography.astro +16 -0
  68. package/src/tool/crown-reference-guide/bibliography.ts +20 -0
  69. package/src/tool/crown-reference-guide/client.ts +193 -0
  70. package/src/tool/crown-reference-guide/component.astro +69 -0
  71. package/src/tool/crown-reference-guide/components/CrownView.astro +40 -0
  72. package/src/tool/crown-reference-guide/components/MovementSelector.astro +26 -0
  73. package/src/tool/crown-reference-guide/components/PositionPanel.astro +59 -0
  74. package/src/tool/crown-reference-guide/crown-reference-guide.css +383 -0
  75. package/src/tool/crown-reference-guide/entry.ts +60 -0
  76. package/src/tool/crown-reference-guide/i18n/de.ts +207 -0
  77. package/src/tool/crown-reference-guide/i18n/en.ts +207 -0
  78. package/src/tool/crown-reference-guide/i18n/es.ts +207 -0
  79. package/src/tool/crown-reference-guide/i18n/fr.ts +207 -0
  80. package/src/tool/crown-reference-guide/i18n/id.ts +207 -0
  81. package/src/tool/crown-reference-guide/i18n/it.ts +207 -0
  82. package/src/tool/crown-reference-guide/i18n/ja.ts +207 -0
  83. package/src/tool/crown-reference-guide/i18n/ko.ts +207 -0
  84. package/src/tool/crown-reference-guide/i18n/nl.ts +207 -0
  85. package/src/tool/crown-reference-guide/i18n/pl.ts +207 -0
  86. package/src/tool/crown-reference-guide/i18n/pt.ts +207 -0
  87. package/src/tool/crown-reference-guide/i18n/ru.ts +207 -0
  88. package/src/tool/crown-reference-guide/i18n/sv.ts +207 -0
  89. package/src/tool/crown-reference-guide/i18n/tr.ts +207 -0
  90. package/src/tool/crown-reference-guide/i18n/zh.ts +207 -0
  91. package/src/tool/crown-reference-guide/index.ts +11 -0
  92. package/src/tool/crown-reference-guide/seo.astro +16 -0
  93. package/src/tool/crown-reference-guide/utils.ts +0 -0
  94. package/src/tool/demagnetizing-timer/bibliography.astro +16 -0
  95. package/src/tool/demagnetizing-timer/bibliography.ts +12 -0
  96. package/src/tool/demagnetizing-timer/client.ts +221 -0
  97. package/src/tool/demagnetizing-timer/component.astro +15 -0
  98. package/src/tool/demagnetizing-timer/components/TimerPanel.astro +92 -0
  99. package/src/tool/demagnetizing-timer/demagnetizing-timer.css +389 -0
  100. package/src/tool/demagnetizing-timer/entry.ts +50 -0
  101. package/src/tool/demagnetizing-timer/helpers/field.ts +134 -0
  102. package/src/tool/demagnetizing-timer/i18n/de.ts +143 -0
  103. package/src/tool/demagnetizing-timer/i18n/en.ts +143 -0
  104. package/src/tool/demagnetizing-timer/i18n/es.ts +143 -0
  105. package/src/tool/demagnetizing-timer/i18n/fr.ts +143 -0
  106. package/src/tool/demagnetizing-timer/i18n/id.ts +143 -0
  107. package/src/tool/demagnetizing-timer/i18n/it.ts +143 -0
  108. package/src/tool/demagnetizing-timer/i18n/ja.ts +143 -0
  109. package/src/tool/demagnetizing-timer/i18n/ko.ts +143 -0
  110. package/src/tool/demagnetizing-timer/i18n/nl.ts +143 -0
  111. package/src/tool/demagnetizing-timer/i18n/pl.ts +143 -0
  112. package/src/tool/demagnetizing-timer/i18n/pt.ts +143 -0
  113. package/src/tool/demagnetizing-timer/i18n/ru.ts +143 -0
  114. package/src/tool/demagnetizing-timer/i18n/sv.ts +143 -0
  115. package/src/tool/demagnetizing-timer/i18n/tr.ts +143 -0
  116. package/src/tool/demagnetizing-timer/i18n/zh.ts +143 -0
  117. package/src/tool/demagnetizing-timer/index.ts +11 -0
  118. package/src/tool/demagnetizing-timer/seo.astro +16 -0
  119. package/src/tool/demagnetizing-timer/utils.ts +0 -0
  120. package/src/tool/power-reserve-estimator/bibliography.astro +16 -0
  121. package/src/tool/power-reserve-estimator/bibliography.ts +16 -0
  122. package/src/tool/power-reserve-estimator/client.ts +139 -0
  123. package/src/tool/power-reserve-estimator/component.astro +15 -0
  124. package/src/tool/power-reserve-estimator/components/EstimatorPanel.astro +150 -0
  125. package/src/tool/power-reserve-estimator/entry.ts +51 -0
  126. package/src/tool/power-reserve-estimator/i18n/de.ts +158 -0
  127. package/src/tool/power-reserve-estimator/i18n/en.ts +158 -0
  128. package/src/tool/power-reserve-estimator/i18n/es.ts +158 -0
  129. package/src/tool/power-reserve-estimator/i18n/fr.ts +158 -0
  130. package/src/tool/power-reserve-estimator/i18n/id.ts +158 -0
  131. package/src/tool/power-reserve-estimator/i18n/it.ts +158 -0
  132. package/src/tool/power-reserve-estimator/i18n/ja.ts +158 -0
  133. package/src/tool/power-reserve-estimator/i18n/ko.ts +158 -0
  134. package/src/tool/power-reserve-estimator/i18n/nl.ts +158 -0
  135. package/src/tool/power-reserve-estimator/i18n/pl.ts +158 -0
  136. package/src/tool/power-reserve-estimator/i18n/pt.ts +158 -0
  137. package/src/tool/power-reserve-estimator/i18n/ru.ts +158 -0
  138. package/src/tool/power-reserve-estimator/i18n/sv.ts +158 -0
  139. package/src/tool/power-reserve-estimator/i18n/tr.ts +158 -0
  140. package/src/tool/power-reserve-estimator/i18n/zh.ts +158 -0
  141. package/src/tool/power-reserve-estimator/index.ts +11 -0
  142. package/src/tool/power-reserve-estimator/power-reserve-estimator.css +402 -0
  143. package/src/tool/power-reserve-estimator/seo.astro +16 -0
  144. package/src/tool/strap-taper-calculator/bibliography.astro +16 -0
  145. package/src/tool/strap-taper-calculator/bibliography.ts +12 -0
  146. package/src/tool/strap-taper-calculator/client.ts +129 -0
  147. package/src/tool/strap-taper-calculator/component.astro +15 -0
  148. package/src/tool/strap-taper-calculator/components/CalculatorPanel.astro +114 -0
  149. package/src/tool/strap-taper-calculator/entry.ts +56 -0
  150. package/src/tool/strap-taper-calculator/i18n/de.ts +152 -0
  151. package/src/tool/strap-taper-calculator/i18n/en.ts +152 -0
  152. package/src/tool/strap-taper-calculator/i18n/es.ts +152 -0
  153. package/src/tool/strap-taper-calculator/i18n/fr.ts +152 -0
  154. package/src/tool/strap-taper-calculator/i18n/id.ts +152 -0
  155. package/src/tool/strap-taper-calculator/i18n/it.ts +152 -0
  156. package/src/tool/strap-taper-calculator/i18n/ja.ts +152 -0
  157. package/src/tool/strap-taper-calculator/i18n/ko.ts +152 -0
  158. package/src/tool/strap-taper-calculator/i18n/nl.ts +152 -0
  159. package/src/tool/strap-taper-calculator/i18n/pl.ts +152 -0
  160. package/src/tool/strap-taper-calculator/i18n/pt.ts +152 -0
  161. package/src/tool/strap-taper-calculator/i18n/ru.ts +152 -0
  162. package/src/tool/strap-taper-calculator/i18n/sv.ts +152 -0
  163. package/src/tool/strap-taper-calculator/i18n/tr.ts +152 -0
  164. package/src/tool/strap-taper-calculator/i18n/zh.ts +152 -0
  165. package/src/tool/strap-taper-calculator/index.ts +11 -0
  166. package/src/tool/strap-taper-calculator/seo.astro +16 -0
  167. package/src/tool/strap-taper-calculator/strap-taper-calculator.css +320 -0
  168. package/src/tool/watch-accuracy-tracker/bibliography.astro +16 -0
  169. package/src/tool/watch-accuracy-tracker/bibliography.ts +12 -0
  170. package/src/tool/watch-accuracy-tracker/chart.ts +126 -0
  171. package/src/tool/watch-accuracy-tracker/client.ts +287 -0
  172. package/src/tool/watch-accuracy-tracker/component.astro +35 -0
  173. package/src/tool/watch-accuracy-tracker/components/AccuracyTracker.astro +96 -0
  174. package/src/tool/watch-accuracy-tracker/components/DriftPredictor.astro +126 -0
  175. package/src/tool/watch-accuracy-tracker/components/LogHistory.astro +66 -0
  176. package/src/tool/watch-accuracy-tracker/entry.ts +94 -0
  177. package/src/tool/watch-accuracy-tracker/i18n/de.ts +167 -0
  178. package/src/tool/watch-accuracy-tracker/i18n/en.ts +167 -0
  179. package/src/tool/watch-accuracy-tracker/i18n/es.ts +167 -0
  180. package/src/tool/watch-accuracy-tracker/i18n/fr.ts +167 -0
  181. package/src/tool/watch-accuracy-tracker/i18n/id.ts +167 -0
  182. package/src/tool/watch-accuracy-tracker/i18n/it.ts +167 -0
  183. package/src/tool/watch-accuracy-tracker/i18n/ja.ts +167 -0
  184. package/src/tool/watch-accuracy-tracker/i18n/ko.ts +167 -0
  185. package/src/tool/watch-accuracy-tracker/i18n/nl.ts +167 -0
  186. package/src/tool/watch-accuracy-tracker/i18n/pl.ts +167 -0
  187. package/src/tool/watch-accuracy-tracker/i18n/pt.ts +167 -0
  188. package/src/tool/watch-accuracy-tracker/i18n/ru.ts +167 -0
  189. package/src/tool/watch-accuracy-tracker/i18n/sv.ts +167 -0
  190. package/src/tool/watch-accuracy-tracker/i18n/tr.ts +167 -0
  191. package/src/tool/watch-accuracy-tracker/i18n/zh.ts +167 -0
  192. package/src/tool/watch-accuracy-tracker/index.ts +9 -0
  193. package/src/tool/watch-accuracy-tracker/logger.ts +105 -0
  194. package/src/tool/watch-accuracy-tracker/seo.astro +16 -0
  195. package/src/tool/watch-accuracy-tracker/utils.ts +99 -0
  196. package/src/tool/watch-accuracy-tracker/watch-accuracy-tracker.css +564 -0
  197. package/src/tool/watch-savings-planner/bibliography.astro +16 -0
  198. package/src/tool/watch-savings-planner/bibliography.ts +8 -0
  199. package/src/tool/watch-savings-planner/client.ts +271 -0
  200. package/src/tool/watch-savings-planner/component.astro +33 -0
  201. package/src/tool/watch-savings-planner/components/AddGoalForm.astro +49 -0
  202. package/src/tool/watch-savings-planner/components/GoalCard.astro +58 -0
  203. package/src/tool/watch-savings-planner/entry.ts +62 -0
  204. package/src/tool/watch-savings-planner/i18n/de.ts +153 -0
  205. package/src/tool/watch-savings-planner/i18n/en.ts +155 -0
  206. package/src/tool/watch-savings-planner/i18n/es.ts +153 -0
  207. package/src/tool/watch-savings-planner/i18n/fr.ts +153 -0
  208. package/src/tool/watch-savings-planner/i18n/id.ts +153 -0
  209. package/src/tool/watch-savings-planner/i18n/it.ts +153 -0
  210. package/src/tool/watch-savings-planner/i18n/ja.ts +153 -0
  211. package/src/tool/watch-savings-planner/i18n/ko.ts +153 -0
  212. package/src/tool/watch-savings-planner/i18n/nl.ts +153 -0
  213. package/src/tool/watch-savings-planner/i18n/pl.ts +153 -0
  214. package/src/tool/watch-savings-planner/i18n/pt.ts +153 -0
  215. package/src/tool/watch-savings-planner/i18n/ru.ts +153 -0
  216. package/src/tool/watch-savings-planner/i18n/sv.ts +153 -0
  217. package/src/tool/watch-savings-planner/i18n/tr.ts +153 -0
  218. package/src/tool/watch-savings-planner/i18n/zh.ts +153 -0
  219. package/src/tool/watch-savings-planner/index.ts +11 -0
  220. package/src/tool/watch-savings-planner/seo.astro +16 -0
  221. package/src/tool/watch-savings-planner/utils.ts +0 -0
  222. package/src/tool/watch-savings-planner/watch-savings-planner.css +460 -0
  223. package/src/tool/water-resistance-converter/bibliography.astro +16 -0
  224. package/src/tool/water-resistance-converter/bibliography.ts +16 -0
  225. package/src/tool/water-resistance-converter/client.ts +56 -0
  226. package/src/tool/water-resistance-converter/component.astro +15 -0
  227. package/src/tool/water-resistance-converter/components/ConverterPanel.astro +113 -0
  228. package/src/tool/water-resistance-converter/entry.ts +52 -0
  229. package/src/tool/water-resistance-converter/i18n/de.ts +148 -0
  230. package/src/tool/water-resistance-converter/i18n/en.ts +148 -0
  231. package/src/tool/water-resistance-converter/i18n/es.ts +148 -0
  232. package/src/tool/water-resistance-converter/i18n/fr.ts +148 -0
  233. package/src/tool/water-resistance-converter/i18n/id.ts +148 -0
  234. package/src/tool/water-resistance-converter/i18n/it.ts +148 -0
  235. package/src/tool/water-resistance-converter/i18n/ja.ts +148 -0
  236. package/src/tool/water-resistance-converter/i18n/ko.ts +148 -0
  237. package/src/tool/water-resistance-converter/i18n/nl.ts +148 -0
  238. package/src/tool/water-resistance-converter/i18n/pl.ts +148 -0
  239. package/src/tool/water-resistance-converter/i18n/pt.ts +148 -0
  240. package/src/tool/water-resistance-converter/i18n/ru.ts +148 -0
  241. package/src/tool/water-resistance-converter/i18n/sv.ts +148 -0
  242. package/src/tool/water-resistance-converter/i18n/tr.ts +148 -0
  243. package/src/tool/water-resistance-converter/i18n/zh.ts +148 -0
  244. package/src/tool/water-resistance-converter/index.ts +11 -0
  245. package/src/tool/water-resistance-converter/seo.astro +16 -0
  246. package/src/tool/water-resistance-converter/water-resistance-converter.css +254 -0
  247. package/src/tool/wrist-presence-calculator/bibliography.astro +16 -0
  248. package/src/tool/wrist-presence-calculator/bibliography.ts +12 -0
  249. package/src/tool/wrist-presence-calculator/client.ts +180 -0
  250. package/src/tool/wrist-presence-calculator/component.astro +23 -0
  251. package/src/tool/wrist-presence-calculator/components/CalculatorInputs.astro +97 -0
  252. package/src/tool/wrist-presence-calculator/components/FitResult.astro +68 -0
  253. package/src/tool/wrist-presence-calculator/components/Visualizer.astro +16 -0
  254. package/src/tool/wrist-presence-calculator/entry.ts +59 -0
  255. package/src/tool/wrist-presence-calculator/helpers/canvas.ts +189 -0
  256. package/src/tool/wrist-presence-calculator/helpers/results.ts +78 -0
  257. package/src/tool/wrist-presence-calculator/i18n/de.ts +139 -0
  258. package/src/tool/wrist-presence-calculator/i18n/en.ts +155 -0
  259. package/src/tool/wrist-presence-calculator/i18n/es.ts +139 -0
  260. package/src/tool/wrist-presence-calculator/i18n/fr.ts +139 -0
  261. package/src/tool/wrist-presence-calculator/i18n/id.ts +139 -0
  262. package/src/tool/wrist-presence-calculator/i18n/it.ts +139 -0
  263. package/src/tool/wrist-presence-calculator/i18n/ja.ts +139 -0
  264. package/src/tool/wrist-presence-calculator/i18n/ko.ts +139 -0
  265. package/src/tool/wrist-presence-calculator/i18n/nl.ts +139 -0
  266. package/src/tool/wrist-presence-calculator/i18n/pl.ts +139 -0
  267. package/src/tool/wrist-presence-calculator/i18n/pt.ts +139 -0
  268. package/src/tool/wrist-presence-calculator/i18n/ru.ts +139 -0
  269. package/src/tool/wrist-presence-calculator/i18n/sv.ts +139 -0
  270. package/src/tool/wrist-presence-calculator/i18n/tr.ts +139 -0
  271. package/src/tool/wrist-presence-calculator/i18n/zh.ts +155 -0
  272. package/src/tool/wrist-presence-calculator/index.ts +11 -0
  273. package/src/tool/wrist-presence-calculator/seo.astro +16 -0
  274. package/src/tool/wrist-presence-calculator/utils.ts +30 -0
  275. package/src/tool/wrist-presence-calculator/wrist-presence-calculator.css +372 -0
  276. package/src/tools.ts +26 -0
  277. package/src/types.ts +70 -0
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@jjlmoya/utils-chrono",
3
+ "version": "1.2.0",
4
+ "type": "module",
5
+ "main": "./src/index.ts",
6
+ "types": "./src/index.ts",
7
+ "exports": {
8
+ ".": "./src/index.ts",
9
+ "./data": "./src/data.ts",
10
+ "./entries": "./src/entries.ts"
11
+ },
12
+ "files": [
13
+ "src",
14
+ "scripts"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "scripts": {
20
+ "dev": "astro dev",
21
+ "start": "astro dev",
22
+ "build": "astro build",
23
+ "preview": "astro preview",
24
+ "astro": "astro",
25
+ "lint": "eslint src/ --max-warnings 0 && stylelint \"src/**/*.{css,astro}\"",
26
+ "check": "astro check",
27
+ "type-check": "astro check",
28
+ "test": "vitest run",
29
+ "preversion": "npm run lint && npm run test",
30
+ "postversion": "git push && git push --tags",
31
+ "patch": "npm version patch",
32
+ "minor": "npm version minor",
33
+ "major": "npm version major",
34
+ "postinstall": "node scripts/postinstall.mjs"
35
+ },
36
+ "lint-staged": {
37
+ "*.{ts,tsx,astro}": [
38
+ "eslint --fix"
39
+ ]
40
+ },
41
+ "dependencies": {
42
+ "@iconify-json/mdi": "^1.2.3",
43
+ "@jjlmoya/prompagate": "^1.1.0",
44
+ "@jjlmoya/utils-shared": "1.2.0",
45
+ "astro": "^6.1.2",
46
+ "astro-icon": "^1.1.0",
47
+ "html2canvas": "^1.4.1"
48
+ },
49
+ "devDependencies": {
50
+ "@astrojs/check": "^0.9.8",
51
+ "eslint": "^9.39.4",
52
+ "eslint-plugin-astro": "^1.6.0",
53
+ "eslint-plugin-no-comments": "^1.1.10",
54
+ "husky": "^9.1.7",
55
+ "lint-staged": "^16.4.0",
56
+ "postcss-html": "^1.8.1",
57
+ "schema-dts": "^1.1.2",
58
+ "stylelint": "^17.6.0",
59
+ "stylelint-config-standard": "^40.0.0",
60
+ "stylelint-declaration-strict-value": "^1.11.1",
61
+ "typescript": "^5.4.0",
62
+ "typescript-eslint": "^8.58.0",
63
+ "vitest": "^4.1.2"
64
+ }
65
+ }
@@ -0,0 +1,27 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const libDir = dirname(fileURLToPath(import.meta.url));
6
+ const toolsDir = join(libDir, '../src/tool');
7
+
8
+ const inNodeModules = libDir.includes('node_modules');
9
+ if (!inNodeModules) process.exit(0);
10
+
11
+ const projectRoot = join(libDir, '../../../..');
12
+ const categoryKey = JSON.parse(readFileSync(join(libDir, '../package.json'), 'utf8')).name.replace('@jjlmoya/utils-', '');
13
+ const destDir = join(projectRoot, `public/styles/lib/${categoryKey}`);
14
+
15
+ mkdirSync(destDir, { recursive: true });
16
+
17
+ const tools = readdirSync(toolsDir, { withFileTypes: true }).filter(d => d.isDirectory());
18
+ for (const tool of tools) {
19
+ const toolDir = join(toolsDir, tool.name);
20
+ let files;
21
+ try { files = readdirSync(toolDir).filter(f => f.endsWith('.css')); }
22
+ catch { continue; }
23
+ for (const file of files) {
24
+ writeFileSync(join(destDir, file), readFileSync(join(toolDir, file)));
25
+ console.log(`[@jjlmoya/utils-${categoryKey}] copied ${file}`);
26
+ }
27
+ }
@@ -0,0 +1,8 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { chronoCategory } from './index';
4
+
5
+ const categoryContent = await chronoCategory.i18n.es?.();
6
+ ---
7
+
8
+ {categoryContent && <SEORenderer content={{ locale: 'es', sections: categoryContent.seo }} />}
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horologie';
4
+ const title = 'Uhrmacherwerkzeuge & Referenzführer';
5
+ const description = 'Professionelle uhrmacherische Hilfsmittel für Uhrenliebhaber — verfolgen Sie die Ganggenauigkeit, entmagnetisieren Sie Uhrwerke, berechnen Sie die Tragedauer am Handgelenk und erkunden Sie Kronenpositions-Referenzen für gängige Kaliber.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Wesentliche Werkzeuge für Uhrenliebhaber', level: 2 },
13
+ { type: 'paragraph', html: 'Ob Sie ein mechanisches Uhrwerk regulieren, eine kürzlich magnetisierte Uhr entmagnetisieren, nachverfolgen wie oft Sie eine Uhr tragen oder die Kronenpositionen Ihres Lieblingskalibers lernen — diese Suite legt professionelle uhrmacherische Werkzeuge in Ihre Hände, ganz ohne teure Ausrüstung.' },
14
+ { type: 'title', text: 'Ganggenauigkeit, Entmagnetisierung & Kronenreferenzen', level: 2 },
15
+ { type: 'paragraph', html: 'Von der täglichen Abweichungsmessung gegen Atomzeit über das sichere Entmagnetisieren eines Uhrwerks mit präzisem Timing, vom Wissen wann Sie Ihre Uhr zuletzt getragen haben bis zum Verständnis jeder Kronenposition an einem ETA- oder Miyota-Kaliber — diese Werkzeuge decken die täglichen Bedürfnisse jedes Sammlers und Liebhabers ab.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Werkzeuge', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Kaliber', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Sprachen', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Datenschutz', value: 'Lokal', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horology';
4
+ const title = 'Horology Tools & Reference Guides';
5
+ const description = 'Professional-grade horology utilities for watch enthusiasts — track accuracy, demagnetize movements, calculate wrist presence, and explore crown position references for popular calibers.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Essential Tools for Watch Enthusiasts', level: 2 },
13
+ { type: 'paragraph', html: 'Whether you are regulating a mechanical movement, demagnetizing a recently magnetized watch, tracking how often you wear a timepiece, or learning the crown positions of your favorite caliber, this suite puts professional-grade horology tools at your fingertips — no expensive equipment required.' },
14
+ { type: 'title', text: 'Accuracy, Demagnetization & Crown References', level: 2 },
15
+ { type: 'paragraph', html: 'From tracking daily rate deviation against atomic time to safely demagnetizing a movement with precise timing, from knowing exactly when you last wore a watch to understanding every crown position on an ETA or Miyota caliber — these tools cover the day-to-day needs of any collector or enthusiast.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Tools', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Calibers', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Languages', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Data Privacy', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horologia';
4
+ const title = 'Herramientas de Relojería y Guías de Referencia';
5
+ const description = 'Utilidades de relojería de grado profesional para entusiastas del reloj: mide la precisión, desmagnetiza movimientos, calcula el uso en muñeca y explora referencias de posiciones de corona para calibres populares.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Herramientas Esenciales para Entusiastas del Reloj', level: 2 },
13
+ { type: 'paragraph', html: 'Ya sea que estés regulando un movimiento mecánico, desmagnetizando un reloj recién magnetizado, registrando con qué frecuencia usas un reloj o aprendiendo las posiciones de la corona de tu calibre favorito, esta suite pone herramientas profesionales de relojería al alcance de tu mano, sin necesidad de equipos costosos.' },
14
+ { type: 'title', text: 'Precisión, Desmagnetización y Referencias de Corona', level: 2 },
15
+ { type: 'paragraph', html: 'Desde medir la desviación diaria contra el tiempo atómico hasta desmagnetizar un movimiento con una temporización precisa, desde saber exactamente cuándo usaste un reloj por última vez hasta entender cada posición de la corona en un calibre ETA o Miyota: estas herramientas cubren las necesidades diarias de cualquier coleccionista o entusiasta.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Herramientas', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Calibres', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Idiomas', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Privacidad', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horlogerie';
4
+ const title = "Outils d'Horlogerie et Guides de Référence";
5
+ const description = "Des utilitaires d'horlogerie de qualité professionnelle pour les passionnés de montres — suivez la précision, démagnétisez les mouvements, calculez le temps de port au poignet et explorez les références de positions de couronne pour les calibres populaires.";
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: "Outils Essentiels pour les Passionnés de Montres", level: 2 },
13
+ { type: 'paragraph', html: "Que vous régliez un mouvement mécanique, que vous démagnétisiez une montre récemment aimantée, que vous suiviez la fréquence à laquelle vous portez une montre ou que vous appreniez les positions de couronne de votre calibre préféré, cette suite met à votre disposition des outils d'horlogerie professionnels — sans équipement coûteux." },
14
+ { type: 'title', text: "Précision, Démagnétisation et Références de Couronne", level: 2 },
15
+ { type: 'paragraph', html: "Du suivi de l'écart quotidien par rapport au temps atomique à la démagnétisation sécurisée d'un mouvement avec un timing précis, en passant par la connaissance du dernier porté de votre montre et la compréhension de chaque position de couronne sur un calibre ETA ou Miyota — ces outils couvrent les besoins quotidiens de tout collectionneur ou passionné." },
16
+ { type: 'stats', items: [
17
+ { label: 'Outils', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Calibres', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Langues', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Confidentialité', value: 'Locale', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horologi';
4
+ const title = 'Alat Horologi & Panduan Referensi';
5
+ const description = 'Utilitas horologi kelas profesional untuk penggemar jam tangan — lacak akurasi, demagnetisasi gerakan, hitung kehadiran di pergelangan tangan, dan jelajahi referensi posisi mahkota untuk kaliber populer.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Peralatan Penting untuk Penggemar Jam Tangan', level: 2 },
13
+ { type: 'paragraph', html: 'Baik Anda sedang menyetel gerakan mekanis, mendemagnetisasi jam tangan yang baru termagnetisasi, melacak seberapa sering Anda memakai arloji, atau mempelajari posisi mahkota kaliber favorit Anda, rangkaian ini menghadirkan alat horologi kelas profesional di ujung jari Anda — tanpa perlu peralatan mahal.' },
14
+ { type: 'title', text: 'Akurasi, Demagnetisasi & Referensi Posisi Mahkota', level: 2 },
15
+ { type: 'paragraph', html: 'Mulai dari melacak deviasi laju harian terhadap waktu atom hingga mendemagnetisasi gerakan dengan aman, dari mengetahui kapan terakhir kali Anda memakai jam tangan hingga memahami setiap posisi mahkota pada kaliber ETA atau Miyota — alat-alat ini mencakup kebutuhan sehari-hari setiap kolektor atau penggemar.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Alat', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Caliber', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Bahasa', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Privasi Data', value: 'Lokal', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'orologeria';
4
+ const title = 'Strumenti di Orologeria e Guide di Riferimento';
5
+ const description = 'Utilità di orologeria di livello professionale per appassionati di orologi — monitora la precisione, smagnetizza i movimenti, calcola il tempo al polso ed esplora le posizioni della corona per calibri popolari.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Strumenti Essenziali per Appassionati di Orologi', level: 2 },
13
+ { type: 'paragraph', html: 'Che tu stia regolando un movimento meccanico, smagnetizzando un orologio recentemente magnetizzato, monitorando la frequenza con cui indossi un segnatempo o imparando le posizioni della corona del tuo calibro preferito, questa suite mette strumenti di orologeria professionali a portata di mano — senza costose attrezzature.' },
14
+ { type: 'title', text: 'Precisione, Smagnetizzazione e Riferimenti della Corona', level: 2 },
15
+ { type: 'paragraph', html: 'Dal monitoraggio dello scostamento giornaliero rispetto al tempo atomico alla smagnetizzazione sicura di un movimento con tempistiche precise, dal sapere esattamente quando hai indossato un orologio l\'ultima volta alla comprensione di ogni posizione della corona su un calibro ETA o Miyota — questi strumenti coprono le esigenze quotidiane di qualsiasi collezionista o appassionato.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Strumenti', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Calibri', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Lingue', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Privacy', value: 'Locale', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horology';
4
+ const title = '時計学ツール&リファレンスガイド';
5
+ const description = '時計愛好家のためのプロ仕様の時計学ユーティリティ — 精度の追跡、ムーブメントの消磁、装着時間の計算、人気キャリバーの竜頭位置リファレンスを提供します。';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: '時計愛好家のための必須ツール', level: 2 },
13
+ { type: 'paragraph', html: '機械式ムーブメントの調整、磁化された時計の消磁、時計の装着頻度の記録、お気に入りキャリバーの竜頭位置の学習など、このスイートはプロ仕様の時計学ツールをあなたの指先に届けます — 高価な機器は必要ありません。' },
14
+ { type: 'title', text: '精度、消磁、竜頭位置リファレンス', level: 2 },
15
+ { type: 'paragraph', html: '原子時計に対する日差の追跡から、正確なタイミングでのムーブメントの安全な消磁、時計を最後に着用した日時の確認、ETAやMiyotaキャリバーのすべての竜頭位置の理解まで — これらのツールはあらゆるコレクターや愛好家の日々のニーズをカバーします。' },
16
+ { type: 'stats', items: [
17
+ { label: 'ツール数', value: '4', icon: 'mdi:tools' },
18
+ { label: 'キャリバー数', value: '8+', icon: 'mdi:engine' },
19
+ { label: '言語数', value: '15', icon: 'mdi:translate' },
20
+ { label: 'データプライバシー', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horology';
4
+ const title = '시계학 도구 & 참고 가이드';
5
+ const description = '시계 애호가를 위한 프로페셔널급 시계학 유틸리티 — 정밀도 추적, 무브먼트 자기 제거, 착용 시간 계산, 인기 칼리버의 용두 위치 참고 자료를 제공합니다.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: '시계 애호가를 위한 필수 도구', level: 2 },
13
+ { type: 'paragraph', html: '기계식 무브먼트를 조정하거나, 최근에 자화된 시계의 자기를 제거하거나, 시계 착용 빈도를 추적하거나, 좋아하는 칼리버의 용두 위치를 학습하는 등, 이 스위트는 프로페셔널급 시계학 도구를 여러분의 손끝에 제공합니다 — 고가의 장비는 필요 없습니다.' },
14
+ { type: 'title', text: '정밀도, 자기 제거 & 용두 위치 참고 자료', level: 2 },
15
+ { type: 'paragraph', html: '원자시계 대비 일일 오차 추적부터 정확한 타이밍으로 무브먼트를 안전하게 자기 제거하는 방법, 시계를 마지막으로 착용한 시점 확인, ETA 또는 Miyota 칼리버의 모든 용두 위치 이해까지 — 이 도구들은 모든 수집가와 애호가의 일상적인 필요를 충족합니다.' },
16
+ { type: 'stats', items: [
17
+ { label: '도구', value: '4', icon: 'mdi:tools' },
18
+ { label: '칼리버', value: '8+', icon: 'mdi:engine' },
19
+ { label: '언어', value: '15', icon: 'mdi:translate' },
20
+ { label: '데이터 개인정보 보호', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horologie';
4
+ const title = 'Horologie Gereedschappen & Referentiegidsen';
5
+ const description = 'Professionele horologie-hulpmiddelen voor horlogeliefhebbers — volg nauwkeurigheid, demagnetiseer uurwerken, bereken draagtijd en verken kroonpositie-referenties voor populaire kalibers.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Essentiële Gereedschappen voor Horlogeliefhebbers', level: 2 },
13
+ { type: 'paragraph', html: 'Of u nu een mechanisch uurwerk reguleert, een recent gemagnetiseerd horloge demagnetiseert, bijhoudt hoe vaak u een horloge draagt, of de kroonposities van uw favoriete kaliber leert, deze suite biedt professionele horologie-gereedschappen binnen handbereik — geen dure apparatuur nodig.' },
14
+ { type: 'title', text: 'Nauwkeurigheid, Demagnetisatie & Kroonposities', level: 2 },
15
+ { type: 'paragraph', html: 'Van het volgen van de dagelijkse afwijking ten opzichte van atoomtijd tot het veilig demagnetiseren van een uurwerk, van weten wanneer u uw horloge voor het laatst droeg tot het begrijpen van elke kroonpositie op een ETA- of Miyota-kaliber — deze gereedschappen dekken de dagelijkse behoeften van elke verzamelaar of liefhebber.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Gereedschappen', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Kalibers', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Talen', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Gegevensprivacy', value: 'Lokaal', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horologia';
4
+ const title = 'Narzędzia Horologiczne & Przewodniki Referencyjne';
5
+ const description = 'Profesjonalne narzędzia horologiczne dla entuzjastów zegarków — śledź dokładność, rozmagnesowuj mechanizmy, obliczaj obecność na nadgarstku i poznawaj pozycje koronki popularnych kalibrów.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Niezbędne Narzędzia dla Miłośników Zegarków', level: 2 },
13
+ { type: 'paragraph', html: 'Niezależnie od tego, czy regulujesz mechaniczny mechanizm, rozmagnesowujesz niedawno namagnesowany zegarek, śledzisz jak często nosisz dany czasomierz, czy uczysz się pozycji koronki swojego ulubionego kalibru, ten zestaw zapewnia profesjonalne narzędzia horologiczne na wyciągnięcie ręki — bez potrzeby drogiego sprzętu.' },
14
+ { type: 'title', text: 'Dokładność, Rozmagnesowywanie & Pozycje Koronki', level: 2 },
15
+ { type: 'paragraph', html: 'Od śledzenia dziennego odchylenia względem czasu atomowego po bezpieczne rozmagnesowywanie mechanizmu, od wiedzy kiedy ostatnio nosiłeś zegarek po zrozumienie każdej pozycji koronki w kalibrze ETA lub Miyota — te narzędzia pokrywają codzienne potrzeby każdego kolekcjonera i entuzjasty.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Narzędzia', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Kalibry', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Języki', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Prywatność Danych', value: 'Lokalnie', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'relojoaria';
4
+ const title = 'Ferramentas de Relojoaria & Guias de Referência';
5
+ const description = 'Utilitários de relojoaria de nível profissional para entusiastas de relógios — monitore a precisão, desmagnetize movimentos, calcule o uso no pulso e explore referências de posições de coroa para calibres populares.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Ferramentas Essenciais para Entusiastas de Relógios', level: 2 },
13
+ { type: 'paragraph', html: 'Quer você esteja regulando um movimento mecânico, desmagnetizando um relógio recentemente magnetizado, monitorando a frequência com que usa um relógio ou aprendendo as posições da coroa do seu calibre favorito, este conjunto coloca ferramentas profissionais de relojoaria ao seu alcance — sem necessidade de equipamentos caros.' },
14
+ { type: 'title', text: 'Precisão, Desmagnetização & Referências de Coroa', level: 2 },
15
+ { type: 'paragraph', html: 'Desde monitorar o desvio diário em relação ao tempo atômico até desmagnetizar um movimento com segurança, desde saber exatamente quando usou um relógio pela última vez até entender cada posição da coroa em um calibre ETA ou Miyota — estas ferramentas cobrem as necessidades diárias de qualquer colecionador ou entusiasta.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Ferramentas', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Calibres', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Idiomas', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Privacidade de Dados', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horologiya';
4
+ const title = 'Инструменты для хорологии и справочные руководства';
5
+ const description = 'Профессиональные хорологические утилиты для энтузиастов часов — отслеживание точности, размагничивание механизмов, расчёт ношения на запястье и изучение положений заводной головки популярных калибров.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Основные инструменты для энтузиастов часов', level: 2 },
13
+ { type: 'paragraph', html: 'Регулируете ли вы механический механизм, размагничиваете недавно намагниченные часы, отслеживаете, как часто носите хронометр, или изучаете положения заводной головки вашего любимого калибра — этот набор предоставляет профессиональные хорологические инструменты у вас под рукой — без дорогостоящего оборудования.' },
14
+ { type: 'title', text: 'Точность, размагничивание и справочник положений заводной головки', level: 2 },
15
+ { type: 'paragraph', html: 'От отслеживания ежедневного отклонения по атомному времени до безопасного размагничивания механизма с точным расчётом времени, от точного знания, когда вы в последний раз носили часы, до понимания каждого положения заводной головки на калибре ETA или Miyota — эти инструменты покрывают повседневные потребности любого коллекционера или энтузиаста.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Инструментов', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Калибров', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Языков', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Конфиденциальность данных', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horologi';
4
+ const title = 'Horologiverktyg & Referensguider';
5
+ const description = 'Professionella horologiverktyg för klockentusiaster — spåra noggrannhet, avmagnetisera urverk, beräkna handledsnärvaro och utforska kronpositioner för populära kalibrar.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Viktiga verktyg för klockentusiaster', level: 2 },
13
+ { type: 'paragraph', html: 'Oavsett om du reglerar ett mekaniskt urverk, avmagnetiserar en nyligen magnetiserad klocka, håller koll på hur ofta du bär en tidtagare eller lär dig kronpositionerna för din favoritkaliber, ger denna svit dig professionella horologiverktyg direkt till hands — ingen dyr utrustning krävs.' },
14
+ { type: 'title', text: 'Noggrannhet, Avmagnetisering & Kronreferenser', level: 2 },
15
+ { type: 'paragraph', html: 'Från att spåra daglig avvikelse mot atomtid till att säkert avmagnetisera ett urverk med exakt tajming, från att veta exakt när du senast bar en klocka till att förstå varje kronposition på en ETA- eller Miyota-kaliber — dessa verktyg täcker de vardagliga behoven hos varje samlare och entusiast.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Verktyg', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Kalibrar', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Språk', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Dataintegritet', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horoloji';
4
+ const title = 'Horoloji Araçları & Referans Kılavuzları';
5
+ const description = 'Saat tutkunları için profesyonel düzeyde horoloji araçları — hassasiyet takibi, mekanizma demanyetizasyonu, bilekte geçen süre hesaplama ve popüler kalibreler için kurma kolu pozisyon referansları.';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: 'Saat Tutkunları İçin Temel Araçlar', level: 2 },
13
+ { type: 'paragraph', html: 'İster mekanik bir mekanizmayı regüle ediyor, ister yakın zamanda manyetize olmuş bir saati demanyetize ediyor, bir zaman ölçeri ne sıklıkta taktığınızı takip ediyor ya da favori kalibrenizin kurma kolu pozisyonlarını öğreniyor olun, bu paket profesyonel düzeyde horoloji araçlarını parmaklarınızın ucuna getiriyor — pahalı ekipman gerektirmez.' },
14
+ { type: 'title', text: 'Hassasiyet, Demanyetizasyon & Kurma Kolu Referansları', level: 2 },
15
+ { type: 'paragraph', html: 'Atom saatine karşı günlük sapma takibinden hassas zamanlamayla bir mekanizmayı güvenle demanyetize etmeye, bir saati en son ne zaman taktığınızı bilmekten bir ETA veya Miyota kalibresindeki her kurma kolu pozisyonunu anlamaya kadar — bu araçlar her koleksiyoncu ve meraklının günlük ihtiyaçlarını karşılar.' },
16
+ { type: 'stats', items: [
17
+ { label: 'Araçlar', value: '4', icon: 'mdi:tools' },
18
+ { label: 'Kalibreler', value: '8+', icon: 'mdi:engine' },
19
+ { label: 'Diller', value: '15', icon: 'mdi:translate' },
20
+ { label: 'Veri Gizliliği', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ const slug = 'horology';
4
+ const title = '钟表学工具与参考指南';
5
+ const description = '面向腕表爱好者的专业级钟表学工具 — 追踪精度、消磁机芯、计算佩戴频率、探索热门机芯的錶冠位置参考。';
6
+
7
+ export const content: CategoryLocaleContent = {
8
+ slug,
9
+ title,
10
+ description,
11
+ seo: [
12
+ { type: 'title', text: '腕表爱好者必备工具', level: 2 },
13
+ { type: 'paragraph', html: '无论您是在调校机械机芯、为最近受磁的手表消磁、追踪佩戴手表的频率,还是了解您最爱机芯的錶冠位置,这套工具将专业级钟表学功能置于您的指尖 — 无需昂贵设备。' },
14
+ { type: 'title', text: '精度、消磁与錶冠位置参考', level: 2 },
15
+ { type: 'paragraph', html: '从追踪与原子时计的日差到精确计时地安全消磁机芯,从了解您上次佩戴手表的时间到理解ETA或Miyota机芯的每个錶冠位置 — 这些工具覆盖了每位收藏家和爱好者的日常需求。' },
16
+ { type: 'stats', items: [
17
+ { label: '工具', value: '4', icon: 'mdi:tools' },
18
+ { label: '机芯', value: '8+', icon: 'mdi:engine' },
19
+ { label: '语言', value: '15', icon: 'mdi:translate' },
20
+ { label: '数据隐私', value: 'Local', icon: 'mdi:shield-check' },
21
+ ] },
22
+ ],
23
+ };
@@ -0,0 +1,42 @@
1
+ import type { ChronoCategoryEntry } from '../types';
2
+ import { watchAccuracyTracker } from '../tool/watch-accuracy-tracker/entry';
3
+ import { wristPresenceCalculator } from '../tool/wrist-presence-calculator/entry';
4
+ import { demagnetizingTimer } from '../tool/demagnetizing-timer/entry';
5
+ import { crownReferenceGuide } from '../tool/crown-reference-guide/entry';
6
+ import { powerReserveEstimator } from '../tool/power-reserve-estimator/entry';
7
+ import { beatRateConverter } from '../tool/beat-rate-converter/entry';
8
+ import { waterResistanceConverter } from '../tool/water-resistance-converter/entry';
9
+ import { strapTaperCalculator } from '../tool/strap-taper-calculator/entry';
10
+
11
+ export const chronoCategory: ChronoCategoryEntry = {
12
+ icon: 'mdi:clock-outline',
13
+ tools: [
14
+ watchAccuracyTracker,
15
+ wristPresenceCalculator,
16
+ demagnetizingTimer,
17
+ crownReferenceGuide,
18
+ powerReserveEstimator,
19
+ beatRateConverter,
20
+ waterResistanceConverter,
21
+ strapTaperCalculator,
22
+ ],
23
+ i18n: {
24
+ de: () => import('./i18n/de').then((m) => m.content),
25
+ en: () => import('./i18n/en').then((m) => m.content),
26
+ es: () => import('./i18n/es').then((m) => m.content),
27
+ fr: () => import('./i18n/fr').then((m) => m.content),
28
+ id: () => import('./i18n/id').then((m) => m.content),
29
+ it: () => import('./i18n/it').then((m) => m.content),
30
+ ja: () => import('./i18n/ja').then((m) => m.content),
31
+ ko: () => import('./i18n/ko').then((m) => m.content),
32
+ nl: () => import('./i18n/nl').then((m) => m.content),
33
+ pl: () => import('./i18n/pl').then((m) => m.content),
34
+ pt: () => import('./i18n/pt').then((m) => m.content),
35
+ ru: () => import('./i18n/ru').then((m) => m.content),
36
+ sv: () => import('./i18n/sv').then((m) => m.content),
37
+ tr: () => import('./i18n/tr').then((m) => m.content),
38
+ zh: () => import('./i18n/zh').then((m) => m.content),
39
+ },
40
+ };
41
+
42
+
@@ -0,0 +1,116 @@
1
+ ---
2
+ interface NavItem {
3
+ id: string;
4
+ title: string;
5
+ href: string;
6
+ isActive?: boolean;
7
+ }
8
+
9
+ interface Props {
10
+ categoryTitle: string;
11
+ tools?: NavItem[];
12
+ }
13
+
14
+ const { categoryTitle, tools = [] } = Astro.props;
15
+ ---
16
+
17
+ <nav class="preview-nav-sidebar">
18
+ <div class="sidebar-header">
19
+ <h3>{categoryTitle}</h3>
20
+ </div>
21
+
22
+ <ul class="tools-list">
23
+ {tools.map((tool) => (
24
+ <li>
25
+ <a
26
+ href={tool.href}
27
+ class:list={['tool-link', { active: tool.isActive }]}
28
+ >
29
+ <span class="tool-title">{tool.title}</span>
30
+ </a>
31
+ </li>
32
+ ))}
33
+ </ul>
34
+ </nav>
35
+
36
+ <style>
37
+ .preview-nav-sidebar {
38
+ display: flex;
39
+ flex-direction: column;
40
+ height: 100%;
41
+ background: var(--bg-surface, #0f172a);
42
+ }
43
+
44
+ .sidebar-header {
45
+ padding: 2rem 1.5rem 1.5rem;
46
+ border-bottom: 1px solid var(--border-color, #1e293b);
47
+ }
48
+
49
+ .sidebar-header h3 {
50
+ margin: 0;
51
+ font-size: 0.75rem;
52
+ font-weight: 900;
53
+ text-transform: uppercase;
54
+ letter-spacing: 0.1em;
55
+ color: var(--text-muted, #94a3b8);
56
+ }
57
+
58
+ .tools-list {
59
+ list-style: none;
60
+ margin: 0;
61
+ padding: 0.5rem 0;
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 0.25rem;
65
+ }
66
+
67
+ .tools-list li {
68
+ margin: 0;
69
+ }
70
+
71
+ .tool-link {
72
+ display: flex;
73
+ align-items: center;
74
+ padding: 0.75rem 1.5rem;
75
+ color: var(--text-muted, #94a3b8);
76
+ text-decoration: none;
77
+ font-size: 0.9375rem;
78
+ font-weight: 500;
79
+ transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
80
+ border-left: 3px solid transparent;
81
+ position: relative;
82
+ }
83
+
84
+ .tool-link:hover {
85
+ color: var(--text-base, #f1f5f9);
86
+ background: rgba(255, 255, 255, 0.08);
87
+ padding-left: 1.75rem;
88
+ }
89
+
90
+ .tool-link.active {
91
+ color: var(--accent, #f43f5e);
92
+ background: rgba(244, 63, 94, 0.15);
93
+ border-left-color: var(--accent, #f43f5e);
94
+ font-weight: 600;
95
+ }
96
+
97
+ .tool-link.active::before {
98
+ content: '';
99
+ position: absolute;
100
+ left: 0;
101
+ top: 50%;
102
+ transform: translateY(-50%);
103
+ width: 3px;
104
+ height: 24px;
105
+ background: var(--accent, #f43f5e);
106
+ border-radius: 0 2px 2px 0;
107
+ }
108
+
109
+ .tool-title {
110
+ display: block;
111
+ overflow: hidden;
112
+ text-overflow: ellipsis;
113
+ white-space: nowrap;
114
+ }
115
+ </style>
116
+