cronli5 0.8.2 → 0.8.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.js CHANGED
@@ -277,6 +277,20 @@ var stepOrdinals = {
277
277
  8: "achten",
278
278
  12: "zw\xF6lften"
279
279
  };
280
+ var minuteStepOrdinals = {
281
+ 3: "dritten",
282
+ 4: "vierten",
283
+ 5: "f\xFCnften",
284
+ 6: "sechsten",
285
+ 7: "siebten",
286
+ 8: "achten",
287
+ 9: "neunten",
288
+ 10: "zehnten",
289
+ 12: "zw\xF6lften",
290
+ 15: "f\xFCnfzehnten",
291
+ 20: "zwanzigsten",
292
+ 30: "drei\xDFigsten"
293
+ };
280
294
  function everyNthHour(segment) {
281
295
  const base = "in jeder " + stepOrdinals[segment.interval] + " Stunde";
282
296
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
@@ -504,7 +518,10 @@ function renderSecondsWithinMinute(schedule, plan) {
504
518
  if (plan.singleSecond) {
505
519
  return "in Minute " + schedule.pattern.minute + " und Sekunde " + schedule.pattern.second + " jeder Stunde";
506
520
  }
507
- return secondsLead(schedule) + ", in Minute " + schedule.pattern.minute + " jeder Stunde";
521
+ if (secondsConfinesMinute(schedule)) {
522
+ return secondsLead(schedule) + " " + confinedMinutePhrase(schedule);
523
+ }
524
+ return secondsLead(schedule) + " in Minute " + schedule.pattern.minute + " jeder Stunde";
508
525
  }
509
526
  function wholeHour(hour) {
510
527
  if (hour === 0) {
@@ -529,6 +546,67 @@ function isEveryOtherMinuteSeconds(schedule, plan) {
529
546
  const minuteStep = stepSegment(schedule, "minute");
530
547
  return minuteStep.startToken === "*" && minuteStep.interval === 2;
531
548
  }
549
+ function minuteStride(schedule) {
550
+ if (schedule.shapes.minute === "step") {
551
+ const segment = stepSegment(schedule, "minute");
552
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
553
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
554
+ }
555
+ const values = singleValues(segmentsOf(schedule, "minute"));
556
+ return values && arithmeticStep(values);
557
+ }
558
+ function minuteStepConfinement(schedule, stride) {
559
+ const ordinal = minuteStepOrdinals[stride.interval];
560
+ const head = ordinal ? "in jeder " + ordinal + " Minute" : "alle " + stride.interval + " Minuten";
561
+ const tail = renderStride({ ...stride, cycle: 60 }, {
562
+ bare: () => "",
563
+ offset: () => " ab Minute " + stride.start,
564
+ bounded: () => " von Minute " + stride.start + " bis " + stride.last
565
+ });
566
+ return secondsLead(schedule) + " " + head + tail + " jeder Stunde";
567
+ }
568
+ function isSteppedMinuteSeconds(schedule, plan) {
569
+ return (plan.rest.kind === "minuteFrequency" || plan.rest.kind === "multipleMinutes") && (schedule.shapes.second === "wildcard" || schedule.shapes.second === "step") && schedule.shapes.hour === "wildcard" && schedule.pattern.minute !== "*/2" && minuteStride(schedule) !== null;
570
+ }
571
+ function confinedMinutePhrase(schedule) {
572
+ const stride = minuteStride(schedule);
573
+ if (stride && schedule.pattern.minute !== "*/2") {
574
+ const ordinal = minuteStepOrdinals[stride.interval];
575
+ const head = ordinal ? "jeder " + ordinal + " Minute" : "alle " + stride.interval + " Minuten";
576
+ const tail = renderStride({ ...stride, cycle: 60 }, {
577
+ bare: () => "",
578
+ offset: () => " ab Minute " + stride.start,
579
+ bounded: () => " von Minute " + stride.start + " bis " + stride.last
580
+ });
581
+ return head + tail + " jeder Stunde";
582
+ }
583
+ const genitive = schedule.shapes.minute === "single" ? "der Minute " + schedule.pattern.minute : "der Minuten " + joinList(fieldValues(schedule, "minute"));
584
+ return genitive + " jeder Stunde";
585
+ }
586
+ function minuteConfinementRender(plan, schedule) {
587
+ if (isSteppedMinuteSeconds(schedule, plan)) {
588
+ return minuteStepConfinement(schedule, minuteStride(schedule));
589
+ }
590
+ const minuteRest = plan.rest.kind === "minuteFrequency" || plan.rest.kind === "multipleMinutes" || plan.rest.kind === "rangeOfMinutes";
591
+ if (minuteRest && secondsConfinesMinute(schedule)) {
592
+ return secondsLead(schedule) + " " + confinedMinutePhrase(schedule);
593
+ }
594
+ return null;
595
+ }
596
+ function secondsConfinesMinute(schedule) {
597
+ const { second, minute, hour } = schedule.shapes;
598
+ if (second === "list") {
599
+ const values = singleValues(segmentsOf(schedule, "second"));
600
+ if (values && arithmeticStep(values)) {
601
+ return false;
602
+ }
603
+ }
604
+ const clockPoint = second === "single" || second === "range" || second === "list";
605
+ return clockPoint && minute !== "wildcard" && hour === "wildcard" && !(second === "single" && minute === "single");
606
+ }
607
+ function isLocativeMinuteConfinement(schedule, plan) {
608
+ return (plan.rest.kind === "multipleMinutes" || plan.rest.kind === "singleMinute") && schedule.shapes.hour === "wildcard";
609
+ }
532
610
  function renderComposeSeconds(schedule, plan, opts) {
533
611
  if ((plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes") && schedule.shapes.minute === "single") {
534
612
  const minute = +schedule.pattern.minute;
@@ -540,9 +618,16 @@ function renderComposeSeconds(schedule, plan, opts) {
540
618
  if (composeSingleMinute(schedule, plan)) {
541
619
  return secondsLead(schedule) + " " + clockMinuteGenitive(plan.rest.times, opts.style.sep);
542
620
  }
621
+ const confined = minuteConfinementRender(plan, schedule);
622
+ if (confined !== null) {
623
+ return confined;
624
+ }
543
625
  if (isEveryOtherMinuteSeconds(schedule, plan)) {
544
626
  return secondsLead(schedule) + " jeder zweiten Minute";
545
627
  }
628
+ if (isLocativeMinuteConfinement(schedule, plan)) {
629
+ return secondsLead(schedule) + " " + render(schedule, plan.rest, opts);
630
+ }
546
631
  const restOwnsLead = plan.rest.kind === "compactClockTimes" && schedule.analyses.clockSecond;
547
632
  const lead = restOwnsLead ? "" : secondsLead(schedule) + ", ";
548
633
  return lead + render(schedule, plan.rest, opts);
package/dist/lang/en.cjs CHANGED
@@ -521,6 +521,45 @@ var stepOrdinals = {
521
521
  8: "eighth",
522
522
  12: "twelfth"
523
523
  };
524
+ var spelledOrdinals = {
525
+ 2: "other",
526
+ 3: "third",
527
+ 4: "fourth",
528
+ 5: "fifth",
529
+ 6: "sixth",
530
+ 7: "seventh",
531
+ 8: "eighth",
532
+ 9: "ninth",
533
+ 10: "tenth",
534
+ 11: "eleventh",
535
+ 12: "twelfth",
536
+ 15: "fifteenth",
537
+ 20: "twentieth",
538
+ 30: "thirtieth"
539
+ };
540
+ function ordinalWord(interval) {
541
+ return spelledOrdinals[interval] ?? getOrdinal(interval);
542
+ }
543
+ function minuteStrideConfinement(stride, opts) {
544
+ const base = " during every " + ordinalWord(stride.interval) + " minute";
545
+ return renderStride({ ...stride, cycle: 60 }, {
546
+ bare: () => base,
547
+ offset: () => base + " from " + getNumber(stride.start, opts) + " " + pluralize(stride.start, "minute") + " past the hour",
548
+ bounded: () => {
549
+ const num = seriesNumber();
550
+ return base + " from " + num(stride.start) + through(opts) + num(stride.last) + " " + pluralize(stride.last, "minute") + " past the hour";
551
+ }
552
+ });
553
+ }
554
+ function minuteStride(schedule) {
555
+ if (schedule.shapes.minute === "step") {
556
+ const segment = stepSegment(schedule, "minute");
557
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
558
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
559
+ }
560
+ const values = singleValues(segmentsOf(schedule, "minute"));
561
+ return values && arithmeticStep(values);
562
+ }
524
563
  function everyNthHour(segment, opts) {
525
564
  const base = "during every " + stepOrdinals[segment.interval] + " hour";
526
565
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
@@ -702,9 +741,27 @@ function outlierTail(times, opts) {
702
741
  function isCadenceField(token) {
703
742
  return token === "*" || token.startsWith("*/") && token.indexOf("-") === -1;
704
743
  }
744
+ function secondLeadsCadence(schedule) {
745
+ if (isCadenceField(schedule.pattern.second)) {
746
+ return true;
747
+ }
748
+ if (schedule.shapes.second !== "step") {
749
+ return false;
750
+ }
751
+ return isOpenStep(schedule.pattern.second);
752
+ }
753
+ function secondLeadsClockPoint(schedule) {
754
+ if (schedule.plan.kind !== "composeSeconds" && schedule.plan.kind !== "secondsWithinMinute") {
755
+ return false;
756
+ }
757
+ const { second, minute, hour } = schedule.shapes;
758
+ const clockPoint = second === "single" || second === "range" || second === "list";
759
+ const minuteRestricted = minute !== "wildcard";
760
+ return clockPoint && minuteRestricted && hour === "wildcard" && !(second === "single" && minute === "single");
761
+ }
705
762
  function leadingCadence(schedule, opts) {
706
763
  const { second, minute } = schedule.pattern;
707
- if (isCadenceField(second)) {
764
+ if (secondLeadsCadence(schedule) || secondLeadsClockPoint(schedule)) {
708
765
  return { secondLead: true, text: secondsClause(schedule, "minute", opts) };
709
766
  }
710
767
  if (second === "0" && isCadenceField(minute)) {
@@ -726,9 +783,13 @@ function minuteConfinement(schedule, opts) {
726
783
  if (minute === "*") {
727
784
  return "";
728
785
  }
729
- if (isCadenceField(minute)) {
786
+ if (minute === "*/2") {
730
787
  return " of every other minute";
731
788
  }
789
+ const stride = minuteStride(schedule);
790
+ if (stride) {
791
+ return minuteStrideConfinement(stride, opts);
792
+ }
732
793
  const segments = segmentsOf(schedule, "minute");
733
794
  if (schedule.shapes.minute === "single") {
734
795
  return " during minute :" + pad(minute);
@@ -745,7 +806,7 @@ function minuteConfinement(schedule, opts) {
745
806
  function hourConfinement(schedule, opts) {
746
807
  const hour = schedule.pattern.hour;
747
808
  if (hour === "*") {
748
- const minutePinned = schedule.pattern.minute !== "*" && !isCadenceField(schedule.pattern.minute);
809
+ const minutePinned = schedule.pattern.minute !== "*" && !isCadenceField(schedule.pattern.minute) && !minuteStride(schedule);
749
810
  return minutePinned ? " of every hour" : "";
750
811
  }
751
812
  if (isCadenceField(hour)) {
@@ -794,9 +855,12 @@ function confinementEligible(schedule, lead) {
794
855
  }
795
856
  if (lead.secondLead) {
796
857
  if (minuteStep) {
797
- return minute === "*/2" && schedule.shapes.hour !== "range";
858
+ return minute === "*/2" ? schedule.shapes.hour !== "range" : schedule.pattern.hour === "*";
859
+ }
860
+ if (isMinuteStride(schedule)) {
861
+ return schedule.pattern.hour === "*";
798
862
  }
799
- if (isMinuteStride(schedule) || schedule.shapes.minute === "list" && schedule.shapes.hour === "list") {
863
+ if (schedule.shapes.minute === "list" && schedule.shapes.hour === "list") {
800
864
  return false;
801
865
  }
802
866
  return true;
package/dist/lang/en.js CHANGED
@@ -495,6 +495,45 @@ var stepOrdinals = {
495
495
  8: "eighth",
496
496
  12: "twelfth"
497
497
  };
498
+ var spelledOrdinals = {
499
+ 2: "other",
500
+ 3: "third",
501
+ 4: "fourth",
502
+ 5: "fifth",
503
+ 6: "sixth",
504
+ 7: "seventh",
505
+ 8: "eighth",
506
+ 9: "ninth",
507
+ 10: "tenth",
508
+ 11: "eleventh",
509
+ 12: "twelfth",
510
+ 15: "fifteenth",
511
+ 20: "twentieth",
512
+ 30: "thirtieth"
513
+ };
514
+ function ordinalWord(interval) {
515
+ return spelledOrdinals[interval] ?? getOrdinal(interval);
516
+ }
517
+ function minuteStrideConfinement(stride, opts) {
518
+ const base = " during every " + ordinalWord(stride.interval) + " minute";
519
+ return renderStride({ ...stride, cycle: 60 }, {
520
+ bare: () => base,
521
+ offset: () => base + " from " + getNumber(stride.start, opts) + " " + pluralize(stride.start, "minute") + " past the hour",
522
+ bounded: () => {
523
+ const num = seriesNumber();
524
+ return base + " from " + num(stride.start) + through(opts) + num(stride.last) + " " + pluralize(stride.last, "minute") + " past the hour";
525
+ }
526
+ });
527
+ }
528
+ function minuteStride(schedule) {
529
+ if (schedule.shapes.minute === "step") {
530
+ const segment = stepSegment(schedule, "minute");
531
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
532
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
533
+ }
534
+ const values = singleValues(segmentsOf(schedule, "minute"));
535
+ return values && arithmeticStep(values);
536
+ }
498
537
  function everyNthHour(segment, opts) {
499
538
  const base = "during every " + stepOrdinals[segment.interval] + " hour";
500
539
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
@@ -676,9 +715,27 @@ function outlierTail(times, opts) {
676
715
  function isCadenceField(token) {
677
716
  return token === "*" || token.startsWith("*/") && token.indexOf("-") === -1;
678
717
  }
718
+ function secondLeadsCadence(schedule) {
719
+ if (isCadenceField(schedule.pattern.second)) {
720
+ return true;
721
+ }
722
+ if (schedule.shapes.second !== "step") {
723
+ return false;
724
+ }
725
+ return isOpenStep(schedule.pattern.second);
726
+ }
727
+ function secondLeadsClockPoint(schedule) {
728
+ if (schedule.plan.kind !== "composeSeconds" && schedule.plan.kind !== "secondsWithinMinute") {
729
+ return false;
730
+ }
731
+ const { second, minute, hour } = schedule.shapes;
732
+ const clockPoint = second === "single" || second === "range" || second === "list";
733
+ const minuteRestricted = minute !== "wildcard";
734
+ return clockPoint && minuteRestricted && hour === "wildcard" && !(second === "single" && minute === "single");
735
+ }
679
736
  function leadingCadence(schedule, opts) {
680
737
  const { second, minute } = schedule.pattern;
681
- if (isCadenceField(second)) {
738
+ if (secondLeadsCadence(schedule) || secondLeadsClockPoint(schedule)) {
682
739
  return { secondLead: true, text: secondsClause(schedule, "minute", opts) };
683
740
  }
684
741
  if (second === "0" && isCadenceField(minute)) {
@@ -700,9 +757,13 @@ function minuteConfinement(schedule, opts) {
700
757
  if (minute === "*") {
701
758
  return "";
702
759
  }
703
- if (isCadenceField(minute)) {
760
+ if (minute === "*/2") {
704
761
  return " of every other minute";
705
762
  }
763
+ const stride = minuteStride(schedule);
764
+ if (stride) {
765
+ return minuteStrideConfinement(stride, opts);
766
+ }
706
767
  const segments = segmentsOf(schedule, "minute");
707
768
  if (schedule.shapes.minute === "single") {
708
769
  return " during minute :" + pad(minute);
@@ -719,7 +780,7 @@ function minuteConfinement(schedule, opts) {
719
780
  function hourConfinement(schedule, opts) {
720
781
  const hour = schedule.pattern.hour;
721
782
  if (hour === "*") {
722
- const minutePinned = schedule.pattern.minute !== "*" && !isCadenceField(schedule.pattern.minute);
783
+ const minutePinned = schedule.pattern.minute !== "*" && !isCadenceField(schedule.pattern.minute) && !minuteStride(schedule);
723
784
  return minutePinned ? " of every hour" : "";
724
785
  }
725
786
  if (isCadenceField(hour)) {
@@ -768,9 +829,12 @@ function confinementEligible(schedule, lead) {
768
829
  }
769
830
  if (lead.secondLead) {
770
831
  if (minuteStep) {
771
- return minute === "*/2" && schedule.shapes.hour !== "range";
832
+ return minute === "*/2" ? schedule.shapes.hour !== "range" : schedule.pattern.hour === "*";
833
+ }
834
+ if (isMinuteStride(schedule)) {
835
+ return schedule.pattern.hour === "*";
772
836
  }
773
- if (isMinuteStride(schedule) || schedule.shapes.minute === "list" && schedule.shapes.hour === "list") {
837
+ if (schedule.shapes.minute === "list" && schedule.shapes.hour === "list") {
774
838
  return false;
775
839
  }
776
840
  return true;
package/dist/lang/es.cjs CHANGED
@@ -223,6 +223,20 @@ var weekdayNames = [
223
223
  "s\xE1bado"
224
224
  ];
225
225
  var nthWeekdayNames = [null, "primer", "segundo", "tercer", "cuarto", "quinto"];
226
+ var stepOrdinals = {
227
+ 3: "tercer",
228
+ 4: "cuarto",
229
+ 5: "quinto",
230
+ 6: "sexto",
231
+ 7: "s\xE9ptimo",
232
+ 8: "octavo",
233
+ 9: "noveno",
234
+ 10: "d\xE9cimo",
235
+ 12: "duod\xE9cimo",
236
+ 15: "decimoquinto",
237
+ 20: "vig\xE9simo",
238
+ 30: "trig\xE9simo"
239
+ };
226
240
  function normalizeOptions(options) {
227
241
  options = options || {};
228
242
  const style = resolveDialect(options.dialect);
@@ -263,7 +277,10 @@ function renderSecondsWithinMinute(schedule, plan, opts) {
263
277
  if (plan.singleSecond) {
264
278
  return "en el minuto " + minuteField + " y el segundo " + schedule.pattern.second + " de cada hora" + trailingQualifier(schedule, opts);
265
279
  }
266
- return secondsLeadClause(schedule, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(schedule, opts);
280
+ if (secondsConfinesMinute(schedule)) {
281
+ return secondsBareLead(schedule) + " " + confinedMinutePhrase(schedule, opts) + trailingQualifier(schedule, opts);
282
+ }
283
+ return secondsLeadClause(schedule, opts) + " en el minuto " + minuteField + " de cada hora" + trailingQualifier(schedule, opts);
267
284
  }
268
285
  function secondsListAtClock(schedule, rest, opts) {
269
286
  const clockPhrases = rest.times.map(function clock(time) {
@@ -287,6 +304,88 @@ function composeHourCadence(schedule, plan, opts) {
287
304
  function isPinnedMinuteSeconds(schedule, plan) {
288
305
  return plan.rest.kind === "clockTimes" && (schedule.shapes.second === "wildcard" || schedule.shapes.second === "step");
289
306
  }
307
+ function minuteStride(schedule) {
308
+ if (schedule.shapes.minute === "step") {
309
+ const segment = stepSegment(schedule, "minute");
310
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
311
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
312
+ }
313
+ const values = singleValues(segmentsOf(schedule, "minute"));
314
+ return values && arithmeticStep(values);
315
+ }
316
+ function minuteStepConfinement(schedule, stride, opts) {
317
+ const ordinal = stepOrdinals[stride.interval];
318
+ const head = ordinal ? "cada " + ordinal + " minuto" : "cada " + numero(stride.interval, opts) + " minutos";
319
+ const tail = renderStride({ ...stride, cycle: 60 }, {
320
+ bare: () => "",
321
+ offset: () => " a partir del minuto " + stride.start,
322
+ bounded: () => " del minuto " + stride.start + " al " + stride.last
323
+ });
324
+ return secondsLeadClause(schedule, opts) + " en " + head + tail + " de cada hora" + trailingQualifier(schedule, opts);
325
+ }
326
+ function isSteppedMinuteSeconds(schedule, plan) {
327
+ return (plan.rest.kind === "minuteFrequency" || plan.rest.kind === "multipleMinutes") && (schedule.shapes.second === "wildcard" || schedule.shapes.second === "step") && schedule.shapes.hour === "wildcard" && schedule.pattern.minute !== "*/2" && minuteStride(schedule) !== null;
328
+ }
329
+ function secondsBareLead(schedule) {
330
+ const secondField = schedule.pattern.second;
331
+ const shape = schedule.shapes.second;
332
+ if (shape === "range") {
333
+ const bounds = secondField.split("-");
334
+ return "cada segundo del " + bounds[0] + " al " + bounds[1];
335
+ }
336
+ if (shape === "single") {
337
+ return "en el segundo " + secondField;
338
+ }
339
+ return "en los segundos " + joinList(segmentWords(segmentsOf(schedule, "second")));
340
+ }
341
+ function confinedMinutePhrase(schedule, opts) {
342
+ const stride = minuteStride(schedule);
343
+ if (stride && schedule.pattern.minute !== "*/2") {
344
+ const ordinal = stepOrdinals[stride.interval];
345
+ const head = ordinal ? "cada " + ordinal + " minuto" : "cada " + numero(stride.interval, opts) + " minutos";
346
+ const tail = renderStride({ ...stride, cycle: 60 }, {
347
+ bare: () => "",
348
+ offset: () => " a partir del minuto " + stride.start,
349
+ bounded: () => " del minuto " + stride.start + " al " + stride.last
350
+ });
351
+ return "de " + head + tail + " de cada hora";
352
+ }
353
+ if (schedule.shapes.minute === "range") {
354
+ return "de " + minuteRangeLead(schedule.pattern.minute) + " de cada hora";
355
+ }
356
+ if (schedule.shapes.minute === "list") {
357
+ return "de los minutos " + joinList(segmentWords(segmentsOf(schedule, "minute"))) + " de cada hora";
358
+ }
359
+ return "del minuto " + schedule.pattern.minute + " de cada hora";
360
+ }
361
+ function minuteConfinementRender(plan, schedule, opts) {
362
+ if (isSteppedMinuteSeconds(schedule, plan)) {
363
+ return minuteStepConfinement(schedule, minuteStride(schedule), opts);
364
+ }
365
+ const minuteRest = plan.rest.kind === "minuteFrequency" || plan.rest.kind === "multipleMinutes" || plan.rest.kind === "rangeOfMinutes";
366
+ if (minuteRest && secondsConfinesMinute(schedule)) {
367
+ return secondsBareLead(schedule) + " " + confinedMinutePhrase(schedule, opts) + trailingQualifier(schedule, opts);
368
+ }
369
+ return null;
370
+ }
371
+ function secondsConfinesMinute(schedule) {
372
+ const { second, minute, hour } = schedule.shapes;
373
+ if (second === "list") {
374
+ const values = singleValues(segmentsOf(schedule, "second"));
375
+ if (values && arithmeticStep(values)) {
376
+ return false;
377
+ }
378
+ }
379
+ const clockPoint = second === "single" || second === "range" || second === "list";
380
+ return clockPoint && minute !== "wildcard" && hour === "wildcard" && !(second === "single" && minute === "single");
381
+ }
382
+ function composeConnector(schedule, plan, opts) {
383
+ if (plan.rest.kind === "compactClockTimes" && schedule.analyses.clockSecond) {
384
+ return "";
385
+ }
386
+ const locative = (plan.rest.kind === "multipleMinutes" || plan.rest.kind === "singleMinute") && schedule.shapes.hour === "wildcard";
387
+ return secondsLeadClause(schedule, opts) + (locative ? " " : ", ");
388
+ }
290
389
  function renderComposeSeconds(schedule, plan, opts) {
291
390
  const hourCad = composeHourCadence(schedule, plan, opts);
292
391
  if (hourCad !== null) {
@@ -305,11 +404,14 @@ function renderComposeSeconds(schedule, plan, opts) {
305
404
  const cadence = "cada " + numero(stepSegment(schedule, "second").interval, opts) + " segundos del minuto " + schedule.pattern.minute;
306
405
  return dayFrame + ", " + window + ", " + cadence;
307
406
  }
407
+ const confined = minuteConfinementRender(plan, schedule, opts);
408
+ if (confined !== null) {
409
+ return confined;
410
+ }
308
411
  if (isEveryOtherMinuteSeconds(schedule, plan)) {
309
412
  return secondsLeadClause(schedule, opts) + " de " + render(schedule, plan.rest, opts);
310
413
  }
311
- const restOwnsLead = plan.rest.kind === "compactClockTimes" && schedule.analyses.clockSecond;
312
- const lead = restOwnsLead ? "" : secondsLeadClause(schedule, opts) + ", ";
414
+ const lead = composeConnector(schedule, plan, opts);
313
415
  return lead + render(schedule, plan.rest, opts);
314
416
  }
315
417
  function isEveryOtherMinuteSeconds(schedule, plan) {
package/dist/lang/es.js CHANGED
@@ -197,6 +197,20 @@ var weekdayNames = [
197
197
  "s\xE1bado"
198
198
  ];
199
199
  var nthWeekdayNames = [null, "primer", "segundo", "tercer", "cuarto", "quinto"];
200
+ var stepOrdinals = {
201
+ 3: "tercer",
202
+ 4: "cuarto",
203
+ 5: "quinto",
204
+ 6: "sexto",
205
+ 7: "s\xE9ptimo",
206
+ 8: "octavo",
207
+ 9: "noveno",
208
+ 10: "d\xE9cimo",
209
+ 12: "duod\xE9cimo",
210
+ 15: "decimoquinto",
211
+ 20: "vig\xE9simo",
212
+ 30: "trig\xE9simo"
213
+ };
200
214
  function normalizeOptions(options) {
201
215
  options = options || {};
202
216
  const style = resolveDialect(options.dialect);
@@ -237,7 +251,10 @@ function renderSecondsWithinMinute(schedule, plan, opts) {
237
251
  if (plan.singleSecond) {
238
252
  return "en el minuto " + minuteField + " y el segundo " + schedule.pattern.second + " de cada hora" + trailingQualifier(schedule, opts);
239
253
  }
240
- return secondsLeadClause(schedule, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(schedule, opts);
254
+ if (secondsConfinesMinute(schedule)) {
255
+ return secondsBareLead(schedule) + " " + confinedMinutePhrase(schedule, opts) + trailingQualifier(schedule, opts);
256
+ }
257
+ return secondsLeadClause(schedule, opts) + " en el minuto " + minuteField + " de cada hora" + trailingQualifier(schedule, opts);
241
258
  }
242
259
  function secondsListAtClock(schedule, rest, opts) {
243
260
  const clockPhrases = rest.times.map(function clock(time) {
@@ -261,6 +278,88 @@ function composeHourCadence(schedule, plan, opts) {
261
278
  function isPinnedMinuteSeconds(schedule, plan) {
262
279
  return plan.rest.kind === "clockTimes" && (schedule.shapes.second === "wildcard" || schedule.shapes.second === "step");
263
280
  }
281
+ function minuteStride(schedule) {
282
+ if (schedule.shapes.minute === "step") {
283
+ const segment = stepSegment(schedule, "minute");
284
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
285
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
286
+ }
287
+ const values = singleValues(segmentsOf(schedule, "minute"));
288
+ return values && arithmeticStep(values);
289
+ }
290
+ function minuteStepConfinement(schedule, stride, opts) {
291
+ const ordinal = stepOrdinals[stride.interval];
292
+ const head = ordinal ? "cada " + ordinal + " minuto" : "cada " + numero(stride.interval, opts) + " minutos";
293
+ const tail = renderStride({ ...stride, cycle: 60 }, {
294
+ bare: () => "",
295
+ offset: () => " a partir del minuto " + stride.start,
296
+ bounded: () => " del minuto " + stride.start + " al " + stride.last
297
+ });
298
+ return secondsLeadClause(schedule, opts) + " en " + head + tail + " de cada hora" + trailingQualifier(schedule, opts);
299
+ }
300
+ function isSteppedMinuteSeconds(schedule, plan) {
301
+ return (plan.rest.kind === "minuteFrequency" || plan.rest.kind === "multipleMinutes") && (schedule.shapes.second === "wildcard" || schedule.shapes.second === "step") && schedule.shapes.hour === "wildcard" && schedule.pattern.minute !== "*/2" && minuteStride(schedule) !== null;
302
+ }
303
+ function secondsBareLead(schedule) {
304
+ const secondField = schedule.pattern.second;
305
+ const shape = schedule.shapes.second;
306
+ if (shape === "range") {
307
+ const bounds = secondField.split("-");
308
+ return "cada segundo del " + bounds[0] + " al " + bounds[1];
309
+ }
310
+ if (shape === "single") {
311
+ return "en el segundo " + secondField;
312
+ }
313
+ return "en los segundos " + joinList(segmentWords(segmentsOf(schedule, "second")));
314
+ }
315
+ function confinedMinutePhrase(schedule, opts) {
316
+ const stride = minuteStride(schedule);
317
+ if (stride && schedule.pattern.minute !== "*/2") {
318
+ const ordinal = stepOrdinals[stride.interval];
319
+ const head = ordinal ? "cada " + ordinal + " minuto" : "cada " + numero(stride.interval, opts) + " minutos";
320
+ const tail = renderStride({ ...stride, cycle: 60 }, {
321
+ bare: () => "",
322
+ offset: () => " a partir del minuto " + stride.start,
323
+ bounded: () => " del minuto " + stride.start + " al " + stride.last
324
+ });
325
+ return "de " + head + tail + " de cada hora";
326
+ }
327
+ if (schedule.shapes.minute === "range") {
328
+ return "de " + minuteRangeLead(schedule.pattern.minute) + " de cada hora";
329
+ }
330
+ if (schedule.shapes.minute === "list") {
331
+ return "de los minutos " + joinList(segmentWords(segmentsOf(schedule, "minute"))) + " de cada hora";
332
+ }
333
+ return "del minuto " + schedule.pattern.minute + " de cada hora";
334
+ }
335
+ function minuteConfinementRender(plan, schedule, opts) {
336
+ if (isSteppedMinuteSeconds(schedule, plan)) {
337
+ return minuteStepConfinement(schedule, minuteStride(schedule), opts);
338
+ }
339
+ const minuteRest = plan.rest.kind === "minuteFrequency" || plan.rest.kind === "multipleMinutes" || plan.rest.kind === "rangeOfMinutes";
340
+ if (minuteRest && secondsConfinesMinute(schedule)) {
341
+ return secondsBareLead(schedule) + " " + confinedMinutePhrase(schedule, opts) + trailingQualifier(schedule, opts);
342
+ }
343
+ return null;
344
+ }
345
+ function secondsConfinesMinute(schedule) {
346
+ const { second, minute, hour } = schedule.shapes;
347
+ if (second === "list") {
348
+ const values = singleValues(segmentsOf(schedule, "second"));
349
+ if (values && arithmeticStep(values)) {
350
+ return false;
351
+ }
352
+ }
353
+ const clockPoint = second === "single" || second === "range" || second === "list";
354
+ return clockPoint && minute !== "wildcard" && hour === "wildcard" && !(second === "single" && minute === "single");
355
+ }
356
+ function composeConnector(schedule, plan, opts) {
357
+ if (plan.rest.kind === "compactClockTimes" && schedule.analyses.clockSecond) {
358
+ return "";
359
+ }
360
+ const locative = (plan.rest.kind === "multipleMinutes" || plan.rest.kind === "singleMinute") && schedule.shapes.hour === "wildcard";
361
+ return secondsLeadClause(schedule, opts) + (locative ? " " : ", ");
362
+ }
264
363
  function renderComposeSeconds(schedule, plan, opts) {
265
364
  const hourCad = composeHourCadence(schedule, plan, opts);
266
365
  if (hourCad !== null) {
@@ -279,11 +378,14 @@ function renderComposeSeconds(schedule, plan, opts) {
279
378
  const cadence = "cada " + numero(stepSegment(schedule, "second").interval, opts) + " segundos del minuto " + schedule.pattern.minute;
280
379
  return dayFrame + ", " + window + ", " + cadence;
281
380
  }
381
+ const confined = minuteConfinementRender(plan, schedule, opts);
382
+ if (confined !== null) {
383
+ return confined;
384
+ }
282
385
  if (isEveryOtherMinuteSeconds(schedule, plan)) {
283
386
  return secondsLeadClause(schedule, opts) + " de " + render(schedule, plan.rest, opts);
284
387
  }
285
- const restOwnsLead = plan.rest.kind === "compactClockTimes" && schedule.analyses.clockSecond;
286
- const lead = restOwnsLead ? "" : secondsLeadClause(schedule, opts) + ", ";
388
+ const lead = composeConnector(schedule, plan, opts);
287
389
  return lead + render(schedule, plan.rest, opts);
288
390
  }
289
391
  function isEveryOtherMinuteSeconds(schedule, plan) {