@hebcal/leyning 9.6.0 → 10.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.
- package/dist/esm/aliyot.json.d.ts +1574 -0
- package/dist/esm/aliyot.json.js +1250 -5
- package/dist/esm/aliyot.json.js.map +1 -1
- package/dist/esm/ashkenazi.po.js +2 -5
- package/dist/esm/ashkenazi.po.js.map +1 -1
- package/dist/esm/calculateHaftarahNumVerses.js +36 -0
- package/dist/esm/calculateHaftarahNumVerses.js.map +1 -0
- package/dist/esm/clone.d.ts +2 -7
- package/dist/esm/clone.js +3 -14
- package/dist/esm/clone.js.map +1 -1
- package/dist/esm/common.d.ts +1 -1
- package/dist/esm/common.js +8 -12
- package/dist/esm/common.js.map +1 -1
- package/dist/esm/csv.d.ts +1 -1
- package/dist/esm/csv.js +8 -12
- package/dist/esm/csv.js.map +1 -1
- package/dist/esm/festival.d.ts +1 -1
- package/dist/esm/festival.js +3 -7
- package/dist/esm/festival.js.map +1 -1
- package/dist/esm/format.d.ts +1 -1
- package/dist/esm/format.js +4 -9
- package/dist/esm/format.js.map +1 -1
- package/dist/esm/getLeyningForHoliday.d.ts +1 -1
- package/dist/esm/getLeyningForHoliday.js +5 -10
- package/dist/esm/getLeyningForHoliday.js.map +1 -1
- package/dist/esm/getLeyningKeyForEvent.js +5 -9
- package/dist/esm/getLeyningKeyForEvent.js.map +1 -1
- package/dist/esm/getLeyningOnDate.d.ts +1 -1
- package/dist/esm/getLeyningOnDate.js +5 -9
- package/dist/esm/getLeyningOnDate.js.map +1 -1
- package/dist/esm/he-x-NoNikud.po.js +2 -5
- package/dist/esm/he-x-NoNikud.po.js.map +1 -1
- package/dist/esm/he.po.js +2 -5
- package/dist/esm/he.po.js.map +1 -1
- package/dist/esm/holiday-readings.json.d.ts +2786 -0
- package/dist/esm/holiday-readings.json.js +650 -5
- package/dist/esm/holiday-readings.json.js.map +1 -1
- package/dist/esm/index.d.ts +13 -13
- package/dist/esm/index.js +12 -11
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internalTypes.d.ts +1 -1
- package/dist/esm/internalTypes.js +2 -0
- package/dist/esm/internalTypes.js.map +1 -0
- package/dist/esm/leyning.d.ts +1 -1
- package/dist/esm/leyning.js +9 -14
- package/dist/esm/leyning.js.map +1 -1
- package/dist/esm/locale.js +2 -4
- package/dist/esm/locale.js.map +1 -1
- package/dist/esm/numverses.json.d.ts +35 -0
- package/dist/esm/numverses.json.js +47 -5
- package/dist/esm/numverses.json.js.map +1 -1
- package/dist/esm/specialReadings.d.ts +1 -1
- package/dist/esm/specialReadings.js +3 -7
- package/dist/esm/specialReadings.js.map +1 -1
- package/dist/esm/summary.d.ts +1 -1
- package/dist/esm/summary.js +5 -10
- package/dist/esm/summary.js.map +1 -1
- package/dist/esm/translate.d.ts +1 -1
- package/dist/esm/translate.js +5 -10
- package/dist/esm/translate.js.map +1 -1
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +11 -25
- package/dist/bundle.js +0 -3096
- package/dist/bundle.min.js +0 -15
package/dist/bundle.js
DELETED
|
@@ -1,3096 +0,0 @@
|
|
|
1
|
-
/*! @hebcal/leyning v9.6.0 */
|
|
2
|
-
var hebcal__leyning = (function (exports, locale, event, holidays, sedra, ParshaEvent) {
|
|
3
|
-
'use strict';
|
|
4
|
-
|
|
5
|
-
var poHe$1 = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he_IL" }, "contexts": { "": { "Shabbat Machar Chodesh": ["שַׁבָּת מָחָר חוֹדֶשׁ"], "Shabbat Rosh Chodesh": ["שַׁבָּת רֹאשׁ חוֹדֶשׁ"], "Pesach I (on Shabbat)": ["פֶּסַח יוֹם א׳ (בְּשַׁבָּת)"], "Pesach Chol ha-Moed Day 1": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם א׳"], "Pesach Chol ha-Moed Day 2": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ב׳"], "Pesach Chol ha-Moed Day 2 on Sunday": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ב׳ (בְּיוֹם רִאשׁוֹן)"], "Pesach Chol ha-Moed Day 3": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ג׳"], "Pesach Chol ha-Moed Day 3 on Monday": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ג׳ (בְּיוֹם שֵׁנִי)"], "Pesach Chol ha-Moed Day 4": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ד׳"], "Pesach Chol ha-Moed Day 5": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ה׳"], "Pesach VII (on Shabbat)": ["פֶּסַח ז׳ (בְּשַׁבָּת)"], "Pesach VIII (on Shabbat)": ["פֶּסַח ח׳ (בְּשַׁבָּת)"], "Shavuot II (on Shabbat)": ["שָׁבוּעוֹת יוֹם ב׳ (בְּשַׁבָּת)"], "Fast Day (Morning)": ["תַּעֲנִית (שַׁחֲרִית)"], "Fast Day (Afternoon)": ["תַּעֲנִית (מִנְחָה)"], "Rosh Hashana I (on Shabbat)": ["רֹאשׁ הַשָּׁנָה א׳ (בְּשַׁבָּת)"], "Yom Kippur (on Shabbat)": ["יוֹם כִּפּוּר (בְּשַׁבָּת)"], "Yom Kippur (Mincha, Traditional)": ["יוֹם כִּפּוּר מִנְחָה"], "Yom Kippur (Mincha, Alternate)": ["יוֹם כִּפּוּר מִנְחָה"], "Sukkot I (on Shabbat)": ["סֻכּוֹת יוֹם א׳ (בְּשַׁבָּת)"], "Sukkot Chol ha-Moed Day 1": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם א׳"], "Sukkot Chol ha-Moed Day 2": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם ב׳"], "Sukkot Chol ha-Moed Day 3": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם ג׳"], "Sukkot Chol ha-Moed Day 4": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם ד׳"], "Sukkot Chol ha-Moed Day 5": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם ה׳"], "Sukkot Final Day (Hoshana Raba)": ["סֻכּוֹת ז׳ (הוֹשַׁעְנָא רַבָּה)"], "Shmini Atzeret (on Shabbat)": ["שְׁמִינִי עֲצֶרֶת (בְּשַׁבָּת)"], "Simchat Torah (on Shabbat)": ["שִׂמְחַת תּוֹרָה (בְּשַׁבָּת)"], "Chanukah Day 1": ["חֲנוּכָּה יוֹם א׳"], "Chanukah Day 2": ["חֲנוּכָּה יוֹם ב׳"], "Chanukah Day 3": ["חֲנוּכָּה יוֹם ג׳"], "Chanukah Day 4": ["חֲנוּכָּה יוֹם ד׳"], "Chanukah Day 5": ["חֲנוּכָּה יוֹם ה׳"], "Chanukah Day 6": ["חֲנוּכָּה יוֹם ו׳"], "Chanukah Day 7": ["חֲנוּכָּה יוֹם ז׳"], "Chanukah Day 7 (on Rosh Chodesh)": ["חֲנוּכָּה יוֹם ז׳ (רֹאשׁ חוֹדֶשׁ)"], "Chanukah Day 8": ["חֲנוּכָּה יוֹם ח׳"], "Chanukah Day 1 (on Shabbat)": ["חֲנוּכָּה יוֹם א׳ (בְּשַׁבָּת)"], "Chanukah Day 2 (on Shabbat)": ["חֲנוּכָּה יוֹם ב׳ (בְּשַׁבָּת)"], "Chanukah Day 3 (on Shabbat)": ["חֲנוּכָּה יוֹם ג׳ (בְּשַׁבָּת)"], "Chanukah Day 4 (on Shabbat)": ["חֲנוּכָּה יוֹם ד׳ (בְּשַׁבָּת)"], "Chanukah Day 5 (on Shabbat)": ["חֲנוּכָּה יוֹם ה׳ (בְּשַׁבָּת)"], "Chanukah Day 7 (on Shabbat)": ["חֲנוּכָּה יוֹם ז׳ (בְּשַׁבָּת)"], "Chanukah Day 8 (on Shabbat)": ["חֲנוּכָּה יוֹם ח׳ (בְּשַׁבָּת)"], "Shabbat Rosh Chodesh Chanukah": ["שַׁבָּת רֹאשׁ חוֹדֶשׁ חֲנוּכָּה"], "Shushan Purim (on Shabbat)": ["שׁוּשַׁן פּוּרִים (בְּשַׁבָּת)"], "Yom Kippur (Mincha)": ["יוֹם כִּפּוּר (מִנְחָה)"], "Tish'a B'Av (Mincha)": ["תִּשְׁעָה בְּאָב (מִנְחָה)"], "Asara B'Tevet (Mincha)": ["עֲשָׂרָה בְּטֵבֵת (מִנְחָה)"], "Ta'anit Bechorot (Mincha)": ["תַּעֲנִית בְּכוֹרוֹת (מִנְחָה)"], "Ta'anit Esther (Mincha)": ["תַּעֲנִית אֶסְתֵּר (מִנְחָה)"], "Tzom Gedaliah (Mincha)": ["צוֹם גְּדַלְיָה (מִנְחָה)"], "Tzom Tammuz (Mincha)": ["צוֹם י״ז בְּתַמּוּז (מִנְחָה)"], "Genesis": ["בְּרֵאשִׁית"], "Exodus": ["שְׁמוֹת"], "Leviticus": ["וַיִּקְרָא"], "Numbers": ["בְּמִדְבַּר"], "Deuteronomy": ["דְּבָרִים"], "Joshua": ["יְהוֹשֻׁעַ"], "Judges": ["שׁוֹפְטִים"], "I Samuel": ["שְׁמוּאֵל א"], "II Samuel": ["שְׁמוּאֵל ב"], "I Kings": ["מְלָכִים א"], "II Kings": ["מְלָכִים ב"], "Isaiah": ["יְשַׁעְיָהוּ"], "Jeremiah": ["יִרְמְיָהוּ"], "Ezekiel": ["יְחֶזְקֵאל"], "Hosea": ["הוֹשֵׁעַ"], "Joel": ["יוֹאֵל"], "Amos": ["עָמוֹס"], "Obadiah": ["עוֹבַדְיָה"], "Jonah": ["יוֹנָה"], "Micah": ["מִיכָה"], "Nachum": ["נַחוּם"], "Habakkuk": ["חֲבַקּוּק"], "Zephaniah": ["צְפַנְיָה"], "Haggai": ["חַגַּי"], "Zechariah": ["זְכַרְיָה"], "Malachi": ["מַלְאָכִי"], "Song of Songs": ["שִׁיר הַשִּׁירִים"], "Ruth": ["רוּת"], "Lamentations": ["אֵיכָה"], "Ecclesiastes": ["קֹהֶלֶת"], "Esther": ["אֶסְתֵּר"], "Pinchas occurring after 17 Tammuz": ["פִּינְחָס מתרחש לאחר יז׳ בְּתַמּוּז"], "Kedoshim following Special Shabbat": ["קְדֹשִׁים לאחר שַׁבָּת מיוחדת"], "Masei on Shabbat Rosh Chodesh": ["מַסְעֵי בְּשַׁבָּת רֹאשׁ חוֹדֶשׁ"], "Matot-Masei on Shabbat Rosh Chodesh": ["מַטּוֹת־מַסְעֵי בְּשַׁבָּת רֹאשׁ חוֹדֶשׁ"], "Ki Teitzei with 3rd Haftarah of Consolation": ["כִּי־תֵצֵא עם הַפְטָרָה שְׁלִישִׁית שֶׁל נֶחָמָה"], "Shabbat HaChodesh (on Rosh Chodesh)": ["שַׁבָּת הַחוֹדֶשׁ (בְּרֹאשׁ חוֹדֶשׁ)"], "Shabbat Shekalim (on Rosh Chodesh)": ["שַׁבָּת שְׁקָלִים (רֹאשׁ חוֹדֶשׁ)"], "Shabbat Shuva (with Vayeilech)": ["שַׁבַּת שׁוּבָה (עם וַיֵּלֶךְ)"], "Shabbat Shuva (with Ha'azinu)": ["שַׁבַּת שׁוּבָה (עם הַאֲזִינוּ)"] } } };
|
|
6
|
-
|
|
7
|
-
var poAshkenazi$1 = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "und-x-ashkenaz" }, "contexts": { "": { "Shabbat Machar Chodesh": ["Shabbos Machar Chodesh"], "Shabbat Rosh Chodesh": ["Shabbos Rosh Chodesh"], "Pesach I (on Shabbat)": ["Pesach I (on Shabbos)"], "Pesach Shabbat Chol ha-Moed": ["Pesach Shabbos Chol ha-Moed"], "Pesach VII (on Shabbat)": ["Pesach VII (on Shabbos)"], "Pesach VIII (on Shabbat)": ["Pesach VIII (on Shabbos)"], "Shavuot II (on Shabbat)": ["Shavuos II (on Shabbos)"], "Rosh Hashana I (on Shabbat)": ["Rosh Hashana I (on Shabbos)"], "Yom Kippur (on Shabbat)": ["Yom Kippur (on Shabbos)"], "Sukkot I (on Shabbat)": ["Sukkos I (on Shabbos)"], "Sukkot Chol ha-Moed Day 1": ["Sukkos Chol ha-Moed Day 1"], "Sukkot Chol ha-Moed Day 2": ["Sukkos Chol ha-Moed Day 2"], "Sukkot Chol ha-Moed Day 3": ["Sukkos Chol ha-Moed Day 3"], "Sukkot Chol ha-Moed Day 4": ["Sukkos Chol ha-Moed Day 4"], "Sukkot Chol ha-Moed Day 5": ["Sukkos Chol ha-Moed Day 5"], "Sukkot Shabbat Chol ha-Moed": ["Sukkos Shabbos Chol ha-Moed"], "Sukkot Final Day (Hoshana Raba)": ["Sukkos Final Day (Hoshana Raba)"], "Shmini Atzeret (on Shabbat)": ["Shmini Atzeres (on Shabbos)"], "Chanukah Day 1 (on Shabbat)": ["Chanukah Day 1 (on Shabbos)"], "Chanukah Day 2 (on Shabbat)": ["Chanukah Day 2 (on Shabbos)"], "Chanukah Day 3 (on Shabbat)": ["Chanukah Day 3 (on Shabbos)"], "Chanukah Day 4 (on Shabbat)": ["Chanukah Day 4 (on Shabbos)"], "Chanukah Day 5 (on Shabbat)": ["Chanukah Day 5 (on Shabbos)"], "Chanukah Day 7 (on Shabbat)": ["Chanukah Day 7 (on Shabbos)"], "Chanukah Day 8 (on Shabbat)": ["Chanukah Day 8 (on Shabbos)"], "Shabbat Rosh Chodesh Chanukah": ["Shabbos Rosh Chodesh Chanukah"], "Asara B'Tevet (Mincha)": ["Asara B’Teves (Mincha)"], "Ta'anit Bechorot (Mincha)": ["Ta’anis Bechoros (Mincha)"], "Ta'anit Esther (Mincha)": ["Ta’anis Esther (Mincha)"] } } };
|
|
8
|
-
|
|
9
|
-
var noNikudOverride = { "headers": { "plural-forms": "nplurals=2; plural=(n != 1);", "language": "he-x-NoNikud" }, "contexts": { "": { "Pesach Chol ha-Moed Day 1": ["פסח חול המועד יום א׳"], "Pesach Chol ha-Moed Day 2": ["פסח חול המועד יום ב׳"], "Pesach Chol ha-Moed Day 2 on Sunday": ["פסח חול המועד יום ב׳ (ביום ראשון)"], "Pesach Chol ha-Moed Day 3": ["פסח חול המועד יום ג׳"], "Pesach Chol ha-Moed Day 3 on Monday": ["פסח חול המועד יום ג׳ (ביום שני)"], "Pesach Chol ha-Moed Day 4": ["פסח חול המועד יום ד׳"], "Pesach Chol ha-Moed Day 5": ["פסח חול המועד יום ה׳"], "Sukkot Chol ha-Moed Day 1": ["סוכות חול המועד יום א׳"], "Sukkot Chol ha-Moed Day 2": ["סוכות חול המועד יום ב׳"], "Sukkot Chol ha-Moed Day 3": ["סוכות חול המועד יום ג׳"], "Sukkot Chol ha-Moed Day 4": ["סוכות חול המועד יום ד׳"], "Sukkot Chol ha-Moed Day 5": ["סוכות חול המועד יום ה׳"], "Sukkot I (on Shabbat)": ["סוכות יום א׳ (בשבת)"], "Sukkot Final Day (Hoshana Raba)": ["סוכות ז׳ (הושענא רבה)"], "Yom Kippur (on Shabbat)": ["יום כיפור (בשבת)"], "Yom Kippur (Mincha, Traditional)": ["יום כיפור מנחה"], "Yom Kippur (Mincha, Alternate)": ["יום כיפור מנחה"], "Yom Kippur (Mincha)": ["יום כיפור (מנחה)"] } } };
|
|
10
|
-
|
|
11
|
-
locale.Locale.addTranslations('ashkenazi', poAshkenazi$1);
|
|
12
|
-
locale.Locale.addTranslations('he', poHe$1);
|
|
13
|
-
/* Hebrew without nikkud */
|
|
14
|
-
const poHeNoNikud$1 = locale.Locale.copyLocaleNoNikud(poHe$1);
|
|
15
|
-
locale.Locale.addTranslations('he-x-NoNikud', poHeNoNikud$1);
|
|
16
|
-
locale.Locale.addTranslations('he-x-NoNikud', noNikudOverride);
|
|
17
|
-
|
|
18
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
19
|
-
/** @private */
|
|
20
|
-
const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
21
|
-
/** @private */
|
|
22
|
-
const monthLengths = [lengths, lengths.slice()];
|
|
23
|
-
monthLengths[1][2] = 29;
|
|
24
|
-
/**
|
|
25
|
-
* @private
|
|
26
|
-
*/
|
|
27
|
-
function mod$1(x, y) {
|
|
28
|
-
return x - y * Math.floor(x / y);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* @private
|
|
32
|
-
*/
|
|
33
|
-
function quotient(x, y) {
|
|
34
|
-
return Math.floor(x / y);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* @private
|
|
38
|
-
* @param abs - R.D. number of days
|
|
39
|
-
*/
|
|
40
|
-
function yearFromFixed(abs) {
|
|
41
|
-
const l0 = abs - 1;
|
|
42
|
-
const n400 = quotient(l0, 146097);
|
|
43
|
-
const d1 = mod$1(l0, 146097);
|
|
44
|
-
const n100 = quotient(d1, 36524);
|
|
45
|
-
const d2 = mod$1(d1, 36524);
|
|
46
|
-
const n4 = quotient(d2, 1461);
|
|
47
|
-
const d3 = mod$1(d2, 1461);
|
|
48
|
-
const n1 = quotient(d3, 365);
|
|
49
|
-
const year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
|
|
50
|
-
return n100 !== 4 && n1 !== 4 ? year + 1 : year;
|
|
51
|
-
}
|
|
52
|
-
/*
|
|
53
|
-
const ABS_14SEP1752 = 639797;
|
|
54
|
-
const ABS_2SEP1752 = 639785;
|
|
55
|
-
*/
|
|
56
|
-
/*
|
|
57
|
-
* Formerly in namespace, now top-level
|
|
58
|
-
*/
|
|
59
|
-
/**
|
|
60
|
-
* Returns true if the Gregorian year is a leap year
|
|
61
|
-
* @param year Gregorian year
|
|
62
|
-
* @example
|
|
63
|
-
* isGregLeapYear(2000); // true
|
|
64
|
-
* isGregLeapYear(2020); // true
|
|
65
|
-
* isGregLeapYear(2023); // false
|
|
66
|
-
* isGregLeapYear(2100); // false (divisible by 100 but not 400)
|
|
67
|
-
*/
|
|
68
|
-
function isGregLeapYear(year) {
|
|
69
|
-
return !(year % 4) && (!!(year % 100) || !(year % 400));
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Number of days in the Gregorian month for given year
|
|
73
|
-
* @param month Gregorian month (1=January, 12=December)
|
|
74
|
-
* @param year Gregorian year
|
|
75
|
-
* @example
|
|
76
|
-
* daysInGregMonth(2, 2024); // 29 (February in a leap year)
|
|
77
|
-
* daysInGregMonth(2, 2023); // 28
|
|
78
|
-
* daysInGregMonth(7, 2024); // 31 (July)
|
|
79
|
-
*/
|
|
80
|
-
function daysInGregMonth(month, year) {
|
|
81
|
-
// 1 based months
|
|
82
|
-
return monthLengths[+isGregLeapYear(year)][month];
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Returns true if the object is a Javascript Date
|
|
86
|
-
* @example
|
|
87
|
-
* isDate(new Date()); // true
|
|
88
|
-
* isDate('2024-01-01'); // false
|
|
89
|
-
* isDate(1700000000000); // false
|
|
90
|
-
*/
|
|
91
|
-
function isDate(obj) {
|
|
92
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
93
|
-
return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* @private
|
|
97
|
-
* @param year
|
|
98
|
-
* @param month (1-12)
|
|
99
|
-
* @param day (1-31)
|
|
100
|
-
*/
|
|
101
|
-
function toFixed(year, month, day) {
|
|
102
|
-
const py = year - 1;
|
|
103
|
-
return (365 * py +
|
|
104
|
-
quotient(py, 4) -
|
|
105
|
-
quotient(py, 100) +
|
|
106
|
-
quotient(py, 400) +
|
|
107
|
-
quotient(367 * month - 362, 12) +
|
|
108
|
-
(month <= 2 ? 0 : isGregLeapYear(year) ? -1 : -2) +
|
|
109
|
-
day);
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
113
|
-
* @param date Gregorian date
|
|
114
|
-
* @example
|
|
115
|
-
* greg2abs(new Date(2008, 10, 13)); // 733359 (13 November 2008)
|
|
116
|
-
* greg2abs(new Date(2005, 3, 2)); // 732038 (2 April 2005)
|
|
117
|
-
*/
|
|
118
|
-
function greg2abs(date) {
|
|
119
|
-
if (!isDate(date)) {
|
|
120
|
-
throw new TypeError(`not a Date: ${date}`);
|
|
121
|
-
}
|
|
122
|
-
else if (isNaN(date.getTime())) {
|
|
123
|
-
throw new RangeError('Invalid Date');
|
|
124
|
-
}
|
|
125
|
-
const abs = toFixed(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
126
|
-
/*
|
|
127
|
-
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
128
|
-
throw new RangeError(`Invalid Date: ${date}`);
|
|
129
|
-
}
|
|
130
|
-
*/
|
|
131
|
-
return abs;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Converts from Rata Die (R.D. number) to Gregorian date.
|
|
135
|
-
* See the footnote on page 384 of ``Calendrical Calculations, Part II:
|
|
136
|
-
* Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M.
|
|
137
|
-
* Clamen, Software--Practice and Experience, Volume 23, Number 4
|
|
138
|
-
* (April, 1993), pages 383-404 for an explanation.
|
|
139
|
-
*
|
|
140
|
-
* Note that this function returns the daytime portion of the date.
|
|
141
|
-
* For example, the 15th of Cheshvan 5769 began at sundown on
|
|
142
|
-
* 12 November 2008 and continues through 13 November 2008. This
|
|
143
|
-
* function would return only the date 13 November 2008.
|
|
144
|
-
* @param abs - R.D. number of days
|
|
145
|
-
* @example
|
|
146
|
-
* const abs = hebrew2abs(5769, months.CHESHVAN, 15);
|
|
147
|
-
* const date = abs2greg(abs); // 13 November 2008
|
|
148
|
-
* const year = date.getFullYear(); // 2008
|
|
149
|
-
* const monthNum = date.getMonth() + 1; // 11
|
|
150
|
-
* const day = date.getDate(); // 13
|
|
151
|
-
*/
|
|
152
|
-
function abs2greg(abs) {
|
|
153
|
-
if (typeof abs !== 'number' || isNaN(abs)) {
|
|
154
|
-
throw new TypeError(`not a Number: ${abs}`);
|
|
155
|
-
}
|
|
156
|
-
abs = Math.trunc(abs);
|
|
157
|
-
/*
|
|
158
|
-
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
159
|
-
throw new RangeError(`Invalid Date: ${abs}`);
|
|
160
|
-
}
|
|
161
|
-
*/
|
|
162
|
-
const year = yearFromFixed(abs);
|
|
163
|
-
const priorDays = abs - toFixed(year, 1, 1);
|
|
164
|
-
const correction = abs < toFixed(year, 3, 1) ? 0 : isGregLeapYear(year) ? 1 : 2;
|
|
165
|
-
const month = quotient(12 * (priorDays + correction) + 373, 367);
|
|
166
|
-
const day = abs - toFixed(year, month, 1) + 1;
|
|
167
|
-
const dt = new Date(year, month - 1, day);
|
|
168
|
-
if (year < 100 && year >= 0) {
|
|
169
|
-
dt.setFullYear(year);
|
|
170
|
-
}
|
|
171
|
-
return dt;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
175
|
-
|
|
176
|
-
/* eslint-disable @typescript-eslint/no-namespace */
|
|
177
|
-
/**
|
|
178
|
-
* Gregorian date helper functions
|
|
179
|
-
*/
|
|
180
|
-
var greg;
|
|
181
|
-
(function (greg) {
|
|
182
|
-
})(greg || (greg = {}));
|
|
183
|
-
greg.abs2greg = abs2greg;
|
|
184
|
-
greg.daysInMonth = daysInGregMonth;
|
|
185
|
-
greg.greg2abs = greg2abs;
|
|
186
|
-
greg.isDate = isDate;
|
|
187
|
-
greg.isLeapYear = isGregLeapYear;
|
|
188
|
-
|
|
189
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
190
|
-
/**
|
|
191
|
-
* Removes niqqud from Hebrew string
|
|
192
|
-
* @example
|
|
193
|
-
* hebrewStripNikkud('אֱלוּל'); // 'אלול'
|
|
194
|
-
* hebrewStripNikkud('חֶשְׁוָן'); // 'חשון'
|
|
195
|
-
*/
|
|
196
|
-
function hebrewStripNikkud(str) {
|
|
197
|
-
if (typeof str !== 'string') {
|
|
198
|
-
throw new TypeError(`bad nikkud str: ${str}`);
|
|
199
|
-
}
|
|
200
|
-
const a = str.normalize();
|
|
201
|
-
// now strip out niqqud and trope
|
|
202
|
-
return a.replace(/[\u0590-\u05bd]/g, '').replace(/[\u05bf-\u05c7]/g, '');
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
206
|
-
|
|
207
|
-
/*
|
|
208
|
-
* More minimal HDate
|
|
209
|
-
*/
|
|
210
|
-
const NISAN = 1;
|
|
211
|
-
const IYYAR = 2;
|
|
212
|
-
const SIVAN = 3;
|
|
213
|
-
const TAMUZ = 4;
|
|
214
|
-
const AV = 5;
|
|
215
|
-
const ELUL = 6;
|
|
216
|
-
const TISHREI = 7;
|
|
217
|
-
const CHESHVAN = 8;
|
|
218
|
-
const KISLEV = 9;
|
|
219
|
-
const TEVET = 10;
|
|
220
|
-
const SHVAT = 11;
|
|
221
|
-
const ADAR_I = 12;
|
|
222
|
-
const ADAR_II = 13;
|
|
223
|
-
/**
|
|
224
|
-
* Hebrew months of the year (NISAN=1, TISHREI=7)
|
|
225
|
-
* @readonly
|
|
226
|
-
* @enum {number}
|
|
227
|
-
*/
|
|
228
|
-
const months = {
|
|
229
|
-
/** Av / אב */
|
|
230
|
-
AV,
|
|
231
|
-
/** Elul / אלול */
|
|
232
|
-
ELUL,
|
|
233
|
-
/** Tishrei / תִּשְׁרֵי */
|
|
234
|
-
TISHREI,
|
|
235
|
-
/** Adar Sheini (only on leap years) / אדר ב׳ */
|
|
236
|
-
ADAR_II,
|
|
237
|
-
};
|
|
238
|
-
const NISAN_STR = 'Nisan';
|
|
239
|
-
const monthNames0 = [
|
|
240
|
-
'',
|
|
241
|
-
NISAN_STR,
|
|
242
|
-
'Iyyar',
|
|
243
|
-
'Sivan',
|
|
244
|
-
'Tamuz',
|
|
245
|
-
'Av',
|
|
246
|
-
'Elul',
|
|
247
|
-
'Tishrei',
|
|
248
|
-
'Cheshvan',
|
|
249
|
-
'Kislev',
|
|
250
|
-
'Tevet',
|
|
251
|
-
"Sh'vat",
|
|
252
|
-
];
|
|
253
|
-
/*
|
|
254
|
-
* Transliterations of Hebrew month names.
|
|
255
|
-
* Regular years are index 0 and leap years are index 1.
|
|
256
|
-
* @private
|
|
257
|
-
*/
|
|
258
|
-
const monthNames = [
|
|
259
|
-
[...monthNames0, 'Adar', NISAN_STR],
|
|
260
|
-
[...monthNames0, 'Adar I', 'Adar II', NISAN_STR],
|
|
261
|
-
];
|
|
262
|
-
// Typed-array cache for elapsedDays, indexed by `year - ED_CACHE_MIN`.
|
|
263
|
-
// The range covers Hebrew years ~AD 1240 through ~AD 3240, which spans
|
|
264
|
-
// every realistic modern use. Years outside the range fall through
|
|
265
|
-
// uncached. 0 is the "not computed" sentinel; every valid input
|
|
266
|
-
// (year >= 1) produces a result >= 1, so it can't collide.
|
|
267
|
-
// elapsedDays(6999) is ~2.56M, well within Int32 range.
|
|
268
|
-
const ED_CACHE_MIN = 5000;
|
|
269
|
-
const ED_CACHE_MAX = 6999;
|
|
270
|
-
const edCache = new Int32Array(ED_CACHE_MAX - ED_CACHE_MIN + 1);
|
|
271
|
-
const EPOCH = -1373428;
|
|
272
|
-
// Avg year length in the cycle (19 solar years with 235 lunar months)
|
|
273
|
-
const AVG_HEBYEAR_DAYS = 365.24682220597794;
|
|
274
|
-
/**
|
|
275
|
-
* @private
|
|
276
|
-
*/
|
|
277
|
-
function assertNumber(n, name) {
|
|
278
|
-
if (typeof n !== 'number' || isNaN(n)) {
|
|
279
|
-
throw new TypeError(`param '${name}' not a number: ${n}`);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Converts Hebrew date to R.D. (Rata Die) fixed days.
|
|
284
|
-
* R.D. 1 is the imaginary date Monday, January 1, 1 on the Gregorian
|
|
285
|
-
* Calendar.
|
|
286
|
-
* @param year Hebrew year
|
|
287
|
-
* @param month Hebrew month
|
|
288
|
-
* @param day Hebrew date (1-30)
|
|
289
|
-
* @example
|
|
290
|
-
* import {hebrew2abs, months} from '@hebcal/hdate';
|
|
291
|
-
* hebrew2abs(5769, months.CHESHVAN, 15); // 733359
|
|
292
|
-
*/
|
|
293
|
-
function hebrew2abs(year, month, day) {
|
|
294
|
-
assertNumber(year, 'year');
|
|
295
|
-
assertNumber(month, 'month');
|
|
296
|
-
assertNumber(day, 'day');
|
|
297
|
-
if (year < 1) {
|
|
298
|
-
throw new RangeError(`hebrew2abs: invalid year ${year}`);
|
|
299
|
-
}
|
|
300
|
-
let tempabs = day;
|
|
301
|
-
if (month < TISHREI) {
|
|
302
|
-
const endMonth = monthsInYear(year);
|
|
303
|
-
for (let m = TISHREI; m <= endMonth; m++) {
|
|
304
|
-
tempabs += daysInMonth(m, year);
|
|
305
|
-
}
|
|
306
|
-
for (let m = NISAN; m < month; m++) {
|
|
307
|
-
tempabs += daysInMonth(m, year);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
else {
|
|
311
|
-
for (let m = TISHREI; m < month; m++) {
|
|
312
|
-
tempabs += daysInMonth(m, year);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
return EPOCH + elapsedDays(year) + tempabs - 1;
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* @private
|
|
319
|
-
*/
|
|
320
|
-
function newYear(year) {
|
|
321
|
-
return EPOCH + elapsedDays(year);
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Converts absolute R.D. days to Hebrew date
|
|
325
|
-
* @param abs absolute R.D. days
|
|
326
|
-
* @example
|
|
327
|
-
* abs2hebrew(733359); // {yy: 5769, mm: 8, dd: 15} (15 Cheshvan 5769)
|
|
328
|
-
*/
|
|
329
|
-
function abs2hebrew(abs) {
|
|
330
|
-
assertNumber(abs, 'abs');
|
|
331
|
-
abs = Math.trunc(abs);
|
|
332
|
-
if (abs <= EPOCH) {
|
|
333
|
-
throw new RangeError(`abs2hebrew: ${abs} is before epoch`);
|
|
334
|
-
}
|
|
335
|
-
// first, quickly approximate year
|
|
336
|
-
let year = Math.floor((abs - EPOCH) / AVG_HEBYEAR_DAYS);
|
|
337
|
-
while (newYear(year) <= abs) {
|
|
338
|
-
++year;
|
|
339
|
-
}
|
|
340
|
-
--year;
|
|
341
|
-
let month = abs < hebrew2abs(year, 1, 1) ? 7 : 1;
|
|
342
|
-
while (abs > hebrew2abs(year, month, daysInMonth(month, year))) {
|
|
343
|
-
++month;
|
|
344
|
-
}
|
|
345
|
-
const day = 1 + abs - hebrew2abs(year, month, 1);
|
|
346
|
-
return { yy: year, mm: month, dd: day };
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Returns true if Hebrew year is a leap year
|
|
350
|
-
* @param year Hebrew year
|
|
351
|
-
* @example
|
|
352
|
-
* isLeapYear(5783); // false
|
|
353
|
-
* isLeapYear(5784); // true
|
|
354
|
-
*/
|
|
355
|
-
function isLeapYear(year) {
|
|
356
|
-
return (1 + year * 7) % 19 < 7;
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Number of months in this Hebrew year (either 12 or 13 depending on leap year)
|
|
360
|
-
* @param year Hebrew year
|
|
361
|
-
* @example
|
|
362
|
-
* monthsInYear(5783); // 12
|
|
363
|
-
* monthsInYear(5784); // 13
|
|
364
|
-
*/
|
|
365
|
-
function monthsInYear(year) {
|
|
366
|
-
return 12 + +isLeapYear(year); // boolean is cast to 1 or 0
|
|
367
|
-
}
|
|
368
|
-
// Static day counts indexed by month number. 0 marks months whose length
|
|
369
|
-
// depends on the year (CHESHVAN, KISLEV, ADAR_I).
|
|
370
|
-
const STATIC_DAYS_IN_MONTH = [
|
|
371
|
-
0, 30, 29, 30, 29, 30, 29, 30, 0, 0, 29, 30, 0, 29,
|
|
372
|
-
];
|
|
373
|
-
/**
|
|
374
|
-
* Number of days in Hebrew month in a given year (29 or 30)
|
|
375
|
-
* @param month Hebrew month (e.g. months.TISHREI)
|
|
376
|
-
* @param year Hebrew year
|
|
377
|
-
* @example
|
|
378
|
-
* import {daysInMonth, months} from '@hebcal/hdate';
|
|
379
|
-
* daysInMonth(months.CHESHVAN, 5769); // 29
|
|
380
|
-
* daysInMonth(months.KISLEV, 5769); // 30
|
|
381
|
-
*/
|
|
382
|
-
function daysInMonth(month, year) {
|
|
383
|
-
const d = STATIC_DAYS_IN_MONTH[month];
|
|
384
|
-
if (d !== 0)
|
|
385
|
-
return d;
|
|
386
|
-
if (month === ADAR_I)
|
|
387
|
-
return isLeapYear(year) ? 30 : 29;
|
|
388
|
-
if (month === CHESHVAN)
|
|
389
|
-
return longCheshvan(year) ? 30 : 29;
|
|
390
|
-
return shortKislev(year) ? 29 : 30; // KISLEV
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Returns a transliterated string name of Hebrew month in year,
|
|
394
|
-
* for example 'Elul' or 'Cheshvan'.
|
|
395
|
-
* @param month Hebrew month (e.g. months.TISHREI)
|
|
396
|
-
* @param year Hebrew year
|
|
397
|
-
* @example
|
|
398
|
-
* import {getMonthName, months} from '@hebcal/hdate';
|
|
399
|
-
* getMonthName(months.CHESHVAN, 5769); // 'Cheshvan'
|
|
400
|
-
* getMonthName(months.ADAR_I, 5784); // 'Adar I' (leap year)
|
|
401
|
-
* getMonthName(months.ADAR_I, 5783); // 'Adar' (common year)
|
|
402
|
-
*/
|
|
403
|
-
function getMonthName(month, year) {
|
|
404
|
-
assertNumber(month, 'month');
|
|
405
|
-
assertNumber(year, 'year');
|
|
406
|
-
if (month < 1 || month > 14) {
|
|
407
|
-
throw new TypeError(`bad monthNum: ${month}`);
|
|
408
|
-
}
|
|
409
|
-
return monthNames[+isLeapYear(year)][month];
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Days from sunday prior to start of Hebrew calendar to mean
|
|
413
|
-
* conjunction of Tishrei in Hebrew YEAR
|
|
414
|
-
* @param year Hebrew year
|
|
415
|
-
*/
|
|
416
|
-
function elapsedDays(year) {
|
|
417
|
-
if (year >= ED_CACHE_MIN && year <= ED_CACHE_MAX) {
|
|
418
|
-
const idx = year - ED_CACHE_MIN;
|
|
419
|
-
const n = edCache[idx];
|
|
420
|
-
if (n !== 0)
|
|
421
|
-
return n;
|
|
422
|
-
const elapsed = elapsedDays0(year);
|
|
423
|
-
edCache[idx] = elapsed;
|
|
424
|
-
return elapsed;
|
|
425
|
-
}
|
|
426
|
-
return elapsedDays0(year);
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Days from sunday prior to start of Hebrew calendar to mean
|
|
430
|
-
* conjunction of Tishrei in Hebrew YEAR
|
|
431
|
-
* @private
|
|
432
|
-
* @param year Hebrew year
|
|
433
|
-
*/
|
|
434
|
-
function elapsedDays0(year) {
|
|
435
|
-
const prevYear = year - 1;
|
|
436
|
-
const mElapsed = 235 * Math.floor(prevYear / 19) + // Months in complete 19 year lunar (Metonic) cycles so far
|
|
437
|
-
12 * (prevYear % 19) + // Regular months in this cycle
|
|
438
|
-
Math.floor(((prevYear % 19) * 7 + 1) / 19); // Leap months this cycle
|
|
439
|
-
const pElapsed = 204 + 793 * (mElapsed % 1080);
|
|
440
|
-
const hElapsed = 5 +
|
|
441
|
-
12 * mElapsed +
|
|
442
|
-
793 * Math.floor(mElapsed / 1080) +
|
|
443
|
-
Math.floor(pElapsed / 1080);
|
|
444
|
-
const parts = (pElapsed % 1080) + 1080 * (hElapsed % 24);
|
|
445
|
-
const day = 1 + 29 * mElapsed + Math.floor(hElapsed / 24);
|
|
446
|
-
let altDay = day;
|
|
447
|
-
if (parts >= 19440 ||
|
|
448
|
-
(2 === day % 7 && parts >= 9924 && !isLeapYear(year)) ||
|
|
449
|
-
(1 === day % 7 && parts >= 16789 && isLeapYear(prevYear))) {
|
|
450
|
-
altDay++;
|
|
451
|
-
}
|
|
452
|
-
if (altDay % 7 === 0 || altDay % 7 === 3 || altDay % 7 === 5) {
|
|
453
|
-
return altDay + 1;
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
return altDay;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Number of days in the hebrew YEAR.
|
|
461
|
-
* A common Hebrew calendar year can have a length of 353, 354 or 355 days
|
|
462
|
-
* A leap Hebrew calendar year can have a length of 383, 384 or 385 days
|
|
463
|
-
* @param year Hebrew year
|
|
464
|
-
* @example
|
|
465
|
-
* daysInYear(5783); // 355
|
|
466
|
-
* daysInYear(5784); // 383 (leap year)
|
|
467
|
-
*/
|
|
468
|
-
function daysInYear(year) {
|
|
469
|
-
return elapsedDays(year + 1) - elapsedDays(year);
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* true if Cheshvan is long in Hebrew year
|
|
473
|
-
* @param year Hebrew year
|
|
474
|
-
* @example
|
|
475
|
-
* longCheshvan(5783); // true
|
|
476
|
-
* longCheshvan(5784); // false
|
|
477
|
-
*/
|
|
478
|
-
function longCheshvan(year) {
|
|
479
|
-
return daysInYear(year) % 10 === 5;
|
|
480
|
-
}
|
|
481
|
-
/**
|
|
482
|
-
* true if Kislev is short in Hebrew year
|
|
483
|
-
* @param year Hebrew year
|
|
484
|
-
* @example
|
|
485
|
-
* shortKislev(5783); // false
|
|
486
|
-
* shortKislev(5784); // true
|
|
487
|
-
*/
|
|
488
|
-
function shortKislev(year) {
|
|
489
|
-
return daysInYear(year) % 10 === 3;
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* Converts Hebrew month string name to numeric
|
|
493
|
-
* @param monthName monthName
|
|
494
|
-
* @example
|
|
495
|
-
* monthFromName('Cheshvan'); // 8
|
|
496
|
-
* monthFromName('חשון'); // 8
|
|
497
|
-
* monthFromName('Adar II'); // 13
|
|
498
|
-
* monthFromName(7); // 7 (passthrough)
|
|
499
|
-
*/
|
|
500
|
-
function monthFromName(monthName) {
|
|
501
|
-
if (typeof monthName === 'number') {
|
|
502
|
-
if (isNaN(monthName) || monthName < 1 || monthName > 14) {
|
|
503
|
-
throw new RangeError(`bad monthName: ${monthName}`);
|
|
504
|
-
}
|
|
505
|
-
return monthName;
|
|
506
|
-
}
|
|
507
|
-
if (typeof monthName !== 'string') {
|
|
508
|
-
throw new TypeError(`bad monthName: ${monthName}`);
|
|
509
|
-
}
|
|
510
|
-
let c = monthName.trim().toLowerCase();
|
|
511
|
-
// remove all niqud and trailing gershayim (for Adar Alef/Bet)
|
|
512
|
-
c = hebrewStripNikkud(c).replace(/׳$/, '');
|
|
513
|
-
// If Hebrew month starts with a bet (for example `בתמוז`) then ignore it
|
|
514
|
-
if (c.startsWith('ב')) {
|
|
515
|
-
c = c.substring(1);
|
|
516
|
-
}
|
|
517
|
-
/*
|
|
518
|
-
the Hebrew months are unique to their second letter
|
|
519
|
-
N Nisan (November?)
|
|
520
|
-
I Iyyar
|
|
521
|
-
E Elul
|
|
522
|
-
C Cheshvan
|
|
523
|
-
K Kislev
|
|
524
|
-
1 1Adar
|
|
525
|
-
2 2Adar
|
|
526
|
-
Si Sh Sivan, Shvat
|
|
527
|
-
Ta Ti Te Tamuz, Tishrei, Tevet
|
|
528
|
-
Av Ad Av, Adar
|
|
529
|
-
|
|
530
|
-
אב אד אי אל אב אדר אייר אלול
|
|
531
|
-
ח חשון
|
|
532
|
-
ט טבת
|
|
533
|
-
כ כסלו
|
|
534
|
-
נ ניסן
|
|
535
|
-
ס סיון
|
|
536
|
-
ש שבט
|
|
537
|
-
תמ תש תמוז תשרי
|
|
538
|
-
*/
|
|
539
|
-
switch (c[0]) {
|
|
540
|
-
case 'n':
|
|
541
|
-
case 'נ':
|
|
542
|
-
if (c[1] === 'o') {
|
|
543
|
-
break; /* this catches "november" */
|
|
544
|
-
}
|
|
545
|
-
return NISAN;
|
|
546
|
-
case 'i':
|
|
547
|
-
return IYYAR;
|
|
548
|
-
case 'e':
|
|
549
|
-
return ELUL;
|
|
550
|
-
case 'c':
|
|
551
|
-
case 'ח':
|
|
552
|
-
return CHESHVAN;
|
|
553
|
-
case 'k':
|
|
554
|
-
case 'כ':
|
|
555
|
-
return KISLEV;
|
|
556
|
-
case 's':
|
|
557
|
-
switch (c[1]) {
|
|
558
|
-
case 'i':
|
|
559
|
-
return SIVAN;
|
|
560
|
-
case 'h':
|
|
561
|
-
return SHVAT;
|
|
562
|
-
}
|
|
563
|
-
break;
|
|
564
|
-
case 't':
|
|
565
|
-
switch (c[1]) {
|
|
566
|
-
case 'a':
|
|
567
|
-
return TAMUZ;
|
|
568
|
-
case 'i':
|
|
569
|
-
return TISHREI;
|
|
570
|
-
case 'e':
|
|
571
|
-
return TEVET;
|
|
572
|
-
}
|
|
573
|
-
break;
|
|
574
|
-
case 'a':
|
|
575
|
-
switch (c[1]) {
|
|
576
|
-
case 'v':
|
|
577
|
-
return AV;
|
|
578
|
-
case 'd':
|
|
579
|
-
if (/(1|[^i]i|a|א)$/i.test(c)) {
|
|
580
|
-
return ADAR_I;
|
|
581
|
-
}
|
|
582
|
-
return ADAR_II; // else assume sheini
|
|
583
|
-
}
|
|
584
|
-
break;
|
|
585
|
-
case 'ס':
|
|
586
|
-
return SIVAN;
|
|
587
|
-
case 'ט':
|
|
588
|
-
return TEVET;
|
|
589
|
-
case 'ש':
|
|
590
|
-
return SHVAT;
|
|
591
|
-
case 'א':
|
|
592
|
-
switch (c[1]) {
|
|
593
|
-
case 'ב':
|
|
594
|
-
return AV;
|
|
595
|
-
case 'ד':
|
|
596
|
-
if (/(1|[^i]i|a|א)$/i.test(c)) {
|
|
597
|
-
return ADAR_I;
|
|
598
|
-
}
|
|
599
|
-
return ADAR_II; // else assume sheini
|
|
600
|
-
case 'י':
|
|
601
|
-
return IYYAR;
|
|
602
|
-
case 'ל':
|
|
603
|
-
return ELUL;
|
|
604
|
-
}
|
|
605
|
-
break;
|
|
606
|
-
case 'ת':
|
|
607
|
-
switch (c[1]) {
|
|
608
|
-
case 'מ':
|
|
609
|
-
return TAMUZ;
|
|
610
|
-
case 'ש':
|
|
611
|
-
return TISHREI;
|
|
612
|
-
}
|
|
613
|
-
break;
|
|
614
|
-
}
|
|
615
|
-
throw new RangeError(`bad monthName: ${monthName}`);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
619
|
-
const GERESH = '׳';
|
|
620
|
-
const GERSHAYIM = '״';
|
|
621
|
-
const heb2num = {
|
|
622
|
-
א: 1,
|
|
623
|
-
ב: 2,
|
|
624
|
-
ג: 3,
|
|
625
|
-
ד: 4,
|
|
626
|
-
ה: 5,
|
|
627
|
-
ו: 6,
|
|
628
|
-
ז: 7,
|
|
629
|
-
ח: 8,
|
|
630
|
-
ט: 9,
|
|
631
|
-
י: 10,
|
|
632
|
-
כ: 20,
|
|
633
|
-
ל: 30,
|
|
634
|
-
מ: 40,
|
|
635
|
-
נ: 50,
|
|
636
|
-
ס: 60,
|
|
637
|
-
ע: 70,
|
|
638
|
-
פ: 80,
|
|
639
|
-
צ: 90,
|
|
640
|
-
ק: 100,
|
|
641
|
-
ר: 200,
|
|
642
|
-
ש: 300,
|
|
643
|
-
ת: 400,
|
|
644
|
-
};
|
|
645
|
-
const num2heb = {};
|
|
646
|
-
for (const [key, val] of Object.entries(heb2num)) {
|
|
647
|
-
num2heb[val] = key;
|
|
648
|
-
}
|
|
649
|
-
function num2digits(num) {
|
|
650
|
-
const digits = [];
|
|
651
|
-
while (num > 0) {
|
|
652
|
-
if (num === 15 || num === 16) {
|
|
653
|
-
digits.push(9, num - 9);
|
|
654
|
-
break;
|
|
655
|
-
}
|
|
656
|
-
let incr = 100;
|
|
657
|
-
let i;
|
|
658
|
-
for (i = 400; i > num; i -= incr) {
|
|
659
|
-
if (i === incr) {
|
|
660
|
-
incr = incr / 10;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
digits.push(i);
|
|
664
|
-
num -= i;
|
|
665
|
-
}
|
|
666
|
-
return digits;
|
|
667
|
-
}
|
|
668
|
-
/**
|
|
669
|
-
* Converts a numerical value to a string of Hebrew letters.
|
|
670
|
-
*
|
|
671
|
-
* When specifying years of the Hebrew calendar in the present millennium,
|
|
672
|
-
* we omit the thousands (which is presently 5 [ה]).
|
|
673
|
-
* @example
|
|
674
|
-
* gematriya(5774) // 'תשע״ד' - cropped to 774
|
|
675
|
-
* gematriya(25) // 'כ״ה'
|
|
676
|
-
* gematriya(60) // 'ס׳'
|
|
677
|
-
* gematriya(3761) // 'ג׳תשס״א'
|
|
678
|
-
* gematriya(1123) // 'א׳קכ״ג'
|
|
679
|
-
*/
|
|
680
|
-
function gematriya(num) {
|
|
681
|
-
const num1 = parseInt(num, 10);
|
|
682
|
-
if (!num1 || num1 < 0) {
|
|
683
|
-
throw new TypeError(`invalid number: ${num}`);
|
|
684
|
-
}
|
|
685
|
-
let str = '';
|
|
686
|
-
const thousands = Math.floor(num1 / 1000);
|
|
687
|
-
if (thousands > 0 && thousands !== 5) {
|
|
688
|
-
const tdigits = num2digits(thousands);
|
|
689
|
-
for (const tdig of tdigits) {
|
|
690
|
-
str += num2heb[tdig];
|
|
691
|
-
}
|
|
692
|
-
str += GERESH;
|
|
693
|
-
}
|
|
694
|
-
const digits = num2digits(num1 % 1000);
|
|
695
|
-
if (digits.length === 1) {
|
|
696
|
-
return str + num2heb[digits[0]] + GERESH;
|
|
697
|
-
}
|
|
698
|
-
for (let i = 0; i < digits.length; i++) {
|
|
699
|
-
if (i + 1 === digits.length) {
|
|
700
|
-
str += GERSHAYIM;
|
|
701
|
-
}
|
|
702
|
-
str += num2heb[digits[i]];
|
|
703
|
-
}
|
|
704
|
-
return str;
|
|
705
|
-
}
|
|
706
|
-
/**
|
|
707
|
-
* Converts a string of Hebrew letters to a numerical value.
|
|
708
|
-
*
|
|
709
|
-
* Only considers the value of Hebrew letters `א` through `ת`.
|
|
710
|
-
* Ignores final Hebrew letters such as `ך` (kaf sofit) or `ם` (mem sofit)
|
|
711
|
-
* and vowels (nekudot).
|
|
712
|
-
* @example
|
|
713
|
-
* gematriyaStrToNum('תשע״ד'); // 774
|
|
714
|
-
* gematriyaStrToNum('ט״ו'); // 15
|
|
715
|
-
* gematriyaStrToNum('ג׳תשס״א'); // 3761 (thousands prefix)
|
|
716
|
-
*/
|
|
717
|
-
function gematriyaStrToNum(str) {
|
|
718
|
-
if (typeof str !== 'string') {
|
|
719
|
-
throw new TypeError(`bad gematriya str: ${str}`);
|
|
720
|
-
}
|
|
721
|
-
let num = 0;
|
|
722
|
-
const gereshIdx = str.indexOf(GERESH);
|
|
723
|
-
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
|
|
724
|
-
const thousands = str.substring(0, gereshIdx);
|
|
725
|
-
num += gematriyaStrToNum(thousands) * 1000;
|
|
726
|
-
str = str.substring(gereshIdx);
|
|
727
|
-
}
|
|
728
|
-
for (const ch of str) {
|
|
729
|
-
const n = heb2num[ch];
|
|
730
|
-
if (typeof n === 'number') {
|
|
731
|
-
num += n;
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
return num;
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
738
|
-
var poAshkenazi = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "und-x-ashkenaz" }, "contexts": { "": { "Tevet": ["Teves"] } } };
|
|
739
|
-
|
|
740
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
741
|
-
var poHe = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he" }, "contexts": { "": { "Adar": ["אֲדָר"], "Adar I": ["אֲדָר א׳"], "Adar II": ["אֲדָר ב׳"], "Av": ["אָב"], "Cheshvan": ["חֶשְׁוָן"], "Elul": ["אֱלוּל"], "Iyyar": ["אִיָּיר"], "Kislev": ["כִּסְלֵו"], "Nisan": ["נִיסָן"], "Sh'vat": ["שְׁבָט"], "Sivan": ["סִיוָן"], "Tamuz": ["תַּמּוּז"], "Tammuz": ["תַּמּוּז"], "Tevet": ["טֵבֵת"], "Tishrei": ["תִּשְׁרֵי"] } } };
|
|
742
|
-
|
|
743
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
744
|
-
|
|
745
|
-
const noopLocale = {
|
|
746
|
-
headers: { 'plural-forms': 'nplurals=2; plural=(n!=1);' },
|
|
747
|
-
contexts: { '': {} },
|
|
748
|
-
};
|
|
749
|
-
const alias = {
|
|
750
|
-
h: 'he',
|
|
751
|
-
a: 'ashkenazi',
|
|
752
|
-
s: 'en',
|
|
753
|
-
'': 'en',
|
|
754
|
-
};
|
|
755
|
-
/** @private */
|
|
756
|
-
const locales = new Map();
|
|
757
|
-
/** @private */
|
|
758
|
-
function getEnOrdinal(n) {
|
|
759
|
-
const s = ['th', 'st', 'nd', 'rd'];
|
|
760
|
-
const v = n % 100;
|
|
761
|
-
return n + (s[(v - 20) % 10] || s[v] || s[0]);
|
|
762
|
-
}
|
|
763
|
-
/** @private */
|
|
764
|
-
function checkLocale(locale) {
|
|
765
|
-
if (typeof locale !== 'string') {
|
|
766
|
-
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
767
|
-
}
|
|
768
|
-
locale = alias[locale] || locale;
|
|
769
|
-
return locale.toLowerCase();
|
|
770
|
-
}
|
|
771
|
-
/** @private */
|
|
772
|
-
function getExistingLocale(locale) {
|
|
773
|
-
const locale1 = checkLocale(locale);
|
|
774
|
-
const loc = locales.get(locale1);
|
|
775
|
-
if (!loc) {
|
|
776
|
-
throw new RangeError(`Locale '${locale}' not found`);
|
|
777
|
-
}
|
|
778
|
-
return loc;
|
|
779
|
-
}
|
|
780
|
-
/**
|
|
781
|
-
* A locale in Hebcal is used for translations/transliterations of
|
|
782
|
-
* holidays. `@hebcal/hdate` supports four locales by default
|
|
783
|
-
* * `en` - default, Sephardic transliterations (e.g. "Shabbat")
|
|
784
|
-
* * `ashkenazi` - Ashkenazi transliterations (e.g. "Shabbos")
|
|
785
|
-
* * `he` - Hebrew (e.g. "שַׁבָּת")
|
|
786
|
-
* * `he-x-NoNikud` - Hebrew without nikud (e.g. "שבת")
|
|
787
|
-
*/
|
|
788
|
-
class Locale {
|
|
789
|
-
/**
|
|
790
|
-
* Returns translation only if `locale` offers a non-empty translation for `id`.
|
|
791
|
-
* Otherwise, returns `undefined`.
|
|
792
|
-
* @param id Message ID to translate
|
|
793
|
-
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to no-op locale.
|
|
794
|
-
* @example
|
|
795
|
-
* Locale.lookupTranslation('Adar II', 'he-x-NoNikud'); // 'אדר ב׳'
|
|
796
|
-
* Locale.lookupTranslation('Foobar', 'he-x-NoNikud'); // undefined
|
|
797
|
-
*/
|
|
798
|
-
static lookupTranslation(id, locale) {
|
|
799
|
-
const loc = (typeof locale === 'string' && locales.get(checkLocale(locale))) ||
|
|
800
|
-
noopLocale.contexts[''];
|
|
801
|
-
const array = loc[id];
|
|
802
|
-
if (array?.length && array[0].length) {
|
|
803
|
-
return array[0];
|
|
804
|
-
}
|
|
805
|
-
return undefined;
|
|
806
|
-
}
|
|
807
|
-
/**
|
|
808
|
-
* By default, if no translation was found, returns `id`.
|
|
809
|
-
* @param id Message ID to translate
|
|
810
|
-
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to no-op locale.
|
|
811
|
-
* @example
|
|
812
|
-
* Locale.gettext('Elul', 'he'); // 'אֱלוּל'
|
|
813
|
-
* Locale.gettext('Tevet', 'ashkenazi'); // 'Teves'
|
|
814
|
-
* Locale.gettext('Unknown', 'he'); // 'Unknown' (falls back to id)
|
|
815
|
-
*/
|
|
816
|
-
static gettext(id, locale) {
|
|
817
|
-
const text = this.lookupTranslation(id, locale);
|
|
818
|
-
if (text === undefined) {
|
|
819
|
-
return id;
|
|
820
|
-
}
|
|
821
|
-
return text;
|
|
822
|
-
}
|
|
823
|
-
/**
|
|
824
|
-
* Register locale translations.
|
|
825
|
-
* @param locale Locale name (i.e.: `'he'`, `'fr'`)
|
|
826
|
-
* @param data parsed data from a `.po` file.
|
|
827
|
-
* @example
|
|
828
|
-
* import poFr from './fr.po';
|
|
829
|
-
* Locale.addLocale('fr', poFr);
|
|
830
|
-
* Locale.gettext('Shabbat', 'fr'); // 'Chabbat'
|
|
831
|
-
*/
|
|
832
|
-
static addLocale(locale, data) {
|
|
833
|
-
locale = checkLocale(locale);
|
|
834
|
-
const ctx = data.contexts;
|
|
835
|
-
if (typeof ctx !== 'object' || typeof ctx[''] !== 'object') {
|
|
836
|
-
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
837
|
-
}
|
|
838
|
-
locales.set(locale, ctx['']);
|
|
839
|
-
}
|
|
840
|
-
/**
|
|
841
|
-
* Adds a translation to `locale`, replacing any previous translation.
|
|
842
|
-
* @param locale Locale name (i.e: `'he'`, `'fr'`).
|
|
843
|
-
* @param id Message ID to translate
|
|
844
|
-
* @param translation Translation text
|
|
845
|
-
* @example
|
|
846
|
-
* Locale.addTranslation('ashkenazi', 'Foobar', 'Quux');
|
|
847
|
-
* Locale.gettext('Foobar', 'ashkenazi'); // 'Quux'
|
|
848
|
-
*/
|
|
849
|
-
static addTranslation(locale, id, translation) {
|
|
850
|
-
const loc = getExistingLocale(locale);
|
|
851
|
-
if (typeof id !== 'string' || id.length === 0) {
|
|
852
|
-
throw new TypeError(`Invalid id string: ${id}`);
|
|
853
|
-
}
|
|
854
|
-
const isArray = Array.isArray(translation);
|
|
855
|
-
if (isArray) {
|
|
856
|
-
const t0 = translation[0];
|
|
857
|
-
if (typeof t0 !== 'string' || t0.length === 0) {
|
|
858
|
-
throw new TypeError(`Invalid translation array: ${translation}`);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
else if (typeof translation !== 'string') {
|
|
862
|
-
throw new TypeError(`Invalid translation string: ${translation}`);
|
|
863
|
-
}
|
|
864
|
-
loc[id] = isArray ? translation : [translation];
|
|
865
|
-
}
|
|
866
|
-
/**
|
|
867
|
-
* Adds multiple translations to `locale`, replacing any previous translations.
|
|
868
|
-
*
|
|
869
|
-
* The locale must already be registered (typically via `addLocale`);
|
|
870
|
-
* to register a brand-new locale instead, call `addLocale` directly.
|
|
871
|
-
* Use this method to merge an additional `.po` file (e.g. holiday
|
|
872
|
-
* translations supplied by a separate `@hebcal/*` package) into an
|
|
873
|
-
* existing locale.
|
|
874
|
-
* @param locale Locale name (i.e: `'he'`, `'fr'`).
|
|
875
|
-
* @param data parsed data from a `.po` file.
|
|
876
|
-
*/
|
|
877
|
-
static addTranslations(locale, data) {
|
|
878
|
-
const loc = getExistingLocale(locale);
|
|
879
|
-
const ctx = data.contexts;
|
|
880
|
-
if (typeof ctx !== 'object' || typeof ctx[''] !== 'object') {
|
|
881
|
-
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
882
|
-
}
|
|
883
|
-
Object.assign(loc, ctx['']);
|
|
884
|
-
}
|
|
885
|
-
/**
|
|
886
|
-
* Returns the names of registered locales
|
|
887
|
-
* @example
|
|
888
|
-
* Locale.getLocaleNames(); // ['ashkenazi', 'en', 'he', 'he-x-nonikud']
|
|
889
|
-
*/
|
|
890
|
-
static getLocaleNames() {
|
|
891
|
-
const keys = Array.from(locales.keys());
|
|
892
|
-
return keys.sort((a, b) => a.localeCompare(b));
|
|
893
|
-
}
|
|
894
|
-
/**
|
|
895
|
-
* Checks whether a locale has been registered
|
|
896
|
-
* @param locale Locale name (i.e: `'he'`, `'fr'`).
|
|
897
|
-
* @example
|
|
898
|
-
* Locale.hasLocale('he'); // true
|
|
899
|
-
* Locale.hasLocale('fr'); // false
|
|
900
|
-
*/
|
|
901
|
-
static hasLocale(locale) {
|
|
902
|
-
const locale1 = checkLocale(locale);
|
|
903
|
-
return locales.has(locale1);
|
|
904
|
-
}
|
|
905
|
-
/**
|
|
906
|
-
* Renders a number in ordinal, such as 1st, 2nd or 3rd
|
|
907
|
-
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to no-op locale.
|
|
908
|
-
* @example
|
|
909
|
-
* Locale.ordinal(3, 'en'); // '3rd'
|
|
910
|
-
* Locale.ordinal(3, 'es'); // '3º'
|
|
911
|
-
* Locale.ordinal(3, 'fr'); // '3.'
|
|
912
|
-
* Locale.ordinal(3, 'he'); // '3'
|
|
913
|
-
*/
|
|
914
|
-
static ordinal(n, locale) {
|
|
915
|
-
const locale1 = checkLocale(locale || '');
|
|
916
|
-
if (locale1 === 'en' || locale1.startsWith('ashkenazi')) {
|
|
917
|
-
return getEnOrdinal(n);
|
|
918
|
-
}
|
|
919
|
-
else if (Locale.isHebrewLocale(locale1)) {
|
|
920
|
-
return String(n);
|
|
921
|
-
}
|
|
922
|
-
else if (locale1 === 'es') {
|
|
923
|
-
return n + 'º';
|
|
924
|
-
}
|
|
925
|
-
return n + '.';
|
|
926
|
-
}
|
|
927
|
-
/**
|
|
928
|
-
* Removes nekudot from Hebrew string
|
|
929
|
-
* @example
|
|
930
|
-
* Locale.hebrewStripNikkud('אֱלוּל'); // 'אלול'
|
|
931
|
-
*/
|
|
932
|
-
static hebrewStripNikkud(str) {
|
|
933
|
-
return hebrewStripNikkud(str);
|
|
934
|
-
}
|
|
935
|
-
/**
|
|
936
|
-
* Returns a new `LocaleData` derived from `data` with niqqud (vowel
|
|
937
|
-
* points) stripped from every translation value. The input is not
|
|
938
|
-
* modified.
|
|
939
|
-
*
|
|
940
|
-
* This is the helper used internally to build the `he-x-NoNikud`
|
|
941
|
-
* locale from `he`; call it when registering a derived "no nikud"
|
|
942
|
-
* variant of a custom Hebrew-script locale.
|
|
943
|
-
*/
|
|
944
|
-
static copyLocaleNoNikud(data) {
|
|
945
|
-
const strs = data.contexts[''];
|
|
946
|
-
const m = {};
|
|
947
|
-
for (const [key, val] of Object.entries(strs)) {
|
|
948
|
-
m[key] = [hebrewStripNikkud(val[0])];
|
|
949
|
-
}
|
|
950
|
-
return {
|
|
951
|
-
headers: data.headers,
|
|
952
|
-
contexts: { '': m },
|
|
953
|
-
};
|
|
954
|
-
}
|
|
955
|
-
/**
|
|
956
|
-
* Returns true if `locale` is a Hebrew locale (i.e. `he` or `he-x-NoNikud`)
|
|
957
|
-
* @example
|
|
958
|
-
* Locale.isHebrewLocale('he'); // true
|
|
959
|
-
* Locale.isHebrewLocale('he-x-NoNikud'); // true
|
|
960
|
-
* Locale.isHebrewLocale('en'); // false
|
|
961
|
-
*/
|
|
962
|
-
static isHebrewLocale(locale) {
|
|
963
|
-
if (typeof locale !== 'string') {
|
|
964
|
-
return false;
|
|
965
|
-
}
|
|
966
|
-
locale = alias[locale] || locale;
|
|
967
|
-
locale = locale.toLowerCase();
|
|
968
|
-
return locale.startsWith('he');
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
Locale.addLocale('en', noopLocale);
|
|
972
|
-
/* Ashkenazic transliterations */
|
|
973
|
-
Locale.addLocale('ashkenazi', poAshkenazi);
|
|
974
|
-
/* Hebrew with nikkud */
|
|
975
|
-
Locale.addLocale('he', poHe);
|
|
976
|
-
/* Hebrew without nikkud */
|
|
977
|
-
const poHeNoNikud = Locale.copyLocaleNoNikud(poHe);
|
|
978
|
-
Locale.addLocale('he-x-NoNikud', poHeNoNikud);
|
|
979
|
-
|
|
980
|
-
/*! @hebcal/hdate v0.22.5, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
981
|
-
|
|
982
|
-
/*
|
|
983
|
-
Hebcal - A Jewish Calendar Generator
|
|
984
|
-
Copyright (c) 1994-2020 Danny Sadinoff
|
|
985
|
-
Portions copyright Eyal Schachter and Michael J. Radwin
|
|
986
|
-
|
|
987
|
-
https://github.com/hebcal/hebcal-es6
|
|
988
|
-
|
|
989
|
-
This program is free software; you can redistribute it and/or
|
|
990
|
-
modify it under the terms of the GNU General Public License
|
|
991
|
-
as published by the Free Software Foundation; either version 2
|
|
992
|
-
of the License, or (at your option) any later version.
|
|
993
|
-
|
|
994
|
-
This program is distributed in the hope that it will be useful,
|
|
995
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
996
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
997
|
-
GNU General Public License for more details.
|
|
998
|
-
|
|
999
|
-
You should have received a copy of the GNU General Public License
|
|
1000
|
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
1001
|
-
*/
|
|
1002
|
-
function mod(x, y) {
|
|
1003
|
-
return x - y * Math.floor(x / y);
|
|
1004
|
-
}
|
|
1005
|
-
function isSimpleHebrewDate(obj) {
|
|
1006
|
-
return obj.yy !== undefined;
|
|
1007
|
-
}
|
|
1008
|
-
const UNITS_DAY = 'day';
|
|
1009
|
-
const UNITS_WEEK = 'week';
|
|
1010
|
-
const UNITS_MONTH = 'month';
|
|
1011
|
-
const UNITS_YEAR = 'year';
|
|
1012
|
-
/**
|
|
1013
|
-
* A `HDate` represents a Hebrew calendar date.
|
|
1014
|
-
*
|
|
1015
|
-
* An instance of this class encapsulates a date in the Hebrew calendar system.
|
|
1016
|
-
* It consists of a year, month, and day, without any associated time or location data.
|
|
1017
|
-
* The Hebrew calendar is a lunisolar calendar, meaning it is based on both lunar and solar cycles.
|
|
1018
|
-
*
|
|
1019
|
-
* A Hebrew date internally stores three numbers:
|
|
1020
|
-
* - year: The Hebrew year (1-9999). Counted from the traditional Hebrew date of creation (3761 BCE in the Gregorian calendar)
|
|
1021
|
-
* - month: The Hebrew month (1-13). Month 1 is Nisan, month 7 is Tishrei. There are 12 months in a regular year and 13 months in a leap year.
|
|
1022
|
-
* - day: The day of the month (1-30)
|
|
1023
|
-
*
|
|
1024
|
-
* This class uses Rata Die to convert between the Hebrew and Gregorian calendars.
|
|
1025
|
-
*
|
|
1026
|
-
* To calculate times of day, use `Zmanim` class from `@hebcal/core`
|
|
1027
|
-
* @see {@link https://en.wikipedia.org/wiki/Rata_Die | Rata Die}
|
|
1028
|
-
* @see {@link https://hebcal.github.io/api/core/classes/Zmanim.html | Zmanim}
|
|
1029
|
-
*/
|
|
1030
|
-
class HDate {
|
|
1031
|
-
/** Hebrew year, 1-9999 */
|
|
1032
|
-
yy;
|
|
1033
|
-
/** Hebrew month of year (1=NISAN, 7=TISHREI) */
|
|
1034
|
-
mm;
|
|
1035
|
-
/** Hebrew day within the month (1-30) */
|
|
1036
|
-
dd;
|
|
1037
|
-
/** absolute Rata Die (R.D.) days */
|
|
1038
|
-
rd;
|
|
1039
|
-
/**
|
|
1040
|
-
* Create a Hebrew date. There are 3 basic forms for the `HDate()` constructor.
|
|
1041
|
-
*
|
|
1042
|
-
* 1. No parameters - represents the current Hebrew date at time of instantiation
|
|
1043
|
-
* 2. One parameter
|
|
1044
|
-
* * `Date` - represents the Hebrew date corresponding to the Gregorian date using
|
|
1045
|
-
* local time. Hours, minutes, seconds and milliseconds are ignored.
|
|
1046
|
-
* * `HDate` - clones a copy of the given Hebrew date
|
|
1047
|
-
* * `number` - Converts absolute R.D. days to Hebrew date.
|
|
1048
|
-
* R.D. 1 == the imaginary date January 1, 1 (Gregorian)
|
|
1049
|
-
* 3. Three parameters: Hebrew day, Hebrew month, Hebrew year. Hebrew day should
|
|
1050
|
-
* be a number between 1-30, Hebrew month can be a number or string, and
|
|
1051
|
-
* Hebrew year is always a number.
|
|
1052
|
-
* @example
|
|
1053
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1054
|
-
*
|
|
1055
|
-
* const hd1 = new HDate();
|
|
1056
|
-
* const hd2 = new HDate(new Date(2008, 10, 13));
|
|
1057
|
-
* const hd3 = new HDate(15, 'Cheshvan', 5769);
|
|
1058
|
-
* const hd4 = new HDate(15, months.CHESHVAN, 5769);
|
|
1059
|
-
* const hd5 = new HDate(733359); // ==> 15 Cheshvan 5769
|
|
1060
|
-
* const monthName = 'אייר';
|
|
1061
|
-
* const hd6 = new HDate(5, monthName, 5773);
|
|
1062
|
-
* @param [day] - Day of month (1-30) if a `number`.
|
|
1063
|
-
* If a `Date` is specified, represents the Hebrew date corresponding to the
|
|
1064
|
-
* Gregorian date using local time.
|
|
1065
|
-
* If an `HDate` is specified, clones a copy of the given Hebrew date.
|
|
1066
|
-
* @param [month] - Hebrew month of year (1=NISAN, 7=TISHREI)
|
|
1067
|
-
* @param [year] - Hebrew year
|
|
1068
|
-
*/
|
|
1069
|
-
constructor(day, month, year) {
|
|
1070
|
-
if (arguments.length === 2 || arguments.length > 3) {
|
|
1071
|
-
throw new TypeError('HDate constructor requires 0, 1 or 3 arguments');
|
|
1072
|
-
}
|
|
1073
|
-
if (arguments.length === 3) {
|
|
1074
|
-
// Hebrew day, Hebrew month, Hebrew year
|
|
1075
|
-
this.dd = this.mm = 1;
|
|
1076
|
-
const yy = typeof year === 'string' ? parseInt(year, 10) : year;
|
|
1077
|
-
if (isNaN(yy)) {
|
|
1078
|
-
throw new TypeError(`HDate called with bad year: ${year}`);
|
|
1079
|
-
}
|
|
1080
|
-
this.yy = yy;
|
|
1081
|
-
setMonth(this, month); // will throw if we can't parse
|
|
1082
|
-
const dd = typeof day === 'string' ? parseInt(day, 10) : day;
|
|
1083
|
-
if (isNaN(dd)) {
|
|
1084
|
-
throw new TypeError(`HDate called with bad day: ${day}`);
|
|
1085
|
-
}
|
|
1086
|
-
setDate(this, dd);
|
|
1087
|
-
}
|
|
1088
|
-
else {
|
|
1089
|
-
// 0 arguments
|
|
1090
|
-
if (day === undefined || day === null) {
|
|
1091
|
-
day = new Date();
|
|
1092
|
-
}
|
|
1093
|
-
// 1 argument
|
|
1094
|
-
const abs0 = typeof day === 'number' && !isNaN(day)
|
|
1095
|
-
? day
|
|
1096
|
-
: isDate(day)
|
|
1097
|
-
? greg2abs(day)
|
|
1098
|
-
: isSimpleHebrewDate(day)
|
|
1099
|
-
? day
|
|
1100
|
-
: null;
|
|
1101
|
-
if (abs0 === null) {
|
|
1102
|
-
throw new TypeError(`HDate called with bad arg: ${day}`);
|
|
1103
|
-
}
|
|
1104
|
-
const isNumber = typeof abs0 === 'number';
|
|
1105
|
-
const d = isNumber ? abs2hebrew(abs0) : abs0;
|
|
1106
|
-
this.yy = d.yy;
|
|
1107
|
-
this.mm = d.mm;
|
|
1108
|
-
this.dd = d.dd;
|
|
1109
|
-
if (isNumber) {
|
|
1110
|
-
this.rd = abs0;
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
/**
|
|
1115
|
-
* Returns the Hebrew year of this Hebrew date
|
|
1116
|
-
* @returns an integer >= 1
|
|
1117
|
-
* @example
|
|
1118
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1119
|
-
* hd.getFullYear(); // 5769
|
|
1120
|
-
*/
|
|
1121
|
-
getFullYear() {
|
|
1122
|
-
return this.yy;
|
|
1123
|
-
}
|
|
1124
|
-
/**
|
|
1125
|
-
* Returns `true` if this Hebrew date occurs during a Hebrew leap year
|
|
1126
|
-
* @example
|
|
1127
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1128
|
-
* hd.isLeapYear(); // false
|
|
1129
|
-
*/
|
|
1130
|
-
isLeapYear() {
|
|
1131
|
-
return isLeapYear(this.yy);
|
|
1132
|
-
}
|
|
1133
|
-
/**
|
|
1134
|
-
* Returns the Hebrew month (1=NISAN, 7=TISHREI) of this Hebrew date
|
|
1135
|
-
* @returns an integer 1-13
|
|
1136
|
-
* @example
|
|
1137
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1138
|
-
* hd.getMonth(); // 8
|
|
1139
|
-
*/
|
|
1140
|
-
getMonth() {
|
|
1141
|
-
return this.mm;
|
|
1142
|
-
}
|
|
1143
|
-
/**
|
|
1144
|
-
* The Tishrei-based month of this Hebrew date. 1 is Tishrei, 7 is Nisan, 13 is Elul in a leap year
|
|
1145
|
-
* @returns an integer 1-13
|
|
1146
|
-
* @example
|
|
1147
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1148
|
-
* hd.getTishreiMonth(); // 2
|
|
1149
|
-
*/
|
|
1150
|
-
getTishreiMonth() {
|
|
1151
|
-
const nummonths = monthsInYear(this.getFullYear());
|
|
1152
|
-
return (this.getMonth() + nummonths - 6) % nummonths || nummonths;
|
|
1153
|
-
}
|
|
1154
|
-
/**
|
|
1155
|
-
* Number of days in the month of this Hebrew date (29 or 30)
|
|
1156
|
-
* @returns an integer 29-30
|
|
1157
|
-
* @example
|
|
1158
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1159
|
-
* hd.daysInMonth(); // 29
|
|
1160
|
-
*/
|
|
1161
|
-
daysInMonth() {
|
|
1162
|
-
return daysInMonth(this.getMonth(), this.getFullYear());
|
|
1163
|
-
}
|
|
1164
|
-
/**
|
|
1165
|
-
* Gets the day within the month (1-30)
|
|
1166
|
-
* @returns an integer 1-30
|
|
1167
|
-
* @example
|
|
1168
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1169
|
-
* hd.getDate(); // 15
|
|
1170
|
-
*/
|
|
1171
|
-
getDate() {
|
|
1172
|
-
return this.dd;
|
|
1173
|
-
}
|
|
1174
|
-
/**
|
|
1175
|
-
* Returns the day of the week for this Hebrew date,
|
|
1176
|
-
* where 0 represents Sunday, 1 represents Monday, 6 represents Saturday.
|
|
1177
|
-
*
|
|
1178
|
-
* For the day of the month, see `getDate()`
|
|
1179
|
-
* @returns an integer 0-6
|
|
1180
|
-
* @example
|
|
1181
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1182
|
-
* hd.getDate(); // 4
|
|
1183
|
-
*/
|
|
1184
|
-
getDay() {
|
|
1185
|
-
return mod(this.abs(), 7);
|
|
1186
|
-
}
|
|
1187
|
-
/**
|
|
1188
|
-
* Converts this Hebrew date to the corresponding Gregorian date.
|
|
1189
|
-
*
|
|
1190
|
-
* The returned `Date` object will be in the local (i.e. host system) time zone.
|
|
1191
|
-
* Hours, minutes, seconds and milliseconds will all be zero.
|
|
1192
|
-
*
|
|
1193
|
-
* Note that this function returns the daytime portion of the date.
|
|
1194
|
-
* For example, the 15th of Cheshvan 5769 began at sundown on
|
|
1195
|
-
* 12 November 2008 and continues through 13 November 2008. This
|
|
1196
|
-
* function would return only the date 13 November 2008.
|
|
1197
|
-
* @example
|
|
1198
|
-
* const hd = new HDate(15, 'Cheshvan', 5769);
|
|
1199
|
-
* const date = hd.greg(); // 13 November 2008
|
|
1200
|
-
* const year = date.getFullYear(); // 2008
|
|
1201
|
-
* const monthNum = date.getMonth() + 1; // 11
|
|
1202
|
-
* const day = date.getDate(); // 13
|
|
1203
|
-
*/
|
|
1204
|
-
greg() {
|
|
1205
|
-
return abs2greg(this.abs());
|
|
1206
|
-
}
|
|
1207
|
-
/**
|
|
1208
|
-
* Converts from Hebrew date representation to R.D. (Rata Die) fixed days.
|
|
1209
|
-
* R.D. 1 is the imaginary date Monday, January 1, 1 (Gregorian).
|
|
1210
|
-
* Note also that R.D. = Julian Date − 1,721,424.5
|
|
1211
|
-
* @see {@link https://en.wikipedia.org/wiki/Rata_Die | Rata Die}
|
|
1212
|
-
* @example
|
|
1213
|
-
* const hd = new HDate(15, 'Cheshvan', 5769);
|
|
1214
|
-
* hd.abs(); // 733359
|
|
1215
|
-
*/
|
|
1216
|
-
abs() {
|
|
1217
|
-
if (typeof this.rd !== 'number') {
|
|
1218
|
-
this.rd = hebrew2abs(this.yy, this.mm, this.dd);
|
|
1219
|
-
}
|
|
1220
|
-
return this.rd;
|
|
1221
|
-
}
|
|
1222
|
-
/**
|
|
1223
|
-
* Converts Hebrew date to R.D. (Rata Die) fixed days.
|
|
1224
|
-
* R.D. 1 is the imaginary date Monday, January 1, 1 on the Gregorian
|
|
1225
|
-
* Calendar.
|
|
1226
|
-
* @param year Hebrew year
|
|
1227
|
-
* @param month Hebrew month (1=NISAN, 7=TISHREI)
|
|
1228
|
-
* @param day Hebrew date (1-30)
|
|
1229
|
-
* @example
|
|
1230
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1231
|
-
* HDate.hebrew2abs(5769, months.CHESHVAN, 15); // 733359
|
|
1232
|
-
*/
|
|
1233
|
-
static hebrew2abs(year, month, day) {
|
|
1234
|
-
return hebrew2abs(year, month, day);
|
|
1235
|
-
}
|
|
1236
|
-
/**
|
|
1237
|
-
* Returns a transliterated Hebrew month name, e.g. `'Elul'` or `'Cheshvan'`.
|
|
1238
|
-
* @example
|
|
1239
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1240
|
-
* hd.getMonthName(); // 'Cheshvan'
|
|
1241
|
-
*/
|
|
1242
|
-
getMonthName() {
|
|
1243
|
-
return getMonthName(this.getMonth(), this.getFullYear());
|
|
1244
|
-
}
|
|
1245
|
-
/**
|
|
1246
|
-
* Renders this Hebrew date as a translated or transliterated string,
|
|
1247
|
-
* including ordinal e.g. `'15th of Cheshvan, 5769'`.
|
|
1248
|
-
* @example
|
|
1249
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1250
|
-
*
|
|
1251
|
-
* const hd = new HDate(15, months.CHESHVAN, 5769);
|
|
1252
|
-
* console.log(hd.render('en')); // '15th of Cheshvan, 5769'
|
|
1253
|
-
* console.log(hd.render('he')); // '15 חֶשְׁוָן, 5769'
|
|
1254
|
-
* console.log(hd.render('en', false)); // '15th of Cheshvan'
|
|
1255
|
-
* console.log(hd.render('he', false)); // '15 חֶשְׁוָן'
|
|
1256
|
-
* @param [locale] Optional locale name (defaults to active locale).
|
|
1257
|
-
* @param [showYear=true] Display year (defaults to true).
|
|
1258
|
-
* @see {@link Locale}
|
|
1259
|
-
*/
|
|
1260
|
-
render(locale, showYear = true) {
|
|
1261
|
-
const locale0 = locale || 'en';
|
|
1262
|
-
const day = this.getDate();
|
|
1263
|
-
const monthName0 = Locale.gettext(this.getMonthName(), locale0);
|
|
1264
|
-
const monthName = monthName0.replace(/'/g, '’');
|
|
1265
|
-
const nth = Locale.ordinal(day, locale0);
|
|
1266
|
-
const dayOf = getDayOfTranslation(locale0);
|
|
1267
|
-
const dateStr = `${nth}${dayOf} ${monthName}`;
|
|
1268
|
-
if (showYear) {
|
|
1269
|
-
const fullYear = this.getFullYear();
|
|
1270
|
-
return `${dateStr}, ${fullYear}`;
|
|
1271
|
-
}
|
|
1272
|
-
else {
|
|
1273
|
-
return dateStr;
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
/**
|
|
1277
|
-
* Renders this Hebrew date in Hebrew gematriya, regardless of locale.
|
|
1278
|
-
* @param suppressNikud - suppress nekudot (default false)
|
|
1279
|
-
* @param suppressYear - suppress Hebrew year (default false)
|
|
1280
|
-
* @example
|
|
1281
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1282
|
-
* const hd = new HDate(15, months.CHESHVAN, 5769);
|
|
1283
|
-
* hd.renderGematriya(); // 'ט״ו חֶשְׁוָן תשס״ט'
|
|
1284
|
-
* hd.renderGematriya(true); // 'ט״ו חשון תשס״ט'
|
|
1285
|
-
* hd.renderGematriya(false, true); // 'ט״ו חֶשְׁוָן'
|
|
1286
|
-
*/
|
|
1287
|
-
renderGematriya(suppressNikud = false, suppressYear = false) {
|
|
1288
|
-
const d = this.getDate();
|
|
1289
|
-
const locale = suppressNikud ? 'he-x-NoNikud' : 'he';
|
|
1290
|
-
const m = Locale.gettext(this.getMonthName(), locale);
|
|
1291
|
-
const prefix = gematriya(d) + ' ' + m;
|
|
1292
|
-
if (suppressYear) {
|
|
1293
|
-
return prefix;
|
|
1294
|
-
}
|
|
1295
|
-
const y = this.getFullYear();
|
|
1296
|
-
return prefix + ' ' + gematriya(y);
|
|
1297
|
-
}
|
|
1298
|
-
/**
|
|
1299
|
-
* Returns an `HDate` corresponding to the specified day of week
|
|
1300
|
-
* **before** this Hebrew date
|
|
1301
|
-
* @example
|
|
1302
|
-
* new HDate(new Date('Wednesday February 19, 2014')).before(6).greg() // Sat Feb 15 2014
|
|
1303
|
-
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1304
|
-
*/
|
|
1305
|
-
before(dayOfWeek) {
|
|
1306
|
-
return onOrBefore(dayOfWeek, this, -1);
|
|
1307
|
-
}
|
|
1308
|
-
/**
|
|
1309
|
-
* Returns an `HDate` corresponding to the specified day of week
|
|
1310
|
-
* **on or before** this Hebrew date
|
|
1311
|
-
* @example
|
|
1312
|
-
* new HDate(new Date('Wednesday February 19, 2014')).onOrBefore(6).greg() // Sat Feb 15 2014
|
|
1313
|
-
* new HDate(new Date('Saturday February 22, 2014')).onOrBefore(6).greg() // Sat Feb 22 2014
|
|
1314
|
-
* new HDate(new Date('Sunday February 23, 2014')).onOrBefore(6).greg() // Sat Feb 22 2014
|
|
1315
|
-
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1316
|
-
*/
|
|
1317
|
-
onOrBefore(dayOfWeek) {
|
|
1318
|
-
return onOrBefore(dayOfWeek, this, 0);
|
|
1319
|
-
}
|
|
1320
|
-
/**
|
|
1321
|
-
* Returns an `HDate` corresponding to the specified day of week
|
|
1322
|
-
* **nearest** to this Hebrew date
|
|
1323
|
-
* @example
|
|
1324
|
-
* new HDate(new Date('Wednesday February 19, 2014')).nearest(6).greg() // Sat Feb 22 2014
|
|
1325
|
-
* new HDate(new Date('Tuesday February 18, 2014')).nearest(6).greg() // Sat Feb 15 2014
|
|
1326
|
-
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1327
|
-
*/
|
|
1328
|
-
nearest(dayOfWeek) {
|
|
1329
|
-
return onOrBefore(dayOfWeek, this, 3);
|
|
1330
|
-
}
|
|
1331
|
-
/**
|
|
1332
|
-
* Returns an `HDate` corresponding to the specified day of week
|
|
1333
|
-
* **on or after** this Hebrew date
|
|
1334
|
-
* @example
|
|
1335
|
-
* new HDate(new Date('Wednesday February 19, 2014')).onOrAfter(6).greg() // Sat Feb 22 2014
|
|
1336
|
-
* new HDate(new Date('Saturday February 22, 2014')).onOrAfter(6).greg() // Sat Feb 22 2014
|
|
1337
|
-
* new HDate(new Date('Sunday February 23, 2014')).onOrAfter(6).greg() // Sat Mar 01 2014
|
|
1338
|
-
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1339
|
-
*/
|
|
1340
|
-
onOrAfter(dayOfWeek) {
|
|
1341
|
-
return onOrBefore(dayOfWeek, this, 6);
|
|
1342
|
-
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Returns an `HDate` corresponding to the specified day of week
|
|
1345
|
-
* **after** this Hebrew date
|
|
1346
|
-
* @example
|
|
1347
|
-
* new HDate(new Date('Wednesday February 19, 2014')).after(6).greg() // Sat Feb 22 2014
|
|
1348
|
-
* new HDate(new Date('Saturday February 22, 2014')).after(6).greg() // Sat Mar 01 2014
|
|
1349
|
-
* new HDate(new Date('Sunday February 23, 2014')).after(6).greg() // Sat Mar 01 2014
|
|
1350
|
-
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1351
|
-
*/
|
|
1352
|
-
after(dayOfWeek) {
|
|
1353
|
-
return onOrBefore(dayOfWeek, this, 7);
|
|
1354
|
-
}
|
|
1355
|
-
/**
|
|
1356
|
-
* Returns the next Hebrew date
|
|
1357
|
-
* @example
|
|
1358
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1359
|
-
* hd.next(); // '16 Cheshvan 5769'
|
|
1360
|
-
*/
|
|
1361
|
-
next() {
|
|
1362
|
-
return new HDate(this.abs() + 1);
|
|
1363
|
-
}
|
|
1364
|
-
/**
|
|
1365
|
-
* Returns the previous Hebrew date
|
|
1366
|
-
* @example
|
|
1367
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1368
|
-
* hd.prev(); // '14 Cheshvan 5769'
|
|
1369
|
-
*/
|
|
1370
|
-
prev() {
|
|
1371
|
-
return new HDate(this.abs() - 1);
|
|
1372
|
-
}
|
|
1373
|
-
/**
|
|
1374
|
-
* Returns a cloned `HDate` object with a specified amount of time added
|
|
1375
|
-
*
|
|
1376
|
-
* Units are case insensitive, and support plural and short forms.
|
|
1377
|
-
* Note, short forms are case sensitive.
|
|
1378
|
-
*
|
|
1379
|
-
* | Unit | Shorthand | Description
|
|
1380
|
-
* | --- | --- | --- |
|
|
1381
|
-
* | `day` | `d` | days |
|
|
1382
|
-
* | `week` | `w` | weeks |
|
|
1383
|
-
* | `month` | `M` | months |
|
|
1384
|
-
* | `year` | `y` | years |
|
|
1385
|
-
* @example
|
|
1386
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1387
|
-
*
|
|
1388
|
-
* const hd1 = new HDate(15, months.CHESHVAN, 5769);
|
|
1389
|
-
* hd1.add(7, 'd'); // 22 Cheshvan 5769
|
|
1390
|
-
* hd1.add(1, 'weeks'); // 22 Cheshvan 5769
|
|
1391
|
-
* hd1.add(1, 'year'); // 15 Cheshvan 5770
|
|
1392
|
-
*/
|
|
1393
|
-
add(amount, units = 'd') {
|
|
1394
|
-
amount = typeof amount === 'string' ? parseInt(amount, 10) : amount;
|
|
1395
|
-
if (!amount) {
|
|
1396
|
-
return new HDate(this);
|
|
1397
|
-
}
|
|
1398
|
-
units = standardizeUnits(units);
|
|
1399
|
-
if (units === UNITS_DAY) {
|
|
1400
|
-
return new HDate(this.abs() + amount);
|
|
1401
|
-
}
|
|
1402
|
-
else if (units === UNITS_WEEK) {
|
|
1403
|
-
return new HDate(this.abs() + 7 * amount);
|
|
1404
|
-
}
|
|
1405
|
-
else if (units === UNITS_YEAR) {
|
|
1406
|
-
return new HDate(this.getDate(), this.getMonth(), this.getFullYear() + amount);
|
|
1407
|
-
}
|
|
1408
|
-
else {
|
|
1409
|
-
// units === UNITS_MONTH
|
|
1410
|
-
let hd = new HDate(this);
|
|
1411
|
-
const sign = amount > 0 ? 1 : -1;
|
|
1412
|
-
amount = Math.abs(amount);
|
|
1413
|
-
for (let i = 0; i < amount; i++) {
|
|
1414
|
-
hd = new HDate(hd.abs() + sign * hd.daysInMonth());
|
|
1415
|
-
}
|
|
1416
|
-
return hd;
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
/**
|
|
1420
|
-
* Returns a cloned `HDate` object with a specified amount of time subracted
|
|
1421
|
-
*
|
|
1422
|
-
* Units are case insensitive, and support plural and short forms.
|
|
1423
|
-
* Note, short forms are case sensitive.
|
|
1424
|
-
*
|
|
1425
|
-
* | Unit | Shorthand | Description
|
|
1426
|
-
* | --- | --- | --- |
|
|
1427
|
-
* | `day` | `d` | days |
|
|
1428
|
-
* | `week` | `w` | weeks |
|
|
1429
|
-
* | `month` | `M` | months |
|
|
1430
|
-
* | `year` | `y` | years |
|
|
1431
|
-
* @example
|
|
1432
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1433
|
-
*
|
|
1434
|
-
* const hd1 = new HDate(15, months.CHESHVAN, 5769);
|
|
1435
|
-
* const hd2 = hd1.add(1, 'weeks'); // 7 Kislev 5769
|
|
1436
|
-
* const hd3 = hd1.add(-3, 'M'); // 30 Av 5768
|
|
1437
|
-
*/
|
|
1438
|
-
subtract(amount, units = 'd') {
|
|
1439
|
-
return this.add(amount * -1, units);
|
|
1440
|
-
}
|
|
1441
|
-
/**
|
|
1442
|
-
* Returns the difference in days between the two given HDates.
|
|
1443
|
-
*
|
|
1444
|
-
* The result is positive if `this` date is comes chronologically
|
|
1445
|
-
* after the `other` date, and negative
|
|
1446
|
-
* if the order of the two dates is reversed.
|
|
1447
|
-
*
|
|
1448
|
-
* The result is zero if the two dates are identical.
|
|
1449
|
-
* @example
|
|
1450
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1451
|
-
*
|
|
1452
|
-
* const hd1 = new HDate(25, months.KISLEV, 5770);
|
|
1453
|
-
* const hd2 = new HDate(15, months.CHESHVAN, 5769);
|
|
1454
|
-
* const days = hd1.deltaDays(hd2); // 394
|
|
1455
|
-
* @param other Hebrew date to compare
|
|
1456
|
-
*/
|
|
1457
|
-
deltaDays(other) {
|
|
1458
|
-
return this.abs() - other.abs();
|
|
1459
|
-
}
|
|
1460
|
-
/**
|
|
1461
|
-
* Compares this Hebrew date to another date, returning `true` if the dates match.
|
|
1462
|
-
* @param other Hebrew date to compare
|
|
1463
|
-
* @example
|
|
1464
|
-
* const hd1 = new HDate(new Date(2008, 10, 13));
|
|
1465
|
-
* const hd2 = new HDate(15, 'Cheshvan', 5769);
|
|
1466
|
-
* hd1.isSameDate(hd2); // true
|
|
1467
|
-
*/
|
|
1468
|
-
isSameDate(other) {
|
|
1469
|
-
return this.yy === other.yy && this.mm === other.mm && this.dd === other.dd;
|
|
1470
|
-
}
|
|
1471
|
-
/**
|
|
1472
|
-
* Returns a string representation of this Hebrew date using English transliterations
|
|
1473
|
-
* @example
|
|
1474
|
-
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1475
|
-
* hd.toString(); // '15 Cheshvan 5769'
|
|
1476
|
-
*/
|
|
1477
|
-
toString() {
|
|
1478
|
-
const day = this.getDate();
|
|
1479
|
-
const fullYear = this.getFullYear();
|
|
1480
|
-
const monthName = this.getMonthName();
|
|
1481
|
-
return `${day} ${monthName} ${fullYear}`;
|
|
1482
|
-
}
|
|
1483
|
-
/**
|
|
1484
|
-
* Returns true if Hebrew year is a leap year
|
|
1485
|
-
* @param year Hebrew year
|
|
1486
|
-
* @example
|
|
1487
|
-
* HDate.isLeapYear(5783); // false
|
|
1488
|
-
* HDate.isLeapYear(5784); // true
|
|
1489
|
-
*/
|
|
1490
|
-
static isLeapYear(year) {
|
|
1491
|
-
return isLeapYear(year);
|
|
1492
|
-
}
|
|
1493
|
-
/**
|
|
1494
|
-
* Number of months in this Hebrew year (either 12 or 13 depending on leap year)
|
|
1495
|
-
* @param year Hebrew year
|
|
1496
|
-
* @example
|
|
1497
|
-
* HDate.monthsInYear(5783); // 12
|
|
1498
|
-
* HDate.monthsInYear(5784); // 13
|
|
1499
|
-
*/
|
|
1500
|
-
static monthsInYear(year) {
|
|
1501
|
-
return monthsInYear(year);
|
|
1502
|
-
}
|
|
1503
|
-
/**
|
|
1504
|
-
* Number of days in Hebrew month in a given year (29 or 30)
|
|
1505
|
-
* @param month Hebrew month (e.g. months.TISHREI)
|
|
1506
|
-
* @param year Hebrew year
|
|
1507
|
-
* @example
|
|
1508
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1509
|
-
* HDate.daysInMonth(months.CHESHVAN, 5769); // 29
|
|
1510
|
-
*/
|
|
1511
|
-
static daysInMonth(month, year) {
|
|
1512
|
-
return daysInMonth(month, year);
|
|
1513
|
-
}
|
|
1514
|
-
/**
|
|
1515
|
-
* Returns a transliterated string name of Hebrew month in year,
|
|
1516
|
-
* for example 'Elul' or 'Cheshvan'.
|
|
1517
|
-
* @param month Hebrew month (e.g. months.TISHREI)
|
|
1518
|
-
* @param year Hebrew year
|
|
1519
|
-
* @example
|
|
1520
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1521
|
-
* HDate.getMonthName(months.CHESHVAN, 5769); // 'Cheshvan'
|
|
1522
|
-
*/
|
|
1523
|
-
static getMonthName(month, year) {
|
|
1524
|
-
return getMonthName(month, year);
|
|
1525
|
-
}
|
|
1526
|
-
/**
|
|
1527
|
-
* Returns the Hebrew month number (NISAN=1, TISHREI=7)
|
|
1528
|
-
* @param month A number, or Hebrew month name string
|
|
1529
|
-
* @example
|
|
1530
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1531
|
-
* HDate.monthNum(months.CHESHVAN); // 8
|
|
1532
|
-
* HDate.monthNum('Cheshvan'); // 8
|
|
1533
|
-
* HDate.monthNum('חשון'); // 8
|
|
1534
|
-
*/
|
|
1535
|
-
static monthNum(month) {
|
|
1536
|
-
if (typeof month === 'number') {
|
|
1537
|
-
if (isNaN(month) || month > 14) {
|
|
1538
|
-
throw new RangeError(`bad monthNum: ${month}`);
|
|
1539
|
-
}
|
|
1540
|
-
return month;
|
|
1541
|
-
}
|
|
1542
|
-
if (typeof month !== 'string') {
|
|
1543
|
-
throw new TypeError(`bad monthNum: ${month}`);
|
|
1544
|
-
}
|
|
1545
|
-
return month.charCodeAt(0) >= 48 && month.charCodeAt(0) <= 57 /* number */
|
|
1546
|
-
? parseInt(month, 10)
|
|
1547
|
-
: monthFromName(month);
|
|
1548
|
-
}
|
|
1549
|
-
/**
|
|
1550
|
-
* Number of days in the Hebrew year.
|
|
1551
|
-
* Regular years can have 353, 354, or 355 days.
|
|
1552
|
-
* Leap years can have 383, 384, or 385 days.
|
|
1553
|
-
* @param year Hebrew year
|
|
1554
|
-
* @example
|
|
1555
|
-
* HDate.daysInYear(5783); // 355
|
|
1556
|
-
* HDate.daysInYear(5784); // 383
|
|
1557
|
-
*/
|
|
1558
|
-
static daysInYear(year) {
|
|
1559
|
-
return daysInYear(year);
|
|
1560
|
-
}
|
|
1561
|
-
/**
|
|
1562
|
-
* true if Cheshvan is long in Hebrew year
|
|
1563
|
-
* @param year Hebrew year
|
|
1564
|
-
* @example
|
|
1565
|
-
* HDate.longCheshvan(5783); // true
|
|
1566
|
-
* HDate.longCheshvan(5784); // false
|
|
1567
|
-
*/
|
|
1568
|
-
static longCheshvan(year) {
|
|
1569
|
-
return longCheshvan(year);
|
|
1570
|
-
}
|
|
1571
|
-
/**
|
|
1572
|
-
* true if Kislev is short in Hebrew year
|
|
1573
|
-
* @param year Hebrew year
|
|
1574
|
-
* @example
|
|
1575
|
-
* HDate.shortKislev(5783); // false
|
|
1576
|
-
* HDate.shortKislev(5784); // true
|
|
1577
|
-
*/
|
|
1578
|
-
static shortKislev(year) {
|
|
1579
|
-
return shortKislev(year);
|
|
1580
|
-
}
|
|
1581
|
-
/**
|
|
1582
|
-
* Converts Hebrew month string name to numeric
|
|
1583
|
-
* @example
|
|
1584
|
-
* import {HDate, months} from '@hebcal/hdate';
|
|
1585
|
-
* HDate.monthFromName(months.CHESHVAN); // 8
|
|
1586
|
-
* HDate.monthFromName('Cheshvan'); // 8
|
|
1587
|
-
* HDate.monthFromName('חשון'); // 8
|
|
1588
|
-
*/
|
|
1589
|
-
static monthFromName(monthName) {
|
|
1590
|
-
return monthFromName(monthName);
|
|
1591
|
-
}
|
|
1592
|
-
/**
|
|
1593
|
-
* Convenience function for determining the R.D. date
|
|
1594
|
-
* near a specified R.D. date, corresponding to the specified day of week.
|
|
1595
|
-
*
|
|
1596
|
-
* Note: Applying this function to d+6 gives us the `dayOfWeek` on or after an
|
|
1597
|
-
* absolute day d. Similarly, applying it to d+3 gives the `dayOfWeek` nearest to
|
|
1598
|
-
* absolute date d, applying it to d-1 gives the `dayOfWeek` previous to absolute
|
|
1599
|
-
* date d, and applying it to d+7 gives the `dayOfWeek` following absolute date d.
|
|
1600
|
-
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1601
|
-
*/
|
|
1602
|
-
static dayOnOrBefore(dayOfWeek, absdate) {
|
|
1603
|
-
return absdate - ((absdate - dayOfWeek) % 7);
|
|
1604
|
-
}
|
|
1605
|
-
/**
|
|
1606
|
-
* Tests if the object is an instance of `HDate`
|
|
1607
|
-
* @example
|
|
1608
|
-
* HDate.isHDate(new HDate()); // true
|
|
1609
|
-
* HDate.isHDate(new Date()); // false
|
|
1610
|
-
* HDate.isHDate(null); // false
|
|
1611
|
-
* HDate.isHDate(12345); // false
|
|
1612
|
-
* HDate.isHDate('15 Cheshvan 5769'); // false
|
|
1613
|
-
*/
|
|
1614
|
-
static isHDate(obj0) {
|
|
1615
|
-
const obj = obj0;
|
|
1616
|
-
return (obj !== null &&
|
|
1617
|
-
typeof obj === 'object' &&
|
|
1618
|
-
typeof obj.yy === 'number' &&
|
|
1619
|
-
typeof obj.mm === 'number' &&
|
|
1620
|
-
typeof obj.dd === 'number' &&
|
|
1621
|
-
typeof obj.greg === 'function' &&
|
|
1622
|
-
typeof obj.abs === 'function');
|
|
1623
|
-
}
|
|
1624
|
-
/**
|
|
1625
|
-
* Construct a new instance of `HDate` from a Gematriya-formatted string
|
|
1626
|
-
* @example
|
|
1627
|
-
* HDate.fromGematriyaString('כ״ז בְּתַמּוּז תשפ״ג') // 27 Tamuz 5783
|
|
1628
|
-
* HDate.fromGematriyaString('כ׳ סיון תש״ד') // 20 Sivan 5704
|
|
1629
|
-
* HDate.fromGematriyaString('ה׳ אִיָיר תש״ח') // 5 Iyyar 5708
|
|
1630
|
-
*/
|
|
1631
|
-
static fromGematriyaString(str, currentThousands = 5000) {
|
|
1632
|
-
if (typeof str !== 'string') {
|
|
1633
|
-
throw new TypeError(`bad gematriya str: ${str}`);
|
|
1634
|
-
}
|
|
1635
|
-
const parts = str.split(' ').filter(x => x.length !== 0);
|
|
1636
|
-
const numParts = parts.length;
|
|
1637
|
-
if (numParts !== 3 && numParts !== 4) {
|
|
1638
|
-
throw new RangeError(`cannot parse gematriya str: "${str}"`);
|
|
1639
|
-
}
|
|
1640
|
-
const day = gematriyaStrToNum(parts[0]);
|
|
1641
|
-
const monthStr = numParts === 3 ? parts[1] : parts[1] + ' ' + parts[2];
|
|
1642
|
-
const month = monthFromName(monthStr);
|
|
1643
|
-
const yearStr = numParts === 3 ? parts[2] : parts[3];
|
|
1644
|
-
let year = gematriyaStrToNum(yearStr);
|
|
1645
|
-
if (year < 1000) {
|
|
1646
|
-
year += currentThousands;
|
|
1647
|
-
}
|
|
1648
|
-
return new HDate(day, month, year);
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
function standardizeUnits(units) {
|
|
1652
|
-
switch (units) {
|
|
1653
|
-
case 'd':
|
|
1654
|
-
return UNITS_DAY;
|
|
1655
|
-
case 'w':
|
|
1656
|
-
return UNITS_WEEK;
|
|
1657
|
-
case 'M':
|
|
1658
|
-
return UNITS_MONTH;
|
|
1659
|
-
case 'y':
|
|
1660
|
-
return UNITS_YEAR;
|
|
1661
|
-
}
|
|
1662
|
-
const str = String(units || '')
|
|
1663
|
-
.toLowerCase()
|
|
1664
|
-
.replace(/s$/, '');
|
|
1665
|
-
switch (str) {
|
|
1666
|
-
case UNITS_DAY:
|
|
1667
|
-
case UNITS_WEEK:
|
|
1668
|
-
case UNITS_MONTH:
|
|
1669
|
-
case UNITS_YEAR:
|
|
1670
|
-
return str;
|
|
1671
|
-
}
|
|
1672
|
-
throw new TypeError(`Invalid units '${units}'`);
|
|
1673
|
-
}
|
|
1674
|
-
function getDayOfTranslation(locale) {
|
|
1675
|
-
switch (locale) {
|
|
1676
|
-
case 'en':
|
|
1677
|
-
case 's':
|
|
1678
|
-
case 'a':
|
|
1679
|
-
case 'ashkenazi':
|
|
1680
|
-
return ' of';
|
|
1681
|
-
}
|
|
1682
|
-
const ofStr = Locale.lookupTranslation('of', locale);
|
|
1683
|
-
if (ofStr) {
|
|
1684
|
-
return ' ' + ofStr;
|
|
1685
|
-
}
|
|
1686
|
-
if (locale.startsWith('ashkenazi')) {
|
|
1687
|
-
return ' of';
|
|
1688
|
-
}
|
|
1689
|
-
return '';
|
|
1690
|
-
}
|
|
1691
|
-
/**
|
|
1692
|
-
* Sets the day of the month of the date. Returns the object it was called upon
|
|
1693
|
-
* @private
|
|
1694
|
-
* @param month A number, or Hebrew month name string
|
|
1695
|
-
*/
|
|
1696
|
-
function setMonth(hd, month) {
|
|
1697
|
-
hd.mm = HDate.monthNum(month);
|
|
1698
|
-
fix(hd);
|
|
1699
|
-
return hd;
|
|
1700
|
-
}
|
|
1701
|
-
function setDate(hd, date) {
|
|
1702
|
-
hd.dd = date;
|
|
1703
|
-
fix(hd);
|
|
1704
|
-
return hd;
|
|
1705
|
-
}
|
|
1706
|
-
function fix(hd) {
|
|
1707
|
-
fixMonth(hd);
|
|
1708
|
-
fixDate(hd);
|
|
1709
|
-
}
|
|
1710
|
-
function fixDate(hd) {
|
|
1711
|
-
if (hd.dd < 1) {
|
|
1712
|
-
if (hd.mm === months.TISHREI) {
|
|
1713
|
-
hd.yy -= 1;
|
|
1714
|
-
}
|
|
1715
|
-
hd.dd += daysInMonth(hd.mm, hd.yy);
|
|
1716
|
-
hd.mm -= 1;
|
|
1717
|
-
fix(hd);
|
|
1718
|
-
}
|
|
1719
|
-
if (hd.dd > daysInMonth(hd.mm, hd.yy)) {
|
|
1720
|
-
if (hd.mm === months.ELUL) {
|
|
1721
|
-
hd.yy += 1;
|
|
1722
|
-
}
|
|
1723
|
-
hd.dd -= daysInMonth(hd.mm, hd.yy);
|
|
1724
|
-
if (hd.mm === monthsInYear(hd.yy)) {
|
|
1725
|
-
hd.mm = 1; // rollover to NISAN
|
|
1726
|
-
}
|
|
1727
|
-
else {
|
|
1728
|
-
hd.mm += 1;
|
|
1729
|
-
}
|
|
1730
|
-
fix(hd);
|
|
1731
|
-
}
|
|
1732
|
-
fixMonth(hd);
|
|
1733
|
-
}
|
|
1734
|
-
function fixMonth(hd) {
|
|
1735
|
-
if (hd.mm === months.ADAR_II && !hd.isLeapYear()) {
|
|
1736
|
-
hd.mm -= 1; // to Adar I
|
|
1737
|
-
fix(hd);
|
|
1738
|
-
}
|
|
1739
|
-
else if (hd.mm < 1) {
|
|
1740
|
-
hd.mm += monthsInYear(hd.yy);
|
|
1741
|
-
hd.yy -= 1;
|
|
1742
|
-
fix(hd);
|
|
1743
|
-
}
|
|
1744
|
-
else if (hd.mm > monthsInYear(hd.yy)) {
|
|
1745
|
-
hd.mm -= monthsInYear(hd.yy);
|
|
1746
|
-
hd.yy += 1;
|
|
1747
|
-
fix(hd);
|
|
1748
|
-
}
|
|
1749
|
-
delete hd.rd;
|
|
1750
|
-
}
|
|
1751
|
-
function onOrBefore(day, t, offset) {
|
|
1752
|
-
return new HDate(HDate.dayOnOrBefore(day, t.abs() + offset));
|
|
1753
|
-
}
|
|
1754
|
-
|
|
1755
|
-
function gematriya2(num) {
|
|
1756
|
-
const str = gematriya(num);
|
|
1757
|
-
return str.replaceAll(/[׳״]/g, '');
|
|
1758
|
-
}
|
|
1759
|
-
/**
|
|
1760
|
-
* Converts a `chapter:verse` string to Hebrew numerals (gematriya), e.g.
|
|
1761
|
-
* `'28:9'` becomes `'כח:ט'`. Returns the input unchanged if it is not a valid
|
|
1762
|
-
* `chapter:verse`, or `''` for `null`/`undefined`.
|
|
1763
|
-
* @param chapVerse a `chapter:verse` string
|
|
1764
|
-
* @returns the verse with chapter and verse in Hebrew numerals
|
|
1765
|
-
*/
|
|
1766
|
-
function formatVerseToHebrew(chapVerse) {
|
|
1767
|
-
if (chapVerse === undefined || chapVerse === null) {
|
|
1768
|
-
return '';
|
|
1769
|
-
}
|
|
1770
|
-
const cv = chapVerse.split(':');
|
|
1771
|
-
const chapter = parseInt(cv[0], 10);
|
|
1772
|
-
const verse = parseInt(cv[1], 10);
|
|
1773
|
-
// if not number return empty string
|
|
1774
|
-
if (isNaN(chapter) || isNaN(verse)) {
|
|
1775
|
-
return chapVerse;
|
|
1776
|
-
}
|
|
1777
|
-
return `${gematriya2(chapter)}:${gematriya2(verse)}`;
|
|
1778
|
-
}
|
|
1779
|
-
/**
|
|
1780
|
-
* Formats a passage compactly, omitting a repeated chapter number in the end
|
|
1781
|
-
* verse, e.g. `"Numbers 28:9-15"` (versus `"Numbers 28:9-28:15"`).
|
|
1782
|
-
* @param aliyah the passage to format
|
|
1783
|
-
* @param showBook whether to prefix the book name
|
|
1784
|
-
* @param [language] language for the book name and numerals (default `'en'`)
|
|
1785
|
-
* @returns the formatted citation
|
|
1786
|
-
*/
|
|
1787
|
-
function formatAliyahShort(aliyah, showBook, language = 'en') {
|
|
1788
|
-
const isEnglish = language === 'en';
|
|
1789
|
-
const begin = isEnglish ? aliyah.b : formatVerseToHebrew(aliyah.b);
|
|
1790
|
-
const end0 = isEnglish ? aliyah.e : formatVerseToHebrew(aliyah.e);
|
|
1791
|
-
const prefix = showBook ? locale.Locale.gettext(aliyah.k, language) + ' ' : '';
|
|
1792
|
-
if (begin === end0) {
|
|
1793
|
-
return `${prefix}${begin}`;
|
|
1794
|
-
}
|
|
1795
|
-
const cv1 = begin.split(':');
|
|
1796
|
-
const cv2 = end0.split(':');
|
|
1797
|
-
const end = cv1[0] === cv2[0] ? cv2[1] : end0;
|
|
1798
|
-
return `${prefix}${begin}-${end}`;
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
|
-
const Genesis=[0,31,25,24,26,32,22,24,22,29,32,32,20,18,24,21,16,27,33,38,18,34,24,20,67,34,35,46,22,35,43,54,33,20,31,29,43,36,30,23,23,57,38,34,34,28,34,31,22,33,26];const Exodus=[0,22,25,22,31,23,30,29,28,35,29,10,51,22,31,27,36,16,27,25,23,37,30,33,18,40,37,21,43,46,38,18,35,23,35,35,38,29,31,43,38];const Leviticus=[0,17,16,17,35,26,23,38,36,24,20,47,8,59,57,33,34,16,30,37,27,24,33,44,23,55,46,34];const Numbers=[0,54,34,51,49,31,27,89,26,23,36,35,16,33,45,41,35,28,32,22,29,35,41,30,25,19,65,23,31,39,17,54,42,56,29,34,13];const Deuteronomy=[0,46,37,29,49,30,25,26,20,29,22,32,31,19,29,23,22,20,22,21,20,23,29,26,22,19,19,26,69,28,20,30,52,29,12];const Joshua=[0,18,24,17,24,15,27,26,35,27,43,23,24,33,15,63,10,18,28,51,9,45,34,16,33];const Judges=[0,36,23,31,24,31,40,25,35,57,18,40,15,25,20,20,31,13,31,30,48,25];const Ruth=[0,22,23,18,22];const Isaiah=[0,31,22,26,6,30,13,25,23,20,34,16,6,22,32,9,14,14,7,25,6,17,25,18,23,12,21,13,29,24,33,9,20,24,17,10,22,38,22,8,31,29,25,28,28,25,13,15,22,26,11,23,15,12,17,13,12,21,14,21,22,11,12,19,11,25,24];const Jeremiah=[0,19,37,25,31,31,30,34,23,25,25,23,17,27,22,21,21,27,23,15,18,14,30,40,10,38,24,22,17,32,24,40,44,26,22,19,32,21,28,18,16,18,22,13,30,5,28,7,47,39,46,64,34];const Lamentations=[0,22,22,66,22,22];const Esther=[0,22,23,15,17,14,14,10,17,32,3];const Ecclesiastes=[0,18,26,22,17,19,12,29,17,18,20,10,14];const Ezekiel=[0,28,10,27,17,17,14,27,18,11,22,25,28,23,23,8,63,24,32,14,44,37,31,49,27,17,21,36,26,21,26,18,32,33,31,15,38,28,23,29,49,26,20,27,31,25,24,23,35];const Daniel=[0,21,49,100,34,30,29,28,27,27,21,45,13,64,42];const Hosea=[0,9,25,5,19,15,11,16,14,17,15,11,15,15,10];const Joel=[0,20,27,5,21];const Amos=[0,15,16,15,13,27,14,17,14,15];const Obadiah=[0,21];const Jonah=[0,16,11,10,11];const Micah=[0,16,13,12,14,14,16,20];const Nachum=[0,14,14,19];const Habakkuk=[0,17,20,19];const Zephaniah=[0,18,15,20];const Haggai=[0,15,23];const Zechariah=[0,17,17,10,14,11,15,14,23,17,12,17,14,9,21];const Malachi=[0,14,17,24];var numverses = {Genesis:Genesis,Exodus:Exodus,Leviticus:Leviticus,Numbers:Numbers,Deuteronomy:Deuteronomy,Joshua:Joshua,Judges:Judges,Ruth:Ruth,"I Samuel":[0,28,36,21,22,12,21,17,22,27,27,15,25,23,52,35,23,58,30,24,42,16,23,28,23,43,25,12,25,11,31,13],"II Samuel":[0,27,32,39,12,25,23,29,18,13,19,27,31,39,33,37,23,29,32,44,26,22,51,39,25],"I Kings":[0,53,46,28,20,32,38,51,66,28,29,43,33,34,31,34,34,24,46,21,43,29,54],"II Kings":[0,18,25,27,44,27,33,20,29,37,36,20,22,25,29,38,20,41,37,37,21,26,20,37,20,30],Isaiah:Isaiah,Jeremiah:Jeremiah,Lamentations:Lamentations,Esther:Esther,Ecclesiastes:Ecclesiastes,"Song of Songs":[0,17,17,11,16,16,12,14,14],Ezekiel:Ezekiel,Daniel:Daniel,Hosea:Hosea,Joel:Joel,Amos:Amos,Obadiah:Obadiah,Jonah:Jonah,Micah:Micah,Nachum:Nachum,Habakkuk:Habakkuk,Zephaniah:Zephaniah,Haggai:Haggai,Zechariah:Zechariah,Malachi:Malachi};
|
|
1802
|
-
|
|
1803
|
-
/**
|
|
1804
|
-
* Names of the books of the Torah.
|
|
1805
|
-
*
|
|
1806
|
-
* `BOOK[1] === 'Genesis'`
|
|
1807
|
-
* @readonly
|
|
1808
|
-
*/
|
|
1809
|
-
const BOOK = [
|
|
1810
|
-
'',
|
|
1811
|
-
'Genesis',
|
|
1812
|
-
'Exodus',
|
|
1813
|
-
'Leviticus',
|
|
1814
|
-
'Numbers',
|
|
1815
|
-
'Deuteronomy',
|
|
1816
|
-
];
|
|
1817
|
-
/**
|
|
1818
|
-
* The number of verses in each book of the Tanakh.
|
|
1819
|
-
* Indexed by English transliterated name of book,
|
|
1820
|
-
* and arrays are 1-based.
|
|
1821
|
-
*
|
|
1822
|
-
* There are 51 chapters in Genesis, so
|
|
1823
|
-
* `NUM_VERSES['Genesis'].length === 51`.
|
|
1824
|
-
*
|
|
1825
|
-
* There are 26 verses in Genesis chapter 4,
|
|
1826
|
-
* so `NUM_VERSES['Genesis'][4] === 26`.
|
|
1827
|
-
* @readonly
|
|
1828
|
-
*/
|
|
1829
|
-
const NUM_VERSES = numverses;
|
|
1830
|
-
/**
|
|
1831
|
-
* Joins a parsha name into a single string, using a hyphen for a doubled
|
|
1832
|
-
* parsha (e.g. `['Matot', 'Masei']` becomes `'Matot-Masei'`).
|
|
1833
|
-
* @param parsha a parsha name, or an array of one or two names
|
|
1834
|
-
* @returns the parsha name as a single string
|
|
1835
|
-
* @throws {TypeError} if `parsha` is an array of zero or more than two names
|
|
1836
|
-
*/
|
|
1837
|
-
function parshaToString(parsha) {
|
|
1838
|
-
if (typeof parsha === 'string') {
|
|
1839
|
-
return parsha;
|
|
1840
|
-
}
|
|
1841
|
-
else if (!Array.isArray(parsha) ||
|
|
1842
|
-
parsha.length === 0 ||
|
|
1843
|
-
parsha.length > 2) {
|
|
1844
|
-
throw new TypeError(`Bad parsha argument: ${parsha}`);
|
|
1845
|
-
}
|
|
1846
|
-
let s = parsha[0];
|
|
1847
|
-
if (parsha.length === 2) {
|
|
1848
|
-
s += '-' + parsha[1];
|
|
1849
|
-
}
|
|
1850
|
-
return s;
|
|
1851
|
-
}
|
|
1852
|
-
/**
|
|
1853
|
-
* Calculates the number of verses in an aliyah or Haftarah from its `b`
|
|
1854
|
-
* (begin verse), `e` (end verse) and `k` (book), caching the result on the
|
|
1855
|
-
* object's `v` field. If `v` is already set, returns it unchanged.
|
|
1856
|
-
* @param aliyah the passage to measure; mutated in place to set `v`
|
|
1857
|
-
* @returns the number of verses in the passage
|
|
1858
|
-
*/
|
|
1859
|
-
function calculateNumVerses(aliyah) {
|
|
1860
|
-
if (aliyah.v) {
|
|
1861
|
-
return aliyah.v;
|
|
1862
|
-
}
|
|
1863
|
-
aliyah.v = subtractVerses(aliyah.k, aliyah.b, aliyah.e) + 1;
|
|
1864
|
-
return aliyah.v;
|
|
1865
|
-
}
|
|
1866
|
-
/**
|
|
1867
|
-
* Finds the number of verses between two locations in the same book.
|
|
1868
|
-
* @param book The English name of the book (e.g. "Numbers")
|
|
1869
|
-
* @param from The starting verse (e.g. "28:9")
|
|
1870
|
-
* @param to The ending verse (e.g. "28:15")
|
|
1871
|
-
* @returns The number of verses between the two locations, excluding the `to` verse.
|
|
1872
|
-
*/
|
|
1873
|
-
function subtractVerses(book, from, to) {
|
|
1874
|
-
const chapVerseBegin = from.split(':');
|
|
1875
|
-
const chapVerseEnd = to.split(':');
|
|
1876
|
-
const c1 = parseInt(chapVerseBegin[0], 10);
|
|
1877
|
-
const c2 = parseInt(chapVerseEnd[0], 10);
|
|
1878
|
-
const v1 = parseInt(chapVerseBegin[1], 10);
|
|
1879
|
-
const v2 = parseInt(chapVerseEnd[1], 10);
|
|
1880
|
-
let result = 0;
|
|
1881
|
-
if (c1 === c2) {
|
|
1882
|
-
return v2 - v1;
|
|
1883
|
-
}
|
|
1884
|
-
const numv = NUM_VERSES[book];
|
|
1885
|
-
if (typeof numv !== 'object' || !numv.length) {
|
|
1886
|
-
throw new ReferenceError(`Can't find numverses for ${book}`);
|
|
1887
|
-
}
|
|
1888
|
-
let total = numv[c1] - v1;
|
|
1889
|
-
for (let chap = c1 + 1; chap < c2; chap++) {
|
|
1890
|
-
total += numv[chap];
|
|
1891
|
-
}
|
|
1892
|
-
total += v2;
|
|
1893
|
-
result = total;
|
|
1894
|
-
return result;
|
|
1895
|
-
}
|
|
1896
|
-
/**
|
|
1897
|
-
* Calculates the next verse after adding a number of verses to a given location.
|
|
1898
|
-
* @param book The English name of the book (e.g. "Numbers")
|
|
1899
|
-
* @param from The starting verse (e.g. "28:9")
|
|
1900
|
-
* @param numVerses The number of verses to add; must be nonnegative.
|
|
1901
|
-
* @returns The next verse after adding the specified number of verses,
|
|
1902
|
-
* or null if the resulting verse exceeds the number of verses
|
|
1903
|
-
* in the book.
|
|
1904
|
-
*/
|
|
1905
|
-
function addVerses(book, from, numVerses) {
|
|
1906
|
-
const chapVerseBegin = from.split(':');
|
|
1907
|
-
const c1 = parseInt(chapVerseBegin[0], 10);
|
|
1908
|
-
const v1 = parseInt(chapVerseBegin[1], 10);
|
|
1909
|
-
const numv = NUM_VERSES[book];
|
|
1910
|
-
if (typeof numv !== 'object' || !numv.length) {
|
|
1911
|
-
throw new ReferenceError(`Can't find numverses for ${book}`);
|
|
1912
|
-
}
|
|
1913
|
-
let total = v1 + numVerses;
|
|
1914
|
-
let c2 = c1;
|
|
1915
|
-
while (total > numv[c2]) {
|
|
1916
|
-
total -= numv[c2];
|
|
1917
|
-
c2++;
|
|
1918
|
-
if (!numv[c2])
|
|
1919
|
-
return null;
|
|
1920
|
-
}
|
|
1921
|
-
return `${c2}:${total}`;
|
|
1922
|
-
}
|
|
1923
|
-
/**
|
|
1924
|
-
* Formats an aliyah with its full begin and end citation, e.g.
|
|
1925
|
-
* `"Numbers 28:9-28:15"`. See {@link formatAliyahShort} for a shorter form.
|
|
1926
|
-
* @param a the passage to format
|
|
1927
|
-
* @returns the formatted English citation
|
|
1928
|
-
*/
|
|
1929
|
-
function formatAliyahWithBook(a) {
|
|
1930
|
-
return `${a.k} ${a.b}-${a.e}`;
|
|
1931
|
-
}
|
|
1932
|
-
|
|
1933
|
-
const Shavuot={note:"Israel only",il:true,megillah:"Ruth",haft:[{k:"Ezekiel",b:"1:1",e:"1:28"},{k:"Ezekiel",b:"3:12",e:"3:12"}],fullkriyah:{"1":{p:17,k:2,b:"19:1",e:"19:6"},"2":{p:17,k:2,b:"19:7",e:"19:13"},"3":{p:17,k:2,b:"19:14",e:"19:19"},"4":{p:17,k:2,b:"19:20",e:"20:14"},"5":{p:17,k:2,b:"20:15",e:"20:23"},M:{p:41,k:4,b:"28:26",e:"28:31"}}};const Purim={megillah:"Esther",fullkriyah:{"1":{p:16,k:2,b:"17:8",e:"17:10"},"2":{p:16,k:2,b:"17:11",e:"17:13"},"3":{p:16,k:2,b:"17:14",e:"17:16"}}};var festivals0 = {"Pesach I":{haft:[{k:"Joshua",b:"3:5",e:"3:7"},{k:"Joshua",b:"5:2",e:"6:1"},{k:"Joshua",b:"6:27",e:"6:27"}],seph:[{k:"Joshua",b:"5:2",e:"6:1"},{k:"Joshua",b:"6:27",e:"6:27"}],fullkriyah:{"1":{p:15,k:2,b:"12:21",e:"12:24"},"2":{p:15,k:2,b:"12:25",e:"12:28"},"3":{p:15,k:2,b:"12:29",e:"12:36"},"4":{p:15,k:2,b:"12:37",e:"12:42"},"5":{p:15,k:2,b:"12:43",e:"12:51"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach I (on Shabbat)":{haft:[{k:"Joshua",b:"3:5",e:"3:7"},{k:"Joshua",b:"5:2",e:"6:1"},{k:"Joshua",b:"6:27",e:"6:27"}],seph:[{k:"Joshua",b:"5:2",e:"6:1"},{k:"Joshua",b:"6:27",e:"6:27"}],fullkriyah:{"1":{p:15,k:2,b:"12:21",e:"12:24"},"2":{p:15,k:2,b:"12:25",e:"12:28"},"3":{p:15,k:2,b:"12:29",e:"12:32"},"4":{p:15,k:2,b:"12:33",e:"12:36"},"5":{p:15,k:2,b:"12:37",e:"12:42"},"6":{p:15,k:2,b:"12:43",e:"12:47"},"7":{p:15,k:2,b:"12:48",e:"12:51"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach II":{haft:[{k:"II Kings",b:"23:1",e:"23:9"},{k:"II Kings",b:"23:21",e:"23:25"}],fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach II (CH''M)":{note:"Israel only - according to Vaani T'fillati Siddur Yisraeli",il:true,fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:8"},"2":{p:31,k:3,b:"23:9",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:44"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 1":{fullkriyah:{"1":{p:15,k:2,b:"13:1",e:"13:4"},"2":{p:15,k:2,b:"13:5",e:"13:10"},"3":{p:15,k:2,b:"13:11",e:"13:16"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 2":{fullkriyah:{"1":{p:18,k:2,b:"22:24",e:"22:26"},"2":{p:18,k:2,b:"22:27",e:"23:5"},"3":{p:18,k:2,b:"23:6",e:"23:19"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 3":{fullkriyah:{"1":{p:21,k:2,b:"34:1",e:"34:10"},"2":{p:21,k:2,b:"34:11",e:"34:17"},"3":{p:21,k:2,b:"34:18",e:"34:26"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 4":{fullkriyah:{"1":{p:36,k:4,b:"9:1",e:"9:5"},"2":{p:36,k:4,b:"9:6",e:"9:8"},"3":{p:36,k:4,b:"9:9",e:"9:14"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Shabbat Chol ha-Moed":{megillah:"Song of Songs",haft:{k:"Ezekiel",b:"37:1",e:"37:14"},fullkriyah:{"1":{p:21,k:2,b:"33:12",e:"33:16"},"2":{p:21,k:2,b:"33:17",e:"33:19"},"3":{p:21,k:2,b:"33:20",e:"33:23"},"4":{p:21,k:2,b:"34:1",e:"34:3"},"5":{p:21,k:2,b:"34:4",e:"34:10"},"6":{p:21,k:2,b:"34:11",e:"34:17"},"7":{p:21,k:2,b:"34:18",e:"34:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VII":{haft:{k:"II Samuel",b:"22:1",e:"22:51"},fullkriyah:{"1":{p:16,k:2,b:"13:17",e:"13:22"},"2":{p:16,k:2,b:"14:1",e:"14:8"},"3":{p:16,k:2,b:"14:9",e:"14:14"},"4":{p:16,k:2,b:"14:15",e:"14:25"},"5":{p:16,k:2,b:"14:26",e:"15:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VII (on Shabbat)":{megillah:"Song of Songs",haft:{k:"II Samuel",b:"22:1",e:"22:51"},fullkriyah:{"1":{p:16,k:2,b:"13:17",e:"13:19"},"2":{p:16,k:2,b:"13:20",e:"13:22"},"3":{p:16,k:2,b:"14:1",e:"14:4"},"4":{p:16,k:2,b:"14:5",e:"14:8"},"5":{p:16,k:2,b:"14:9",e:"14:14"},"6":{p:16,k:2,b:"14:15",e:"14:25"},"7":{p:16,k:2,b:"14:26",e:"15:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VIII":{haft:{k:"Isaiah",b:"10:32",e:"12:6"},fullkriyah:{"1":{p:47,k:5,b:"15:19",e:"15:23"},"2":{p:47,k:5,b:"16:1",e:"16:3"},"3":{p:47,k:5,b:"16:4",e:"16:8"},"4":{p:47,k:5,b:"16:9",e:"16:12"},"5":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VIII (on Shabbat)":{megillah:"Song of Songs",haft:{k:"Isaiah",b:"10:32",e:"12:6"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach III (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 1"},"Pesach IV (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 2"},"Pesach V (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 3"},"Pesach VI (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 4"},"Pesach Chol ha-Moed Day 2 on Sunday":{alias:true,il:false,key:"Pesach Chol ha-Moed Day 1"},"Pesach Chol ha-Moed Day 3 on Monday":{alias:true,il:false,key:"Pesach Chol ha-Moed Day 2"},Shavuot:Shavuot,"Shavuot I":{haft:[{k:"Ezekiel",b:"1:1",e:"1:28"},{k:"Ezekiel",b:"3:12",e:"3:12"}],fullkriyah:{"1":{p:17,k:2,b:"19:1",e:"19:6"},"2":{p:17,k:2,b:"19:7",e:"19:13"},"3":{p:17,k:2,b:"19:14",e:"19:19"},"4":{p:17,k:2,b:"19:20",e:"20:14"},"5":{p:17,k:2,b:"20:15",e:"20:23"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Shavuot II":{megillah:"Ruth",haft:{k:"Habakkuk",b:"3:1",e:"3:19"},seph:{k:"Habakkuk",b:"2:20",e:"3:19"},fullkriyah:{"1":{p:47,k:5,b:"15:19",e:"15:23"},"2":{p:47,k:5,b:"16:1",e:"16:3"},"3":{p:47,k:5,b:"16:4",e:"16:8"},"4":{p:47,k:5,b:"16:9",e:"16:12"},"5":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Shavuot II (on Shabbat)":{megillah:"Ruth",haft:{k:"Habakkuk",b:"3:1",e:"3:19"},seph:{k:"Habakkuk",b:"2:20",e:"3:19"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Fast Day (Morning)":{fullkriyah:{"1":{p:21,k:2,b:"32:11",e:"32:14"},"2":{p:21,k:2,b:"34:1",e:"34:3"},"3":{p:21,k:2,b:"34:4",e:"34:10"}}},"Fast Day (Afternoon)":{haft:{k:"Isaiah",b:"55:6",e:"56:8"},fullkriyah:{"1":{p:21,k:2,b:"32:11",e:"32:14"},"2":{p:21,k:2,b:"34:1",e:"34:3"},M:{p:21,k:2,b:"34:4",e:"34:10"}}},"Asara B'Tevet":{alias:true,key:"Fast Day (Morning)"},"Ta'anit Esther":{alias:true,key:"Fast Day (Morning)"},"Tzom Gedaliah":{alias:true,key:"Fast Day (Morning)"},"Tzom Tammuz":{alias:true,key:"Fast Day (Morning)"},"Asara B'Tevet (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Ta'anit Esther (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Tzom Gedaliah (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Tzom Tammuz (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Erev Tish'a B'Av":{megillah:"Lamentations"},"Tish'a B'Av":{haft:{k:"Jeremiah",b:"8:13",e:"9:23"},fullkriyah:{"1":{p:45,k:5,b:"4:25",e:"4:29"},"2":{p:45,k:5,b:"4:30",e:"4:35"},"3":{p:45,k:5,b:"4:36",e:"4:40"}},megillah:"Lamentations"},"Tish'a B'Av (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Rosh Hashana I":{haft:{k:"I Samuel",b:"1:1",e:"2:10"},fullkriyah:{"1":{p:4,k:1,b:"21:1",e:"21:4"},"2":{p:4,k:1,b:"21:5",e:"21:12"},"3":{p:4,k:1,b:"21:13",e:"21:21"},"4":{p:4,k:1,b:"21:22",e:"21:27"},"5":{p:4,k:1,b:"21:28",e:"21:34"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Rosh Hashana I (on Shabbat)":{haft:{k:"I Samuel",b:"1:1",e:"2:10"},fullkriyah:{"1":{p:4,k:1,b:"21:1",e:"21:4"},"2":{p:4,k:1,b:"21:5",e:"21:8"},"3":{p:4,k:1,b:"21:9",e:"21:12"},"4":{p:4,k:1,b:"21:13",e:"21:17"},"5":{p:4,k:1,b:"21:18",e:"21:21"},"6":{p:4,k:1,b:"21:22",e:"21:27"},"7":{p:4,k:1,b:"21:28",e:"21:34"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Rosh Hashana II":{haft:{k:"Jeremiah",b:"31:2",e:"31:20",note:"labeled 31:1–19 in some books"},fullkriyah:{"1":{p:4,k:1,b:"22:1",e:"22:3"},"2":{p:4,k:1,b:"22:4",e:"22:8"},"3":{p:4,k:1,b:"22:9",e:"22:14"},"4":{p:4,k:1,b:"22:15",e:"22:19"},"5":{p:4,k:1,b:"22:20",e:"22:24"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Yom Kippur":{haft:{k:"Isaiah",b:"57:14",e:"58:14"},fullkriyah:{"1":{p:29,k:3,b:"16:1",e:"16:6"},"2":{p:29,k:3,b:"16:7",e:"16:11"},"3":{p:29,k:3,b:"16:12",e:"16:17"},"4":{p:29,k:3,b:"16:18",e:"16:24"},"5":{p:29,k:3,b:"16:25",e:"16:30"},"6":{p:29,k:3,b:"16:31",e:"16:34"},M:{p:41,k:4,b:"29:7",e:"29:11"}}},"Yom Kippur (on Shabbat)":{haft:{k:"Isaiah",b:"57:14",e:"58:14"},fullkriyah:{"1":{p:29,k:3,b:"16:1",e:"16:3"},"2":{p:29,k:3,b:"16:4",e:"16:6"},"3":{p:29,k:3,b:"16:7",e:"16:11"},"4":{p:29,k:3,b:"16:12",e:"16:17"},"5":{p:29,k:3,b:"16:18",e:"16:24"},"6":{p:29,k:3,b:"16:25",e:"16:30"},"7":{p:29,k:3,b:"16:31",e:"16:34"},M:{p:41,k:4,b:"29:7",e:"29:11"}}},"Yom Kippur (Mincha)":{alias:true,key:"Yom Kippur (Mincha, Traditional)"},"Yom Kippur (Mincha, Traditional)":{haft:[{k:"Jonah",b:"1:1",e:"4:11"},{k:"Micah",b:"7:18",e:"7:20"}],fullkriyah:{"1":{p:29,k:3,b:"18:1",e:"18:5"},"2":{p:29,k:3,b:"18:6",e:"18:21"},M:{p:29,k:3,b:"18:22",e:"18:30"}}},"Yom Kippur (Mincha, Alternate)":{haft:[{k:"Jonah",b:"1:1",e:"4:11"},{k:"Micah",b:"7:18",e:"7:20"}],fullkriyah:{"1":{p:30,k:3,b:"19:1",e:"19:4"},"2":{p:30,k:3,b:"19:5",e:"19:10"},M:{p:30,k:3,b:"19:11",e:"19:18"}}},"Sukkot I":{haft:{k:"Zechariah",b:"14:1",e:"14:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot I (on Shabbat)":{haft:{k:"Zechariah",b:"14:1",e:"14:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"22:33"},"2":{p:31,k:3,b:"23:1",e:"23:3"},"3":{p:31,k:3,b:"23:4",e:"23:8"},"4":{p:31,k:3,b:"23:9",e:"23:14"},"5":{p:31,k:3,b:"23:15",e:"23:22"},"6":{p:31,k:3,b:"23:23",e:"23:32"},"7":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot II":{haft:{k:"I Kings",b:"8:2",e:"8:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot Chol ha-Moed Day 1":{fullkriyah:{"1":{p:41,k:4,b:"29:17",e:"29:19"},"2":{p:41,k:4,b:"29:20",e:"29:22"},"3":{p:41,k:4,b:"29:23",e:"29:25"},"4":{p:41,k:4,b:"29:17",e:"29:22"}}},"Sukkot Chol ha-Moed Day 2":{fullkriyah:{"1":{p:41,k:4,b:"29:20",e:"29:22"},"2":{p:41,k:4,b:"29:23",e:"29:25"},"3":{p:41,k:4,b:"29:26",e:"29:28"},"4":{p:41,k:4,b:"29:20",e:"29:25"}}},"Sukkot Chol ha-Moed Day 3":{fullkriyah:{"1":{p:41,k:4,b:"29:23",e:"29:25"},"2":{p:41,k:4,b:"29:26",e:"29:28"},"3":{p:41,k:4,b:"29:29",e:"29:31"},"4":{p:41,k:4,b:"29:23",e:"29:28"}}},"Sukkot Chol ha-Moed Day 4":{fullkriyah:{"1":{p:41,k:4,b:"29:26",e:"29:28"},"2":{p:41,k:4,b:"29:29",e:"29:31"},"3":{p:41,k:4,b:"29:32",e:"29:34"},"4":{p:41,k:4,b:"29:26",e:"29:31"}}},"Sukkot Chol ha-Moed Day 5":{fullkriyah:{"1":{p:41,k:4,b:"29:29",e:"29:31"},"2":{p:41,k:4,b:"29:32",e:"29:34"},"3":{p:41,k:4,b:"29:35",e:"29:37"},"4":{p:41,k:4,b:"29:29",e:"29:34"}}},"Sukkot Shabbat Chol ha-Moed":{megillah:"Ecclesiastes",haft:{k:"Ezekiel",b:"38:18",e:"39:16"},fullkriyah:{"1":{p:21,k:2,b:"33:12",e:"33:16"},"2":{p:21,k:2,b:"33:17",e:"33:19"},"3":{p:21,k:2,b:"33:20",e:"33:23"},"4":{p:21,k:2,b:"34:1",e:"34:3"},"5":{p:21,k:2,b:"34:4",e:"34:10"},"6":{p:21,k:2,b:"34:11",e:"34:17"},"7":{p:21,k:2,b:"34:18",e:"34:26"},"M-day1":{p:41,k:4,b:"29:17",e:"29:22"},"M-day2":{p:41,k:4,b:"29:20",e:"29:25"},"M-day3":{p:41,k:4,b:"29:23",e:"29:28"},"M-day4":{p:41,k:4,b:"29:26",e:"29:31"},"M-day5":{p:41,k:4,b:"29:29",e:"29:34"}}},"Sukkot Final Day (Hoshana Raba)":{fullkriyah:{"1":{p:41,k:4,b:"29:26",e:"29:28"},"2":{p:41,k:4,b:"29:29",e:"29:31"},"3":{p:41,k:4,b:"29:32",e:"29:34"},"4":{p:41,k:4,b:"29:29",e:"29:34"}}},"Shmini Atzeret":{haft:{k:"I Kings",b:"8:54",e:"8:66"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"16:3"},"4":{p:47,k:5,b:"16:4",e:"16:8"},"5":{p:47,k:5,b:"16:9",e:"16:17"},M:{p:41,k:4,b:"29:35",e:"30:1"}},alt:{"1":{p:47,k:5,b:"14:22",e:"15:23"},"2":{p:47,k:5,b:"16:1",e:"16:3"},"3":{p:47,k:5,b:"16:4",e:"16:8"},"4":{p:47,k:5,b:"16:9",e:"16:12"},"5":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Shmini Atzeret (on Shabbat)":{megillah:"Ecclesiastes",haft:{k:"I Kings",b:"8:54",e:"8:66"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Erev Simchat Torah":{fullkriyah:{"1":{p:54,k:5,b:"33:1",e:"33:7"},"2":{p:54,k:5,b:"33:8",e:"33:12"},"3":{p:54,k:5,b:"33:13",e:"33:17"}}},"Simchat Torah":{haft:{k:"Joshua",b:"1:1",e:"1:18"},fullkriyah:{"1":{p:54,k:5,b:"33:1",e:"33:7"},"2":{p:54,k:5,b:"33:8",e:"33:12"},"3":{p:54,k:5,b:"33:13",e:"33:17"},"4":{p:54,k:5,b:"33:18",e:"33:21"},"5":{p:54,k:5,b:"33:22",e:"33:26"},"6":{p:54,k:5,b:"33:27",e:"34:12"},"7":{p:1,k:1,b:"1:1",e:"2:3"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Simchat Torah (on Shabbat)":{megillah:"Ecclesiastes",haft:{k:"Joshua",b:"1:1",e:"1:18"},fullkriyah:{"1":{p:54,k:5,b:"33:1",e:"33:7"},"2":{p:54,k:5,b:"33:8",e:"33:12"},"3":{p:54,k:5,b:"33:13",e:"33:17"},"4":{p:54,k:5,b:"33:18",e:"33:21"},"5":{p:54,k:5,b:"33:22",e:"33:26"},"6":{p:54,k:5,b:"33:27",e:"33:29"},"7":{p:54,k:5,b:"34:1",e:"34:12"},"8":{p:1,k:1,b:"1:1",e:"2:3"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Shabbat Rosh Chodesh Chanukah":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:35,k:4,b:"7:42",e:"7:47"}}},"Chanukah Day 1":{fullkriyah:{"1":{p:35,k:4,b:"7:1",e:"7:11"},"2":{p:35,k:4,b:"7:12",e:"7:14"},"3":{p:35,k:4,b:"7:15",e:"7:17"}},alt:{"1":{p:35,k:4,b:"7:1",e:"7:3"},"2":{p:35,k:4,b:"7:4",e:"7:11"},"3":{p:35,k:4,b:"7:12",e:"7:17"}}},"Chanukah Day 1 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:1",e:"7:17"}}},"Chanukah Day 2":{fullkriyah:{"1":{p:35,k:4,b:"7:18",e:"7:20"},"2":{p:35,k:4,b:"7:21",e:"7:23"},"3":{p:35,k:4,b:"7:24",e:"7:29"}},alt:{"1":{p:35,k:4,b:"7:18",e:"7:20"},"2":{p:35,k:4,b:"7:21",e:"7:23"},"3":{p:35,k:4,b:"7:18",e:"7:23"}}},"Chanukah Day 2 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:18",e:"7:23"}}},"Chanukah Day 3":{fullkriyah:{"1":{p:35,k:4,b:"7:24",e:"7:26"},"2":{p:35,k:4,b:"7:27",e:"7:29"},"3":{p:35,k:4,b:"7:30",e:"7:35"}},alt:{"1":{p:35,k:4,b:"7:24",e:"7:26"},"2":{p:35,k:4,b:"7:27",e:"7:29"},"3":{p:35,k:4,b:"7:24",e:"7:29"}}},"Chanukah Day 3 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:24",e:"7:29"}}},"Chanukah Day 4":{fullkriyah:{"1":{p:35,k:4,b:"7:30",e:"7:32"},"2":{p:35,k:4,b:"7:33",e:"7:35"},"3":{p:35,k:4,b:"7:36",e:"7:41"}},alt:{"1":{p:35,k:4,b:"7:30",e:"7:32"},"2":{p:35,k:4,b:"7:33",e:"7:35"},"3":{p:35,k:4,b:"7:30",e:"7:35"}}},"Chanukah Day 4 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:30",e:"7:35"}}},"Chanukah Day 5":{fullkriyah:{"1":{p:35,k:4,b:"7:36",e:"7:38"},"2":{p:35,k:4,b:"7:39",e:"7:41"},"3":{p:35,k:4,b:"7:42",e:"7:47"}},alt:{"1":{p:35,k:4,b:"7:36",e:"7:38"},"2":{p:35,k:4,b:"7:39",e:"7:41"},"3":{p:35,k:4,b:"7:36",e:"7:41"}}},"Chanukah Day 5 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:36",e:"7:41"}}},"Chanukah Day 6":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:5"},"2":{p:41,k:4,b:"28:6",e:"28:10"},"3":{p:41,k:4,b:"28:11",e:"28:15"},"4":{p:35,k:4,b:"7:42",e:"7:47"}}},"Chanukah Day 7":{fullkriyah:{"1":{p:35,k:4,b:"7:48",e:"7:50"},"2":{p:35,k:4,b:"7:51",e:"7:53"},"3":{p:35,k:4,b:"7:54",e:"7:59"}},alt:{"1":{p:35,k:4,b:"7:48",e:"7:50"},"2":{p:35,k:4,b:"7:51",e:"7:53"},"3":{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 7 (on Rosh Chodesh)":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:5"},"2":{p:41,k:4,b:"28:6",e:"28:10"},"3":{p:41,k:4,b:"28:11",e:"28:15"},"4":{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 7 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 8":{fullkriyah:{"1":{p:35,k:4,b:"7:54",e:"7:56"},"2":{p:35,k:4,b:"7:57",e:"7:59"},"3":{p:35,k:4,b:"7:60",e:"8:4"}}},"Chanukah Day 8 (on Shabbat)":{haft:{k:"I Kings",b:"7:40",e:"7:50"},fullkriyah:{M:{p:35,k:4,b:"7:54",e:"8:4"}}},"Erev Purim":{megillah:"Esther"},Purim:Purim,"Shushan Purim":{note:"Jerusalem & walled cities only",il:true,megillah:"Esther",fullkriyah:{"1":{p:16,k:2,b:"17:8",e:"17:10"},"2":{p:16,k:2,b:"17:11",e:"17:13"},"3":{p:16,k:2,b:"17:14",e:"17:16"}}},"Shushan Purim (on Shabbat)":{il:true,note:"Jerusalem & walled cities only: special maftir Exodus 17:8-16, same Haftara as Shabbat Zachor"},"Shabbat HaChodesh":{haft:{k:"Ezekiel",b:"45:16",e:"46:18"},seph:{k:"Ezekiel",b:"45:18",e:"46:15"},chabad:{k:"Ezekiel",b:"45:18",e:"46:16"},fullkriyah:{M:{p:15,k:2,b:"12:1",e:"12:20"}}},"Shabbat HaChodesh (on Rosh Chodesh)":{haft:{k:"Ezekiel",b:"45:16",e:"46:18"},seph:{k:"Ezekiel",b:"45:18",e:"46:15"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:15,k:2,b:"12:1",e:"12:20"}}},"Shabbat HaGadol":{haft:{k:"Malachi",b:"3:4",e:"3:24"}},"Shabbat Parah":{haft:{k:"Ezekiel",b:"36:16",e:"36:38"},seph:{k:"Ezekiel",b:"36:16",e:"36:36"},fullkriyah:{M:{p:39,k:4,b:"19:1",e:"19:22"}}},"Shabbat Shekalim":{haft:{k:"II Kings",b:"12:1",e:"12:17"},seph:{k:"II Kings",b:"11:17",e:"12:17"},fullkriyah:{M:{p:21,k:2,b:"30:11",e:"30:16"}}},"Shabbat Shekalim (on Rosh Chodesh)":{haft:{k:"II Kings",b:"12:1",e:"12:17"},seph:{k:"II Kings",b:"11:17",e:"12:17"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:21,k:2,b:"30:11",e:"30:16"}}},"Shabbat Shuva (with Vayeilech)":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"}]},"Shabbat Shuva (with Ha'azinu)":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Joel",b:"2:15",e:"2:27"}],seph:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"}]},"Shabbat Shuva":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"},{k:"Joel",b:"2:15",e:"2:27"}]},"Shabbat Zachor":{haft:{k:"I Samuel",b:"15:2",e:"15:34"},seph:{k:"I Samuel",b:"15:1",e:"15:34"},chabad:{sameas:"haft"},fullkriyah:{M:{p:49,k:5,b:"25:17",e:"25:19"}}},"Pinchas occurring after 17 Tammuz":{haft:{k:"Jeremiah",b:"1:1",e:"2:3"},haftTheme:{admonition:1}},"Kedoshim following Special Shabbat":{haft:{k:"Amos",b:"9:7",e:"9:15"},seph:{k:"Ezekiel",b:"20:2",e:"20:20"}},"Masei on Shabbat Rosh Chodesh":{haft:[{k:"Jeremiah",b:"2:4",e:"2:28"},{k:"Jeremiah",b:"3:4",e:"3:4"}],seph:[{k:"Jeremiah",b:"2:4",e:"2:28"},{k:"Jeremiah",b:"4:1",e:"4:2"},{k:"Isaiah",b:"66:1",e:"66:1"},{k:"Isaiah",b:"66:23",e:"66:23"}],haftTheme:{admonition:2},fullkriyah:{M:{p:41,k:4,b:"28:9",e:"28:15"}}},"Matot-Masei on Shabbat Rosh Chodesh":{alias:true,key:"Masei on Shabbat Rosh Chodesh"},"Ki Teitzei with 3rd Haftarah of Consolation":{haft:[{k:"Isaiah",b:"54:1",e:"54:10"},{k:"Isaiah",b:"54:11",e:"55:5"}],haftTheme:{consolation:"3,5"}},"Rosh Chodesh":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:3"},"2":{p:41,k:4,b:"28:3",e:"28:5"},"3":{p:41,k:4,b:"28:6",e:"28:10"},"4":{p:41,k:4,b:"28:11",e:"28:15"}}},"Rosh Chodesh Nisan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Iyyar":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Sivan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Tamuz":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Av":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Elul":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Tishrei":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Cheshvan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Kislev":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Sh'vat":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar I":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar II":{alias:true,key:"Rosh Chodesh"},"Shabbat Rosh Chodesh":{haft:{k:"Isaiah",b:"66:1",e:"66:24"},fullkriyah:{M:{p:41,k:4,b:"28:9",e:"28:15"}}},"Shabbat Machar Chodesh":{haft:{k:"I Samuel",b:"20:18",e:"20:42"}},"Yom HaAtzma'ut":{haft:{k:"Isaiah",b:"10:32",e:"12:6"},fullkriyah:{"1":{p:46,k:5,b:"7:12",e:"7:21"},"2":{p:46,k:5,b:"7:22",e:"8:3"},"3":{p:46,k:5,b:"8:4",e:"8:18"}}}};
|
|
1934
|
-
|
|
1935
|
-
const festivals = festivals0;
|
|
1936
|
-
/**
|
|
1937
|
-
* Tests whether `holiday-readings.json` has a reading for the given key.
|
|
1938
|
-
* @param holiday an (untranslated) reading key, e.g. `'Purim'`
|
|
1939
|
-
* @returns `true` if a reading exists for this key
|
|
1940
|
-
*/
|
|
1941
|
-
function hasFestival(holiday) {
|
|
1942
|
-
return typeof festivals[holiday] === 'object';
|
|
1943
|
-
}
|
|
1944
|
-
function aliyotBookNumToStr(aliyot) {
|
|
1945
|
-
if (aliyot) {
|
|
1946
|
-
for (const aliyah of Object.values(aliyot)) {
|
|
1947
|
-
if (typeof aliyah.k === 'number') {
|
|
1948
|
-
aliyah.k = BOOK[aliyah.k];
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
}
|
|
1952
|
-
}
|
|
1953
|
-
/**
|
|
1954
|
-
* Returns the raw reading metadata for a holiday key from
|
|
1955
|
-
* `holiday-readings.json`, resolving any `alias` entry and normalizing book
|
|
1956
|
-
* numbers to English names.
|
|
1957
|
-
*
|
|
1958
|
-
* This is the underlying data; most callers want
|
|
1959
|
-
* {@link getLeyningForHolidayKey}, which builds a complete {@link Leyning}.
|
|
1960
|
-
* @param holiday an (untranslated) reading key, e.g. `'Purim'`
|
|
1961
|
-
* @returns the raw festival metadata, or `undefined` if the key is unknown
|
|
1962
|
-
*/
|
|
1963
|
-
function lookupFestival(holiday) {
|
|
1964
|
-
let src = festivals[holiday];
|
|
1965
|
-
if (!src) {
|
|
1966
|
-
return undefined;
|
|
1967
|
-
}
|
|
1968
|
-
if (src.alias) {
|
|
1969
|
-
const tmp = festivals[src.key];
|
|
1970
|
-
if (!tmp) {
|
|
1971
|
-
throw new Error(`Leyning alias ${holiday} => ${src.key} not found`);
|
|
1972
|
-
}
|
|
1973
|
-
src = tmp;
|
|
1974
|
-
}
|
|
1975
|
-
const result = src.fullkriyah
|
|
1976
|
-
? structuredClone(src)
|
|
1977
|
-
: src;
|
|
1978
|
-
aliyotBookNumToStr(result.fullkriyah);
|
|
1979
|
-
aliyotBookNumToStr(result.alt);
|
|
1980
|
-
if (src.chabad && 'sameas' in src.chabad) {
|
|
1981
|
-
result.chabad = result.haft;
|
|
1982
|
-
}
|
|
1983
|
-
return result;
|
|
1984
|
-
}
|
|
1985
|
-
|
|
1986
|
-
/**
|
|
1987
|
-
* @private
|
|
1988
|
-
*/
|
|
1989
|
-
function isChapVerseBefore(a, b) {
|
|
1990
|
-
const cv1 = a.split(':').map(x => +x);
|
|
1991
|
-
const cv2 = b.split(':').map(x => +x);
|
|
1992
|
-
return cv1[0] * 100 + cv1[1] < cv2[0] * 100 + cv2[1];
|
|
1993
|
-
}
|
|
1994
|
-
/**
|
|
1995
|
-
* Formats one or more passages into a human-readable citation.
|
|
1996
|
-
*
|
|
1997
|
-
* Ranges from the same book are joined with commas
|
|
1998
|
-
* (`Isaiah 6:1-7:6, 9:5-6`); ranges from different books are joined with
|
|
1999
|
-
* semicolons (`Genesis 21:1-34; Numbers 29:1-6`).
|
|
2000
|
-
* @param parts a single passage or an array of passages
|
|
2001
|
-
* @param [language] language for book names (default `'en'`)
|
|
2002
|
-
* @returns the formatted citation
|
|
2003
|
-
*/
|
|
2004
|
-
function makeSummaryFromParts(parts, language = 'en') {
|
|
2005
|
-
if (!Array.isArray(parts)) {
|
|
2006
|
-
parts = [parts];
|
|
2007
|
-
}
|
|
2008
|
-
let prev = parts[0];
|
|
2009
|
-
let summary = formatAliyahShort(prev, true, language);
|
|
2010
|
-
for (let i = 1; i < parts.length; i++) {
|
|
2011
|
-
const part = parts[i];
|
|
2012
|
-
if (part.k === prev.k) {
|
|
2013
|
-
summary += ', ';
|
|
2014
|
-
}
|
|
2015
|
-
else {
|
|
2016
|
-
summary += `; ${locale.Locale.gettext(part.k, language)} `;
|
|
2017
|
-
}
|
|
2018
|
-
summary += formatAliyahShort(part, false, language);
|
|
2019
|
-
prev = part;
|
|
2020
|
-
}
|
|
2021
|
-
return summary;
|
|
2022
|
-
}
|
|
2023
|
-
/**
|
|
2024
|
-
* Collapses an `AliyotMap` into the minimal set of contiguous passages.
|
|
2025
|
-
*
|
|
2026
|
-
* Adjacent aliyot from the same book are merged; a non-contiguous passage
|
|
2027
|
-
* (such as a special 7th aliyah or maftir from another book) becomes its own
|
|
2028
|
-
* part. Useful for building a compact summary.
|
|
2029
|
-
* @param aliyot map of aliyot keyed by `'1'`–`'7'` plus `'M'`
|
|
2030
|
-
* @returns the contiguous passages, in reading order
|
|
2031
|
-
*/
|
|
2032
|
-
function makeLeyningParts(aliyot) {
|
|
2033
|
-
const nums = Object.keys(aliyot).filter(x => {
|
|
2034
|
-
if (x.length === 1) {
|
|
2035
|
-
return true;
|
|
2036
|
-
}
|
|
2037
|
-
const code = x.charCodeAt(0);
|
|
2038
|
-
return code >= 48 && code <= 57;
|
|
2039
|
-
});
|
|
2040
|
-
let start = aliyot[nums[0]];
|
|
2041
|
-
let end = start;
|
|
2042
|
-
const parts = [];
|
|
2043
|
-
for (let i = 0; i < nums.length; i++) {
|
|
2044
|
-
const num = nums[i];
|
|
2045
|
-
const aliyah = aliyot[num];
|
|
2046
|
-
if (i === nums.length - 1 && aliyah.k === end.k && aliyah.e === end.e) {
|
|
2047
|
-
// short-circuit when final aliyah is within the previous (e.g. M inside of 7)
|
|
2048
|
-
continue;
|
|
2049
|
-
}
|
|
2050
|
-
const prevEndChap = +end.e.split(':')[0];
|
|
2051
|
-
const curStartChap = +aliyah.b.split(':')[0];
|
|
2052
|
-
const sameOrNextChap = curStartChap === prevEndChap || curStartChap === prevEndChap + 1;
|
|
2053
|
-
if (i !== 0 &&
|
|
2054
|
-
(aliyah.k !== start.k ||
|
|
2055
|
-
isChapVerseBefore(aliyah.b, start.e) ||
|
|
2056
|
-
!sameOrNextChap)) {
|
|
2057
|
-
parts.push({ k: start.k, b: start.b, e: end.e });
|
|
2058
|
-
start = aliyah;
|
|
2059
|
-
}
|
|
2060
|
-
end = aliyah;
|
|
2061
|
-
}
|
|
2062
|
-
parts.push({ k: start.k, b: start.b, e: end.e });
|
|
2063
|
-
return parts;
|
|
2064
|
-
}
|
|
2065
|
-
/**
|
|
2066
|
-
* Builds a one-line summary of a Torah reading, e.g. `"Genesis 6:9-11:32"`.
|
|
2067
|
-
* Equivalent to {@link makeSummaryFromParts} applied to the output of
|
|
2068
|
-
* {@link makeLeyningParts}.
|
|
2069
|
-
* @param aliyot map of aliyot keyed by `'1'`–`'7'` plus `'M'`
|
|
2070
|
-
* @returns the formatted summary
|
|
2071
|
-
*/
|
|
2072
|
-
function makeLeyningSummary(aliyot) {
|
|
2073
|
-
const parts = makeLeyningParts(aliyot);
|
|
2074
|
-
return makeSummaryFromParts(parts);
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
/**
|
|
2078
|
-
* Bitmask of event flags that never have their own Torah reading (Daf Yomi,
|
|
2079
|
-
* Omer count, molad, Shabbat Mevarchim, etc.), used to skip such events when
|
|
2080
|
-
* finding a leyning key. {@link flags.MODERN_HOLIDAY} is included here, but a
|
|
2081
|
-
* few modern holidays do have readings — see {@link isModernHolidayWithReading}.
|
|
2082
|
-
* @readonly
|
|
2083
|
-
*/
|
|
2084
|
-
const HOLIDAY_IGNORE_MASK = event.flags.DAF_YOMI |
|
|
2085
|
-
event.flags.OMER_COUNT |
|
|
2086
|
-
event.flags.SHABBAT_MEVARCHIM |
|
|
2087
|
-
event.flags.MOLAD |
|
|
2088
|
-
event.flags.USER_EVENT |
|
|
2089
|
-
event.flags.HEBREW_DATE |
|
|
2090
|
-
event.flags.MISHNA_YOMI |
|
|
2091
|
-
event.flags.MODERN_HOLIDAY |
|
|
2092
|
-
event.flags.YERUSHALMI_YOMI;
|
|
2093
|
-
/**
|
|
2094
|
-
* Most modern holidays have no Torah reading, but a few (such as
|
|
2095
|
-
* Yom HaAtzma'ut) do have an entry in `holiday-readings.json`
|
|
2096
|
-
* @param ev event
|
|
2097
|
-
* @returns true if this is a modern holiday that has a reading
|
|
2098
|
-
*/
|
|
2099
|
-
function isModernHolidayWithReading(ev) {
|
|
2100
|
-
const mask = ev.getFlags();
|
|
2101
|
-
return Boolean(mask & event.flags.MODERN_HOLIDAY) && hasFestival(ev.getDesc());
|
|
2102
|
-
}
|
|
2103
|
-
/**
|
|
2104
|
-
* From an event's date, type and title, derives the key used to look up its
|
|
2105
|
-
* reading in `holiday-readings.json` (accounting for Shabbat, Rosh Chodesh,
|
|
2106
|
-
* Chol ha-Moed, and the Israel vs. Diaspora schedule).
|
|
2107
|
-
* @param ev the holiday event
|
|
2108
|
-
* @param [il] `true` for the Israel schedule (default `false`)
|
|
2109
|
-
* @returns the reading key for `holiday-readings.json`, or `undefined` if the
|
|
2110
|
-
* event has no reading
|
|
2111
|
-
*/
|
|
2112
|
-
function getLeyningKeyForEvent(ev, il = false) {
|
|
2113
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2114
|
-
if (ev.eventTime !== undefined) {
|
|
2115
|
-
return undefined;
|
|
2116
|
-
}
|
|
2117
|
-
const mask = ev.getFlags();
|
|
2118
|
-
if (mask & HOLIDAY_IGNORE_MASK) {
|
|
2119
|
-
return isModernHolidayWithReading(ev) ? ev.getDesc() : undefined;
|
|
2120
|
-
}
|
|
2121
|
-
// Skip all Erevs except for Simchat Torah
|
|
2122
|
-
const desc = ev.getDesc();
|
|
2123
|
-
if (mask & event.flags.EREV && !hasFestival(desc)) {
|
|
2124
|
-
return undefined;
|
|
2125
|
-
}
|
|
2126
|
-
const hd = ev.getDate();
|
|
2127
|
-
const day = hd.getDate();
|
|
2128
|
-
const dow = hd.abs() % 7;
|
|
2129
|
-
const month = hd.getMonth();
|
|
2130
|
-
const isShabbat = dow === 6;
|
|
2131
|
-
const isRoshChodesh = day === 1 || day === 30;
|
|
2132
|
-
const holiday = ev.basename();
|
|
2133
|
-
const isPesach = holiday === 'Pesach';
|
|
2134
|
-
if (il && isPesach) {
|
|
2135
|
-
if (isShabbat) {
|
|
2136
|
-
return day === 15 || day === 21
|
|
2137
|
-
? desc + ' (on Shabbat)'
|
|
2138
|
-
: 'Pesach Shabbat Chol ha-Moed';
|
|
2139
|
-
}
|
|
2140
|
-
return desc;
|
|
2141
|
-
}
|
|
2142
|
-
if (day === 1 && month === months.TISHREI) {
|
|
2143
|
-
return isShabbat ? 'Rosh Hashana I (on Shabbat)' : 'Rosh Hashana I';
|
|
2144
|
-
}
|
|
2145
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2146
|
-
const cholHaMoedDay = ev.cholHaMoedDay;
|
|
2147
|
-
if (typeof cholHaMoedDay === 'number') {
|
|
2148
|
-
// Sukkot or Pesach
|
|
2149
|
-
if (isShabbat) {
|
|
2150
|
-
return holiday + ' Shabbat Chol ha-Moed';
|
|
2151
|
-
}
|
|
2152
|
-
else if (desc === 'Sukkot VII (Hoshana Raba)') {
|
|
2153
|
-
return 'Sukkot Final Day (Hoshana Raba)';
|
|
2154
|
-
}
|
|
2155
|
-
if (isPesach && cholHaMoedDay) {
|
|
2156
|
-
if (dow === 0 && desc === "Pesach IV (CH''M)") {
|
|
2157
|
-
return 'Pesach Chol ha-Moed Day 2 on Sunday';
|
|
2158
|
-
}
|
|
2159
|
-
else if (dow === 1 && desc === "Pesach V (CH''M)") {
|
|
2160
|
-
return 'Pesach Chol ha-Moed Day 3 on Monday';
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
return `${holiday} Chol ha-Moed Day ${cholHaMoedDay}`;
|
|
2164
|
-
}
|
|
2165
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2166
|
-
const chanukahDay = ev.chanukahDay;
|
|
2167
|
-
if (typeof chanukahDay === 'number') {
|
|
2168
|
-
if (isShabbat && isRoshChodesh) {
|
|
2169
|
-
return 'Shabbat Rosh Chodesh Chanukah';
|
|
2170
|
-
}
|
|
2171
|
-
else if (isRoshChodesh && chanukahDay === 7) {
|
|
2172
|
-
return 'Chanukah Day 7 (on Rosh Chodesh)';
|
|
2173
|
-
}
|
|
2174
|
-
else if (isShabbat) {
|
|
2175
|
-
return `Chanukah Day ${chanukahDay} (on Shabbat)`;
|
|
2176
|
-
}
|
|
2177
|
-
else {
|
|
2178
|
-
return `Chanukah Day ${chanukahDay}`;
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
if (isRoshChodesh &&
|
|
2182
|
-
(desc === 'Shabbat HaChodesh' || desc === 'Shabbat Shekalim')) {
|
|
2183
|
-
return desc + ' (on Rosh Chodesh)';
|
|
2184
|
-
}
|
|
2185
|
-
if (il && desc === 'Shmini Atzeret') {
|
|
2186
|
-
return 'Simchat Torah' + (isShabbat ? ' (on Shabbat)' : '');
|
|
2187
|
-
}
|
|
2188
|
-
if (desc === 'Chag HaBanot') {
|
|
2189
|
-
return undefined;
|
|
2190
|
-
}
|
|
2191
|
-
if (isShabbat && 'Shabbat' !== desc.substring(0, 7)) {
|
|
2192
|
-
if (isRoshChodesh) {
|
|
2193
|
-
if (desc === 'Rosh Chodesh Tevet') {
|
|
2194
|
-
return 'Shabbat Rosh Chodesh Chanukah';
|
|
2195
|
-
}
|
|
2196
|
-
return 'Shabbat Rosh Chodesh';
|
|
2197
|
-
}
|
|
2198
|
-
const desc2 = desc + ' (on Shabbat)';
|
|
2199
|
-
if (hasFestival(desc2)) {
|
|
2200
|
-
return desc2;
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
2203
|
-
if (hasFestival(desc)) {
|
|
2204
|
-
return desc;
|
|
2205
|
-
}
|
|
2206
|
-
if (isShabbat) {
|
|
2207
|
-
const tommorow = hd.next().getDate();
|
|
2208
|
-
if (tommorow === 30 || tommorow === 1) {
|
|
2209
|
-
return 'Shabbat Machar Chodesh';
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
|
-
if (desc === 'Rosh Hashana LaBehemot') {
|
|
2213
|
-
return undefined;
|
|
2214
|
-
}
|
|
2215
|
-
if (desc === 'Rosh Chodesh Tevet') {
|
|
2216
|
-
if (isShabbat) {
|
|
2217
|
-
return 'Shabbat Rosh Chodesh Chanukah';
|
|
2218
|
-
}
|
|
2219
|
-
if (day === 30 || HDate.shortKislev(hd.getFullYear())) {
|
|
2220
|
-
return 'Chanukah Day 6'; // 30th of Kislev or 1st of Tevet
|
|
2221
|
-
}
|
|
2222
|
-
else {
|
|
2223
|
-
return 'Chanukah Day 7 (on Rosh Chodesh)'; // 1st of Tevet
|
|
2224
|
-
}
|
|
2225
|
-
}
|
|
2226
|
-
if (isRoshChodesh) {
|
|
2227
|
-
return desc;
|
|
2228
|
-
}
|
|
2229
|
-
if (desc === "Tish'a B'Av (observed)") {
|
|
2230
|
-
return "Tish'a B'Av";
|
|
2231
|
-
}
|
|
2232
|
-
return undefined;
|
|
2233
|
-
}
|
|
2234
|
-
|
|
2235
|
-
/**
|
|
2236
|
-
* Makes a deep copy of the src object using JSON stringify and parse
|
|
2237
|
-
* @deprecated Use structuredClone instead
|
|
2238
|
-
*/
|
|
2239
|
-
function clone(src) {
|
|
2240
|
-
return structuredClone(src);
|
|
2241
|
-
}
|
|
2242
|
-
/**
|
|
2243
|
-
* Deep-clones a Haftarah (a single passage or an array) and fills in the
|
|
2244
|
-
* verse count `v` on each passage via {@link calculateNumVerses}.
|
|
2245
|
-
* @param haft the Haftarah to clone
|
|
2246
|
-
* @returns a new Haftarah with verse counts populated
|
|
2247
|
-
*/
|
|
2248
|
-
function cloneHaftara(haft) {
|
|
2249
|
-
if (!haft) {
|
|
2250
|
-
return haft;
|
|
2251
|
-
}
|
|
2252
|
-
const dest = structuredClone(haft);
|
|
2253
|
-
if (Array.isArray(dest)) {
|
|
2254
|
-
dest.forEach(calculateNumVerses);
|
|
2255
|
-
}
|
|
2256
|
-
else {
|
|
2257
|
-
calculateNumVerses(dest);
|
|
2258
|
-
}
|
|
2259
|
-
return dest;
|
|
2260
|
-
}
|
|
2261
|
-
/**
|
|
2262
|
-
* Sums the verse counts (`v`) of a Haftarah's passages. Each passage must
|
|
2263
|
-
* already have its `v` populated (e.g. by {@link cloneHaftara}).
|
|
2264
|
-
* @param aliyot a single passage or an array of passages
|
|
2265
|
-
* @returns the total number of verses
|
|
2266
|
-
*/
|
|
2267
|
-
function sumVerses(aliyot) {
|
|
2268
|
-
return Array.isArray(aliyot)
|
|
2269
|
-
? aliyot.reduce((prev, cur) => prev + cur.v, 0)
|
|
2270
|
-
: aliyot.v;
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
function aliyotCombine67(aliyot) {
|
|
2274
|
-
const a6 = structuredClone(aliyot['6']);
|
|
2275
|
-
const a7 = aliyot['7'];
|
|
2276
|
-
if (a6.k !== a7.k) {
|
|
2277
|
-
throw new Error('Impossible to combine aliyot 6 & 7: ' + JSON.stringify(aliyot));
|
|
2278
|
-
}
|
|
2279
|
-
delete aliyot['7'];
|
|
2280
|
-
aliyot['6'] = {
|
|
2281
|
-
k: a6.k,
|
|
2282
|
-
b: a6.b,
|
|
2283
|
-
e: a7.e,
|
|
2284
|
-
};
|
|
2285
|
-
if (a6.v && a7.v) {
|
|
2286
|
-
aliyot['6'].v = a6.v + a7.v;
|
|
2287
|
-
}
|
|
2288
|
-
}
|
|
2289
|
-
function mergeAliyotWithSpecial(aliyot, special) {
|
|
2290
|
-
if (special['7']) {
|
|
2291
|
-
aliyotCombine67(aliyot);
|
|
2292
|
-
aliyot['7'] = structuredClone(special['7']);
|
|
2293
|
-
calculateNumVerses(aliyot['7']);
|
|
2294
|
-
}
|
|
2295
|
-
if (special['M']) {
|
|
2296
|
-
aliyot['M'] = structuredClone(special['M']);
|
|
2297
|
-
calculateNumVerses(aliyot['M']);
|
|
2298
|
-
}
|
|
2299
|
-
}
|
|
2300
|
-
/**
|
|
2301
|
-
* Determines if the regular parashat haShavua coincides with an event that requires
|
|
2302
|
-
* a special maftir or Haftara (for example Shabbat HaGadol, Shabbat Chanukah, Rosh
|
|
2303
|
-
* Chodesh or Machar Chodesh, etc.).
|
|
2304
|
-
*
|
|
2305
|
-
* This function does not modify `aliyot`. Instead, it returns a deep copy
|
|
2306
|
-
* with `aliyot['M']` replaced and sets `reason.M`
|
|
2307
|
-
* (and in some cases the 6th and 7th aliyah, setting `reason['7']`).
|
|
2308
|
-
*
|
|
2309
|
-
* If a special Haftarah applies, the result will have a `haft` property
|
|
2310
|
-
* pointing to Haftarah object and sets `reason.haftara`.
|
|
2311
|
-
* @param parsha untranslated parsha name(s), e.g. `['Pinchas']`
|
|
2312
|
-
* @param hd the Hebrew date of this Shabbat
|
|
2313
|
-
* @param il `true` for the Israel schedule
|
|
2314
|
-
* @param aliyot the parsha's regular Shabbat aliyot (not modified)
|
|
2315
|
-
* @returns the special-reading overrides (see {@link SpecialReading})
|
|
2316
|
-
*/
|
|
2317
|
-
function specialReadings2(parsha, hd, il, aliyot) {
|
|
2318
|
-
let haft;
|
|
2319
|
-
let seph;
|
|
2320
|
-
let chabad;
|
|
2321
|
-
let specialHaft = false;
|
|
2322
|
-
const reason = {};
|
|
2323
|
-
function handleSpecial(key) {
|
|
2324
|
-
const special = lookupFestival(key);
|
|
2325
|
-
if (!special) {
|
|
2326
|
-
return;
|
|
2327
|
-
}
|
|
2328
|
-
if (typeof special.il === 'boolean' && il !== special.il) {
|
|
2329
|
-
return;
|
|
2330
|
-
}
|
|
2331
|
-
if (special.haft && !specialHaft) {
|
|
2332
|
-
haft = cloneHaftara(special.haft);
|
|
2333
|
-
reason.haftara = key;
|
|
2334
|
-
specialHaft = true;
|
|
2335
|
-
if (special.seph) {
|
|
2336
|
-
seph = cloneHaftara(special.seph);
|
|
2337
|
-
reason.sephardic = key;
|
|
2338
|
-
}
|
|
2339
|
-
if (special.chabad) {
|
|
2340
|
-
chabad = cloneHaftara(special.chabad);
|
|
2341
|
-
reason.chabad = key;
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2344
|
-
if (special.fullkriyah) {
|
|
2345
|
-
const aliyotMap = structuredClone(aliyot);
|
|
2346
|
-
mergeAliyotWithSpecial(aliyotMap, special.fullkriyah);
|
|
2347
|
-
for (const num of Object.keys(special.fullkriyah)) {
|
|
2348
|
-
reason[num] = key;
|
|
2349
|
-
}
|
|
2350
|
-
aliyot = aliyotMap;
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
const parshaName = parshaToString(parsha);
|
|
2354
|
-
const events0 = holidays.getHolidaysOnDate(hd, il) || [];
|
|
2355
|
-
const events = events0.filter(ev => !(ev.getFlags() & event.flags.ROSH_CHODESH));
|
|
2356
|
-
for (const ev of events) {
|
|
2357
|
-
if (ev.getDesc() === 'Shabbat Shuva') {
|
|
2358
|
-
handleSpecial(`Shabbat Shuva (with ${parshaName})`);
|
|
2359
|
-
}
|
|
2360
|
-
else {
|
|
2361
|
-
const key = getLeyningKeyForEvent(ev, il);
|
|
2362
|
-
if (key) {
|
|
2363
|
-
handleSpecial(key);
|
|
2364
|
-
}
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
if (!haft) {
|
|
2368
|
-
const day = hd.getDate();
|
|
2369
|
-
if (parshaName === 'Pinchas' && day > 17) {
|
|
2370
|
-
// Pinchas is always read in Tamuz (never another month)
|
|
2371
|
-
// either on the 14, 16, 17 (in Israel), 19, 21, 23, 24
|
|
2372
|
-
handleSpecial('Pinchas occurring after 17 Tammuz');
|
|
2373
|
-
}
|
|
2374
|
-
else if (day === 30 || day === 1) {
|
|
2375
|
-
const key = parshaName === 'Masei' || parshaName === 'Matot-Masei'
|
|
2376
|
-
? `${parshaName} on Shabbat Rosh Chodesh`
|
|
2377
|
-
: 'Shabbat Rosh Chodesh';
|
|
2378
|
-
handleSpecial(key);
|
|
2379
|
-
}
|
|
2380
|
-
else if (parshaName === 'Ki Teitzei' && day === 14) {
|
|
2381
|
-
// Ki Teitzei is always read in Elul on 9, 11, 13 or 14
|
|
2382
|
-
// "Because Shabbat Re’eh was Rosh Ḥodesh, the usual 3rd haftarah of
|
|
2383
|
-
// consolation was not read. Chant the haftarah of Ki tetse and then
|
|
2384
|
-
// the haftarah of Re’eh as a single haftarah.
|
|
2385
|
-
// In the book of Isaiah these two brief passages are adjacent."
|
|
2386
|
-
// Source: Luaḥ Hashanah, Rabbi Miles B. Cohen and Leslie Rubin
|
|
2387
|
-
handleSpecial('Ki Teitzei with 3rd Haftarah of Consolation');
|
|
2388
|
-
}
|
|
2389
|
-
else if (parshaName === 'Kedoshim' &&
|
|
2390
|
-
(day === 26 || day === 28 || day === 6)) {
|
|
2391
|
-
// Kedoshim is read separately from Achrei Mot in ~37% of years.
|
|
2392
|
-
// When this happens, it is will be read on
|
|
2393
|
-
// 26th or 28th of Nisan (Achrei Mot was Shabbat HaGadol, ~10%),
|
|
2394
|
-
// or 1st of Iyyar (Rosh Chodesh, ~10%),
|
|
2395
|
-
// or 6th of Iyyar (~10%, immediately after Shabbat Machar Chodesh)
|
|
2396
|
-
// or 3rd of Iyyar (~6%, "the nominal situation — in which both parashiyyot
|
|
2397
|
-
// are read separately and no overriding occasions coincide")
|
|
2398
|
-
// http://www.scholar.davidesstein.name/Articles/HaftarotOfEtzHayim--Stein.pdf
|
|
2399
|
-
// "The Haftarot of Etz Hayim," David E. S. Stein, Conservative Judaism 54/3 (Spring 2002)
|
|
2400
|
-
handleSpecial('Kedoshim following Special Shabbat');
|
|
2401
|
-
}
|
|
2402
|
-
else if (hd.getMonth() !== months.AV) {
|
|
2403
|
-
// Parashat Re'eh is always read in Av on 25, 27, 29 or 30.
|
|
2404
|
-
// When it coincides with Erev Rosh Chodesh, the Haftarah is
|
|
2405
|
-
// עניה סוערה (Isaiah 54:11-55:5) and not מחר חדש
|
|
2406
|
-
const tommorow = hd.next().getDate();
|
|
2407
|
-
if (tommorow === 30 || tommorow === 1) {
|
|
2408
|
-
handleSpecial('Shabbat Machar Chodesh');
|
|
2409
|
-
}
|
|
2410
|
-
}
|
|
2411
|
-
}
|
|
2412
|
-
return { aliyot, reason, haft, seph, chabad };
|
|
2413
|
-
}
|
|
2414
|
-
|
|
2415
|
-
/**
|
|
2416
|
-
* Translates an aliyah's book name and verse numbers into the target
|
|
2417
|
-
* language, in place. Only Hebrew (`'he'`) currently transforms the object;
|
|
2418
|
-
* any other language leaves it unchanged.
|
|
2419
|
-
* @param aliyah the aliyah to translate (mutated in place)
|
|
2420
|
-
* @param language target language code, e.g. `'he'` for Hebrew
|
|
2421
|
-
* @returns the same `aliyah` object, translated
|
|
2422
|
-
*/
|
|
2423
|
-
function translateAliyah(aliyah, language) {
|
|
2424
|
-
if (language === 'he') {
|
|
2425
|
-
aliyah.k = locale.Locale.gettext(aliyah.k, language);
|
|
2426
|
-
aliyah.b = formatVerseToHebrew(aliyah.b);
|
|
2427
|
-
aliyah.e = formatVerseToHebrew(aliyah.e);
|
|
2428
|
-
}
|
|
2429
|
-
return aliyah;
|
|
2430
|
-
}
|
|
2431
|
-
/**
|
|
2432
|
-
* Translates aliyah(s) - handles single Aliyah, arrays, and AliyotMap.
|
|
2433
|
-
* For non-English languages, translates book names and converts verse numbers to Hebrew numerals.
|
|
2434
|
-
* Returns a new translated copy, leaving the original unchanged.
|
|
2435
|
-
* @param aliyahOrArray a single Aliyah, an array of Aliyah, or an AliyotMap
|
|
2436
|
-
* @param [language] target language code, e.g. `'he'` for Hebrew (default `'en'`)
|
|
2437
|
-
* @returns a translated copy in the same shape as the input
|
|
2438
|
-
*/
|
|
2439
|
-
function translateAliyahOrArray(aliyahOrArray, language = 'en') {
|
|
2440
|
-
// Handle array of Aliyah objects
|
|
2441
|
-
if (Array.isArray(aliyahOrArray)) {
|
|
2442
|
-
const result = aliyahOrArray.map(aliyah => {
|
|
2443
|
-
const copy = { ...aliyah };
|
|
2444
|
-
return translateAliyah(copy, language);
|
|
2445
|
-
});
|
|
2446
|
-
return result;
|
|
2447
|
-
}
|
|
2448
|
-
// Handle single Aliyah object (has 'k' or 'b' property)
|
|
2449
|
-
if ('k' in aliyahOrArray || 'b' in aliyahOrArray) {
|
|
2450
|
-
const copy = { ...aliyahOrArray };
|
|
2451
|
-
return translateAliyah(copy, language);
|
|
2452
|
-
}
|
|
2453
|
-
// Handle AliyotMap (Record<string, Aliyah>)
|
|
2454
|
-
const result = {};
|
|
2455
|
-
for (const [key, aliyah] of Object.entries(aliyahOrArray)) {
|
|
2456
|
-
const copy = { ...aliyah };
|
|
2457
|
-
result[key] = translateAliyah(copy, language);
|
|
2458
|
-
}
|
|
2459
|
-
return result;
|
|
2460
|
-
}
|
|
2461
|
-
/**
|
|
2462
|
-
* Translates a Leyning object to the target language.
|
|
2463
|
-
* @param leyning - The Leyning object to translate
|
|
2464
|
-
* @param language - The target language code (e.g., 'he' for Hebrew)
|
|
2465
|
-
* @returns The translated Leyning object
|
|
2466
|
-
* @example
|
|
2467
|
-
* const leyning: Leyning = {
|
|
2468
|
-
* seph: [{k: 'Genesis', b: '1:1', e: '1:5'}],
|
|
2469
|
-
* haft: [{k: 'Genesis', b: '1:6', e: '1:10'}],
|
|
2470
|
-
* megillah: [{k: 'Genesis', b: '1:11', e: '1:15'}],
|
|
2471
|
-
* fullkriyah: [{k: 'Genesis', b: '1:16', e: '1:20'}],
|
|
2472
|
-
* };
|
|
2473
|
-
* const translatedLeyning = translateLeyning(leyning, 'he');
|
|
2474
|
-
* @todo add reason translation
|
|
2475
|
-
*/
|
|
2476
|
-
function translateLeyning(leyning, language) {
|
|
2477
|
-
if (language === 'en') {
|
|
2478
|
-
return leyning;
|
|
2479
|
-
}
|
|
2480
|
-
if (leyning.seph) {
|
|
2481
|
-
leyning.sephardic = makeSummaryFromParts(leyning.seph, language);
|
|
2482
|
-
leyning.seph = translateAliyahOrArray(leyning.seph, language);
|
|
2483
|
-
}
|
|
2484
|
-
if (leyning.haft) {
|
|
2485
|
-
leyning.haftara = makeSummaryFromParts(leyning.haft, language);
|
|
2486
|
-
leyning.haft = translateAliyahOrArray(leyning.haft, language);
|
|
2487
|
-
}
|
|
2488
|
-
if (leyning.megillah) {
|
|
2489
|
-
const parts = makeLeyningParts(leyning.megillah);
|
|
2490
|
-
const megillahSummary = makeSummaryFromParts(parts, language);
|
|
2491
|
-
leyning.megillah = translateAliyahOrArray(leyning.megillah, language);
|
|
2492
|
-
leyning.summary = megillahSummary;
|
|
2493
|
-
}
|
|
2494
|
-
if (leyning.fullkriyah) {
|
|
2495
|
-
const parts = makeLeyningParts(leyning.fullkriyah);
|
|
2496
|
-
// TODO: add check for summary in those cases getLeyningForHolidayKey
|
|
2497
|
-
if (typeof leyning.fullkriyah['1'] === 'object') {
|
|
2498
|
-
leyning.summary = makeSummaryFromParts(parts, language);
|
|
2499
|
-
}
|
|
2500
|
-
leyning.fullkriyah = translateAliyahOrArray(leyning.fullkriyah, language);
|
|
2501
|
-
if (leyning.summaryParts) {
|
|
2502
|
-
leyning.summaryParts = translateAliyahOrArray(leyning.summaryParts, language);
|
|
2503
|
-
leyning.summary = makeSummaryFromParts(leyning.summaryParts, language);
|
|
2504
|
-
}
|
|
2505
|
-
}
|
|
2506
|
-
if (leyning.weekday) {
|
|
2507
|
-
const parts = makeLeyningParts(leyning.weekday);
|
|
2508
|
-
leyning.weekday = translateAliyahOrArray(leyning.weekday, language);
|
|
2509
|
-
leyning.summary = makeSummaryFromParts(parts, language);
|
|
2510
|
-
}
|
|
2511
|
-
return leyning;
|
|
2512
|
-
}
|
|
2513
|
-
|
|
2514
|
-
/**
|
|
2515
|
-
* Looks up the leyning for a holiday by its (untranslated) reading key —
|
|
2516
|
-
* one of the keys in `holiday-readings.json`.
|
|
2517
|
-
*
|
|
2518
|
-
* Most callers should use {@link getLeyningForHoliday}, which derives the key
|
|
2519
|
-
* from an event; use this directly only when you already know the key.
|
|
2520
|
-
* @param [key] reading name from `holiday-readings.json`, e.g.
|
|
2521
|
-
* `'Yom Kippur (Morning)'`. Returns `undefined` if omitted or unknown.
|
|
2522
|
-
* @param [cholHaMoedDay] day within Chol ha-Moed, used to pick the correct
|
|
2523
|
-
* maftir for `'Sukkot Shabbat Chol ha-Moed'`
|
|
2524
|
-
* @param [il] `true` for the Israel schedule; filters out readings that apply
|
|
2525
|
-
* only to the other schedule
|
|
2526
|
-
* @param [language] language for names and summary (default `'en'`)
|
|
2527
|
-
* @returns the holiday leyning, or `undefined` if there is no such reading
|
|
2528
|
-
*/
|
|
2529
|
-
function getLeyningForHolidayKey(key, cholHaMoedDay, il, language = 'en') {
|
|
2530
|
-
if (typeof key !== 'string') {
|
|
2531
|
-
return undefined;
|
|
2532
|
-
}
|
|
2533
|
-
const src = lookupFestival(key);
|
|
2534
|
-
if (!src) {
|
|
2535
|
-
return undefined;
|
|
2536
|
-
}
|
|
2537
|
-
const israelOnly = src.il;
|
|
2538
|
-
if (typeof israelOnly === 'boolean' &&
|
|
2539
|
-
typeof il === 'boolean' &&
|
|
2540
|
-
il !== israelOnly) {
|
|
2541
|
-
return undefined;
|
|
2542
|
-
}
|
|
2543
|
-
const leyning = {
|
|
2544
|
-
name: {
|
|
2545
|
-
en: key,
|
|
2546
|
-
he: locale.Locale.lookupTranslation(key, 'he'),
|
|
2547
|
-
},
|
|
2548
|
-
type: 'holiday',
|
|
2549
|
-
};
|
|
2550
|
-
if (src.fullkriyah) {
|
|
2551
|
-
leyning.fullkriyah = structuredClone(src.fullkriyah);
|
|
2552
|
-
if (key === 'Sukkot Shabbat Chol ha-Moed' && cholHaMoedDay) {
|
|
2553
|
-
leyning.fullkriyah['M'] = leyning.fullkriyah[`M-day${cholHaMoedDay}`];
|
|
2554
|
-
for (let day = 1; day <= 5; day++) {
|
|
2555
|
-
delete leyning.fullkriyah[`M-day${day}`];
|
|
2556
|
-
}
|
|
2557
|
-
}
|
|
2558
|
-
if (typeof leyning.fullkriyah['1'] === 'object') {
|
|
2559
|
-
const parts = makeLeyningParts(leyning.fullkriyah);
|
|
2560
|
-
leyning.summary = makeSummaryFromParts(parts);
|
|
2561
|
-
leyning.summaryParts = parts;
|
|
2562
|
-
}
|
|
2563
|
-
Object.values(leyning.fullkriyah).forEach(aliyah => calculateNumVerses(aliyah));
|
|
2564
|
-
if (src.alt) {
|
|
2565
|
-
leyning.alt = structuredClone(src.alt);
|
|
2566
|
-
for (const aliyah of Object.values(leyning.alt)) {
|
|
2567
|
-
calculateNumVerses(aliyah);
|
|
2568
|
-
}
|
|
2569
|
-
}
|
|
2570
|
-
}
|
|
2571
|
-
if (src.haft) {
|
|
2572
|
-
const haft = (leyning.haft = cloneHaftara(src.haft));
|
|
2573
|
-
leyning.haftara = makeSummaryFromParts(haft);
|
|
2574
|
-
leyning.haftaraNumV = sumVerses(haft);
|
|
2575
|
-
}
|
|
2576
|
-
if (src.seph) {
|
|
2577
|
-
const seph = (leyning.seph = cloneHaftara(src.seph));
|
|
2578
|
-
leyning.sephardic = makeSummaryFromParts(seph);
|
|
2579
|
-
leyning.sephardicNumV = sumVerses(seph);
|
|
2580
|
-
}
|
|
2581
|
-
if (src.chabad) {
|
|
2582
|
-
if ('sameas' in src.chabad) {
|
|
2583
|
-
leyning.chabad = leyning.haft;
|
|
2584
|
-
}
|
|
2585
|
-
else {
|
|
2586
|
-
leyning.chabad = cloneHaftara(src.chabad);
|
|
2587
|
-
}
|
|
2588
|
-
}
|
|
2589
|
-
let megillah = src.megillah;
|
|
2590
|
-
if (il && key === 'Pesach I (on Shabbat)')
|
|
2591
|
-
megillah = 'Song of Songs';
|
|
2592
|
-
if (megillah) {
|
|
2593
|
-
const chaps = NUM_VERSES[megillah];
|
|
2594
|
-
const m = {};
|
|
2595
|
-
for (let i = 1; i < chaps.length; i++) {
|
|
2596
|
-
const numv = chaps[i];
|
|
2597
|
-
m[`${i}`] = { k: megillah, b: `${i}:1`, e: `${i}:${numv}`, v: numv };
|
|
2598
|
-
}
|
|
2599
|
-
leyning.megillah = m;
|
|
2600
|
-
const parts = makeLeyningParts(m);
|
|
2601
|
-
if (leyning.summaryParts) {
|
|
2602
|
-
leyning.summaryParts.push(...parts);
|
|
2603
|
-
}
|
|
2604
|
-
const megillahSummary = makeSummaryFromParts(parts);
|
|
2605
|
-
leyning.summary = leyning.summary
|
|
2606
|
-
? leyning.summary + '; ' + megillahSummary
|
|
2607
|
-
: megillahSummary;
|
|
2608
|
-
}
|
|
2609
|
-
if (src.note) {
|
|
2610
|
-
leyning.note = src.note;
|
|
2611
|
-
}
|
|
2612
|
-
return translateLeyning(leyning, language);
|
|
2613
|
-
}
|
|
2614
|
-
/**
|
|
2615
|
-
* Looks up the leyning for a holiday event.
|
|
2616
|
-
*
|
|
2617
|
-
* Depending on the holiday, the result may include the full kriyah, a special
|
|
2618
|
-
* maftir, one or more Haftarot, and/or a megillah.
|
|
2619
|
-
* @param ev a Hebcal holiday event (not a parsha hashavua event)
|
|
2620
|
-
* @param [il] `true` for the Israel schedule (default `false`)
|
|
2621
|
-
* @param [language] language for names and summary (default `'en'`)
|
|
2622
|
-
* @returns the holiday leyning, or `undefined` if this event has no reading
|
|
2623
|
-
* @throws {TypeError} if `ev` is not a valid event or is a parsha event
|
|
2624
|
-
*/
|
|
2625
|
-
function getLeyningForHoliday(ev, il = false, language = 'en') {
|
|
2626
|
-
if (typeof ev !== 'object' || typeof ev.getFlags !== 'function') {
|
|
2627
|
-
throw new TypeError(`Bad event argument: ${JSON.stringify(ev)}`);
|
|
2628
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2629
|
-
}
|
|
2630
|
-
else if (ev.eventTime !== undefined) {
|
|
2631
|
-
// Events with eventTime are not supported for leyning lookup
|
|
2632
|
-
return undefined;
|
|
2633
|
-
}
|
|
2634
|
-
else if (ev.getFlags() & event.flags.PARSHA_HASHAVUA) {
|
|
2635
|
-
throw new TypeError(`Event should be a holiday: ${ev.getDesc()}`);
|
|
2636
|
-
}
|
|
2637
|
-
else if (ev.getFlags() & HOLIDAY_IGNORE_MASK &&
|
|
2638
|
-
!isModernHolidayWithReading(ev)) {
|
|
2639
|
-
return undefined;
|
|
2640
|
-
}
|
|
2641
|
-
const key = getLeyningKeyForEvent(ev, il);
|
|
2642
|
-
const leyning = getLeyningForHolidayKey(key, ev.cholHaMoedDay, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
2643
|
-
il, language);
|
|
2644
|
-
return leyning;
|
|
2645
|
-
}
|
|
2646
|
-
|
|
2647
|
-
const Bereshit={num:1,book:1,haft:{k:"Isaiah",b:"42:5",e:"43:10"},seph:{k:"Isaiah",b:"42:5",e:"42:21"},fullkriyah:{"1":["1:1","2:3"],"2":["2:4","2:19"],"3":["2:20","3:21"],"4":["3:22","4:18"],"5":["4:19","4:22","some sources use 4:19-26"],"6":["4:23","5:24","some sources use 5:1-24"],"7":["5:25","6:8"],M:["6:5","6:8"]},weekday:{"1":["1:1","1:5"],"2":["1:6","1:8"],"3":["1:9","1:13"]}};const Noach={num:2,book:1,haft:{k:"Isaiah",b:"54:1",e:"55:5"},seph:{k:"Isaiah",b:"54:1",e:"54:10"},fullkriyah:{"1":["6:9","6:22"],"2":["7:1","7:16"],"3":["7:17","8:14"],"4":["8:15","9:7"],"5":["9:8","9:17"],"6":["9:18","10:32"],"7":["11:1","11:32"],M:["11:29","11:32"]},weekday:{"1":["6:9","6:16"],"2":["6:17","6:19"],"3":["6:20","6:22"]}};const Vayera={num:4,book:1,haft:{k:"II Kings",b:"4:1",e:"4:37"},seph:{k:"II Kings",b:"4:1",e:"4:23"},chabad:{sameas:"haft"},fullkriyah:{"1":["18:1","18:14"],"2":["18:15","18:33"],"3":["19:1","19:20"],"4":["19:21","21:4"],"5":["21:5","21:21"],"6":["21:22","21:34"],"7":["22:1","22:24"],M:["22:20","22:24"]},weekday:{"1":["18:1","18:5"],"2":["18:6","18:8"],"3":["18:9","18:14"]}};const Toldot={num:6,book:1,haft:{k:"Malachi",b:"1:1",e:"2:7"},fullkriyah:{"1":["25:19","26:5"],"2":["26:6","26:12"],"3":["26:13","26:22"],"4":["26:23","26:29"],"5":["26:30","27:27"],"6":["27:28","28:4"],"7":["28:5","28:9"],M:["28:7","28:9"]},weekday:{"1":["25:19","25:22"],"2":["25:23","25:26"],"3":["25:27","26:5"]}};const Vayetzei={num:7,book:1,haft:{k:"Hosea",b:"12:13",e:"14:10"},seph:{k:"Hosea",b:"11:7",e:"12:12"},fullkriyah:{"1":["28:10","28:22"],"2":["29:1","29:17"],"3":["29:18","30:13"],"4":["30:14","30:27"],"5":["30:28","31:16"],"6":["31:17","31:42"],"7":["31:43","32:3"],M:["32:1","32:3"]},weekday:{"1":["28:10","28:12"],"2":["28:13","28:17"],"3":["28:18","28:22"]}};const Vayishlach={num:8,book:1,haft:{k:"Obadiah",b:"1:1",e:"1:21"},fullkriyah:{"1":["32:4","32:13"],"2":["32:14","32:30"],"3":["32:31","33:5"],"4":["33:6","33:20"],"5":["34:1","35:11"],"6":["35:12","36:19"],"7":["36:20","36:43"],M:["36:40","36:43"]},weekday:{"1":["32:4","32:6"],"2":["32:7","32:9"],"3":["32:10","32:13"]}};const Vayeshev={num:9,book:1,haft:{k:"Amos",b:"2:6",e:"3:8"},fullkriyah:{"1":["37:1","37:11"],"2":["37:12","37:22"],"3":["37:23","37:36"],"4":["38:1","38:30"],"5":["39:1","39:6"],"6":["39:7","39:23"],"7":["40:1","40:23"],M:["40:20","40:23"]},weekday:{"1":["37:1","37:3"],"2":["37:4","37:7"],"3":["37:8","37:11"]}};const Miketz={num:10,book:1,haft:{k:"I Kings",b:"3:15",e:"4:1"},fullkriyah:{"1":["41:1","41:14"],"2":["41:15","41:38"],"3":["41:39","41:52"],"4":["41:53","42:18"],"5":["42:19","43:15"],"6":["43:16","43:29"],"7":["43:30","44:17"],M:["44:14","44:17"]},weekday:{"1":["41:1","41:4"],"2":["41:5","41:7"],"3":["41:8","41:14"]}};const Vayigash={num:11,book:1,haft:{k:"Ezekiel",b:"37:15",e:"37:28"},fullkriyah:{"1":["44:18","44:30"],"2":["44:31","45:7"],"3":["45:8","45:18"],"4":["45:19","45:27"],"5":["45:28","46:27"],"6":["46:28","47:10"],"7":["47:11","47:27"],M:["47:25","47:27"]},weekday:{"1":["44:18","44:20"],"2":["44:21","44:24"],"3":["44:25","44:30"]}};const Vayechi={num:12,book:1,haft:{k:"I Kings",b:"2:1",e:"2:12"},fullkriyah:{"1":["47:28","48:9"],"2":["48:10","48:16"],"3":["48:17","48:22"],"4":["49:1","49:18"],"5":["49:19","49:26"],"6":["49:27","50:20"],"7":["50:21","50:26"],M:["50:23","50:26"]},weekday:{"1":["47:28","47:31"],"2":["48:1","48:3"],"3":["48:4","48:9"]}};const Shemot={num:13,book:2,haft:[{k:"Isaiah",b:"27:6",e:"28:13"},{k:"Isaiah",b:"29:22",e:"29:23"}],seph:{k:"Jeremiah",b:"1:1",e:"2:3"},fullkriyah:{"1":["1:1","1:17"],"2":["1:18","2:10"],"3":["2:11","2:25"],"4":["3:1","3:15"],"5":["3:16","4:17"],"6":["4:18","4:31"],"7":["5:1","6:1"],M:["5:22","6:1"]},weekday:{"1":["1:1","1:7"],"2":["1:8","1:12"],"3":["1:13","1:17"]}};const Vaera={num:14,book:2,haft:{k:"Ezekiel",b:"28:25",e:"29:21"},fullkriyah:{"1":["6:2","6:13"],"2":["6:14","6:28"],"3":["6:29","7:7"],"4":["7:8","8:6"],"5":["8:7","8:18"],"6":["8:19","9:16"],"7":["9:17","9:35"],M:["9:33","9:35"]},weekday:{"1":["6:2","6:5"],"2":["6:6","6:9"],"3":["6:10","6:13"]}};const Bo={num:15,book:2,haft:{k:"Jeremiah",b:"46:13",e:"46:28"},fullkriyah:{"1":["10:1","10:11"],"2":["10:12","10:23"],"3":["10:24","11:3"],"4":["11:4","12:20"],"5":["12:21","12:28"],"6":["12:29","12:51"],"7":["13:1","13:16"],M:["13:14","13:16"]},weekday:{"1":["10:1","10:3"],"2":["10:4","10:6"],"3":["10:7","10:11"]}};const Beshalach={num:16,book:2,haft:{k:"Judges",b:"4:4",e:"5:31"},seph:{k:"Judges",b:"5:1",e:"5:31"},chabad:{sameas:"haft"},fullkriyah:{"1":["13:17","14:8"],"2":["14:9","14:14"],"3":["14:15","14:25"],"4":["14:26","15:26"],"5":["15:27","16:10"],"6":["16:11","16:36"],"7":["17:1","17:16"],M:["17:14","17:16"]},weekday:{"1":["13:17","13:22"],"2":["14:1","14:4"],"3":["14:5","14:8"]}};const Yitro={num:17,book:2,haft:[{k:"Isaiah",b:"6:1",e:"7:6"},{k:"Isaiah",b:"9:5",e:"9:6"}],seph:{k:"Isaiah",b:"6:1",e:"6:13"},fullkriyah:{"1":["18:1","18:12"],"2":["18:13","18:23"],"3":["18:24","18:27"],"4":["19:1","19:6"],"5":["19:7","19:19"],"6":["19:20","20:14"],"7":["20:15","20:23"],M:["20:19","20:23"]},weekday:{"1":["18:1","18:4"],"2":["18:5","18:8"],"3":["18:9","18:12"]}};const Mishpatim={num:18,book:2,haft:[{k:"Jeremiah",b:"34:8",e:"34:22"},{k:"Jeremiah",b:"33:25",e:"33:26"}],fullkriyah:{"1":["21:1","21:19"],"2":["21:20","22:3"],"3":["22:4","22:26"],"4":["22:27","23:5"],"5":["23:6","23:19"],"6":["23:20","23:25"],"7":["23:26","24:18"],M:["24:15","24:18"]},weekday:{"1":["21:1","21:6"],"2":["21:7","21:11"],"3":["21:12","21:19"]}};const Terumah={num:19,book:2,haft:{k:"I Kings",b:"5:26",e:"6:13"},fullkriyah:{"1":["25:1","25:16"],"2":["25:17","25:40","some sources use 25:17-30"],"3":["26:1","26:14","some sources use 25:31-26:14"],"4":["26:15","26:30"],"5":["26:31","26:37"],"6":["27:1","27:8"],"7":["27:9","27:19"],M:["27:17","27:19"]},weekday:{"1":["25:1","25:5"],"2":["25:6","25:9"],"3":["25:10","25:16"]}};const Tetzaveh={num:20,book:2,haft:{k:"Ezekiel",b:"43:10",e:"43:27"},fullkriyah:{"1":["27:20","28:12"],"2":["28:13","28:30"],"3":["28:31","28:43"],"4":["29:1","29:18"],"5":["29:19","29:37"],"6":["29:38","29:46"],"7":["30:1","30:10"],M:["30:8","30:10"]},weekday:{"1":["27:20","28:5"],"2":["28:6","28:9"],"3":["28:10","28:12"]}};const Vayakhel={num:22,book:2,haft:{k:"I Kings",b:"7:40",e:"7:50"},seph:{k:"I Kings",b:"7:13",e:"7:26"},fullkriyah:{"1":["35:1","35:20"],"2":["35:21","35:29"],"3":["35:30","36:7"],"4":["36:8","36:19"],"5":["36:20","37:16"],"6":["37:17","37:29"],"7":["38:1","38:20"],M:["38:18","38:20"]},weekday:{"1":["35:1","35:3"],"2":["35:4","35:10"],"3":["35:11","35:20"]}};const Pekudei={num:23,book:2,haft:{k:"I Kings",b:"7:51",e:"8:21"},seph:{k:"I Kings",b:"7:40",e:"7:50"},chabad:{sameas:"haft"},fullkriyah:{"1":["38:21","39:1"],"2":["39:2","39:21"],"3":["39:22","39:32"],"4":["39:33","39:43"],"5":["40:1","40:16"],"6":["40:17","40:27"],"7":["40:28","40:38"],M:["40:34","40:38"]},weekday:{"1":["38:21","38:23"],"2":["38:24","38:27"],"3":["38:28","39:1"]}};const Vayikra={num:24,book:3,haft:{k:"Isaiah",b:"43:21",e:"44:23"},fullkriyah:{"1":["1:1","1:13"],"2":["1:14","2:6"],"3":["2:7","2:16"],"4":["3:1","3:17"],"5":["4:1","4:26"],"6":["4:27","5:10"],"7":["5:11","5:26"],M:["5:24","5:26"]},weekday:{"1":["1:1","1:4"],"2":["1:5","1:9"],"3":["1:10","1:13"]}};const Tzav={num:25,book:3,haft:[{k:"Jeremiah",b:"7:21",e:"8:3"},{k:"Jeremiah",b:"9:22",e:"9:23"}],chabad:[{k:"Jeremiah",b:"7:21",e:"7:28"},{k:"Jeremiah",b:"9:22",e:"9:23"}],fullkriyah:{"1":["6:1","6:11"],"2":["6:12","7:10"],"3":["7:11","7:38"],"4":["8:1","8:13"],"5":["8:14","8:21"],"6":["8:22","8:29"],"7":["8:30","8:36"],M:["8:33","8:36"]},weekday:{"1":["6:1","6:3"],"2":["6:4","6:6"],"3":["6:7","6:11"]}};const Shmini={num:26,book:3,haft:{k:"II Samuel",b:"6:1",e:"7:17"},seph:{k:"II Samuel",b:"6:1",e:"6:19"},fullkriyah:{"1":["9:1","9:16"],"2":["9:17","9:23"],"3":["9:24","10:11"],"4":["10:12","10:15"],"5":["10:16","10:20"],"6":["11:1","11:32"],"7":["11:33","11:47"],M:["11:45","11:47"]},weekday:{"1":["9:1","9:6"],"2":["9:7","9:10"],"3":["9:11","9:16"]}};const Tazria={num:27,book:3,haft:{k:"II Kings",b:"4:42",e:"5:19"},fullkriyah:{"1":["12:1","13:5"],"2":["13:6","13:17"],"3":["13:18","13:23"],"4":["13:24","13:28"],"5":["13:29","13:39"],"6":["13:40","13:54"],"7":["13:55","13:59"],M:["13:57","13:59"]},weekday:{"1":["12:1","12:4"],"2":["12:5","12:8"],"3":["13:1","13:5"]}};const Metzora={num:28,book:3,haft:{k:"II Kings",b:"7:3",e:"7:20"},fullkriyah:{"1":["14:1","14:12"],"2":["14:13","14:20"],"3":["14:21","14:32"],"4":["14:33","14:53"],"5":["14:54","15:15"],"6":["15:16","15:28"],"7":["15:29","15:33"],M:["15:31","15:33"]},weekday:{"1":["14:1","14:5"],"2":["14:6","14:9"],"3":["14:10","14:12"]}};const Kedoshim={num:30,book:3,haft:{k:"Ezekiel",b:"22:1",e:"22:19"},seph:{k:"Ezekiel",b:"20:2",e:"20:20"},fullkriyah:{"1":["19:1","19:14"],"2":["19:15","19:22"],"3":["19:23","19:32"],"4":["19:33","19:37"],"5":["20:1","20:7"],"6":["20:8","20:22"],"7":["20:23","20:27"],M:["20:25","20:27"]},weekday:{"1":["19:1","19:4"],"2":["19:5","19:10"],"3":["19:11","19:14"]}};const Emor={num:31,book:3,haft:{k:"Ezekiel",b:"44:15",e:"44:31"},fullkriyah:{"1":["21:1","21:15"],"2":["21:16","22:16"],"3":["22:17","22:33"],"4":["23:1","23:22"],"5":["23:23","23:32"],"6":["23:33","23:44"],"7":["24:1","24:23"],M:["24:21","24:23"]},weekday:{"1":["21:1","21:6"],"2":["21:7","21:12"],"3":["21:13","21:15"]}};const Behar={num:32,book:3,haft:{k:"Jeremiah",b:"32:6",e:"32:27"},chabad:{k:"Jeremiah",b:"32:6",e:"32:22"},fullkriyah:{"1":["25:1","25:13"],"2":["25:14","25:18"],"3":["25:19","25:24"],"4":["25:25","25:28"],"5":["25:29","25:38"],"6":["25:39","25:46"],"7":["25:47","26:2"],M:["25:55","26:2"]},weekday:{"1":["25:1","25:3"],"2":["25:4","25:7"],"3":["25:8","25:13"]}};const Bechukotai={num:33,book:3,haft:{k:"Jeremiah",b:"16:19",e:"17:14"},fullkriyah:{"1":["26:3","26:5"],"2":["26:6","26:9"],"3":["26:10","26:46"],"4":["27:1","27:15"],"5":["27:16","27:21"],"6":["27:22","27:28"],"7":["27:29","27:34"],M:["27:32","27:34"]},weekday:{"1":["26:3","26:5"],"2":["26:6","26:9"],"3":["26:10","26:13"]}};const Bamidbar={num:34,book:4,haft:{k:"Hosea",b:"2:1",e:"2:22"},fullkriyah:{"1":["1:1","1:19"],"2":["1:20","1:54"],"3":["2:1","2:34"],"4":["3:1","3:13"],"5":["3:14","3:39"],"6":["3:40","3:51"],"7":["4:1","4:20"],M:["4:17","4:20"]},weekday:{"1":["1:1","1:4"],"2":["1:5","1:16"],"3":["1:17","1:19"]}};const Nasso={num:35,book:4,haft:{k:"Judges",b:"13:2",e:"13:25"},fullkriyah:{"1":["4:21","4:37"],"2":["4:38","4:49"],"3":["5:1","5:10"],"4":["5:11","6:27"],"5":["7:1","7:41"],"6":["7:42","7:71"],"7":["7:72","7:89"],M:["7:87","7:89"]},weekday:{"1":["4:21","4:24"],"2":["4:25","4:28"],"3":["4:29","4:33"]}};const Korach={num:38,book:4,haft:{k:"I Samuel",b:"11:14",e:"12:22"},fullkriyah:{"1":["16:1","16:13"],"2":["16:14","16:19"],"3":["16:20","17:8"],"4":["17:9","17:15"],"5":["17:16","17:24"],"6":["17:25","18:20"],"7":["18:21","18:32"],M:["18:30","18:32"]},weekday:{"1":["16:1","16:3"],"2":["16:4","16:7"],"3":["16:8","16:13"]}};const Chukat={num:39,book:4,haft:{k:"Judges",b:"11:1",e:"11:33"},fullkriyah:{"1":["19:1","19:17"],"2":["19:18","20:6"],"3":["20:7","20:13"],"4":["20:14","20:21"],"5":["20:22","21:9"],"6":["21:10","21:20"],"7":["21:21","22:1"],M:["21:34","22:1"]},weekday:{"1":["19:1","19:6"],"2":["19:7","19:9"],"3":["19:10","19:17"]}};const Balak={num:40,book:4,haft:{k:"Micah",b:"5:6",e:"6:8"},fullkriyah:{"1":["22:2","22:12"],"2":["22:13","22:20"],"3":["22:21","22:38"],"4":["22:39","23:12"],"5":["23:13","23:26"],"6":["23:27","24:13"],"7":["24:14","25:9"],M:["25:7","25:9"]},weekday:{"1":["22:2","22:4"],"2":["22:5","22:7"],"3":["22:8","22:12"]}};const Pinchas={num:41,book:4,haft:{k:"I Kings",b:"18:46",e:"19:21"},fullkriyah:{"1":["25:10","26:4"],"2":["26:5","26:51"],"3":["26:52","27:5"],"4":["27:6","27:23"],"5":["28:1","28:15"],"6":["28:16","29:11"],"7":["29:12","30:1"],M:["29:35","30:1"]},weekday:{"1":["25:10","25:12"],"2":["25:13","25:15"],"3":["25:16","26:4"]}};const Matot={num:42,book:4,haft:{k:"Jeremiah",b:"1:1",e:"2:3"},haftTheme:{admonition:1},fullkriyah:{"1":["30:2","30:17"],"2":["31:1","31:12"],"3":["31:13","31:24"],"4":["31:25","31:41"],"5":["31:42","31:54"],"6":["32:1","32:19"],"7":["32:20","32:42"],M:["32:39","32:42"]},weekday:{"1":["30:2","30:9"],"2":["30:10","30:13"],"3":["30:14","30:17"]}};const Masei={num:43,book:4,haft:[{k:"Jeremiah",b:"2:4",e:"2:28"},{k:"Jeremiah",b:"3:4",e:"3:4"}],haftTheme:{admonition:2},seph:[{k:"Jeremiah",b:"2:4",e:"2:28"},{k:"Jeremiah",b:"4:1",e:"4:2"}],fullkriyah:{"1":["33:1","33:10"],"2":["33:11","33:49"],"3":["33:50","34:15"],"4":["34:16","34:29"],"5":["35:1","35:8"],"6":["35:9","35:34"],"7":["36:1","36:13"],M:["36:11","36:13"]},weekday:{"1":["33:1","33:3"],"2":["33:4","33:6"],"3":["33:7","33:10"]}};const Devarim={num:44,book:5,haft:{k:"Isaiah",b:"1:1",e:"1:27"},haftTheme:{admonition:3},fullkriyah:{"1":["1:1","1:10"],"2":["1:11","1:21"],"3":["1:22","1:38"],"4":["1:39","2:1"],"5":["2:2","2:30"],"6":["2:31","3:14"],"7":["3:15","3:22"],M:["3:20","3:22"]},weekday:{"1":["1:1","1:3"],"2":["1:4","1:7"],"3":["1:8","1:11"]}};const Vaetchanan={num:45,book:5,haft:{k:"Isaiah",b:"40:1",e:"40:26"},haftTheme:{consolation:1},fullkriyah:{"1":["3:23","4:4"],"2":["4:5","4:40"],"3":["4:41","4:49"],"4":["5:1","5:18"],"5":["5:19","6:3"],"6":["6:4","6:25"],"7":["7:1","7:11"],M:["7:9","7:11"]},weekday:{"1":["3:23","3:25"],"2":["3:26","4:4"],"3":["4:5","4:8"]}};const Eikev={num:46,book:5,haft:{k:"Isaiah",b:"49:14",e:"51:3"},haftTheme:{consolation:2},fullkriyah:{"1":["7:12","8:10"],"2":["8:11","9:3"],"3":["9:4","9:29"],"4":["10:1","10:11"],"5":["10:12","11:9"],"6":["11:10","11:21"],"7":["11:22","11:25"],M:["11:22","11:25"]},weekday:{"1":["7:12","7:21"],"2":["7:22","8:3"],"3":["8:4","8:10"]}};const Shoftim={num:48,book:5,haft:{k:"Isaiah",b:"51:12",e:"52:12"},haftTheme:{consolation:4},fullkriyah:{"1":["16:18","17:13"],"2":["17:14","17:20"],"3":["18:1","18:5"],"4":["18:6","18:13"],"5":["18:14","19:13"],"6":["19:14","20:9"],"7":["20:10","21:9"],M:["21:7","21:9"]},weekday:{"1":["16:18","16:20"],"2":["16:21","17:10"],"3":["17:11","17:13"]}};const Nitzavim={num:51,book:5,haft:{k:"Isaiah",b:"61:10",e:"63:9"},haftTheme:{consolation:7},fullkriyah:{"1":["29:9","29:11"],"2":["29:12","29:14"],"3":["29:15","29:28"],"4":["30:1","30:6"],"5":["30:7","30:10"],"6":["30:11","30:14"],"7":["30:15","30:20"],M:["30:15","30:20"]},weekday:{"1":["29:9","29:11"],"2":["29:12","29:14"],"3":["29:15","29:28"]}};const Vayeilech={num:52,book:5,haft:{k:"Isaiah",b:"55:6",e:"56:8"},fullkriyah:{"1":["31:1","31:3"],"2":["31:4","31:6"],"3":["31:7","31:9"],"4":["31:10","31:13"],"5":["31:14","31:19"],"6":["31:20","31:24"],"7":["31:25","31:30"],M:["31:28","31:30"]},weekday:{"1":["31:1","31:3"],"2":["31:4","31:6"],"3":["31:7","31:13"]}};var parshiyotObj0 = {Bereshit:Bereshit,Noach:Noach,"Lech-Lecha":{num:3,book:1,haft:{k:"Isaiah",b:"40:27",e:"41:16"},fullkriyah:{"1":["12:1","12:13"],"2":["12:14","13:4"],"3":["13:5","13:18"],"4":["14:1","14:20"],"5":["14:21","15:6"],"6":["15:7","17:6"],"7":["17:7","17:27"],M:["17:24","17:27"]},weekday:{"1":["12:1","12:3"],"2":["12:4","12:9"],"3":["12:10","12:13"]}},Vayera:Vayera,"Chayei Sara":{num:5,book:1,haft:{k:"I Kings",b:"1:1",e:"1:31"},fullkriyah:{"1":["23:1","23:16"],"2":["23:17","24:9"],"3":["24:10","24:26"],"4":["24:27","24:52"],"5":["24:53","24:67"],"6":["25:1","25:11"],"7":["25:12","25:18"],M:["25:16","25:18"]},weekday:{"1":["23:1","23:7"],"2":["23:8","23:12"],"3":["23:13","23:16"]}},Toldot:Toldot,Vayetzei:Vayetzei,Vayishlach:Vayishlach,Vayeshev:Vayeshev,Miketz:Miketz,Vayigash:Vayigash,Vayechi:Vayechi,Shemot:Shemot,Vaera:Vaera,Bo:Bo,Beshalach:Beshalach,Yitro:Yitro,Mishpatim:Mishpatim,Terumah:Terumah,Tetzaveh:Tetzaveh,"Ki Tisa":{num:21,book:2,haft:{k:"I Kings",b:"18:1",e:"18:39"},seph:{k:"I Kings",b:"18:20",e:"18:39"},fullkriyah:{"1":["30:11","31:17"],"2":["31:18","33:11"],"3":["33:12","33:16"],"4":["33:17","33:23"],"5":["34:1","34:9"],"6":["34:10","34:26"],"7":["34:27","34:35"],M:["34:33","34:35"]},weekday:{"1":["30:11","30:13"],"2":["30:14","30:16"],"3":["30:17","30:21"]}},Vayakhel:Vayakhel,Pekudei:Pekudei,Vayikra:Vayikra,Tzav:Tzav,Shmini:Shmini,Tazria:Tazria,Metzora:Metzora,"Achrei Mot":{num:29,book:3,haft:{k:"Amos",b:"9:7",e:"9:15"},seph:{k:"Ezekiel",b:"22:1",e:"22:16"},chabad:{sameas:"haft"},fullkriyah:{"1":["16:1","16:17"],"2":["16:18","16:24"],"3":["16:25","16:34"],"4":["17:1","17:7"],"5":["17:8","18:5"],"6":["18:6","18:21"],"7":["18:22","18:30"],M:["18:28","18:30"]},weekday:{"1":["16:1","16:6"],"2":["16:7","16:11"],"3":["16:12","16:17"]}},Kedoshim:Kedoshim,Emor:Emor,Behar:Behar,Bechukotai:Bechukotai,Bamidbar:Bamidbar,Nasso:Nasso,"Beha'alotcha":{num:36,book:4,haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{"1":["8:1","8:14"],"2":["8:15","8:26"],"3":["9:1","9:14"],"4":["9:15","10:10"],"5":["10:11","10:34"],"6":["10:35","11:29"],"7":["11:30","12:16"],M:["12:14","12:16"]},weekday:{"1":["8:1","8:4"],"2":["8:5","8:9"],"3":["8:10","8:14"]}},"Sh'lach":{num:37,book:4,haft:{k:"Joshua",b:"2:1",e:"2:24"},fullkriyah:{"1":["13:1","13:20"],"2":["13:21","14:7"],"3":["14:8","14:25"],"4":["14:26","15:7"],"5":["15:8","15:16"],"6":["15:17","15:26"],"7":["15:27","15:41"],M:["15:37","15:41"]},weekday:{"1":["13:1","13:3"],"2":["13:4","13:16"],"3":["13:17","13:20"]}},Korach:Korach,Chukat:Chukat,Balak:Balak,Pinchas:Pinchas,Matot:Matot,Masei:Masei,Devarim:Devarim,Vaetchanan:Vaetchanan,Eikev:Eikev,"Re'eh":{num:47,book:5,haft:{k:"Isaiah",b:"54:11",e:"55:5"},haftTheme:{consolation:3},fullkriyah:{"1":["11:26","12:10"],"2":["12:11","12:28"],"3":["12:29","13:19"],"4":["14:1","14:21"],"5":["14:22","14:29"],"6":["15:1","15:18"],"7":["15:19","16:17"],M:["16:13","16:17"]},weekday:{"1":["11:26","11:31"],"2":["11:32","12:5"],"3":["12:6","12:10"]}},Shoftim:Shoftim,"Ki Teitzei":{num:49,book:5,haft:{k:"Isaiah",b:"54:1",e:"54:10"},haftTheme:{consolation:5},fullkriyah:{"1":["21:10","21:21"],"2":["21:22","22:7"],"3":["22:8","23:7"],"4":["23:8","23:24"],"5":["23:25","24:4"],"6":["24:5","24:13"],"7":["24:14","25:19"],M:["25:17","25:19"]},weekday:{"1":["21:10","21:14"],"2":["21:15","21:17"],"3":["21:18","21:21"]}},"Ki Tavo":{num:50,book:5,haft:{k:"Isaiah",b:"60:1",e:"60:22"},haftTheme:{consolation:6},fullkriyah:{"1":["26:1","26:11"],"2":["26:12","26:15"],"3":["26:16","26:19"],"4":["27:1","27:10"],"5":["27:11","28:6"],"6":["28:7","28:69"],"7":["29:1","29:8"],M:["29:6","29:8"]},weekday:{"1":["26:1","26:3"],"2":["26:4","26:11"],"3":["26:12","26:15"]}},Nitzavim:Nitzavim,Vayeilech:Vayeilech,"Ha'azinu":{num:53,book:5,haft:{k:"II Samuel",b:"22:1",e:"22:51"},fullkriyah:{"1":["32:1","32:6"],"2":["32:7","32:12"],"3":["32:13","32:18"],"4":["32:19","32:28"],"5":["32:29","32:39"],"6":["32:40","32:43"],"7":["32:44","32:52"],M:["32:48","32:52"]},weekday:{"1":["32:1","32:3"],"2":["32:4","32:6"],"3":["32:7","32:12"]}},"Vezot Haberakhah":{num:54,book:5,haft:{k:"Joshua",b:"1:1",e:"1:18"},seph:{k:"Joshua",b:"1:1",e:"1:9"},chabad:{sameas:"haft"},fullkriyah:{"1":["33:1","33:7"],"2":["33:8","33:12"],"3":["33:13","33:17"],"4":["33:18","33:21"],"5":["33:22","33:26"],"6":["33:27","33:29"],"7":["34:1","34:12"]},weekday:{"1":["33:1","33:7"],"2":["33:8","33:12"],"3":["33:13","33:17"]}},"Vayakhel-Pekudei":{num:[22,23],combined:true,p1:"Vayakhel",p2:"Pekudei",num1:22,num2:23,book:2,fullkriyah:{"1":["35:1","35:29"],"2":["35:30","37:16"],"3":["37:17","37:29"],"4":["38:1","39:1"],"5":["39:2","39:21"],"6":["39:22","39:43"],"7":["40:1","40:38"],M:["40:34","40:38"]}},"Tazria-Metzora":{num:[27,28],combined:true,p1:"Tazria",p2:"Metzora",num1:27,num2:28,book:3,fullkriyah:{"1":["12:1","13:23"],"2":["13:24","13:39"],"3":["13:40","13:54"],"4":["13:55","14:20"],"5":["14:21","14:32"],"6":["14:33","15:15"],"7":["15:16","15:33"],M:["15:31","15:33"]}},"Achrei Mot-Kedoshim":{num:[29,30],combined:true,p1:"Achrei Mot",p2:"Kedoshim",num1:29,num2:30,book:3,haft:{k:"Amos",b:"9:7",e:"9:15"},seph:{k:"Ezekiel",b:"20:2",e:"20:20"},chabad:{sameas:"haft"},fullkriyah:{"1":["16:1","16:24"],"2":["16:25","17:7"],"3":["17:8","18:21"],"4":["18:22","19:14"],"5":["19:15","19:32"],"6":["19:33","20:7"],"7":["20:8","20:27"],M:["20:25","20:27"]}},"Behar-Bechukotai":{num:[32,33],combined:true,p1:"Behar",p2:"Bechukotai",num1:32,num2:33,book:3,fullkriyah:{"1":["25:1","25:18"],"2":["25:19","25:28"],"3":["25:29","25:38"],"4":["25:39","26:9"],"5":["26:10","26:46"],"6":["27:1","27:15"],"7":["27:16","27:34"],M:["27:32","27:34"]}},"Chukat-Balak":{num:[39,40],combined:true,p1:"Chukat",p2:"Balak",num1:39,num2:40,book:4,fullkriyah:{"1":["19:1","20:6"],"2":["20:7","20:21"],"3":["20:22","21:20"],"4":["21:21","22:12"],"5":["22:13","22:38"],"6":["22:39","23:26"],"7":["23:27","25:9"],M:["25:7","25:9"]}},"Matot-Masei":{num:[42,43],combined:true,p1:"Matot",p2:"Masei",num1:42,num2:43,book:4,fullkriyah:{"1":["30:2","31:12"],"2":["31:13","31:54"],"3":["32:1","32:19"],"4":["32:20","33:49"],"5":["33:50","34:15"],"6":["34:16","35:8"],"7":["35:9","36:13"],M:["36:11","36:13"]}},"Nitzavim-Vayeilech":{num:[51,52],combined:true,p1:"Nitzavim",p2:"Vayeilech",num1:51,num2:52,book:5,fullkriyah:{"1":["29:9","29:28"],"2":["30:1","30:6"],"3":["30:7","30:14"],"4":["30:15","31:6"],"5":["31:7","31:13"],"6":["31:14","31:19"],"7":["31:20","31:30"],M:["31:28","31:30"]}}};
|
|
2648
|
-
|
|
2649
|
-
const parshiyotObj = parshiyotObj0;
|
|
2650
|
-
/**
|
|
2651
|
-
* on doubled parshiot, read only the second Haftarah
|
|
2652
|
-
* except for Nitzavim-Vayelech and Achrei Mot-Kedoshim
|
|
2653
|
-
* @private
|
|
2654
|
-
*/
|
|
2655
|
-
function getHaftaraKey(parsha) {
|
|
2656
|
-
const first = parsha[0];
|
|
2657
|
-
if (parsha.length === 2 && first === 'Achrei Mot') {
|
|
2658
|
-
return parshaToString(parsha); // 'Achrei Mot-Kedoshim'
|
|
2659
|
-
}
|
|
2660
|
-
if (parsha.length === 1 || first === 'Nitzavim') {
|
|
2661
|
-
return first;
|
|
2662
|
-
}
|
|
2663
|
-
else {
|
|
2664
|
-
return parsha[1];
|
|
2665
|
-
}
|
|
2666
|
-
}
|
|
2667
|
-
/**
|
|
2668
|
-
* Builds the transliterated English and Hebrew names for a parsha.
|
|
2669
|
-
* @param parsha untranslated parsha name(s), e.g. `['Pinchas']` or
|
|
2670
|
-
* `['Matot', 'Masei']` for a doubled parsha
|
|
2671
|
-
* @returns object with the `en` name and `he` name (Hebrew with nikud)
|
|
2672
|
-
*/
|
|
2673
|
-
function makeLeyningNames(parsha) {
|
|
2674
|
-
const name = parshaToString(parsha);
|
|
2675
|
-
return {
|
|
2676
|
-
en: name,
|
|
2677
|
-
he: parsha.map(s => locale.Locale.lookupTranslation(s, 'he')).join('־'),
|
|
2678
|
-
};
|
|
2679
|
-
}
|
|
2680
|
-
/**
|
|
2681
|
-
* Looks up regular leyning for a weekly parsha with no special readings
|
|
2682
|
-
* @private
|
|
2683
|
-
* @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
|
|
2684
|
-
* @returns map of aliyot
|
|
2685
|
-
*/
|
|
2686
|
-
function getLeyningForParshaShabbatOnly(parsha, language = 'en') {
|
|
2687
|
-
const raw = lookupParsha(parsha);
|
|
2688
|
-
const fullkriyah = {};
|
|
2689
|
-
const book = BOOK[raw.book];
|
|
2690
|
-
for (const [num, src] of Object.entries(raw.fullkriyah)) {
|
|
2691
|
-
const aliyah = { k: book, b: src[0], e: src[1] };
|
|
2692
|
-
if (src.length === 3) {
|
|
2693
|
-
aliyah.reason = src[2];
|
|
2694
|
-
}
|
|
2695
|
-
calculateNumVerses(aliyah);
|
|
2696
|
-
fullkriyah[num] = aliyah;
|
|
2697
|
-
}
|
|
2698
|
-
const name = parshaToString(parsha);
|
|
2699
|
-
const parshaNameArray = raw.combined ? [raw.p1, raw.p2] : [name];
|
|
2700
|
-
const parts = makeLeyningParts(fullkriyah);
|
|
2701
|
-
const summary = makeSummaryFromParts(parts);
|
|
2702
|
-
const result = {
|
|
2703
|
-
name: makeLeyningNames(parshaNameArray),
|
|
2704
|
-
type: 'shabbat',
|
|
2705
|
-
parsha: parshaNameArray,
|
|
2706
|
-
parshaNum: raw.num,
|
|
2707
|
-
summary,
|
|
2708
|
-
fullkriyah: fullkriyah,
|
|
2709
|
-
haftara: '',
|
|
2710
|
-
haft: [],
|
|
2711
|
-
};
|
|
2712
|
-
if (parts.length > 1) {
|
|
2713
|
-
result.summaryParts = parts;
|
|
2714
|
-
}
|
|
2715
|
-
const hkey = getHaftaraKey(parshaNameArray);
|
|
2716
|
-
const haft0 = parshiyotObj[hkey].haft;
|
|
2717
|
-
if (haft0) {
|
|
2718
|
-
const haft = (result.haft = cloneHaftara(haft0));
|
|
2719
|
-
result.haftara = makeSummaryFromParts(haft);
|
|
2720
|
-
result.haftaraNumV = sumVerses(haft);
|
|
2721
|
-
}
|
|
2722
|
-
const seph0 = parshiyotObj[hkey].seph;
|
|
2723
|
-
if (seph0) {
|
|
2724
|
-
const seph = (result.seph = cloneHaftara(seph0));
|
|
2725
|
-
result.sephardic = makeSummaryFromParts(seph);
|
|
2726
|
-
result.sephardicNumV = sumVerses(seph);
|
|
2727
|
-
}
|
|
2728
|
-
const chabad = parshiyotObj[hkey].chabad;
|
|
2729
|
-
if (chabad) {
|
|
2730
|
-
if ('sameas' in chabad) {
|
|
2731
|
-
result.chabad = result.haft;
|
|
2732
|
-
}
|
|
2733
|
-
else {
|
|
2734
|
-
result.chabad = cloneHaftara(chabad);
|
|
2735
|
-
}
|
|
2736
|
-
}
|
|
2737
|
-
return translateLeyning(result, language);
|
|
2738
|
-
}
|
|
2739
|
-
/**
|
|
2740
|
-
* Looks up the weekday (Monday & Thursday) Torah reading for a regular parsha.
|
|
2741
|
-
*
|
|
2742
|
-
* These are the abbreviated three-aliyah readings chanted on weekday
|
|
2743
|
-
* mornings, drawn from the beginning of the upcoming Shabbat parsha.
|
|
2744
|
-
* @param parsha untranslated name, e.g. `'Pinchas'`, `['Pinchas']`, or
|
|
2745
|
-
* `['Matot', 'Masei']` for a doubled parsha
|
|
2746
|
-
* @param [language] language for book names (default `'en'`)
|
|
2747
|
-
* @returns map of aliyot keyed by `'1'` through `'3'`
|
|
2748
|
-
*/
|
|
2749
|
-
function getWeekdayReading(parsha, language = 'en') {
|
|
2750
|
-
const raw = lookupParsha(parsha);
|
|
2751
|
-
const parshaMeta = raw.combined ? lookupParsha(raw.p1) : raw;
|
|
2752
|
-
const aliyot = parshaMeta.weekday;
|
|
2753
|
-
if (!aliyot) {
|
|
2754
|
-
throw new Error(`Parsha missing weekday: ${parsha}`);
|
|
2755
|
-
}
|
|
2756
|
-
const book = BOOK[raw.book];
|
|
2757
|
-
const weekday = {};
|
|
2758
|
-
for (let i = 1; i <= 3; i++) {
|
|
2759
|
-
const num = '' + i;
|
|
2760
|
-
const src = aliyot[num];
|
|
2761
|
-
const aliyah = { k: book, b: src[0], e: src[1] };
|
|
2762
|
-
calculateNumVerses(aliyah);
|
|
2763
|
-
weekday[num] = aliyah;
|
|
2764
|
-
}
|
|
2765
|
-
return translateAliyahOrArray(weekday, language);
|
|
2766
|
-
}
|
|
2767
|
-
/**
|
|
2768
|
-
* Looks up the leyning for a regular parsha, ignoring any special occasion.
|
|
2769
|
-
*
|
|
2770
|
-
* Unlike {@link getLeyningForParshaHaShavua}, this takes a bare parsha name
|
|
2771
|
-
* rather than a dated event and applies no special maftir/Haftarah overrides,
|
|
2772
|
-
* so it is date-independent. The result includes both the Shabbat
|
|
2773
|
-
* `fullkriyah` and the `weekday` reading.
|
|
2774
|
-
* @param parsha untranslated name, e.g. `'Pinchas'`, `['Pinchas']`, or
|
|
2775
|
-
* `['Matot', 'Masei']` for a doubled parsha
|
|
2776
|
-
* @param [language] language for names and summary (default `'en'`)
|
|
2777
|
-
* @returns the complete leyning for this parsha
|
|
2778
|
-
*/
|
|
2779
|
-
function getLeyningForParsha(parsha, language = 'en') {
|
|
2780
|
-
const result = getLeyningForParshaShabbatOnly(parsha, language);
|
|
2781
|
-
result.weekday = getWeekdayReading(parsha);
|
|
2782
|
-
return result;
|
|
2783
|
-
}
|
|
2784
|
-
const reasonHaftKey = {
|
|
2785
|
-
haftara: 'haft',
|
|
2786
|
-
sephardic: 'seph',
|
|
2787
|
-
chabad: 'chabad',
|
|
2788
|
-
};
|
|
2789
|
-
/**
|
|
2790
|
-
* Returns the theme of the Haftarah tied to the weeks around Tish'a B'Av:
|
|
2791
|
-
* the number of the Haftarah of Admonition (תְּלָתָא דְּפוּרְעָנוּתָא, three
|
|
2792
|
-
* Shabbatot before Tish'a B'Av) or of the Haftarah of Consolation
|
|
2793
|
-
* (שֶׁבַע דְּנֶחָמְתָא, seven Shabbatot after Tish'a B'Av), if applicable.
|
|
2794
|
-
*
|
|
2795
|
-
* The number lives in the `haftTheme` data: on the base parsha in
|
|
2796
|
-
* `aliyot.json`, or — when a special reading replaces the Haftarah — on the
|
|
2797
|
-
* festival entry in `holiday-readings.json`. When a special reading displaces
|
|
2798
|
-
* the Haftarah with an unthemed one (e.g. Re'eh on Shabbat Rosh Chodesh),
|
|
2799
|
-
* neither has a `haftTheme` and `undefined` is returned.
|
|
2800
|
-
* @private
|
|
2801
|
-
* @param parsha untranslated name like `['Pinchas']` or `['Matot','Masei']`
|
|
2802
|
-
* @param haftReason untranslated `reason.haftara` key from `specialReadings2()`
|
|
2803
|
-
*/
|
|
2804
|
-
function getHaftarahTheme(parsha, haftReason) {
|
|
2805
|
-
return haftReason
|
|
2806
|
-
? lookupFestival(haftReason)?.haftTheme
|
|
2807
|
-
: parshiyotObj[getHaftaraKey(parsha)]?.haftTheme;
|
|
2808
|
-
}
|
|
2809
|
-
/**
|
|
2810
|
-
* Looks up the leyning for a regular Shabbat parsha, applying any special
|
|
2811
|
-
* maftir or Haftarah that a coinciding occasion requires — Shabbat Rosh
|
|
2812
|
-
* Chodesh, Shabbat Chanukah, one of the four special Shabbatot, a Haftarah of
|
|
2813
|
-
* Admonition or Consolation, and so on.
|
|
2814
|
-
* @param ev the `ParshaEvent` for this Shabbat
|
|
2815
|
-
* @param [il] `true` for the Israel reading schedule (default `false`)
|
|
2816
|
-
* @param [language] language for names and summary (default `'en'`)
|
|
2817
|
-
* @returns the complete leyning, including `fullkriyah`, `haftara`, and any
|
|
2818
|
-
* `reason` explanations for overrides
|
|
2819
|
-
* @throws {TypeError} if `ev` is not a parsha hashavua event
|
|
2820
|
-
*/
|
|
2821
|
-
function getLeyningForParshaHaShavua(ev, il = false, language = 'en') {
|
|
2822
|
-
if (typeof ev !== 'object' || typeof ev.getFlags !== 'function') {
|
|
2823
|
-
throw new TypeError(`Bad event argument: ${ev}`);
|
|
2824
|
-
}
|
|
2825
|
-
else if (ev.getFlags() !== event.flags.PARSHA_HASHAVUA) {
|
|
2826
|
-
throw new TypeError(`Event must be parsha hashavua: ${ev.getDesc()}`);
|
|
2827
|
-
}
|
|
2828
|
-
// first, collect the default aliyot and haftara
|
|
2829
|
-
const parsha = ev.p.parsha;
|
|
2830
|
-
const result = getLeyningForParshaShabbatOnly(parsha);
|
|
2831
|
-
const hd = ev.getDate();
|
|
2832
|
-
// Now, check for special maftir or haftara on same date
|
|
2833
|
-
const special = specialReadings2(parsha, hd, il, result.fullkriyah);
|
|
2834
|
-
const reason = special.reason;
|
|
2835
|
-
const haftTheme = getHaftarahTheme(parsha, reason.haftara);
|
|
2836
|
-
if (haftTheme) {
|
|
2837
|
-
Object.assign(result, haftTheme);
|
|
2838
|
-
}
|
|
2839
|
-
if (special.haft) {
|
|
2840
|
-
delete result.chabad;
|
|
2841
|
-
delete result.seph;
|
|
2842
|
-
delete result.sephardic;
|
|
2843
|
-
delete result.sephardicNumV;
|
|
2844
|
-
const haft = (result.haft = cloneHaftara(special.haft));
|
|
2845
|
-
result.haftara = makeSummaryFromParts(haft);
|
|
2846
|
-
result.haftaraNumV = sumVerses(haft);
|
|
2847
|
-
if (special.seph) {
|
|
2848
|
-
const seph = (result.seph = cloneHaftara(special.seph));
|
|
2849
|
-
result.sephardic = makeSummaryFromParts(seph);
|
|
2850
|
-
result.sephardicNumV = sumVerses(seph);
|
|
2851
|
-
}
|
|
2852
|
-
if (special.chabad) {
|
|
2853
|
-
result.chabad = cloneHaftara(special.chabad);
|
|
2854
|
-
}
|
|
2855
|
-
}
|
|
2856
|
-
if (reason['7'] || reason['M']) {
|
|
2857
|
-
result.fullkriyah = special.aliyot;
|
|
2858
|
-
const parts = makeLeyningParts(result.fullkriyah);
|
|
2859
|
-
result.summary = makeSummaryFromParts(parts);
|
|
2860
|
-
result.summaryParts = parts;
|
|
2861
|
-
}
|
|
2862
|
-
const reasons = Object.keys(reason);
|
|
2863
|
-
if (reasons.length !== 0) {
|
|
2864
|
-
// Translate reason strings to target language if not English
|
|
2865
|
-
const translatedReason = {};
|
|
2866
|
-
for (const [key, val] of Object.entries(reason)) {
|
|
2867
|
-
translatedReason[key] = locale.Locale.gettext(val, language);
|
|
2868
|
-
}
|
|
2869
|
-
result.reason = translatedReason;
|
|
2870
|
-
for (const num of reasons) {
|
|
2871
|
-
if (reasonHaftKey[num]) {
|
|
2872
|
-
const haftKey = reasonHaftKey[num];
|
|
2873
|
-
const haftObj = result[haftKey];
|
|
2874
|
-
const hafts = Array.isArray(haftObj) ? haftObj : [haftObj];
|
|
2875
|
-
for (const haft of hafts) {
|
|
2876
|
-
haft.reason = translatedReason[num];
|
|
2877
|
-
}
|
|
2878
|
-
}
|
|
2879
|
-
else {
|
|
2880
|
-
const aliyah = result.fullkriyah[num];
|
|
2881
|
-
if (typeof aliyah === 'object') {
|
|
2882
|
-
aliyah.reason = translatedReason[num];
|
|
2883
|
-
}
|
|
2884
|
-
}
|
|
2885
|
-
}
|
|
2886
|
-
}
|
|
2887
|
-
return translateLeyning(result, language);
|
|
2888
|
-
}
|
|
2889
|
-
/**
|
|
2890
|
-
* Returns the raw metadata for a parsha from `aliyot.json`.
|
|
2891
|
-
*
|
|
2892
|
-
* This is the underlying data (verse tuples, book number, Haftarah theme,
|
|
2893
|
-
* etc.), not a computed reading — use {@link getLeyningForParsha} for that.
|
|
2894
|
-
* @param parsha untranslated name, e.g. `'Pinchas'`, `['Pinchas']`, or
|
|
2895
|
-
* `['Matot', 'Masei']` for a doubled parsha
|
|
2896
|
-
* @param [language] language for the Hebrew name and Haftarah (default `'en'`)
|
|
2897
|
-
* @returns the parsha metadata (see {@link ParshaMeta})
|
|
2898
|
-
* @throws {TypeError} if `parsha` is not a known parsha name
|
|
2899
|
-
*/
|
|
2900
|
-
function lookupParsha(parsha, language = 'en') {
|
|
2901
|
-
const name = parshaToString(parsha);
|
|
2902
|
-
const raw = parshiyotObj[name];
|
|
2903
|
-
if (typeof raw !== 'object') {
|
|
2904
|
-
throw new TypeError(`Bad parsha argument: ${parsha}`);
|
|
2905
|
-
}
|
|
2906
|
-
if (raw.combined) {
|
|
2907
|
-
const [p1, p2] = name.split('-');
|
|
2908
|
-
if (!raw.hebrew) {
|
|
2909
|
-
raw.hebrew = locale.Locale.gettext(p1, 'he') + '־' + locale.Locale.gettext(p2, 'he');
|
|
2910
|
-
}
|
|
2911
|
-
if (!raw.haft) {
|
|
2912
|
-
const haftKey = p1 === 'Nitzavim' ? p1 : p2;
|
|
2913
|
-
raw.haft = lookupParsha(haftKey, language).haft;
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
else {
|
|
2917
|
-
raw.hebrew = locale.Locale.gettext(name, 'he');
|
|
2918
|
-
}
|
|
2919
|
-
raw.haft = translateAliyahOrArray(raw.haft, language);
|
|
2920
|
-
if (raw.seph) {
|
|
2921
|
-
raw.seph = translateAliyahOrArray(raw.seph, language);
|
|
2922
|
-
}
|
|
2923
|
-
if (raw.chabad && 'sameas' in raw.chabad) {
|
|
2924
|
-
raw.chabad = raw.haft;
|
|
2925
|
-
}
|
|
2926
|
-
if (raw.chabad) {
|
|
2927
|
-
raw.chabad = translateAliyahOrArray(raw.chabad, language);
|
|
2928
|
-
}
|
|
2929
|
-
return raw;
|
|
2930
|
-
}
|
|
2931
|
-
|
|
2932
|
-
function findParshaHaShavua(saturday, il) {
|
|
2933
|
-
const hyear = saturday.getFullYear();
|
|
2934
|
-
const sedra$1 = sedra.getSedra(hyear, il);
|
|
2935
|
-
const parsha = sedra$1.lookup(saturday);
|
|
2936
|
-
if (!parsha.chag) {
|
|
2937
|
-
return parsha;
|
|
2938
|
-
}
|
|
2939
|
-
// Special case between YK and Simchat Torah
|
|
2940
|
-
// If Vayeilech or Ha'azinu occurs between RH and YK, the following block for
|
|
2941
|
-
// Monday/Thursday weekday isn't executed because the above sedra.lookup()
|
|
2942
|
-
// would have already found the regular Saturday parsha.
|
|
2943
|
-
if (saturday.getMonth() === months.TISHREI) {
|
|
2944
|
-
const dd = saturday.getDate();
|
|
2945
|
-
const simchatTorah = il ? 22 : 23;
|
|
2946
|
-
if (dd > 2 && dd <= simchatTorah) {
|
|
2947
|
-
return {
|
|
2948
|
-
parsha: ['Vezot Haberakhah'],
|
|
2949
|
-
chag: false,
|
|
2950
|
-
num: 54,
|
|
2951
|
-
hdate: saturday,
|
|
2952
|
-
il,
|
|
2953
|
-
};
|
|
2954
|
-
}
|
|
2955
|
-
}
|
|
2956
|
-
// Search for next regular parsha, which could even spill into next year
|
|
2957
|
-
const endOfYear = new HDate(1, months.TISHREI, hyear + 1).abs() - 1;
|
|
2958
|
-
const endAbs = endOfYear + 30;
|
|
2959
|
-
for (let sat2 = saturday.abs() + 7; sat2 <= endAbs; sat2 += 7) {
|
|
2960
|
-
const sedra2 = sat2 > endOfYear ? sedra.getSedra(hyear + 1, il) : sedra$1;
|
|
2961
|
-
const parsha2 = sedra2.lookup(sat2);
|
|
2962
|
-
if (!parsha2.chag) {
|
|
2963
|
-
return parsha2;
|
|
2964
|
-
}
|
|
2965
|
-
}
|
|
2966
|
-
/* NOTREACHED */
|
|
2967
|
-
throw new Error(`can't findParshaHaShavua for ${saturday}/${il}`);
|
|
2968
|
-
}
|
|
2969
|
-
function getLeyningOnDate(hdate, il, wantarray = false, language = 'en') {
|
|
2970
|
-
const dow = hdate.getDay();
|
|
2971
|
-
const arr = [];
|
|
2972
|
-
let hasParshaHaShavua = false;
|
|
2973
|
-
if (dow === 6) {
|
|
2974
|
-
const hyear = hdate.getFullYear();
|
|
2975
|
-
const sedra$1 = sedra.getSedra(hyear, il);
|
|
2976
|
-
const parsha = sedra$1.lookup(hdate);
|
|
2977
|
-
if (!parsha.chag) {
|
|
2978
|
-
const parshaEvent = new ParshaEvent.ParshaEvent(parsha);
|
|
2979
|
-
const reading = getLeyningForParshaHaShavua(parshaEvent, il, language);
|
|
2980
|
-
if (wantarray) {
|
|
2981
|
-
hasParshaHaShavua = true;
|
|
2982
|
-
arr.push(reading);
|
|
2983
|
-
}
|
|
2984
|
-
else {
|
|
2985
|
-
return reading;
|
|
2986
|
-
}
|
|
2987
|
-
}
|
|
2988
|
-
}
|
|
2989
|
-
const events = holidays.getHolidaysOnDate(hdate, il) || [];
|
|
2990
|
-
let hasFullKriyah = false;
|
|
2991
|
-
for (const ev of events) {
|
|
2992
|
-
const specialShabbat = Boolean(ev.getFlags() & (event.flags.SPECIAL_SHABBAT | event.flags.ROSH_CHODESH));
|
|
2993
|
-
if (hasParshaHaShavua && specialShabbat) {
|
|
2994
|
-
continue;
|
|
2995
|
-
}
|
|
2996
|
-
const reading = getLeyningForHoliday(ev, il);
|
|
2997
|
-
if (reading) {
|
|
2998
|
-
// Skip duplicate readings from overlapping events (eg, Rosh Chodesh + Chanukah)
|
|
2999
|
-
if (arr.some(r => r.name.en === reading.name.en))
|
|
3000
|
-
continue;
|
|
3001
|
-
const fk = reading.fullkriyah;
|
|
3002
|
-
if (fk) {
|
|
3003
|
-
hasFullKriyah = true;
|
|
3004
|
-
}
|
|
3005
|
-
const specialMaftirOnly = hasParshaHaShavua && hasFullKriyah && fk.M && !fk['1'];
|
|
3006
|
-
if (!specialMaftirOnly) {
|
|
3007
|
-
arr.push(reading);
|
|
3008
|
-
}
|
|
3009
|
-
const mincha = getMincha(ev, il);
|
|
3010
|
-
if (mincha) {
|
|
3011
|
-
arr.push(mincha);
|
|
3012
|
-
}
|
|
3013
|
-
// Special case for Erev Simchat Torah - the only time we read Torah at night
|
|
3014
|
-
const desc = ev.getDesc();
|
|
3015
|
-
if ((il && desc === 'Sukkot VII (Hoshana Raba)') ||
|
|
3016
|
-
(!il && desc === 'Shmini Atzeret')) {
|
|
3017
|
-
const erevST = getLeyningForHolidayKey('Erev Simchat Torah');
|
|
3018
|
-
arr.push(erevST);
|
|
3019
|
-
}
|
|
3020
|
-
}
|
|
3021
|
-
}
|
|
3022
|
-
if (!hasFullKriyah && (dow === 1 || dow === 4)) {
|
|
3023
|
-
const saturday = hdate.onOrAfter(6);
|
|
3024
|
-
const parsha = findParshaHaShavua(saturday, il);
|
|
3025
|
-
const aliyot = getWeekdayReading(parsha.parsha);
|
|
3026
|
-
const parts = makeLeyningParts(aliyot);
|
|
3027
|
-
const reading = {
|
|
3028
|
-
name: makeLeyningNames(parsha.parsha),
|
|
3029
|
-
type: 'weekday',
|
|
3030
|
-
parsha: parsha.parsha,
|
|
3031
|
-
parshaNum: parsha.num,
|
|
3032
|
-
weekday: aliyot,
|
|
3033
|
-
summary: makeSummaryFromParts(parts),
|
|
3034
|
-
};
|
|
3035
|
-
arr.unshift(reading);
|
|
3036
|
-
}
|
|
3037
|
-
// call translateLeyning on arr or arr[0]
|
|
3038
|
-
if (arr.length === 0) {
|
|
3039
|
-
return wantarray ? arr : arr[0];
|
|
3040
|
-
}
|
|
3041
|
-
if (wantarray) {
|
|
3042
|
-
return arr.map(reading => translateLeyning(reading, language));
|
|
3043
|
-
}
|
|
3044
|
-
return translateLeyning(arr[0], language);
|
|
3045
|
-
}
|
|
3046
|
-
const minchaSuffix = ' (Mincha)';
|
|
3047
|
-
function getMincha(ev, il) {
|
|
3048
|
-
const desc = ev.getDesc() + minchaSuffix;
|
|
3049
|
-
const reading1 = getLeyningForHolidayKey(desc, ev.cholHaMoedDay, il);
|
|
3050
|
-
if (reading1) {
|
|
3051
|
-
return reading1;
|
|
3052
|
-
}
|
|
3053
|
-
const desc2 = getLeyningKeyForEvent(ev, il);
|
|
3054
|
-
if (desc2) {
|
|
3055
|
-
const reading2 = getLeyningForHolidayKey(desc2 + minchaSuffix, ev.cholHaMoedDay, il);
|
|
3056
|
-
if (reading2) {
|
|
3057
|
-
return reading2;
|
|
3058
|
-
}
|
|
3059
|
-
}
|
|
3060
|
-
return undefined;
|
|
3061
|
-
}
|
|
3062
|
-
|
|
3063
|
-
Object.defineProperty(exports, "Locale", {
|
|
3064
|
-
enumerable: true,
|
|
3065
|
-
get: function () { return locale.Locale; }
|
|
3066
|
-
});
|
|
3067
|
-
exports.BOOK = BOOK;
|
|
3068
|
-
exports.NUM_VERSES = NUM_VERSES;
|
|
3069
|
-
exports.addVerses = addVerses;
|
|
3070
|
-
exports.calculateNumVerses = calculateNumVerses;
|
|
3071
|
-
exports.clone = clone;
|
|
3072
|
-
exports.cloneHaftara = cloneHaftara;
|
|
3073
|
-
exports.formatAliyahShort = formatAliyahShort;
|
|
3074
|
-
exports.formatAliyahWithBook = formatAliyahWithBook;
|
|
3075
|
-
exports.getLeyningForHoliday = getLeyningForHoliday;
|
|
3076
|
-
exports.getLeyningForHolidayKey = getLeyningForHolidayKey;
|
|
3077
|
-
exports.getLeyningForParsha = getLeyningForParsha;
|
|
3078
|
-
exports.getLeyningForParshaHaShavua = getLeyningForParshaHaShavua;
|
|
3079
|
-
exports.getLeyningKeyForEvent = getLeyningKeyForEvent;
|
|
3080
|
-
exports.getLeyningOnDate = getLeyningOnDate;
|
|
3081
|
-
exports.getWeekdayReading = getWeekdayReading;
|
|
3082
|
-
exports.hasFestival = hasFestival;
|
|
3083
|
-
exports.lookupFestival = lookupFestival;
|
|
3084
|
-
exports.lookupParsha = lookupParsha;
|
|
3085
|
-
exports.makeLeyningNames = makeLeyningNames;
|
|
3086
|
-
exports.makeLeyningParts = makeLeyningParts;
|
|
3087
|
-
exports.makeLeyningSummary = makeLeyningSummary;
|
|
3088
|
-
exports.makeSummaryFromParts = makeSummaryFromParts;
|
|
3089
|
-
exports.parshaToString = parshaToString;
|
|
3090
|
-
exports.specialReadings2 = specialReadings2;
|
|
3091
|
-
exports.subtractVerses = subtractVerses;
|
|
3092
|
-
exports.sumVerses = sumVerses;
|
|
3093
|
-
|
|
3094
|
-
return exports;
|
|
3095
|
-
|
|
3096
|
-
})({}, hebcal, hebcal, hebcal, hebcal, hebcal);
|