cronli5 0.1.4 → 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/dist/lang/de.cjs CHANGED
@@ -40,12 +40,28 @@ var weekdayNumbers = {
40
40
  FRI: 5,
41
41
  SAT: 6
42
42
  };
43
+ var maxClockTimes = 6;
43
44
 
44
45
  // src/core/util.ts
45
46
  function isNonNegativeInteger(value) {
46
47
  const digits = /^\d+$/;
47
48
  return digits.test(value);
48
49
  }
50
+ function arithmeticStep(values) {
51
+ if (values.length < 5) {
52
+ return null;
53
+ }
54
+ const interval = values[1] - values[0];
55
+ if (interval < 2) {
56
+ return null;
57
+ }
58
+ for (let i = 2; i < values.length; i += 1) {
59
+ if (values[i] - values[i - 1] !== interval) {
60
+ return null;
61
+ }
62
+ }
63
+ return { start: values[0], interval, last: values[values.length - 1] };
64
+ }
49
65
  function toFieldNumber(token, numberMap) {
50
66
  return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
51
67
  }
@@ -112,6 +128,49 @@ function stepSegment(segments) {
112
128
  function cleanStep(segment, cycle) {
113
129
  return (segment.startToken === "*" || +segment.startToken === 0) && cycle % segment.interval === 0;
114
130
  }
131
+ function renderStride(stride) {
132
+ const { interval, start, last, cycle, unit, anchor } = stride;
133
+ const cadence = everyN(interval, unit);
134
+ const tiles = cycle % interval === 0;
135
+ if (start === 0 && tiles) {
136
+ return cadence;
137
+ }
138
+ const tail = anchor ? " " + anchor : "";
139
+ if (start < interval && tiles) {
140
+ return cadence + " ab " + unit.singular + " " + start + tail;
141
+ }
142
+ return cadence + " von " + unit.singular + " " + start + " bis " + last + tail;
143
+ }
144
+ function stepClause(segment, unit, anchor) {
145
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
146
+ const short = start !== 0 && segment.fires.length <= 3;
147
+ if (segment.startToken.indexOf("-") !== -1 || short) {
148
+ return "in den " + unit.plural + " " + joinList(segment.fires.map(String)) + " " + anchor;
149
+ }
150
+ return renderStride({
151
+ interval: segment.interval,
152
+ start,
153
+ last: segment.fires[segment.fires.length - 1],
154
+ cycle: 60,
155
+ unit,
156
+ anchor
157
+ });
158
+ }
159
+ function singleValues(segments) {
160
+ const values = [];
161
+ for (const segment of segments) {
162
+ if (segment.kind !== "single") {
163
+ return null;
164
+ }
165
+ values.push(+segment.value);
166
+ }
167
+ return values;
168
+ }
169
+ function strideFromSegments(segments, unit, anchor) {
170
+ const values = singleValues(segments);
171
+ const step = values && arithmeticStep(values);
172
+ return step ? renderStride({ ...step, cycle: 60, unit, anchor }) : null;
173
+ }
115
174
  var weekdayNames = [
116
175
  "sonntags",
117
176
  "montags",
@@ -178,6 +237,13 @@ function everyNthHour(segment) {
178
237
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
179
238
  return start === 0 ? base : base + " ab " + start + " Uhr";
180
239
  }
240
+ function confinedHourStride(segment) {
241
+ if (segment.startToken.indexOf("-") !== -1) {
242
+ return false;
243
+ }
244
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
245
+ return 24 % segment.interval === 0 && start < segment.interval;
246
+ }
181
247
  function weekdayNoun(token) {
182
248
  return weekdayNouns[toFieldNumber(token, weekdayNumbers)];
183
249
  }
@@ -281,14 +347,17 @@ function countedPhrase(ir, field, singular, plural) {
281
347
  return "in den " + plural + " " + joinList(fieldValues(ir, field));
282
348
  }
283
349
  function secondsLead(ir) {
350
+ return secondsClause(ir, "jeder Minute");
351
+ }
352
+ function secondsClause(ir, anchor) {
284
353
  if (ir.pattern.second === "*") {
285
354
  return "jede Sekunde";
286
355
  }
287
356
  const segments = ir.analyses.segments.second;
288
- if (ir.shapes.second === "step" && cleanStep(stepSegment(segments), 60)) {
289
- return everyN(stepSegment(segments).interval, UNITS.second);
357
+ if (ir.shapes.second === "step") {
358
+ return stepClause(stepSegment(segments), UNITS.second, anchor);
290
359
  }
291
- return countedPhrase(ir, "second", "Sekunde", "Sekunden") + " jeder Minute";
360
+ return strideFromSegments(segments, UNITS.second, anchor) ?? countedPhrase(ir, "second", "Sekunde", "Sekunden") + " " + anchor;
292
361
  }
293
362
  function spanTime(hour, minute, sep) {
294
363
  return hour + sep + pad(minute);
@@ -357,8 +426,15 @@ function renderEveryHour() {
357
426
  function renderSeconds(ir) {
358
427
  return secondsLead(ir);
359
428
  }
429
+ function minutePastClause(ir) {
430
+ return strideFromSegments(
431
+ fieldSegments(ir, "minute"),
432
+ UNITS.minute,
433
+ "jeder Stunde"
434
+ ) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
435
+ }
360
436
  function renderMinutePast(ir) {
361
- return countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
437
+ return minutePastClause(ir);
362
438
  }
363
439
  function renderSecondsWithinMinute(ir, plan) {
364
440
  if (plan.singleSecond) {
@@ -382,11 +458,30 @@ function renderMinuteSpanInHour(ir, plan, opts) {
382
458
  const sep = opts.style.sep;
383
459
  return "jede Minute von " + spanTime(plan.hour, plan.span[0], sep) + " bis " + spanTime(plan.hour, plan.span[1], sep) + " Uhr";
384
460
  }
461
+ function isEveryOtherMinuteSeconds(ir, plan) {
462
+ if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
463
+ return false;
464
+ }
465
+ const minuteStep = stepSegment(ir.analyses.segments.minute);
466
+ return minuteStep.startToken === "*" && minuteStep.interval === 2;
467
+ }
385
468
  function renderComposeSeconds(ir, plan, opts) {
469
+ if ((plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes") && ir.shapes.minute === "single") {
470
+ const minute = +ir.pattern.minute;
471
+ const cadence = hourCadence(ir, minute) ?? hourRangeCadence(ir, minute);
472
+ if (cadence !== null) {
473
+ return cadence;
474
+ }
475
+ }
386
476
  if (composeMinuteZero(ir, plan)) {
387
477
  return secondsLead(ir) + " " + clockMinuteGenitive(plan.rest.times, opts.style.sep);
388
478
  }
389
- return secondsLead(ir) + ", " + render(ir, plan.rest, opts);
479
+ if (isEveryOtherMinuteSeconds(ir, plan)) {
480
+ return secondsLead(ir) + " jeder zweiten Minute";
481
+ }
482
+ const restOwnsLead = plan.rest.kind === "compactClockTimes" && ir.analyses.clockSecond;
483
+ const lead = restOwnsLead ? "" : secondsLead(ir) + ", ";
484
+ return lead + render(ir, plan.rest, opts);
390
485
  }
391
486
  function composeMinuteZero(ir, plan) {
392
487
  return plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0);
@@ -399,33 +494,45 @@ function clockMinuteGenitive(times, sep) {
399
494
  }
400
495
  function renderMinutesAcrossHours(ir, plan, opts) {
401
496
  const sep = opts.style.sep;
497
+ const cadence = unevenHourCadence(ir);
402
498
  if (plan.form === "wildcard") {
403
- return "jede Minute " + duringHours(ir, plan.times, sep);
499
+ return cadence ? "jede Minute, " + cadence : "jede Minute " + duringHours(ir, plan.times, sep);
500
+ }
501
+ const minuteLead = strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten");
502
+ if (cadence !== null) {
503
+ return minuteLead + ", " + cadence;
404
504
  }
405
505
  const hours = plan.times.kind === "fires" ? atHours(plan.times.fires) : joinList(hourSegmentParts(ir, 0, 0, sep));
406
- return countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hours;
506
+ return minuteLead + ", " + hours;
407
507
  }
408
508
  function renderMinuteSpanAcrossHourStep(ir, plan) {
509
+ const cadence = unevenHourCadence(ir);
409
510
  if (plan.form === "wildcard") {
410
511
  return "jede Minute " + everyNthHour(stepSegment(ir.analyses.segments.hour));
411
512
  }
412
- return countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hourStepPhrase(ir);
513
+ const segment = stepSegment(ir.analyses.segments.hour);
514
+ const hours = cadence ?? (confinedHourStride(segment) ? everyNthHour(segment) : atHours(segment.fires));
515
+ return (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
413
516
  }
414
517
  function renderCompactClockTimes(ir, plan, opts) {
415
518
  const sep = opts.style.sep;
416
519
  if (plan.fold) {
520
+ const cadence = hourCadence(ir, plan.minute) ?? hourRangeCadence(ir, plan.minute);
521
+ if (cadence !== null) {
522
+ return cadence;
523
+ }
417
524
  const hourly = fieldSegments(ir, "hour").some((segment) => segment.kind === "range");
418
525
  return (hourly ? "st\xFCndlich " : "t\xE4glich ") + joinList(hourSegmentParts(ir, plan.minute, ir.analyses.clockSecond, sep));
419
526
  }
420
- const hours = fieldSegments(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir));
527
+ const hours = unevenHourCadence(ir) ?? (fieldSegments(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir)));
421
528
  const lead = ir.analyses.clockSecond ? countedPhrase(ir, "second", "Sekunde", "Sekunden") + ", " : "";
422
- return lead + countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hours;
529
+ return lead + (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
423
530
  }
424
531
  function renderMinuteFrequency(ir, plan, opts) {
425
532
  const segment = stepSegment(ir.analyses.segments.minute);
426
533
  const sep = opts.style.sep;
427
534
  const clean = cleanStep(segment, 60);
428
- const base = clean ? everyN(segment.interval, UNITS.minute) : countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
535
+ const base = stepClause(segment, UNITS.minute, "jeder Stunde");
429
536
  if (plan.hours.kind === "window") {
430
537
  const window = hourWindow(
431
538
  plan.hours.from,
@@ -436,7 +543,8 @@ function renderMinuteFrequency(ir, plan, opts) {
436
543
  return clean ? base + " " + window : base + ", " + window;
437
544
  }
438
545
  if (plan.hours.kind === "during") {
439
- return base + " " + duringHours(ir, plan.hours.times, sep);
546
+ const cadence = unevenHourCadence(ir);
547
+ return cadence ? base + ", " + cadence : base + " " + duringHours(ir, plan.hours.times, sep);
440
548
  }
441
549
  if (plan.hours.kind === "step") {
442
550
  return base + " " + everyNthHour(stepSegment(ir.analyses.segments.hour));
@@ -444,9 +552,126 @@ function renderMinuteFrequency(ir, plan, opts) {
444
552
  return base;
445
553
  }
446
554
  function hourStepPhrase(ir) {
555
+ const cadence = unevenHourCadence(ir);
556
+ if (cadence !== null) {
557
+ return cadence;
558
+ }
447
559
  const segment = stepSegment(ir.analyses.segments.hour);
448
560
  return cleanStep(segment, 24) ? everyN(segment.interval, UNITS.hour) : atHours(segment.fires);
449
561
  }
562
+ function hourStrideCadence(stride) {
563
+ const { start, interval, last } = stride;
564
+ const cadence = everyN(interval, UNITS.hour);
565
+ const tiles = 24 % interval === 0;
566
+ if (start === 0 && tiles) {
567
+ return cadence;
568
+ }
569
+ if (start < interval && tiles) {
570
+ return cadence + " ab " + start + " Uhr";
571
+ }
572
+ return cadence + " von " + start + " bis " + last + " Uhr";
573
+ }
574
+ function hourListStride(values) {
575
+ if (values.length < 2) {
576
+ return null;
577
+ }
578
+ const interval = values[1] - values[0];
579
+ if (interval < 2) {
580
+ return null;
581
+ }
582
+ for (let i = 2; i < values.length; i += 1) {
583
+ if (values[i] - values[i - 1] !== interval) {
584
+ return null;
585
+ }
586
+ }
587
+ if (values[0] !== 0 && values.length < 5) {
588
+ return null;
589
+ }
590
+ return { interval, last: values[values.length - 1], start: values[0] };
591
+ }
592
+ function offsetCleanStride(stride) {
593
+ return stride.start < stride.interval && 24 % stride.interval === 0;
594
+ }
595
+ function hourStride(ir) {
596
+ const segments = fieldSegments(ir, "hour");
597
+ if (!segments) {
598
+ return null;
599
+ }
600
+ if (segments.length === 1 && segments[0].kind === "step") {
601
+ const segment = segments[0];
602
+ if (segment.fires.length < 2) {
603
+ return null;
604
+ }
605
+ const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
606
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
607
+ }
608
+ const values = singleValues(segments);
609
+ return values && hourListStride(values);
610
+ }
611
+ function unevenHourCadence(ir) {
612
+ const stride = hourStride(ir);
613
+ if (!stride || offsetCleanStride(stride)) {
614
+ return null;
615
+ }
616
+ return hourStrideCadence(stride);
617
+ }
618
+ function subMinuteSecond(ir) {
619
+ return ir.pattern.second === "*" || ir.shapes.second === "step";
620
+ }
621
+ function hourCadenceLead(ir, minute) {
622
+ if (minute === 0) {
623
+ if (subMinuteSecond(ir)) {
624
+ return secondsClause(ir, "jeder Minute") + " f\xFCr eine Minute";
625
+ }
626
+ return secondsClause(ir, "jeder Stunde");
627
+ }
628
+ const minutePhrase = "in Minute " + minute;
629
+ if (ir.pattern.second === "0") {
630
+ return minutePhrase;
631
+ }
632
+ return secondsClause(ir, "jeder Minute") + ", " + minutePhrase;
633
+ }
634
+ function hourCadence(ir, minute) {
635
+ const stride = hourStride(ir);
636
+ if (!stride) {
637
+ return null;
638
+ }
639
+ const fires = (stride.last - stride.start) / stride.interval + 1;
640
+ if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
641
+ return null;
642
+ }
643
+ const segment = fieldSegments(ir, "hour")[0];
644
+ const confined = minute === 0 && subMinuteSecond(ir) && fieldSegments(ir, "hour").length === 1 && segment.kind === "step" && confinedHourStride(segment);
645
+ if (confined) {
646
+ return secondsClause(ir, "jeder Minute") + " f\xFCr eine Minute " + everyNthHour(segment);
647
+ }
648
+ if (minute === 0 && ir.pattern.second === "0") {
649
+ return hourStrideCadence(stride);
650
+ }
651
+ return hourCadenceLead(ir, minute) + ", " + hourStrideCadence(stride);
652
+ }
653
+ function hourCadenceApplies(ir) {
654
+ if (ir.shapes.minute !== "single") {
655
+ return false;
656
+ }
657
+ const minute = +ir.pattern.minute;
658
+ return hourCadence(ir, minute) !== null || hourRangeCadence(ir, minute) !== null;
659
+ }
660
+ function hasHourWindow(ir) {
661
+ const segments = fieldSegments(ir, "hour");
662
+ return !!segments && segments.some(function range(segment) {
663
+ return segment.kind === "range";
664
+ });
665
+ }
666
+ function hourRangeCadence(ir, minute) {
667
+ if (minute !== 0 || !hasHourWindow(ir) || ir.pattern.second === "0") {
668
+ return null;
669
+ }
670
+ return hourCadenceLead(ir, minute) + ", " + hourRangeWindowTail(ir);
671
+ }
672
+ function hourRangeWindowTail(ir) {
673
+ return joinList(hourSegmentParts(ir, 0, 0, ":"));
674
+ }
450
675
  function renderHourRange(ir, plan, opts) {
451
676
  const window = hourWindow(
452
677
  plan.from,
@@ -460,9 +685,20 @@ function renderHourRange(ir, plan, opts) {
460
685
  if (plan.minuteForm === "lead" && ir.pattern.minute === "0") {
461
686
  return "st\xFCndlich " + window;
462
687
  }
463
- return countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde, " + window;
688
+ return (strideFromSegments(
689
+ fieldSegments(ir, "minute"),
690
+ UNITS.minute,
691
+ "jeder Stunde"
692
+ ) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde") + ", " + window;
464
693
  }
465
694
  function renderClockTimes(ir, plan, opts) {
695
+ if (ir.shapes.minute === "single") {
696
+ const minute = +ir.pattern.minute;
697
+ const cadence = hourCadence(ir, minute) ?? hourRangeCadence(ir, minute);
698
+ if (cadence !== null) {
699
+ return cadence;
700
+ }
701
+ }
466
702
  return "um " + timesPhrase(plan.times, opts.style.sep);
467
703
  }
468
704
  var renderers = {
@@ -512,6 +748,9 @@ function isComposeMinuteZero(ir) {
512
748
  return ir.plan.kind === "composeSeconds" && composeMinuteZero(ir, ir.plan);
513
749
  }
514
750
  function needsDailyFrame(ir) {
751
+ if (hourCadenceApplies(ir)) {
752
+ return false;
753
+ }
515
754
  if (ir.plan.kind === "clockTimes" || isComposeMinuteZero(ir)) {
516
755
  return true;
517
756
  }