@jjlmoya/utils-chrono 1.3.0 → 1.4.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 (160) hide show
  1. package/package.json +1 -1
  2. package/src/category/i18n/de.ts +11 -9
  3. package/src/category/i18n/en.ts +11 -9
  4. package/src/category/i18n/fr.ts +11 -9
  5. package/src/category/i18n/id.ts +11 -9
  6. package/src/category/i18n/it.ts +11 -9
  7. package/src/category/i18n/ja.ts +11 -9
  8. package/src/category/i18n/ko.ts +11 -9
  9. package/src/category/i18n/nl.ts +11 -9
  10. package/src/category/i18n/pl.ts +11 -9
  11. package/src/category/i18n/pt.ts +11 -9
  12. package/src/category/i18n/ru.ts +11 -9
  13. package/src/category/i18n/sv.ts +11 -9
  14. package/src/category/i18n/tr.ts +11 -9
  15. package/src/category/i18n/zh.ts +11 -9
  16. package/src/category/index.ts +6 -0
  17. package/src/entries.ts +10 -1
  18. package/src/index.ts +3 -0
  19. package/src/tests/locale_completeness.test.ts +1 -1
  20. package/src/tests/no_h1_in_components.test.ts +1 -1
  21. package/src/tests/tool_validation.test.ts +1 -1
  22. package/src/tool/beat-rate-converter/bibliography.ts +1 -1
  23. package/src/tool/beat-rate-converter/components/ConverterPanel.astro +57 -20
  24. package/src/tool/beat-rate-converter/i18n/en.ts +5 -5
  25. package/src/tool/crown-reference-guide/bibliography.ts +3 -3
  26. package/src/tool/crown-reference-guide/i18n/de.ts +37 -29
  27. package/src/tool/crown-reference-guide/i18n/en.ts +38 -30
  28. package/src/tool/crown-reference-guide/i18n/es.ts +36 -28
  29. package/src/tool/crown-reference-guide/i18n/fr.ts +38 -30
  30. package/src/tool/crown-reference-guide/i18n/id.ts +38 -30
  31. package/src/tool/crown-reference-guide/i18n/it.ts +38 -30
  32. package/src/tool/crown-reference-guide/i18n/ja.ts +38 -30
  33. package/src/tool/crown-reference-guide/i18n/ko.ts +38 -30
  34. package/src/tool/crown-reference-guide/i18n/nl.ts +38 -30
  35. package/src/tool/crown-reference-guide/i18n/pl.ts +38 -30
  36. package/src/tool/crown-reference-guide/i18n/pt.ts +38 -30
  37. package/src/tool/crown-reference-guide/i18n/ru.ts +41 -33
  38. package/src/tool/crown-reference-guide/i18n/sv.ts +38 -30
  39. package/src/tool/crown-reference-guide/i18n/tr.ts +38 -30
  40. package/src/tool/crown-reference-guide/i18n/zh.ts +37 -29
  41. package/src/tool/demagnetizing-timer/i18n/de.ts +1 -1
  42. package/src/tool/demagnetizing-timer/i18n/en.ts +1 -1
  43. package/src/tool/demagnetizing-timer/i18n/es.ts +1 -1
  44. package/src/tool/demagnetizing-timer/i18n/fr.ts +1 -1
  45. package/src/tool/demagnetizing-timer/i18n/id.ts +1 -1
  46. package/src/tool/demagnetizing-timer/i18n/it.ts +1 -1
  47. package/src/tool/demagnetizing-timer/i18n/ja.ts +1 -1
  48. package/src/tool/demagnetizing-timer/i18n/ko.ts +1 -1
  49. package/src/tool/demagnetizing-timer/i18n/nl.ts +1 -1
  50. package/src/tool/demagnetizing-timer/i18n/pl.ts +2 -2
  51. package/src/tool/demagnetizing-timer/i18n/pt.ts +1 -1
  52. package/src/tool/demagnetizing-timer/i18n/ru.ts +7 -7
  53. package/src/tool/demagnetizing-timer/i18n/sv.ts +1 -1
  54. package/src/tool/demagnetizing-timer/i18n/tr.ts +1 -1
  55. package/src/tool/demagnetizing-timer/i18n/zh.ts +1 -1
  56. package/src/tool/lume-color-simulator/bibliography.astro +16 -0
  57. package/src/tool/lume-color-simulator/bibliography.ts +16 -0
  58. package/src/tool/lume-color-simulator/client.ts +186 -0
  59. package/src/tool/lume-color-simulator/component.astro +17 -0
  60. package/src/tool/lume-color-simulator/components/LumePanel.astro +98 -0
  61. package/src/tool/lume-color-simulator/entry.ts +57 -0
  62. package/src/tool/lume-color-simulator/i18n/de.ts +174 -0
  63. package/src/tool/lume-color-simulator/i18n/en.ts +174 -0
  64. package/src/tool/lume-color-simulator/i18n/es.ts +174 -0
  65. package/src/tool/lume-color-simulator/i18n/fr.ts +174 -0
  66. package/src/tool/lume-color-simulator/i18n/id.ts +174 -0
  67. package/src/tool/lume-color-simulator/i18n/it.ts +175 -0
  68. package/src/tool/lume-color-simulator/i18n/ja.ts +174 -0
  69. package/src/tool/lume-color-simulator/i18n/ko.ts +174 -0
  70. package/src/tool/lume-color-simulator/i18n/nl.ts +175 -0
  71. package/src/tool/lume-color-simulator/i18n/pl.ts +174 -0
  72. package/src/tool/lume-color-simulator/i18n/pt.ts +174 -0
  73. package/src/tool/lume-color-simulator/i18n/ru.ts +174 -0
  74. package/src/tool/lume-color-simulator/i18n/sv.ts +174 -0
  75. package/src/tool/lume-color-simulator/i18n/tr.ts +174 -0
  76. package/src/tool/lume-color-simulator/i18n/zh.ts +174 -0
  77. package/src/tool/lume-color-simulator/index.ts +11 -0
  78. package/src/tool/lume-color-simulator/lume-color-simulator.css +208 -0
  79. package/src/tool/lume-color-simulator/seo.astro +16 -0
  80. package/src/tool/moon-phase-visualizer/bibliography.astro +16 -0
  81. package/src/tool/moon-phase-visualizer/bibliography.ts +16 -0
  82. package/src/tool/moon-phase-visualizer/client.ts +243 -0
  83. package/src/tool/moon-phase-visualizer/component.astro +17 -0
  84. package/src/tool/moon-phase-visualizer/components/MoonPanel.astro +63 -0
  85. package/src/tool/moon-phase-visualizer/entry.ts +51 -0
  86. package/src/tool/moon-phase-visualizer/i18n/de.ts +175 -0
  87. package/src/tool/moon-phase-visualizer/i18n/en.ts +175 -0
  88. package/src/tool/moon-phase-visualizer/i18n/es.ts +175 -0
  89. package/src/tool/moon-phase-visualizer/i18n/fr.ts +175 -0
  90. package/src/tool/moon-phase-visualizer/i18n/id.ts +175 -0
  91. package/src/tool/moon-phase-visualizer/i18n/it.ts +176 -0
  92. package/src/tool/moon-phase-visualizer/i18n/ja.ts +175 -0
  93. package/src/tool/moon-phase-visualizer/i18n/ko.ts +175 -0
  94. package/src/tool/moon-phase-visualizer/i18n/nl.ts +176 -0
  95. package/src/tool/moon-phase-visualizer/i18n/pl.ts +175 -0
  96. package/src/tool/moon-phase-visualizer/i18n/pt.ts +175 -0
  97. package/src/tool/moon-phase-visualizer/i18n/ru.ts +175 -0
  98. package/src/tool/moon-phase-visualizer/i18n/sv.ts +175 -0
  99. package/src/tool/moon-phase-visualizer/i18n/tr.ts +175 -0
  100. package/src/tool/moon-phase-visualizer/i18n/zh.ts +175 -0
  101. package/src/tool/moon-phase-visualizer/index.ts +11 -0
  102. package/src/tool/moon-phase-visualizer/moon-phase-visualizer.css +216 -0
  103. package/src/tool/moon-phase-visualizer/seo.astro +16 -0
  104. package/src/tool/power-reserve-estimator/bibliography.ts +2 -2
  105. package/src/tool/power-reserve-estimator/components/EstimatorPanel.astro +146 -39
  106. package/src/tool/power-reserve-estimator/i18n/en.ts +3 -3
  107. package/src/tool/strap-taper-calculator/i18n/en.ts +2 -2
  108. package/src/tool/strap-taper-calculator/i18n/ru.ts +3 -3
  109. package/src/tool/watch-accuracy-tracker/i18n/ru.ts +2 -2
  110. package/src/tool/watch-savings-planner/i18n/en.ts +5 -5
  111. package/src/tool/watch-size-comparator/bibliography.astro +16 -0
  112. package/src/tool/watch-size-comparator/bibliography.ts +16 -0
  113. package/src/tool/watch-size-comparator/client.ts +287 -0
  114. package/src/tool/watch-size-comparator/component.astro +17 -0
  115. package/src/tool/watch-size-comparator/components/WatchForm.astro +121 -0
  116. package/src/tool/watch-size-comparator/drawing/index.ts +79 -0
  117. package/src/tool/watch-size-comparator/drawing/measures.ts +57 -0
  118. package/src/tool/watch-size-comparator/drawing/utils.ts +37 -0
  119. package/src/tool/watch-size-comparator/drawing/watch.ts +78 -0
  120. package/src/tool/watch-size-comparator/entry.ts +62 -0
  121. package/src/tool/watch-size-comparator/i18n/de.ts +189 -0
  122. package/src/tool/watch-size-comparator/i18n/en.ts +189 -0
  123. package/src/tool/watch-size-comparator/i18n/es.ts +189 -0
  124. package/src/tool/watch-size-comparator/i18n/fr.ts +189 -0
  125. package/src/tool/watch-size-comparator/i18n/id.ts +189 -0
  126. package/src/tool/watch-size-comparator/i18n/it.ts +190 -0
  127. package/src/tool/watch-size-comparator/i18n/ja.ts +189 -0
  128. package/src/tool/watch-size-comparator/i18n/ko.ts +189 -0
  129. package/src/tool/watch-size-comparator/i18n/nl.ts +190 -0
  130. package/src/tool/watch-size-comparator/i18n/pl.ts +189 -0
  131. package/src/tool/watch-size-comparator/i18n/pt.ts +189 -0
  132. package/src/tool/watch-size-comparator/i18n/ru.ts +189 -0
  133. package/src/tool/watch-size-comparator/i18n/sv.ts +189 -0
  134. package/src/tool/watch-size-comparator/i18n/tr.ts +189 -0
  135. package/src/tool/watch-size-comparator/i18n/zh.ts +189 -0
  136. package/src/tool/watch-size-comparator/index.ts +11 -0
  137. package/src/tool/watch-size-comparator/seo.astro +16 -0
  138. package/src/tool/watch-size-comparator/watch-size-comparator.css +373 -0
  139. package/src/tool/water-resistance-converter/bibliography.ts +2 -2
  140. package/src/tool/water-resistance-converter/i18n/de.ts +5 -5
  141. package/src/tool/water-resistance-converter/i18n/en.ts +6 -6
  142. package/src/tool/water-resistance-converter/i18n/es.ts +6 -6
  143. package/src/tool/water-resistance-converter/i18n/fr.ts +6 -6
  144. package/src/tool/water-resistance-converter/i18n/id.ts +6 -6
  145. package/src/tool/water-resistance-converter/i18n/it.ts +6 -6
  146. package/src/tool/water-resistance-converter/i18n/ja.ts +6 -6
  147. package/src/tool/water-resistance-converter/i18n/ko.ts +6 -6
  148. package/src/tool/water-resistance-converter/i18n/nl.ts +6 -6
  149. package/src/tool/water-resistance-converter/i18n/pl.ts +6 -6
  150. package/src/tool/water-resistance-converter/i18n/pt.ts +6 -6
  151. package/src/tool/water-resistance-converter/i18n/ru.ts +8 -8
  152. package/src/tool/water-resistance-converter/i18n/sv.ts +6 -6
  153. package/src/tool/water-resistance-converter/i18n/tr.ts +6 -6
  154. package/src/tool/water-resistance-converter/i18n/zh.ts +3 -3
  155. package/src/tool/wrist-presence-calculator/i18n/fr.ts +1 -1
  156. package/src/tool/wrist-presence-calculator/i18n/pl.ts +1 -1
  157. package/src/tool/wrist-presence-calculator/i18n/pt.ts +1 -1
  158. package/src/tool/wrist-presence-calculator/i18n/ru.ts +5 -5
  159. package/src/tool/wrist-presence-calculator/i18n/sv.ts +1 -1
  160. package/src/tools.ts +6 -0
@@ -10,16 +10,16 @@ const { labels } = Astro.props;
10
10
  <div class="panel-section">
11
11
  <div class="section-label">{labels.movementLabel || "Movement"}</div>
12
12
  <select class="movement-select" id="movement-select">
13
- <option value="eta-2824">ETA 2824-2 / SW20038h</option>
14
- <option value="eta-2892">ETA 2892-A2 / SW30042h</option>
15
- <option value="valjoux-7750">Valjoux 7750 / SW50048h</option>
16
- <option value="miyota-8215">Miyota 821540h</option>
17
- <option value="miyota-9015">Miyota 901542h</option>
18
- <option value="seiko-nh35">Seiko NH35 / 4R3541h</option>
19
- <option value="seiko-6r35">Seiko 6R3570h</option>
20
- <option value="unitas-6498">Unitas 6497 / 649846h</option>
21
- <option value="rolex-3135">Rolex 313548h</option>
22
- <option value="rolex-3235">Rolex 323570h</option>
13
+ <option value="eta-2824">ETA 2824-2 / SW200-38h</option>
14
+ <option value="eta-2892">ETA 2892-A2 / SW300-42h</option>
15
+ <option value="valjoux-7750">Valjoux 7750 / SW500-48h</option>
16
+ <option value="miyota-8215">Miyota 8215-40h</option>
17
+ <option value="miyota-9015">Miyota 9015-42h</option>
18
+ <option value="seiko-nh35">Seiko NH35 / 4R35-41h</option>
19
+ <option value="seiko-6r35">Seiko 6R35-70h</option>
20
+ <option value="unitas-6498">Unitas 6497 / 6498-46h</option>
21
+ <option value="rolex-3135">Rolex 3135-48h</option>
22
+ <option value="rolex-3235">Rolex 3235-70h</option>
23
23
  <option value="custom">{labels.customMovement || "Custom"}</option>
24
24
  </select>
25
25
  </div>
@@ -28,55 +28,145 @@ const { labels } = Astro.props;
28
28
  <div class="section-label">{labels.customMovement || "Custom"}</div>
29
29
  <div class="input-row">
30
30
  <div class="input-group">
31
- <label class="input-label" for="custom-reserve">{labels.powerReserveHours || "Reserve (h)"}</label>
31
+ <label class="input-label" for="custom-reserve"
32
+ >{labels.powerReserveHours || "Reserve (h)"}</label
33
+ >
32
34
  <div class="stepper-wrap">
33
- <button type="button" class="stepper-btn" data-target="custom-reserve" data-dir="-1">−</button>
34
- <input type="number" class="stepper-input" id="custom-reserve" min="1" max="336" value="38" />
35
- <button type="button" class="stepper-btn" data-target="custom-reserve" data-dir="1">+</button>
35
+ <button
36
+ type="button"
37
+ class="stepper-btn"
38
+ data-target="custom-reserve"
39
+ data-dir="-1">−</button
40
+ >
41
+ <input
42
+ type="number"
43
+ class="stepper-input"
44
+ id="custom-reserve"
45
+ min="1"
46
+ max="336"
47
+ value="38"
48
+ />
49
+ <button
50
+ type="button"
51
+ class="stepper-btn"
52
+ data-target="custom-reserve"
53
+ data-dir="1">+</button
54
+ >
36
55
  </div>
37
56
  </div>
38
57
  <div class="input-group">
39
- <label class="input-label" for="custom-turns">{labels.fullWindTurns || "Turns to full"}</label>
58
+ <label class="input-label" for="custom-turns"
59
+ >{labels.fullWindTurns || "Turns to full"}</label
60
+ >
40
61
  <div class="stepper-wrap">
41
- <button type="button" class="stepper-btn" data-target="custom-turns" data-dir="-1">−</button>
42
- <input type="number" class="stepper-input" id="custom-turns" min="1" max="100" value="40" />
43
- <button type="button" class="stepper-btn" data-target="custom-turns" data-dir="1">+</button>
62
+ <button
63
+ type="button"
64
+ class="stepper-btn"
65
+ data-target="custom-turns"
66
+ data-dir="-1">−</button
67
+ >
68
+ <input
69
+ type="number"
70
+ class="stepper-input"
71
+ id="custom-turns"
72
+ min="1"
73
+ max="100"
74
+ value="40"
75
+ />
76
+ <button
77
+ type="button"
78
+ class="stepper-btn"
79
+ data-target="custom-turns"
80
+ data-dir="1">+</button
81
+ >
44
82
  </div>
45
83
  </div>
46
84
  </div>
47
85
  </div>
48
86
 
49
87
  <div class="panel-section">
50
- <div class="section-label">{labels.turnsLabel || "Crown Turns"} <span class="label-sub">+</span></div>
88
+ <div class="section-label">
89
+ {labels.turnsLabel || "Crown Turns"}
90
+ <span class="label-sub">+</span>
91
+ </div>
51
92
  <div class="input-row">
52
93
  <div class="input-group">
53
- <label class="input-label" for="turns-input">{labels.turnsInput || "Turns"}</label>
94
+ <label class="input-label" for="turns-input"
95
+ >{labels.turnsInput || "Turns"}</label
96
+ >
54
97
  <div class="stepper-wrap">
55
- <button type="button" class="stepper-btn" data-target="turns-input" data-dir="-5">−5</button>
56
- <input type="number" class="stepper-input" id="turns-input" min="0" max="100" value="0" />
57
- <button type="button" class="stepper-btn" data-target="turns-input" data-dir="5">+5</button>
98
+ <button
99
+ type="button"
100
+ class="stepper-btn"
101
+ data-target="turns-input"
102
+ data-dir="-5">−5</button
103
+ >
104
+ <input
105
+ type="number"
106
+ class="stepper-input"
107
+ id="turns-input"
108
+ min="0"
109
+ max="100"
110
+ value="0"
111
+ />
112
+ <button
113
+ type="button"
114
+ class="stepper-btn"
115
+ data-target="turns-input"
116
+ data-dir="5">+5</button
117
+ >
58
118
  </div>
59
119
  </div>
60
120
  </div>
61
121
  </div>
62
122
 
63
123
  <div class="panel-section">
64
- <div class="section-label">{labels.hoursLabel || "Wear Time"} <span class="label-sub">+</span></div>
124
+ <div class="section-label">
125
+ {labels.hoursLabel || "Wear Time"}
126
+ <span class="label-sub">+</span>
127
+ </div>
65
128
  <div class="input-row">
66
129
  <div class="input-group">
67
- <label class="input-label" for="hours-input">{labels.hoursInput || "Hours"}</label>
130
+ <label class="input-label" for="hours-input"
131
+ >{labels.hoursInput || "Hours"}</label
132
+ >
68
133
  <div class="stepper-wrap">
69
- <button type="button" class="stepper-btn" data-target="hours-input" data-dir="-1">−</button>
70
- <input type="number" class="stepper-input" id="hours-input" min="0" max="24" value="0" />
71
- <button type="button" class="stepper-btn" data-target="hours-input" data-dir="1">+</button>
134
+ <button
135
+ type="button"
136
+ class="stepper-btn"
137
+ data-target="hours-input"
138
+ data-dir="-1">−</button
139
+ >
140
+ <input
141
+ type="number"
142
+ class="stepper-input"
143
+ id="hours-input"
144
+ min="0"
145
+ max="24"
146
+ value="0"
147
+ />
148
+ <button
149
+ type="button"
150
+ class="stepper-btn"
151
+ data-target="hours-input"
152
+ data-dir="1">+</button
153
+ >
72
154
  </div>
73
155
  </div>
74
156
  <div class="input-group">
75
- <label class="input-label" for="activity-select">{labels.activityLabel || "Activity"}</label>
157
+ <label class="input-label" for="activity-select"
158
+ >{labels.activityLabel || "Activity"}</label
159
+ >
76
160
  <div class="chip-group">
77
- <button type="button" class="chip active" data-activity="low">{labels.activityLow || "Low"}</button>
78
- <button type="button" class="chip" data-activity="medium">{labels.activityMedium || "Medium"}</button>
79
- <button type="button" class="chip" data-activity="high">{labels.activityHigh || "High"}</button>
161
+ <button type="button" class="chip active" data-activity="low"
162
+ >{labels.activityLow || "Low"}</button
163
+ >
164
+ <button type="button" class="chip" data-activity="medium"
165
+ >{labels.activityMedium || "Medium"}</button
166
+ >
167
+ <button type="button" class="chip" data-activity="high"
168
+ >{labels.activityHigh || "High"}</button
169
+ >
80
170
  </div>
81
171
  </div>
82
172
  </div>
@@ -84,7 +174,9 @@ const { labels } = Astro.props;
84
174
 
85
175
  <button type="button" class="calc-btn" id="calc-btn">
86
176
  <svg viewBox="0 0 24 24" width="16" height="16">
87
- <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" fill="currentColor" />
177
+ <path
178
+ d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"
179
+ fill="currentColor"></path>
88
180
  </svg>
89
181
  {labels.calculate || "Calculate"}
90
182
  </button>
@@ -92,7 +184,9 @@ const { labels } = Astro.props;
92
184
  <div class="result-card" id="result-card" style="display: none">
93
185
  <div class="result-header">
94
186
  <svg viewBox="0 0 24 24" width="18" height="18">
95
- <path d="M13 2.05v2.02c3.95.49 7 3.85 7 7.93 0 4.42-3.58 8-8 8s-8-3.58-8-8c0-4.08 3.05-7.44 7-7.93V2.05C5.05 2.58 2 6.13 2 11c0 5.52 4.48 10 10 10s10-4.48 10-10c0-4.87-3.05-8.42-7-8.95zM12 6v5l4.28 2.54.72-1.21-3.5-2.08V6H12z" fill="currentColor" />
187
+ <path
188
+ d="M13 2.05v2.02c3.95.49 7 3.85 7 7.93 0 4.42-3.58 8-8 8s-8-3.58-8-8c0-4.08 3.05-7.44 7-7.93V2.05C5.05 2.58 2 6.13 2 11c0 5.52 4.48 10 10 10s10-4.48 10-10c0-4.87-3.05-8.42-7-8.95zM12 6v5l4.28 2.54.72-1.21-3.5-2.08V6H12z"
189
+ fill="currentColor"></path>
96
190
  </svg>
97
191
  <span>{labels.resultLabel || "Estimated Reserve"}</span>
98
192
  </div>
@@ -129,22 +223,35 @@ const { labels } = Astro.props;
129
223
  <div class="steps-section">
130
224
  <div class="step-row">
131
225
  <div class="step-marker">1</div>
132
- <span class="step-text">{labels.step1 || "Select your movement from the dropdown."}</span>
226
+ <span class="step-text"
227
+ >{labels.step1 || "Select your movement from the dropdown."}</span
228
+ >
133
229
  </div>
134
230
  <div class="step-row">
135
231
  <div class="step-marker">2</div>
136
- <span class="step-text">{labels.step2 || "Enter crown turns and hours worn."}</span>
232
+ <span class="step-text"
233
+ >{labels.step2 || "Enter crown turns and hours worn."}</span
234
+ >
137
235
  </div>
138
236
  <div class="step-row">
139
237
  <div class="step-marker">3</div>
140
- <span class="step-text">{labels.step3 || "Press Calculate to see your reserve."}</span>
238
+ <span class="step-text"
239
+ >{labels.step3 || "Press Calculate to see your reserve."}</span
240
+ >
141
241
  </div>
142
242
  </div>
143
243
 
144
244
  <div class="tip-row">
145
245
  <svg class="tip-icon" viewBox="0 0 24 24" width="16" height="16">
146
- <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill="currentColor" />
246
+ <path
247
+ d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
248
+ fill="currentColor"></path>
147
249
  </svg>
148
- <span class="tip-text">{labels.tipContent || "Manual-wind movements only charge when you turn the crown. Automatic movements also charge while worn."}</span>
250
+ <span class="tip-text"
251
+ >{
252
+ labels.tipContent ||
253
+ "Manual-wind movements only charge when you turn the crown. Automatic movements also charge while worn."
254
+ }</span
255
+ >
149
256
  </div>
150
257
  </div>
@@ -34,12 +34,12 @@ export const content: ToolLocaleContent<PowerReserveEstimatorUI> = {
34
34
  tipContent: 'Manual-wind movements only charge when you turn the crown. Automatic movements also charge while worn.',
35
35
  },
36
36
  seo: [
37
- { type: 'title', text: 'Watch Power Reserve EstimatorHow Much Reserve Does Your Movement Have Left?', level: 2 },
37
+ { type: 'title', text: 'Watch Power Reserve Estimator-How Much Reserve Does Your Movement Have Left?', level: 2 },
38
38
  { type: 'paragraph', html: 'Wondering how much power is left in your mechanical watch? Whether you wound the crown this morning or wore it all day, this estimator tells you the approximate charge level and remaining hours for popular calibers like <strong>ETA, Sellita, Miyota, Seiko, and Rolex</strong>.' },
39
39
  { type: 'title', text: 'How Power Reserve Works in a Mechanical Watch', level: 3 },
40
- { type: 'paragraph', html: 'The power reserve is the amount of energy stored in the mainspring. When you wind the crown, you tighten the mainspring, storing potential energy. An automatic rotor also winds the mainspring while you wear the watch. The energy then drains at a steady ratetypically 2-3% per houruntil the watch stops.' },
40
+ { type: 'paragraph', html: 'The power reserve is the amount of energy stored in the mainspring. When you wind the crown, you tighten the mainspring, storing potential energy. An automatic rotor also winds the mainspring while you wear the watch. The energy then drains at a steady rate-typically 2-3% per hour-until the watch stops.' },
41
41
  { type: 'title', text: 'Crown Winding vs. Rotor Charging', level: 3 },
42
- { type: 'paragraph', html: 'Manual winding via the crown is the most efficient way to charge a watcheach full rotation adds a predictable amount of energy, typically around 2.5% of the total reserve. Wearing the watch charges more slowly and depends on your activity level: an office worker might charge 4-6% per hour, while someone active might charge 8-10%. This estimator uses a conservative average.' },
42
+ { type: 'paragraph', html: 'Manual winding via the crown is the most efficient way to charge a watch-each full rotation adds a predictable amount of energy, typically around 2.5% of the total reserve. Wearing the watch charges more slowly and depends on your activity level: an office worker might charge 4-6% per hour, while someone active might charge 8-10%. This estimator uses a conservative average.' },
43
43
  { type: 'title', text: 'Why Power Reserve Estimation Matters', level: 3 },
44
44
  { type: 'paragraph', html: 'Knowing your watch\'s charge level helps avoid unexpected stops. A watch that runs down overnight may need more winding before bed, or may not be getting enough wear time. Use this tool to understand your charging habits and keep your automatic running.' },
45
45
  ],
@@ -37,10 +37,10 @@ export const content: ToolLocaleContent<StrapTaperCalculatorUI> = {
37
37
  step3: 'Read the proportions and visual representation.',
38
38
  },
39
39
  seo: [
40
- { type: 'title', text: 'Watch Strap Taper CalculatorProportions, Buckle Width & Visual Guide', level: 2 },
40
+ { type: 'title', text: 'Watch Strap Taper Calculator-Proportions, Buckle Width & Visual Guide', level: 2 },
41
41
  { type: 'paragraph', html: 'A well proportioned strap makes or breaks a watch. Too much taper on a diver makes it look fragile. No taper on a dress watch makes it look clunky. This calculator helps you find the ideal <strong>strap taper ratio</strong> based on your case diameter and lug width.' },
42
42
  { type: 'title', text: 'What Is Strap Taper?', level: 3 },
43
- { type: 'paragraph', html: 'Strap taper is the reduction in width from the lug end to the buckle end of a watch strap. A classic dress watch might taper from 20 mm at the lugs to 16 mm at the bucklea 4 mm taper. A dive watch might stay at 20 mm straight through for a more tool-like appearance.' },
43
+ { type: 'paragraph', html: 'Strap taper is the reduction in width from the lug end to the buckle end of a watch strap. A classic dress watch might taper from 20 mm at the lugs to 16 mm at the buckle-a 4 mm taper. A dive watch might stay at 20 mm straight through for a more tool-like appearance.' },
44
44
  { type: 'title', text: 'The Golden Ratio for Strap Proportions', level: 3 },
45
45
  { type: 'paragraph', html: 'Watch enthusiasts generally agree that a lug width between 45% and 55% of the case diameter looks best. For the taper, a buckle width that is 75% to 85% of the lug width creates a balanced, elegant silhouette. Ratios outside this range can make the watch look top heavy or fragile.' },
46
46
  { type: 'title', text: 'Taper by Watch Style', level: 3 },
@@ -40,7 +40,7 @@ export const content: ToolLocaleContent<StrapTaperCalculatorUI> = {
40
40
  { type: 'title', text: 'Калькулятор сужения ремешка \u2014 Пропорции, ширина пряжки и визуальное руководство', level: 2 },
41
41
  { type: 'paragraph', html: 'Правильно подобранный ремешок может как украсить часы, так и испортить их. Слишком сильное сужение на дайверских часах делает их хрупкими на вид. Отсутствие сужения на классических часах делает их грубыми. Этот калькулятор поможет вам найти идеальное <strong>соотношение сужения ремешка</strong> на основе диаметра корпуса и ширины ушек.' },
42
42
  { type: 'title', text: 'Что такое сужение ремешка?', level: 3 },
43
- { type: 'paragraph', html: 'Сужение ремешка — это уменьшение ширины от ушек до пряжки. Классические часы могут сужаться с 20 мм у ушек до 16 мм у пряжки — сужение на 4 мм. Дайверские часы могут оставаться прямыми на 20 мм для более инструментального вида.' },
43
+ { type: 'paragraph', html: 'Сужение ремешка-это уменьшение ширины от ушек до пряжки. Классические часы могут сужаться с 20 мм у ушек до 16 мм у пряжки-сужение на 4 мм. Дайверские часы могут оставаться прямыми на 20 мм для более инструментального вида.' },
44
44
  { type: 'title', text: 'Золотое сечение для пропорций ремешка', level: 3 },
45
45
  { type: 'paragraph', html: 'Энтузиасты часов в целом сходятся во мнении, что ширина ушек от 45% до 55% диаметра корпуса выглядит лучше всего. Что касается сужения, ширина пряжки от 75% до 85% ширины ушек создаёт сбалансированный, элегантный силуэт. Соотношения за пределами этого диапазона могут сделать часы визуально тяжелыми или слишком хрупкими.' },
46
46
  { type: 'title', text: 'Сужение по стилю часов', level: 3 },
@@ -49,7 +49,7 @@ export const content: ToolLocaleContent<StrapTaperCalculatorUI> = {
49
49
  faq: [
50
50
  {
51
51
  question: 'Какое сужение ремешка идеально подходит для классических часов?',
52
- answer: 'Сужение на 4 мм — классический выбор. Для ширины ушек 20 мм это означает пряжку 16 мм. Это создаёт элегантный силуэт, который дополняет изысканный вид классических часов.',
52
+ answer: 'Сужение на 4 мм-классический выбор. Для ширины ушек 20 мм это означает пряжку 16 мм. Это создаёт элегантный силуэт, который дополняет изысканный вид классических часов.',
53
53
  },
54
54
  {
55
55
  question: 'Должны ли дайверские часы иметь сужающийся ремешок?',
@@ -89,7 +89,7 @@ export const content: ToolLocaleContent<StrapTaperCalculatorUI> = {
89
89
  'name': 'Какое сужение ремешка идеально подходит для классических часов?',
90
90
  'acceptedAnswer': {
91
91
  '@type': 'Answer',
92
- 'text': 'Сужение на 4 мм — классический выбор. Для ширины ушек 20 мм это даёт пряжку 16 мм, создавая элегантный силуэт.',
92
+ 'text': 'Сужение на 4 мм-классический выбор. Для ширины ушек 20 мм это даёт пряжку 16 мм, создавая элегантный силуэт.',
93
93
  },
94
94
  },
95
95
  {
@@ -75,11 +75,11 @@ export const content: ToolLocaleContent = {
75
75
  },
76
76
  seo: [
77
77
  { type: 'title', text: 'Полное руководство по точности и регулировке хода механических часов', level: 2 },
78
- { type: 'paragraph', html: 'Механические часы — это шедевры микромеханики, но в отличие от кварцевых моделей они подвержены влиянию различных физических и внешних факторов. Регулярное отслеживание суточной погрешности хода имеет решающее значение для оценки исправности механизма и определения необходимости профессионального обслуживания.' },
78
+ { type: 'paragraph', html: 'Механические часы-это шедевры микромеханики, но в отличие от кварцевых моделей они подвержены влиянию различных физических и внешних факторов. Регулярное отслеживание суточной погрешности хода имеет решающее значение для оценки исправности механизма и определения необходимости профессионального обслуживания.' },
79
79
  { type: 'title', text: 'Почему механические часы отклоняются: Ключевые факторы', level: 2 },
80
80
  { type: 'paragraph', html: 'На точность хода влияет множество параметров. Гравитация воздействует на балансовое колесо и волосковую пружину по-разному в зависимости от положения часов на ночь (положения покоя). Температурные перепады сжимают или расширяют спираль, изменяя частоту колебаний. Также важна степень завода пружины: полностью заведенные часы работают стабильнее тех, у которых запас хода на исходе.' },
81
81
  { type: 'title', text: 'Накопленная погрешность: Как секунды складываются в минуты', level: 2 },
82
- { type: 'paragraph', html: 'Отклонение всего в +5 секунд в день кажется несущественным, но время накапливается. За неделю это составит 35 секунд, за месяц — 2.5 минуты, а за год часы уйдут вперед более чем на 30 минут. Этот накопительный эффект показывает, почему коллекционерам важно регулярно проверять точность хода своих часов.' },
82
+ { type: 'paragraph', html: 'Отклонение всего в +5 секунд в день кажется несущественным, но время накапливается. За неделю это составит 35 секунд, за месяц-2.5 минуты, а за год часы уйдут вперед более чем на 30 минут. Этот накопительный эффект показывает, почему коллекционерам важно регулярно проверять точность хода своих часов.' },
83
83
  { type: 'title', text: 'Как вручную измерить и рассчитать точность хода часов', level: 2 },
84
84
  { type: 'paragraph', html: 'Вы можете оценить суточную погрешность без дорогого прибора (таймграфера). Синхронизируйте часы с точным источником времени (например, атомными часами по шкале UTC). Через 24 или 48 часов запишите новую разницу в секундах. Разделите эту разницу на количество дней, чтобы определить средний суточный ход.' },
85
85
  { type: 'title', text: 'Использование положений покоя для естественной регулировки', level: 2 },
@@ -43,19 +43,19 @@ export const content: ToolLocaleContent<WatchSavingsPlannerUI> = {
43
43
  now: 'Now',
44
44
  },
45
45
  seo: [
46
- { type: 'title', text: 'Watch Savings Goal PlannerTrack Your Next Watch Purchase', level: 2 },
46
+ { type: 'title', text: 'Watch Savings Goal Planner-Track Your Next Watch Purchase', level: 2 },
47
47
  { type: 'paragraph', html: 'Saving for a watch is a journey. Whether it\'s a <strong>vintage Speedmaster</strong>, a <strong>Submariner</strong>, or a <strong>Grand Seiko</strong>, a clear savings plan turns the dream into a timeline. This tool helps you visualize your progress, adjust your monthly contributions, and see exactly when you\'ll be walking out of the boutique with your grail.' },
48
48
  { type: 'title', text: 'Why a Savings Plan Matters for Watch Collectors', level: 3 },
49
49
  { type: 'paragraph', html: 'Watch collecting is a patient game. Prices for sought-after models climb steadily, and impulse purchases often lead to regret. A structured savings approach keeps you disciplined, prevents financial strain, and makes the final purchase feel earned. Plus, tracking your progress day by day builds anticipation and makes the unboxing even sweeter.' },
50
50
  { type: 'title', text: 'How to Set Realistic Watch Savings Goals', level: 3 },
51
- { type: 'paragraph', html: 'Start with the total price including taxes and shipping. Then divide by how much you can comfortably set aside each month. A good rule of thumb is to dedicate no more than <strong>10–15% of disposable income</strong> to watch savings. If the timeline feels too long, consider breaking it into smaller milestonesor exploring more affordable alternatives in the same style family.' },
51
+ { type: 'paragraph', html: 'Start with the total price including taxes and shipping. Then divide by how much you can comfortably set aside each month. A good rule of thumb is to dedicate no more than <strong>10–15% of disposable income</strong> to watch savings. If the timeline feels too long, consider breaking it into smaller milestones-or exploring more affordable alternatives in the same style family.' },
52
52
  { type: 'title', text: 'The Psychology of Goal Tracking', level: 3 },
53
- { type: 'paragraph', html: 'Visual progress tracking triggers dopamine release, the same neurochemical that makes collecting so rewarding. Each time you log a new contribution and watch the progress ring fill, you reinforce the habit. This is why small, regular savings often work better than sporadic large depositsthe ritual itself becomes part of the collecting experience.' },
53
+ { type: 'paragraph', html: 'Visual progress tracking triggers dopamine release, the same neurochemical that makes collecting so rewarding. Each time you log a new contribution and watch the progress ring fill, you reinforce the habit. This is why small, regular savings often work better than sporadic large deposits-the ritual itself becomes part of the collecting experience.' },
54
54
  ],
55
55
  faq: [
56
56
  {
57
57
  question: 'How much should I save each month for a watch?',
58
- answer: 'Aim for 10–15% of your disposable monthly income. The key is consistencyeven $100 a month adds up to $1,200 a year. Adjust the amount based on your timeline: shorter goals need larger monthly contributions.',
58
+ answer: 'Aim for 10–15% of your disposable monthly income. The key is consistency-even $100 a month adds up to $1,200 a year. Adjust the amount based on your timeline: shorter goals need larger monthly contributions.',
59
59
  },
60
60
  {
61
61
  question: 'Should I save for one watch at a time or multiple?',
@@ -95,7 +95,7 @@ export const content: ToolLocaleContent<WatchSavingsPlannerUI> = {
95
95
  'name': 'How much should I save each month for a watch?',
96
96
  'acceptedAnswer': {
97
97
  '@type': 'Answer',
98
- 'text': 'Aim for 10–15% of your disposable monthly income. The key is consistencyeven $100 a month adds up to $1,200 a year.',
98
+ 'text': 'Aim for 10–15% of your disposable monthly income. The key is consistency-even $100 a month adds up to $1,200 a year.',
99
99
  },
100
100
  },
101
101
  {
@@ -0,0 +1,16 @@
1
+ ---
2
+ import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
+ import { watchSizeComparator } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'en' } = Astro.props as Props;
11
+ const loader = watchSizeComparator.i18n[locale] || watchSizeComparator.i18n.en;
12
+ const content = await loader?.();
13
+ if (!content) return null;
14
+ ---
15
+
16
+ {content && <SharedBibliography links={content.bibliography} />}
@@ -0,0 +1,16 @@
1
+ import type { BibliographyEntry } from '../../types';
2
+
3
+ export const bibliography: BibliographyEntry[] = [
4
+ {
5
+ name: 'Watch Sizing Guide-How to Choose the Right Watch Size',
6
+ url: 'https://www.prestigetime.com/blog/watch-size-guide.html',
7
+ },
8
+ {
9
+ name: 'Lug-to-Lug Measurement Explained-Teddy Baldassarre',
10
+ url: 'https://teddybaldassarre.com/blogs/watches/lug-to-lug',
11
+ },
12
+ {
13
+ name: 'Watch Case Sizes: A Complete Guide',
14
+ url: 'https://www.uniformwares.com/watch-case-sizes/',
15
+ },
16
+ ];