@hebcal/core 5.0.0 → 5.0.2
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/README.md +136 -225
- package/dist/bundle.js +551 -596
- package/dist/bundle.min.js +2 -2
- package/dist/index.js +433 -478
- package/dist/index.mjs +433 -478
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -1,351 +1,6 @@
|
|
|
1
|
-
/*! @hebcal/core v5.0.
|
|
1
|
+
/*! @hebcal/core v5.0.2 */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const GERESH = '׳';
|
|
5
|
-
const GERSHAYIM = '״';
|
|
6
|
-
const heb2num = {
|
|
7
|
-
'א': 1,
|
|
8
|
-
'ב': 2,
|
|
9
|
-
'ג': 3,
|
|
10
|
-
'ד': 4,
|
|
11
|
-
'ה': 5,
|
|
12
|
-
'ו': 6,
|
|
13
|
-
'ז': 7,
|
|
14
|
-
'ח': 8,
|
|
15
|
-
'ט': 9,
|
|
16
|
-
'י': 10,
|
|
17
|
-
'כ': 20,
|
|
18
|
-
'ל': 30,
|
|
19
|
-
'מ': 40,
|
|
20
|
-
'נ': 50,
|
|
21
|
-
'ס': 60,
|
|
22
|
-
'ע': 70,
|
|
23
|
-
'פ': 80,
|
|
24
|
-
'צ': 90,
|
|
25
|
-
'ק': 100,
|
|
26
|
-
'ר': 200,
|
|
27
|
-
'ש': 300,
|
|
28
|
-
'ת': 400
|
|
29
|
-
};
|
|
30
|
-
const num2heb = new Map();
|
|
31
|
-
Object.keys(heb2num).forEach(key => {
|
|
32
|
-
const val = heb2num[key];
|
|
33
|
-
num2heb.set(val, key);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @private
|
|
38
|
-
* @param {number} num
|
|
39
|
-
* @return {number[]}
|
|
40
|
-
*/
|
|
41
|
-
function num2digits(num) {
|
|
42
|
-
const digits = [];
|
|
43
|
-
while (num > 0) {
|
|
44
|
-
if (num === 15 || num === 16) {
|
|
45
|
-
digits.push(9);
|
|
46
|
-
digits.push(num - 9);
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
let incr = 100;
|
|
50
|
-
let i;
|
|
51
|
-
for (i = 400; i > num; i -= incr) {
|
|
52
|
-
if (i === incr) {
|
|
53
|
-
incr = incr / 10;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
digits.push(i);
|
|
57
|
-
num -= i;
|
|
58
|
-
}
|
|
59
|
-
return digits;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Converts a numerical value to a string of Hebrew letters.
|
|
64
|
-
*
|
|
65
|
-
* When specifying years of the Hebrew calendar in the present millennium,
|
|
66
|
-
* we omit the thousands (which is presently 5 [ה]).
|
|
67
|
-
* @example
|
|
68
|
-
* gematriya(5774) // 'תשע״ד' - cropped to 774
|
|
69
|
-
* gematriya(25) // 'כ״ה'
|
|
70
|
-
* gematriya(60) // 'ס׳'
|
|
71
|
-
* gematriya(3761) // 'ג׳תשס״א'
|
|
72
|
-
* gematriya(1123) // 'א׳קכ״ג'
|
|
73
|
-
* @param {number} number
|
|
74
|
-
* @return {string}
|
|
75
|
-
*/
|
|
76
|
-
function gematriya(number) {
|
|
77
|
-
const num = parseInt(number, 10);
|
|
78
|
-
if (!num) {
|
|
79
|
-
throw new TypeError(`invalid parameter to gematriya ${number}`);
|
|
80
|
-
}
|
|
81
|
-
let str = '';
|
|
82
|
-
const thousands = Math.floor(num / 1000);
|
|
83
|
-
if (thousands > 0 && thousands !== 5) {
|
|
84
|
-
const tdigits = num2digits(thousands);
|
|
85
|
-
for (const tdig of tdigits) {
|
|
86
|
-
str += num2heb.get(tdig);
|
|
87
|
-
}
|
|
88
|
-
str += GERESH;
|
|
89
|
-
}
|
|
90
|
-
const digits = num2digits(num % 1000);
|
|
91
|
-
if (digits.length == 1) {
|
|
92
|
-
return str + num2heb.get(digits[0]) + GERESH;
|
|
93
|
-
}
|
|
94
|
-
for (let i = 0; i < digits.length; i++) {
|
|
95
|
-
if (i + 1 === digits.length) {
|
|
96
|
-
str += GERSHAYIM;
|
|
97
|
-
}
|
|
98
|
-
str += num2heb.get(digits[i]);
|
|
99
|
-
}
|
|
100
|
-
return str;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Converts a string of Hebrew letters to a numerical value.
|
|
105
|
-
*
|
|
106
|
-
* Only considers the value of Hebrew letters `א` through `ת`.
|
|
107
|
-
* Ignores final Hebrew letters such as `ך` (kaf sofit) or `ם` (mem sofit)
|
|
108
|
-
* and vowels (nekudot).
|
|
109
|
-
*
|
|
110
|
-
* @param {string} str
|
|
111
|
-
* @return {number}
|
|
112
|
-
*/
|
|
113
|
-
function gematriyaStrToNum(str) {
|
|
114
|
-
let num = 0;
|
|
115
|
-
const gereshIdx = str.indexOf(GERESH);
|
|
116
|
-
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
|
|
117
|
-
const thousands = str.substring(0, gereshIdx);
|
|
118
|
-
num += gematriyaStrToNum(thousands) * 1000;
|
|
119
|
-
str = str.substring(gereshIdx);
|
|
120
|
-
}
|
|
121
|
-
for (const ch of str) {
|
|
122
|
-
const n = heb2num[ch];
|
|
123
|
-
if (typeof n === 'number') {
|
|
124
|
-
num += n;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return num;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const noopLocale = {
|
|
131
|
-
headers: {
|
|
132
|
-
'plural-forms': 'nplurals=2; plural=(n!=1);'
|
|
133
|
-
},
|
|
134
|
-
contexts: {
|
|
135
|
-
'': {}
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
const alias = {
|
|
139
|
-
'h': 'he',
|
|
140
|
-
'a': 'ashkenazi',
|
|
141
|
-
's': 'en',
|
|
142
|
-
'': 'en'
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
/** @private */
|
|
146
|
-
const locales = new Map();
|
|
147
|
-
/** @private */
|
|
148
|
-
let activeLocale = null;
|
|
149
|
-
/** @private */
|
|
150
|
-
let activeName = null;
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* A locale in Hebcal is used for translations/transliterations of
|
|
154
|
-
* holidays. `@hebcal/core` supports four locales by default
|
|
155
|
-
* * `en` - default, Sephardic transliterations (e.g. "Shabbat")
|
|
156
|
-
* * `ashkenazi` - Ashkenazi transliterations (e.g. "Shabbos")
|
|
157
|
-
* * `he` - Hebrew (e.g. "שַׁבָּת")
|
|
158
|
-
* * `he-x-NoNikud` - Hebrew without nikud (e.g. "שבת")
|
|
159
|
-
*/
|
|
160
|
-
class Locale {
|
|
161
|
-
/**
|
|
162
|
-
* Returns translation only if `locale` offers a non-empty translation for `id`.
|
|
163
|
-
* Otherwise, returns `undefined`.
|
|
164
|
-
* @param {string} id Message ID to translate
|
|
165
|
-
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
166
|
-
* @return {string}
|
|
167
|
-
*/
|
|
168
|
-
static lookupTranslation(id, locale) {
|
|
169
|
-
const locale0 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
170
|
-
const loc = typeof locale == 'string' && locales.get(locale0) || activeLocale;
|
|
171
|
-
const array = loc[id];
|
|
172
|
-
if (array && array.length && array[0].length) {
|
|
173
|
-
return array[0];
|
|
174
|
-
}
|
|
175
|
-
return undefined;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* By default, if no translation was found, returns `id`.
|
|
180
|
-
* @param {string} id Message ID to translate
|
|
181
|
-
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
182
|
-
* @return {string}
|
|
183
|
-
*/
|
|
184
|
-
static gettext(id, locale) {
|
|
185
|
-
const text = this.lookupTranslation(id, locale);
|
|
186
|
-
if (typeof text == 'undefined') {
|
|
187
|
-
return id;
|
|
188
|
-
}
|
|
189
|
-
return text;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Register locale translations.
|
|
194
|
-
* @param {string} locale Locale name (i.e.: `'he'`, `'fr'`)
|
|
195
|
-
* @param {LocaleData} data parsed data from a `.po` file.
|
|
196
|
-
*/
|
|
197
|
-
static addLocale(locale, data) {
|
|
198
|
-
if (typeof locale !== 'string') {
|
|
199
|
-
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
200
|
-
}
|
|
201
|
-
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
202
|
-
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
203
|
-
}
|
|
204
|
-
locales.set(locale.toLowerCase(), data.contexts['']);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Adds a translation to `locale`, replacing any previous translation.
|
|
209
|
-
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`).
|
|
210
|
-
* @param {string} id Message ID to translate
|
|
211
|
-
* @param {string} translation Translation text
|
|
212
|
-
*/
|
|
213
|
-
static addTranslation(locale, id, translation) {
|
|
214
|
-
if (typeof locale !== 'string') {
|
|
215
|
-
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
216
|
-
}
|
|
217
|
-
const locale0 = locale.toLowerCase();
|
|
218
|
-
const loc = locales.get(locale0);
|
|
219
|
-
if (!loc) {
|
|
220
|
-
throw new TypeError(`Unknown locale: ${locale}`);
|
|
221
|
-
}
|
|
222
|
-
if (typeof id !== 'string' || id.length === 0) {
|
|
223
|
-
throw new TypeError(`Invalid id: ${id}`);
|
|
224
|
-
}
|
|
225
|
-
const isArray = Array.isArray(translation);
|
|
226
|
-
if (isArray) {
|
|
227
|
-
const t0 = translation[0];
|
|
228
|
-
if (typeof t0 !== 'string' || t0.length === 0) {
|
|
229
|
-
throw new TypeError(`Invalid translation array: ${translation}`);
|
|
230
|
-
}
|
|
231
|
-
} else if (typeof translation !== 'string') {
|
|
232
|
-
throw new TypeError(`Invalid translation: ${translation}`);
|
|
233
|
-
}
|
|
234
|
-
loc[id] = isArray ? translation : [translation];
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Adds multiple translations to `locale`, replacing any previous translations.
|
|
238
|
-
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`).
|
|
239
|
-
* @param {LocaleData} data parsed data from a `.po` file.
|
|
240
|
-
*/
|
|
241
|
-
static addTranslations(locale, data) {
|
|
242
|
-
if (typeof locale !== 'string') {
|
|
243
|
-
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
244
|
-
}
|
|
245
|
-
const locale0 = locale.toLowerCase();
|
|
246
|
-
const loc = locales.get(locale0);
|
|
247
|
-
if (!loc) {
|
|
248
|
-
throw new TypeError(`Unknown locale: ${locale}`);
|
|
249
|
-
}
|
|
250
|
-
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
251
|
-
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
252
|
-
}
|
|
253
|
-
const ctx = data.contexts[''];
|
|
254
|
-
Object.keys(ctx).forEach(id => {
|
|
255
|
-
loc[id] = ctx[id];
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Activates a locale. Throws an error if the locale has not been previously added.
|
|
260
|
-
* After setting the locale to be used, all strings marked for translations
|
|
261
|
-
* will be represented by the corresponding translation in the specified locale.
|
|
262
|
-
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`)
|
|
263
|
-
* @return {LocaleData}
|
|
264
|
-
*/
|
|
265
|
-
static useLocale(locale) {
|
|
266
|
-
const locale0 = locale.toLowerCase();
|
|
267
|
-
const obj = locales.get(locale0);
|
|
268
|
-
if (!obj) {
|
|
269
|
-
throw new RangeError(`Locale '${locale}' not found`);
|
|
270
|
-
}
|
|
271
|
-
activeName = alias[locale0] || locale0;
|
|
272
|
-
activeLocale = obj;
|
|
273
|
-
return activeLocale;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Returns the name of the active locale (i.e. 'he', 'ashkenazi', 'fr')
|
|
278
|
-
* @return {string}
|
|
279
|
-
*/
|
|
280
|
-
static getLocaleName() {
|
|
281
|
-
return activeName;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Returns the names of registered locales
|
|
286
|
-
* @return {string[]}
|
|
287
|
-
*/
|
|
288
|
-
static getLocaleNames() {
|
|
289
|
-
const keys = Array.from(locales.keys());
|
|
290
|
-
return keys.sort((a, b) => a.localeCompare(b));
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* @param {number} n
|
|
295
|
-
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
296
|
-
* @return {string}
|
|
297
|
-
*/
|
|
298
|
-
static ordinal(n, locale) {
|
|
299
|
-
const locale1 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
300
|
-
const locale0 = locale1 || activeName;
|
|
301
|
-
if (!locale0) {
|
|
302
|
-
return this.getEnOrdinal(n);
|
|
303
|
-
}
|
|
304
|
-
switch (locale0) {
|
|
305
|
-
case 'en':
|
|
306
|
-
case 's':
|
|
307
|
-
case 'a':
|
|
308
|
-
case 'ashkenazi':
|
|
309
|
-
case 'ashkenazi_litvish':
|
|
310
|
-
case 'ashkenazi_poylish':
|
|
311
|
-
case 'ashkenazi_standard':
|
|
312
|
-
return this.getEnOrdinal(n);
|
|
313
|
-
case 'es':
|
|
314
|
-
return n + 'º';
|
|
315
|
-
case 'h':
|
|
316
|
-
case 'he':
|
|
317
|
-
case 'he-x-nonikud':
|
|
318
|
-
return String(n);
|
|
319
|
-
default:
|
|
320
|
-
return n + '.';
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* @private
|
|
326
|
-
* @param {number} n
|
|
327
|
-
* @return {string}
|
|
328
|
-
*/
|
|
329
|
-
static getEnOrdinal(n) {
|
|
330
|
-
const s = ['th', 'st', 'nd', 'rd'];
|
|
331
|
-
const v = n % 100;
|
|
332
|
-
return n + (s[(v - 20) % 10] || s[v] || s[0]);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Removes nekudot from Hebrew string
|
|
337
|
-
* @param {string} str
|
|
338
|
-
* @return {string}
|
|
339
|
-
*/
|
|
340
|
-
static hebrewStripNikkud(str) {
|
|
341
|
-
return str.replace(/[\u0590-\u05bd]/g, '').replace(/[\u05bf-\u05c7]/g, '');
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
Locale.addLocale('en', noopLocale);
|
|
345
|
-
Locale.addLocale('s', noopLocale);
|
|
346
|
-
Locale.addLocale('', noopLocale);
|
|
347
|
-
Locale.useLocale('en');
|
|
348
|
-
|
|
349
4
|
/** @private */
|
|
350
5
|
const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
351
6
|
/** @private */
|
|
@@ -939,76 +594,413 @@ function toSimpleHebrewDate(obj) {
|
|
|
939
594
|
else {
|
|
940
595
|
throw new TypeError(`Argument not a Date: ${obj}`);
|
|
941
596
|
}
|
|
942
|
-
}
|
|
943
|
-
function getYahrzeitHD(hyear, date) {
|
|
944
|
-
let hDeath = toSimpleHebrewDate(date);
|
|
945
|
-
if (hyear <= hDeath.yy) {
|
|
946
|
-
// Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
|
|
947
|
-
return undefined;
|
|
597
|
+
}
|
|
598
|
+
function getYahrzeitHD(hyear, date) {
|
|
599
|
+
let hDeath = toSimpleHebrewDate(date);
|
|
600
|
+
if (hyear <= hDeath.yy) {
|
|
601
|
+
// Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
|
|
602
|
+
return undefined;
|
|
603
|
+
}
|
|
604
|
+
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hDeath.yy + 1)) {
|
|
605
|
+
// If it's Heshvan 30 it depends on the first anniversary;
|
|
606
|
+
// if that was not Heshvan 30, use the day before Kislev 1.
|
|
607
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, KISLEV$1, 1) - 1);
|
|
608
|
+
}
|
|
609
|
+
else if (hDeath.mm == KISLEV$1 && hDeath.dd == 30 && shortKislev(hDeath.yy + 1)) {
|
|
610
|
+
// If it's Kislev 30 it depends on the first anniversary;
|
|
611
|
+
// if that was not Kislev 30, use the day before Teveth 1.
|
|
612
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
|
|
613
|
+
}
|
|
614
|
+
else if (hDeath.mm == ADAR_II) {
|
|
615
|
+
// If it's Adar II, use the same day in last month of year (Adar or Adar II).
|
|
616
|
+
hDeath.mm = monthsInYear(hyear);
|
|
617
|
+
}
|
|
618
|
+
else if (hDeath.mm == ADAR_I$1 && hDeath.dd == 30 && !isLeapYear(hyear)) {
|
|
619
|
+
// If it's the 30th in Adar I and year is not a leap year
|
|
620
|
+
// (so Adar has only 29 days), use the last day in Shevat.
|
|
621
|
+
hDeath.dd = 30;
|
|
622
|
+
hDeath.mm = SHVAT;
|
|
623
|
+
}
|
|
624
|
+
// In all other cases, use the normal anniversary of the date of death.
|
|
625
|
+
// advance day to rosh chodesh if needed
|
|
626
|
+
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hyear)) {
|
|
627
|
+
hDeath.mm = KISLEV$1;
|
|
628
|
+
hDeath.dd = 1;
|
|
629
|
+
}
|
|
630
|
+
else if (hDeath.mm == KISLEV$1 && hDeath.dd == 30 && shortKislev(hyear)) {
|
|
631
|
+
hDeath.mm = TEVET$1;
|
|
632
|
+
hDeath.dd = 1;
|
|
633
|
+
}
|
|
634
|
+
hDeath.yy = hyear;
|
|
635
|
+
return hDeath;
|
|
636
|
+
}
|
|
637
|
+
function getBirthdayHD(hyear, date) {
|
|
638
|
+
const orig = toSimpleHebrewDate(date);
|
|
639
|
+
const origYear = orig.yy;
|
|
640
|
+
if (hyear === origYear) {
|
|
641
|
+
return orig;
|
|
642
|
+
}
|
|
643
|
+
else if (hyear < origYear) {
|
|
644
|
+
// Hebrew year ${hyear} occurs on or before original date in ${origYear}
|
|
645
|
+
return undefined;
|
|
646
|
+
}
|
|
647
|
+
const isOrigLeap = isLeapYear(origYear);
|
|
648
|
+
let month = orig.mm;
|
|
649
|
+
let day = orig.dd;
|
|
650
|
+
if ((month == ADAR_I$1 && !isOrigLeap) || (month == ADAR_II && isOrigLeap)) {
|
|
651
|
+
month = monthsInYear(hyear);
|
|
652
|
+
}
|
|
653
|
+
else if (month == CHESHVAN && day == 30 && !longCheshvan(hyear)) {
|
|
654
|
+
month = KISLEV$1;
|
|
655
|
+
day = 1;
|
|
656
|
+
}
|
|
657
|
+
else if (month == KISLEV$1 && day == 30 && shortKislev(hyear)) {
|
|
658
|
+
month = TEVET$1;
|
|
659
|
+
day = 1;
|
|
660
|
+
}
|
|
661
|
+
else if (month == ADAR_I$1 && day == 30 && isOrigLeap && !isLeapYear(hyear)) {
|
|
662
|
+
month = NISAN$3;
|
|
663
|
+
day = 1;
|
|
664
|
+
}
|
|
665
|
+
return { yy: hyear, mm: month, dd: day };
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const GERESH = '׳';
|
|
669
|
+
const GERSHAYIM = '״';
|
|
670
|
+
const alefbet = {
|
|
671
|
+
'א': 1,
|
|
672
|
+
'ב': 2,
|
|
673
|
+
'ג': 3,
|
|
674
|
+
'ד': 4,
|
|
675
|
+
'ה': 5,
|
|
676
|
+
'ו': 6,
|
|
677
|
+
'ז': 7,
|
|
678
|
+
'ח': 8,
|
|
679
|
+
'ט': 9,
|
|
680
|
+
'י': 10,
|
|
681
|
+
'כ': 20,
|
|
682
|
+
'ל': 30,
|
|
683
|
+
'מ': 40,
|
|
684
|
+
'נ': 50,
|
|
685
|
+
'ס': 60,
|
|
686
|
+
'ע': 70,
|
|
687
|
+
'פ': 80,
|
|
688
|
+
'צ': 90,
|
|
689
|
+
'ק': 100,
|
|
690
|
+
'ר': 200,
|
|
691
|
+
'ש': 300,
|
|
692
|
+
'ת': 400,
|
|
693
|
+
};
|
|
694
|
+
const heb2num = new Map();
|
|
695
|
+
const num2heb = new Map();
|
|
696
|
+
for (const [key, val] of Object.entries(alefbet)) {
|
|
697
|
+
heb2num.set(key, val);
|
|
698
|
+
num2heb.set(val, key);
|
|
699
|
+
}
|
|
700
|
+
function num2digits(num) {
|
|
701
|
+
const digits = [];
|
|
702
|
+
while (num > 0) {
|
|
703
|
+
if (num === 15 || num === 16) {
|
|
704
|
+
digits.push(9);
|
|
705
|
+
digits.push(num - 9);
|
|
706
|
+
break;
|
|
707
|
+
}
|
|
708
|
+
let incr = 100;
|
|
709
|
+
let i;
|
|
710
|
+
for (i = 400; i > num; i -= incr) {
|
|
711
|
+
if (i === incr) {
|
|
712
|
+
incr = incr / 10;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
digits.push(i);
|
|
716
|
+
num -= i;
|
|
717
|
+
}
|
|
718
|
+
return digits;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Converts a numerical value to a string of Hebrew letters.
|
|
722
|
+
*
|
|
723
|
+
* When specifying years of the Hebrew calendar in the present millennium,
|
|
724
|
+
* we omit the thousands (which is presently 5 [ה]).
|
|
725
|
+
* @example
|
|
726
|
+
* gematriya(5774) // 'תשע״ד' - cropped to 774
|
|
727
|
+
* gematriya(25) // 'כ״ה'
|
|
728
|
+
* gematriya(60) // 'ס׳'
|
|
729
|
+
* gematriya(3761) // 'ג׳תשס״א'
|
|
730
|
+
* gematriya(1123) // 'א׳קכ״ג'
|
|
731
|
+
* @param {number} num
|
|
732
|
+
* @return {string}
|
|
733
|
+
*/
|
|
734
|
+
function gematriya(num) {
|
|
735
|
+
const num0 = num;
|
|
736
|
+
const num1 = parseInt(num0, 10);
|
|
737
|
+
if (!num1) {
|
|
738
|
+
throw new TypeError(`invalid parameter to gematriya ${num}`);
|
|
739
|
+
}
|
|
740
|
+
let str = '';
|
|
741
|
+
const thousands = Math.floor(num1 / 1000);
|
|
742
|
+
if (thousands > 0 && thousands !== 5) {
|
|
743
|
+
const tdigits = num2digits(thousands);
|
|
744
|
+
for (const tdig of tdigits) {
|
|
745
|
+
str += num2heb.get(tdig);
|
|
746
|
+
}
|
|
747
|
+
str += GERESH;
|
|
748
|
+
}
|
|
749
|
+
const digits = num2digits(num1 % 1000);
|
|
750
|
+
if (digits.length == 1) {
|
|
751
|
+
return str + num2heb.get(digits[0]) + GERESH;
|
|
752
|
+
}
|
|
753
|
+
for (let i = 0; i < digits.length; i++) {
|
|
754
|
+
if (i + 1 === digits.length) {
|
|
755
|
+
str += GERSHAYIM;
|
|
756
|
+
}
|
|
757
|
+
str += num2heb.get(digits[i]);
|
|
758
|
+
}
|
|
759
|
+
return str;
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Converts a string of Hebrew letters to a numerical value.
|
|
763
|
+
*
|
|
764
|
+
* Only considers the value of Hebrew letters `א` through `ת`.
|
|
765
|
+
* Ignores final Hebrew letters such as `ך` (kaf sofit) or `ם` (mem sofit)
|
|
766
|
+
* and vowels (nekudot).
|
|
767
|
+
*
|
|
768
|
+
* @param {string} str
|
|
769
|
+
* @return {number}
|
|
770
|
+
*/
|
|
771
|
+
function gematriyaStrToNum(str) {
|
|
772
|
+
let num = 0;
|
|
773
|
+
const gereshIdx = str.indexOf(GERESH);
|
|
774
|
+
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
|
|
775
|
+
const thousands = str.substring(0, gereshIdx);
|
|
776
|
+
num += gematriyaStrToNum(thousands) * 1000;
|
|
777
|
+
str = str.substring(gereshIdx);
|
|
778
|
+
}
|
|
779
|
+
for (const ch of str) {
|
|
780
|
+
const n = heb2num.get(ch);
|
|
781
|
+
if (typeof n === 'number') {
|
|
782
|
+
num += n;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
return num;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
const noopLocale = {
|
|
789
|
+
headers: {
|
|
790
|
+
'plural-forms': 'nplurals=2; plural=(n!=1);'
|
|
791
|
+
},
|
|
792
|
+
contexts: {
|
|
793
|
+
'': {}
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
const alias = {
|
|
797
|
+
'h': 'he',
|
|
798
|
+
'a': 'ashkenazi',
|
|
799
|
+
's': 'en',
|
|
800
|
+
'': 'en'
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
/** @private */
|
|
804
|
+
const locales = new Map();
|
|
805
|
+
/** @private */
|
|
806
|
+
let activeLocale = null;
|
|
807
|
+
/** @private */
|
|
808
|
+
let activeName = null;
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* A locale in Hebcal is used for translations/transliterations of
|
|
812
|
+
* holidays. `@hebcal/core` supports four locales by default
|
|
813
|
+
* * `en` - default, Sephardic transliterations (e.g. "Shabbat")
|
|
814
|
+
* * `ashkenazi` - Ashkenazi transliterations (e.g. "Shabbos")
|
|
815
|
+
* * `he` - Hebrew (e.g. "שַׁבָּת")
|
|
816
|
+
* * `he-x-NoNikud` - Hebrew without nikud (e.g. "שבת")
|
|
817
|
+
*/
|
|
818
|
+
class Locale {
|
|
819
|
+
/**
|
|
820
|
+
* Returns translation only if `locale` offers a non-empty translation for `id`.
|
|
821
|
+
* Otherwise, returns `undefined`.
|
|
822
|
+
* @param {string} id Message ID to translate
|
|
823
|
+
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
824
|
+
* @return {string}
|
|
825
|
+
*/
|
|
826
|
+
static lookupTranslation(id, locale) {
|
|
827
|
+
const locale0 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
828
|
+
const loc = typeof locale == 'string' && locales.get(locale0) || activeLocale;
|
|
829
|
+
const array = loc[id];
|
|
830
|
+
if (array && array.length && array[0].length) {
|
|
831
|
+
return array[0];
|
|
832
|
+
}
|
|
833
|
+
return undefined;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* By default, if no translation was found, returns `id`.
|
|
838
|
+
* @param {string} id Message ID to translate
|
|
839
|
+
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
840
|
+
* @return {string}
|
|
841
|
+
*/
|
|
842
|
+
static gettext(id, locale) {
|
|
843
|
+
const text = this.lookupTranslation(id, locale);
|
|
844
|
+
if (typeof text == 'undefined') {
|
|
845
|
+
return id;
|
|
948
846
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
847
|
+
return text;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Register locale translations.
|
|
852
|
+
* @param {string} locale Locale name (i.e.: `'he'`, `'fr'`)
|
|
853
|
+
* @param {LocaleData} data parsed data from a `.po` file.
|
|
854
|
+
*/
|
|
855
|
+
static addLocale(locale, data) {
|
|
856
|
+
if (typeof locale !== 'string') {
|
|
857
|
+
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
953
858
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
// if that was not Kislev 30, use the day before Teveth 1.
|
|
957
|
-
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
|
|
859
|
+
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
860
|
+
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
958
861
|
}
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
862
|
+
locales.set(locale.toLowerCase(), data.contexts['']);
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* Adds a translation to `locale`, replacing any previous translation.
|
|
867
|
+
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`).
|
|
868
|
+
* @param {string} id Message ID to translate
|
|
869
|
+
* @param {string} translation Translation text
|
|
870
|
+
*/
|
|
871
|
+
static addTranslation(locale, id, translation) {
|
|
872
|
+
if (typeof locale !== 'string') {
|
|
873
|
+
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
962
874
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
hDeath.mm = SHVAT;
|
|
875
|
+
const locale0 = locale.toLowerCase();
|
|
876
|
+
const loc = locales.get(locale0);
|
|
877
|
+
if (!loc) {
|
|
878
|
+
throw new TypeError(`Unknown locale: ${locale}`);
|
|
968
879
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hyear)) {
|
|
972
|
-
hDeath.mm = KISLEV$1;
|
|
973
|
-
hDeath.dd = 1;
|
|
880
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
881
|
+
throw new TypeError(`Invalid id: ${id}`);
|
|
974
882
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
883
|
+
const isArray = Array.isArray(translation);
|
|
884
|
+
if (isArray) {
|
|
885
|
+
const t0 = translation[0];
|
|
886
|
+
if (typeof t0 !== 'string' || t0.length === 0) {
|
|
887
|
+
throw new TypeError(`Invalid translation array: ${translation}`);
|
|
888
|
+
}
|
|
889
|
+
} else if (typeof translation !== 'string') {
|
|
890
|
+
throw new TypeError(`Invalid translation: ${translation}`);
|
|
978
891
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
892
|
+
loc[id] = isArray ? translation : [translation];
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Adds multiple translations to `locale`, replacing any previous translations.
|
|
896
|
+
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`).
|
|
897
|
+
* @param {LocaleData} data parsed data from a `.po` file.
|
|
898
|
+
*/
|
|
899
|
+
static addTranslations(locale, data) {
|
|
900
|
+
if (typeof locale !== 'string') {
|
|
901
|
+
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
987
902
|
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
903
|
+
const locale0 = locale.toLowerCase();
|
|
904
|
+
const loc = locales.get(locale0);
|
|
905
|
+
if (!loc) {
|
|
906
|
+
throw new TypeError(`Unknown locale: ${locale}`);
|
|
991
907
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
let day = orig.dd;
|
|
995
|
-
if ((month == ADAR_I$1 && !isOrigLeap) || (month == ADAR_II && isOrigLeap)) {
|
|
996
|
-
month = monthsInYear(hyear);
|
|
908
|
+
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
909
|
+
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
997
910
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
911
|
+
const ctx = data.contexts[''];
|
|
912
|
+
Object.assign(loc, ctx);
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Activates a locale. Throws an error if the locale has not been previously added.
|
|
916
|
+
* After setting the locale to be used, all strings marked for translations
|
|
917
|
+
* will be represented by the corresponding translation in the specified locale.
|
|
918
|
+
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`)
|
|
919
|
+
* @return {LocaleData}
|
|
920
|
+
*/
|
|
921
|
+
static useLocale(locale) {
|
|
922
|
+
const locale0 = locale.toLowerCase();
|
|
923
|
+
const obj = locales.get(locale0);
|
|
924
|
+
if (!obj) {
|
|
925
|
+
throw new RangeError(`Locale '${locale}' not found`);
|
|
1001
926
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
927
|
+
activeName = alias[locale0] || locale0;
|
|
928
|
+
activeLocale = obj;
|
|
929
|
+
return activeLocale;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* Returns the name of the active locale (i.e. 'he', 'ashkenazi', 'fr')
|
|
934
|
+
* @return {string}
|
|
935
|
+
*/
|
|
936
|
+
static getLocaleName() {
|
|
937
|
+
return activeName;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Returns the names of registered locales
|
|
942
|
+
* @return {string[]}
|
|
943
|
+
*/
|
|
944
|
+
static getLocaleNames() {
|
|
945
|
+
const keys = Array.from(locales.keys());
|
|
946
|
+
return keys.sort((a, b) => a.localeCompare(b));
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* @param {number} n
|
|
951
|
+
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
952
|
+
* @return {string}
|
|
953
|
+
*/
|
|
954
|
+
static ordinal(n, locale) {
|
|
955
|
+
const locale1 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
956
|
+
const locale0 = locale1 || activeName;
|
|
957
|
+
if (!locale0) {
|
|
958
|
+
return this.getEnOrdinal(n);
|
|
1005
959
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
960
|
+
switch (locale0) {
|
|
961
|
+
case 'en':
|
|
962
|
+
case 's':
|
|
963
|
+
case 'a':
|
|
964
|
+
case 'ashkenazi':
|
|
965
|
+
case 'ashkenazi_litvish':
|
|
966
|
+
case 'ashkenazi_poylish':
|
|
967
|
+
case 'ashkenazi_standard':
|
|
968
|
+
return this.getEnOrdinal(n);
|
|
969
|
+
case 'es':
|
|
970
|
+
return n + 'º';
|
|
971
|
+
case 'h':
|
|
972
|
+
case 'he':
|
|
973
|
+
case 'he-x-nonikud':
|
|
974
|
+
return String(n);
|
|
975
|
+
default:
|
|
976
|
+
return n + '.';
|
|
1009
977
|
}
|
|
1010
|
-
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* @private
|
|
982
|
+
* @param {number} n
|
|
983
|
+
* @return {string}
|
|
984
|
+
*/
|
|
985
|
+
static getEnOrdinal(n) {
|
|
986
|
+
const s = ['th', 'st', 'nd', 'rd'];
|
|
987
|
+
const v = n % 100;
|
|
988
|
+
return n + (s[(v - 20) % 10] || s[v] || s[0]);
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/**
|
|
992
|
+
* Removes nekudot from Hebrew string
|
|
993
|
+
* @param {string} str
|
|
994
|
+
* @return {string}
|
|
995
|
+
*/
|
|
996
|
+
static hebrewStripNikkud(str) {
|
|
997
|
+
return str.replace(/[\u0590-\u05bd]/g, '').replace(/[\u05bf-\u05c7]/g, '');
|
|
998
|
+
}
|
|
1011
999
|
}
|
|
1000
|
+
Locale.addLocale('en', noopLocale);
|
|
1001
|
+
Locale.addLocale('s', noopLocale);
|
|
1002
|
+
Locale.addLocale('', noopLocale);
|
|
1003
|
+
Locale.useLocale('en');
|
|
1012
1004
|
|
|
1013
1005
|
/**
|
|
1014
1006
|
* @private
|
|
@@ -1837,7 +1829,7 @@ class Event {
|
|
|
1837
1829
|
this.desc = desc;
|
|
1838
1830
|
this.mask = +mask;
|
|
1839
1831
|
if (typeof attrs === 'object' && attrs !== null) {
|
|
1840
|
-
Object.
|
|
1832
|
+
Object.assign(this, attrs);
|
|
1841
1833
|
}
|
|
1842
1834
|
}
|
|
1843
1835
|
/**
|
|
@@ -3430,10 +3422,10 @@ class Location extends GeoLocation {
|
|
|
3430
3422
|
return true;
|
|
3431
3423
|
}
|
|
3432
3424
|
}
|
|
3433
|
-
|
|
3425
|
+
for (const city of classicCities0) {
|
|
3434
3426
|
const location = new Location(city[2], city[3], city[1] == 'IL', city[4], city[0], city[1], undefined, city[5]);
|
|
3435
3427
|
Location.addLocation(location.getName(), location);
|
|
3436
|
-
}
|
|
3428
|
+
}
|
|
3437
3429
|
|
|
3438
3430
|
const _formatters = new Map();
|
|
3439
3431
|
|
|
@@ -5612,40 +5604,7 @@ const MINOR_HOLIDAY$1 = flags.MINOR_HOLIDAY;
|
|
|
5612
5604
|
const EREV$1 = flags.EREV;
|
|
5613
5605
|
// const CHOL_HAMOED = flags.CHOL_HAMOED;
|
|
5614
5606
|
|
|
5615
|
-
|
|
5616
|
-
* Avoid dependency on ES6 Map object
|
|
5617
|
-
* @private
|
|
5618
|
-
*/
|
|
5619
|
-
class SimpleMap {
|
|
5620
|
-
/**
|
|
5621
|
-
* @param {string} key
|
|
5622
|
-
* @return {boolean}
|
|
5623
|
-
*/
|
|
5624
|
-
has(key) {
|
|
5625
|
-
return typeof this[key] !== 'undefined';
|
|
5626
|
-
}
|
|
5627
|
-
/**
|
|
5628
|
-
* @param {string} key
|
|
5629
|
-
* @return {any}
|
|
5630
|
-
*/
|
|
5631
|
-
get(key) {
|
|
5632
|
-
return this[key];
|
|
5633
|
-
}
|
|
5634
|
-
/**
|
|
5635
|
-
* @param {string} key
|
|
5636
|
-
* @param {any} val
|
|
5637
|
-
*/
|
|
5638
|
-
set(key, val) {
|
|
5639
|
-
this[key] = val;
|
|
5640
|
-
}
|
|
5641
|
-
/**
|
|
5642
|
-
* @return {string[]}
|
|
5643
|
-
*/
|
|
5644
|
-
keys() {
|
|
5645
|
-
return Object.keys(this);
|
|
5646
|
-
}
|
|
5647
|
-
}
|
|
5648
|
-
const sedraCache = new SimpleMap();
|
|
5607
|
+
const sedraCache = new Map();
|
|
5649
5608
|
|
|
5650
5609
|
/**
|
|
5651
5610
|
* @private
|
|
@@ -5689,13 +5648,12 @@ function getHolidaysForYear_(year) {
|
|
|
5689
5648
|
}
|
|
5690
5649
|
const RH = new HDate(1, TISHREI$1, year);
|
|
5691
5650
|
const pesach = new HDate(15, NISAN$1, year);
|
|
5692
|
-
const
|
|
5651
|
+
const map = new Map();
|
|
5693
5652
|
// eslint-disable-next-line require-jsdoc
|
|
5694
5653
|
function add(...events) {
|
|
5695
|
-
|
|
5696
|
-
events.forEach(ev => {
|
|
5654
|
+
for (const ev of events) {
|
|
5697
5655
|
const key = ev.date.toString();
|
|
5698
|
-
const arr =
|
|
5656
|
+
const arr = map.get(key);
|
|
5699
5657
|
if (typeof arr === 'object') {
|
|
5700
5658
|
if (arr[0].getFlags() & flags.EREV) {
|
|
5701
5659
|
arr.unshift(ev);
|
|
@@ -5703,17 +5661,17 @@ function getHolidaysForYear_(year) {
|
|
|
5703
5661
|
arr.push(ev);
|
|
5704
5662
|
}
|
|
5705
5663
|
} else {
|
|
5706
|
-
|
|
5664
|
+
map.set(key, [ev]);
|
|
5707
5665
|
}
|
|
5708
|
-
}
|
|
5666
|
+
}
|
|
5709
5667
|
}
|
|
5710
|
-
|
|
5668
|
+
for (const h of staticHolidays) {
|
|
5711
5669
|
const hd = new HDate(h.dd, h.mm, year);
|
|
5712
5670
|
const ev = new HolidayEvent(hd, h.desc, h.flags);
|
|
5713
5671
|
if (h.emoji) ev.emoji = h.emoji;
|
|
5714
5672
|
if (h.chmDay) ev.cholHaMoedDay = h.chmDay;
|
|
5715
5673
|
add(ev);
|
|
5716
|
-
}
|
|
5674
|
+
}
|
|
5717
5675
|
|
|
5718
5676
|
// standard holidays that don't shift based on year
|
|
5719
5677
|
add(new RoshHashanaEvent(RH, year, CHAG | LIGHT_CANDLES_TZEIS$1));
|
|
@@ -5765,7 +5723,7 @@ function getHolidaysForYear_(year) {
|
|
|
5765
5723
|
if (yomHaZikaronDt) {
|
|
5766
5724
|
add(new HolidayEvent(yomHaZikaronDt, 'Yom HaZikaron', MODERN_HOLIDAY$1, emojiIsraelFlag), new HolidayEvent(yomHaZikaronDt.next(), 'Yom HaAtzma\'ut', MODERN_HOLIDAY$1, emojiIsraelFlag));
|
|
5767
5725
|
}
|
|
5768
|
-
|
|
5726
|
+
for (const h of staticModernHolidays) {
|
|
5769
5727
|
if (year >= h.firstYear) {
|
|
5770
5728
|
let hd = new HDate(h.dd, h.mm, year);
|
|
5771
5729
|
const dow = hd.getDay();
|
|
@@ -5783,7 +5741,7 @@ function getHolidaysForYear_(year) {
|
|
|
5783
5741
|
}
|
|
5784
5742
|
add(ev);
|
|
5785
5743
|
}
|
|
5786
|
-
}
|
|
5744
|
+
}
|
|
5787
5745
|
let tamuz17 = new HDate(17, TAMUZ, year);
|
|
5788
5746
|
let tamuz17attrs;
|
|
5789
5747
|
if (tamuz17.getDay() == SAT$1) {
|
|
@@ -5854,8 +5812,8 @@ function getHolidaysForYear_(year) {
|
|
|
5854
5812
|
emoji: '☀️'
|
|
5855
5813
|
}));
|
|
5856
5814
|
}
|
|
5857
|
-
yearCache.set(year,
|
|
5858
|
-
return
|
|
5815
|
+
yearCache.set(year, map);
|
|
5816
|
+
return map;
|
|
5859
5817
|
}
|
|
5860
5818
|
|
|
5861
5819
|
/**
|
|
@@ -5922,7 +5880,7 @@ class DailyLearning {
|
|
|
5922
5880
|
}
|
|
5923
5881
|
}
|
|
5924
5882
|
|
|
5925
|
-
const version="5.0.
|
|
5883
|
+
const version="5.0.2";
|
|
5926
5884
|
|
|
5927
5885
|
const headers$1={"plural-forms":"nplurals=2; plural=(n > 1);"};const contexts$1={"":{Shabbat:["Shabbos"],"Achrei Mot":["Achrei Mos"],Bechukotai:["Bechukosai"],"Beha'alotcha":["Beha'aloscha"],Bereshit:["Bereshis"],Chukat:["Chukas"],"Erev Shavuot":["Erev Shavuos"],"Erev Sukkot":["Erev Sukkos"],"Ki Tavo":["Ki Savo"],"Ki Teitzei":["Ki Seitzei"],"Ki Tisa":["Ki Sisa"],Matot:["Matos"],"Purim Katan":["Purim Koton"],"Shabbat Chazon":["Shabbos Chazon"],"Shabbat HaChodesh":["Shabbos HaChodesh"],"Shabbat HaGadol":["Shabbos HaGadol"],"Shabbat Nachamu":["Shabbos Nachamu"],"Shabbat Parah":["Shabbos Parah"],"Shabbat Shekalim":["Shabbos Shekalim"],"Shabbat Shuva":["Shabbos Shuvah"],"Shabbat Zachor":["Shabbos Zachor"],Shavuot:["Shavuos"],"Shavuot I":["Shavuos I"],"Shavuot II":["Shavuos II"],Shemot:["Shemos"],"Shmini Atzeret":["Shmini Atzeres"],"Simchat Torah":["Simchas Torah"],Sukkot:["Sukkos"],"Sukkot I":["Sukkos I"],"Sukkot II":["Sukkos II"],"Sukkot II (CH''M)":["Sukkos II (CH''M)"],"Sukkot III (CH''M)":["Sukkos III (CH''M)"],"Sukkot IV (CH''M)":["Sukkos IV (CH''M)"],"Sukkot V (CH''M)":["Sukkos V (CH''M)"],"Sukkot VI (CH''M)":["Sukkos VI (CH''M)"],"Sukkot VII (Hoshana Raba)":["Sukkos VII (Hoshana Raba)"],"Ta'anit Bechorot":["Ta'anis Bechoros"],"Ta'anit Esther":["Ta'anis Esther"],Toldot:["Toldos"],Vaetchanan:["Vaeschanan"],Yitro:["Yisro"],"Vezot Haberakhah":["Vezos Haberakhah"],Parashat:["Parshas"],"Leil Selichot":["Leil Selichos"],"Shabbat Mevarchim Chodesh":["Shabbos Mevorchim Chodesh"],"Shabbat Shirah":["Shabbos Shirah"],Tevet:["Teves"],"Asara B'Tevet":["Asara B'Teves"],"Alot HaShachar":["Alos HaShachar"],"Kriat Shema, sof zeman":["Krias Shema, sof zman"],"Tefilah, sof zeman":["Tefilah, sof zman"],"Kriat Shema, sof zeman (MGA)":["Krias Shema, sof zman (MGA)"],"Tefilah, sof zeman (MGA)":["Tefilah, sof zman (MGA)"],"Chatzot HaLailah":["Chatzos HaLailah"],"Chatzot hayom":["Chatzos"],"Tzeit HaKochavim":["Tzeis HaKochavim"],"Birkat Hachamah":["Birkas Hachamah"],"Shushan Purim Katan":["Shushan Purim Koton"]}};var poAshkenazi = {headers:headers$1,contexts:contexts$1};
|
|
5928
5886
|
|
|
@@ -5935,9 +5893,9 @@ Locale.addLocale('he', poHe);
|
|
|
5935
5893
|
Locale.addLocale('h', poHe);
|
|
5936
5894
|
const heStrs = poHe.contexts[''];
|
|
5937
5895
|
const heNoNikud = {};
|
|
5938
|
-
Object.
|
|
5939
|
-
heNoNikud[key] = [Locale.hebrewStripNikkud(
|
|
5940
|
-
}
|
|
5896
|
+
for (const [key, val] of Object.entries(heStrs)) {
|
|
5897
|
+
heNoNikud[key] = [Locale.hebrewStripNikkud(val[0])];
|
|
5898
|
+
}
|
|
5941
5899
|
const poHeNoNikud = {
|
|
5942
5900
|
headers: poHe.headers,
|
|
5943
5901
|
contexts: {
|
|
@@ -6218,24 +6176,12 @@ const RECOGNIZED_OPTIONS = {
|
|
|
6218
6176
|
* @param {CalOptions} options
|
|
6219
6177
|
*/
|
|
6220
6178
|
function warnUnrecognizedOptions(options) {
|
|
6221
|
-
Object.keys(options)
|
|
6179
|
+
for (const k of Object.keys(options)) {
|
|
6222
6180
|
if (typeof RECOGNIZED_OPTIONS[k] === 'undefined' && !unrecognizedAlreadyWarned.has(k)) {
|
|
6223
6181
|
console.warn(`Ignoring unrecognized HebrewCalendar option: ${k}`);
|
|
6224
6182
|
unrecognizedAlreadyWarned.add(k);
|
|
6225
6183
|
}
|
|
6226
|
-
}
|
|
6227
|
-
}
|
|
6228
|
-
|
|
6229
|
-
/**
|
|
6230
|
-
* A bit like Object.assign(), but just a shallow copy
|
|
6231
|
-
* @private
|
|
6232
|
-
* @param {any} target
|
|
6233
|
-
* @param {any} source
|
|
6234
|
-
* @return {any}
|
|
6235
|
-
*/
|
|
6236
|
-
function shallowCopy(target, source) {
|
|
6237
|
-
Object.keys(source).forEach(k => target[k] = source[k]);
|
|
6238
|
-
return target;
|
|
6184
|
+
}
|
|
6239
6185
|
}
|
|
6240
6186
|
const israelCityOffset = {
|
|
6241
6187
|
'Jerusalem': 40,
|
|
@@ -6596,6 +6542,7 @@ function observedInDiaspora(ev) {
|
|
|
6596
6542
|
return ev.observedInDiaspora();
|
|
6597
6543
|
}
|
|
6598
6544
|
const yearArrayCache = new Map();
|
|
6545
|
+
const holidaysOnDate = new Map();
|
|
6599
6546
|
|
|
6600
6547
|
/**
|
|
6601
6548
|
* HebrewCalendar is the main interface to the `@hebcal/core` library.
|
|
@@ -6713,7 +6660,7 @@ class HebrewCalendar {
|
|
|
6713
6660
|
* @return {Event[]}
|
|
6714
6661
|
*/
|
|
6715
6662
|
static calendar(options = {}) {
|
|
6716
|
-
options =
|
|
6663
|
+
options = Object.assign({}, options); // so we can modify freely
|
|
6717
6664
|
checkCandleOptions(options);
|
|
6718
6665
|
const location = options.location = options.location || defaultLocation;
|
|
6719
6666
|
const il = options.il = options.il || location.il || false;
|
|
@@ -6762,9 +6709,9 @@ class HebrewCalendar {
|
|
|
6762
6709
|
const dow = hd.getDay();
|
|
6763
6710
|
let candlesEv;
|
|
6764
6711
|
const ev = holidaysYear.get(hd.toString()) || [];
|
|
6765
|
-
|
|
6712
|
+
for (const e of ev) {
|
|
6766
6713
|
candlesEv = appendHolidayAndRelated(evts, e, options, candlesEv, dow);
|
|
6767
|
-
}
|
|
6714
|
+
}
|
|
6768
6715
|
if (options.sedrot && dow === SAT) {
|
|
6769
6716
|
const parsha0 = sedra.lookup(abs);
|
|
6770
6717
|
if (!parsha0.chag) {
|
|
@@ -6773,8 +6720,7 @@ class HebrewCalendar {
|
|
|
6773
6720
|
}
|
|
6774
6721
|
const dailyLearning = options.dailyLearning;
|
|
6775
6722
|
if (typeof dailyLearning === 'object') {
|
|
6776
|
-
Object.
|
|
6777
|
-
const val = dailyLearning[key];
|
|
6723
|
+
for (const [key, val] of Object.entries(dailyLearning)) {
|
|
6778
6724
|
if (val) {
|
|
6779
6725
|
const name = key === 'yerushalmi' ? val === 2 ? 'yerushalmi-schottenstein' : 'yerushalmi-vilna' : key;
|
|
6780
6726
|
const learningEv = DailyLearning.lookup(name, hd);
|
|
@@ -6782,7 +6728,7 @@ class HebrewCalendar {
|
|
|
6782
6728
|
evts.push(learningEv);
|
|
6783
6729
|
}
|
|
6784
6730
|
}
|
|
6785
|
-
}
|
|
6731
|
+
}
|
|
6786
6732
|
}
|
|
6787
6733
|
if (options.omer && abs >= beginOmer && abs <= endOmer) {
|
|
6788
6734
|
const omer = abs - beginOmer + 1;
|
|
@@ -6944,20 +6890,29 @@ class HebrewCalendar {
|
|
|
6944
6890
|
}
|
|
6945
6891
|
|
|
6946
6892
|
/**
|
|
6947
|
-
* Returns an array of Events on this date (or undefined if no events)
|
|
6893
|
+
* Returns an array of Events on this date (or `undefined` if no events)
|
|
6948
6894
|
* @param {HDate|Date|number} date Hebrew Date, Gregorian date, or absolute R.D. day number
|
|
6949
6895
|
* @param {boolean} [il] use the Israeli schedule for holidays
|
|
6950
6896
|
* @return {Event[]}
|
|
6951
6897
|
*/
|
|
6952
6898
|
static getHolidaysOnDate(date, il) {
|
|
6953
6899
|
const hd = HDate.isHDate(date) ? date : new HDate(date);
|
|
6900
|
+
const hdStr = hd.toString();
|
|
6901
|
+
const cacheKey = hdStr + '/' + (typeof il === 'undefined' ? 2 : il ? 1 : 0);
|
|
6902
|
+
if (holidaysOnDate.has(cacheKey)) {
|
|
6903
|
+
return holidaysOnDate.get(cacheKey);
|
|
6904
|
+
}
|
|
6954
6905
|
const yearMap = getHolidaysForYear_(hd.getFullYear());
|
|
6955
|
-
const events = yearMap.get(
|
|
6906
|
+
const events = yearMap.get(hdStr);
|
|
6907
|
+
// if il isn't a boolean return both diaspora + IL for day
|
|
6956
6908
|
if (typeof il === 'undefined' || typeof events === 'undefined') {
|
|
6909
|
+
holidaysOnDate.set(cacheKey, events);
|
|
6957
6910
|
return events;
|
|
6958
6911
|
}
|
|
6959
6912
|
const myFilter = il ? observedInIsrael : observedInDiaspora;
|
|
6960
|
-
|
|
6913
|
+
const filtered = events.filter(myFilter);
|
|
6914
|
+
holidaysOnDate.set(cacheKey, filtered);
|
|
6915
|
+
return filtered;
|
|
6961
6916
|
}
|
|
6962
6917
|
|
|
6963
6918
|
/**
|