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/es.js CHANGED
@@ -24,12 +24,28 @@ var weekdayNumbers = {
24
24
  FRI: 5,
25
25
  SAT: 6
26
26
  };
27
+ var maxClockTimes = 6;
27
28
 
28
29
  // src/core/util.ts
29
30
  function isNonNegativeInteger(value) {
30
31
  const digits = /^\d+$/;
31
32
  return digits.test(value);
32
33
  }
34
+ function arithmeticStep(values) {
35
+ if (values.length < 5) {
36
+ return null;
37
+ }
38
+ const interval = values[1] - values[0];
39
+ if (interval < 2) {
40
+ return null;
41
+ }
42
+ for (let i = 2; i < values.length; i += 1) {
43
+ if (values[i] - values[i - 1] !== interval) {
44
+ return null;
45
+ }
46
+ }
47
+ return { start: values[0], interval, last: values[values.length - 1] };
48
+ }
33
49
  function toFieldNumber(token, numberMap) {
34
50
  return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
35
51
  }
@@ -147,19 +163,38 @@ function renderSecondsWithinMinute(ir, plan, opts) {
147
163
  }
148
164
  return secondsLeadClause(ir, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(ir, opts);
149
165
  }
166
+ function secondsListAtClock(ir, rest, opts) {
167
+ const clockPhrases = rest.times.map(function clock(time) {
168
+ return atTime(timePhrase(time.hour, time.minute, null, opts));
169
+ });
170
+ const grouped = groupClockTimesByArticle(clockPhrases);
171
+ const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
172
+ const stride = strideFromSegments(fieldSegments(ir, "second"), "segundo", "", opts);
173
+ const secondsPhrase = stride ?? "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second")));
174
+ const dayFrame = trailingQualifier(ir, opts);
175
+ return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
176
+ }
177
+ function composeHourCadence(ir, plan, opts) {
178
+ const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
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");
187
+ }
150
188
  function renderComposeSeconds(ir, plan, opts) {
151
- if (plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step")) {
189
+ const hourCad = composeHourCadence(ir, plan, opts);
190
+ if (hourCad !== null) {
191
+ return hourCad;
192
+ }
193
+ if (isPinnedMinuteSeconds(ir, plan)) {
152
194
  return pinnedMinuteSeconds(ir, plan.rest, opts);
153
195
  }
154
196
  if (plan.rest.kind === "clockTimes" && ir.shapes.second === "list") {
155
- const clockPhrases = plan.rest.times.map(function clock(time) {
156
- return atTime(timePhrase(time.hour, time.minute, null, opts));
157
- });
158
- const grouped = groupClockTimesByArticle(clockPhrases);
159
- const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
160
- const secondsPhrase = "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second")));
161
- const dayFrame = trailingQualifier(ir, opts);
162
- return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
197
+ return secondsListAtClock(ir, plan.rest, opts);
163
198
  }
164
199
  if (plan.rest.kind === "hourRange" && ir.shapes.second === "step" && ir.pattern.weekday !== "*") {
165
200
  const restNode = plan.rest;
@@ -168,17 +203,32 @@ function renderComposeSeconds(ir, plan, opts) {
168
203
  const cadence = "cada " + numero(stepSegment(ir.analyses.segments.second).interval, opts) + " segundos del minuto " + ir.pattern.minute;
169
204
  return dayFrame + ", " + window + ", " + cadence;
170
205
  }
171
- return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
206
+ if (isEveryOtherMinuteSeconds(ir, plan)) {
207
+ return secondsLeadClause(ir, opts) + " de " + render(ir, plan.rest, opts);
208
+ }
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);
212
+ }
213
+ function isEveryOtherMinuteSeconds(ir, plan) {
214
+ if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
215
+ return false;
216
+ }
217
+ const minuteStep = stepSegment(ir.analyses.segments.minute);
218
+ return minuteStep.startToken === "*" && minuteStep.interval === 2;
172
219
  }
173
220
  function pinnedMinuteSeconds(ir, rest, opts) {
174
221
  const dayTrail = leadingQualifier(ir, opts).trimEnd();
175
222
  const trail = dayTrail ? ", " + dayTrail : "";
176
- if (+rest.times[0].minute === 0) {
223
+ if (+rest.times[0].minute === 0 && ir.shapes.minute === "single") {
177
224
  return secondsLeadClause(ir, opts) + " durante un minuto " + durationHourList(rest.times, opts) + trail;
178
225
  }
179
226
  return secondsLeadClause(ir, opts) + " de " + explicitClockList(rest.times, opts) + trail;
180
227
  }
181
228
  function secondsLeadClause(ir, opts) {
229
+ return secondsClause(ir, "minuto", opts);
230
+ }
231
+ function secondsClause(ir, anchor, opts) {
182
232
  const secondField = ir.pattern.second;
183
233
  const shape = ir.shapes.second;
184
234
  if (secondField === "*") {
@@ -188,18 +238,23 @@ function secondsLeadClause(ir, opts) {
188
238
  return stepCycle60(
189
239
  stepSegment(ir.analyses.segments.second),
190
240
  "segundo",
191
- "minuto",
241
+ anchor,
192
242
  opts
193
243
  );
194
244
  }
195
245
  if (shape === "range") {
196
246
  const bounds = secondField.split("-");
197
- return "cada segundo del " + bounds[0] + " al " + bounds[1] + " de cada minuto";
247
+ return "cada segundo del " + bounds[0] + " al " + bounds[1] + " de cada " + anchor;
198
248
  }
199
249
  if (shape === "single") {
200
- return "en el segundo " + secondField + " de cada minuto";
250
+ return "en el segundo " + secondField + " de cada " + anchor;
201
251
  }
202
- return "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second"))) + " de cada minuto";
252
+ return strideFromSegments(
253
+ fieldSegments(ir, "second"),
254
+ "segundo",
255
+ anchor,
256
+ opts
257
+ ) ?? "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second"))) + " de cada " + anchor;
203
258
  }
204
259
  function renderEveryMinute(ir, plan, opts) {
205
260
  return "cada minuto" + trailingQualifier(ir, opts);
@@ -211,10 +266,15 @@ function renderRangeOfMinutes(ir, plan, opts) {
211
266
  return minuteRangeLead(ir.pattern.minute) + " de cada hora" + trailingQualifier(ir, opts);
212
267
  }
213
268
  function renderMultipleMinutes(ir, plan, opts) {
214
- return minutesList(ir) + trailingQualifier(ir, opts);
269
+ return minutesList(ir, opts) + trailingQualifier(ir, opts);
215
270
  }
216
- function minutesList(ir) {
217
- return "en los minutos " + joinList(segmentWords(fieldSegments(ir, "minute"))) + " de cada hora";
271
+ function minutesList(ir, opts) {
272
+ return strideFromSegments(
273
+ fieldSegments(ir, "minute"),
274
+ "minuto",
275
+ "hora",
276
+ opts
277
+ ) ?? "en los minutos " + joinList(segmentWords(fieldSegments(ir, "minute"))) + " de cada hora";
218
278
  }
219
279
  function minuteRangeLead(minuteField) {
220
280
  const bounds = minuteField.split("-");
@@ -277,7 +337,12 @@ function renderMinuteFrequency(ir, plan, opts) {
277
337
  opts
278
338
  );
279
339
  if (plan.hours.kind === "during") {
280
- phrase += singleHourStep(ir.analyses.segments.hour) ? ", " + stepHourSpan(stepSegment(ir.analyses.segments.hour), opts) : " " + hourSpanFromTimes(ir, plan.hours.times, opts);
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
+ }
281
346
  } else if (plan.hours.kind === "window") {
282
347
  phrase += " " + hourWindow(plan.hours, opts);
283
348
  } else if (plan.hours.kind === "step") {
@@ -296,21 +361,30 @@ function renderMinuteSpanInHour(ir, plan, opts) {
296
361
  ) + trailingQualifier(ir, opts);
297
362
  }
298
363
  function renderMinutesAcrossHours(ir, plan, opts) {
364
+ const cadence = unevenHourCadence(ir, opts);
299
365
  if (plan.form === "wildcard") {
366
+ if (cadence !== null) {
367
+ return "cada minuto, " + cadence + trailingQualifier(ir, opts);
368
+ }
300
369
  if (singleHourStep(ir.analyses.segments.hour)) {
301
370
  return "cada minuto, " + stepHourSpan(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
302
371
  }
303
372
  return "cada minuto " + hourSpanFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
304
373
  }
305
- const lead = plan.form === "range" ? minuteRangeLead(ir.pattern.minute) : minutesList(ir);
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
+ }
306
378
  return lead + ", " + atHourTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
307
379
  }
308
380
  function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
309
381
  const segment = stepSegment(ir.analyses.segments.hour);
382
+ const cadence = unevenHourCadence(ir, opts);
310
383
  if (plan.form === "wildcard") {
311
384
  return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(ir, opts);
312
385
  }
313
- return minuteRangeLead(ir.pattern.minute) + ", " + stepHours(segment, opts) + trailingQualifier(ir, opts);
386
+ const lead = plan.form === "list" ? minutesList(ir, opts) : minuteRangeLead(ir.pattern.minute);
387
+ return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(ir, opts);
314
388
  }
315
389
  function renderEveryHour(ir, plan, opts) {
316
390
  return "cada hora" + trailingQualifier(ir, opts);
@@ -326,10 +400,14 @@ function renderHourRange(ir, plan, opts) {
326
400
  if (ir.pattern.minute === "0") {
327
401
  return "cada hora " + window + trailingQualifier(ir, opts);
328
402
  }
329
- const lead = ir.shapes.minute === "single" ? "en el minuto " + ir.pattern.minute + " de cada hora" : minutesList(ir);
403
+ const lead = ir.shapes.minute === "single" ? "en el minuto " + ir.pattern.minute + " de cada hora" : minutesList(ir, opts);
330
404
  return lead + ", " + window + trailingQualifier(ir, opts);
331
405
  }
332
406
  function renderHourStep(ir, plan, opts) {
407
+ const cadence = unevenHourCadence(ir, opts);
408
+ if (cadence !== null) {
409
+ return cadence + trailingQualifier(ir, opts);
410
+ }
333
411
  return stepHours(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
334
412
  }
335
413
  function boundedWindow(plan) {
@@ -400,6 +478,13 @@ function unionYaseaSuffix(ir, opts) {
400
478
  return ", ya sea " + domArm(ir, opts) + " o " + dowArm(ir);
401
479
  }
402
480
  function renderClockTimes(ir, plan, opts) {
481
+ if (ir.shapes.minute === "single") {
482
+ const minute = +ir.pattern.minute;
483
+ const cadence = hourCadence(ir, minute, opts) ?? hourRangeCadence(ir, minute, opts);
484
+ if (cadence !== null) {
485
+ return cadence;
486
+ }
487
+ }
403
488
  const phrases = plan.times.map(function clock(time) {
404
489
  return atTime(timePhrase(time.hour, time.minute, time.second, opts));
405
490
  });
@@ -581,6 +666,10 @@ function groupClockTimesByArticle(phrases) {
581
666
  }
582
667
  function renderCompactClockTimes(ir, plan, opts) {
583
668
  if (plan.fold) {
669
+ const cadence2 = hourCadence(ir, plan.minute, opts) ?? hourRangeCadence(ir, plan.minute, opts);
670
+ if (cadence2 !== null) {
671
+ return cadence2;
672
+ }
584
673
  const ranged = hourSegments(ir).some(function range(segment) {
585
674
  return segment.kind === "range";
586
675
  });
@@ -589,7 +678,8 @@ function renderCompactClockTimes(ir, plan, opts) {
589
678
  }
590
679
  return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
591
680
  }
592
- const phrase = minutesList(ir) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
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);
593
683
  return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
594
684
  }
595
685
  var renderers = {
@@ -612,19 +702,50 @@ var renderers = {
612
702
  singleMinute: renderSingleMinute,
613
703
  standaloneSeconds: renderStandaloneSeconds
614
704
  };
705
+ function renderStride(stride, opts) {
706
+ const { interval, start, last, cycle, unit, anchor } = stride;
707
+ const cadence = "cada " + numero(interval, opts) + " " + unit + "s";
708
+ const tiles = cycle % interval === 0;
709
+ if (start === 0 && tiles) {
710
+ return cadence;
711
+ }
712
+ const tail = anchor ? " de cada " + anchor : "";
713
+ if (start < interval && tiles) {
714
+ return cadence + " a partir del " + unit + " " + start + tail;
715
+ }
716
+ return cadence + " del " + unit + " " + start + " al " + last + tail;
717
+ }
615
718
  function stepCycle60(segment, unit, anchor, opts) {
616
719
  if (segment.startToken.indexOf("-") !== -1) {
617
720
  return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
618
721
  }
619
722
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
620
- const interval = segment.interval;
621
- if (start !== 0) {
622
- if (segment.fires.length <= 3) {
623
- return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
723
+ if (start !== 0 && segment.fires.length <= 3) {
724
+ return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
725
+ }
726
+ return renderStride({
727
+ interval: segment.interval,
728
+ start,
729
+ last: segment.fires[segment.fires.length - 1],
730
+ cycle: 60,
731
+ unit,
732
+ anchor
733
+ }, opts);
734
+ }
735
+ function strideFromSegments(segments, unit, anchor, opts) {
736
+ const values = singleValues(segments);
737
+ const step = values && arithmeticStep(values);
738
+ return step ? renderStride({ ...step, cycle: 60, unit, anchor }, opts) : null;
739
+ }
740
+ function singleValues(segments) {
741
+ const values = [];
742
+ for (const segment of segments) {
743
+ if (segment.kind !== "single") {
744
+ return null;
624
745
  }
625
- return "cada " + numero(interval, opts) + " " + unit + "s a partir del " + unit + " " + start + " de cada " + anchor;
746
+ values.push(+segment.value);
626
747
  }
627
- return "cada " + numero(interval, opts) + " " + unit + "s";
748
+ return values;
628
749
  }
629
750
  function stepHours(segment, opts) {
630
751
  if (segment.startToken.indexOf("-") !== -1) {
@@ -640,6 +761,115 @@ function stepHours(segment, opts) {
640
761
  }
641
762
  return "cada " + numero(interval, opts) + " horas a partir de " + timePhrase(start, 0, null, opts);
642
763
  }
764
+ function hourStrideCadence(stride, opts) {
765
+ const { start, interval, last } = stride;
766
+ const cadence = "cada " + numero(interval, opts) + " horas";
767
+ const tiles = 24 % interval === 0;
768
+ if (start === 0 && tiles) {
769
+ return cadence;
770
+ }
771
+ if (start < interval && tiles) {
772
+ return cadence + " a partir de " + timePhrase(start, 0, null, opts);
773
+ }
774
+ return cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts);
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
+ }
804
+ function hourStride(ir) {
805
+ const segments = fieldSegments(ir, "hour");
806
+ if (segments.length === 1 && segments[0].kind === "step") {
807
+ const segment = segments[0];
808
+ if (segment.fires.length < 2) {
809
+ return null;
810
+ }
811
+ const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
812
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
813
+ }
814
+ const values = singleValues(segments);
815
+ return values && hourListStride(values);
816
+ }
817
+ function subMinuteSecond(ir) {
818
+ return ir.pattern.second === "*" || ir.shapes.second === "step";
819
+ }
820
+ function hourCadenceLead(ir, minute, opts) {
821
+ if (minute === 0) {
822
+ if (subMinuteSecond(ir)) {
823
+ return secondsClause(ir, "minuto", opts) + " durante un minuto";
824
+ }
825
+ return secondsClause(ir, "hora", opts);
826
+ }
827
+ const minutePhrase = "en el minuto " + minute;
828
+ if (ir.pattern.second === "0") {
829
+ return minutePhrase;
830
+ }
831
+ return secondsClause(ir, "minuto", opts) + ", " + minutePhrase;
832
+ }
833
+ function hourCadence(ir, minute, opts) {
834
+ const stride = hourStride(ir);
835
+ if (!stride) {
836
+ return null;
837
+ }
838
+ const fires = (stride.last - stride.start) / stride.interval + 1;
839
+ if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
840
+ return null;
841
+ }
842
+ const confinement = minute === 0 && subMinuteSecond(ir) && cleanStrideSegment(ir);
843
+ if (confinement) {
844
+ return secondsClause(ir, "minuto", opts) + " durante un minuto, " + stepHourSpan(confinement, opts) + trailingQualifier(ir, opts);
845
+ }
846
+ if (minute === 0 && ir.pattern.second === "0") {
847
+ return hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
848
+ }
849
+ return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
850
+ }
851
+ function cleanStrideSegment(ir) {
852
+ const segments = fieldSegments(ir, "hour");
853
+ const segment = segments.length === 1 && segments[0];
854
+ if (!segment || segment.kind !== "step" || segment.startToken.indexOf("-") !== -1) {
855
+ return null;
856
+ }
857
+ return segment;
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
+ }
643
873
  function atTimes(hours, opts) {
644
874
  return hours.map(function each(hour) {
645
875
  return atTime(timePhrase(hour, 0, null, opts));