cronli5 0.1.1 → 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 +91 -0
- package/cli.js +9 -0
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +127 -38
- package/dist/cronli5.js +127 -38
- package/dist/lang/de.cjs +59 -36
- package/dist/lang/de.js +59 -36
- package/dist/lang/en.cjs +43 -32
- package/dist/lang/en.js +43 -32
- package/dist/lang/es.cjs +81 -40
- package/dist/lang/es.js +81 -40
- package/dist/lang/fi.cjs +46 -44
- package/dist/lang/fi.js +46 -44
- package/dist/lang/zh.cjs +36 -13
- package/dist/lang/zh.js +36 -13
- package/package.json +2 -1
- package/src/core/normalize.ts +144 -6
- package/src/lang/de/index.ts +99 -35
- package/src/lang/en/index.ts +113 -48
- package/src/lang/es/index.ts +140 -41
- package/src/lang/fi/index.ts +62 -39
- package/src/lang/zh/index.ts +93 -21
package/src/lang/fi/index.ts
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
// case-pair construction wherever digits appear.
|
|
11
11
|
|
|
12
12
|
import {clockDigits, numeral} from '../../core/format.js';
|
|
13
|
+
import {weekdayNumbers} from '../../core/specs.js';
|
|
14
|
+
import {toFieldNumber} from '../../core/util.js';
|
|
13
15
|
import {resolveDialect} from './dialects.js';
|
|
14
16
|
import type {
|
|
15
17
|
ClockTime, HourTimesPlan, IR, Language, NormalizedOptions, PlanNode,
|
|
@@ -62,7 +64,6 @@ interface UnitForms {
|
|
|
62
64
|
anchor: string;
|
|
63
65
|
ela: string;
|
|
64
66
|
gen: string;
|
|
65
|
-
restart: string;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
// Genitive numerals for the "N <unit>in välein" construction, spelled
|
|
@@ -160,16 +161,6 @@ const monthStems: (string | null)[] = [
|
|
|
160
161
|
'joulu'
|
|
161
162
|
];
|
|
162
163
|
|
|
163
|
-
// Cron token vocabulary (JAN..DEC, SUN..SAT) is part of cron syntax; map
|
|
164
|
-
// it to field numbers.
|
|
165
|
-
const monthTokens: {[token: string]: number} = {
|
|
166
|
-
JAN: 1, FEB: 2, MAR: 3, APR: 4, MAY: 5, JUN: 6,
|
|
167
|
-
JUL: 7, AUG: 8, SEP: 9, OCT: 10, NOV: 11, DEC: 12
|
|
168
|
-
};
|
|
169
|
-
const weekdayTokens: {[token: string]: number} = {
|
|
170
|
-
SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6
|
|
171
|
-
};
|
|
172
|
-
|
|
173
164
|
// Unit form tables for the anchored-minute/second constructions.
|
|
174
165
|
// `mark` is the frequency for the "N minuutin kohdalla" ("at the
|
|
175
166
|
// N-minute mark") form; `anchor` is the possessive for the elative
|
|
@@ -179,15 +170,13 @@ const units: {minute: UnitForms; second: UnitForms} = {
|
|
|
179
170
|
mark: 'joka tunti',
|
|
180
171
|
anchor: 'jokaisen tunnin',
|
|
181
172
|
ela: 'minuutista',
|
|
182
|
-
gen: 'minuutin'
|
|
183
|
-
restart: 'tasatunnista alkaen'
|
|
173
|
+
gen: 'minuutin'
|
|
184
174
|
},
|
|
185
175
|
second: {
|
|
186
176
|
mark: 'joka minuutti',
|
|
187
177
|
anchor: 'jokaisen minuutin',
|
|
188
178
|
ela: 'sekunnista',
|
|
189
|
-
gen: 'sekunnin'
|
|
190
|
-
restart: 'joka minuutti'
|
|
179
|
+
gen: 'sekunnin'
|
|
191
180
|
}
|
|
192
181
|
};
|
|
193
182
|
|
|
@@ -352,9 +341,42 @@ function renderComposeSeconds(
|
|
|
352
341
|
hourClause + trailingQualifier(ir, opts);
|
|
353
342
|
}
|
|
354
343
|
|
|
344
|
+
// A sub-minute second with the minute pinned to 0 and a specific hour: the
|
|
345
|
+
// clock-time rest would read "klo 9", dropping the pinned :00 and so the
|
|
346
|
+
// one-minute confinement (60 fires in :00, not 3,600 across the hour). Bind
|
|
347
|
+
// the seconds to the explicit clock minute with the "minuutin HH.00 aikana"
|
|
348
|
+
// frame (an "of"/during form, never a range) and trail the day qualifier
|
|
349
|
+
// ("joka sekunti minuutin 9.00 aikana, joka päivä").
|
|
350
|
+
if (plan.rest.kind === 'clockTimes' &&
|
|
351
|
+
plan.rest.times.every((time) => +time.minute === 0)) {
|
|
352
|
+
return composeMinuteZero(ir, plan.rest, opts);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
355
|
return secondsLeadClause(ir, opts) + ', ' + render(ir, plan.rest, opts);
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
// The minute-0 confinement: bind the seconds to the explicit clock minute(s)
|
|
359
|
+
// in the "minuutin/minuuttien HH.00 aikana" frame (an "of"/during form, never
|
|
360
|
+
// a range — a range would round-trip back to the whole hour) and trail the day
|
|
361
|
+
// qualifier ("joka sekunti minuutin 9.00 aikana, joka päivä").
|
|
362
|
+
function composeMinuteZero(
|
|
363
|
+
ir: IR,
|
|
364
|
+
rest: Extract<PlanNode, {kind: 'clockTimes'}>,
|
|
365
|
+
opts: NormalizedOptions
|
|
366
|
+
): string {
|
|
367
|
+
const clocks = rest.times.map(function clock(time): string {
|
|
368
|
+
return clockDigits({hour: time.hour, minute: time.minute},
|
|
369
|
+
{sep: opts.style.sep});
|
|
370
|
+
});
|
|
371
|
+
const frame = clocks.length === 1 ?
|
|
372
|
+
'minuutin ' + clocks[0] :
|
|
373
|
+
'minuuttien ' + joinList(clocks);
|
|
374
|
+
const dayTrail = leadingQualifier(ir, opts).trimEnd();
|
|
375
|
+
|
|
376
|
+
return secondsLeadClause(ir, opts) + ' ' + frame + ' aikana' +
|
|
377
|
+
(dayTrail ? ', ' + dayTrail : '');
|
|
378
|
+
}
|
|
379
|
+
|
|
358
380
|
// The leading clause describing a second field relative to the minute.
|
|
359
381
|
function secondsLeadClause(ir: IR, opts: NormalizedOptions): string {
|
|
360
382
|
const secondField = ir.pattern.second;
|
|
@@ -545,12 +567,20 @@ function renderMinuteFrequency(
|
|
|
545
567
|
return phrase + trailingQualifier(ir, opts);
|
|
546
568
|
}
|
|
547
569
|
|
|
548
|
-
// "joka minuutti klo 9.00–9.59".
|
|
570
|
+
// "joka minuutti klo 9.00–9.59". A wildcard minute is the whole hour, so it
|
|
571
|
+
// reads as that hour itself ("joka minuutti kello 9 aikana") rather than a
|
|
572
|
+
// synthesized "klo 9.00–9.59" range the source never stated; a plain range is
|
|
573
|
+
// a real window and keeps the dash form.
|
|
549
574
|
function renderMinuteSpanInHour(
|
|
550
575
|
ir: IR,
|
|
551
576
|
plan: Extract<PlanNode, {kind: 'minuteSpanInHour'}>,
|
|
552
577
|
opts: NormalizedOptions
|
|
553
578
|
): string {
|
|
579
|
+
if (ir.pattern.minute === '*') {
|
|
580
|
+
return 'joka minuutti kello ' + plan.hour + ' aikana' +
|
|
581
|
+
trailingQualifier(ir, opts);
|
|
582
|
+
}
|
|
583
|
+
|
|
554
584
|
return 'joka minuutti ' +
|
|
555
585
|
kloRange({hour: plan.hour, minute: plan.span[0]},
|
|
556
586
|
{hour: plan.hour, minute: plan.span[1]}, opts) +
|
|
@@ -858,15 +888,9 @@ function stepCycle60(
|
|
|
858
888
|
' alkaen';
|
|
859
889
|
}
|
|
860
890
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
if (segment.fires.length <= 2) {
|
|
866
|
-
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
return cadence + ' ' + unit.restart;
|
|
891
|
+
// A clean stride from the top of the cycle is the bare cadence. (An uneven
|
|
892
|
+
// stride is rewritten to its fires upstream and never reaches here.)
|
|
893
|
+
return cadence;
|
|
870
894
|
}
|
|
871
895
|
|
|
872
896
|
// "kahden tunnin välein", "klo 0, 10 ja 20", or "viiden tunnin välein
|
|
@@ -880,7 +904,9 @@ function stepHours(segment: StepSegment, opts: NormalizedOptions): string {
|
|
|
880
904
|
const interval = segment.interval;
|
|
881
905
|
const cadence = genitive(interval, opts) + ' tunnin välein';
|
|
882
906
|
|
|
883
|
-
|
|
907
|
+
// A clean stride from midnight is the bare cadence. (An uneven stride is
|
|
908
|
+
// rewritten to its fires upstream and never reaches here.)
|
|
909
|
+
if (start === 0) {
|
|
884
910
|
return cadence;
|
|
885
911
|
}
|
|
886
912
|
|
|
@@ -888,10 +914,6 @@ function stepHours(segment: StepSegment, opts: NormalizedOptions): string {
|
|
|
888
914
|
return kloList(segment.fires, opts);
|
|
889
915
|
}
|
|
890
916
|
|
|
891
|
-
if (start === 0) {
|
|
892
|
-
return cadence + ' keskiyöstä alkaen';
|
|
893
|
-
}
|
|
894
|
-
|
|
895
917
|
return cadence + ' klo ' + hourElatives[start] + ' alkaen';
|
|
896
918
|
}
|
|
897
919
|
|
|
@@ -1350,18 +1372,16 @@ function quartzWeekdayPhrase(weekdayField: string): string | undefined {
|
|
|
1350
1372
|
}
|
|
1351
1373
|
}
|
|
1352
1374
|
|
|
1353
|
-
// Resolve a weekday
|
|
1375
|
+
// Resolve a weekday to its table index. Weekday-field segments are already
|
|
1376
|
+
// canonical numbers; a Quartz stem (`5L`, `MON#2`) is not, so resolve any
|
|
1377
|
+
// name via the core's index (with the Sunday alias 7 folding to 0).
|
|
1354
1378
|
function weekdayNumber(token: string | number): number {
|
|
1355
|
-
|
|
1356
|
-
return weekdayTokens[token];
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
return +token % 7;
|
|
1379
|
+
return toFieldNumber('' + token, weekdayNumbers) % 7;
|
|
1360
1380
|
}
|
|
1361
1381
|
|
|
1362
|
-
// Resolve a month
|
|
1382
|
+
// Resolve a canonical month number to its table index.
|
|
1363
1383
|
function monthNumber(token: string | number): number {
|
|
1364
|
-
return
|
|
1384
|
+
return +token;
|
|
1365
1385
|
}
|
|
1366
1386
|
|
|
1367
1387
|
// --- Years. ---
|
|
@@ -1503,7 +1523,10 @@ const fi: Language = {
|
|
|
1503
1523
|
fallback: 'tunnistamaton cron-lauseke',
|
|
1504
1524
|
options: normalizeOptions,
|
|
1505
1525
|
reboot: 'järjestelmän käynnistyessä',
|
|
1506
|
-
|
|
1526
|
+
// A description ending in a period already carries it, so closing the
|
|
1527
|
+
// sentence must not double it.
|
|
1528
|
+
sentence: (description) =>
|
|
1529
|
+
'Suoritetaan ' + description + (description.endsWith('.') ? '' : '.')
|
|
1507
1530
|
};
|
|
1508
1531
|
|
|
1509
1532
|
export default fi;
|
package/src/lang/zh/index.ts
CHANGED
|
@@ -217,11 +217,22 @@ function hourFrame(ir: IR): string {
|
|
|
217
217
|
|
|
218
218
|
// A repeating minute step, optionally confined to active hours.
|
|
219
219
|
function renderMinuteFrequency(ir: IR, plan: PlanNode): string {
|
|
220
|
-
const
|
|
220
|
+
const minuteStep = stepSegment(ir, 'minute');
|
|
221
|
+
// A "每N分钟" cadence is only faithful from the top of the hour; an offset
|
|
222
|
+
// step (5/6 fires at :05,:11,…) enumerates its fires instead.
|
|
223
|
+
const base = minuteStep.startToken === '*' ?
|
|
224
|
+
cadence(minuteStep.interval, UNITS.minute) :
|
|
225
|
+
renderMinutePast(ir);
|
|
221
226
|
const {hours} = plan as Extract<PlanNode, {kind: 'minuteFrequency'}>;
|
|
222
227
|
|
|
223
228
|
if (hours.kind === 'step') {
|
|
224
|
-
|
|
229
|
+
const hourStep = stepSegment(ir, 'hour');
|
|
230
|
+
|
|
231
|
+
// "每N小时" is only faithful from midnight; an offset step (2/6 fires at
|
|
232
|
+
// 2,8,14,20) enumerates its hours instead.
|
|
233
|
+
return hourStep.startToken === '*' ?
|
|
234
|
+
cadence(hourStep.interval, UNITS.hour) + base :
|
|
235
|
+
'在' + hourList(ir) + ',' + base;
|
|
225
236
|
}
|
|
226
237
|
|
|
227
238
|
if (hours.kind === 'single' ||
|
|
@@ -242,10 +253,16 @@ function renderMinuteFrequency(ir: IR, plan: PlanNode): string {
|
|
|
242
253
|
return base;
|
|
243
254
|
}
|
|
244
255
|
|
|
245
|
-
// A minute span within a single hour
|
|
256
|
+
// A minute span within a single hour. A wildcard minute reads as that hour
|
|
257
|
+
// itself — "凌晨0点的每一分钟" — not a synthesized "在H点至H点59分之间" range the
|
|
258
|
+
// source never stated; a partial minute span keeps the named range.
|
|
246
259
|
function renderMinuteSpanInHour(ir: IR, plan: PlanNode): string {
|
|
247
260
|
const span = plan as Extract<PlanNode, {kind: 'minuteSpanInHour'}>;
|
|
248
261
|
|
|
262
|
+
if (ir.pattern.minute === '*') {
|
|
263
|
+
return hourWord(span.hour) + '的每一分钟';
|
|
264
|
+
}
|
|
265
|
+
|
|
249
266
|
return '在' + hourWord(span.hour) + '至' + span.hour + '点' +
|
|
250
267
|
span.span[1] + '分之间,每分钟';
|
|
251
268
|
}
|
|
@@ -266,15 +283,31 @@ function renderMinutesAcrossHours(ir: IR, plan: PlanNode): string {
|
|
|
266
283
|
// A minute clause across a stepped hour field. A wildcard minute reads "每2小时
|
|
267
284
|
// 内,每分钟"; a ranged minute names it: "每2小时,每小时0至30分,每分钟".
|
|
268
285
|
function renderMinuteSpanAcrossHourStep(ir: IR, plan: PlanNode): string {
|
|
269
|
-
const
|
|
286
|
+
const hourStep = stepSegment(ir, 'hour');
|
|
270
287
|
const {form} = plan as Extract<PlanNode, {kind: 'minuteSpanAcrossHourStep'}>;
|
|
288
|
+
const minuteTail = form === 'wildcard' ?
|
|
289
|
+
'每分钟' :
|
|
290
|
+
'每小时' + valueList(fieldSegments(ir, 'minute'), '分') + ',每分钟';
|
|
271
291
|
|
|
272
|
-
|
|
273
|
-
|
|
292
|
+
// An offset stride (2/6 fires at 2,8,14,20) enumerates its hours like a
|
|
293
|
+
// discrete list; "每N小时" is faithful only from midnight.
|
|
294
|
+
if (hourStep.startToken !== '*') {
|
|
295
|
+
return form === 'wildcard' ?
|
|
296
|
+
'在' + hourList(ir) + ',' + minuteTail :
|
|
297
|
+
hourList(ir) + ',' + minuteTail;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// A step-2 hour from midnight IS exactly the even hours; name them so, rather
|
|
301
|
+
// than the vague "每2小时内" that reads as an interval. Other strides keep it.
|
|
302
|
+
if (hourStep.interval === 2 && form === 'wildcard') {
|
|
303
|
+
return '在偶数小时,' + minuteTail;
|
|
274
304
|
}
|
|
275
305
|
|
|
276
|
-
|
|
277
|
-
|
|
306
|
+
const cad = cadence(hourStep.interval, UNITS.hour);
|
|
307
|
+
|
|
308
|
+
return form === 'wildcard' ?
|
|
309
|
+
cad + '内,' + minuteTail :
|
|
310
|
+
cad + ',' + minuteTail;
|
|
278
311
|
}
|
|
279
312
|
|
|
280
313
|
// Discrete clock times: "9点", "9点和17点".
|
|
@@ -323,8 +356,9 @@ function renderHourRange(ir: IR, plan: PlanNode): string {
|
|
|
323
356
|
range.last + '分之间,每分钟';
|
|
324
357
|
}
|
|
325
358
|
|
|
326
|
-
// A stepped hour field: "每2小时", or
|
|
327
|
-
//
|
|
359
|
+
// A stepped hour field: "每2小时", or its two fires as clock words when the
|
|
360
|
+
// stride fires only twice. An uneven stride (one that does not divide 24) is
|
|
361
|
+
// rewritten to its fire list upstream and never reaches here.
|
|
328
362
|
function renderHourStep(ir: IR): string {
|
|
329
363
|
const segment = stepSegment(ir, 'hour');
|
|
330
364
|
|
|
@@ -332,16 +366,11 @@ function renderHourStep(ir: IR): string {
|
|
|
332
366
|
return hourList(ir);
|
|
333
367
|
}
|
|
334
368
|
|
|
335
|
-
// A step that fires only twice reads as two clock times ("凌晨0
|
|
369
|
+
// A step that fires only twice reads as two clock times ("凌晨0点和正午").
|
|
336
370
|
if (segment.fires.length <= 2) {
|
|
337
371
|
return joinAnd(segment.fires.map(hourWord));
|
|
338
372
|
}
|
|
339
373
|
|
|
340
|
-
if (24 % segment.interval !== 0) {
|
|
341
|
-
return '从' + hourWord(segment.fires[0]) + '起,' +
|
|
342
|
-
cadence(segment.interval, UNITS.hour);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
374
|
return cadence(segment.interval, UNITS.hour);
|
|
346
375
|
}
|
|
347
376
|
|
|
@@ -421,11 +450,30 @@ function isHourCadence(ir: IR): boolean {
|
|
|
421
450
|
function composeSecondsOnHour(ir: IR, plan: PlanNode, opts: Opts): string {
|
|
422
451
|
const sec = secondClause(ir);
|
|
423
452
|
const {rest} = plan as Extract<PlanNode, {kind: 'composeSeconds'}>;
|
|
424
|
-
const restText = render(ir, rest, opts);
|
|
425
453
|
|
|
454
|
+
// The minute is pinned to 0 under a specific hour: a bare clock word ("9点")
|
|
455
|
+
// would hide the :00 and leave the second dangling ("…9点每秒"), reading as
|
|
456
|
+
// the whole hour. Fuse the seconds with the explicit clock minute ("9点0分
|
|
457
|
+
// 的每一秒"), so the one-minute confinement (60 fires in :00, not 3,600
|
|
458
|
+
// across the hour) stays visible. The daily frame leads with 每天; a weekday
|
|
459
|
+
// or date qualifier is added by describe().
|
|
426
460
|
if ((rest.kind === 'clockTimes' || rest.kind === 'compactClockTimes') &&
|
|
427
|
-
|
|
428
|
-
|
|
461
|
+
ir.pattern.minute === '0') {
|
|
462
|
+
const clocks = hourFires(ir).map(function clock(hour): string {
|
|
463
|
+
return hourWord(hour) + '0分';
|
|
464
|
+
});
|
|
465
|
+
const tail = sec === '每秒' ? '的每一秒' : '的' + sec;
|
|
466
|
+
const core = joinAnd(clocks) + tail;
|
|
467
|
+
|
|
468
|
+
return isDaily(ir) ? '每天' + core : core;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const restText = render(ir, rest, opts);
|
|
472
|
+
|
|
473
|
+
if (rest.kind === 'clockTimes' || rest.kind === 'compactClockTimes') {
|
|
474
|
+
if (isDaily(ir)) {
|
|
475
|
+
return '每天' + restText + sec;
|
|
476
|
+
}
|
|
429
477
|
}
|
|
430
478
|
|
|
431
479
|
// A stated minute (e.g. minute 0 under a sub-minute second) takes the same
|
|
@@ -465,6 +513,14 @@ function composeSecondsListed(ir: IR): string {
|
|
|
465
513
|
const sec = secondClause(ir);
|
|
466
514
|
const minutes = '每小时' + valueList(fieldSegments(ir, 'minute'), '分');
|
|
467
515
|
|
|
516
|
+
// A single restricted hour with an every-second cadence fuses the clock time
|
|
517
|
+
// with its minutes — "凌晨0点5、20、35、50分的每一秒" — rather than the "每小时"
|
|
518
|
+
// that falsely implies every hour. A non-wildcard second keeps the list form.
|
|
519
|
+
if (ir.shapes.hour === 'single' && sec === '每秒') {
|
|
520
|
+
return hourWord(hourFires(ir)[0]) +
|
|
521
|
+
valueList(fieldSegments(ir, 'minute'), '分') + '的每一秒';
|
|
522
|
+
}
|
|
523
|
+
|
|
468
524
|
if (ir.shapes.hour === 'wildcard') {
|
|
469
525
|
return minutes + ',' + sec;
|
|
470
526
|
}
|
|
@@ -478,12 +534,28 @@ function composeSecondsListed(ir: IR): string {
|
|
|
478
534
|
}
|
|
479
535
|
|
|
480
536
|
// Seconds composed with the minute/hour structure, dispatched on the minute.
|
|
537
|
+
// A single minute over a composed clock-time rest (the core already joined the
|
|
538
|
+
// lone hour and minute into "N点M分") keeps that composition, attaching the
|
|
539
|
+
// second to it rather than splitting the minute back out into the "每小时N分"
|
|
540
|
+
// list path; a minute list stays on that list path so each fire is named.
|
|
481
541
|
function renderComposeSeconds(ir: IR, plan: PlanNode, opts: Opts): string {
|
|
482
|
-
|
|
542
|
+
const {rest} = plan as Extract<PlanNode, {kind: 'composeSeconds'}>;
|
|
543
|
+
const composedClock =
|
|
544
|
+
rest.kind === 'clockTimes' || rest.kind === 'compactClockTimes';
|
|
545
|
+
|
|
546
|
+
if (ir.pattern.minute === '0' ||
|
|
547
|
+
composedClock && ir.shapes.minute === 'single') {
|
|
483
548
|
return composeSecondsOnHour(ir, plan, opts);
|
|
484
549
|
}
|
|
485
550
|
|
|
486
|
-
|
|
551
|
+
// "每N分钟" is faithful only for a wildcard or top-of-hour step; an offset
|
|
552
|
+
// step (5/15 fires at :05,:20,…) takes the enumerated list path so its start
|
|
553
|
+
// is named, never dropped.
|
|
554
|
+
const minuteCadence = ir.pattern.minute === '*' ||
|
|
555
|
+
ir.shapes.minute === 'step' &&
|
|
556
|
+
stepSegment(ir, 'minute').startToken === '*';
|
|
557
|
+
|
|
558
|
+
if (minuteCadence) {
|
|
487
559
|
return composeSecondsCadence(ir);
|
|
488
560
|
}
|
|
489
561
|
|