cronli5 0.1.5 → 0.1.6
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.
- package/CHANGELOG.md +28 -0
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +117 -20
- package/dist/cronli5.js +117 -20
- package/dist/lang/de.cjs +94 -19
- package/dist/lang/de.js +94 -19
- package/dist/lang/en.cjs +117 -20
- package/dist/lang/en.js +117 -20
- package/dist/lang/es.cjs +89 -14
- package/dist/lang/es.js +89 -14
- package/dist/lang/fi.cjs +107 -19
- package/dist/lang/fi.js +107 -19
- package/dist/lang/zh.cjs +90 -53
- package/dist/lang/zh.js +90 -53
- package/package.json +2 -2
- package/src/lang/de/index.ts +238 -51
- package/src/lang/en/index.ts +280 -46
- package/src/lang/es/index.ts +222 -31
- package/src/lang/fi/index.ts +245 -39
- package/src/lang/zh/index.ts +209 -94
package/dist/lang/es.js
CHANGED
|
@@ -176,14 +176,21 @@ function secondsListAtClock(ir, rest, opts) {
|
|
|
176
176
|
}
|
|
177
177
|
function composeHourCadence(ir, plan, opts) {
|
|
178
178
|
const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
|
|
179
|
-
|
|
179
|
+
if (!clockRest || ir.shapes.minute !== "single") {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
const minute = +ir.pattern.minute;
|
|
183
|
+
return hourCadence(ir, minute, opts) ?? hourRangeCadence(ir, minute, opts);
|
|
184
|
+
}
|
|
185
|
+
function isPinnedMinuteSeconds(ir, plan) {
|
|
186
|
+
return plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step");
|
|
180
187
|
}
|
|
181
188
|
function renderComposeSeconds(ir, plan, opts) {
|
|
182
189
|
const hourCad = composeHourCadence(ir, plan, opts);
|
|
183
190
|
if (hourCad !== null) {
|
|
184
191
|
return hourCad;
|
|
185
192
|
}
|
|
186
|
-
if (
|
|
193
|
+
if (isPinnedMinuteSeconds(ir, plan)) {
|
|
187
194
|
return pinnedMinuteSeconds(ir, plan.rest, opts);
|
|
188
195
|
}
|
|
189
196
|
if (plan.rest.kind === "clockTimes" && ir.shapes.second === "list") {
|
|
@@ -199,7 +206,9 @@ function renderComposeSeconds(ir, plan, opts) {
|
|
|
199
206
|
if (isEveryOtherMinuteSeconds(ir, plan)) {
|
|
200
207
|
return secondsLeadClause(ir, opts) + " de " + render(ir, plan.rest, opts);
|
|
201
208
|
}
|
|
202
|
-
|
|
209
|
+
const restOwnsLead = plan.rest.kind === "compactClockTimes" && ir.analyses.clockSecond;
|
|
210
|
+
const lead = restOwnsLead ? "" : secondsLeadClause(ir, opts) + ", ";
|
|
211
|
+
return lead + render(ir, plan.rest, opts);
|
|
203
212
|
}
|
|
204
213
|
function isEveryOtherMinuteSeconds(ir, plan) {
|
|
205
214
|
if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
|
|
@@ -211,7 +220,7 @@ function isEveryOtherMinuteSeconds(ir, plan) {
|
|
|
211
220
|
function pinnedMinuteSeconds(ir, rest, opts) {
|
|
212
221
|
const dayTrail = leadingQualifier(ir, opts).trimEnd();
|
|
213
222
|
const trail = dayTrail ? ", " + dayTrail : "";
|
|
214
|
-
if (+rest.times[0].minute === 0) {
|
|
223
|
+
if (+rest.times[0].minute === 0 && ir.shapes.minute === "single") {
|
|
215
224
|
return secondsLeadClause(ir, opts) + " durante un minuto " + durationHourList(rest.times, opts) + trail;
|
|
216
225
|
}
|
|
217
226
|
return secondsLeadClause(ir, opts) + " de " + explicitClockList(rest.times, opts) + trail;
|
|
@@ -328,7 +337,12 @@ function renderMinuteFrequency(ir, plan, opts) {
|
|
|
328
337
|
opts
|
|
329
338
|
);
|
|
330
339
|
if (plan.hours.kind === "during") {
|
|
331
|
-
|
|
340
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
341
|
+
if (cadence) {
|
|
342
|
+
phrase += ", " + cadence;
|
|
343
|
+
} else {
|
|
344
|
+
phrase += singleHourStep(ir.analyses.segments.hour) ? ", " + stepHourSpan(stepSegment(ir.analyses.segments.hour), opts) : " " + hourSpanFromTimes(ir, plan.hours.times, opts);
|
|
345
|
+
}
|
|
332
346
|
} else if (plan.hours.kind === "window") {
|
|
333
347
|
phrase += " " + hourWindow(plan.hours, opts);
|
|
334
348
|
} else if (plan.hours.kind === "step") {
|
|
@@ -347,22 +361,30 @@ function renderMinuteSpanInHour(ir, plan, opts) {
|
|
|
347
361
|
) + trailingQualifier(ir, opts);
|
|
348
362
|
}
|
|
349
363
|
function renderMinutesAcrossHours(ir, plan, opts) {
|
|
364
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
350
365
|
if (plan.form === "wildcard") {
|
|
366
|
+
if (cadence !== null) {
|
|
367
|
+
return "cada minuto, " + cadence + trailingQualifier(ir, opts);
|
|
368
|
+
}
|
|
351
369
|
if (singleHourStep(ir.analyses.segments.hour)) {
|
|
352
370
|
return "cada minuto, " + stepHourSpan(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
353
371
|
}
|
|
354
372
|
return "cada minuto " + hourSpanFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
355
373
|
}
|
|
356
374
|
const lead = plan.form === "range" ? minuteRangeLead(ir.pattern.minute) : minutesList(ir, opts);
|
|
375
|
+
if (cadence !== null) {
|
|
376
|
+
return lead + ", " + cadence + trailingQualifier(ir, opts);
|
|
377
|
+
}
|
|
357
378
|
return lead + ", " + atHourTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
358
379
|
}
|
|
359
380
|
function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
360
381
|
const segment = stepSegment(ir.analyses.segments.hour);
|
|
382
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
361
383
|
if (plan.form === "wildcard") {
|
|
362
384
|
return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(ir, opts);
|
|
363
385
|
}
|
|
364
386
|
const lead = plan.form === "list" ? minutesList(ir, opts) : minuteRangeLead(ir.pattern.minute);
|
|
365
|
-
return lead + ", " + stepHours(segment, opts) + trailingQualifier(ir, opts);
|
|
387
|
+
return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(ir, opts);
|
|
366
388
|
}
|
|
367
389
|
function renderEveryHour(ir, plan, opts) {
|
|
368
390
|
return "cada hora" + trailingQualifier(ir, opts);
|
|
@@ -382,6 +404,10 @@ function renderHourRange(ir, plan, opts) {
|
|
|
382
404
|
return lead + ", " + window + trailingQualifier(ir, opts);
|
|
383
405
|
}
|
|
384
406
|
function renderHourStep(ir, plan, opts) {
|
|
407
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
408
|
+
if (cadence !== null) {
|
|
409
|
+
return cadence + trailingQualifier(ir, opts);
|
|
410
|
+
}
|
|
385
411
|
return stepHours(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
386
412
|
}
|
|
387
413
|
function boundedWindow(plan) {
|
|
@@ -453,7 +479,8 @@ function unionYaseaSuffix(ir, opts) {
|
|
|
453
479
|
}
|
|
454
480
|
function renderClockTimes(ir, plan, opts) {
|
|
455
481
|
if (ir.shapes.minute === "single") {
|
|
456
|
-
const
|
|
482
|
+
const minute = +ir.pattern.minute;
|
|
483
|
+
const cadence = hourCadence(ir, minute, opts) ?? hourRangeCadence(ir, minute, opts);
|
|
457
484
|
if (cadence !== null) {
|
|
458
485
|
return cadence;
|
|
459
486
|
}
|
|
@@ -639,9 +666,9 @@ function groupClockTimesByArticle(phrases) {
|
|
|
639
666
|
}
|
|
640
667
|
function renderCompactClockTimes(ir, plan, opts) {
|
|
641
668
|
if (plan.fold) {
|
|
642
|
-
const
|
|
643
|
-
if (
|
|
644
|
-
return
|
|
669
|
+
const cadence2 = hourCadence(ir, plan.minute, opts) ?? hourRangeCadence(ir, plan.minute, opts);
|
|
670
|
+
if (cadence2 !== null) {
|
|
671
|
+
return cadence2;
|
|
645
672
|
}
|
|
646
673
|
const ranged = hourSegments(ir).some(function range(segment) {
|
|
647
674
|
return segment.kind === "range";
|
|
@@ -651,7 +678,8 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
651
678
|
}
|
|
652
679
|
return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
|
|
653
680
|
}
|
|
654
|
-
const
|
|
681
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
682
|
+
const phrase = cadence ? minutesList(ir, opts) + ", " + cadence + trailingQualifier(ir, opts) : minutesList(ir, opts) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
655
683
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
|
|
656
684
|
}
|
|
657
685
|
var renderers = {
|
|
@@ -745,16 +773,46 @@ function hourStrideCadence(stride, opts) {
|
|
|
745
773
|
}
|
|
746
774
|
return cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts);
|
|
747
775
|
}
|
|
776
|
+
function offsetCleanStride(stride) {
|
|
777
|
+
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
778
|
+
}
|
|
779
|
+
function unevenHourCadence(ir, opts) {
|
|
780
|
+
const stride = hourStride(ir);
|
|
781
|
+
if (!stride || offsetCleanStride(stride)) {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
return hourStrideCadence(stride, opts);
|
|
785
|
+
}
|
|
786
|
+
function hourListStride(values) {
|
|
787
|
+
if (values.length < 2) {
|
|
788
|
+
return null;
|
|
789
|
+
}
|
|
790
|
+
const interval = values[1] - values[0];
|
|
791
|
+
if (interval < 2) {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
795
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
if (values[0] !== 0 && values.length < 5) {
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
return { interval, last: values[values.length - 1], start: values[0] };
|
|
803
|
+
}
|
|
748
804
|
function hourStride(ir) {
|
|
749
805
|
const segments = fieldSegments(ir, "hour");
|
|
750
806
|
if (segments.length === 1 && segments[0].kind === "step") {
|
|
751
807
|
const segment = segments[0];
|
|
808
|
+
if (segment.fires.length < 2) {
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
752
811
|
const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
|
|
753
812
|
return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
|
|
754
813
|
}
|
|
755
814
|
const values = singleValues(segments);
|
|
756
|
-
|
|
757
|
-
return step || null;
|
|
815
|
+
return values && hourListStride(values);
|
|
758
816
|
}
|
|
759
817
|
function subMinuteSecond(ir) {
|
|
760
818
|
return ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
@@ -778,13 +836,16 @@ function hourCadence(ir, minute, opts) {
|
|
|
778
836
|
return null;
|
|
779
837
|
}
|
|
780
838
|
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
781
|
-
if (ir.pattern.second === "0" && fires <= maxClockTimes) {
|
|
839
|
+
if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
|
|
782
840
|
return null;
|
|
783
841
|
}
|
|
784
842
|
const confinement = minute === 0 && subMinuteSecond(ir) && cleanStrideSegment(ir);
|
|
785
843
|
if (confinement) {
|
|
786
844
|
return secondsClause(ir, "minuto", opts) + " durante un minuto, " + stepHourSpan(confinement, opts) + trailingQualifier(ir, opts);
|
|
787
845
|
}
|
|
846
|
+
if (minute === 0 && ir.pattern.second === "0") {
|
|
847
|
+
return hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
848
|
+
}
|
|
788
849
|
return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
789
850
|
}
|
|
790
851
|
function cleanStrideSegment(ir) {
|
|
@@ -795,6 +856,20 @@ function cleanStrideSegment(ir) {
|
|
|
795
856
|
}
|
|
796
857
|
return segment;
|
|
797
858
|
}
|
|
859
|
+
function hasHourWindow(ir) {
|
|
860
|
+
return hourSegments(ir).some(function range(segment) {
|
|
861
|
+
return segment.kind === "range";
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
function hourRangeCadence(ir, minute, opts) {
|
|
865
|
+
if (minute !== 0 || !hasHourWindow(ir) || ir.pattern.second === "0") {
|
|
866
|
+
return null;
|
|
867
|
+
}
|
|
868
|
+
if (subMinuteSecond(ir)) {
|
|
869
|
+
return secondsClause(ir, "minuto", opts) + " durante un minuto, durante las horas " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
870
|
+
}
|
|
871
|
+
return hourCadenceLead(ir, minute, opts) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
872
|
+
}
|
|
798
873
|
function atTimes(hours, opts) {
|
|
799
874
|
return hours.map(function each(hour) {
|
|
800
875
|
return atTime(timePhrase(hour, 0, null, opts));
|
package/dist/lang/fi.cjs
CHANGED
|
@@ -289,7 +289,11 @@ function composeSecondsOverMinuteStep(ir, freq, opts) {
|
|
|
289
289
|
}
|
|
290
290
|
function composeHourCadence(ir, plan, opts) {
|
|
291
291
|
const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
|
|
292
|
-
|
|
292
|
+
if (!clockRest || ir.shapes.minute !== "single") {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
const minute = +ir.pattern.minute;
|
|
296
|
+
return hourCadence(ir, minute, opts) ?? hourRangeCadence(ir, minute, opts);
|
|
293
297
|
}
|
|
294
298
|
function renderComposeSeconds(ir, plan, opts) {
|
|
295
299
|
const cadence = composeHourCadence(ir, plan, opts);
|
|
@@ -305,7 +309,9 @@ function renderComposeSeconds(ir, plan, opts) {
|
|
|
305
309
|
if (isEveryOtherMinuteSeconds(ir, plan)) {
|
|
306
310
|
return secondsLeadClause(ir, opts) + " joka toisena minuuttina";
|
|
307
311
|
}
|
|
308
|
-
|
|
312
|
+
const restOwnsLead = plan.rest.kind === "compactClockTimes" && ir.analyses.clockSecond;
|
|
313
|
+
const lead = restOwnsLead ? "" : secondsLeadClause(ir, opts) + ", ";
|
|
314
|
+
return lead + render(ir, plan.rest, opts);
|
|
309
315
|
}
|
|
310
316
|
function isEveryOtherMinuteSeconds(ir, plan) {
|
|
311
317
|
if (plan.rest.kind !== "minuteFrequency" || ir.pattern.second !== "*" || ir.shapes.hour !== "wildcard") {
|
|
@@ -424,6 +430,10 @@ function hourSegmentTimesWithSeka(ir, minute, second, opts) {
|
|
|
424
430
|
function renderMinuteFrequency(ir, plan, opts) {
|
|
425
431
|
const seg = stepSegment(ir.analyses.segments.minute);
|
|
426
432
|
if (plan.hours.kind === "during") {
|
|
433
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
434
|
+
if (cadence !== null) {
|
|
435
|
+
return stepCycle60(seg, units.minute, opts) + ", " + cadence + trailingQualifier(ir, opts);
|
|
436
|
+
}
|
|
427
437
|
if (minuteStepIsAnchored(seg)) {
|
|
428
438
|
const bareHours = kloFromTimes(ir, plan.hours.times, opts);
|
|
429
439
|
return hoursFirstMinutes(bareHours, ir, opts) + trailingQualifier(ir, opts);
|
|
@@ -449,8 +459,12 @@ function renderMinuteSpanInHour(ir, plan, opts) {
|
|
|
449
459
|
) + trailingQualifier(ir, opts);
|
|
450
460
|
}
|
|
451
461
|
function renderMinutesAcrossHours(ir, plan, opts) {
|
|
462
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
452
463
|
if (plan.form === "wildcard") {
|
|
453
|
-
return "joka minuutti " + hourWindowsFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
464
|
+
return cadence ? "joka minuutti, " + cadence + trailingQualifier(ir, opts) : "joka minuutti " + hourWindowsFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
465
|
+
}
|
|
466
|
+
if (cadence !== null) {
|
|
467
|
+
return bareMinutes(ir, opts) + ", " + cadence + trailingQualifier(ir, opts);
|
|
454
468
|
}
|
|
455
469
|
if (hoursAreRangeIsolated(ir.analyses.segments.hour)) {
|
|
456
470
|
return bareMinutes(ir, opts) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
@@ -460,12 +474,12 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
460
474
|
}
|
|
461
475
|
function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
462
476
|
const segment = stepSegment(ir.analyses.segments.hour);
|
|
477
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
463
478
|
if (plan.form === "wildcard") {
|
|
464
479
|
return "joka minuutti " + everyNthHour(segment, opts) + trailingQualifier(ir, opts);
|
|
465
480
|
}
|
|
466
|
-
if (
|
|
467
|
-
|
|
468
|
-
return hoursFirstMinutes(hoursStr, ir, opts) + trailingQualifier(ir, opts);
|
|
481
|
+
if (cadence !== null) {
|
|
482
|
+
return bareMinutes(ir, opts) + ", " + cadence + trailingQualifier(ir, opts);
|
|
469
483
|
}
|
|
470
484
|
return bareMinutes(ir, opts) + hourStepTail(segment, opts) + trailingQualifier(ir, opts);
|
|
471
485
|
}
|
|
@@ -540,6 +554,10 @@ function renderHourRange(ir, plan, opts) {
|
|
|
540
554
|
return hoursFirstMinutes(window, ir, opts) + trailingQualifier(ir, opts);
|
|
541
555
|
}
|
|
542
556
|
function renderHourStep(ir, plan, opts) {
|
|
557
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
558
|
+
if (cadence !== null) {
|
|
559
|
+
return cadence + trailingQualifier(ir, opts);
|
|
560
|
+
}
|
|
543
561
|
return stepHours(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
544
562
|
}
|
|
545
563
|
function boundedWindow(plan) {
|
|
@@ -554,7 +572,8 @@ function hourWindow(window, opts) {
|
|
|
554
572
|
}
|
|
555
573
|
function renderClockTimes(ir, plan, opts) {
|
|
556
574
|
if (ir.shapes.minute === "single") {
|
|
557
|
-
const
|
|
575
|
+
const minute = +ir.pattern.minute;
|
|
576
|
+
const cadence = hourCadence(ir, minute, opts) ?? hourRangeCadence(ir, minute, opts);
|
|
558
577
|
if (cadence !== null) {
|
|
559
578
|
return cadence;
|
|
560
579
|
}
|
|
@@ -570,9 +589,9 @@ function renderClockTimes(ir, plan, opts) {
|
|
|
570
589
|
}
|
|
571
590
|
function renderCompactClockTimes(ir, plan, opts) {
|
|
572
591
|
if (plan.fold) {
|
|
573
|
-
const
|
|
574
|
-
if (
|
|
575
|
-
return
|
|
592
|
+
const cadence2 = hourCadence(ir, plan.minute, opts) ?? hourRangeCadence(ir, plan.minute, opts);
|
|
593
|
+
if (cadence2 !== null) {
|
|
594
|
+
return cadence2;
|
|
576
595
|
}
|
|
577
596
|
}
|
|
578
597
|
const hourSegs = ir.analyses.segments.hour;
|
|
@@ -591,8 +610,12 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
591
610
|
if (plan.fold) {
|
|
592
611
|
return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
|
|
593
612
|
}
|
|
594
|
-
const
|
|
595
|
-
const phrase =
|
|
613
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
614
|
+
const phrase = cadence ? bareMinutes(ir, opts) + ", " + cadence + trailingQualifier(ir, opts) : (
|
|
615
|
+
// A minute list over purely enumerated hours (step fires, all singles) —
|
|
616
|
+
// hours-first, drop "joka tunti".
|
|
617
|
+
hoursFirstMinutes(hourSegmentTimes(ir, 0, null, opts), ir, opts) + trailingQualifier(ir, opts)
|
|
618
|
+
);
|
|
596
619
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
|
|
597
620
|
}
|
|
598
621
|
var renderers = {
|
|
@@ -685,6 +708,27 @@ function hourStrideCadence(stride, opts) {
|
|
|
685
708
|
}
|
|
686
709
|
return cadence + " " + kloRange({ hour: start, minute: 0 }, { hour: last, minute: 0 }, opts);
|
|
687
710
|
}
|
|
711
|
+
function hourListStride(values) {
|
|
712
|
+
if (values.length < 2) {
|
|
713
|
+
return null;
|
|
714
|
+
}
|
|
715
|
+
const interval = values[1] - values[0];
|
|
716
|
+
if (interval < 2) {
|
|
717
|
+
return null;
|
|
718
|
+
}
|
|
719
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
720
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
721
|
+
return null;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
if (values[0] !== 0 && values.length < 5) {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
return { interval, last: values[values.length - 1], start: values[0] };
|
|
728
|
+
}
|
|
729
|
+
function offsetCleanStride(stride) {
|
|
730
|
+
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
731
|
+
}
|
|
688
732
|
function hourStride(ir) {
|
|
689
733
|
const segments = ir.analyses.segments.hour;
|
|
690
734
|
if (!segments) {
|
|
@@ -692,12 +736,21 @@ function hourStride(ir) {
|
|
|
692
736
|
}
|
|
693
737
|
if (segments.length === 1 && segments[0].kind === "step") {
|
|
694
738
|
const segment = segments[0];
|
|
739
|
+
if (segment.fires.length < 2) {
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
695
742
|
const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
|
|
696
743
|
return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
|
|
697
744
|
}
|
|
698
745
|
const values = singleValues(segments);
|
|
699
|
-
|
|
700
|
-
|
|
746
|
+
return values && hourListStride(values);
|
|
747
|
+
}
|
|
748
|
+
function unevenHourCadence(ir, opts) {
|
|
749
|
+
const stride = hourStride(ir);
|
|
750
|
+
if (!stride || offsetCleanStride(stride)) {
|
|
751
|
+
return null;
|
|
752
|
+
}
|
|
753
|
+
return hourStrideCadence(stride, opts);
|
|
701
754
|
}
|
|
702
755
|
function subMinuteSecond(ir) {
|
|
703
756
|
return ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
@@ -721,7 +774,7 @@ function hourCadence(ir, minute, opts) {
|
|
|
721
774
|
return null;
|
|
722
775
|
}
|
|
723
776
|
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
724
|
-
if (ir.pattern.second === "0" && fires <= maxClockTimes) {
|
|
777
|
+
if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
|
|
725
778
|
return null;
|
|
726
779
|
}
|
|
727
780
|
const segment = ir.analyses.segments.hour[0];
|
|
@@ -729,6 +782,9 @@ function hourCadence(ir, minute, opts) {
|
|
|
729
782
|
if (confined) {
|
|
730
783
|
return secondsLeadClause(ir, opts) + " minuutin ajan " + everyNthHour(segment, opts) + trailingQualifier(ir, opts);
|
|
731
784
|
}
|
|
785
|
+
if (minute === 0 && ir.pattern.second === "0") {
|
|
786
|
+
return hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
787
|
+
}
|
|
732
788
|
return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
733
789
|
}
|
|
734
790
|
function cleanHourStride(segment) {
|
|
@@ -738,6 +794,23 @@ function cleanHourStride(segment) {
|
|
|
738
794
|
const start = segment.startToken === "*" ? 0 : +segment.startToken;
|
|
739
795
|
return 24 % segment.interval === 0 && start < segment.interval;
|
|
740
796
|
}
|
|
797
|
+
function hasHourWindow(ir) {
|
|
798
|
+
const segments = ir.analyses.segments.hour;
|
|
799
|
+
return !!segments && segments.some(function range(segment) {
|
|
800
|
+
return segment.kind === "range";
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
function hourRangeWindowTail(ir, opts) {
|
|
804
|
+
return ir.analyses.segments.hour.length === 1 ? hourSegmentTimes(ir, 0, null, opts) : hourSegmentTimesWithSeka(ir, 0, null, opts);
|
|
805
|
+
}
|
|
806
|
+
function hourRangeCadence(ir, minute, opts) {
|
|
807
|
+
if (minute !== 0 || !hasHourWindow(ir) || ir.pattern.second === "0") {
|
|
808
|
+
return null;
|
|
809
|
+
}
|
|
810
|
+
const tail = hourRangeWindowTail(ir, opts);
|
|
811
|
+
const joiner = subMinuteSecond(ir) ? " " : ", ";
|
|
812
|
+
return hourCadenceLead(ir, minute, opts) + joiner + tail + trailingQualifier(ir, opts);
|
|
813
|
+
}
|
|
741
814
|
function kloList(hours, opts) {
|
|
742
815
|
if (hours.length === 1) {
|
|
743
816
|
return timeWord(hours[0], 0, null, opts);
|
|
@@ -754,12 +827,16 @@ function kloFromTimes(ir, times, opts) {
|
|
|
754
827
|
}
|
|
755
828
|
function hourWindowsFromTimes(ir, times, opts) {
|
|
756
829
|
if (times.kind === "fires") {
|
|
757
|
-
return
|
|
758
|
-
|
|
759
|
-
|
|
830
|
+
return kloList(times.fires, opts);
|
|
831
|
+
}
|
|
832
|
+
const segments = ir.analyses.segments.hour;
|
|
833
|
+
if (!segments.some(function ranged(segment) {
|
|
834
|
+
return segment.kind === "range";
|
|
835
|
+
})) {
|
|
836
|
+
return kloList(hourSegmentFires(segments), opts);
|
|
760
837
|
}
|
|
761
838
|
const pieces = [];
|
|
762
|
-
|
|
839
|
+
segments.forEach(function window(segment) {
|
|
763
840
|
if (segment.kind === "range") {
|
|
764
841
|
pieces.push(rangeDigits(
|
|
765
842
|
{ hour: +segment.bounds[0], minute: 0 },
|
|
@@ -776,6 +853,17 @@ function hourWindowsFromTimes(ir, times, opts) {
|
|
|
776
853
|
});
|
|
777
854
|
return "klo " + joinList(pieces);
|
|
778
855
|
}
|
|
856
|
+
function hourSegmentFires(segments) {
|
|
857
|
+
const hours = [];
|
|
858
|
+
segments.forEach(function each(segment) {
|
|
859
|
+
if (segment.kind === "step") {
|
|
860
|
+
hours.push(...segment.fires);
|
|
861
|
+
} else if (segment.kind === "single") {
|
|
862
|
+
hours.push(+segment.value);
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
return hours;
|
|
866
|
+
}
|
|
779
867
|
function hourWindowDigits(hour, opts) {
|
|
780
868
|
return rangeDigits({ hour, minute: 0 }, { hour, minute: 59 }, opts);
|
|
781
869
|
}
|