@hebcal/leyning 8.2.9 → 9.0.0

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.
Files changed (47) hide show
  1. package/dist/bundle.js +1660 -2155
  2. package/dist/bundle.min.js +2 -2
  3. package/dist/esm/aliyot.json.js +4 -0
  4. package/dist/esm/calculateHaftarahNumVerses.d.ts +1 -0
  5. package/dist/esm/clone.d.ts +12 -0
  6. package/dist/esm/clone.js +32 -0
  7. package/dist/esm/common.d.ts +33 -0
  8. package/dist/esm/common.js +94 -0
  9. package/dist/esm/csv.d.ts +14 -0
  10. package/dist/esm/festival.d.ts +9 -0
  11. package/dist/esm/festival.js +42 -0
  12. package/dist/esm/getLeyningForHoliday.d.ts +17 -0
  13. package/dist/esm/getLeyningForHoliday.js +106 -0
  14. package/dist/esm/getLeyningKeyForEvent.d.ts +9 -0
  15. package/dist/esm/getLeyningKeyForEvent.js +141 -0
  16. package/dist/esm/getLeyningOnDate.d.ts +21 -0
  17. package/dist/esm/getLeyningOnDate.js +134 -0
  18. package/dist/esm/he.po.d.ts +61 -0
  19. package/dist/esm/he.po.js +4 -0
  20. package/dist/esm/holiday-readings.json.js +4 -0
  21. package/dist/esm/index.d.ts +11 -0
  22. package/dist/esm/index.js +12 -0
  23. package/dist/esm/internalTypes.d.ts +20 -0
  24. package/dist/esm/leyning.d.ts +30 -0
  25. package/dist/esm/leyning.js +203 -0
  26. package/dist/esm/locale.d.ts +2 -0
  27. package/dist/esm/locale.js +17 -0
  28. package/dist/esm/numverses.json.js +4 -0
  29. package/dist/esm/specialReadings.d.ts +15 -0
  30. package/dist/esm/specialReadings.js +142 -0
  31. package/dist/esm/summary.d.ts +18 -0
  32. package/dist/esm/summary.js +83 -0
  33. package/dist/esm/types.d.ts +130 -0
  34. package/dist/getLeyningForHoliday.d.ts +1 -1
  35. package/dist/getLeyningKeyForEvent.d.ts +1 -1
  36. package/dist/getLeyningOnDate.d.ts +1 -1
  37. package/dist/index.cjs +47 -2147
  38. package/dist/index.d.ts +1 -2
  39. package/dist/leyning.d.ts +1 -1
  40. package/dist/locale.d.ts +2 -1
  41. package/dist/specialReadings.d.ts +1 -1
  42. package/package.json +21 -13
  43. package/dist/aliyot.json.d.ts +0 -1570
  44. package/dist/holiday-readings.json.d.ts +0 -2703
  45. package/dist/index.mjs +0 -3039
  46. package/dist/module.d.ts +0 -325
  47. package/dist/numverses.json.d.ts +0 -36
@@ -0,0 +1,33 @@
1
+ import { Aliyah } from './types';
2
+ /**
3
+ * Names of the books of the Torah. BOOK[1] === 'Genesis'
4
+ * @readonly
5
+ */
6
+ export declare const BOOK: readonly ["", "Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy"];
7
+ /**
8
+ * The number of verses in each book of the Tanakh.
9
+ * @readonly
10
+ */
11
+ export declare const NUM_VERSES: NumVerses;
12
+ export type NumVerses = {
13
+ readonly [book: string]: readonly number[];
14
+ };
15
+ /**
16
+ * Formats parsha as a string
17
+ * @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
18
+ */
19
+ export declare function parshaToString(parsha: string | string[]): string;
20
+ /**
21
+ * Calculates the number of verses in an aliyah or haftara based on
22
+ * the `b` (begin verse), `e` (end verse) and `k` (book).
23
+ * Modifies `aliyah` by setting the `v` field.
24
+ */
25
+ export declare function calculateNumVerses(aliyah: Aliyah): number;
26
+ /**
27
+ * Formats an aliyah object like "Numbers 28:9-28:15"
28
+ */
29
+ export declare function formatAliyahWithBook(a: Aliyah): string;
30
+ /**
31
+ * Formats an aliyah object like "Numbers 28:9-15"
32
+ */
33
+ export declare function formatAliyahShort(aliyah: Aliyah, showBook: boolean): string;
@@ -0,0 +1,94 @@
1
+ /*! @hebcal/leyning v9.0.0 */
2
+ import numverses from './numverses.json.js';
3
+
4
+ /**
5
+ * Names of the books of the Torah. BOOK[1] === 'Genesis'
6
+ * @readonly
7
+ */
8
+ const BOOK = [
9
+ '',
10
+ 'Genesis',
11
+ 'Exodus',
12
+ 'Leviticus',
13
+ 'Numbers',
14
+ 'Deuteronomy',
15
+ ];
16
+ /**
17
+ * The number of verses in each book of the Tanakh.
18
+ * @readonly
19
+ */
20
+ const NUM_VERSES = numverses;
21
+ /**
22
+ * Formats parsha as a string
23
+ * @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
24
+ */
25
+ function parshaToString(parsha) {
26
+ if (typeof parsha === 'string') {
27
+ return parsha;
28
+ }
29
+ else if (!Array.isArray(parsha) ||
30
+ parsha.length === 0 ||
31
+ parsha.length > 2) {
32
+ throw new TypeError(`Bad parsha argument: ${parsha}`);
33
+ }
34
+ let s = parsha[0];
35
+ if (parsha.length === 2) {
36
+ s += '-' + parsha[1];
37
+ }
38
+ return s;
39
+ }
40
+ /**
41
+ * Calculates the number of verses in an aliyah or haftara based on
42
+ * the `b` (begin verse), `e` (end verse) and `k` (book).
43
+ * Modifies `aliyah` by setting the `v` field.
44
+ */
45
+ function calculateNumVerses(aliyah) {
46
+ if (aliyah.v) {
47
+ return aliyah.v;
48
+ }
49
+ const chapVerseBegin = aliyah.b.split(':');
50
+ const chapVerseEnd = aliyah.e.split(':');
51
+ const c1 = parseInt(chapVerseBegin[0], 10);
52
+ const c2 = parseInt(chapVerseEnd[0], 10);
53
+ const v1 = parseInt(chapVerseBegin[1], 10);
54
+ const v2 = parseInt(chapVerseEnd[1], 10);
55
+ if (c1 === c2) {
56
+ aliyah.v = v2 - v1 + 1;
57
+ }
58
+ else if (typeof aliyah.k === 'string') {
59
+ const numv = NUM_VERSES[aliyah.k];
60
+ if (typeof numv !== 'object' || !numv.length) {
61
+ throw new ReferenceError(`Can't find numverses for ${aliyah.k}`);
62
+ }
63
+ let total = numv[c1] - v1 + 1;
64
+ for (let chap = c1 + 1; chap < c2; chap++) {
65
+ total += numv[chap];
66
+ }
67
+ total += v2;
68
+ aliyah.v = total;
69
+ }
70
+ return aliyah.v;
71
+ }
72
+ /**
73
+ * Formats an aliyah object like "Numbers 28:9-28:15"
74
+ */
75
+ function formatAliyahWithBook(a) {
76
+ return `${a.k} ${a.b}-${a.e}`;
77
+ }
78
+ /**
79
+ * Formats an aliyah object like "Numbers 28:9-15"
80
+ */
81
+ function formatAliyahShort(aliyah, showBook) {
82
+ const begin = aliyah.b;
83
+ const end0 = aliyah.e;
84
+ const prefix = showBook ? aliyah.k + ' ' : '';
85
+ if (begin === end0) {
86
+ return `${prefix}${begin}`;
87
+ }
88
+ const cv1 = begin.split(':');
89
+ const cv2 = end0.split(':');
90
+ const end = cv1[0] === cv2[0] ? cv2[1] : end0;
91
+ return `${prefix}${begin}-${end}`;
92
+ }
93
+
94
+ export { BOOK, NUM_VERSES, calculateNumVerses, formatAliyahShort, formatAliyahWithBook, parshaToString };
@@ -0,0 +1,14 @@
1
+ import { Event, HolidayEvent } from '@hebcal/core';
2
+ import { WriteStream } from 'node:fs';
3
+ import { Leyning } from './types';
4
+ export interface StringToBoolMap {
5
+ [key: string]: boolean;
6
+ }
7
+ export declare function getParshaDates(events: Event[]): StringToBoolMap;
8
+ export declare function writeFullKriyahCsv(stream: WriteStream, hyear: number, il: boolean): void;
9
+ export declare function writeFullKriyahEvent(stream: WriteStream, ev: Event, il: boolean): void;
10
+ export declare function writeHolidayMincha(stream: WriteStream, ev: HolidayEvent, il: boolean): void;
11
+ /**
12
+ * Formats reading for CSV
13
+ */
14
+ export declare function writeCsvLines(stream: WriteStream, ev: Event, reading: Leyning, il: boolean, isParsha: boolean): void;
@@ -0,0 +1,9 @@
1
+ import { JsonFestivalLeyning } from './internalTypes';
2
+ /**
3
+ * Is there a special festival Torah Reading for `holiday`?
4
+ */
5
+ export declare function hasFestival(holiday: string): boolean;
6
+ /**
7
+ * Returns the raw metadata for festival reading for `holiday`
8
+ */
9
+ export declare function lookupFestival(holiday: string): JsonFestivalLeyning | undefined;
@@ -0,0 +1,42 @@
1
+ /*! @hebcal/leyning v9.0.0 */
2
+ import { BOOK } from './common.js';
3
+ import { clone } from './clone.js';
4
+ import festivals0 from './holiday-readings.json.js';
5
+
6
+ const festivals = festivals0;
7
+ /**
8
+ * Is there a special festival Torah Reading for `holiday`?
9
+ */
10
+ function hasFestival(holiday) {
11
+ return typeof festivals[holiday] === 'object';
12
+ }
13
+ /**
14
+ * Returns the raw metadata for festival reading for `holiday`
15
+ */
16
+ function lookupFestival(holiday) {
17
+ let src = festivals[holiday];
18
+ if (typeof src === 'undefined') {
19
+ return undefined;
20
+ }
21
+ if (src.alias) {
22
+ const tmp = festivals[src.key];
23
+ if (typeof tmp === 'undefined') {
24
+ throw new Error(`Leyning alias ${holiday} => ${src.key} not found`);
25
+ }
26
+ src = tmp;
27
+ }
28
+ const result = src.fullkriyah ? clone(src) : src;
29
+ if (result.fullkriyah) {
30
+ for (const aliyah of Object.values(result.fullkriyah)) {
31
+ if (typeof aliyah.k === 'number') {
32
+ aliyah.k = BOOK[aliyah.k];
33
+ }
34
+ }
35
+ }
36
+ if (src.note) {
37
+ result.note = src.note;
38
+ }
39
+ return result;
40
+ }
41
+
42
+ export { hasFestival, lookupFestival };
@@ -0,0 +1,17 @@
1
+ import { Event } from '@hebcal/core/dist/esm/event';
2
+ import { Leyning } from './types';
3
+ /**
4
+ * Looks up leyning for a given holiday key. Key should be an
5
+ * (untranslated) string used in holiday-readings.json. Returns some
6
+ * of full kriyah aliyot, special Maftir, special Haftarah
7
+ * @param key name from `holiday-readings.json` to find
8
+ */
9
+ export declare function getLeyningForHolidayKey(key?: string, cholHaMoedDay?: number, il?: boolean): Leyning | undefined;
10
+ /**
11
+ * Looks up leyning for a given holiday. Returns some
12
+ * of full kriyah aliyot, special Maftir, special Haftarah
13
+ * @param ev the Hebcal event associated with this leyning
14
+ * @param [il] true if Israel holiday scheme
15
+ * @returns map of aliyot
16
+ */
17
+ export declare function getLeyningForHoliday(ev: Event, il?: boolean): Leyning | undefined;
@@ -0,0 +1,106 @@
1
+ /*! @hebcal/leyning v9.0.0 */
2
+ import { flags } from '@hebcal/core/dist/esm/event';
3
+ import './locale.js';
4
+ import { calculateNumVerses, NUM_VERSES } from './common.js';
5
+ import { clone, cloneHaftara, sumVerses } from './clone.js';
6
+ import { lookupFestival } from './festival.js';
7
+ import { HOLIDAY_IGNORE_MASK, getLeyningKeyForEvent } from './getLeyningKeyForEvent.js';
8
+ import { makeLeyningParts, makeSummaryFromParts } from './summary.js';
9
+ import { Locale } from '@hebcal/core/dist/esm/locale';
10
+
11
+ /**
12
+ * Looks up leyning for a given holiday key. Key should be an
13
+ * (untranslated) string used in holiday-readings.json. Returns some
14
+ * of full kriyah aliyot, special Maftir, special Haftarah
15
+ * @param key name from `holiday-readings.json` to find
16
+ */
17
+ function getLeyningForHolidayKey(key, cholHaMoedDay, il) {
18
+ if (typeof key !== 'string') {
19
+ return undefined;
20
+ }
21
+ const src = lookupFestival(key);
22
+ if (typeof src === 'undefined') {
23
+ return undefined;
24
+ }
25
+ const israelOnly = src.il;
26
+ if (typeof israelOnly === 'boolean' &&
27
+ typeof il === 'boolean' &&
28
+ il !== israelOnly) {
29
+ return undefined;
30
+ }
31
+ const leyning = {
32
+ name: {
33
+ en: key,
34
+ he: Locale.lookupTranslation(key, 'he'),
35
+ },
36
+ };
37
+ if (src.fullkriyah) {
38
+ leyning.fullkriyah = clone(src.fullkriyah);
39
+ if (key === 'Sukkot Shabbat Chol ha-Moed' && cholHaMoedDay) {
40
+ leyning.fullkriyah['M'] = leyning.fullkriyah[`M-day${cholHaMoedDay}`];
41
+ for (let day = 1; day <= 5; day++) {
42
+ delete leyning.fullkriyah[`M-day${day}`];
43
+ }
44
+ }
45
+ if (typeof leyning.fullkriyah['1'] === 'object') {
46
+ const parts = makeLeyningParts(leyning.fullkriyah);
47
+ leyning.summary = makeSummaryFromParts(parts);
48
+ if (parts.length > 1) {
49
+ leyning.summaryParts = parts;
50
+ }
51
+ }
52
+ Object.values(leyning.fullkriyah).map(aliyah => calculateNumVerses(aliyah));
53
+ }
54
+ if (src.haft) {
55
+ const haft = (leyning.haft = cloneHaftara(src.haft));
56
+ leyning.haftara = makeSummaryFromParts(haft);
57
+ leyning.haftaraNumV = sumVerses(haft);
58
+ }
59
+ if (src.seph) {
60
+ const seph = (leyning.seph = cloneHaftara(src.seph));
61
+ leyning.sephardic = makeSummaryFromParts(seph);
62
+ leyning.sephardicNumV = sumVerses(seph);
63
+ }
64
+ let megillah = src.megillah;
65
+ if (il && key === 'Pesach I (on Shabbat)')
66
+ megillah = 'Song of Songs';
67
+ if (megillah) {
68
+ const chaps = NUM_VERSES[megillah];
69
+ const m = {};
70
+ for (let i = 1; i < chaps.length; i++) {
71
+ const numv = chaps[i];
72
+ m[`${i}`] = { k: megillah, b: `${i}:1`, e: `${i}:${numv}`, v: numv };
73
+ }
74
+ leyning.megillah = m;
75
+ }
76
+ if (src.note) {
77
+ leyning.note = src.note;
78
+ }
79
+ return leyning;
80
+ }
81
+ /**
82
+ * Looks up leyning for a given holiday. Returns some
83
+ * of full kriyah aliyot, special Maftir, special Haftarah
84
+ * @param ev the Hebcal event associated with this leyning
85
+ * @param [il] true if Israel holiday scheme
86
+ * @returns map of aliyot
87
+ */
88
+ function getLeyningForHoliday(ev, il = false) {
89
+ if (typeof ev !== 'object' || typeof ev.getFlags !== 'function') {
90
+ throw new TypeError(`Bad event argument: ${JSON.stringify(ev)}`);
91
+ }
92
+ else if (typeof ev.eventTime !== 'undefined') {
93
+ return undefined;
94
+ }
95
+ else if (ev.getFlags() & flags.PARSHA_HASHAVUA) {
96
+ throw new TypeError(`Event should be a holiday: ${ev.getDesc()}`);
97
+ }
98
+ else if (ev.getFlags() & HOLIDAY_IGNORE_MASK) {
99
+ return undefined;
100
+ }
101
+ const key = getLeyningKeyForEvent(ev, il);
102
+ const leyning = getLeyningForHolidayKey(key, ev.cholHaMoedDay, il);
103
+ return leyning;
104
+ }
105
+
106
+ export { getLeyningForHoliday, getLeyningForHolidayKey };
@@ -0,0 +1,9 @@
1
+ import { Event } from '@hebcal/core/dist/esm/event';
2
+ export declare const HOLIDAY_IGNORE_MASK: number;
3
+ /**
4
+ * Based on the event date, type and title, finds the relevant leyning key
5
+ * @param ev event
6
+ * @param [il] true if Israel holiday scheme
7
+ * @returns key to look up in holiday-reading.json
8
+ */
9
+ export declare function getLeyningKeyForEvent(ev: Event, il?: boolean): string | undefined;
@@ -0,0 +1,141 @@
1
+ /*! @hebcal/leyning v9.0.0 */
2
+ import { months, HDate } from '@hebcal/hdate';
3
+ import { flags } from '@hebcal/core/dist/esm/event';
4
+ import { hasFestival } from './festival.js';
5
+
6
+ const HOLIDAY_IGNORE_MASK = flags.DAF_YOMI |
7
+ flags.OMER_COUNT |
8
+ flags.SHABBAT_MEVARCHIM |
9
+ flags.MOLAD |
10
+ flags.USER_EVENT |
11
+ flags.HEBREW_DATE |
12
+ flags.MISHNA_YOMI |
13
+ flags.MODERN_HOLIDAY |
14
+ flags.YERUSHALMI_YOMI;
15
+ /**
16
+ * Based on the event date, type and title, finds the relevant leyning key
17
+ * @param ev event
18
+ * @param [il] true if Israel holiday scheme
19
+ * @returns key to look up in holiday-reading.json
20
+ */
21
+ function getLeyningKeyForEvent(ev, il = false) {
22
+ if (typeof ev.eventTime !== 'undefined') {
23
+ return undefined;
24
+ }
25
+ const mask = ev.getFlags();
26
+ if (mask & HOLIDAY_IGNORE_MASK) {
27
+ return undefined;
28
+ }
29
+ // Skip all Erevs except for Simchat Torah
30
+ const desc = ev.getDesc();
31
+ if (mask & flags.EREV && !hasFestival(desc)) {
32
+ return undefined;
33
+ }
34
+ const hd = ev.getDate();
35
+ const day = hd.getDate();
36
+ const dow = hd.abs() % 7;
37
+ const month = hd.getMonth();
38
+ const isShabbat = dow === 6;
39
+ const isRoshChodesh = day === 1 || day === 30;
40
+ const holiday = ev.basename();
41
+ const isPesach = holiday === 'Pesach';
42
+ if (il && isPesach) {
43
+ if (isShabbat) {
44
+ return day === 15 || day === 21
45
+ ? desc + ' (on Shabbat)'
46
+ : 'Pesach Shabbat Chol ha-Moed';
47
+ }
48
+ return desc;
49
+ }
50
+ if (day === 1 && month === months.TISHREI) {
51
+ return isShabbat ? 'Rosh Hashana I (on Shabbat)' : 'Rosh Hashana I';
52
+ }
53
+ const cholHaMoedDay = ev.cholHaMoedDay;
54
+ if (typeof cholHaMoedDay === 'number') {
55
+ // Sukkot or Pesach
56
+ if (isShabbat) {
57
+ return holiday + ' Shabbat Chol ha-Moed';
58
+ }
59
+ else if (desc === 'Sukkot VII (Hoshana Raba)') {
60
+ return 'Sukkot Final Day (Hoshana Raba)';
61
+ }
62
+ if (isPesach && cholHaMoedDay) {
63
+ if (dow === 0 && desc === "Pesach IV (CH''M)") {
64
+ return 'Pesach Chol ha-Moed Day 2 on Sunday';
65
+ }
66
+ else if (dow === 1 && desc === "Pesach V (CH''M)") {
67
+ return 'Pesach Chol ha-Moed Day 3 on Monday';
68
+ }
69
+ }
70
+ return `${holiday} Chol ha-Moed Day ${cholHaMoedDay}`;
71
+ }
72
+ const chanukahDay = ev.chanukahDay;
73
+ if (typeof chanukahDay === 'number') {
74
+ if (isShabbat && isRoshChodesh) {
75
+ return 'Shabbat Rosh Chodesh Chanukah';
76
+ }
77
+ else if (isRoshChodesh && chanukahDay === 7) {
78
+ return 'Chanukah Day 7 (on Rosh Chodesh)';
79
+ }
80
+ else if (isShabbat) {
81
+ return `Chanukah Day ${chanukahDay} (on Shabbat)`;
82
+ }
83
+ else {
84
+ return `Chanukah Day ${chanukahDay}`;
85
+ }
86
+ }
87
+ if (isRoshChodesh &&
88
+ (desc === 'Shabbat HaChodesh' || desc === 'Shabbat Shekalim')) {
89
+ return desc + ' (on Rosh Chodesh)';
90
+ }
91
+ if (il && desc === 'Shmini Atzeret') {
92
+ return 'Simchat Torah' + (isShabbat ? ' (on Shabbat)' : '');
93
+ }
94
+ if (desc === 'Chag HaBanot') {
95
+ return undefined;
96
+ }
97
+ if (isShabbat && 'Shabbat' !== desc.substring(0, 7)) {
98
+ if (isRoshChodesh) {
99
+ if (desc === 'Rosh Chodesh Tevet') {
100
+ return 'Shabbat Rosh Chodesh Chanukah';
101
+ }
102
+ return 'Shabbat Rosh Chodesh';
103
+ }
104
+ const desc2 = desc + ' (on Shabbat)';
105
+ if (hasFestival(desc2)) {
106
+ return desc2;
107
+ }
108
+ }
109
+ if (hasFestival(desc)) {
110
+ return desc;
111
+ }
112
+ if (isShabbat) {
113
+ const tommorow = hd.next().getDate();
114
+ if (tommorow === 30 || tommorow === 1) {
115
+ return 'Shabbat Machar Chodesh';
116
+ }
117
+ }
118
+ if (desc === 'Rosh Hashana LaBehemot') {
119
+ return undefined;
120
+ }
121
+ if (desc === 'Rosh Chodesh Tevet') {
122
+ if (isShabbat) {
123
+ return 'Shabbat Rosh Chodesh Chanukah';
124
+ }
125
+ if (day === 30 || HDate.shortKislev(hd.getFullYear())) {
126
+ return 'Chanukah Day 6'; // 30th of Kislev or 1st of Tevet
127
+ }
128
+ else {
129
+ return 'Chanukah Day 7 (on Rosh Chodesh)'; // 1st of Tevet
130
+ }
131
+ }
132
+ if (isRoshChodesh) {
133
+ return desc;
134
+ }
135
+ if (desc === "Tish'a B'Av (observed)") {
136
+ return "Tish'a B'Av";
137
+ }
138
+ return undefined;
139
+ }
140
+
141
+ export { HOLIDAY_IGNORE_MASK, getLeyningKeyForEvent };
@@ -0,0 +1,21 @@
1
+ import { HDate } from '@hebcal/hdate';
2
+ import { Leyning, LeyningWeekday } from './types';
3
+ /**
4
+ * Looks up leyning for a regular Shabbat, Monday/Thursday weekday or holiday.
5
+ *
6
+ * If `hdate` coincides with a holiday that has Torah reading, returns the
7
+ * reading for that day (see {@link getLeyningForHoliday})
8
+ *
9
+ * Otherwise, if `hdate` is a Saturday, returns {@link getLeyningForParshaHaShavua}
10
+ *
11
+ * Otherwise, if `hdate` is a Monday or Thursday, returns {@link Leyning} for the
12
+ * Parashat haShavua, containing only the `weekday` aliyot (no `fullkriyah`).
13
+ *
14
+ * Otherwise, returns `undefined`.
15
+ *
16
+ * @param {HDate} hdate Hebrew Date
17
+ * @param {boolean} il in Israel
18
+ * @param {boolean} [wantarray] to return an array of 0 or more readings
19
+ */
20
+ export declare function getLeyningOnDate(hdate: HDate, il: boolean, wantarray?: false): Leyning | LeyningWeekday | undefined;
21
+ export declare function getLeyningOnDate(hdate: HDate, il: boolean, wantarray: true): (Leyning | LeyningWeekday)[];
@@ -0,0 +1,134 @@
1
+ /*! @hebcal/leyning v9.0.0 */
2
+ import { months, HDate } from '@hebcal/hdate';
3
+ import { flags } from '@hebcal/core/dist/esm/event';
4
+ import { getLeyningForHoliday, getLeyningForHolidayKey } from './getLeyningForHoliday.js';
5
+ import { getLeyningKeyForEvent } from './getLeyningKeyForEvent.js';
6
+ import { getLeyningForParshaHaShavua, getWeekdayReading, makeLeyningNames } from './leyning.js';
7
+ import { makeLeyningParts, makeSummaryFromParts } from './summary.js';
8
+ import { getSedra } from '@hebcal/core/dist/esm/sedra';
9
+ import { getHolidaysOnDate } from '@hebcal/core/dist/esm/holidays';
10
+ import { ParshaEvent } from '@hebcal/core/dist/esm/ParshaEvent';
11
+
12
+ function findParshaHaShavua(saturday, il) {
13
+ const hyear = saturday.getFullYear();
14
+ const sedra = getSedra(hyear, il);
15
+ const parsha = sedra.lookup(saturday);
16
+ if (!parsha.chag) {
17
+ return parsha;
18
+ }
19
+ // Special case between YK and Simchat Torah
20
+ // If Vayeilech or Ha'azinu occurs between RH and YK, the following block for
21
+ // Monday/Thursday weekday isn't executed because the above sedra.lookup()
22
+ // would have already found the regular Saturday parsha.
23
+ if (saturday.getMonth() === months.TISHREI) {
24
+ const dd = saturday.getDate();
25
+ const simchatTorah = il ? 22 : 23;
26
+ if (dd > 2 && dd <= simchatTorah) {
27
+ return {
28
+ parsha: ['Vezot Haberakhah'],
29
+ chag: false,
30
+ num: 54,
31
+ hdate: saturday,
32
+ };
33
+ }
34
+ }
35
+ // Search for next regular parsha, which could even spill into next year
36
+ const endOfYear = new HDate(1, months.TISHREI, hyear + 1).abs() - 1;
37
+ const endAbs = endOfYear + 30;
38
+ for (let sat2 = saturday.abs() + 7; sat2 <= endAbs; sat2 += 7) {
39
+ const sedra2 = sat2 > endOfYear ? getSedra(hyear + 1, il) : sedra;
40
+ const parsha2 = sedra2.lookup(sat2);
41
+ if (!parsha2.chag) {
42
+ return parsha2;
43
+ }
44
+ }
45
+ /* NOTREACHED */
46
+ throw new Error(`can't findParshaHaShavua for ${saturday}/${il}`);
47
+ }
48
+ function getLeyningOnDate(hdate, il, wantarray = false) {
49
+ const dow = hdate.getDay();
50
+ const arr = [];
51
+ let hasParshaHaShavua = false;
52
+ if (dow === 6) {
53
+ const hyear = hdate.getFullYear();
54
+ const sedra = getSedra(hyear, il);
55
+ const parsha = sedra.lookup(hdate);
56
+ if (!parsha.chag) {
57
+ const parshaEvent = new ParshaEvent(hdate, parsha.parsha, il);
58
+ const reading = getLeyningForParshaHaShavua(parshaEvent, il);
59
+ if (wantarray) {
60
+ hasParshaHaShavua = true;
61
+ arr.push(reading);
62
+ }
63
+ else {
64
+ return reading;
65
+ }
66
+ }
67
+ }
68
+ const events = getHolidaysOnDate(hdate, il) || [];
69
+ let hasFullKriyah = false;
70
+ for (const ev of events) {
71
+ const specialShabbat = Boolean(ev.getFlags() & (flags.SPECIAL_SHABBAT | flags.ROSH_CHODESH));
72
+ if (hasParshaHaShavua && specialShabbat) {
73
+ continue;
74
+ }
75
+ const reading = getLeyningForHoliday(ev, il);
76
+ if (reading) {
77
+ // Skip duplicate readings from overlapping events (eg, Rosh Chodesh + Chanukah)
78
+ if (arr.some(r => r.name.en === reading.name.en))
79
+ continue;
80
+ const fk = reading.fullkriyah;
81
+ if (fk) {
82
+ hasFullKriyah = true;
83
+ }
84
+ const specialMaftirOnly = hasParshaHaShavua && hasFullKriyah && fk.M && !fk['1'];
85
+ if (!specialMaftirOnly) {
86
+ arr.push(reading);
87
+ }
88
+ const mincha = getMincha(ev, il);
89
+ if (mincha) {
90
+ arr.push(mincha);
91
+ }
92
+ // Special case for Erev Simchat Torah - the only time we read Torah at night
93
+ const desc = ev.getDesc();
94
+ if ((il && desc === 'Sukkot VII (Hoshana Raba)') ||
95
+ (!il && desc === 'Shmini Atzeret')) {
96
+ const erevST = getLeyningForHolidayKey('Erev Simchat Torah');
97
+ arr.push(erevST);
98
+ }
99
+ }
100
+ }
101
+ if (!hasFullKriyah && (dow === 1 || dow === 4)) {
102
+ const saturday = hdate.onOrAfter(6);
103
+ const parsha = findParshaHaShavua(saturday, il);
104
+ const aliyot = getWeekdayReading(parsha.parsha);
105
+ const parts = makeLeyningParts(aliyot);
106
+ const reading = {
107
+ name: makeLeyningNames(parsha.parsha),
108
+ parsha: parsha.parsha,
109
+ parshaNum: parsha.num,
110
+ weekday: aliyot,
111
+ summary: makeSummaryFromParts(parts),
112
+ };
113
+ arr.unshift(reading);
114
+ }
115
+ return wantarray ? arr : arr[0];
116
+ }
117
+ const minchaSuffix = ' (Mincha)';
118
+ function getMincha(ev, il) {
119
+ const desc = ev.getDesc() + minchaSuffix;
120
+ const reading1 = getLeyningForHolidayKey(desc, ev.cholHaMoedDay, il);
121
+ if (reading1) {
122
+ return reading1;
123
+ }
124
+ const desc2 = getLeyningKeyForEvent(ev, il);
125
+ if (desc2) {
126
+ const reading2 = getLeyningForHolidayKey(desc2 + minchaSuffix, ev.cholHaMoedDay, il);
127
+ if (reading2) {
128
+ return reading2;
129
+ }
130
+ }
131
+ return undefined;
132
+ }
133
+
134
+ export { getLeyningOnDate };