@jjlmoya/utils-chrono 1.23.0 → 1.24.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 (35) hide show
  1. package/package.json +1 -1
  2. package/src/layouts/PreviewLayout.astro +1 -1
  3. package/src/tests/diacritics_density.test.ts +118 -0
  4. package/src/tests/inverted_punctuation.test.ts +84 -0
  5. package/src/tests/script_density.test.ts +94 -0
  6. package/src/tool/gear-train-explorer/client.ts +13 -12
  7. package/src/tool/gear-train-explorer/component.astro +1 -1
  8. package/src/tool/gear-train-explorer/gear-train-explorer.css +49 -24
  9. package/src/tool/mainspring-finder/i18n/es.ts +6 -6
  10. package/src/tool/mainspring-finder/i18n/it.ts +1 -1
  11. package/src/tool/power-reserve-estimator/client.ts +13 -12
  12. package/src/tool/power-reserve-estimator/component.astro +1 -1
  13. package/src/tool/power-reserve-estimator/power-reserve-estimator.css +69 -53
  14. package/src/tool/quartz-battery-health/client.ts +20 -20
  15. package/src/tool/quartz-battery-health/component.astro +1 -1
  16. package/src/tool/quartz-battery-health/i18n/es.ts +1 -1
  17. package/src/tool/quartz-battery-health/i18n/fr.ts +1 -1
  18. package/src/tool/quartz-battery-health/i18n/pt.ts +1 -1
  19. package/src/tool/quartz-battery-health/quartz-battery-health.css +77 -59
  20. package/src/tool/sidereal-time-tracker/component.astro +1 -1
  21. package/src/tool/sidereal-time-tracker/sidereal-time-tracker.css +60 -1
  22. package/src/tool/tachymeter-calculator/i18n/es.ts +6 -6
  23. package/src/tool/tachymeter-calculator/i18n/fr.ts +1 -1
  24. package/src/tool/tachymeter-calculator/i18n/it.ts +1 -1
  25. package/src/tool/tachymeter-calculator/i18n/pl.ts +1 -1
  26. package/src/tool/tachymeter-calculator/i18n/pt.ts +1 -1
  27. package/src/tool/tachymeter-calculator/i18n/tr.ts +1 -1
  28. package/src/tool/telemeter-calculator/component.astro +1 -1
  29. package/src/tool/telemeter-calculator/i18n/es.ts +1 -1
  30. package/src/tool/telemeter-calculator/telemeter-calculator.css +51 -6
  31. package/src/tool/watch-savings-planner/i18n/es.ts +2 -2
  32. package/src/tool/watch-savings-planner/i18n/pl.ts +1 -1
  33. package/src/tool/wrist-presence-calculator/client.ts +1 -1
  34. package/src/tool/wrist-presence-calculator/component.astro +3 -3
  35. package/src/tool/wrist-presence-calculator/wrist-presence-calculator.css +30 -8
@@ -25,18 +25,19 @@ const activityFactors: Record<string, number> = {
25
25
  };
26
26
 
27
27
  const movementSelect = document.getElementById('movement-select') as HTMLSelectElement;
28
+ const root = movementSelect.closest('.power-reserve-card') || document;
28
29
  const turnsInput = document.getElementById('turns-input') as HTMLInputElement;
29
30
  const hoursInput = document.getElementById('hours-input') as HTMLInputElement;
30
- const activityChips = document.querySelectorAll('[data-activity]') as NodeListOf<HTMLButtonElement>;
31
- const customFields = document.getElementById('custom-fields') as HTMLElement;
32
- const customReserve = document.getElementById('custom-reserve') as HTMLInputElement;
33
- const customTurns = document.getElementById('custom-turns') as HTMLInputElement;
34
- const calcBtn = document.getElementById('calc-btn') as HTMLButtonElement;
35
- const resultCard = document.getElementById('result-card') as HTMLElement;
36
- const gaugeFill = document.getElementById('gauge-fill') as HTMLElement;
37
- const chargeValue = document.getElementById('charge-value') as HTMLElement;
38
- const reserveValue = document.getElementById('reserve-value') as HTMLElement;
39
- const stopValue = document.getElementById('stop-value') as HTMLElement;
31
+ const activityChips = root.querySelectorAll('[data-activity]') as NodeListOf<HTMLButtonElement>;
32
+ const customFields = root.querySelector('#custom-fields') as HTMLElement;
33
+ const customReserve = root.querySelector('#custom-reserve') as HTMLInputElement;
34
+ const customTurns = root.querySelector('#custom-turns') as HTMLInputElement;
35
+ const calcBtn = root.querySelector('#calc-btn') as HTMLButtonElement;
36
+ const resultCard = root.querySelector('#result-card') as HTMLElement;
37
+ const gaugeFill = root.querySelector('#gauge-fill') as HTMLElement;
38
+ const chargeValue = root.querySelector('#charge-value') as HTMLElement;
39
+ const reserveValue = root.querySelector('#reserve-value') as HTMLElement;
40
+ const stopValue = root.querySelector('#stop-value') as HTMLElement;
40
41
 
41
42
  let currentActivity = 'medium';
42
43
 
@@ -115,9 +116,9 @@ activityChips.forEach((chip) => {
115
116
  });
116
117
  });
117
118
 
118
- document.querySelectorAll('.stepper-btn').forEach((btn) => {
119
+ root.querySelectorAll('.stepper-btn').forEach((btn) => {
119
120
  btn.addEventListener('click', () => {
120
- const target = document.getElementById(btn.getAttribute('data-target') || '') as HTMLInputElement;
121
+ const target = root.querySelector('#' + (btn.getAttribute('data-target') || '')) as HTMLInputElement;
121
122
  const dir = parseInt(btn.getAttribute('data-dir') || '1', 10);
122
123
  if (target) {
123
124
  calcValue(target, dir);
@@ -8,7 +8,7 @@ interface Props {
8
8
  const { ui } = Astro.props;
9
9
  ---
10
10
 
11
- <div class="tool-main-card" data-ui={JSON.stringify(ui)}>
11
+ <div class="power-reserve-card" data-ui={JSON.stringify(ui)}>
12
12
  <EstimatorPanel labels={ui} />
13
13
  </div>
14
14
 
@@ -1,4 +1,4 @@
1
- .tool-main-card {
1
+ .power-reserve-card {
2
2
  background: var(--bg-surface);
3
3
  border: 1px solid var(--border-color);
4
4
  border-radius: 1.25rem;
@@ -13,7 +13,7 @@
13
13
  overflow: hidden;
14
14
  }
15
15
 
16
- .estimator-panel {
16
+ .power-reserve-card .estimator-panel {
17
17
  display: flex;
18
18
  flex-direction: column;
19
19
  gap: 1.25rem;
@@ -21,13 +21,13 @@
21
21
  z-index: 1;
22
22
  }
23
23
 
24
- .panel-section {
24
+ .power-reserve-card .panel-section {
25
25
  display: flex;
26
26
  flex-direction: column;
27
27
  gap: 0.5rem;
28
28
  }
29
29
 
30
- .section-label {
30
+ .power-reserve-card .section-label {
31
31
  font-size: 0.75rem;
32
32
  font-weight: 600;
33
33
  color: var(--text-dimmed);
@@ -38,7 +38,7 @@
38
38
  gap: 0.3rem;
39
39
  }
40
40
 
41
- .label-sub {
41
+ .power-reserve-card .label-sub {
42
42
  font-size: 0.65rem;
43
43
  color: var(--text-base);
44
44
  opacity: 0.35;
@@ -47,7 +47,7 @@
47
47
  letter-spacing: 0;
48
48
  }
49
49
 
50
- .movement-select {
50
+ .power-reserve-card .movement-select {
51
51
  width: 100%;
52
52
  padding: 0.65rem 0.75rem;
53
53
  background: var(--bg-page);
@@ -64,31 +64,31 @@
64
64
  padding-right: 2rem;
65
65
  }
66
66
 
67
- .movement-select:focus {
67
+ .power-reserve-card .movement-select:focus {
68
68
  outline: none;
69
69
  border-color: var(--accent);
70
70
  }
71
71
 
72
- .input-row {
72
+ .power-reserve-card .input-row {
73
73
  display: flex;
74
74
  gap: 0.75rem;
75
75
  align-items: flex-end;
76
76
  }
77
77
 
78
- .input-group {
78
+ .power-reserve-card .input-group {
79
79
  flex: 1;
80
80
  display: flex;
81
81
  flex-direction: column;
82
82
  gap: 0.35rem;
83
83
  }
84
84
 
85
- .input-label {
85
+ .power-reserve-card .input-label {
86
86
  font-size: 0.75rem;
87
87
  color: var(--text-dimmed);
88
88
  font-weight: 600;
89
89
  }
90
90
 
91
- .stepper-wrap {
91
+ .power-reserve-card .stepper-wrap {
92
92
  display: flex;
93
93
  align-items: center;
94
94
  background: var(--bg-page);
@@ -98,11 +98,11 @@
98
98
  transition: border-color 0.2s;
99
99
  }
100
100
 
101
- .stepper-wrap:focus-within {
101
+ .power-reserve-card .stepper-wrap:focus-within {
102
102
  border-color: var(--accent);
103
103
  }
104
104
 
105
- .stepper-input {
105
+ .power-reserve-card .stepper-input {
106
106
  width: 100%;
107
107
  padding: 0.6rem 0.25rem;
108
108
  border: none;
@@ -115,17 +115,17 @@
115
115
  -moz-appearance: textfield;
116
116
  }
117
117
 
118
- .stepper-input::-webkit-inner-spin-button,
119
- .stepper-input::-webkit-outer-spin-button {
118
+ .power-reserve-card .stepper-input::-webkit-inner-spin-button,
119
+ .power-reserve-card .stepper-input::-webkit-outer-spin-button {
120
120
  -webkit-appearance: none;
121
121
  margin: 0;
122
122
  }
123
123
 
124
- .stepper-input:focus {
124
+ .power-reserve-card .stepper-input:focus {
125
125
  outline: none;
126
126
  }
127
127
 
128
- .stepper-btn {
128
+ .power-reserve-card .stepper-btn {
129
129
  display: flex;
130
130
  align-items: center;
131
131
  justify-content: center;
@@ -141,17 +141,17 @@
141
141
  user-select: none;
142
142
  }
143
143
 
144
- .stepper-btn:hover {
144
+ .power-reserve-card .stepper-btn:hover {
145
145
  background: var(--bg-page);
146
146
  color: var(--accent);
147
147
  }
148
148
 
149
- .stepper-btn:active {
149
+ .power-reserve-card .stepper-btn:active {
150
150
  background: var(--border-base);
151
151
  transform: scale(0.95);
152
152
  }
153
153
 
154
- .chip-group {
154
+ .power-reserve-card .chip-group {
155
155
  display: flex;
156
156
  gap: 0.25rem;
157
157
  background: var(--bg-page);
@@ -160,7 +160,7 @@
160
160
  border: 1px solid var(--border-base);
161
161
  }
162
162
 
163
- .chip {
163
+ .power-reserve-card .chip {
164
164
  flex: 1;
165
165
  padding: 0.3rem 0.4rem;
166
166
  border: none;
@@ -174,16 +174,16 @@
174
174
  white-space: nowrap;
175
175
  }
176
176
 
177
- .chip:hover {
177
+ .power-reserve-card .chip:hover {
178
178
  color: var(--text-base);
179
179
  }
180
180
 
181
- .chip.active {
181
+ .power-reserve-card .chip.active {
182
182
  background: var(--accent);
183
183
  color: var(--text-on-primary, #fff);
184
184
  }
185
185
 
186
- .calc-btn {
186
+ .power-reserve-card .calc-btn {
187
187
  display: flex;
188
188
  align-items: center;
189
189
  justify-content: center;
@@ -201,17 +201,17 @@
201
201
  box-shadow: 0 2px 12px rgba(99, 102, 241, 0.25);
202
202
  }
203
203
 
204
- .calc-btn:hover {
204
+ .power-reserve-card .calc-btn:hover {
205
205
  opacity: 0.9;
206
206
  transform: translateY(-1px);
207
207
  box-shadow: 0 4px 16px rgba(99, 102, 241, 0.35);
208
208
  }
209
209
 
210
- .calc-btn:active {
210
+ .power-reserve-card .calc-btn:active {
211
211
  transform: scale(0.97);
212
212
  }
213
213
 
214
- .result-card {
214
+ .power-reserve-card .result-card {
215
215
  background: var(--bg-page);
216
216
  border: 1px solid var(--border-base);
217
217
  border-radius: 1rem;
@@ -222,7 +222,7 @@
222
222
  animation: fade-slide-in 0.3s ease;
223
223
  }
224
224
 
225
- .result-header {
225
+ .power-reserve-card .result-header {
226
226
  display: flex;
227
227
  align-items: center;
228
228
  gap: 0.5rem;
@@ -231,13 +231,13 @@
231
231
  font-weight: 700;
232
232
  }
233
233
 
234
- .gauge-wrap {
234
+ .power-reserve-card .gauge-wrap {
235
235
  display: flex;
236
236
  flex-direction: column;
237
237
  gap: 0.25rem;
238
238
  }
239
239
 
240
- .gauge-track {
240
+ .power-reserve-card .gauge-track {
241
241
  width: 100%;
242
242
  height: 14px;
243
243
  background: var(--border-base);
@@ -245,49 +245,49 @@
245
245
  overflow: hidden;
246
246
  }
247
247
 
248
- .gauge-fill {
248
+ .power-reserve-card .gauge-fill {
249
249
  height: 100%;
250
250
  border-radius: 6px;
251
251
  transition: width 0.6s ease, background 0.6s ease;
252
252
  }
253
253
 
254
- .gauge-marks {
254
+ .power-reserve-card .gauge-marks {
255
255
  display: flex;
256
256
  justify-content: space-between;
257
257
  padding: 0 0.1rem;
258
258
  }
259
259
 
260
- .gauge-mark {
260
+ .power-reserve-card .gauge-mark {
261
261
  font-size: 0.6rem;
262
262
  font-weight: 700;
263
263
  color: var(--text-base);
264
264
  opacity: 0.4;
265
265
  }
266
266
 
267
- .gauge-mark.gauge-danger {
267
+ .power-reserve-card .gauge-mark.gauge-danger {
268
268
  color: var(--color-danger, #ef4444);
269
269
  opacity: 0.9;
270
270
  font-weight: 800;
271
271
  }
272
272
 
273
- .gauge-mark.gauge-warning {
273
+ .power-reserve-card .gauge-mark.gauge-warning {
274
274
  color: var(--color-warning, #f59e0b);
275
275
  opacity: 0.85;
276
276
  font-weight: 800;
277
277
  }
278
278
 
279
- .gauge-mark.gauge-ok {
279
+ .power-reserve-card .gauge-mark.gauge-ok {
280
280
  color: var(--color-success, #22c55e);
281
281
  opacity: 0.85;
282
282
  font-weight: 800;
283
283
  }
284
284
 
285
- .charge-stats {
285
+ .power-reserve-card .charge-stats {
286
286
  display: flex;
287
287
  gap: 0.5rem;
288
288
  }
289
289
 
290
- .charge-stat {
290
+ .power-reserve-card .charge-stat {
291
291
  flex: 1;
292
292
  display: flex;
293
293
  flex-direction: column;
@@ -295,14 +295,14 @@
295
295
  gap: 0.15rem;
296
296
  }
297
297
 
298
- .stat-value {
298
+ .power-reserve-card .stat-value {
299
299
  font-size: 1.25rem;
300
300
  font-weight: 800;
301
301
  color: var(--text-base);
302
302
  letter-spacing: -0.02em;
303
303
  }
304
304
 
305
- .stat-label {
305
+ .power-reserve-card .stat-label {
306
306
  font-size: 0.6rem;
307
307
  font-weight: 600;
308
308
  color: var(--text-dimmed);
@@ -311,7 +311,7 @@
311
311
  text-align: center;
312
312
  }
313
313
 
314
- .steps-section {
314
+ .power-reserve-card .steps-section {
315
315
  display: flex;
316
316
  flex-direction: column;
317
317
  gap: 0.625rem;
@@ -321,13 +321,13 @@
321
321
  border: 1px solid var(--border-base);
322
322
  }
323
323
 
324
- .step-row {
324
+ .power-reserve-card .step-row {
325
325
  display: flex;
326
326
  align-items: center;
327
327
  gap: 0.75rem;
328
328
  }
329
329
 
330
- .step-marker {
330
+ .power-reserve-card .step-marker {
331
331
  width: 1.375rem;
332
332
  height: 1.375rem;
333
333
  border-radius: 50%;
@@ -341,14 +341,14 @@
341
341
  flex-shrink: 0;
342
342
  }
343
343
 
344
- .step-text {
344
+ .power-reserve-card .step-text {
345
345
  font-size: 0.8125rem;
346
346
  color: var(--text-base);
347
347
  line-height: 1.4;
348
348
  opacity: 0.85;
349
349
  }
350
350
 
351
- .tip-row {
351
+ .power-reserve-card .tip-row {
352
352
  display: flex;
353
353
  gap: 0.5rem;
354
354
  padding: 0.75rem 1rem;
@@ -357,13 +357,13 @@
357
357
  border: 1px solid var(--border-base);
358
358
  }
359
359
 
360
- .tip-icon {
360
+ .power-reserve-card .tip-icon {
361
361
  flex-shrink: 0;
362
362
  margin-top: 0.1rem;
363
363
  color: var(--accent);
364
364
  }
365
365
 
366
- .tip-text {
366
+ .power-reserve-card .tip-text {
367
367
  font-size: 0.8rem;
368
368
  color: var(--text-base);
369
369
  line-height: 1.5;
@@ -382,21 +382,37 @@
382
382
  }
383
383
 
384
384
  @media (max-width: 520px) {
385
- .tool-main-card {
385
+ .power-reserve-card {
386
386
  padding: 1rem;
387
387
  gap: 1.25rem;
388
+ max-width: 100%;
389
+ border-radius: 0.875rem;
388
390
  }
389
391
 
390
- .input-row {
392
+ .power-reserve-card .input-row {
391
393
  flex-direction: column;
392
394
  gap: 0.5rem;
395
+ align-items: stretch;
393
396
  }
394
397
 
395
- .charge-stats {
396
- flex-wrap: wrap;
398
+ .power-reserve-card .charge-stats {
399
+ display: grid;
400
+ grid-template-columns: 1fr;
397
401
  }
398
402
 
399
- .charge-stat {
400
- min-width: 30%;
403
+ .power-reserve-card .charge-stat {
404
+ min-width: 0;
405
+ padding: 0.5rem;
406
+ border-radius: 0.75rem;
407
+ background: var(--bg-surface);
408
+ }
409
+
410
+ .power-reserve-card .chip-group {
411
+ width: 100%;
412
+ }
413
+
414
+ .power-reserve-card .stat-value {
415
+ font-size: 1.1rem;
416
+ overflow-wrap: anywhere;
401
417
  }
402
418
  }
@@ -16,25 +16,26 @@ const batteries: BatteryData[] = [
16
16
  { id: 'cr2025', name: 'CR2025', capacity: 165 },
17
17
  ];
18
18
 
19
- const mainEl = document.querySelector('.tool-main-card') as HTMLElement;
19
+ const mainEl = document.querySelector('.quartz-battery-card') as HTMLElement;
20
20
  const ui = mainEl ? JSON.parse(mainEl.dataset.ui || '{}') : {};
21
21
 
22
- const batterySelect = document.getElementById('battery-select') as HTMLSelectElement;
23
- const customFields = document.getElementById('custom-fields') as HTMLElement;
24
- const customCapacity = document.getElementById('custom-capacity') as HTMLInputElement;
25
- const consumptionInput = document.getElementById('consumption-input') as HTMLInputElement;
26
- const installMonth = document.getElementById('install-month') as HTMLSelectElement;
27
- const installYear = document.getElementById('install-year') as HTMLInputElement;
28
- const calcBtn = document.getElementById('calc-btn') as HTMLButtonElement;
29
- const resultCard = document.getElementById('result-card') as HTMLElement;
30
- const lifeYears = document.getElementById('life-years') as HTMLElement;
31
- const lifeMonths = document.getElementById('life-months') as HTMLElement;
32
- const lifeDays = document.getElementById('life-days') as HTMLElement;
33
- const gaugeFill = document.getElementById('gauge-fill') as HTMLElement;
34
- const healthBadge = document.getElementById('health-badge') as HTMLElement;
35
- const changeDateRow = document.getElementById('change-date-row') as HTMLElement;
36
- const changeDateValue = document.getElementById('change-date-value') as HTMLElement;
37
- const changeDateHint = document.getElementById('change-date-hint') as HTMLElement;
22
+ const root = mainEl || document;
23
+ const batterySelect = root.querySelector('#battery-select') as HTMLSelectElement;
24
+ const customFields = root.querySelector('#custom-fields') as HTMLElement;
25
+ const customCapacity = root.querySelector('#custom-capacity') as HTMLInputElement;
26
+ const consumptionInput = root.querySelector('#consumption-input') as HTMLInputElement;
27
+ const installMonth = root.querySelector('#install-month') as HTMLSelectElement;
28
+ const installYear = root.querySelector('#install-year') as HTMLInputElement;
29
+ const calcBtn = root.querySelector('#calc-btn') as HTMLButtonElement;
30
+ const resultCard = root.querySelector('#result-card') as HTMLElement;
31
+ const lifeYears = root.querySelector('#life-years') as HTMLElement;
32
+ const lifeMonths = root.querySelector('#life-months') as HTMLElement;
33
+ const lifeDays = root.querySelector('#life-days') as HTMLElement;
34
+ const gaugeFill = root.querySelector('#gauge-fill') as HTMLElement;
35
+ const healthBadge = root.querySelector('#health-badge') as HTMLElement;
36
+ const changeDateRow = root.querySelector('#change-date-row') as HTMLElement;
37
+ const changeDateValue = root.querySelector('#change-date-value') as HTMLElement;
38
+ const changeDateHint = root.querySelector('#change-date-hint') as HTMLElement;
38
39
 
39
40
  const STORAGE_KEY = 'quartz-battery-health-state';
40
41
 
@@ -179,9 +180,9 @@ calcBtn.addEventListener('click', commit);
179
180
  el.addEventListener('input', commit);
180
181
  });
181
182
 
182
- document.querySelectorAll('.stepper-btn').forEach((btn) => {
183
+ root.querySelectorAll('.stepper-btn').forEach((btn) => {
183
184
  btn.addEventListener('click', () => {
184
- const target = document.getElementById(btn.getAttribute('data-target') || '') as HTMLInputElement;
185
+ const target = root.querySelector('#' + (btn.getAttribute('data-target') || '')) as HTMLInputElement;
185
186
  const dir = parseFloat(btn.getAttribute('data-dir') || '1');
186
187
  if (target) {
187
188
  calcValue(target, dir);
@@ -195,4 +196,3 @@ toggleCustom();
195
196
  commit();
196
197
 
197
198
  export {};
198
-
@@ -8,7 +8,7 @@ interface Props {
8
8
  const { ui } = Astro.props;
9
9
  ---
10
10
 
11
- <div class="tool-main-card" data-ui={JSON.stringify(ui)}>
11
+ <div class="quartz-battery-card" data-ui={JSON.stringify(ui)}>
12
12
  <BatteryHealthPanel labels={ui} />
13
13
  </div>
14
14
 
@@ -48,7 +48,7 @@ export const content: ToolLocaleContent<QuartzBatteryHealthUI> = {
48
48
  ],
49
49
  columns: 3,
50
50
  },
51
- { type: 'paragraph', html: 'Se pregunta cuándo dejará de funcionar su reloj de cuarzo? El <strong>Comprobador de Salud de Batería de Cuarzo</strong> le ayuda a estimar la vida restante de cualquier pila de movimiento de cuarzo comparando la capacidad de la pila (medida en mAh) con el consumo medio de energía del movimiento (medido en microamperios, µA). Ya sea que tenga un ETA suizo, un Miyota japonés, un Seiko, un Ronda o un movimiento chino DG, esta herramienta calcula la vida útil teórica en años, meses y días, e incluso puede predecir la fecha exacta de reemplazo si introduce el mes y año de instalación.' },
51
+ { type: 'paragraph', html: '¿Se pregunta cuándo dejará de funcionar su reloj de cuarzo? El <strong>Comprobador de Salud de Batería de Cuarzo</strong> le ayuda a estimar la vida restante de cualquier pila de movimiento de cuarzo comparando la capacidad de la pila (medida en mAh) con el consumo medio de energía del movimiento (medido en microamperios, µA). Ya sea que tenga un ETA suizo, un Miyota japonés, un Seiko, un Ronda o un movimiento chino DG, esta herramienta calcula la vida útil teórica en años, meses y días, e incluso puede predecir la fecha exacta de reemplazo si introduce el mes y año de instalación.' },
52
52
  { type: 'title', text: 'Cómo se calcula la vida de la batería de cuarzo: las matemáticas detrás de la estimación', level: 3 },
53
53
  { type: 'paragraph', html: 'La vida de la batería sigue una fórmula eléctrica simple: <strong>Vida (horas) = (Capacidad de la pila en mAh x 1000) / Consumo de corriente en µA</strong>. Dividiendo ese resultado por 24 se obtienen días, y por 365,25 se obtienen años. Por ejemplo, una pila <strong>SR920SW (371) estándar de 40 mAh</strong> alimentando un movimiento que consume <strong>1,5 µA</strong> durará teóricamente unos <strong>3 años</strong>. Reduzca el consumo a 1,0 µA y la misma pila supera los 4,5 años. Auméntelo a 2,5 µA y la vida de la batería cae por debajo de 2 años. Cada fracción de microamperio importa a la hora de planificar los intervalos de servicio.' },
54
54
  { type: 'title', text: 'Tipos de pila de reloj de cuarzo más comunes y sus capacidades', level: 3 },
@@ -5,7 +5,7 @@ import { bibliography } from '../bibliography';
5
5
  export const content: ToolLocaleContent<QuartzBatteryHealthUI> = {
6
6
  slug: 'controleur-sante-pile-quartz',
7
7
  title: 'Controleur de Sante de Pile Quartz',
8
- description: 'Calculez la duree de vie theorique d\'une pile de mouvement quartz en entrant la capacite de la cellule (mAh) et la consommation du calibre (µA). Ajoutez optionnellement la date d\'installation pour estimer la date de remplacement.',
8
+ description: 'Calculez la durée de vie théorique d\'une pile de mouvement quartz en entrant la capacité de la cellule (mAh) et la consommation du calibre (µA). Ajoutez optionnellement la date d\'installation pour estimer la date de remplacement.',
9
9
  ui: {
10
10
  title: 'Controleur de Sante de Pile Quartz',
11
11
  batteryLabel: 'Pile',
@@ -5,7 +5,7 @@ import { bibliography } from '../bibliography';
5
5
  export const content: ToolLocaleContent<QuartzBatteryHealthUI> = {
6
6
  slug: 'verificador-saude-bateria-quartzo',
7
7
  title: 'Verificador de Saude da Bateria de Quartzo',
8
- description: 'Calcule a vida teorica da bateria de um movimento de quartzo inserindo a capacidade da pilha (mAh) e o consumo do calibre (microamperes). Opcionalmente defina a data de instalacao para estimar a data de substituicao.',
8
+ description: 'Calcule a vida teórica da bateria de um movimento de quartzo inserindo a capacidade da pilha (mAh) e o consumo do calibre (microamperes). Opcionalmente defina a data de instalação para estimar a data de substituição.',
9
9
  ui: {
10
10
  title: 'Verificador de Saude da Bateria de Quartzo',
11
11
  batteryLabel: 'Pilha',