@hebcal/leyning 8.2.5 → 8.2.7

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/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @hebcal/leyning v8.2.5 */
1
+ /*! @hebcal/leyning v8.2.7 */
2
2
  import { flags, months, HDate, HebrewCalendar, Locale, ParshaEvent, HolidayEvent, Event } from '@hebcal/core';
3
3
 
4
4
  var numverses = {
@@ -53,7 +53,14 @@ var numverses = {
53
53
  * Names of the books of the Torah. BOOK[1] === 'Genesis'
54
54
  * @readonly
55
55
  */
56
- const BOOK = ['', 'Genesis', 'Exodus', 'Leviticus', 'Numbers', 'Deuteronomy'];
56
+ const BOOK = [
57
+ '',
58
+ 'Genesis',
59
+ 'Exodus',
60
+ 'Leviticus',
61
+ 'Numbers',
62
+ 'Deuteronomy',
63
+ ];
57
64
  /**
58
65
  * Formats parsha as a string
59
66
  * @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
@@ -62,7 +69,9 @@ function parshaToString(parsha) {
62
69
  if (typeof parsha === 'string') {
63
70
  return parsha;
64
71
  }
65
- else if (!Array.isArray(parsha) || parsha.length === 0 || parsha.length > 2) {
72
+ else if (!Array.isArray(parsha) ||
73
+ parsha.length === 0 ||
74
+ parsha.length > 2) {
66
75
  throw new TypeError(`Bad parsha argument: ${parsha}`);
67
76
  }
68
77
  let s = parsha[0];
@@ -129,16 +138,16 @@ function formatAliyahShort(aliyah, showBook) {
129
138
  * @private
130
139
  */
131
140
  function isChapVerseBefore(a, b) {
132
- const cv1 = a.split(':').map((x) => +x);
133
- const cv2 = b.split(':').map((x) => +x);
134
- return (cv1[0] * 100 + cv1[1]) < (cv2[0] * 100 + cv2[1]);
141
+ const cv1 = a.split(':').map(x => +x);
142
+ const cv2 = b.split(':').map(x => +x);
143
+ return cv1[0] * 100 + cv1[1] < cv2[0] * 100 + cv2[1];
135
144
  }
136
145
  /**
137
146
  * Summarizes an `AliyotMap` by collapsing all adjacent aliyot.
138
147
  * Finds any non-overlapping parts (e.g. special 7th aliyah or maftir)
139
148
  */
140
149
  function makeLeyningParts(aliyot) {
141
- const nums = Object.keys(aliyot).filter((x) => {
150
+ const nums = Object.keys(aliyot).filter(x => {
142
151
  if (x.length === 1) {
143
152
  return true;
144
153
  }
@@ -151,15 +160,17 @@ function makeLeyningParts(aliyot) {
151
160
  for (let i = 0; i < nums.length; i++) {
152
161
  const num = nums[i];
153
162
  const aliyah = aliyot[num];
154
- if ((i === nums.length - 1) && (aliyah.k === end.k) && (aliyah.e === end.e)) {
163
+ if (i === nums.length - 1 && aliyah.k === end.k && aliyah.e === end.e) {
155
164
  // short-circuit when final aliyah is within the previous (e.g. M inside of 7)
156
165
  continue;
157
166
  }
158
- const prevEndChap = +(end.e.split(':')[0]);
159
- const curStartChap = +(aliyah.b.split(':')[0]);
167
+ const prevEndChap = +end.e.split(':')[0];
168
+ const curStartChap = +aliyah.b.split(':')[0];
160
169
  const sameOrNextChap = curStartChap === prevEndChap || curStartChap === prevEndChap + 1;
161
- if ((i !== 0) &&
162
- (aliyah.k !== start.k || isChapVerseBefore(aliyah.b, start.e) || !sameOrNextChap)) {
170
+ if (i !== 0 &&
171
+ (aliyah.k !== start.k ||
172
+ isChapVerseBefore(aliyah.b, start.e) ||
173
+ !sameOrNextChap)) {
163
174
  parts.push({ k: start.k, b: start.b, e: end.e });
164
175
  start = aliyah;
165
176
  }
@@ -225,7 +236,9 @@ function cloneHaftara(haft) {
225
236
  * Returns the total number of verses in an array of Aliyah (or haftarah) objects
226
237
  */
227
238
  function sumVerses(aliyot) {
228
- return Array.isArray(aliyot) ? aliyot.reduce((prev, cur) => prev + cur.v, 0) : aliyot.v;
239
+ return Array.isArray(aliyot)
240
+ ? aliyot.reduce((prev, cur) => prev + cur.v, 0)
241
+ : aliyot.v;
229
242
  }
230
243
 
231
244
  var festivals0 = { "Pesach I": {
@@ -880,9 +893,15 @@ function lookupFestival(holiday) {
880
893
  return result;
881
894
  }
882
895
 
883
- const HOLIDAY_IGNORE_MASK = flags.DAF_YOMI | flags.OMER_COUNT | flags.SHABBAT_MEVARCHIM |
884
- flags.MOLAD | flags.USER_EVENT | flags.HEBREW_DATE | flags.MISHNA_YOMI |
885
- flags.MODERN_HOLIDAY | flags.YERUSHALMI_YOMI;
896
+ const HOLIDAY_IGNORE_MASK = flags.DAF_YOMI |
897
+ flags.OMER_COUNT |
898
+ flags.SHABBAT_MEVARCHIM |
899
+ flags.MOLAD |
900
+ flags.USER_EVENT |
901
+ flags.HEBREW_DATE |
902
+ flags.MISHNA_YOMI |
903
+ flags.MODERN_HOLIDAY |
904
+ flags.YERUSHALMI_YOMI;
886
905
  /**
887
906
  * Based on the event date, type and title, finds the relevant leyning key
888
907
  * @param ev event
@@ -906,13 +925,15 @@ function getLeyningKeyForEvent(ev, il = false) {
906
925
  const day = hd.getDate();
907
926
  const dow = hd.abs() % 7;
908
927
  const month = hd.getMonth();
909
- const isShabbat = (dow == 6);
910
- const isRoshChodesh = (day == 1 || day == 30);
928
+ const isShabbat = dow == 6;
929
+ const isRoshChodesh = day == 1 || day == 30;
911
930
  const holiday = ev.basename();
912
931
  const isPesach = holiday === 'Pesach';
913
932
  if (il && isPesach) {
914
933
  if (isShabbat) {
915
- return day === 15 || day === 21 ? desc + ' (on Shabbat)' : 'Pesach Shabbat Chol ha-Moed';
934
+ return day === 15 || day === 21
935
+ ? desc + ' (on Shabbat)'
936
+ : 'Pesach Shabbat Chol ha-Moed';
916
937
  }
917
938
  return desc;
918
939
  }
@@ -929,10 +950,10 @@ function getLeyningKeyForEvent(ev, il = false) {
929
950
  return 'Sukkot Final Day (Hoshana Raba)';
930
951
  }
931
952
  if (isPesach && cholHaMoedDay) {
932
- if (dow === 0 && desc === 'Pesach IV (CH\'\'M)') {
953
+ if (dow === 0 && desc === "Pesach IV (CH''M)") {
933
954
  return 'Pesach Chol ha-Moed Day 2 on Sunday';
934
955
  }
935
- else if (dow === 1 && desc === 'Pesach V (CH\'\'M)') {
956
+ else if (dow === 1 && desc === "Pesach V (CH''M)") {
936
957
  return 'Pesach Chol ha-Moed Day 3 on Monday';
937
958
  }
938
959
  }
@@ -944,7 +965,7 @@ function getLeyningKeyForEvent(ev, il = false) {
944
965
  return 'Shabbat Rosh Chodesh Chanukah';
945
966
  }
946
967
  else if (isRoshChodesh && chanukahDay == 7) {
947
- return `Chanukah Day 7 (on Rosh Chodesh)`;
968
+ return 'Chanukah Day 7 (on Rosh Chodesh)';
948
969
  }
949
970
  else if (isShabbat) {
950
971
  return `Chanukah Day ${chanukahDay} (on Shabbat)`;
@@ -953,7 +974,8 @@ function getLeyningKeyForEvent(ev, il = false) {
953
974
  return `Chanukah Day ${chanukahDay}`;
954
975
  }
955
976
  }
956
- if (isRoshChodesh && (desc == 'Shabbat HaChodesh' || desc == 'Shabbat Shekalim')) {
977
+ if (isRoshChodesh &&
978
+ (desc == 'Shabbat HaChodesh' || desc == 'Shabbat Shekalim')) {
957
979
  return desc + ' (on Rosh Chodesh)';
958
980
  }
959
981
  if (il && desc == 'Shmini Atzeret') {
@@ -1000,8 +1022,8 @@ function getLeyningKeyForEvent(ev, il = false) {
1000
1022
  if (isRoshChodesh) {
1001
1023
  return desc;
1002
1024
  }
1003
- if (desc === 'Tish\'a B\'Av (observed)') {
1004
- return 'Tish\'a B\'Av';
1025
+ if (desc === "Tish'a B'Av (observed)") {
1026
+ return "Tish'a B'Av";
1005
1027
  }
1006
1028
  return undefined;
1007
1029
  }
@@ -1078,7 +1100,7 @@ function specialReadings2(parsha, hd, il, aliyot) {
1078
1100
  }
1079
1101
  const parshaName = parshaToString(parsha);
1080
1102
  const events0 = HebrewCalendar.getHolidaysOnDate(hd, il) || [];
1081
- const events = events0.filter((ev) => !(ev.getFlags() & flags.ROSH_CHODESH));
1103
+ const events = events0.filter(ev => !(ev.getFlags() & flags.ROSH_CHODESH));
1082
1104
  for (const ev of events) {
1083
1105
  if (ev.getDesc() === 'Shabbat Shuva') {
1084
1106
  handleSpecial(`Shabbat Shuva (with ${parshaName})`);
@@ -1098,9 +1120,9 @@ function specialReadings2(parsha, hd, il, aliyot) {
1098
1120
  handleSpecial('Pinchas occurring after 17 Tammuz');
1099
1121
  }
1100
1122
  else if (day === 30 || day === 1) {
1101
- const key = (parshaName === 'Masei' || parshaName === 'Matot-Masei') ?
1102
- `${parshaName} on Shabbat Rosh Chodesh` :
1103
- 'Shabbat Rosh Chodesh';
1123
+ const key = parshaName === 'Masei' || parshaName === 'Matot-Masei'
1124
+ ? `${parshaName} on Shabbat Rosh Chodesh`
1125
+ : 'Shabbat Rosh Chodesh';
1104
1126
  handleSpecial(key);
1105
1127
  }
1106
1128
  else if (parshaName === 'Ki Teitzei' && day === 14) {
@@ -1112,7 +1134,8 @@ function specialReadings2(parsha, hd, il, aliyot) {
1112
1134
  // Source: Luaḥ Hashanah, Rabbi Miles B. Cohen and Leslie Rubin
1113
1135
  handleSpecial('Ki Teitzei with 3rd Haftarah of Consolation');
1114
1136
  }
1115
- else if (parshaName === 'Kedoshim' && (day === 26 || day === 28 || day === 6)) {
1137
+ else if (parshaName === 'Kedoshim' &&
1138
+ (day === 26 || day === 28 || day === 6)) {
1116
1139
  // Kedoshim is read separately from Achrei Mot in ~37% of years.
1117
1140
  // When this happens, it is will be read on
1118
1141
  // 26th or 28th of Nisan (Achrei Mot was Shabbat HaGadol, ~10%),
@@ -1152,7 +1175,9 @@ function getLeyningForHolidayKey(key, cholHaMoedDay, il) {
1152
1175
  return undefined;
1153
1176
  }
1154
1177
  const israelOnly = src.il;
1155
- if (typeof israelOnly === 'boolean' && typeof il === 'boolean' && il !== israelOnly) {
1178
+ if (typeof israelOnly === 'boolean' &&
1179
+ typeof il === 'boolean' &&
1180
+ il !== israelOnly) {
1156
1181
  return undefined;
1157
1182
  }
1158
1183
  const leyning = {
@@ -1176,15 +1201,15 @@ function getLeyningForHolidayKey(key, cholHaMoedDay, il) {
1176
1201
  leyning.summaryParts = parts;
1177
1202
  }
1178
1203
  }
1179
- Object.values(leyning.fullkriyah).map((aliyah) => calculateNumVerses(aliyah));
1204
+ Object.values(leyning.fullkriyah).map(aliyah => calculateNumVerses(aliyah));
1180
1205
  }
1181
1206
  if (src.haft) {
1182
- const haft = leyning.haft = cloneHaftara(src.haft);
1207
+ const haft = (leyning.haft = cloneHaftara(src.haft));
1183
1208
  leyning.haftara = makeSummaryFromParts(haft);
1184
1209
  leyning.haftaraNumV = sumVerses(haft);
1185
1210
  }
1186
1211
  if (src.seph) {
1187
- const seph = leyning.seph = cloneHaftara(src.seph);
1212
+ const seph = (leyning.seph = cloneHaftara(src.seph));
1188
1213
  leyning.sephardic = makeSummaryFromParts(seph);
1189
1214
  leyning.sephardicNumV = sumVerses(seph);
1190
1215
  }
@@ -2540,7 +2565,7 @@ function makeLeyningNames(parsha) {
2540
2565
  const name = parshaToString(parsha);
2541
2566
  return {
2542
2567
  en: name,
2543
- he: parsha.map((s) => Locale.lookupTranslation(s, 'he')).join('־'),
2568
+ he: parsha.map(s => Locale.lookupTranslation(s, 'he')).join('־'),
2544
2569
  };
2545
2570
  }
2546
2571
  /**
@@ -2577,13 +2602,13 @@ function getLeyningForParshaShabbatOnly(parsha) {
2577
2602
  const hkey = getHaftaraKey(parshaNameArray);
2578
2603
  const haft0 = parshiyotObj[hkey].haft;
2579
2604
  if (haft0) {
2580
- const haft = result.haft = cloneHaftara(haft0);
2605
+ const haft = (result.haft = cloneHaftara(haft0));
2581
2606
  result.haftara = makeSummaryFromParts(haft);
2582
2607
  result.haftaraNumV = sumVerses(haft);
2583
2608
  }
2584
2609
  const seph0 = parshiyotObj[hkey].seph;
2585
2610
  if (seph0) {
2586
- const seph = result.seph = cloneHaftara(seph0);
2611
+ const seph = (result.seph = cloneHaftara(seph0));
2587
2612
  result.sephardic = makeSummaryFromParts(seph);
2588
2613
  result.sephardicNumV = sumVerses(seph);
2589
2614
  }
@@ -2642,11 +2667,11 @@ function getLeyningForParshaHaShavua(ev, il = false) {
2642
2667
  const special = specialReadings2(parsha, hd, il, result.fullkriyah);
2643
2668
  const reason = special.reason;
2644
2669
  if (special.haft) {
2645
- const haft = result.haft = cloneHaftara(special.haft);
2670
+ const haft = (result.haft = cloneHaftara(special.haft));
2646
2671
  result.haftara = makeSummaryFromParts(haft);
2647
2672
  result.haftaraNumV = sumVerses(haft);
2648
2673
  if (special.seph) {
2649
- const seph = result.seph = cloneHaftara(special.seph);
2674
+ const seph = (result.seph = cloneHaftara(special.seph));
2650
2675
  result.sephardic = makeSummaryFromParts(seph);
2651
2676
  result.sephardicNumV = sumVerses(seph);
2652
2677
  }
@@ -2787,6 +2812,9 @@ function getLeyningOnDate(hdate, il, wantarray = false) {
2787
2812
  }
2788
2813
  const reading = getLeyningForHoliday(ev, il);
2789
2814
  if (reading) {
2815
+ // Skip duplicate readings from overlapping events (eg, Rosh Chodesh + Chanukah)
2816
+ if (arr.some(r => r.name.en === reading.name.en))
2817
+ continue;
2790
2818
  const fk = reading.fullkriyah;
2791
2819
  if (fk) {
2792
2820
  hasFullKriyah = true;
@@ -2842,14 +2870,16 @@ function getMincha(ev, il) {
2842
2870
  }
2843
2871
 
2844
2872
  const fmt = new Intl.DateTimeFormat('en-US', {
2845
- year: 'numeric', month: 'short', day: '2-digit',
2873
+ year: 'numeric',
2874
+ month: 'short',
2875
+ day: '2-digit',
2846
2876
  });
2847
2877
  function fmtDate(dt) {
2848
2878
  const s = fmt.format(dt).split(' ');
2849
2879
  return s[1].substring(0, 2) + '-' + s[0] + '-' + s[2];
2850
2880
  }
2851
2881
  function getParshaDates(events) {
2852
- const parshaEvents = events.filter((ev) => ev.getFlags() === flags.PARSHA_HASHAVUA);
2882
+ const parshaEvents = events.filter(ev => ev.getFlags() === flags.PARSHA_HASHAVUA);
2853
2883
  const emptyMap = {};
2854
2884
  const parshaDates = parshaEvents.reduce((set, ev) => {
2855
2885
  set[ev.getDate().toString()] = true;
@@ -2868,7 +2898,8 @@ function writeFullKriyahCsv(stream, hyear, il) {
2868
2898
  const parshaDates = getParshaDates(events);
2869
2899
  stream.write('"Date","Parashah","Aliyah","Reading","Verses"\r\n');
2870
2900
  for (const ev of events) {
2871
- if (ev.getFlags() === flags.PARSHA_HASHAVUA || !parshaDates[ev.getDate().toString()]) {
2901
+ if (ev.getFlags() === flags.PARSHA_HASHAVUA ||
2902
+ !parshaDates[ev.getDate().toString()]) {
2872
2903
  writeFullKriyahEvent(stream, ev, il);
2873
2904
  }
2874
2905
  }
@@ -2889,7 +2920,9 @@ function writeFullKriyahEvent(stream, ev, il) {
2889
2920
  }
2890
2921
  const mask = ev.getFlags();
2891
2922
  const isParsha = mask === flags.PARSHA_HASHAVUA;
2892
- const reading = isParsha ? getLeyningForParshaHaShavua(ev, il) : getLeyningForHoliday(ev, il);
2923
+ const reading = isParsha
2924
+ ? getLeyningForParshaHaShavua(ev, il)
2925
+ : getLeyningForHoliday(ev, il);
2893
2926
  if (reading) {
2894
2927
  writeCsvLines(stream, ev, reading, il, isParsha);
2895
2928
  if (!isParsha) {
@@ -2918,7 +2951,9 @@ function writeHolidayMincha(stream, ev, il) {
2918
2951
  * Formats reading for CSV
2919
2952
  */
2920
2953
  function writeCsvLines(stream, ev, reading, il, isParsha) {
2921
- const parsha = isParsha ? ev.basename() : getLeyningKeyForEvent(ev, il) || ev.render();
2954
+ const parsha = isParsha
2955
+ ? ev.basename()
2956
+ : getLeyningKeyForEvent(ev, il) || ev.render();
2922
2957
  const date = fmtDate(ev.getDate().greg());
2923
2958
  const lines = getFullKriyahLines(reading);
2924
2959
  for (const s of lines) {
@@ -2958,7 +2993,11 @@ function getFullKriyahLines(reading) {
2958
2993
  if ((_c = reading.reason) === null || _c === void 0 ? void 0 : _c.sephardic) {
2959
2994
  sephardic += ' | ' + reading.reason.sephardic;
2960
2995
  }
2961
- lines.push(['Haftara for Sephardim', sephardic, reading.sephardicNumV || '']);
2996
+ lines.push([
2997
+ 'Haftara for Sephardim',
2998
+ sephardic,
2999
+ reading.sephardicNumV || '',
3000
+ ]);
2962
3001
  }
2963
3002
  if (reading.triHaftara) {
2964
3003
  const haftara = reading.triHaftara.replace(/,/g, ';');
@@ -0,0 +1,316 @@
1
+ import { Event, HDate, HolidayEvent } from '@hebcal/core';
2
+ import { WriteStream } from 'node:fs';
3
+
4
+ /**
5
+ * Represents an aliyah
6
+ */
7
+ type Aliyah = {
8
+ /** Book (e.g. "Numbers") */
9
+ k: string;
10
+ /** beginning verse (e.g. "28:9") */
11
+ b: string;
12
+ /** ending verse (e.g. "28:15") */
13
+ e: string;
14
+ /** number of verses */
15
+ v?: number;
16
+ /** parsha number (1=Bereshit, 54=Vezot HaBracha) */
17
+ p?: number;
18
+ reason?: string;
19
+ };
20
+ type StringMap = {
21
+ [key: string]: string;
22
+ };
23
+ type AliyotMap = {
24
+ [key: string]: Aliyah;
25
+ };
26
+ /** Name of the parsha hashavua or holiday */
27
+ type LeyningNames = {
28
+ /** English */
29
+ en: string;
30
+ /** Hebrew (with nikud) */
31
+ he: string;
32
+ };
33
+ /**
34
+ * Parsha metadata (underlying JSON object)
35
+ */
36
+ type ParshaMeta = {
37
+ /** 1 for Bereshit, 2 for Noach, etc. `undefined` for holiday readings */
38
+ num: number | number[];
39
+ /** parsha name in Hebrew with niqud */
40
+ hebrew: string;
41
+ /** 1 for Genesis, 2 for Exodus, 5 for Deuteronomy */
42
+ book: number;
43
+ /** Haftarah object(s) */
44
+ haft: Aliyah | Aliyah[];
45
+ /** Haftarah object(s) for Sephardim */
46
+ seph?: Aliyah | Aliyah[];
47
+ /** Map of Shabbat aliyot `1` through `7` plus `M` for maftir */
48
+ fullkriyah: {
49
+ [key: string]: string[];
50
+ };
51
+ /**
52
+ * Map of weekday Torah Readings
53
+ * aliyot `1` through `3` for Monday and Thursday
54
+ */
55
+ weekday?: {
56
+ [key: string]: string[];
57
+ };
58
+ combined?: boolean;
59
+ p1?: string;
60
+ p2?: string;
61
+ num1?: number;
62
+ num2?: number;
63
+ };
64
+ type SpecialReading = {
65
+ /** Map of aliyot `1` through `7` plus `M` for maftir */
66
+ aliyot: AliyotMap;
67
+ /**
68
+ * Explanations for special readings,
69
+ * keyed by aliyah number, `M` for maftir or `haftara` for Haftarah
70
+ */
71
+ reason: StringMap;
72
+ /** Haftarah object(s) */
73
+ haft?: Aliyah | Aliyah[];
74
+ /** Haftarah object(s) for Sephardim */
75
+ seph?: Aliyah | Aliyah[];
76
+ };
77
+ /**
78
+ * Leyning base - weekday, parsha hashavua or holiday
79
+ */
80
+ type LeyningBase = {
81
+ /** Name of the parsha hashavua or holiday */
82
+ name: LeyningNames;
83
+ /** Such as `Genesis 1:1 - 6:8` */
84
+ summary: string;
85
+ summaryParts?: Aliyah[];
86
+ note?: string;
87
+ };
88
+ /**
89
+ * Parashat haShavua - weekday or Shabbat
90
+ */
91
+ type LeyningParshaHaShavua = LeyningBase & {
92
+ /** An array of either 1 (regular) or 2 (doubled parsha). `undefined` for holiday readings */
93
+ parsha?: string[];
94
+ /** 1 for Bereshit, 2 for Noach, etc. `undefined` for holiday readings */
95
+ parshaNum?: number | number[];
96
+ };
97
+ /**
98
+ * Parashat haShavua - weekday
99
+ */
100
+ type LeyningWeekday = LeyningParshaHaShavua & {
101
+ /** Optional map of weekday Torah Readings aliyot `1` through `3` for Monday and Thursday */
102
+ weekday?: AliyotMap;
103
+ };
104
+ type HaftarahProps = {
105
+ /** Haftarah object */
106
+ haft: Aliyah | Aliyah[];
107
+ /** Haftarah, such as `Isaiah 42:5 – 43:11` */
108
+ haftara: string;
109
+ /** Number of verses in the Haftarah */
110
+ haftaraNumV?: number;
111
+ };
112
+ /**
113
+ * Shabbat and holiday leyning always has full kriyah and haftarah
114
+ */
115
+ type LeyningShabbatHoliday = LeyningBase & HaftarahProps & {
116
+ /** Map of aliyot `1` through `7` plus `M` for maftir */
117
+ fullkriyah: AliyotMap;
118
+ /** Haftarah object for Sephardim */
119
+ seph?: Aliyah | Aliyah[];
120
+ /** Haftarah for Sephardim, such as `Isaiah 42:5 - 42:21` */
121
+ sephardic?: string;
122
+ /** Number of verses in the Haftarah for Sephardim */
123
+ sephardicNumV?: number;
124
+ /** Explanations for special readings, keyed by aliyah number, `M` for maftir or `haftara` for Haftarah */
125
+ reason?: StringMap;
126
+ /** Song of Songs is read on the sabbath of Passover week, the Book of Ruth on Shavuot, Lamentations on Tisha be-Av, Ecclesiastes on the sabbath of the week of Sukkoth, and the Book of Esther on Purim */
127
+ megillah?: AliyotMap;
128
+ /** Triennial alternate Haftara */
129
+ triHaftara?: string;
130
+ /** Triennial alternate Haftara number of verses */
131
+ triHaftaraNumV?: number;
132
+ };
133
+ type Leyning = LeyningBase & LeyningParshaHaShavua & LeyningShabbatHoliday & LeyningWeekday;
134
+
135
+ /**
136
+ * Names of the books of the Torah. BOOK[1] === 'Genesis'
137
+ * @readonly
138
+ */
139
+ declare const BOOK: string[];
140
+ /**
141
+ * Formats parsha as a string
142
+ * @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
143
+ */
144
+ declare function parshaToString(parsha: string | string[]): string;
145
+ /**
146
+ * Calculates the number of verses in an aliyah or haftara based on
147
+ * the `b` (begin verse), `e` (end verse) and `k` (book).
148
+ * Modifies `aliyah` by setting the `v` field.
149
+ */
150
+ declare function calculateNumVerses(aliyah: Aliyah): number;
151
+ /**
152
+ * Formats an aliyah object like "Numbers 28:9-28:15"
153
+ */
154
+ declare function formatAliyahWithBook(a: Aliyah): string;
155
+ /**
156
+ * Formats an aliyah object like "Numbers 28:9-15"
157
+ */
158
+ declare function formatAliyahShort(aliyah: Aliyah, showBook: boolean): string;
159
+
160
+ /**
161
+ * Summarizes an `AliyotMap` by collapsing all adjacent aliyot.
162
+ * Finds any non-overlapping parts (e.g. special 7th aliyah or maftir)
163
+ */
164
+ declare function makeLeyningParts(aliyot: AliyotMap): Aliyah[];
165
+ /**
166
+ * Returns a string representation of the leyning parts.
167
+ * Separate verse ranges read from the same book are separated
168
+ * by commas, e.g. `Isaiah 6:1-7:6, 9:5-6`.
169
+ * Verse ranges from different books are separated by semicolons,
170
+ * e.g. `Genesis 21:1-34; Numbers 29:1-6`.
171
+ */
172
+ declare function makeSummaryFromParts(parts: Aliyah | Aliyah[]): string;
173
+ /**
174
+ * Makes a summary of the leyning, like "Genesis 6:9-11:32"
175
+ */
176
+ declare function makeLeyningSummary(aliyot: AliyotMap): string;
177
+
178
+ type JsonFestivalAliyah = {
179
+ k: number | string;
180
+ b: string;
181
+ e: string;
182
+ v?: number;
183
+ p?: number;
184
+ };
185
+ type JsonFestivalAliyotMap = {
186
+ [key: string]: JsonFestivalAliyah;
187
+ };
188
+ type JsonFestivalLeyning = {
189
+ haft?: JsonFestivalAliyah | JsonFestivalAliyah[];
190
+ seph?: JsonFestivalAliyah | JsonFestivalAliyah[];
191
+ fullkriyah?: JsonFestivalAliyotMap;
192
+ megillah?: string;
193
+ alias?: boolean;
194
+ key?: string;
195
+ note?: string;
196
+ il?: boolean;
197
+ };
198
+
199
+ /**
200
+ * Is there a special festival Torah Reading for `holiday`?
201
+ */
202
+ declare function hasFestival(holiday: string): boolean;
203
+ /**
204
+ * Returns the raw metadata for festival reading for `holiday`
205
+ */
206
+ declare function lookupFestival(holiday: string): JsonFestivalLeyning | undefined;
207
+
208
+ /**
209
+ * Based on the event date, type and title, finds the relevant leyning key
210
+ * @param ev event
211
+ * @param [il] true if Israel holiday scheme
212
+ * @returns key to look up in holiday-reading.json
213
+ */
214
+ declare function getLeyningKeyForEvent(ev: Event, il?: boolean): string | undefined;
215
+
216
+ /**
217
+ * Determines if the regular parashat haShavua coincides with an event that requires
218
+ * a special maftir or Haftara (for example Shabbat HaGadol, Shabbat Chanukah, Rosh
219
+ * Chodesh or Machar Chodesh, etc.).
220
+ *
221
+ * This function does not modify `aliyot`. Instead, it returns a deep copy
222
+ * with `aliyot['M']` replaced and sets `reason.M`
223
+ * (and in some cases the 6th and 7th aliyah, setting `reason['7']`).
224
+ *
225
+ * If a special Haftarah applies, the result will have a `haft` property
226
+ * pointing to Haftarah object and sets `reason.haftara`.
227
+ */
228
+ declare function specialReadings2(parsha: string[], hd: HDate, il: boolean, aliyot: AliyotMap): SpecialReading;
229
+
230
+ /**
231
+ * Looks up leyning for a given holiday key. Key should be an
232
+ * (untranslated) string used in holiday-readings.json. Returns some
233
+ * of full kriyah aliyot, special Maftir, special Haftarah
234
+ * @param key name from `holiday-readings.json` to find
235
+ */
236
+ declare function getLeyningForHolidayKey(key?: string, cholHaMoedDay?: number, il?: boolean): Leyning | undefined;
237
+ /**
238
+ * Looks up leyning for a given holiday. Returns some
239
+ * of full kriyah aliyot, special Maftir, special Haftarah
240
+ * @param ev the Hebcal event associated with this leyning
241
+ * @param [il] true if Israel holiday scheme
242
+ * @returns map of aliyot
243
+ */
244
+ declare function getLeyningForHoliday(ev: Event, il?: boolean): Leyning | undefined;
245
+
246
+ /**
247
+ * Transliterated English and Hebrew names of this parsha
248
+ * @param parsha untranslated name like ['Pinchas'] or ['Matot','Masei']
249
+ */
250
+ declare function makeLeyningNames(parsha: string[]): LeyningNames;
251
+ /**
252
+ * Looks up Monday/Thursday aliyot for a regular parsha
253
+ * @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
254
+ */
255
+ declare function getWeekdayReading(parsha: string | string[]): AliyotMap;
256
+ /**
257
+ * Looks up regular leyning for a weekly parsha with no special readings
258
+ * @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
259
+ */
260
+ declare function getLeyningForParsha(parsha: string | string[]): Leyning;
261
+ /**
262
+ * Looks up leyning for a regular Shabbat parsha, including any special
263
+ * maftir or Haftara.
264
+ * @param ev the Hebcal event associated with this leyning
265
+ * @param [il] in Israel
266
+ * @returns map of aliyot
267
+ */
268
+ declare function getLeyningForParshaHaShavua(ev: Event, il?: boolean): Leyning;
269
+ /**
270
+ * Returns the parsha metadata
271
+ * @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
272
+ */
273
+ declare function lookupParsha(parsha: string | string[]): ParshaMeta;
274
+
275
+ /**
276
+ * Looks up leyning for a regular Shabbat, Monday/Thursday weekday or holiday.
277
+ *
278
+ * If `hdate` coincides with a holiday that has Torah reading, returns the
279
+ * reading for that day (see {@link getLeyningForHoliday})
280
+ *
281
+ * Otherwise, if `hdate` is a Saturday, returns {@link getLeyningForParshaHaShavua}
282
+ *
283
+ * Otherwise, if `hdate` is a Monday or Thursday, returns {@link Leyning} for the
284
+ * Parashat haShavua, containing only the `weekday` aliyot (no `fullkriyah`).
285
+ *
286
+ * Otherwise, returns `undefined`.
287
+ *
288
+ * @param {HDate} hdate Hebrew Date
289
+ * @param {boolean} il in Israel
290
+ * @param {boolean} [wantarray] to return an array of 0 or more readings
291
+ */
292
+ declare function getLeyningOnDate(hdate: HDate, il: boolean, wantarray?: boolean): (Leyning | LeyningWeekday) | (Leyning | LeyningWeekday)[] | undefined;
293
+
294
+ interface StringToBoolMap {
295
+ [key: string]: boolean;
296
+ }
297
+ declare function getParshaDates(events: Event[]): StringToBoolMap;
298
+ declare function writeFullKriyahCsv(stream: WriteStream, hyear: number, il: boolean): void;
299
+ declare function writeHolidayMincha(stream: WriteStream, ev: HolidayEvent, il: boolean): void;
300
+ /**
301
+ * Formats reading for CSV
302
+ */
303
+ declare function writeCsvLines(stream: WriteStream, ev: Event, reading: Leyning, il: boolean, isParsha: boolean): void;
304
+
305
+ /**
306
+ * Makes a deep copy of the src object using JSON stringify and parse
307
+ */
308
+ declare function clone(src: any): any;
309
+ type Haftarah = Aliyah | Aliyah[] | JsonFestivalAliyah | JsonFestivalAliyah[];
310
+ declare function cloneHaftara(haft: Haftarah): Aliyah | Aliyah[];
311
+ /**
312
+ * Returns the total number of verses in an array of Aliyah (or haftarah) objects
313
+ */
314
+ declare function sumVerses(aliyot: Haftarah): number;
315
+
316
+ export { type Aliyah, type AliyotMap, BOOK, type Haftarah, type HaftarahProps, type Leyning, type LeyningBase, type LeyningNames, type LeyningParshaHaShavua, type LeyningShabbatHoliday, type LeyningWeekday, type ParshaMeta, type SpecialReading, type StringMap, type StringToBoolMap, calculateNumVerses, clone, cloneHaftara, formatAliyahShort, formatAliyahWithBook, getLeyningForHoliday, getLeyningForHolidayKey, getLeyningForParsha, getLeyningForParshaHaShavua, getLeyningKeyForEvent, getLeyningOnDate, getParshaDates, getWeekdayReading, hasFestival, lookupFestival, lookupParsha, makeLeyningNames, makeLeyningParts, makeLeyningSummary, makeSummaryFromParts, parshaToString, specialReadings2, sumVerses, writeCsvLines, writeFullKriyahCsv, writeHolidayMincha };