cronli5 0.1.2 → 0.1.5

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
@@ -30,6 +30,42 @@ function pad(n) {
30
30
  return n.length < 2 ? "0" + n : n;
31
31
  }
32
32
 
33
+ // src/core/specs.ts
34
+ var weekdayNumbers = {
35
+ SUN: 0,
36
+ MON: 1,
37
+ TUE: 2,
38
+ WED: 3,
39
+ THU: 4,
40
+ FRI: 5,
41
+ SAT: 6
42
+ };
43
+ var maxClockTimes = 6;
44
+
45
+ // src/core/util.ts
46
+ function isNonNegativeInteger(value) {
47
+ const digits = /^\d+$/;
48
+ return digits.test(value);
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
+ }
65
+ function toFieldNumber(token, numberMap) {
66
+ return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
67
+ }
68
+
33
69
  // src/lang/de/dialects.ts
34
70
  var months = [
35
71
  null,
@@ -92,6 +128,49 @@ function stepSegment(segments) {
92
128
  function cleanStep(segment, cycle) {
93
129
  return (segment.startToken === "*" || +segment.startToken === 0) && cycle % segment.interval === 0;
94
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
+ }
95
174
  var weekdayNames = [
96
175
  "sonntags",
97
176
  "montags",
@@ -101,15 +180,6 @@ var weekdayNames = [
101
180
  "freitags",
102
181
  "samstags"
103
182
  ];
104
- var weekdayTokens = {
105
- SUN: 0,
106
- MON: 1,
107
- TUE: 2,
108
- WED: 3,
109
- THU: 4,
110
- FRI: 5,
111
- SAT: 6
112
- };
113
183
  function fieldSegments(ir, field) {
114
184
  return ir.analyses.segments[field];
115
185
  }
@@ -130,10 +200,7 @@ function joinList(items) {
130
200
  return items.slice(0, -1).join(", ") + " und " + items[items.length - 1];
131
201
  }
132
202
  function weekdayName(token) {
133
- if (token === "7" || token === 7) {
134
- return weekdayNames[0];
135
- }
136
- return weekdayNames[token] || weekdayNames[weekdayTokens[token]];
203
+ return weekdayNames[+token];
137
204
  }
138
205
  function weekdayRange(bounds) {
139
206
  return weekdayName(bounds[0]) + " bis " + weekdayName(bounds[1]);
@@ -170,11 +237,15 @@ function everyNthHour(segment) {
170
237
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
171
238
  return start === 0 ? base : base + " ab " + start + " Uhr";
172
239
  }
173
- function weekdayNoun(token) {
174
- if (token === "7") {
175
- return weekdayNouns[0];
240
+ function confinedHourStride(segment) {
241
+ if (segment.startToken.indexOf("-") !== -1) {
242
+ return false;
176
243
  }
177
- return weekdayNouns[token in weekdayTokens ? weekdayTokens[token] : +token];
244
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
245
+ return 24 % segment.interval === 0 && start < segment.interval;
246
+ }
247
+ function weekdayNoun(token) {
248
+ return weekdayNouns[toFieldNumber(token, weekdayNumbers)];
178
249
  }
179
250
  function quartzWeekday(field) {
180
251
  if (field.indexOf("#") !== -1) {
@@ -198,22 +269,8 @@ function quartzDate(field) {
198
269
  }
199
270
  return null;
200
271
  }
201
- var monthTokens = {
202
- JAN: 1,
203
- FEB: 2,
204
- MAR: 3,
205
- APR: 4,
206
- MAY: 5,
207
- JUN: 6,
208
- JUL: 7,
209
- AUG: 8,
210
- SEP: 9,
211
- OCT: 10,
212
- NOV: 11,
213
- DEC: 12
214
- };
215
272
  function monthName(token, months2) {
216
- return months2[token] || months2[monthTokens[token]];
273
+ return months2[+token];
217
274
  }
218
275
  function monthRange(bounds, months2) {
219
276
  return "von " + monthName(bounds[0], months2) + " bis " + monthName(bounds[1], months2);
@@ -290,14 +347,17 @@ function countedPhrase(ir, field, singular, plural) {
290
347
  return "in den " + plural + " " + joinList(fieldValues(ir, field));
291
348
  }
292
349
  function secondsLead(ir) {
350
+ return secondsClause(ir, "jeder Minute");
351
+ }
352
+ function secondsClause(ir, anchor) {
293
353
  if (ir.pattern.second === "*") {
294
354
  return "jede Sekunde";
295
355
  }
296
356
  const segments = ir.analyses.segments.second;
297
- if (ir.shapes.second === "step" && cleanStep(stepSegment(segments), 60)) {
298
- return everyN(stepSegment(segments).interval, UNITS.second);
357
+ if (ir.shapes.second === "step") {
358
+ return stepClause(stepSegment(segments), UNITS.second, anchor);
299
359
  }
300
- return countedPhrase(ir, "second", "Sekunde", "Sekunden") + " jeder Minute";
360
+ return strideFromSegments(segments, UNITS.second, anchor) ?? countedPhrase(ir, "second", "Sekunde", "Sekunden") + " " + anchor;
301
361
  }
302
362
  function spanTime(hour, minute, sep) {
303
363
  return hour + sep + pad(minute);
@@ -366,8 +426,15 @@ function renderEveryHour() {
366
426
  function renderSeconds(ir) {
367
427
  return secondsLead(ir);
368
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
+ }
369
436
  function renderMinutePast(ir) {
370
- return countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
437
+ return minutePastClause(ir);
371
438
  }
372
439
  function renderSecondsWithinMinute(ir, plan) {
373
440
  if (plan.singleSecond) {
@@ -375,42 +442,84 @@ function renderSecondsWithinMinute(ir, plan) {
375
442
  }
376
443
  return secondsLead(ir) + ", in Minute " + ir.pattern.minute + " jeder Stunde";
377
444
  }
445
+ function wholeHour(hour) {
446
+ if (hour === 0) {
447
+ return "der Mitternachtsstunde";
448
+ }
449
+ if (hour === 12) {
450
+ return "der Mittagsstunde";
451
+ }
452
+ return "der " + hour + "-Uhr-Stunde";
453
+ }
378
454
  function renderMinuteSpanInHour(ir, plan, opts) {
455
+ if (ir.pattern.minute === "*") {
456
+ return "jede Minute " + wholeHour(plan.hour);
457
+ }
379
458
  const sep = opts.style.sep;
380
459
  return "jede Minute von " + spanTime(plan.hour, plan.span[0], sep) + " bis " + spanTime(plan.hour, plan.span[1], sep) + " Uhr";
381
460
  }
382
461
  function renderComposeSeconds(ir, plan, opts) {
462
+ if ((plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes") && ir.shapes.minute === "single") {
463
+ const cadence = hourCadence(ir, +ir.pattern.minute);
464
+ if (cadence !== null) {
465
+ return cadence;
466
+ }
467
+ }
468
+ if (composeMinuteZero(ir, plan)) {
469
+ return secondsLead(ir) + " " + clockMinuteGenitive(plan.rest.times, opts.style.sep);
470
+ }
471
+ if (plan.rest.kind === "minuteFrequency" && ir.shapes.second === "wildcard" && ir.shapes.hour === "wildcard") {
472
+ const minuteStep = stepSegment(ir.analyses.segments.minute);
473
+ if (minuteStep.startToken === "*" && minuteStep.interval === 2) {
474
+ return secondsLead(ir) + " jeder zweiten Minute";
475
+ }
476
+ }
383
477
  return secondsLead(ir) + ", " + render(ir, plan.rest, opts);
384
478
  }
479
+ function composeMinuteZero(ir, plan) {
480
+ return plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0);
481
+ }
482
+ function clockMinuteGenitive(times, sep) {
483
+ const clocks = times.map(function clock(time) {
484
+ return time.hour + sep + pad(time.minute);
485
+ });
486
+ return clocks.length === 1 ? "der Minute " + clocks[0] : "der Minuten " + joinList(clocks);
487
+ }
385
488
  function renderMinutesAcrossHours(ir, plan, opts) {
386
489
  const sep = opts.style.sep;
387
490
  if (plan.form === "wildcard") {
388
491
  return "jede Minute " + duringHours(ir, plan.times, sep);
389
492
  }
390
493
  const hours = plan.times.kind === "fires" ? atHours(plan.times.fires) : joinList(hourSegmentParts(ir, 0, 0, sep));
391
- return countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hours;
494
+ return (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
392
495
  }
393
496
  function renderMinuteSpanAcrossHourStep(ir, plan) {
394
497
  if (plan.form === "wildcard") {
395
498
  return "jede Minute " + everyNthHour(stepSegment(ir.analyses.segments.hour));
396
499
  }
397
- return countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hourStepPhrase(ir);
500
+ const segment = stepSegment(ir.analyses.segments.hour);
501
+ const hours = confinedHourStride(segment) ? everyNthHour(segment) : atHours(segment.fires);
502
+ return (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
398
503
  }
399
504
  function renderCompactClockTimes(ir, plan, opts) {
400
505
  const sep = opts.style.sep;
401
506
  if (plan.fold) {
507
+ const cadence = hourCadence(ir, plan.minute);
508
+ if (cadence !== null) {
509
+ return cadence;
510
+ }
402
511
  const hourly = fieldSegments(ir, "hour").some((segment) => segment.kind === "range");
403
512
  return (hourly ? "st\xFCndlich " : "t\xE4glich ") + joinList(hourSegmentParts(ir, plan.minute, ir.analyses.clockSecond, sep));
404
513
  }
405
514
  const hours = fieldSegments(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir));
406
515
  const lead = ir.analyses.clockSecond ? countedPhrase(ir, "second", "Sekunde", "Sekunden") + ", " : "";
407
- return lead + countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hours;
516
+ return lead + (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
408
517
  }
409
518
  function renderMinuteFrequency(ir, plan, opts) {
410
519
  const segment = stepSegment(ir.analyses.segments.minute);
411
520
  const sep = opts.style.sep;
412
521
  const clean = cleanStep(segment, 60);
413
- const base = clean ? everyN(segment.interval, UNITS.minute) : countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
522
+ const base = stepClause(segment, UNITS.minute, "jeder Stunde");
414
523
  if (plan.hours.kind === "window") {
415
524
  const window = hourWindow(
416
525
  plan.hours.from,
@@ -432,6 +541,67 @@ function hourStepPhrase(ir) {
432
541
  const segment = stepSegment(ir.analyses.segments.hour);
433
542
  return cleanStep(segment, 24) ? everyN(segment.interval, UNITS.hour) : atHours(segment.fires);
434
543
  }
544
+ function hourStrideCadence(stride) {
545
+ const { start, interval, last } = stride;
546
+ const cadence = everyN(interval, UNITS.hour);
547
+ const tiles = 24 % interval === 0;
548
+ if (start === 0 && tiles) {
549
+ return cadence;
550
+ }
551
+ if (start < interval && tiles) {
552
+ return cadence + " ab " + start + " Uhr";
553
+ }
554
+ return cadence + " von " + start + " bis " + last + " Uhr";
555
+ }
556
+ function hourStride(ir) {
557
+ const segments = fieldSegments(ir, "hour");
558
+ if (!segments) {
559
+ return null;
560
+ }
561
+ if (segments.length === 1 && segments[0].kind === "step") {
562
+ const segment = segments[0];
563
+ const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
564
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
565
+ }
566
+ const values = singleValues(segments);
567
+ const step = values && arithmeticStep(values);
568
+ return step || null;
569
+ }
570
+ function subMinuteSecond(ir) {
571
+ return ir.pattern.second === "*" || ir.shapes.second === "step";
572
+ }
573
+ function hourCadenceLead(ir, minute) {
574
+ if (minute === 0) {
575
+ if (subMinuteSecond(ir)) {
576
+ return secondsClause(ir, "jeder Minute") + " f\xFCr eine Minute";
577
+ }
578
+ return secondsClause(ir, "jeder Stunde");
579
+ }
580
+ const minutePhrase = "in Minute " + minute;
581
+ if (ir.pattern.second === "0") {
582
+ return minutePhrase;
583
+ }
584
+ return secondsClause(ir, "jeder Minute") + ", " + minutePhrase;
585
+ }
586
+ function hourCadence(ir, minute) {
587
+ const stride = hourStride(ir);
588
+ if (!stride) {
589
+ return null;
590
+ }
591
+ const fires = (stride.last - stride.start) / stride.interval + 1;
592
+ if (ir.pattern.second === "0" && fires <= maxClockTimes) {
593
+ return null;
594
+ }
595
+ const segment = fieldSegments(ir, "hour")[0];
596
+ const confined = minute === 0 && subMinuteSecond(ir) && fieldSegments(ir, "hour").length === 1 && segment.kind === "step" && confinedHourStride(segment);
597
+ if (confined) {
598
+ return secondsClause(ir, "jeder Minute") + " f\xFCr eine Minute " + everyNthHour(segment);
599
+ }
600
+ return hourCadenceLead(ir, minute) + ", " + hourStrideCadence(stride);
601
+ }
602
+ function hourCadenceApplies(ir) {
603
+ return ir.shapes.minute === "single" && hourCadence(ir, +ir.pattern.minute) !== null;
604
+ }
435
605
  function renderHourRange(ir, plan, opts) {
436
606
  const window = hourWindow(
437
607
  plan.from,
@@ -448,6 +618,12 @@ function renderHourRange(ir, plan, opts) {
448
618
  return countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde, " + window;
449
619
  }
450
620
  function renderClockTimes(ir, plan, opts) {
621
+ if (ir.shapes.minute === "single") {
622
+ const cadence = hourCadence(ir, +ir.pattern.minute);
623
+ if (cadence !== null) {
624
+ return cadence;
625
+ }
626
+ }
451
627
  return "um " + timesPhrase(plan.times, opts.style.sep);
452
628
  }
453
629
  var renderers = {
@@ -490,8 +666,17 @@ function qualifier(ir, months2) {
490
666
  return "";
491
667
  }
492
668
  var LEADING_PLANS = /* @__PURE__ */ new Set(["clockTimes"]);
669
+ function leadsQualifier(ir) {
670
+ return LEADING_PLANS.has(ir.plan.kind) || isComposeMinuteZero(ir);
671
+ }
672
+ function isComposeMinuteZero(ir) {
673
+ return ir.plan.kind === "composeSeconds" && composeMinuteZero(ir, ir.plan);
674
+ }
493
675
  function needsDailyFrame(ir) {
494
- if (ir.plan.kind === "clockTimes") {
676
+ if (hourCadenceApplies(ir)) {
677
+ return false;
678
+ }
679
+ if (ir.plan.kind === "clockTimes" || isComposeMinuteZero(ir)) {
495
680
  return true;
496
681
  }
497
682
  return ir.plan.kind === "hourStep" && !cleanStep(stepSegment(ir.analyses.segments.hour), 24);
@@ -534,7 +719,7 @@ function describe(ir, opts) {
534
719
  const qual = qualifier(ir, opts.style.months);
535
720
  let base = core;
536
721
  if (qual) {
537
- base = LEADING_PLANS.has(ir.plan.kind) ? qual + " " + core : core + " " + qual;
722
+ base = leadsQualifier(ir) ? qual + " " + core : core + " " + qual;
538
723
  } else if (needsDailyFrame(ir)) {
539
724
  base = "t\xE4glich " + core;
540
725
  }