@hebcal/leyning 8.2.9 → 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +1671 -2155
- package/dist/bundle.min.js +14 -2
- package/dist/esm/aliyot.json.js +4 -0
- package/dist/esm/calculateHaftarahNumVerses.d.ts +1 -0
- package/dist/esm/clone.d.ts +12 -0
- package/dist/esm/clone.js +32 -0
- package/dist/esm/common.d.ts +33 -0
- package/dist/esm/common.js +94 -0
- package/dist/esm/csv.d.ts +14 -0
- package/dist/esm/csv.js +153 -0
- package/dist/esm/festival.d.ts +9 -0
- package/dist/esm/festival.js +42 -0
- package/dist/esm/getLeyningForHoliday.d.ts +17 -0
- package/dist/esm/getLeyningForHoliday.js +106 -0
- package/dist/esm/getLeyningKeyForEvent.d.ts +9 -0
- package/dist/esm/getLeyningKeyForEvent.js +141 -0
- package/dist/esm/getLeyningOnDate.d.ts +21 -0
- package/dist/esm/getLeyningOnDate.js +134 -0
- package/dist/esm/he.po.d.ts +61 -0
- package/dist/esm/he.po.js +4 -0
- package/dist/esm/holiday-readings.json.js +4 -0
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/internalTypes.d.ts +20 -0
- package/dist/esm/leyning.d.ts +30 -0
- package/dist/esm/leyning.js +203 -0
- package/dist/esm/locale.d.ts +2 -0
- package/dist/esm/locale.js +17 -0
- package/dist/esm/numverses.json.js +4 -0
- package/dist/esm/specialReadings.d.ts +15 -0
- package/dist/esm/specialReadings.js +142 -0
- package/dist/esm/summary.d.ts +18 -0
- package/dist/esm/summary.js +83 -0
- package/dist/esm/types.d.ts +130 -0
- package/dist/getLeyningForHoliday.d.ts +1 -1
- package/dist/getLeyningKeyForEvent.d.ts +1 -1
- package/dist/getLeyningOnDate.d.ts +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/leyning.d.ts +1 -1
- package/dist/locale.d.ts +2 -1
- package/dist/specialReadings.d.ts +1 -1
- package/package.json +23 -19
- package/bin/leyning-csv +0 -23
- package/dist/aliyot.json.d.ts +0 -1570
- package/dist/holiday-readings.json.d.ts +0 -2703
- package/dist/index.cjs +0 -3068
- package/dist/index.mjs +0 -3039
- package/dist/module.d.ts +0 -325
- package/dist/numverses.json.d.ts +0 -36
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*! @hebcal/leyning v9.0.1 */
|
|
2
|
+
import { calculateNumVerses } from './common.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Makes a deep copy of the src object using JSON stringify and parse
|
|
6
|
+
*/
|
|
7
|
+
function clone(src) {
|
|
8
|
+
return JSON.parse(JSON.stringify(src));
|
|
9
|
+
}
|
|
10
|
+
function cloneHaftara(haft) {
|
|
11
|
+
if (!haft) {
|
|
12
|
+
return haft;
|
|
13
|
+
}
|
|
14
|
+
const dest = clone(haft);
|
|
15
|
+
if (Array.isArray(dest)) {
|
|
16
|
+
dest.map(calculateNumVerses);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
calculateNumVerses(dest);
|
|
20
|
+
}
|
|
21
|
+
return dest;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the total number of verses in an array of Aliyah (or haftarah) objects
|
|
25
|
+
*/
|
|
26
|
+
function sumVerses(aliyot) {
|
|
27
|
+
return Array.isArray(aliyot)
|
|
28
|
+
? aliyot.reduce((prev, cur) => prev + cur.v, 0)
|
|
29
|
+
: aliyot.v;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { clone, cloneHaftara, sumVerses };
|
|
@@ -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.1 */
|
|
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;
|
package/dist/esm/csv.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/*! @hebcal/leyning v9.0.1 */
|
|
2
|
+
import { flags, HebrewCalendar, HolidayEvent, Event } from '@hebcal/core';
|
|
3
|
+
import { formatAliyahWithBook } from './common.js';
|
|
4
|
+
import { getLeyningForHoliday, getLeyningForHolidayKey } from './getLeyningForHoliday.js';
|
|
5
|
+
import { getLeyningKeyForEvent } from './getLeyningKeyForEvent.js';
|
|
6
|
+
import { getLeyningForParshaHaShavua } from './leyning.js';
|
|
7
|
+
|
|
8
|
+
const fmt = new Intl.DateTimeFormat('en-US', {
|
|
9
|
+
year: 'numeric',
|
|
10
|
+
month: 'short',
|
|
11
|
+
day: '2-digit',
|
|
12
|
+
});
|
|
13
|
+
function fmtDate(dt) {
|
|
14
|
+
const s = fmt.format(dt).split(' ');
|
|
15
|
+
return s[1].substring(0, 2) + '-' + s[0] + '-' + s[2];
|
|
16
|
+
}
|
|
17
|
+
function getParshaDates(events) {
|
|
18
|
+
const parshaEvents = events.filter(ev => ev.getFlags() === flags.PARSHA_HASHAVUA);
|
|
19
|
+
const emptyMap = {};
|
|
20
|
+
const parshaDates = parshaEvents.reduce((set, ev) => {
|
|
21
|
+
set[ev.getDate().toString()] = true;
|
|
22
|
+
return set;
|
|
23
|
+
}, emptyMap);
|
|
24
|
+
return parshaDates;
|
|
25
|
+
}
|
|
26
|
+
function writeFullKriyahCsv(stream, hyear, il) {
|
|
27
|
+
const events0 = HebrewCalendar.calendar({
|
|
28
|
+
year: hyear,
|
|
29
|
+
isHebrewYear: true,
|
|
30
|
+
sedrot: true,
|
|
31
|
+
il: il,
|
|
32
|
+
});
|
|
33
|
+
const events = events0.filter((ev) => ev.getDesc() !== 'Rosh Chodesh Tevet');
|
|
34
|
+
const parshaDates = getParshaDates(events);
|
|
35
|
+
stream.write('"Date","Parashah","Aliyah","Reading","Verses"\r\n');
|
|
36
|
+
for (const ev of events) {
|
|
37
|
+
if (ev.getFlags() === flags.PARSHA_HASHAVUA ||
|
|
38
|
+
!parshaDates[ev.getDate().toString()]) {
|
|
39
|
+
writeFullKriyahEvent(stream, ev, il);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function ignore(ev) {
|
|
44
|
+
const mask = ev.getFlags();
|
|
45
|
+
if (mask === flags.SPECIAL_SHABBAT) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (mask !== flags.ROSH_CHODESH) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return ev.getDate().getDay() === 6;
|
|
52
|
+
}
|
|
53
|
+
function writeFullKriyahEvent(stream, ev, il) {
|
|
54
|
+
if (ignore(ev)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const mask = ev.getFlags();
|
|
58
|
+
const isParsha = mask === flags.PARSHA_HASHAVUA;
|
|
59
|
+
const reading = isParsha
|
|
60
|
+
? getLeyningForParshaHaShavua(ev, il)
|
|
61
|
+
: getLeyningForHoliday(ev, il);
|
|
62
|
+
if (reading) {
|
|
63
|
+
writeCsvLines(stream, ev, reading, il, isParsha);
|
|
64
|
+
if (!isParsha) {
|
|
65
|
+
writeHolidayMincha(stream, ev, il);
|
|
66
|
+
const desc = ev.getDesc();
|
|
67
|
+
if ((il && desc === 'Sukkot VII (Hoshana Raba)') ||
|
|
68
|
+
(!il && desc === 'Shmini Atzeret')) {
|
|
69
|
+
const ev2 = new HolidayEvent(ev.getDate(), 'Erev Simchat Torah', flags.EREV);
|
|
70
|
+
writeFullKriyahEvent(stream, ev2, il);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function writeHolidayMincha(stream, ev, il) {
|
|
76
|
+
const desc = ev.getDesc();
|
|
77
|
+
const minchaDesc1 = desc + ' (Mincha)';
|
|
78
|
+
const readingMincha1 = getLeyningForHolidayKey(minchaDesc1, ev.cholHaMoedDay, il);
|
|
79
|
+
const readingMincha = readingMincha1 ||
|
|
80
|
+
getLeyningForHolidayKey(getLeyningKeyForEvent(ev, il) + ' (Mincha)', ev.cholHaMoedDay, il);
|
|
81
|
+
if (readingMincha) {
|
|
82
|
+
const minchaEv = new Event(ev.getDate(), minchaDesc1, flags.USER_EVENT);
|
|
83
|
+
writeCsvLines(stream, minchaEv, readingMincha, il, false);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Formats reading for CSV
|
|
88
|
+
*/
|
|
89
|
+
function writeCsvLines(stream, ev, reading, il, isParsha) {
|
|
90
|
+
const parsha = isParsha
|
|
91
|
+
? ev.basename()
|
|
92
|
+
: getLeyningKeyForEvent(ev, il) || ev.render();
|
|
93
|
+
const date = fmtDate(ev.getDate().greg());
|
|
94
|
+
const lines = getFullKriyahLines(reading);
|
|
95
|
+
for (const s of lines) {
|
|
96
|
+
const code = s[0].charCodeAt(0);
|
|
97
|
+
if (code < 48 || code > 57) {
|
|
98
|
+
s[0] = `"${s[0]}"`;
|
|
99
|
+
}
|
|
100
|
+
stream.write(`${date},"${parsha}",${s[0]},"${s[1]}",${s[2]}\r\n`);
|
|
101
|
+
}
|
|
102
|
+
stream.write('\r\n');
|
|
103
|
+
}
|
|
104
|
+
function getFullKriyahLines(reading) {
|
|
105
|
+
var _a, _b, _c;
|
|
106
|
+
const lines = [];
|
|
107
|
+
if (reading.fullkriyah) {
|
|
108
|
+
for (const [num, a] of Object.entries(reading.fullkriyah)) {
|
|
109
|
+
if (typeof a !== 'undefined') {
|
|
110
|
+
const k = num === 'M' ? 'maf' : num;
|
|
111
|
+
let aliyah = formatAliyahWithBook(a);
|
|
112
|
+
if ((_a = reading.reason) === null || _a === void 0 ? void 0 : _a[num]) {
|
|
113
|
+
aliyah += ' | ' + reading.reason[num];
|
|
114
|
+
}
|
|
115
|
+
lines.push([k, aliyah, a.v || '']);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (reading.haftara) {
|
|
120
|
+
let haftara = reading.haftara.replace(/,/g, ';');
|
|
121
|
+
if ((_b = reading.reason) === null || _b === void 0 ? void 0 : _b.haftara) {
|
|
122
|
+
haftara += ' | ' + reading.reason.haftara;
|
|
123
|
+
}
|
|
124
|
+
const title = reading.sephardic ? 'Haftara for Ashkenazim' : 'Haftara';
|
|
125
|
+
lines.push([title, haftara, reading.haftaraNumV || '']);
|
|
126
|
+
}
|
|
127
|
+
if (reading.sephardic) {
|
|
128
|
+
let sephardic = reading.sephardic.replace(/,/g, ';');
|
|
129
|
+
if ((_c = reading.reason) === null || _c === void 0 ? void 0 : _c.sephardic) {
|
|
130
|
+
sephardic += ' | ' + reading.reason.sephardic;
|
|
131
|
+
}
|
|
132
|
+
lines.push([
|
|
133
|
+
'Haftara for Sephardim',
|
|
134
|
+
sephardic,
|
|
135
|
+
reading.sephardicNumV || '',
|
|
136
|
+
]);
|
|
137
|
+
}
|
|
138
|
+
if (reading.triHaftara) {
|
|
139
|
+
const haftara = reading.triHaftara.replace(/,/g, ';');
|
|
140
|
+
lines.push(['Alternate Haftara', haftara, reading.triHaftaraNumV || '']);
|
|
141
|
+
}
|
|
142
|
+
if (reading.megillah) {
|
|
143
|
+
for (const [num, a] of Object.entries(reading.megillah)) {
|
|
144
|
+
if (typeof a !== 'undefined') {
|
|
145
|
+
const aliyah = formatAliyahWithBook(a);
|
|
146
|
+
lines.push([`Megillah Ch. ${num}`, aliyah, a.v || '']);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return lines;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export { getParshaDates, writeCsvLines, writeFullKriyahCsv, writeFullKriyahEvent, writeHolidayMincha };
|
|
@@ -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.1 */
|
|
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.1 */
|
|
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.1 */
|
|
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)[];
|