cronli5 0.1.2 → 0.1.4

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 CHANGED
@@ -6,6 +6,70 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.4]
10
+
11
+ ### Fixed
12
+
13
+ - **A pinned minute 0 under sub-minute seconds no longer loses its one-minute
14
+ confinement.** `* 0 0` runs every second of the single minute 00:00 — sixty
15
+ fires, then nothing until the next midnight — but read "every second … at
16
+ midnight", which a reader takes for the whole midnight hour (3,600 fires). It
17
+ now names the bounded minute: English "every second for one minute at
18
+ midnight", Spanish "cada segundo durante un minuto a medianoche", German "jede
19
+ Sekunde der Minute 0:00", Finnish "joka sekunti minuutin 0.00 aikana", Chinese
20
+ "凌晨0点0分的每一秒". Hour lists, ranges, and steps too (`* 0 9-17`, `* 0 */2`).
21
+ Every non-zero pinned minute under seconds now reads compactly as "every second
22
+ of 9:05 a.m." / "de las 09:05". All languages.
23
+ - **Chinese keeps the start of an offset step in every context.** An offset step
24
+ such as `2/6` (hours 2, 8, 14, 20) or `5/15` (minutes :05, :20, …) could render
25
+ as the bare "每6小时" / "每15分钟" cadence — silently dropping the start — under a
26
+ minute frequency, composed with seconds, or across an hour step. Each now
27
+ enumerates its fires.
28
+
29
+ ### Changed
30
+
31
+ - **A single hour with a wildcard minute reads as that hour, not a synthesized
32
+ range.** `0 * 9` reads "every minute of the 9 a.m. hour" rather than "every
33
+ minute from 9 a.m. through 9:59 a.m." — the source has no range. Spanish "cada
34
+ minuto de la hora de las 09:00", German "jede Minute der 9-Uhr-Stunde", Finnish
35
+ "joka minuutti kello 9 aikana", Chinese "9点的每一分钟". Genuine hour ranges
36
+ (`9-17`) and partial-minute single hours (`0-30 9`) are unchanged. All
37
+ languages.
38
+ - **English `* */2` under seconds** reads "every second of every other minute"
39
+ (was "every second, every two minutes", which juxtaposed two cadences that read
40
+ as contradictory).
41
+ - **Chinese idiom polish:** an every-other-hour minute (`0 * */2` → "在偶数小时,
42
+ 每分钟"), single-hour minutes, and a restricted-hour second list ("凌晨0点5、20、
43
+ 35、50分的每一秒" instead of the misleading "每小时…").
44
+
45
+ ## [0.1.3]
46
+
47
+ ### Changed
48
+
49
+ - **Full-span ranges now read as no restriction**, matching their `*` form. A
50
+ plain range covering an entire field imposes no restriction, so `0 0 * * 0-6`
51
+ reads "every day at midnight" (was "every Sunday through Saturday at
52
+ midnight"), `0-59` is "every minute", `0 0-23 * * *` "every hour",
53
+ `1-31`/`1-12` add nothing, and every seven-day weekday range (`0-6`, `1-7`,
54
+ `0-7`, `SUN-SAT`) collapses to every day. A step whose range covers the field
55
+ does the same: `0-59/2` reads "every two minutes" instead of listing 30 fires,
56
+ `0-23/2` "every two hours". Partial ranges and steps (`9-17`, `9-17/2`,
57
+ `MON-FRI`) and the year field are unchanged. All languages.
58
+ - **Chinese now composes the clock time in second-level patterns.**
59
+ `* 2 0 * * *` read "在凌晨0点,每小时2分,每秒" — three floating clauses, with the
60
+ minute mis-stated as "minute 2 of every hour" and the hour split off — and now
61
+ reads "每天0点2分每秒". The other languages already composed these; Chinese
62
+ reused its list path for single-minute patterns instead of the clock time the
63
+ core had already assembled.
64
+
65
+ ### Fixed
66
+
67
+ - **English** no longer doubles the period when a sentence ends in an
68
+ abbreviation: `0 9 * * *` reads "Runs every day at 9 a.m." (was "…9 a.m..").
69
+ The terminator guard German gained in 0.1.2 now covers English's `a.m.`/`p.m.`.
70
+ - The **CLI reports an unknown option clearly**: `--land` (a typo for `--lang`)
71
+ now reports "Unknown option: --land" instead of mis-blaming the minute field.
72
+
9
73
  ## [0.1.2]
10
74
 
11
75
  ### Changed
package/cli.js CHANGED
@@ -52,6 +52,10 @@ if (flag !== -1) {
52
52
  }
53
53
  }
54
54
 
55
+ // After the recognized flags are consumed, any remaining `--flag` is a typo or
56
+ // an unsupported option (e.g. `--land` for `--lang`); naming it beats letting
57
+ // it fall through and surface as a confusing "invalid field value" error.
58
+ const unknownFlag = args.find((a) => a.startsWith('--'));
55
59
  const pattern = args.length === 1 ? args[0] : args;
56
60
  const requested = code || 'en';
57
61
 
@@ -59,6 +63,11 @@ if (missingLang) {
59
63
  console.error('Missing language value for --lang');
60
64
  process.exitCode = 1;
61
65
  }
66
+ else if (unknownFlag) {
67
+ console.error('Unknown option: ' + unknownFlag +
68
+ ' (valid options: --lang, --fragment)');
69
+ process.exitCode = 1;
70
+ }
62
71
  else if (availableLanguages().includes(requested)) {
63
72
  emit(pattern, (await import('./dist/lang/' + requested + '.js')).default);
64
73
  }
package/cronli5.min.js CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";(()=>{var qn={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6},Vn={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},p={second:{cyclic:!0,max:59,min:0,top:59},minute:{cyclic:!0,max:59,min:0,top:59},hour:{cyclic:!0,max:23,min:0,top:23},date:{aliases:{"?":"*"},cyclic:!0,max:31,min:1,top:31},month:{cyclic:!0,max:12,min:1,numbers:Vn,top:12},weekday:{aliases:{"?":"*",L:"6"},cyclic:!0,max:7,min:0,numbers:qn,top:6},year:{max:9999,min:1970}},O=["second","minute","hour","date","month","weekday","year"],U={"@annually":"0 0 1 1 *","@yearly":"0 0 1 1 *","@monthly":"0 0 1 * *","@weekly":"0 0 * * 0","@daily":"0 0 * * *","@midnight":"0 0 * * *","@hourly":"0 * * * *"},Q=6;function s(n,e){return(""+n).indexOf(e)!==-1}function T(n){return Array.from(new Set(n))}function I(n){return/^\d+$/.test(n)}function d(n,e){return I(n)?+n:e[n.toUpperCase()]}function sn(n){return O.forEach(function(r){Jn(n[r],p[r],r)}),n}function Jn(n,e,r){typeof n!="string"&&typeof n!="number"&&un(n,r);let t=""+n;t!=="*"&&(r==="date"&&v(t)||r==="weekday"&&w(t,e)||t.split(",").forEach(function(o){$n(o,e)||un(o,r)}))}function v(n){if(n==="L"||n==="LW"||n==="WL")return!0;let e=/^L-(\d{1,2})$/.exec(n);if(e)return+e[1]>=1&&+e[1]<=30;let r=/^(\d{1,2})W$|^W(\d{1,2})$/.exec(n);if(r){let t=+(r[1]||r[2]);return t>=1&&t<=31}return!1}function w(n,e){if(/L$/.test(n))return C(n.slice(0,-1),e);let r=n.split("#");return r.length===2?C(r[0],e)&&/^[1-5]$/.test(r[1]):!1}function $n(n,e){return s(n,"/")?Yn(n,e):s(n,"-")?an(n,e):C(n,e)}function Yn(n,e){let r=n.split("/");return r.length!==2||!I(r[1])||+r[1]<1?!1:r[0]==="*"||C(r[0],e)||an(r[0],e,!0)}function an(n,e,r){let t=n.split("-");return t.length!==2||!C(t[0],e)||!C(t[1],e)?!1:e.cyclic&&!r?!0:d(t[0],e.numbers)<=d(t[1],e.numbers)}function C(n,e){return n==="*"?!1:I(n)?+n>=e.min&&+n<=e.max:e.numbers?n.toUpperCase()in e.numbers:!1}function un(n,e){throw new Error('`cronli5` was passed an invalid field value "'+n+'" for the '+e+" field.")}var Bn={hour:24,minute:60,second:60};function cn(n){O.forEach(function(r){let t=p[r].aliases,i=t&&t[""+n[r]];i&&(n[r]=i)})}function mn(n){return O.forEach(function(r){let t=""+n[r];if(r==="date"&&v(t)||r==="weekday"&&w(t,p[r])){n[r]=t;return}n[r]=Gn(t,r,p[r])}),n}function Gn(n,e,r){let t=""+n;if(t==="*")return t;let i=Bn[e],o=t.split(",").map(function(a){return Xn(_n(Zn(Kn(a,r),r),r),r,i)}).join(",").split(",");return o.indexOf("*")!==-1?"*":T(o).sort(function(a,c){return ln(a,r)-ln(c,r)}).join(",")}function Kn(n,e){let r=n.split("/");if(!e.cyclic||r.length!==2||+r[1]!=1)return n;let t=r[0];return s(t,"-")?t:t==="*"||d(t,e.numbers)===e.min?"*":t+"-"+e.top}function Zn(n,e){let r=n.split("/");if(!e.cyclic||typeof e.top!="number"||r.length!==2||s(r[0],"-"))return n;let t=r[0];return(t==="*"?e.min:d(t,e.numbers))+ +r[1]<=e.top?n:t==="*"?""+e.min:t}function Xn(n,e,r){let t=n.split("/");if(typeof r!="number"||t.length!==2||s(t[0],"-"))return n;let i=+t[1],o=t[0]==="*"?e.min:d(t[0]);if(r%i===0&&o<i)return n;let u=[];for(let a=o;a<=e.top;a+=i)u.push(a);return u.join(",")}function _n(n,e){let r=n.split("/")[0];if(!s(r,"-"))return n;let t=r.split("-");return d(t[0],e.numbers)!==d(t[1],e.numbers)?n:t[0]}function ln(n,e){let r=n.split("/")[0].split("-")[0];return r==="*"?e.min:d(r,e.numbers)}function dn(n,e){let r=n instanceof Array;if(n===null||typeof n>"u"||n===""||r&&n.length===0)throw new Error("`cronli5` expects a non-empty cron pattern as the first argument.");if(r)return fn(n,e);if(typeof n=="object")return ne(n);if(typeof n=="string")return ee(n,e);throw new Error("`cronli5` was passed an unexpected type.")}function fn(n,e){if(n.length>7)throw new Error("`cronli5` was passed a cron pattern with more than seven fields.");return!e.seconds&&n.length<(e.years?7:6)&&n.unshift("0"),{second:n[0]||"0",minute:n[1]||"*",hour:n[2]||"*",date:n[3]||"*",month:n[4]||"*",weekday:n[5]||"*",year:n[6]||"*"}}function ne(n){if(!n.second&&!n.minute&&!n.hour)throw new Error("`cronli5` expects that any object being interpreted as a cron pattern have at least one of the following properties: `second`, `minute`, or `hour`");let e=typeof n.second<"u",r=typeof n.minute<"u",t=e?"*":"0",i=e||r?"*":"0";return{second:k(n.second,"0"),minute:k(n.minute,t),hour:k(n.hour,i),date:k(n.date,"*"),month:k(n.month,"*"),weekday:k(n.weekday,"*"),year:k(n.year,"*")}}function k(n,e){return typeof n>"u"?e:n}function ee(n,e){let r=re(n).split(/\s+/);return fn(r,e)}function re(n){let e=n.trim();if(e.charAt(0)!=="@")return n;let r=e.toLowerCase();if(Object.hasOwn(U,r))return U[r];throw new Error("`cronli5` does not recognize the macro `"+e+"`.")}function gn(n){return n!=="*"&&!s(n,",")&&!s(n,"-")&&!s(n,"/")}function q(n){return s(n,"-")&&!s(n,",")&&!s(n,"/")}function te(n){return s(n,"/")&&!s(n,",")}function V(n){return n!=="*"&&!s(n,"-")&&!s(n,"/")}function J(n){return n!=="*"&&!q(n)&&!te(n)}function R(n,e,r){let t=[],i=n;for(;i<=r;)t.push(i),i+=e;return t}function pn(n,e,r,t){let i=n.split("/"),o=+i[1];if(s(i[0],"-")){let a=i[0].split("-");return R(d(a[0],t),o,d(a[1],t))}let u=i[0]==="*"?e:d(i[0],t);return R(u,o,r)}function $(n,e,r){let t=[];return n.split(",").forEach(function(o){if(s(o,"/"))t.push(...pn(o,e,r));else if(s(o,"-")){let u=o.split("-");+u[0]<=+u[1]?t.push(...R(+u[0],1,+u[1])):(t.push(...R(+u[0],1,r)),t.push(...R(e,1,+u[1])))}else t.push(+o)}),T(t)}function ie(n){return V(n)?n.split(",").map(Number):[0]}function oe(n){if(n==="*")return[0,59];if(q(n)){let e=n.split("-");if(+e[0]<=+e[1])return[+e[0],+e[1]]}return null}function ue(n){return n==="*"?59:Math.max(...$(n,0,59))}function se(n){if(gn(n)&&n!=="0")return+n}function ae(n,e){return n==="*"?"wildcard":e==="date"&&v(n)||e==="weekday"&&w(n,p.weekday)?"quartz":s(n,",")?"list":s(n,"/")?"step":s(n,"-")?"range":"single"}function le(n,e,r){return e==="wildcard"||e==="quartz"?null:n.split(",").map(function(i){if(s(i,"/")){let o=i.split("/");return{fires:pn(i,r.min,r.top,r.numbers),interval:+o[1],kind:"step",startToken:o[0]}}return s(i,"-")?{bounds:i.split("-"),kind:"range"}:{kind:"single",value:i}})}function hn(n){let e={},r={};O.forEach(function(u){e[u]=ae(n[u],u),r[u]=le(n[u],e[u],p[u])});let i={analyses:{clockSecond:se(n.second),lastMinuteFire:ue(n.minute),minuteSpan:oe(n.minute),segments:r},pattern:n,shapes:e};return{...i,plan:ce(i)}}function ce(n){let{analyses:e,pattern:r,shapes:t}=n;if(r.second!=="0"){let i=me(r,t,e);if(i)return i}return yn(r,t,e)||Sn(r,t,e)}function me(n,e,r){let t=de(n,e);return t||(n.hour==="*"&&e.minute==="single"&&n.second!=="*"?{kind:"secondsWithinMinute",singleSecond:e.second==="single"}:e.second==="single"&&V(n.minute)&&J(n.hour)?null:{kind:"composeSeconds",rest:yn(n,e,r,!0)||Sn(n,e,r,!0)})}function de(n,e){return n.minute!=="*"||n.hour!=="*"?null:n.second==="*"?{kind:"everySecond"}:e.second==="single"?{kind:"secondPastMinute"}:{kind:"standaloneSeconds"}}function yn(n,e,r,t=!1){if(e.minute==="step")return{hours:ge(n,e,r),kind:"minuteFrequency"};if(e.hour==="single"&&r.minuteSpan)return{hour:+n.hour,kind:"minuteSpanInHour",span:r.minuteSpan};let i=pe(n,e);if(i)return i;let o=fe(n,e);if(o)return o;if(n.hour==="*")return he(n,e,t)}function bn(n){let[e,r]=n.split("/"),t=e==="*"?0:+e;return e.indexOf("-")===-1&&24%+r===0&&t<+r}function fe(n,e){return e.hour!=="step"?null:n.minute==="*"?bn(n.hour)?{form:"wildcard",kind:"minuteSpanAcrossHourStep"}:{form:"wildcard",kind:"minutesAcrossHours",times:M(n.hour)}:e.minute==="range"?{form:"range",kind:"minuteSpanAcrossHourStep"}:null}function ge(n,e,r){if(e.hour==="list")return{kind:"during",times:M(n.hour)};if(e.hour==="range"){let t=n.hour.split("-");return{from:+t[0],kind:"window",last:r.lastMinuteFire,to:+t[1]}}return e.hour==="single"?{from:+n.hour,kind:"window",last:r.lastMinuteFire,to:+n.hour}:e.hour==="step"?bn(n.hour)?{kind:"step"}:{kind:"during",times:M(n.hour)}:{kind:"none"}}function pe(n,e){return J(n.hour)?n.minute==="*"?{form:"wildcard",kind:"minutesAcrossHours",times:M(n.hour)}:e.minute==="range"||e.minute==="list"&&s(n.minute,"-")&&!s(n.minute,"/")?{form:e.minute==="range"?"range":"list",kind:"minutesAcrossHours",times:M(n.hour)}:null:null}function he(n,e,r){if(e.minute==="range")return{kind:"rangeOfMinutes"};if(e.minute==="list")return{kind:"multipleMinutes"};if(n.minute==="*")return{kind:"everyMinute"};if(n.minute!=="0"||r)return{kind:"singleMinute"}}function Sn(n,e,r,t=!1){let i=t&&n.minute==="0";return e.hour==="range"&&!i?ye(n,e,r):e.hour==="step"&&n.minute==="0"&&!t?{kind:"hourStep"}:n.hour==="*"&&!i?{kind:"everyHour"}:be(n,r,i)}function ye(n,e,r){let t=n.hour.split("-"),i="lead";return n.minute==="*"?i="wildcard":e.minute==="range"&&(i="range"),{boundMinute:e.minute==="range"||e.minute==="list"?null:r.lastMinuteFire,from:+t[0],kind:"hourRange",last:r.lastMinuteFire,minuteForm:i,to:+t[1]}}function be(n,e,r=!1){let t=$(n.hour,0,23),i=ie(n.minute);if(!r&&t.length*i.length>Q)return{fold:i.length===1,kind:"compactClockTimes",minute:i[0]};let o=[];return t.forEach(function(a){i.forEach(function(j){o.push({hour:a,minute:j,second:e.clockSecond})})}),{kind:"clockTimes",times:o}}function M(n){let e=$(n,0,23);return e.length<=Q?{fires:e,kind:"fires"}:{kind:"segments"}}function On(n,e){let r=dn(n,e);return cn(r),sn(r),mn(r)}function Y(n){return n=""+n,n.length<2?"0"+n:n}function kn(n,e,r){return r.short?n:e[n]||n}function B(n,{sep:e,pad:r,lean:t}){let i=r?Y(n.hour):""+n.hour;return t&&!n.minute&&!n.second?i:i+e+Y(n.minute)+(n.second?e+Y(n.second):"")}var G={gb:{am:"am",closeUp:!0,dayFirst:!0,midday:"midday",midnight:"midnight",ordinals:!1,pm:"pm",sep:".",serialComma:!1,through:" to "},us:{am:"a.m.",closeUp:!1,dayFirst:!1,midday:"noon",midnight:"midnight",ordinals:!1,pm:"p.m.",sep:":",serialComma:!0,through:" through "},house:{am:"AM",closeUp:!1,dayFirst:!1,midday:"noon",midnight:"midnight",ordinals:!0,pm:"PM",sep:":",serialComma:!0,through:" - "}};function Nn(n){return typeof n=="object"&&n!==null?{...G.us,...n}:G[n==="uk"?"gb":n]||G.us}var Se=["zero","one","two","three","four","five","six","seven","eight","nine","ten"],K=["th","st","nd","rd"],f=[null,["January","Jan"],["February","Feb"],["March","Mar"],["April","Apr"],["May","May"],["June","Jun"],["July","Jul"],["August","Aug"],["September","Sep"],["October","Oct"],["November","Nov"],["December","Dec"]],y=[["Sunday","Sun"],["Monday","Mon"],["Tuesday","Tue"],["Wednesday","Wed"],["Thursday","Thu"],["Friday","Fri"],["Saturday","Sat"]],Oe={JAN:f[1],FEB:f[2],MAR:f[3],APR:f[4],MAY:f[5],JUN:f[6],JUL:f[7],AUG:f[8],SEP:f[9],OCT:f[10],NOV:f[11],DEC:f[12]},ke={SUN:y[0],MON:y[1],TUE:y[2],WED:y[3],THU:y[4],FRI:y[5],SAT:y[6]},Ne=[null,"first","second","third","fourth","fifth"];function ze(n){return n=n||{},{ampm:typeof n.ampm=="boolean"?n.ampm:!0,lenient:!!n.lenient,seconds:!!n.seconds,short:!!n.short,style:Nn(n.dialect),years:!!n.years}}function Pe(n,e){return er(Pn(n,n.plan,e),n,e)}function Pn(n,e,r){let t=$e[e.kind];return t(n,e,r)}function Ce(n,e,r){return"every second"+l(n,r)}function ve(n,e,r){return H(n,r)+l(n,r)}function we(n,e,r){let t=n.pattern.second;return g(t,r)+" "+P(t,"second")+" past the minute, every minute"+l(n,r)}function Re(n,e,r){let t=n.pattern.minute,i=g(t,r),o=P(t,"minute");if(e.singleSecond){let u=n.pattern.second;return i+" "+o+" and "+g(u,r)+" "+P(u,"second")+" past the hour, every hour"+l(n,r)}return H(n,r)+", "+i+" "+o+" past the hour, every hour"+l(n,r)}function Me(n,e,r){return H(n,r)+", "+Pn(n,e.rest,r)}function H(n,e){let r=n.pattern.second,t=n.shapes.second;if(r==="*")return"every second";if(t==="step")return Rn(n.analyses.segments.second[0],"second","minute",e);if(t==="range"){let i=r.split("-"),o=A(i,e);return"every second from "+o(i[0])+S(e)+o(i[1])+" past the minute"}return t==="single"?"at "+g(r,e)+" "+P(r,"second")+" past the minute":z(F(n.analyses.segments.second,e),"second","minute",e)}function xe(n,e,r){return"every minute"+l(n,r)}function Fe(n,e,r){let t=n.pattern.minute;return g(t,r)+" "+P(t,"minute")+" past the hour, every hour"+l(n,r)}function Te(n,e,r){return L(n.pattern.minute,r)+l(n,r)}function Ie(n,e,r){return z(F(n.analyses.segments.minute,r),"minute","hour",r)+l(n,r)}function He(n,e,r){let t=Rn(n.analyses.segments.minute[0],"minute","hour",r);return e.hours.kind==="during"?t+=" during the "+X(n,e.hours.times,!1,r)+" hours":e.hours.kind==="window"?t+=" "+wn(e.hours,r):e.hours.kind==="step"&&(t+=" "+Cn(n.analyses.segments.hour[0],r)),t+l(n,r)}function Le(n,e,r){return"every minute from "+m({hour:e.hour,minute:e.span[0]},r)+S(r)+m({hour:e.hour,minute:e.span[1]},r)+l(n,r)}function Ae(n,e,r){if(e.form==="wildcard")return"every minute during the "+X(n,e.times,!1,r)+" hours"+l(n,r);let t=X(n,e.times,!0,r);return(e.form==="range"?L(n.pattern.minute,r):z(F(n.analyses.segments.minute,r),"minute","hour",r))+", at "+t+l(n,r)}var Ee={2:"other",3:"third",4:"fourth",6:"sixth",8:"eighth",12:"twelfth"};function Cn(n,e){let r="during every "+Ee[n.interval]+" hour",t=n.startToken==="*"?0:+n.startToken;return t===0?r:r+" starting at "+m({hour:t,minute:0},e)}function We(n,e,r){let t=n.analyses.segments.hour[0];return e.form==="wildcard"?"every minute "+Cn(t,r)+l(n,r):L(n.pattern.minute,r)+", "+Mn(t,r)+l(n,r)}function L(n,e){let r=n.split("-"),t=A(r,e);return"every minute from "+t(r[0])+S(e)+t(r[1])+" past the hour"}function je(n,e,r){return"every hour"+l(n,r)}function De(n,e,r){let t=wn(Qe(e),r);return e.minuteForm==="wildcard"?"every minute "+t+l(n,r):e.minuteForm==="range"?L(n.pattern.minute,r)+", "+t+l(n,r):vn(n,r)+" "+t+l(n,r)}function vn(n,e){return n.pattern.minute==="0"?"every hour":z(F(n.analyses.segments.minute,e),"minute","hour",e)}function Ue(n,e,r){return Mn(n.analyses.segments.hour[0],r)+l(n,r)}function Qe(n){return{from:n.from,last:n.boundMinute??0,to:n.to}}function wn(n,e){return"from "+m({hour:n.from,minute:0},e)+S(e)+m({hour:n.to,minute:n.last},e)}function qe(n,e,r){let t=rn(e.times),i=e.times.map(function(u){return m({hour:u.hour,minute:u.minute,second:u.second,plain:t},r)});return xn(n,r)+"at "+b(i,r)}function Ve(n,e,r){if(e.fold){if(n.analyses.segments.hour.some(function(a){return a.kind==="range"})&&!n.analyses.clockSecond)return Je(n,e,r)+l(n,r);let o={minute:e.minute,second:n.analyses.clockSecond};return xn(n,r)+"at "+_(n,o,!0,r)}let t=z(F(n.analyses.segments.minute,r),"minute","hour",r)+", at "+_(n,{minute:0,second:null},!0,r)+l(n,r);return n.analyses.clockSecond?H(n,r)+", "+t:t}function Je(n,e,r){let t=e.minute,i=[],o=[];n.analyses.segments.hour.forEach(function(c){c.kind==="range"?i.push("from "+m({hour:c.bounds[0],minute:0},r)+S(r)+m({hour:c.bounds[1],minute:t},r)):c.kind==="step"?o.push(...c.fires):o.push(+c.value)});let u=vn(n,r)+" "+b(i,r);return o.length&&(u+=" and at "+b(o.map(function(c){return m({hour:c,minute:t},r)}),r)),u}var $e={clockTimes:qe,compactClockTimes:Ve,composeSeconds:Me,everyHour:je,everyMinute:xe,everySecond:Ce,hourRange:De,hourStep:Ue,minuteFrequency:He,minuteSpanAcrossHourStep:We,minuteSpanInHour:Le,minutesAcrossHours:Ae,multipleMinutes:Ie,rangeOfMinutes:Te,secondPastMinute:we,secondsWithinMinute:Re,singleMinute:Fe,standaloneSeconds:ve};function Rn(n,e,r,t){if(n.startToken.indexOf("-")!==-1)return z(zn(n.fires,t),e,r,t);let i=n.startToken==="*"?0:+n.startToken,o=n.interval;return i!==0?n.fires.length<=3?z(zn(n.fires,t),e,r,t):"every "+g(o,t)+" "+e+"s from "+g(i,t)+" "+P(i,e)+" past the "+r:"every "+g(o,t)+" "+e+"s"}function Mn(n,e){if(n.startToken.indexOf("-")!==-1)return"at "+Z(n.fires,e);let r=n.startToken==="*"?0:+n.startToken,t=n.interval;return r===0?"every "+g(t,e)+" hours":n.fires.length<=3?"at "+Z(n.fires,e):"every "+g(t,e)+" hours from "+m({hour:r,minute:0},e)}function A(n,e){let r=n.some(function(i){return+i>10});return function(i){return r?""+i:g(i,e)}}function zn(n,e){return n.map(A(n,e))}function F(n,e){let r=n.flatMap(function(o){return o.kind==="range"?o.bounds:o.kind==="step"?o.fires:[o.value]}),t=A(r,e);return n.flatMap(function(o){return o.kind==="range"?[t(o.bounds[0])+S(e)+t(o.bounds[1])]:o.kind==="step"?o.fires.map(t):[t(o.value)]})}function z(n,e,r,t){return"at "+b(n,t)+" "+e+"s past the "+r}function Ye(n,e,r){return(+n==0||+n==12)&&+e==0&&!(typeof r=="number"&&r>0)}function rn(n){let e=n.filter(function(t){return Ye(t.hour,t.minute,t.second)});return e.length>0&&e.length<n.length}function Z(n,e){let r=rn(n.map(function(o){return{hour:o,minute:0}})),t=n.map(function(o){return m({hour:o,minute:0,plain:r},e)});return b(t,e)}function X(n,e,r,t){return e.kind==="fires"?Z(e.fires,t):_(n,{minute:0,second:null},r,t)}function Be(n){return n.kind==="range"?n.bounds:n.kind==="step"?n.fires:[n.value]}function _(n,e,r,t){let{minute:i,second:o}=e,u=n.analyses.segments.hour,a=rn(u.flatMap(function(h){return Be(h).map(function(D){return{hour:+D,minute:i,second:o}})})),c=[];return u.forEach(function(h){h.kind==="step"?c.push(...h.fires.map(function(D){return m({hour:D,minute:i,second:o,plain:a},t)})):h.kind==="range"?c.push(m({hour:h.bounds[0],minute:i,second:o,plain:a},t)+S(t)+m({hour:h.bounds[1],minute:i,second:o,plain:a},t)):c.push(m({hour:h.value,minute:i,second:o,plain:a},t))}),b(Ge(c,u,r),t)}function Ge(n,e,r){let t=e.some(function(o){return o.kind==="range"});return!r||!t?n:n.map(function(o,u){return u===0?o:"at "+o})}function b(n,e){if(n.length<=1)return n.join("");if(n.length===2)return n[0]+" and "+n[1];let r=e.style.serialComma?", and ":" and ";return n.slice(0,-1).join(", ")+r+n[n.length-1]}var Ke={all:"",month:"in ",stepDate:"on ",weekday:"on "},Ze={all:"every day",month:"every day in ",stepDate:"",weekday:"every "};function l(n,e){let r=Fn(n,Ke,e);return r&&" "+r}function xn(n,e){return Fn(n,Ze,e)+" "}function Fn(n,e,r){let t=n.pattern;return t.date!=="*"&&t.weekday!=="*"?_e(n,r):t.date!=="*"?Xe(n,e,r):t.weekday!=="*"?(Hn(t.weekday,r)||e.weekday+Wn(n,r))+N(n,r):t.month!=="*"?e.month+E(n,r):e.all}function Xe(n,e,r){let t=n.pattern,i=In(t.date,r);return i?i+N(n,r):tn(t.date)?e.stepDate+An(t.date)+N(n,r):t.month!=="*"&&!Tn(n)?"on the "+nn(n,r)+N(n,r):t.month!=="*"?"on "+Ln(n,r):"on the "+nn(n,r)}function Tn(n){return!En(n.pattern.month)&&n.analyses.segments.month.every(function(r){return r.kind!=="range"})}function _e(n,e){let r=n.pattern,t=Hn(r.weekday,e)||"on "+Wn(n,e),i=In(r.date,e);return i?i+N(n,e)+" or "+t:tn(r.date)?An(r.date)+N(n,e)+" or "+t:r.month!=="*"&&Tn(n)?"on "+Ln(n,e)+" or "+t+" in "+E(n,e):"on the "+nn(n,e)+" or "+t+N(n,e)}function In(n,e){if(n==="L")return"on the last day of the month";if(n==="LW"||n==="WL")return"on the last weekday of the month";let r=/^L-(\d{1,2})$/.exec(n);if(r)return g(+r[1],e)+" "+P(r[1],"day")+" before the last day of the month";let t=/^(\d{1,2})W$|^W(\d{1,2})$/.exec(n);if(t)return"on the weekday nearest the "+x(t[1]||t[2])}function Hn(n,e){let r=n.split("#");if(r.length===2)return"on the "+Ne[+r[1]]+" "+en(r[0],e)+" of the month";if(/L$/.test(n))return"on the last "+en(n.slice(0,-1),e)+" of the month"}function Ln(n,e){let r=E(n,e),t=W(n.analyses.segments.date,e.style.ordinals?x:nr,e);return e.style.dayFirst?t+" "+r:r+" "+t}function nr(n){return""+n}function N(n,e){return n.pattern.month==="*"?"":" in "+E(n,e)}function An(n){let e=n.split("/"),r=+e[1],t=e[0],o=(r===2?"every other":"every "+x(r))+" day of the month";return t!=="*"&&t!=="1"&&(o+=" from the "+x(t)),o}function nn(n,e){return W(n.analyses.segments.date,x,e)}function E(n,e){let r=En(n.pattern.month);return r||W(n.analyses.segments.month,function(i){return or(i,e)},e)}function En(n){if(!tn(n))return null;let[e,r]=n.split("/");return+r!=2?null:e==="*"||e==="1"?"every odd-numbered month":e==="2"?"every even-numbered month":null}function Wn(n,e){return W(n.analyses.segments.weekday,function(t){return en(t,e)},e)}function W(n,e,r){let t=[];return n.forEach(function(o){o.kind==="step"?t.push(...o.fires.map(e)):o.kind==="range"?t.push(o.bounds.map(e).join(S(r))):t.push(e(o.value))}),b(t,r)}function tn(n){return n.indexOf("/")!==-1&&n.indexOf("-")===-1&&n.indexOf(",")===-1}function er(n,e,r){let t=e.pattern.year;if(t==="*")return n;if(t.indexOf("/")!==-1)return n+" "+tr(t,r);let i=rr(t,r);if(t.indexOf("-")===-1&&t.indexOf(",")===-1&&e.pattern.date!=="*"&&n.indexOf(" at ")!==-1){let o=r.style.dayFirst?" ":", ";return n.replace(" at ",o+i+" at ")}return n+" in "+i}function rr(n,e){return n.indexOf(",")!==-1?b(n.split(","),e):n}function tr(n,e){let r=n.split("/"),t=+r[1],i=r[0];if(t<=1)return"every year";let o="every "+g(t,e)+" years";return i!=="*"&&i!=="0"&&(o+=" from "+i),o}function m(n,e){let{hour:r,minute:t,plain:i}=n,o=typeof n.second=="number"&&n.second>0?n.second:0;return e.ampm?ir({hour:r,minute:t,second:o,plain:i},e):B({hour:r,minute:t,second:o},{pad:!0,sep:e.style.sep})}function ir(n,e){let{hour:r,minute:t,second:i,plain:o}=n,u=e.style;if(!o&&+t==0&&!i){if(+r==0)return u.midnight;if(+r==12)return u.midday}return B({hour:r%12||12,minute:t,second:i},{lean:!0,sep:u.sep})+(u.closeUp?"":" ")+(r<12?u.am:u.pm)}function g(n,e){return kn(n,Se,e)}function P(n,e){return+n==1?e:e+"s"}function S(n){return n.short?"-":n.style.through}function x(n){let e=Math.abs(n),r=K[e];return r||(e=(e%100-20)%10,r=K[e]||K[0]),n+r}function or(n,e){let r=f[n]||Oe[n];return r&&r[e.short?1:0]}function en(n,e){let r=n===7||n==="7"?0:n,t=y[r]||ke[r];return t&&t[e.short?1:0]}var ur={describe:Pe,fallback:"an unrecognizable cron pattern",options:ze,reboot:"at system startup",sentence:n=>"Runs "+n+"."},jn=ur;/**
1
+ "use strict";(()=>{var Vn={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6},$n={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},h={second:{cyclic:!0,max:59,min:0,top:59},minute:{cyclic:!0,max:59,min:0,top:59},hour:{cyclic:!0,max:23,min:0,top:23},date:{aliases:{"?":"*"},cyclic:!0,max:31,min:1,top:31},month:{cyclic:!0,max:12,min:1,numbers:$n,top:12},weekday:{aliases:{"?":"*",L:"6"},cyclic:!0,max:7,min:0,numbers:Vn,top:6},year:{max:9999,min:1970}},S=["second","minute","hour","date","month","weekday","year"],U={"@annually":"0 0 1 1 *","@yearly":"0 0 1 1 *","@monthly":"0 0 1 * *","@weekly":"0 0 * * 0","@daily":"0 0 * * *","@midnight":"0 0 * * *","@hourly":"0 * * * *"},Q=6;function a(n,e){return(""+n).indexOf(e)!==-1}function T(n){return Array.from(new Set(n))}function I(n){return/^\d+$/.test(n)}function f(n,e){return I(n)?+n:e[n.toUpperCase()]}function an(n){return S.forEach(function(r){Jn(n[r],h[r],r)}),n}function Jn(n,e,r){typeof n!="string"&&typeof n!="number"&&sn(n,r);let t=""+n;t!=="*"&&(r==="date"&&w(t)||r==="weekday"&&R(t,e)||t.split(",").forEach(function(o){Yn(o,e)||sn(o,r)}))}function w(n){if(n==="L"||n==="LW"||n==="WL")return!0;let e=/^L-(\d{1,2})$/.exec(n);if(e)return+e[1]>=1&&+e[1]<=30;let r=/^(\d{1,2})W$|^W(\d{1,2})$/.exec(n);if(r){let t=+(r[1]||r[2]);return t>=1&&t<=31}return!1}function R(n,e){if(/L$/.test(n))return P(n.slice(0,-1),e);let r=n.split("#");return r.length===2?P(r[0],e)&&/^[1-5]$/.test(r[1]):!1}function Yn(n,e){return a(n,"/")?Bn(n,e):a(n,"-")?ln(n,e):P(n,e)}function Bn(n,e){let r=n.split("/");return r.length!==2||!I(r[1])||+r[1]<1?!1:r[0]==="*"||P(r[0],e)||ln(r[0],e,!0)}function ln(n,e,r){let t=n.split("-");return t.length!==2||!P(t[0],e)||!P(t[1],e)?!1:e.cyclic&&!r?!0:f(t[0],e.numbers)<=f(t[1],e.numbers)}function P(n,e){return n==="*"?!1:I(n)?+n>=e.min&&+n<=e.max:e.numbers?n.toUpperCase()in e.numbers:!1}function sn(n,e){throw new Error('`cronli5` was passed an invalid field value "'+n+'" for the '+e+" field.")}var Gn={hour:24,minute:60,second:60};function mn(n){S.forEach(function(r){let t=h[r].aliases,i=t&&t[""+n[r]];i&&(n[r]=i)})}function fn(n){return S.forEach(function(r){let t=""+n[r];if(r==="date"&&w(t)||r==="weekday"&&R(t,h[r])){n[r]=t;return}n[r]=Kn(t,r,h[r])}),n}function Kn(n,e,r){let t=""+n;if(t==="*")return t;let i=Gn[e],o=t.split(",").map(function(s){return Zn(dn(ee(re(te(ne(_n(s,r),r),r),r),r,i),r),r)}).join(",").split(",");return o.indexOf("*")!==-1?"*":T(o).sort(function(s,m){return cn(s,r)-cn(m,r)}).join(",")}function Zn(n,e){if(!e.numbers)return n;let r=n.split("/"),t=r[0].split("-").map(function(o){return Xn(o,e)}).join("-");return r.length===2?t+"/"+r[1]:t}function Xn(n,e){if(n==="*")return n;let r=f(n,e.numbers);return""+(r>e.top?e.min:r)}function _n(n,e){let r=n.split("/");if(!e.cyclic||r.length!==2||+r[1]!=1)return n;let t=r[0];return a(t,"-")?t:t==="*"||f(t,e.numbers)===e.min?"*":t+"-"+e.top}function ne(n,e){let r=n.split("/");if(!e.cyclic||typeof e.top!="number"||r.length!==2||a(r[0],"-"))return n;let t=r[0];return(t==="*"?e.min:f(t,e.numbers))+ +r[1]<=e.top?n:t==="*"?""+e.min:t}function ee(n,e,r){let t=n.split("/");if(typeof r!="number"||t.length!==2||a(t[0],"-"))return n;let i=+t[1],o=t[0]==="*"?e.min:f(t[0]);if(r%i===0&&o<i)return n;let u=[];for(let s=o;s<=e.top;s+=i)u.push(s);return u.join(",")}function re(n,e){let r=n.split("/");return r.length!==2||!a(r[0],"-")?n:dn(r[0],e)==="*"?"*/"+r[1]:n}function dn(n,e){if(typeof e.top!="number"||a(n,"/")||!a(n,"-"))return n;let r=n.split("-"),t=f(r[0],e.numbers),i=f(r[1],e.numbers);if(t>i)return n;let o=e.top,u={};for(let s=t;s<=i;s+=1)u[s>o?e.min:s]=!0;for(let s=e.min;s<=o;s+=1)if(!u[s])return n;return"*"}function te(n,e){let r=n.split("/")[0];if(!a(r,"-"))return n;let t=r.split("-");return f(t[0],e.numbers)!==f(t[1],e.numbers)?n:t[0]}function cn(n,e){let r=n.split("/")[0].split("-")[0];return r==="*"?e.min:f(r,e.numbers)}function gn(n,e){let r=n instanceof Array;if(n===null||typeof n>"u"||n===""||r&&n.length===0)throw new Error("`cronli5` expects a non-empty cron pattern as the first argument.");if(r)return hn(n,e);if(typeof n=="object")return ie(n);if(typeof n=="string")return oe(n,e);throw new Error("`cronli5` was passed an unexpected type.")}function hn(n,e){if(n.length>7)throw new Error("`cronli5` was passed a cron pattern with more than seven fields.");return!e.seconds&&n.length<(e.years?7:6)&&n.unshift("0"),{second:n[0]||"0",minute:n[1]||"*",hour:n[2]||"*",date:n[3]||"*",month:n[4]||"*",weekday:n[5]||"*",year:n[6]||"*"}}function ie(n){if(!n.second&&!n.minute&&!n.hour)throw new Error("`cronli5` expects that any object being interpreted as a cron pattern have at least one of the following properties: `second`, `minute`, or `hour`");let e=typeof n.second<"u",r=typeof n.minute<"u",t=e?"*":"0",i=e||r?"*":"0";return{second:O(n.second,"0"),minute:O(n.minute,t),hour:O(n.hour,i),date:O(n.date,"*"),month:O(n.month,"*"),weekday:O(n.weekday,"*"),year:O(n.year,"*")}}function O(n,e){return typeof n>"u"?e:n}function oe(n,e){let r=ue(n).split(/\s+/);return hn(r,e)}function ue(n){let e=n.trim();if(e.charAt(0)!=="@")return n;let r=e.toLowerCase();if(Object.hasOwn(U,r))return U[r];throw new Error("`cronli5` does not recognize the macro `"+e+"`.")}function pn(n){return n!=="*"&&!a(n,",")&&!a(n,"-")&&!a(n,"/")}function q(n){return a(n,"-")&&!a(n,",")&&!a(n,"/")}function se(n){return a(n,"/")&&!a(n,",")}function V(n){return n!=="*"&&!a(n,"-")&&!a(n,"/")}function $(n){return n!=="*"&&!q(n)&&!se(n)}function C(n,e,r){let t=[],i=n;for(;i<=r;)t.push(i),i+=e;return t}function yn(n,e,r,t){let i=n.split("/"),o=+i[1];if(a(i[0],"-")){let s=i[0].split("-");return C(f(s[0],t),o,f(s[1],t))}let u=i[0]==="*"?e:f(i[0],t);return C(u,o,r)}function J(n,e,r){let t=[];return n.split(",").forEach(function(o){if(a(o,"/"))t.push(...yn(o,e,r));else if(a(o,"-")){let u=o.split("-");+u[0]<=+u[1]?t.push(...C(+u[0],1,+u[1])):(t.push(...C(+u[0],1,r)),t.push(...C(e,1,+u[1])))}else t.push(+o)}),T(t)}function ae(n){return V(n)?n.split(",").map(Number):[0]}function le(n){if(n==="*")return[0,59];if(q(n)){let e=n.split("-");if(+e[0]<=+e[1])return[+e[0],+e[1]]}return null}function ce(n){return n==="*"?59:Math.max(...J(n,0,59))}function me(n){if(pn(n)&&n!=="0")return+n}function fe(n,e){return n==="*"?"wildcard":e==="date"&&w(n)||e==="weekday"&&R(n,h.weekday)?"quartz":a(n,",")?"list":a(n,"/")?"step":a(n,"-")?"range":"single"}function de(n,e,r){return e==="wildcard"||e==="quartz"?null:n.split(",").map(function(i){if(a(i,"/")){let o=i.split("/");return{fires:yn(i,r.min,r.top,r.numbers),interval:+o[1],kind:"step",startToken:o[0]}}return a(i,"-")?{bounds:i.split("-"),kind:"range"}:{kind:"single",value:i}})}function bn(n){let e={},r={};S.forEach(function(u){e[u]=fe(n[u],u),r[u]=de(n[u],e[u],h[u])});let i={analyses:{clockSecond:me(n.second),lastMinuteFire:ce(n.minute),minuteSpan:le(n.minute),segments:r},pattern:n,shapes:e};return{...i,plan:ge(i)}}function ge(n){let{analyses:e,pattern:r,shapes:t}=n;if(r.second!=="0"){let i=he(r,t,e);if(i)return i}return Sn(r,t,e)||kn(r,t,e)}function he(n,e,r){let t=pe(n,e);return t||(n.hour==="*"&&e.minute==="single"&&n.second!=="*"?{kind:"secondsWithinMinute",singleSecond:e.second==="single"}:e.second==="single"&&V(n.minute)&&$(n.hour)?null:{kind:"composeSeconds",rest:Sn(n,e,r,!0)||kn(n,e,r,!0)})}function pe(n,e){return n.minute!=="*"||n.hour!=="*"?null:n.second==="*"?{kind:"everySecond"}:e.second==="single"?{kind:"secondPastMinute"}:{kind:"standaloneSeconds"}}function Sn(n,e,r,t=!1){if(e.minute==="step")return{hours:be(n,e,r),kind:"minuteFrequency"};if(e.hour==="single"&&r.minuteSpan)return{hour:+n.hour,kind:"minuteSpanInHour",span:r.minuteSpan};let i=Se(n,e);if(i)return i;let o=ye(n,e);if(o)return o;if(n.hour==="*")return Oe(n,e,t)}function On(n){let[e,r]=n.split("/"),t=e==="*"?0:+e;return e.indexOf("-")===-1&&24%+r===0&&t<+r}function ye(n,e){return e.hour!=="step"?null:n.minute==="*"?On(n.hour)?{form:"wildcard",kind:"minuteSpanAcrossHourStep"}:{form:"wildcard",kind:"minutesAcrossHours",times:x(n.hour)}:e.minute==="range"?{form:"range",kind:"minuteSpanAcrossHourStep"}:null}function be(n,e,r){if(e.hour==="list")return{kind:"during",times:x(n.hour)};if(e.hour==="range"){let t=n.hour.split("-");return{from:+t[0],kind:"window",last:r.lastMinuteFire,to:+t[1]}}return e.hour==="single"?{from:+n.hour,kind:"window",last:r.lastMinuteFire,to:+n.hour}:e.hour==="step"?On(n.hour)?{kind:"step"}:{kind:"during",times:x(n.hour)}:{kind:"none"}}function Se(n,e){return $(n.hour)?n.minute==="*"?{form:"wildcard",kind:"minutesAcrossHours",times:x(n.hour)}:e.minute==="range"||e.minute==="list"&&a(n.minute,"-")&&!a(n.minute,"/")?{form:e.minute==="range"?"range":"list",kind:"minutesAcrossHours",times:x(n.hour)}:null:null}function Oe(n,e,r){if(e.minute==="range")return{kind:"rangeOfMinutes"};if(e.minute==="list")return{kind:"multipleMinutes"};if(n.minute==="*")return{kind:"everyMinute"};if(n.minute!=="0"||r)return{kind:"singleMinute"}}function kn(n,e,r,t=!1){let i=t&&n.minute==="0";return e.hour==="range"&&!i?ke(n,e,r):e.hour==="step"&&n.minute==="0"&&!t?{kind:"hourStep"}:n.hour==="*"&&!i?{kind:"everyHour"}:Ne(n,r,i)}function ke(n,e,r){let t=n.hour.split("-"),i="lead";return n.minute==="*"?i="wildcard":e.minute==="range"&&(i="range"),{boundMinute:e.minute==="range"||e.minute==="list"?null:r.lastMinuteFire,from:+t[0],kind:"hourRange",last:r.lastMinuteFire,minuteForm:i,to:+t[1]}}function Ne(n,e,r=!1){let t=J(n.hour,0,23),i=ae(n.minute);if(!r&&t.length*i.length>Q)return{fold:i.length===1,kind:"compactClockTimes",minute:i[0]};let o=[];return t.forEach(function(s){i.forEach(function(A){o.push({hour:s,minute:A,second:e.clockSecond})})}),{kind:"clockTimes",times:o}}function x(n){let e=J(n,0,23);return e.length<=Q?{fires:e,kind:"fires"}:{kind:"segments"}}function Nn(n,e){let r=gn(n,e);return mn(r),an(r),fn(r)}function Y(n){return n=""+n,n.length<2?"0"+n:n}function zn(n,e,r){return r.short?n:e[n]||n}function B(n,{sep:e,pad:r,lean:t}){let i=r?Y(n.hour):""+n.hour;return t&&!n.minute&&!n.second?i:i+e+Y(n.minute)+(n.second?e+Y(n.second):"")}var G={gb:{am:"am",closeUp:!0,dayFirst:!0,midday:"midday",midnight:"midnight",ordinals:!1,pm:"pm",sep:".",serialComma:!1,through:" to "},us:{am:"a.m.",closeUp:!1,dayFirst:!1,midday:"noon",midnight:"midnight",ordinals:!1,pm:"p.m.",sep:":",serialComma:!0,through:" through "},house:{am:"AM",closeUp:!1,dayFirst:!1,midday:"noon",midnight:"midnight",ordinals:!0,pm:"PM",sep:":",serialComma:!0,through:" - "}};function Pn(n){return typeof n=="object"&&n!==null?{...G.us,...n}:G[n==="uk"?"gb":n]||G.us}var ze=["zero","one","two","three","four","five","six","seven","eight","nine","ten"],K=["th","st","nd","rd"],Pe=[null,["January","Jan"],["February","Feb"],["March","Mar"],["April","Apr"],["May","May"],["June","Jun"],["July","Jul"],["August","Aug"],["September","Sep"],["October","Oct"],["November","Nov"],["December","Dec"]],y=[["Sunday","Sun"],["Monday","Mon"],["Tuesday","Tue"],["Wednesday","Wed"],["Thursday","Thu"],["Friday","Fri"],["Saturday","Sat"]],ve={SUN:y[0],MON:y[1],TUE:y[2],WED:y[3],THU:y[4],FRI:y[5],SAT:y[6]},we=[null,"first","second","third","fourth","fifth"];function Re(n){return n=n||{},{ampm:typeof n.ampm=="boolean"?n.ampm:!0,lenient:!!n.lenient,seconds:!!n.seconds,short:!!n.short,style:Pn(n.dialect),years:!!n.years}}function Ce(n,e){return ur(wn(n,n.plan,e),n,e)}function wn(n,e,r){let t=Xe[e.kind];return t(n,e,r)}function xe(n,e,r){return"every second"+l(n,r)}function Fe(n,e,r){return v(n,r)+l(n,r)}function Me(n,e,r){let t=n.pattern.second;return d(t,r)+" "+z(t,"second")+" past the minute, every minute"+l(n,r)}function Te(n,e,r){let t=n.pattern.minute,i=d(t,r),o=z(t,"minute");if(e.singleSecond){let u=n.pattern.second;return i+" "+o+" and "+d(u,r)+" "+z(u,"second")+" past the hour, every hour"+l(n,r)}return v(n,r)+", "+i+" "+o+" past the hour, every hour"+l(n,r)}function Ie(n,e,r){return e.rest.kind==="clockTimes"&&(n.shapes.second==="wildcard"||n.shapes.second==="step")?+e.rest.times[0].minute==0?v(n,r)+" for one minute at "+He(n,e.rest,r):v(n,r)+" of "+Le(n,e.rest,r):n.shapes.second==="wildcard"&&e.rest.kind==="minuteFrequency"&&e.rest.hours.kind==="none"&&n.pattern.minute==="*/2"?"every second of every other minute"+l(n,r):v(n,r)+", "+wn(n,e.rest,r)}function He(n,e,r){let t=e.times.map(function(u){return c({hour:u.hour,minute:0},r)}),i=W(n,tn,r);return g(t,r)+(i&&", "+i)}function Le(n,e,r){let t=e.times.map(function(u){return c({hour:u.hour,minute:u.minute,second:u.second,explicit:!0},r)}),i=W(n,tn,r);return g(t,r)+(i&&", "+i)}function v(n,e){let r=n.pattern.second,t=n.shapes.second;if(r==="*")return"every second";if(t==="step")return Fn(n.analyses.segments.second[0],"second","minute",e);if(t==="range"){let i=r.split("-"),o=L(i,e);return"every second from "+o(i[0])+b(e)+o(i[1])+" past the minute"}return t==="single"?"at "+d(r,e)+" "+z(r,"second")+" past the minute":N(M(n.analyses.segments.second,e),"second","minute",e)}function We(n,e,r){return"every minute"+l(n,r)}function je(n,e,r){let t=n.pattern.minute;return d(t,r)+" "+z(t,"minute")+" past the hour, every hour"+l(n,r)}function Ee(n,e,r){return H(n.pattern.minute,r)+l(n,r)}function Ae(n,e,r){return N(M(n.analyses.segments.minute,r),"minute","hour",r)+l(n,r)}function De(n,e,r){let t=Fn(n.analyses.segments.minute[0],"minute","hour",r);return e.hours.kind==="during"?t+=" during the "+X(n,e.hours.times,!1,r)+" hours":e.hours.kind==="window"?t+=" "+xn(e.hours,r):e.hours.kind==="step"&&(t+=" "+Rn(n.analyses.segments.hour[0],r)),t+l(n,r)}function Ue(n,e,r){return n.pattern.minute==="*"?"every minute of the "+c({hour:e.hour,minute:0},r)+" hour"+l(n,r):"every minute from "+c({hour:e.hour,minute:e.span[0]},r)+b(r)+c({hour:e.hour,minute:e.span[1]},r)+l(n,r)}function Qe(n,e,r){if(e.form==="wildcard")return"every minute during the "+X(n,e.times,!1,r)+" hours"+l(n,r);let t=X(n,e.times,!0,r);return(e.form==="range"?H(n.pattern.minute,r):N(M(n.analyses.segments.minute,r),"minute","hour",r))+", at "+t+l(n,r)}var qe={2:"other",3:"third",4:"fourth",6:"sixth",8:"eighth",12:"twelfth"};function Rn(n,e){let r="during every "+qe[n.interval]+" hour",t=n.startToken==="*"?0:+n.startToken;return t===0?r:r+" starting at "+c({hour:t,minute:0},e)}function Ve(n,e,r){let t=n.analyses.segments.hour[0];return e.form==="wildcard"?"every minute "+Rn(t,r)+l(n,r):H(n.pattern.minute,r)+", "+Mn(t,r)+l(n,r)}function H(n,e){let r=n.split("-"),t=L(r,e);return"every minute from "+t(r[0])+b(e)+t(r[1])+" past the hour"}function $e(n,e,r){return"every hour"+l(n,r)}function Je(n,e,r){let t=xn(Be(e),r);return e.minuteForm==="wildcard"?"every minute "+t+l(n,r):e.minuteForm==="range"?H(n.pattern.minute,r)+", "+t+l(n,r):Cn(n,r)+" "+t+l(n,r)}function Cn(n,e){return n.pattern.minute==="0"?"every hour":N(M(n.analyses.segments.minute,e),"minute","hour",e)}function Ye(n,e,r){return Mn(n.analyses.segments.hour[0],r)+l(n,r)}function Be(n){return{from:n.from,last:n.boundMinute??0,to:n.to}}function xn(n,e){return"from "+c({hour:n.from,minute:0},e)+b(e)+c({hour:n.to,minute:n.last},e)}function Ge(n,e,r){let t=rn(e.times),i=e.times.map(function(u){return c({hour:u.hour,minute:u.minute,second:u.second,plain:t},r)});return Tn(n,r)+"at "+g(i,r)}function Ke(n,e,r){if(e.fold){if(n.analyses.segments.hour.some(function(s){return s.kind==="range"})&&!n.analyses.clockSecond)return Ze(n,e,r)+l(n,r);let o={minute:e.minute,second:n.analyses.clockSecond};return Tn(n,r)+"at "+_(n,o,!0,r)}let t=N(M(n.analyses.segments.minute,r),"minute","hour",r)+", at "+_(n,{minute:0,second:null},!0,r)+l(n,r);return n.analyses.clockSecond?v(n,r)+", "+t:t}function Ze(n,e,r){let t=e.minute,i=[],o=[];n.analyses.segments.hour.forEach(function(m){m.kind==="range"?i.push("from "+c({hour:m.bounds[0],minute:0},r)+b(r)+c({hour:m.bounds[1],minute:t},r)):m.kind==="step"?o.push(...m.fires):o.push(+m.value)});let u=Cn(n,r)+" "+g(i,r);return o.length&&(u+=" and at "+g(o.map(function(m){return c({hour:m,minute:t},r)}),r)),u}var Xe={clockTimes:Ge,compactClockTimes:Ke,composeSeconds:Ie,everyHour:$e,everyMinute:We,everySecond:xe,hourRange:Je,hourStep:Ye,minuteFrequency:De,minuteSpanAcrossHourStep:Ve,minuteSpanInHour:Ue,minutesAcrossHours:Qe,multipleMinutes:Ae,rangeOfMinutes:Ee,secondPastMinute:Me,secondsWithinMinute:Te,singleMinute:je,standaloneSeconds:Fe};function Fn(n,e,r,t){if(n.startToken.indexOf("-")!==-1)return N(vn(n.fires,t),e,r,t);let i=n.startToken==="*"?0:+n.startToken,o=n.interval;return i!==0?n.fires.length<=3?N(vn(n.fires,t),e,r,t):"every "+d(o,t)+" "+e+"s from "+d(i,t)+" "+z(i,e)+" past the "+r:"every "+d(o,t)+" "+e+"s"}function Mn(n,e){if(n.startToken.indexOf("-")!==-1)return"at "+Z(n.fires,e);let r=n.startToken==="*"?0:+n.startToken,t=n.interval;return r===0?"every "+d(t,e)+" hours":n.fires.length<=3?"at "+Z(n.fires,e):"every "+d(t,e)+" hours from "+c({hour:r,minute:0},e)}function L(n,e){let r=n.some(function(i){return+i>10});return function(i){return r?""+i:d(i,e)}}function vn(n,e){return n.map(L(n,e))}function M(n,e){let r=n.flatMap(function(o){return o.kind==="range"?o.bounds:o.kind==="step"?o.fires:[o.value]}),t=L(r,e);return n.flatMap(function(o){return o.kind==="range"?[t(o.bounds[0])+b(e)+t(o.bounds[1])]:o.kind==="step"?o.fires.map(t):[t(o.value)]})}function N(n,e,r,t){return"at "+g(n,t)+" "+e+"s past the "+r}function _e(n,e,r){return(+n==0||+n==12)&&+e==0&&!(typeof r=="number"&&r>0)}function rn(n){let e=n.filter(function(t){return _e(t.hour,t.minute,t.second)});return e.length>0&&e.length<n.length}function Z(n,e){let r=rn(n.map(function(o){return{hour:o,minute:0}})),t=n.map(function(o){return c({hour:o,minute:0,plain:r},e)});return g(t,e)}function X(n,e,r,t){return e.kind==="fires"?Z(e.fires,t):_(n,{minute:0,second:null},r,t)}function nr(n){return n.kind==="range"?n.bounds:n.kind==="step"?n.fires:[n.value]}function _(n,e,r,t){let{minute:i,second:o}=e,u=n.analyses.segments.hour,s=rn(u.flatMap(function(p){return nr(p).map(function(D){return{hour:+D,minute:i,second:o}})})),m=[];return u.forEach(function(p){p.kind==="step"?m.push(...p.fires.map(function(D){return c({hour:D,minute:i,second:o,plain:s},t)})):p.kind==="range"?m.push(c({hour:p.bounds[0],minute:i,second:o,plain:s},t)+b(t)+c({hour:p.bounds[1],minute:i,second:o,plain:s},t)):m.push(c({hour:p.value,minute:i,second:o,plain:s},t))}),g(er(m,u,r),t)}function er(n,e,r){let t=e.some(function(o){return o.kind==="range"});return!r||!t?n:n.map(function(o,u){return u===0?o:"at "+o})}function g(n,e){if(n.length<=1)return n.join("");if(n.length===2)return n[0]+" and "+n[1];let r=e.style.serialComma?", and ":" and ";return n.slice(0,-1).join(", ")+r+n[n.length-1]}var rr={all:"",month:"in ",stepDate:"on ",weekday:"on "},tn={all:"every day",month:"every day in ",stepDate:"",weekday:"every "};function l(n,e){let r=W(n,rr,e);return r&&" "+r}function Tn(n,e){return W(n,tn,e)+" "}function W(n,e,r){let t=n.pattern;return t.date!=="*"&&t.weekday!=="*"?ir(n,r):t.date!=="*"?tr(n,e,r):t.weekday!=="*"?(Ln(t.weekday,r)||e.weekday+An(n,r))+k(n,r):t.month!=="*"?e.month+j(n,r):e.all}function tr(n,e,r){let t=n.pattern,i=Hn(t.date,r);return i?i+k(n,r):on(t.date)?e.stepDate+jn(t.date)+k(n,r):t.month!=="*"&&!In(n)?"on the "+nn(n,r)+k(n,r):t.month!=="*"?"on "+Wn(n,r):"on the "+nn(n,r)}function In(n){return!En(n.pattern.month)&&n.analyses.segments.month.every(function(r){return r.kind!=="range"})}function ir(n,e){let r=n.pattern,t=Ln(r.weekday,e)||"on "+An(n,e),i=Hn(r.date,e);return i?i+k(n,e)+" or "+t:on(r.date)?jn(r.date)+k(n,e)+" or "+t:r.month!=="*"&&In(n)?"on "+Wn(n,e)+" or "+t+" in "+j(n,e):"on the "+nn(n,e)+" or "+t+k(n,e)}function Hn(n,e){if(n==="L")return"on the last day of the month";if(n==="LW"||n==="WL")return"on the last weekday of the month";let r=/^L-(\d{1,2})$/.exec(n);if(r)return d(+r[1],e)+" "+z(r[1],"day")+" before the last day of the month";let t=/^(\d{1,2})W$|^W(\d{1,2})$/.exec(n);if(t)return"on the weekday nearest the "+F(t[1]||t[2])}function Ln(n,e){let r=n.split("#");if(r.length===2)return"on the "+we[+r[1]]+" "+en(r[0],e)+" of the month";if(/L$/.test(n))return"on the last "+en(n.slice(0,-1),e)+" of the month"}function Wn(n,e){let r=j(n,e),t=E(n.analyses.segments.date,e.style.ordinals?F:or,e);return e.style.dayFirst?t+" "+r:r+" "+t}function or(n){return""+n}function k(n,e){return n.pattern.month==="*"?"":" in "+j(n,e)}function jn(n){let e=n.split("/"),r=+e[1],t=e[0],o=(r===2?"every other":"every "+F(r))+" day of the month";return t!=="*"&&t!=="1"&&(o+=" from the "+F(t)),o}function nn(n,e){return E(n.analyses.segments.date,F,e)}function j(n,e){let r=En(n.pattern.month);return r||E(n.analyses.segments.month,function(i){return cr(i,e)},e)}function En(n){if(!on(n))return null;let[e,r]=n.split("/");return+r!=2?null:e==="*"||e==="1"?"every odd-numbered month":e==="2"?"every even-numbered month":null}function An(n,e){return E(n.analyses.segments.weekday,function(t){return en(t,e)},e)}function E(n,e,r){let t=[];return n.forEach(function(o){o.kind==="step"?t.push(...o.fires.map(e)):o.kind==="range"?t.push(o.bounds.map(e).join(b(r))):t.push(e(o.value))}),g(t,r)}function on(n){return n.indexOf("/")!==-1&&n.indexOf("-")===-1&&n.indexOf(",")===-1}function ur(n,e,r){let t=e.pattern.year;if(t==="*")return n;if(t.indexOf("/")!==-1)return n+" "+ar(t,r);let i=sr(t,r);if(t.indexOf("-")===-1&&t.indexOf(",")===-1&&e.pattern.date!=="*"&&n.indexOf(" at ")!==-1){let o=r.style.dayFirst?" ":", ";return n.replace(" at ",o+i+" at ")}return n+" in "+i}function sr(n,e){return n.indexOf(",")!==-1?g(n.split(","),e):n}function ar(n,e){let r=n.split("/"),t=+r[1],i=r[0];if(t<=1)return"every year";let o="every "+d(t,e)+" years";return i!=="*"&&i!=="0"&&(o+=" from "+i),o}function c(n,e){let{hour:r,minute:t,plain:i,explicit:o}=n,u=typeof n.second=="number"&&n.second>0?n.second:0;return e.ampm?lr({hour:r,minute:t,second:u,plain:i,explicit:o},e):B({hour:r,minute:t,second:u},{pad:!0,sep:e.style.sep})}function lr(n,e){let{hour:r,minute:t,second:i,plain:o,explicit:u}=n,s=e.style;if(!o&&!u&&+t==0&&!i){if(+r==0)return s.midnight;if(+r==12)return s.midday}return B({hour:r%12||12,minute:t,second:i},{lean:!u,sep:s.sep})+(s.closeUp?"":" ")+(r<12?s.am:s.pm)}function d(n,e){return zn(n,ze,e)}function z(n,e){return+n==1?e:e+"s"}function b(n){return n.short?"-":n.style.through}function F(n){let e=Math.abs(n),r=K[e];return r||(e=(e%100-20)%10,r=K[e]||K[0]),n+r}function cr(n,e){let r=Pe[+n];return r&&r[e.short?1:0]}function en(n,e){let r=n===7||n==="7"?0:n,t=y[r]||ve[r];return t&&t[e.short?1:0]}var mr={describe:Ce,fallback:"an unrecognizable cron pattern",options:Re,reboot:"at system startup",sentence:n=>"Runs "+n+(n.endsWith(".")?"":".")},Dn=mr;/**
2
2
  * @license MIT, Copyright (c) 2026 Andrew Brož
3
- */function sr(n,e){let r=e&&e.lang||jn,t=r.options(e);if(!t.lenient)return Dn(Un(n,r,t),r,e);try{return Dn(Un(n,r,t),r,e)}catch{return r.fallback}}function Dn(n,e,r){return r&&r.sentence?e.sentence(n):n}function Un(n,e,r){if(typeof n=="string"&&n.trim().toLowerCase()==="@reboot")return e.reboot;let t=hn(On(n,r)),i=e.strategy?e.strategy(t,t.plan):t.plan;return e.describe({...t,plan:i},r)}var on=sr;typeof globalThis<"u"&&Object.assign(globalThis,{cronli5:on});var qr=on;})();
3
+ */function fr(n,e){let r=e&&e.lang||Dn,t=r.options(e);if(!t.lenient)return Un(Qn(n,r,t),r,e);try{return Un(Qn(n,r,t),r,e)}catch{return r.fallback}}function Un(n,e,r){return r&&r.sentence?e.sentence(n):n}function Qn(n,e,r){if(typeof n=="string"&&n.trim().toLowerCase()==="@reboot")return e.reboot;let t=bn(Nn(n,r)),i=e.strategy?e.strategy(t,t.plan):t.plan;return e.describe({...t,plan:i},r)}var un=fr;typeof globalThis<"u"&&Object.assign(globalThis,{cronli5:un});var Br=un;})();
package/dist/cronli5.cjs CHANGED
@@ -226,14 +226,20 @@ function normalizeField(value, field, spec) {
226
226
  }
227
227
  const cycle = timeFieldCycle[field];
228
228
  const segments = stringValue.split(",").map(function canonical(segment) {
229
- return enumerateNonUniformStep(
230
- collapseDegenerateRange(
231
- collapseOnceStep(collapseUnitStep(segment, spec), spec),
232
- spec
229
+ return canonicalizeTokens(collapseFullSpanRange(
230
+ enumerateNonUniformStep(
231
+ collapseFullSpanStep(
232
+ collapseDegenerateRange(
233
+ collapseOnceStep(collapseUnitStep(segment, spec), spec),
234
+ spec
235
+ ),
236
+ spec
237
+ ),
238
+ spec,
239
+ cycle
233
240
  ),
234
- spec,
235
- cycle
236
- );
241
+ spec
242
+ ), spec);
237
243
  }).join(",").split(",");
238
244
  if (segments.indexOf("*") !== -1) {
239
245
  return "*";
@@ -242,6 +248,23 @@ function normalizeField(value, field, spec) {
242
248
  return firstFire(a, spec) - firstFire(b, spec);
243
249
  }).join(",");
244
250
  }
251
+ function canonicalizeTokens(segment, spec) {
252
+ if (!spec.numbers) {
253
+ return segment;
254
+ }
255
+ const parts = segment.split("/");
256
+ const start = parts[0].split("-").map(function fold(token) {
257
+ return canonicalizeToken(token, spec);
258
+ }).join("-");
259
+ return parts.length === 2 ? start + "/" + parts[1] : start;
260
+ }
261
+ function canonicalizeToken(token, spec) {
262
+ if (token === "*") {
263
+ return token;
264
+ }
265
+ const number = toFieldNumber(token, spec.numbers);
266
+ return "" + (number > spec.top ? spec.min : number);
267
+ }
245
268
  function collapseUnitStep(segment, spec) {
246
269
  const parts = segment.split("/");
247
270
  if (!spec.cyclic || parts.length !== 2 || +parts[1] !== 1) {
@@ -284,6 +307,35 @@ function enumerateNonUniformStep(segment, spec, cycle) {
284
307
  }
285
308
  return fires.join(",");
286
309
  }
310
+ function collapseFullSpanStep(segment, spec) {
311
+ const parts = segment.split("/");
312
+ if (parts.length !== 2 || !includes(parts[0], "-")) {
313
+ return segment;
314
+ }
315
+ return collapseFullSpanRange(parts[0], spec) === "*" ? "*/" + parts[1] : segment;
316
+ }
317
+ function collapseFullSpanRange(segment, spec) {
318
+ if (typeof spec.top !== "number" || includes(segment, "/") || !includes(segment, "-")) {
319
+ return segment;
320
+ }
321
+ const bounds = segment.split("-");
322
+ const low = toFieldNumber(bounds[0], spec.numbers);
323
+ const high = toFieldNumber(bounds[1], spec.numbers);
324
+ if (low > high) {
325
+ return segment;
326
+ }
327
+ const top = spec.top;
328
+ const fired = {};
329
+ for (let value = low; value <= high; value += 1) {
330
+ fired[value > top ? spec.min : value] = true;
331
+ }
332
+ for (let value = spec.min; value <= top; value += 1) {
333
+ if (!fired[value]) {
334
+ return segment;
335
+ }
336
+ }
337
+ return "*";
338
+ }
287
339
  function collapseDegenerateRange(segment, spec) {
288
340
  const start = segment.split("/")[0];
289
341
  if (!includes(start, "-")) {
@@ -852,20 +904,6 @@ var weekdayNames = [
852
904
  ["Friday", "Fri"],
853
905
  ["Saturday", "Sat"]
854
906
  ];
855
- var monthAbbreviations = {
856
- JAN: monthNames[1],
857
- FEB: monthNames[2],
858
- MAR: monthNames[3],
859
- APR: monthNames[4],
860
- MAY: monthNames[5],
861
- JUN: monthNames[6],
862
- JUL: monthNames[7],
863
- AUG: monthNames[8],
864
- SEP: monthNames[9],
865
- OCT: monthNames[10],
866
- NOV: monthNames[11],
867
- DEC: monthNames[12]
868
- };
869
907
  var weekdayAbbreviations = {
870
908
  SUN: weekdayNames[0],
871
909
  MON: weekdayNames[1],
@@ -915,8 +953,37 @@ function renderSecondsWithinMinute(ir, plan, opts) {
915
953
  return secondsLeadClause(ir, opts) + ", " + minuteWord + " " + minuteUnit + " past the hour, every hour" + trailingQualifier(ir, opts);
916
954
  }
917
955
  function renderComposeSeconds(ir, plan, opts) {
956
+ if (plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step")) {
957
+ const minute = plan.rest.times[0].minute;
958
+ if (+minute === 0) {
959
+ return secondsLeadClause(ir, opts) + " for one minute at " + durationHours(ir, plan.rest, opts);
960
+ }
961
+ return secondsLeadClause(ir, opts) + " of " + clockTimesOf(ir, plan.rest, opts);
962
+ }
963
+ if (ir.shapes.second === "wildcard" && plan.rest.kind === "minuteFrequency" && plan.rest.hours.kind === "none" && ir.pattern.minute === "*/2") {
964
+ return "every second of every other minute" + trailingQualifier(ir, opts);
965
+ }
918
966
  return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
919
967
  }
968
+ function durationHours(ir, plan, opts) {
969
+ const hours = plan.times.map(function clock(time) {
970
+ return getTime({ hour: time.hour, minute: 0 }, opts);
971
+ });
972
+ const trail = dayQualifier(ir, leadingWords, opts);
973
+ return joinList(hours, opts) + (trail && ", " + trail);
974
+ }
975
+ function clockTimesOf(ir, plan, opts) {
976
+ const times = plan.times.map(function clock(time) {
977
+ return getTime({
978
+ hour: time.hour,
979
+ minute: time.minute,
980
+ second: time.second,
981
+ explicit: true
982
+ }, opts);
983
+ });
984
+ const trail = dayQualifier(ir, leadingWords, opts);
985
+ return joinList(times, opts) + (trail && ", " + trail);
986
+ }
920
987
  function secondsLeadClause(ir, opts) {
921
988
  const secondField = ir.pattern.second;
922
989
  const shape = ir.shapes.second;
@@ -981,6 +1048,9 @@ function renderMinuteFrequency(ir, plan, opts) {
981
1048
  return phrase + trailingQualifier(ir, opts);
982
1049
  }
983
1050
  function renderMinuteSpanInHour(ir, plan, opts) {
1051
+ if (ir.pattern.minute === "*") {
1052
+ return "every minute of the " + getTime({ hour: plan.hour, minute: 0 }, opts) + " hour" + trailingQualifier(ir, opts);
1053
+ }
984
1054
  return "every minute from " + getTime({ hour: plan.hour, minute: plan.span[0] }, opts) + through(opts) + getTime({ hour: plan.hour, minute: plan.span[1] }, opts) + trailingQualifier(ir, opts);
985
1055
  }
986
1056
  function renderMinutesAcrossHours(ir, plan, opts) {
@@ -1479,7 +1549,7 @@ function stepYears(yearField, opts) {
1479
1549
  return phrase;
1480
1550
  }
1481
1551
  function getTime(time, opts) {
1482
- const { hour, minute, plain } = time;
1552
+ const { hour, minute, plain, explicit } = time;
1483
1553
  const second = typeof time.second === "number" && time.second > 0 ? time.second : 0;
1484
1554
  if (!opts.ampm) {
1485
1555
  return clockDigits({
@@ -1488,12 +1558,12 @@ function getTime(time, opts) {
1488
1558
  second
1489
1559
  }, { pad: true, sep: opts.style.sep });
1490
1560
  }
1491
- return twelveHourTime({ hour, minute, second, plain }, opts);
1561
+ return twelveHourTime({ hour, minute, second, plain, explicit }, opts);
1492
1562
  }
1493
1563
  function twelveHourTime(time, opts) {
1494
- const { hour, minute, second, plain } = time;
1564
+ const { hour, minute, second, plain, explicit } = time;
1495
1565
  const style = opts.style;
1496
- if (!plain && +minute === 0 && !second) {
1566
+ if (!plain && !explicit && +minute === 0 && !second) {
1497
1567
  if (+hour === 0) {
1498
1568
  return style.midnight;
1499
1569
  }
@@ -1503,7 +1573,7 @@ function twelveHourTime(time, opts) {
1503
1573
  }
1504
1574
  const digits = clockDigits(
1505
1575
  { hour: hour % 12 || 12, minute, second },
1506
- { lean: true, sep: style.sep }
1576
+ { lean: !explicit, sep: style.sep }
1507
1577
  );
1508
1578
  return digits + (style.closeUp ? "" : " ") + (hour < 12 ? style.am : style.pm);
1509
1579
  }
@@ -1526,7 +1596,7 @@ function getOrdinal(n) {
1526
1596
  return n + suffix;
1527
1597
  }
1528
1598
  function getMonth(m, opts) {
1529
- const month = monthNames[m] || monthAbbreviations[m];
1599
+ const month = monthNames[+m];
1530
1600
  return month && month[opts.short ? 1 : 0];
1531
1601
  }
1532
1602
  function getWeekday(d, opts) {
@@ -1539,7 +1609,9 @@ var en = {
1539
1609
  fallback: "an unrecognizable cron pattern",
1540
1610
  options: normalizeOptions,
1541
1611
  reboot: "at system startup",
1542
- sentence: (description) => "Runs " + description + "."
1612
+ // A description ending in an abbreviation already carries its period
1613
+ // ("…9 a.m."), so closing the sentence must not double it.
1614
+ sentence: (description) => "Runs " + description + (description.endsWith(".") ? "" : ".")
1543
1615
  };
1544
1616
  var en_default = en;
1545
1617
 
package/dist/cronli5.js CHANGED
@@ -200,14 +200,20 @@ function normalizeField(value, field, spec) {
200
200
  }
201
201
  const cycle = timeFieldCycle[field];
202
202
  const segments = stringValue.split(",").map(function canonical(segment) {
203
- return enumerateNonUniformStep(
204
- collapseDegenerateRange(
205
- collapseOnceStep(collapseUnitStep(segment, spec), spec),
206
- spec
203
+ return canonicalizeTokens(collapseFullSpanRange(
204
+ enumerateNonUniformStep(
205
+ collapseFullSpanStep(
206
+ collapseDegenerateRange(
207
+ collapseOnceStep(collapseUnitStep(segment, spec), spec),
208
+ spec
209
+ ),
210
+ spec
211
+ ),
212
+ spec,
213
+ cycle
207
214
  ),
208
- spec,
209
- cycle
210
- );
215
+ spec
216
+ ), spec);
211
217
  }).join(",").split(",");
212
218
  if (segments.indexOf("*") !== -1) {
213
219
  return "*";
@@ -216,6 +222,23 @@ function normalizeField(value, field, spec) {
216
222
  return firstFire(a, spec) - firstFire(b, spec);
217
223
  }).join(",");
218
224
  }
225
+ function canonicalizeTokens(segment, spec) {
226
+ if (!spec.numbers) {
227
+ return segment;
228
+ }
229
+ const parts = segment.split("/");
230
+ const start = parts[0].split("-").map(function fold(token) {
231
+ return canonicalizeToken(token, spec);
232
+ }).join("-");
233
+ return parts.length === 2 ? start + "/" + parts[1] : start;
234
+ }
235
+ function canonicalizeToken(token, spec) {
236
+ if (token === "*") {
237
+ return token;
238
+ }
239
+ const number = toFieldNumber(token, spec.numbers);
240
+ return "" + (number > spec.top ? spec.min : number);
241
+ }
219
242
  function collapseUnitStep(segment, spec) {
220
243
  const parts = segment.split("/");
221
244
  if (!spec.cyclic || parts.length !== 2 || +parts[1] !== 1) {
@@ -258,6 +281,35 @@ function enumerateNonUniformStep(segment, spec, cycle) {
258
281
  }
259
282
  return fires.join(",");
260
283
  }
284
+ function collapseFullSpanStep(segment, spec) {
285
+ const parts = segment.split("/");
286
+ if (parts.length !== 2 || !includes(parts[0], "-")) {
287
+ return segment;
288
+ }
289
+ return collapseFullSpanRange(parts[0], spec) === "*" ? "*/" + parts[1] : segment;
290
+ }
291
+ function collapseFullSpanRange(segment, spec) {
292
+ if (typeof spec.top !== "number" || includes(segment, "/") || !includes(segment, "-")) {
293
+ return segment;
294
+ }
295
+ const bounds = segment.split("-");
296
+ const low = toFieldNumber(bounds[0], spec.numbers);
297
+ const high = toFieldNumber(bounds[1], spec.numbers);
298
+ if (low > high) {
299
+ return segment;
300
+ }
301
+ const top = spec.top;
302
+ const fired = {};
303
+ for (let value = low; value <= high; value += 1) {
304
+ fired[value > top ? spec.min : value] = true;
305
+ }
306
+ for (let value = spec.min; value <= top; value += 1) {
307
+ if (!fired[value]) {
308
+ return segment;
309
+ }
310
+ }
311
+ return "*";
312
+ }
261
313
  function collapseDegenerateRange(segment, spec) {
262
314
  const start = segment.split("/")[0];
263
315
  if (!includes(start, "-")) {
@@ -826,20 +878,6 @@ var weekdayNames = [
826
878
  ["Friday", "Fri"],
827
879
  ["Saturday", "Sat"]
828
880
  ];
829
- var monthAbbreviations = {
830
- JAN: monthNames[1],
831
- FEB: monthNames[2],
832
- MAR: monthNames[3],
833
- APR: monthNames[4],
834
- MAY: monthNames[5],
835
- JUN: monthNames[6],
836
- JUL: monthNames[7],
837
- AUG: monthNames[8],
838
- SEP: monthNames[9],
839
- OCT: monthNames[10],
840
- NOV: monthNames[11],
841
- DEC: monthNames[12]
842
- };
843
881
  var weekdayAbbreviations = {
844
882
  SUN: weekdayNames[0],
845
883
  MON: weekdayNames[1],
@@ -889,8 +927,37 @@ function renderSecondsWithinMinute(ir, plan, opts) {
889
927
  return secondsLeadClause(ir, opts) + ", " + minuteWord + " " + minuteUnit + " past the hour, every hour" + trailingQualifier(ir, opts);
890
928
  }
891
929
  function renderComposeSeconds(ir, plan, opts) {
930
+ if (plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step")) {
931
+ const minute = plan.rest.times[0].minute;
932
+ if (+minute === 0) {
933
+ return secondsLeadClause(ir, opts) + " for one minute at " + durationHours(ir, plan.rest, opts);
934
+ }
935
+ return secondsLeadClause(ir, opts) + " of " + clockTimesOf(ir, plan.rest, opts);
936
+ }
937
+ if (ir.shapes.second === "wildcard" && plan.rest.kind === "minuteFrequency" && plan.rest.hours.kind === "none" && ir.pattern.minute === "*/2") {
938
+ return "every second of every other minute" + trailingQualifier(ir, opts);
939
+ }
892
940
  return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
893
941
  }
942
+ function durationHours(ir, plan, opts) {
943
+ const hours = plan.times.map(function clock(time) {
944
+ return getTime({ hour: time.hour, minute: 0 }, opts);
945
+ });
946
+ const trail = dayQualifier(ir, leadingWords, opts);
947
+ return joinList(hours, opts) + (trail && ", " + trail);
948
+ }
949
+ function clockTimesOf(ir, plan, opts) {
950
+ const times = plan.times.map(function clock(time) {
951
+ return getTime({
952
+ hour: time.hour,
953
+ minute: time.minute,
954
+ second: time.second,
955
+ explicit: true
956
+ }, opts);
957
+ });
958
+ const trail = dayQualifier(ir, leadingWords, opts);
959
+ return joinList(times, opts) + (trail && ", " + trail);
960
+ }
894
961
  function secondsLeadClause(ir, opts) {
895
962
  const secondField = ir.pattern.second;
896
963
  const shape = ir.shapes.second;
@@ -955,6 +1022,9 @@ function renderMinuteFrequency(ir, plan, opts) {
955
1022
  return phrase + trailingQualifier(ir, opts);
956
1023
  }
957
1024
  function renderMinuteSpanInHour(ir, plan, opts) {
1025
+ if (ir.pattern.minute === "*") {
1026
+ return "every minute of the " + getTime({ hour: plan.hour, minute: 0 }, opts) + " hour" + trailingQualifier(ir, opts);
1027
+ }
958
1028
  return "every minute from " + getTime({ hour: plan.hour, minute: plan.span[0] }, opts) + through(opts) + getTime({ hour: plan.hour, minute: plan.span[1] }, opts) + trailingQualifier(ir, opts);
959
1029
  }
960
1030
  function renderMinutesAcrossHours(ir, plan, opts) {
@@ -1453,7 +1523,7 @@ function stepYears(yearField, opts) {
1453
1523
  return phrase;
1454
1524
  }
1455
1525
  function getTime(time, opts) {
1456
- const { hour, minute, plain } = time;
1526
+ const { hour, minute, plain, explicit } = time;
1457
1527
  const second = typeof time.second === "number" && time.second > 0 ? time.second : 0;
1458
1528
  if (!opts.ampm) {
1459
1529
  return clockDigits({
@@ -1462,12 +1532,12 @@ function getTime(time, opts) {
1462
1532
  second
1463
1533
  }, { pad: true, sep: opts.style.sep });
1464
1534
  }
1465
- return twelveHourTime({ hour, minute, second, plain }, opts);
1535
+ return twelveHourTime({ hour, minute, second, plain, explicit }, opts);
1466
1536
  }
1467
1537
  function twelveHourTime(time, opts) {
1468
- const { hour, minute, second, plain } = time;
1538
+ const { hour, minute, second, plain, explicit } = time;
1469
1539
  const style = opts.style;
1470
- if (!plain && +minute === 0 && !second) {
1540
+ if (!plain && !explicit && +minute === 0 && !second) {
1471
1541
  if (+hour === 0) {
1472
1542
  return style.midnight;
1473
1543
  }
@@ -1477,7 +1547,7 @@ function twelveHourTime(time, opts) {
1477
1547
  }
1478
1548
  const digits = clockDigits(
1479
1549
  { hour: hour % 12 || 12, minute, second },
1480
- { lean: true, sep: style.sep }
1550
+ { lean: !explicit, sep: style.sep }
1481
1551
  );
1482
1552
  return digits + (style.closeUp ? "" : " ") + (hour < 12 ? style.am : style.pm);
1483
1553
  }
@@ -1500,7 +1570,7 @@ function getOrdinal(n) {
1500
1570
  return n + suffix;
1501
1571
  }
1502
1572
  function getMonth(m, opts) {
1503
- const month = monthNames[m] || monthAbbreviations[m];
1573
+ const month = monthNames[+m];
1504
1574
  return month && month[opts.short ? 1 : 0];
1505
1575
  }
1506
1576
  function getWeekday(d, opts) {
@@ -1513,7 +1583,9 @@ var en = {
1513
1583
  fallback: "an unrecognizable cron pattern",
1514
1584
  options: normalizeOptions,
1515
1585
  reboot: "at system startup",
1516
- sentence: (description) => "Runs " + description + "."
1586
+ // A description ending in an abbreviation already carries its period
1587
+ // ("…9 a.m."), so closing the sentence must not double it.
1588
+ sentence: (description) => "Runs " + description + (description.endsWith(".") ? "" : ".")
1517
1589
  };
1518
1590
  var en_default = en;
1519
1591