@hebcal/core 5.3.4 → 5.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +2 -2
- package/dist/bundle.min.js +2 -2
- package/dist/index.cjs +688 -592
- package/dist/index.mjs +688 -592
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @hebcal/core v5.3.
|
|
1
|
+
/*! @hebcal/core v5.3.5 */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-namespace, no-inner-declarations */
|
|
@@ -11,29 +11,29 @@ monthLengths[1][2] = 29;
|
|
|
11
11
|
* @private
|
|
12
12
|
*/
|
|
13
13
|
function mod$1(x, y) {
|
|
14
|
-
|
|
14
|
+
return x - y * Math.floor(x / y);
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* @private
|
|
18
18
|
*/
|
|
19
19
|
function quotient(x, y) {
|
|
20
|
-
|
|
20
|
+
return Math.floor(x / y);
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* @private
|
|
24
24
|
* @param abs - R.D. number of days
|
|
25
25
|
*/
|
|
26
26
|
function yearFromFixed(abs) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
const l0 = abs - 1;
|
|
28
|
+
const n400 = quotient(l0, 146097);
|
|
29
|
+
const d1 = mod$1(l0, 146097);
|
|
30
|
+
const n100 = quotient(d1, 36524);
|
|
31
|
+
const d2 = mod$1(d1, 36524);
|
|
32
|
+
const n4 = quotient(d2, 1461);
|
|
33
|
+
const d3 = mod$1(d2, 1461);
|
|
34
|
+
const n1 = quotient(d3, 365);
|
|
35
|
+
const year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
|
|
36
|
+
return n100 !== 4 && n1 !== 4 ? year + 1 : year;
|
|
37
37
|
}
|
|
38
38
|
/*
|
|
39
39
|
const ABS_14SEP1752 = 639797;
|
|
@@ -44,95 +44,101 @@ const ABS_2SEP1752 = 639785;
|
|
|
44
44
|
*/
|
|
45
45
|
exports.greg = void 0;
|
|
46
46
|
(function (greg) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
greg.isLeapYear = isLeapYear;
|
|
56
|
-
/**
|
|
57
|
-
* Number of days in the Gregorian month for given year
|
|
58
|
-
* @param {number} month Gregorian month (1=January, 12=December)
|
|
59
|
-
* @param {number} year Gregorian year
|
|
60
|
-
* @return {number}
|
|
61
|
-
*/
|
|
62
|
-
function daysInMonth(month, year) {
|
|
63
|
-
// 1 based months
|
|
64
|
-
return monthLengths[+isLeapYear(year)][month];
|
|
65
|
-
}
|
|
66
|
-
greg.daysInMonth = daysInMonth;
|
|
67
|
-
/**
|
|
68
|
-
* Returns true if the object is a Javascript Date
|
|
69
|
-
* @param {Object} obj
|
|
70
|
-
* @return {boolean}
|
|
71
|
-
*/
|
|
72
|
-
function isDate(obj) {
|
|
73
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
74
|
-
return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
|
|
75
|
-
}
|
|
76
|
-
greg.isDate = isDate;
|
|
77
|
-
/**
|
|
78
|
-
* @private
|
|
79
|
-
* @param year
|
|
80
|
-
* @param month (1-12)
|
|
81
|
-
* @param day (1-31)
|
|
82
|
-
*/
|
|
83
|
-
function toFixed(year, month, day) {
|
|
84
|
-
const py = year - 1;
|
|
85
|
-
return 365 * py + quotient(py, 4) - quotient(py, 100) + quotient(py, 400) + quotient(367 * month - 362, 12) + (month <= 2 ? 0 : isLeapYear(year) ? -1 : -2) + day;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
89
|
-
* @param {Date} date Gregorian date
|
|
90
|
-
* @return {number}
|
|
91
|
-
*/
|
|
92
|
-
function greg2abs(date) {
|
|
93
|
-
if (!isDate(date)) {
|
|
94
|
-
throw new TypeError(`Argument not a Date: ${date}`);
|
|
47
|
+
/**
|
|
48
|
+
* Returns true if the Gregorian year is a leap year
|
|
49
|
+
* @param {number} year Gregorian year
|
|
50
|
+
* @return {boolean}
|
|
51
|
+
*/
|
|
52
|
+
function isLeapYear(year) {
|
|
53
|
+
return !(year % 4) && (!!(year % 100) || !(year % 400));
|
|
95
54
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
55
|
+
greg.isLeapYear = isLeapYear;
|
|
56
|
+
/**
|
|
57
|
+
* Number of days in the Gregorian month for given year
|
|
58
|
+
* @param {number} month Gregorian month (1=January, 12=December)
|
|
59
|
+
* @param {number} year Gregorian year
|
|
60
|
+
* @return {number}
|
|
61
|
+
*/
|
|
62
|
+
function daysInMonth(month, year) {
|
|
63
|
+
// 1 based months
|
|
64
|
+
return monthLengths[+isLeapYear(year)][month];
|
|
100
65
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
* (April, 1993), pages 383-404 for an explanation.
|
|
111
|
-
* @param {number} abs - R.D. number of days
|
|
112
|
-
* @return {Date}
|
|
113
|
-
*/
|
|
114
|
-
function abs2greg(abs) {
|
|
115
|
-
if (typeof abs !== 'number') {
|
|
116
|
-
throw new TypeError(`Argument not a Number: ${abs}`);
|
|
66
|
+
greg.daysInMonth = daysInMonth;
|
|
67
|
+
/**
|
|
68
|
+
* Returns true if the object is a Javascript Date
|
|
69
|
+
* @param {Object} obj
|
|
70
|
+
* @return {boolean}
|
|
71
|
+
*/
|
|
72
|
+
function isDate(obj) {
|
|
73
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
74
|
+
return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
|
|
117
75
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
76
|
+
greg.isDate = isDate;
|
|
77
|
+
/**
|
|
78
|
+
* @private
|
|
79
|
+
* @param year
|
|
80
|
+
* @param month (1-12)
|
|
81
|
+
* @param day (1-31)
|
|
82
|
+
*/
|
|
83
|
+
function toFixed(year, month, day) {
|
|
84
|
+
const py = year - 1;
|
|
85
|
+
return (365 * py +
|
|
86
|
+
quotient(py, 4) -
|
|
87
|
+
quotient(py, 100) +
|
|
88
|
+
quotient(py, 400) +
|
|
89
|
+
quotient(367 * month - 362, 12) +
|
|
90
|
+
(month <= 2 ? 0 : isLeapYear(year) ? -1 : -2) +
|
|
91
|
+
day);
|
|
122
92
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
95
|
+
* @param {Date} date Gregorian date
|
|
96
|
+
* @return {number}
|
|
97
|
+
*/
|
|
98
|
+
function greg2abs(date) {
|
|
99
|
+
if (!isDate(date)) {
|
|
100
|
+
throw new TypeError(`Argument not a Date: ${date}`);
|
|
101
|
+
}
|
|
102
|
+
const abs = toFixed(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
103
|
+
/*
|
|
104
|
+
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
105
|
+
throw new RangeError(`Invalid Date: ${date}`);
|
|
106
|
+
}
|
|
107
|
+
*/
|
|
108
|
+
return abs;
|
|
109
|
+
}
|
|
110
|
+
greg.greg2abs = greg2abs;
|
|
111
|
+
/**
|
|
112
|
+
* Converts from Rata Die (R.D. number) to Gregorian date.
|
|
113
|
+
* See the footnote on page 384 of ``Calendrical Calculations, Part II:
|
|
114
|
+
* Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M.
|
|
115
|
+
* Clamen, Software--Practice and Experience, Volume 23, Number 4
|
|
116
|
+
* (April, 1993), pages 383-404 for an explanation.
|
|
117
|
+
* @param {number} abs - R.D. number of days
|
|
118
|
+
* @return {Date}
|
|
119
|
+
*/
|
|
120
|
+
function abs2greg(abs) {
|
|
121
|
+
if (typeof abs !== 'number') {
|
|
122
|
+
throw new TypeError(`Argument not a Number: ${abs}`);
|
|
123
|
+
}
|
|
124
|
+
abs = Math.trunc(abs);
|
|
125
|
+
/*
|
|
126
|
+
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
127
|
+
throw new RangeError(`Invalid Date: ${abs}`);
|
|
128
|
+
}
|
|
129
|
+
*/
|
|
130
|
+
const year = yearFromFixed(abs);
|
|
131
|
+
const priorDays = abs - toFixed(year, 1, 1);
|
|
132
|
+
const correction = abs < toFixed(year, 3, 1) ? 0 : isLeapYear(year) ? 1 : 2;
|
|
133
|
+
const month = quotient(12 * (priorDays + correction) + 373, 367);
|
|
134
|
+
const day = abs - toFixed(year, month, 1) + 1;
|
|
135
|
+
const dt = new Date(year, month - 1, day);
|
|
136
|
+
if (year < 100 && year >= 0) {
|
|
137
|
+
dt.setFullYear(year);
|
|
138
|
+
}
|
|
139
|
+
return dt;
|
|
140
|
+
}
|
|
141
|
+
greg.abs2greg = abs2greg;
|
|
136
142
|
})(exports.greg || (exports.greg = {}));
|
|
137
143
|
|
|
138
144
|
/*
|
|
@@ -157,40 +163,56 @@ const ADAR_II$2 = 13;
|
|
|
157
163
|
* @enum {number}
|
|
158
164
|
*/
|
|
159
165
|
const months = {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
166
|
+
/** Nissan / ניסן */
|
|
167
|
+
NISAN: 1,
|
|
168
|
+
/** Iyyar / אייר */
|
|
169
|
+
IYYAR: 2,
|
|
170
|
+
/** Sivan / סיון */
|
|
171
|
+
SIVAN: 3,
|
|
172
|
+
/** Tamuz (sometimes Tammuz) / תמוז */
|
|
173
|
+
TAMUZ: 4,
|
|
174
|
+
/** Av / אב */
|
|
175
|
+
AV: 5,
|
|
176
|
+
/** Elul / אלול */
|
|
177
|
+
ELUL: 6,
|
|
178
|
+
/** Tishrei / תִּשְׁרֵי */
|
|
179
|
+
TISHREI: 7,
|
|
180
|
+
/** Cheshvan / חשון */
|
|
181
|
+
CHESHVAN: 8,
|
|
182
|
+
/** Kislev / כסלו */
|
|
183
|
+
KISLEV: 9,
|
|
184
|
+
/** Tevet / טבת */
|
|
185
|
+
TEVET: 10,
|
|
186
|
+
/** Sh'vat / שבט */
|
|
187
|
+
SHVAT: 11,
|
|
188
|
+
/** Adar or Adar Rishon / אדר */
|
|
189
|
+
ADAR_I: 12,
|
|
190
|
+
/** Adar Sheini (only on leap years) / אדר ב׳ */
|
|
191
|
+
ADAR_II: 13,
|
|
186
192
|
};
|
|
187
|
-
const monthNames0 = [
|
|
193
|
+
const monthNames0 = [
|
|
194
|
+
'',
|
|
195
|
+
'Nisan',
|
|
196
|
+
'Iyyar',
|
|
197
|
+
'Sivan',
|
|
198
|
+
'Tamuz',
|
|
199
|
+
'Av',
|
|
200
|
+
'Elul',
|
|
201
|
+
'Tishrei',
|
|
202
|
+
'Cheshvan',
|
|
203
|
+
'Kislev',
|
|
204
|
+
'Tevet',
|
|
205
|
+
"Sh'vat",
|
|
206
|
+
];
|
|
188
207
|
/**
|
|
189
208
|
* Transliterations of Hebrew month names.
|
|
190
209
|
* Regular years are index 0 and leap years are index 1.
|
|
191
210
|
* @private
|
|
192
211
|
*/
|
|
193
|
-
const monthNames = [
|
|
212
|
+
const monthNames = [
|
|
213
|
+
monthNames0.concat(['Adar', 'Nisan']),
|
|
214
|
+
monthNames0.concat(['Adar I', 'Adar II', 'Nisan']),
|
|
215
|
+
];
|
|
194
216
|
const edCache = new Map();
|
|
195
217
|
const EPOCH = -1373428;
|
|
196
218
|
// Avg year length in the cycle (19 solar years with 235 lunar months)
|
|
@@ -199,9 +221,9 @@ const AVG_HEBYEAR_DAYS = 365.24682220597794;
|
|
|
199
221
|
* @private
|
|
200
222
|
*/
|
|
201
223
|
function assertNumber(n, name) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
224
|
+
if (typeof n !== 'number' || isNaN(n)) {
|
|
225
|
+
throw new TypeError(`invalid parameter '${name}' not a number: ${n}`);
|
|
226
|
+
}
|
|
205
227
|
}
|
|
206
228
|
/**
|
|
207
229
|
* Converts Hebrew date to R.D. (Rata Die) fixed days.
|
|
@@ -213,32 +235,33 @@ function assertNumber(n, name) {
|
|
|
213
235
|
* @return {number}
|
|
214
236
|
*/
|
|
215
237
|
function hebrew2abs(year, month, day) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
238
|
+
assertNumber(year, 'year');
|
|
239
|
+
assertNumber(month, 'month');
|
|
240
|
+
assertNumber(day, 'day');
|
|
241
|
+
if (year < 1) {
|
|
242
|
+
throw new RangeError(`hebrew2abs: invalid year ${year}`);
|
|
243
|
+
}
|
|
244
|
+
let tempabs = day;
|
|
245
|
+
if (month < TISHREI$2) {
|
|
246
|
+
for (let m = TISHREI$2; m <= monthsInYear(year); m++) {
|
|
247
|
+
tempabs += daysInMonth(m, year);
|
|
248
|
+
}
|
|
249
|
+
for (let m = NISAN$4; m < month; m++) {
|
|
250
|
+
tempabs += daysInMonth(m, year);
|
|
251
|
+
}
|
|
229
252
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
253
|
+
else {
|
|
254
|
+
for (let m = TISHREI$2; m < month; m++) {
|
|
255
|
+
tempabs += daysInMonth(m, year);
|
|
256
|
+
}
|
|
233
257
|
}
|
|
234
|
-
|
|
235
|
-
return EPOCH + elapsedDays(year) + tempabs - 1;
|
|
258
|
+
return EPOCH + elapsedDays(year) + tempabs - 1;
|
|
236
259
|
}
|
|
237
260
|
/**
|
|
238
261
|
* @private
|
|
239
262
|
*/
|
|
240
263
|
function newYear(year) {
|
|
241
|
-
|
|
264
|
+
return EPOCH + elapsedDays(year);
|
|
242
265
|
}
|
|
243
266
|
/**
|
|
244
267
|
* Converts absolute R.D. days to Hebrew date
|
|
@@ -246,27 +269,23 @@ function newYear(year) {
|
|
|
246
269
|
* @return {SimpleHebrewDate}
|
|
247
270
|
*/
|
|
248
271
|
function abs2hebrew(abs) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
yy: year,
|
|
267
|
-
mm: month,
|
|
268
|
-
dd: day
|
|
269
|
-
};
|
|
272
|
+
assertNumber(abs, 'abs');
|
|
273
|
+
abs = Math.trunc(abs);
|
|
274
|
+
if (abs <= EPOCH) {
|
|
275
|
+
throw new RangeError(`abs2hebrew: ${abs} is before epoch`);
|
|
276
|
+
}
|
|
277
|
+
// first, quickly approximate year
|
|
278
|
+
let year = Math.floor((abs - EPOCH) / AVG_HEBYEAR_DAYS);
|
|
279
|
+
while (newYear(year) <= abs) {
|
|
280
|
+
++year;
|
|
281
|
+
}
|
|
282
|
+
--year;
|
|
283
|
+
let month = abs < hebrew2abs(year, 1, 1) ? 7 : 1;
|
|
284
|
+
while (abs > hebrew2abs(year, month, daysInMonth(month, year))) {
|
|
285
|
+
++month;
|
|
286
|
+
}
|
|
287
|
+
const day = 1 + abs - hebrew2abs(year, month, 1);
|
|
288
|
+
return { yy: year, mm: month, dd: day };
|
|
270
289
|
}
|
|
271
290
|
/**
|
|
272
291
|
* Returns true if Hebrew year is a leap year
|
|
@@ -274,7 +293,7 @@ function abs2hebrew(abs) {
|
|
|
274
293
|
* @return {boolean}
|
|
275
294
|
*/
|
|
276
295
|
function isLeapYear(year) {
|
|
277
|
-
|
|
296
|
+
return (1 + year * 7) % 19 < 7;
|
|
278
297
|
}
|
|
279
298
|
/**
|
|
280
299
|
* Number of months in this Hebrew year (either 12 or 13 depending on leap year)
|
|
@@ -282,7 +301,7 @@ function isLeapYear(year) {
|
|
|
282
301
|
* @return {number}
|
|
283
302
|
*/
|
|
284
303
|
function monthsInYear(year) {
|
|
285
|
-
|
|
304
|
+
return 12 + +isLeapYear(year); // boolean is cast to 1 or 0
|
|
286
305
|
}
|
|
287
306
|
/**
|
|
288
307
|
* Number of days in Hebrew month in a given year (29 or 30)
|
|
@@ -291,19 +310,22 @@ function monthsInYear(year) {
|
|
|
291
310
|
* @return {number}
|
|
292
311
|
*/
|
|
293
312
|
function daysInMonth(month, year) {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
313
|
+
switch (month) {
|
|
314
|
+
case IYYAR$1:
|
|
315
|
+
case TAMUZ$1:
|
|
316
|
+
case ELUL$1:
|
|
317
|
+
case TEVET$2:
|
|
318
|
+
case ADAR_II$2:
|
|
319
|
+
return 29;
|
|
320
|
+
}
|
|
321
|
+
if ((month === ADAR_I$2 && !isLeapYear(year)) ||
|
|
322
|
+
(month === CHESHVAN$1 && !longCheshvan(year)) ||
|
|
323
|
+
(month === KISLEV$2 && shortKislev(year))) {
|
|
324
|
+
return 29;
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
return 30;
|
|
328
|
+
}
|
|
307
329
|
}
|
|
308
330
|
/**
|
|
309
331
|
* Returns a transliterated string name of Hebrew month in year,
|
|
@@ -312,12 +334,12 @@ function daysInMonth(month, year) {
|
|
|
312
334
|
* @param {number} year Hebrew year
|
|
313
335
|
*/
|
|
314
336
|
function getMonthName(month, year) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
337
|
+
assertNumber(month, 'month');
|
|
338
|
+
assertNumber(year, 'year');
|
|
339
|
+
if (month < 1 || month > 14) {
|
|
340
|
+
throw new TypeError(`bad month argument ${month}`);
|
|
341
|
+
}
|
|
342
|
+
return monthNames[+isLeapYear(year)][month];
|
|
321
343
|
}
|
|
322
344
|
/**
|
|
323
345
|
* Days from sunday prior to start of Hebrew calendar to mean
|
|
@@ -326,13 +348,13 @@ function getMonthName(month, year) {
|
|
|
326
348
|
* @return {number}
|
|
327
349
|
*/
|
|
328
350
|
function elapsedDays(year) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
351
|
+
const n = edCache.get(year);
|
|
352
|
+
if (typeof n === 'number') {
|
|
353
|
+
return n;
|
|
354
|
+
}
|
|
355
|
+
const elapsed = elapsedDays0(year);
|
|
356
|
+
edCache.set(year, elapsed);
|
|
357
|
+
return elapsed;
|
|
336
358
|
}
|
|
337
359
|
/**
|
|
338
360
|
* Days from sunday prior to start of Hebrew calendar to mean
|
|
@@ -341,25 +363,29 @@ function elapsedDays(year) {
|
|
|
341
363
|
* @param year Hebrew year
|
|
342
364
|
*/
|
|
343
365
|
function elapsedDays0(year) {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
366
|
+
const prevYear = year - 1;
|
|
367
|
+
const mElapsed = 235 * Math.floor(prevYear / 19) + // Months in complete 19 year lunar (Metonic) cycles so far
|
|
368
|
+
12 * (prevYear % 19) + // Regular months in this cycle
|
|
369
|
+
Math.floor(((prevYear % 19) * 7 + 1) / 19); // Leap months this cycle
|
|
370
|
+
const pElapsed = 204 + 793 * (mElapsed % 1080);
|
|
371
|
+
const hElapsed = 5 +
|
|
372
|
+
12 * mElapsed +
|
|
373
|
+
793 * Math.floor(mElapsed / 1080) +
|
|
374
|
+
Math.floor(pElapsed / 1080);
|
|
375
|
+
const parts = (pElapsed % 1080) + 1080 * (hElapsed % 24);
|
|
376
|
+
const day = 1 + 29 * mElapsed + Math.floor(hElapsed / 24);
|
|
377
|
+
let altDay = day;
|
|
378
|
+
if (parts >= 19440 ||
|
|
379
|
+
(2 === day % 7 && parts >= 9924 && !isLeapYear(year)) ||
|
|
380
|
+
(1 === day % 7 && parts >= 16789 && isLeapYear(prevYear))) {
|
|
381
|
+
altDay++;
|
|
382
|
+
}
|
|
383
|
+
if (altDay % 7 === 0 || altDay % 7 === 3 || altDay % 7 === 5) {
|
|
384
|
+
return altDay + 1;
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
return altDay;
|
|
388
|
+
}
|
|
363
389
|
}
|
|
364
390
|
/**
|
|
365
391
|
* Number of days in the hebrew YEAR.
|
|
@@ -369,7 +395,7 @@ function elapsedDays0(year) {
|
|
|
369
395
|
* @return {number}
|
|
370
396
|
*/
|
|
371
397
|
function daysInYear(year) {
|
|
372
|
-
|
|
398
|
+
return elapsedDays(year + 1) - elapsedDays(year);
|
|
373
399
|
}
|
|
374
400
|
/**
|
|
375
401
|
* true if Cheshvan is long in Hebrew year
|
|
@@ -377,7 +403,7 @@ function daysInYear(year) {
|
|
|
377
403
|
* @return {boolean}
|
|
378
404
|
*/
|
|
379
405
|
function longCheshvan(year) {
|
|
380
|
-
|
|
406
|
+
return daysInYear(year) % 10 === 5;
|
|
381
407
|
}
|
|
382
408
|
/**
|
|
383
409
|
* true if Kislev is short in Hebrew year
|
|
@@ -385,7 +411,7 @@ function longCheshvan(year) {
|
|
|
385
411
|
* @return {boolean}
|
|
386
412
|
*/
|
|
387
413
|
function shortKislev(year) {
|
|
388
|
-
|
|
414
|
+
return daysInYear(year) % 10 === 3;
|
|
389
415
|
}
|
|
390
416
|
/**
|
|
391
417
|
* Converts Hebrew month string name to numeric
|
|
@@ -393,116 +419,116 @@ function shortKislev(year) {
|
|
|
393
419
|
* @return {number}
|
|
394
420
|
*/
|
|
395
421
|
function monthFromName(monthName) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
return months.IYYAR;
|
|
437
|
-
case 'e':
|
|
438
|
-
return months.ELUL;
|
|
439
|
-
case 'c':
|
|
440
|
-
case 'ח':
|
|
441
|
-
return months.CHESHVAN;
|
|
442
|
-
case 'k':
|
|
443
|
-
case 'כ':
|
|
444
|
-
return months.KISLEV;
|
|
445
|
-
case 's':
|
|
446
|
-
switch (c[1]) {
|
|
447
|
-
case 'i':
|
|
448
|
-
return months.SIVAN;
|
|
449
|
-
case 'h':
|
|
450
|
-
return months.SHVAT;
|
|
451
|
-
}
|
|
452
|
-
break;
|
|
453
|
-
case 't':
|
|
454
|
-
switch (c[1]) {
|
|
455
|
-
case 'a':
|
|
456
|
-
return months.TAMUZ;
|
|
422
|
+
if (typeof monthName === 'number') {
|
|
423
|
+
if (isNaN(monthName) || monthName < 1 || monthName > 14) {
|
|
424
|
+
throw new RangeError(`Invalid month name: ${monthName}`);
|
|
425
|
+
}
|
|
426
|
+
return monthName;
|
|
427
|
+
}
|
|
428
|
+
let c = monthName.trim().toLowerCase();
|
|
429
|
+
// If Hebrew month starts with a bet (for example `בתמוז`) then ignore it
|
|
430
|
+
if (c[0] === 'ב') {
|
|
431
|
+
c = c.substring(1);
|
|
432
|
+
}
|
|
433
|
+
/*
|
|
434
|
+
the Hebrew months are unique to their second letter
|
|
435
|
+
N Nisan (November?)
|
|
436
|
+
I Iyyar
|
|
437
|
+
E Elul
|
|
438
|
+
C Cheshvan
|
|
439
|
+
K Kislev
|
|
440
|
+
1 1Adar
|
|
441
|
+
2 2Adar
|
|
442
|
+
Si Sh Sivan, Shvat
|
|
443
|
+
Ta Ti Te Tamuz, Tishrei, Tevet
|
|
444
|
+
Av Ad Av, Adar
|
|
445
|
+
|
|
446
|
+
אב אד אי אל אב אדר אייר אלול
|
|
447
|
+
ח חשון
|
|
448
|
+
ט טבת
|
|
449
|
+
כ כסלו
|
|
450
|
+
נ ניסן
|
|
451
|
+
ס סיון
|
|
452
|
+
ש שבט
|
|
453
|
+
תמ תש תמוז תשרי
|
|
454
|
+
*/
|
|
455
|
+
switch (c[0]) {
|
|
456
|
+
case 'n':
|
|
457
|
+
case 'נ':
|
|
458
|
+
if (c[1] === 'o') {
|
|
459
|
+
break; /* this catches "november" */
|
|
460
|
+
}
|
|
461
|
+
return months.NISAN;
|
|
457
462
|
case 'i':
|
|
458
|
-
|
|
463
|
+
return months.IYYAR;
|
|
459
464
|
case 'e':
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
case '
|
|
466
|
-
|
|
467
|
-
case '
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
case '
|
|
499
|
-
|
|
465
|
+
return months.ELUL;
|
|
466
|
+
case 'c':
|
|
467
|
+
case 'ח':
|
|
468
|
+
return months.CHESHVAN;
|
|
469
|
+
case 'k':
|
|
470
|
+
case 'כ':
|
|
471
|
+
return months.KISLEV;
|
|
472
|
+
case 's':
|
|
473
|
+
switch (c[1]) {
|
|
474
|
+
case 'i':
|
|
475
|
+
return months.SIVAN;
|
|
476
|
+
case 'h':
|
|
477
|
+
return months.SHVAT;
|
|
478
|
+
}
|
|
479
|
+
break;
|
|
480
|
+
case 't':
|
|
481
|
+
switch (c[1]) {
|
|
482
|
+
case 'a':
|
|
483
|
+
return months.TAMUZ;
|
|
484
|
+
case 'i':
|
|
485
|
+
return months.TISHREI;
|
|
486
|
+
case 'e':
|
|
487
|
+
return months.TEVET;
|
|
488
|
+
}
|
|
489
|
+
break;
|
|
490
|
+
case 'a':
|
|
491
|
+
switch (c[1]) {
|
|
492
|
+
case 'v':
|
|
493
|
+
return months.AV;
|
|
494
|
+
case 'd':
|
|
495
|
+
if (/(1|[^i]i|a|א)$/i.test(monthName)) {
|
|
496
|
+
return months.ADAR_I;
|
|
497
|
+
}
|
|
498
|
+
return months.ADAR_II; // else assume sheini
|
|
499
|
+
}
|
|
500
|
+
break;
|
|
501
|
+
case 'ס':
|
|
502
|
+
return months.SIVAN;
|
|
503
|
+
case 'ט':
|
|
504
|
+
return months.TEVET;
|
|
500
505
|
case 'ש':
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
+
return months.SHVAT;
|
|
507
|
+
case 'א':
|
|
508
|
+
switch (c[1]) {
|
|
509
|
+
case 'ב':
|
|
510
|
+
return months.AV;
|
|
511
|
+
case 'ד':
|
|
512
|
+
if (/(1|[^i]i|a|א)$/i.test(monthName)) {
|
|
513
|
+
return months.ADAR_I;
|
|
514
|
+
}
|
|
515
|
+
return months.ADAR_II; // else assume sheini
|
|
516
|
+
case 'י':
|
|
517
|
+
return months.IYYAR;
|
|
518
|
+
case 'ל':
|
|
519
|
+
return months.ELUL;
|
|
520
|
+
}
|
|
521
|
+
break;
|
|
522
|
+
case 'ת':
|
|
523
|
+
switch (c[1]) {
|
|
524
|
+
case 'מ':
|
|
525
|
+
return months.TAMUZ;
|
|
526
|
+
case 'ש':
|
|
527
|
+
return months.TISHREI;
|
|
528
|
+
}
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
throw new RangeError(`Unable to parse month name: ${monthName}`);
|
|
506
532
|
}
|
|
507
533
|
|
|
508
534
|
const NISAN$3 = months.NISAN;
|
|
@@ -518,140 +544,158 @@ const ADAR_II$1 = months.ADAR_II;
|
|
|
518
544
|
* @param {Object} obj
|
|
519
545
|
*/
|
|
520
546
|
function isSimpleHebrewDate(obj) {
|
|
521
|
-
|
|
547
|
+
return (typeof obj === 'object' &&
|
|
548
|
+
obj !== null &&
|
|
549
|
+
typeof obj.yy === 'number' &&
|
|
550
|
+
typeof obj.mm === 'number' &&
|
|
551
|
+
typeof obj.dd === 'number');
|
|
522
552
|
}
|
|
523
553
|
/**
|
|
524
554
|
* @private
|
|
525
555
|
*/
|
|
526
556
|
function toSimpleHebrewDate(obj) {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
557
|
+
if (isSimpleHebrewDate(obj)) {
|
|
558
|
+
return obj;
|
|
559
|
+
}
|
|
560
|
+
else if (typeof obj === 'number') {
|
|
561
|
+
return abs2hebrew(obj);
|
|
562
|
+
}
|
|
563
|
+
else if (exports.greg.isDate(obj)) {
|
|
564
|
+
const abs = exports.greg.greg2abs(obj);
|
|
565
|
+
return abs2hebrew(abs);
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
throw new TypeError(`Argument not a Date: ${obj}`);
|
|
569
|
+
}
|
|
537
570
|
}
|
|
538
571
|
function getYahrzeitHD(hyear, date) {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
hDeath.
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
+
let hDeath = toSimpleHebrewDate(date);
|
|
573
|
+
if (hyear <= hDeath.yy) {
|
|
574
|
+
// Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
|
|
575
|
+
return undefined;
|
|
576
|
+
}
|
|
577
|
+
if (hDeath.mm === CHESHVAN &&
|
|
578
|
+
hDeath.dd === 30 &&
|
|
579
|
+
!longCheshvan(hDeath.yy + 1)) {
|
|
580
|
+
// If it's Heshvan 30 it depends on the first anniversary;
|
|
581
|
+
// if that was not Heshvan 30, use the day before Kislev 1.
|
|
582
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, KISLEV$1, 1) - 1);
|
|
583
|
+
}
|
|
584
|
+
else if (hDeath.mm === KISLEV$1 &&
|
|
585
|
+
hDeath.dd === 30 &&
|
|
586
|
+
shortKislev(hDeath.yy + 1)) {
|
|
587
|
+
// If it's Kislev 30 it depends on the first anniversary;
|
|
588
|
+
// if that was not Kislev 30, use the day before Teveth 1.
|
|
589
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
|
|
590
|
+
}
|
|
591
|
+
else if (hDeath.mm === ADAR_II$1) {
|
|
592
|
+
// If it's Adar II, use the same day in last month of year (Adar or Adar II).
|
|
593
|
+
hDeath.mm = monthsInYear(hyear);
|
|
594
|
+
}
|
|
595
|
+
else if (hDeath.mm === ADAR_I$1 && hDeath.dd === 30 && !isLeapYear(hyear)) {
|
|
596
|
+
// If it's the 30th in Adar I and year is not a leap year
|
|
597
|
+
// (so Adar has only 29 days), use the last day in Shevat.
|
|
598
|
+
hDeath.dd = 30;
|
|
599
|
+
hDeath.mm = SHVAT;
|
|
600
|
+
}
|
|
601
|
+
// In all other cases, use the normal anniversary of the date of death.
|
|
602
|
+
// advance day to rosh chodesh if needed
|
|
603
|
+
if (hDeath.mm === CHESHVAN && hDeath.dd === 30 && !longCheshvan(hyear)) {
|
|
604
|
+
hDeath.mm = KISLEV$1;
|
|
605
|
+
hDeath.dd = 1;
|
|
606
|
+
}
|
|
607
|
+
else if (hDeath.mm === KISLEV$1 && hDeath.dd === 30 && shortKislev(hyear)) {
|
|
608
|
+
hDeath.mm = TEVET$1;
|
|
609
|
+
hDeath.dd = 1;
|
|
610
|
+
}
|
|
611
|
+
hDeath.yy = hyear;
|
|
612
|
+
return hDeath;
|
|
572
613
|
}
|
|
573
614
|
function getBirthdayHD(hyear, date) {
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
month
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
day
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
615
|
+
const orig = toSimpleHebrewDate(date);
|
|
616
|
+
const origYear = orig.yy;
|
|
617
|
+
if (hyear === origYear) {
|
|
618
|
+
return orig;
|
|
619
|
+
}
|
|
620
|
+
else if (hyear < origYear) {
|
|
621
|
+
// Hebrew year ${hyear} occurs on or before original date in ${origYear}
|
|
622
|
+
return undefined;
|
|
623
|
+
}
|
|
624
|
+
const isOrigLeap = isLeapYear(origYear);
|
|
625
|
+
let month = orig.mm;
|
|
626
|
+
let day = orig.dd;
|
|
627
|
+
if ((month === ADAR_I$1 && !isOrigLeap) || (month === ADAR_II$1 && isOrigLeap)) {
|
|
628
|
+
month = monthsInYear(hyear);
|
|
629
|
+
}
|
|
630
|
+
else if (month === CHESHVAN && day === 30 && !longCheshvan(hyear)) {
|
|
631
|
+
month = KISLEV$1;
|
|
632
|
+
day = 1;
|
|
633
|
+
}
|
|
634
|
+
else if (month === KISLEV$1 && day === 30 && shortKislev(hyear)) {
|
|
635
|
+
month = TEVET$1;
|
|
636
|
+
day = 1;
|
|
637
|
+
}
|
|
638
|
+
else if (month === ADAR_I$1 &&
|
|
639
|
+
day === 30 &&
|
|
640
|
+
isOrigLeap &&
|
|
641
|
+
!isLeapYear(hyear)) {
|
|
642
|
+
month = NISAN$3;
|
|
643
|
+
day = 1;
|
|
644
|
+
}
|
|
645
|
+
return { yy: hyear, mm: month, dd: day };
|
|
602
646
|
}
|
|
603
647
|
|
|
604
648
|
const GERESH = '׳';
|
|
605
649
|
const GERSHAYIM = '״';
|
|
606
650
|
const alefbet = {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
651
|
+
א: 1,
|
|
652
|
+
ב: 2,
|
|
653
|
+
ג: 3,
|
|
654
|
+
ד: 4,
|
|
655
|
+
ה: 5,
|
|
656
|
+
ו: 6,
|
|
657
|
+
ז: 7,
|
|
658
|
+
ח: 8,
|
|
659
|
+
ט: 9,
|
|
660
|
+
י: 10,
|
|
661
|
+
כ: 20,
|
|
662
|
+
ל: 30,
|
|
663
|
+
מ: 40,
|
|
664
|
+
נ: 50,
|
|
665
|
+
ס: 60,
|
|
666
|
+
ע: 70,
|
|
667
|
+
פ: 80,
|
|
668
|
+
צ: 90,
|
|
669
|
+
ק: 100,
|
|
670
|
+
ר: 200,
|
|
671
|
+
ש: 300,
|
|
672
|
+
ת: 400,
|
|
629
673
|
};
|
|
630
674
|
const heb2num = new Map();
|
|
631
675
|
const num2heb = new Map();
|
|
632
676
|
for (const [key, val] of Object.entries(alefbet)) {
|
|
633
|
-
|
|
634
|
-
|
|
677
|
+
heb2num.set(key, val);
|
|
678
|
+
num2heb.set(val, key);
|
|
635
679
|
}
|
|
636
680
|
function num2digits(num) {
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
681
|
+
const digits = [];
|
|
682
|
+
while (num > 0) {
|
|
683
|
+
if (num === 15 || num === 16) {
|
|
684
|
+
digits.push(9);
|
|
685
|
+
digits.push(num - 9);
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
688
|
+
let incr = 100;
|
|
689
|
+
let i;
|
|
690
|
+
for (i = 400; i > num; i -= incr) {
|
|
691
|
+
if (i === incr) {
|
|
692
|
+
incr = incr / 10;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
digits.push(i);
|
|
696
|
+
num -= i;
|
|
650
697
|
}
|
|
651
|
-
digits
|
|
652
|
-
num -= i;
|
|
653
|
-
}
|
|
654
|
-
return digits;
|
|
698
|
+
return digits;
|
|
655
699
|
}
|
|
656
700
|
/**
|
|
657
701
|
* Converts a numerical value to a string of Hebrew letters.
|
|
@@ -668,31 +712,31 @@ function num2digits(num) {
|
|
|
668
712
|
* @return {string}
|
|
669
713
|
*/
|
|
670
714
|
function gematriya(num) {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
715
|
+
const num0 = num;
|
|
716
|
+
const num1 = parseInt(num0, 10);
|
|
717
|
+
if (!num1) {
|
|
718
|
+
throw new TypeError(`invalid parameter to gematriya ${num}`);
|
|
719
|
+
}
|
|
720
|
+
let str = '';
|
|
721
|
+
const thousands = Math.floor(num1 / 1000);
|
|
722
|
+
if (thousands > 0 && thousands !== 5) {
|
|
723
|
+
const tdigits = num2digits(thousands);
|
|
724
|
+
for (const tdig of tdigits) {
|
|
725
|
+
str += num2heb.get(tdig);
|
|
726
|
+
}
|
|
727
|
+
str += GERESH;
|
|
682
728
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
if (digits.length === 1) {
|
|
687
|
-
return str + num2heb.get(digits[0]) + GERESH;
|
|
688
|
-
}
|
|
689
|
-
for (let i = 0; i < digits.length; i++) {
|
|
690
|
-
if (i + 1 === digits.length) {
|
|
691
|
-
str += GERSHAYIM;
|
|
729
|
+
const digits = num2digits(num1 % 1000);
|
|
730
|
+
if (digits.length === 1) {
|
|
731
|
+
return str + num2heb.get(digits[0]) + GERESH;
|
|
692
732
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
733
|
+
for (let i = 0; i < digits.length; i++) {
|
|
734
|
+
if (i + 1 === digits.length) {
|
|
735
|
+
str += GERSHAYIM;
|
|
736
|
+
}
|
|
737
|
+
str += num2heb.get(digits[i]);
|
|
738
|
+
}
|
|
739
|
+
return str;
|
|
696
740
|
}
|
|
697
741
|
/**
|
|
698
742
|
* Converts a string of Hebrew letters to a numerical value.
|
|
@@ -705,48 +749,75 @@ function gematriya(num) {
|
|
|
705
749
|
* @return {number}
|
|
706
750
|
*/
|
|
707
751
|
function gematriyaStrToNum(str) {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
752
|
+
let num = 0;
|
|
753
|
+
const gereshIdx = str.indexOf(GERESH);
|
|
754
|
+
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
|
|
755
|
+
const thousands = str.substring(0, gereshIdx);
|
|
756
|
+
num += gematriyaStrToNum(thousands) * 1000;
|
|
757
|
+
str = str.substring(gereshIdx);
|
|
758
|
+
}
|
|
759
|
+
for (const ch of str) {
|
|
760
|
+
const n = heb2num.get(ch);
|
|
761
|
+
if (typeof n === 'number') {
|
|
762
|
+
num += n;
|
|
763
|
+
}
|
|
719
764
|
}
|
|
720
|
-
|
|
721
|
-
return num;
|
|
765
|
+
return num;
|
|
722
766
|
}
|
|
723
767
|
|
|
724
768
|
const sefirot = {
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
769
|
+
en: {
|
|
770
|
+
infix: 'within ',
|
|
771
|
+
infix26: 'within ',
|
|
772
|
+
words: [
|
|
773
|
+
'',
|
|
774
|
+
'Lovingkindness',
|
|
775
|
+
'Might',
|
|
776
|
+
'Beauty',
|
|
777
|
+
'Eternity',
|
|
778
|
+
'Splendor',
|
|
779
|
+
'Foundation',
|
|
780
|
+
'Majesty',
|
|
781
|
+
],
|
|
782
|
+
},
|
|
783
|
+
he: {
|
|
784
|
+
infix: 'שֶׁבְּ',
|
|
785
|
+
infix26: 'שֶׁבִּ',
|
|
786
|
+
words: [
|
|
787
|
+
'',
|
|
788
|
+
'חֶֽסֶד',
|
|
789
|
+
'גְבוּרָה',
|
|
790
|
+
'תִּפאֶרֶת',
|
|
791
|
+
'נֶּֽצַח',
|
|
792
|
+
'הוֹד',
|
|
793
|
+
'יְּסוֹד',
|
|
794
|
+
'מַּלְכוּת',
|
|
795
|
+
],
|
|
796
|
+
},
|
|
797
|
+
translit: {
|
|
798
|
+
infix: "sheb'",
|
|
799
|
+
infix26: 'shebi',
|
|
800
|
+
words: [
|
|
801
|
+
'',
|
|
802
|
+
'Chesed',
|
|
803
|
+
'Gevurah',
|
|
804
|
+
'Tiferet',
|
|
805
|
+
'Netzach',
|
|
806
|
+
'Hod',
|
|
807
|
+
'Yesod',
|
|
808
|
+
'Malkhut',
|
|
809
|
+
],
|
|
810
|
+
},
|
|
740
811
|
};
|
|
741
812
|
function checkDay(omerDay) {
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
813
|
+
if (omerDay < 1 || omerDay > 49) {
|
|
814
|
+
throw new RangeError(`Invalid Omer day ${omerDay}`);
|
|
815
|
+
}
|
|
745
816
|
}
|
|
746
817
|
function getWeeks(omerDay) {
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
818
|
+
const weekNum = Math.floor((omerDay - 1) / 7) + 1;
|
|
819
|
+
const daysWithinWeeks = omerDay % 7 || 7;
|
|
820
|
+
return [weekNum, daysWithinWeeks];
|
|
750
821
|
}
|
|
751
822
|
/**
|
|
752
823
|
* Returns the sefira. For example, on day 8
|
|
@@ -758,13 +829,13 @@ function getWeeks(omerDay) {
|
|
|
758
829
|
* @returns a string such as `Lovingkindness within Might` or `חֶֽסֶד שֶׁבִּגְבוּרָה`
|
|
759
830
|
*/
|
|
760
831
|
function omerSefira(omerDay, lang) {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
832
|
+
checkDay(omerDay);
|
|
833
|
+
const [weekNum, daysWithinWeeks] = getWeeks(omerDay);
|
|
834
|
+
const config = sefirot[lang];
|
|
835
|
+
const week = config.words[weekNum];
|
|
836
|
+
const dayWithinWeek = config.words[daysWithinWeeks];
|
|
837
|
+
const infix = weekNum === 2 || weekNum === 6 ? config.infix26 : config.infix;
|
|
838
|
+
return (dayWithinWeek + ' ' + infix + week).normalize();
|
|
768
839
|
}
|
|
769
840
|
/**
|
|
770
841
|
* Returns a sentence with that evening's omer count
|
|
@@ -774,35 +845,48 @@ function omerSefira(omerDay, lang) {
|
|
|
774
845
|
* or `הַיוֹם עֲשָׂרָה יָמִים, שְׁהֵם שָׁבוּעַ אֶחָד וְשְׁלוֹשָׁה יָמִים לָעוֹמֶר`
|
|
775
846
|
*/
|
|
776
847
|
function omerTodayIs(omerDay, lang) {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
848
|
+
checkDay(omerDay);
|
|
849
|
+
if (lang === 'en') {
|
|
850
|
+
return omerTodayIsEn(omerDay);
|
|
851
|
+
}
|
|
852
|
+
else if (lang === 'he') {
|
|
853
|
+
return omerTodayIsHe(omerDay);
|
|
854
|
+
}
|
|
855
|
+
else {
|
|
856
|
+
return undefined;
|
|
857
|
+
}
|
|
785
858
|
}
|
|
786
859
|
function omerTodayIsEn(omerDay) {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
860
|
+
const [weekNumber, daysWithinWeeks] = getWeeks(omerDay);
|
|
861
|
+
const totalDaysStr = omerDay === 1 ? 'day' : 'days';
|
|
862
|
+
let str = `Today is ${omerDay} ${totalDaysStr}`;
|
|
863
|
+
if (weekNumber > 1 || omerDay === 7) {
|
|
864
|
+
const day7 = daysWithinWeeks === 7;
|
|
865
|
+
const numWeeks = day7 ? weekNumber : weekNumber - 1;
|
|
866
|
+
const weeksStr = numWeeks === 1 ? 'week' : 'weeks';
|
|
867
|
+
str += `, which is ${numWeeks} ${weeksStr}`;
|
|
868
|
+
if (!day7) {
|
|
869
|
+
const daysStr = daysWithinWeeks === 1 ? 'day' : 'days';
|
|
870
|
+
str += ` and ${daysWithinWeeks} ${daysStr}`;
|
|
871
|
+
}
|
|
798
872
|
}
|
|
799
|
-
|
|
800
|
-
return str + ' of the Omer';
|
|
873
|
+
return str + ' of the Omer';
|
|
801
874
|
}
|
|
802
875
|
// adapted from pip hdate package (GPL)
|
|
803
876
|
// https://github.com/py-libhdate/py-libhdate/blob/master/hdate/date.py
|
|
804
877
|
const tens = ['', 'עֲשָׂרָה', 'עֶשְׂרִים', 'שְׁלוֹשִׁים', 'אַרְבָּעִים'];
|
|
805
|
-
const ones = [
|
|
878
|
+
const ones = [
|
|
879
|
+
'',
|
|
880
|
+
'אֶחָד',
|
|
881
|
+
'שְׁנַיִם',
|
|
882
|
+
'שְׁלוֹשָׁה',
|
|
883
|
+
'אַרְבָּעָה',
|
|
884
|
+
'חֲמִשָּׁה',
|
|
885
|
+
'שִׁשָּׁה',
|
|
886
|
+
'שִׁבְעָה',
|
|
887
|
+
'שְׁמוֹנָה',
|
|
888
|
+
'תִּשְׁעָה',
|
|
889
|
+
];
|
|
806
890
|
const shnei = 'שְׁנֵי';
|
|
807
891
|
const yamim = 'יָמִים';
|
|
808
892
|
const shneiYamim = shnei + ' ' + yamim;
|
|
@@ -810,66 +894,76 @@ const shavuot = 'שָׁבוּעוֹת';
|
|
|
810
894
|
const yom = 'יוֹם';
|
|
811
895
|
const yomEchad = yom + ' ' + ones[1];
|
|
812
896
|
function omerTodayIsHe(omerDay) {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
if (omerDay > 2) {
|
|
826
|
-
if (omerDay > 20 || omerDay === 10 || omerDay === 20) {
|
|
827
|
-
str += tens[ten];
|
|
828
|
-
}
|
|
829
|
-
if (omerDay < 11) {
|
|
830
|
-
str += ones[one] + ' ' + yamim + ' ';
|
|
831
|
-
} else {
|
|
832
|
-
str += ' ' + yom + ' ';
|
|
897
|
+
const ten = Math.floor(omerDay / 10);
|
|
898
|
+
const one = omerDay % 10;
|
|
899
|
+
let str = 'הַיּוֹם ';
|
|
900
|
+
if (10 < omerDay && omerDay < 20) {
|
|
901
|
+
str += ones[one] + ' עָשָׂר';
|
|
902
|
+
}
|
|
903
|
+
else if (omerDay > 9) {
|
|
904
|
+
str += ones[one];
|
|
905
|
+
if (one) {
|
|
906
|
+
str += ' ';
|
|
907
|
+
str += ten === 3 ? 'וּ' : 'וְ';
|
|
908
|
+
}
|
|
833
909
|
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
if (
|
|
846
|
-
str += ones[weeks] + ' ' + shavuot + ' ';
|
|
847
|
-
} else if (weeks === 1) {
|
|
848
|
-
str += 'שָׁבֽוּעַ' + ' ' + ones[1] + ' ';
|
|
849
|
-
} else {
|
|
850
|
-
// weeks == 2
|
|
851
|
-
str += shnei + ' ' + shavuot + ' ';
|
|
852
|
-
}
|
|
853
|
-
if (days) {
|
|
854
|
-
if (days === 2 || days === 3) {
|
|
855
|
-
str += 'וּ';
|
|
856
|
-
} else if (days === 5) {
|
|
857
|
-
str += 'וַ';
|
|
858
|
-
} else {
|
|
859
|
-
str += 'וְ';
|
|
860
|
-
}
|
|
861
|
-
if (days > 2) {
|
|
862
|
-
str += ones[days] + ' ' + yamim + ' ';
|
|
863
|
-
} else if (days === 1) {
|
|
910
|
+
if (omerDay > 2) {
|
|
911
|
+
if (omerDay > 20 || omerDay === 10 || omerDay === 20) {
|
|
912
|
+
str += tens[ten];
|
|
913
|
+
}
|
|
914
|
+
if (omerDay < 11) {
|
|
915
|
+
str += ones[one] + ' ' + yamim + ' ';
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
str += ' ' + yom + ' ';
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
else if (omerDay === 1) {
|
|
864
922
|
str += yomEchad + ' ';
|
|
865
|
-
|
|
866
|
-
|
|
923
|
+
}
|
|
924
|
+
else {
|
|
925
|
+
// omer == 2
|
|
867
926
|
str += shneiYamim + ' ';
|
|
868
|
-
}
|
|
869
927
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
928
|
+
if (omerDay > 6) {
|
|
929
|
+
str = str.trim(); // remove trailing space before comma
|
|
930
|
+
str += ', שְׁהֵם ';
|
|
931
|
+
const weeks = Math.floor(omerDay / 7);
|
|
932
|
+
const days = omerDay % 7;
|
|
933
|
+
if (weeks > 2) {
|
|
934
|
+
str += ones[weeks] + ' ' + shavuot + ' ';
|
|
935
|
+
}
|
|
936
|
+
else if (weeks === 1) {
|
|
937
|
+
str += 'שָׁבֽוּעַ' + ' ' + ones[1] + ' ';
|
|
938
|
+
}
|
|
939
|
+
else {
|
|
940
|
+
// weeks == 2
|
|
941
|
+
str += shnei + ' ' + shavuot + ' ';
|
|
942
|
+
}
|
|
943
|
+
if (days) {
|
|
944
|
+
if (days === 2 || days === 3) {
|
|
945
|
+
str += 'וּ';
|
|
946
|
+
}
|
|
947
|
+
else if (days === 5) {
|
|
948
|
+
str += 'וַ';
|
|
949
|
+
}
|
|
950
|
+
else {
|
|
951
|
+
str += 'וְ';
|
|
952
|
+
}
|
|
953
|
+
if (days > 2) {
|
|
954
|
+
str += ones[days] + ' ' + yamim + ' ';
|
|
955
|
+
}
|
|
956
|
+
else if (days === 1) {
|
|
957
|
+
str += yomEchad + ' ';
|
|
958
|
+
}
|
|
959
|
+
else {
|
|
960
|
+
// days == 2
|
|
961
|
+
str += shneiYamim + ' ';
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
str += 'לָעֽוֹמֶר';
|
|
966
|
+
return str.normalize();
|
|
873
967
|
}
|
|
874
968
|
/**
|
|
875
969
|
* Returns an emoji number symbol with a circle, for example `㊲`
|
|
@@ -878,16 +972,18 @@ function omerTodayIsHe(omerDay) {
|
|
|
878
972
|
* @returns a single Unicode character from `①` through `㊾`
|
|
879
973
|
*/
|
|
880
974
|
function omerEmoji(omerDay) {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
975
|
+
checkDay(omerDay);
|
|
976
|
+
if (omerDay <= 20) {
|
|
977
|
+
return String.fromCodePoint(9312 + omerDay - 1);
|
|
978
|
+
}
|
|
979
|
+
else if (omerDay <= 35) {
|
|
980
|
+
// between 21 and 35 inclusive
|
|
981
|
+
return String.fromCodePoint(12881 + omerDay - 21);
|
|
982
|
+
}
|
|
983
|
+
else {
|
|
984
|
+
// between 36 and 49 inclusive
|
|
985
|
+
return String.fromCodePoint(12977 + omerDay - 36);
|
|
986
|
+
}
|
|
891
987
|
}
|
|
892
988
|
|
|
893
989
|
const noopLocale = {
|
|
@@ -10355,7 +10451,7 @@ class DailyLearning {
|
|
|
10355
10451
|
}
|
|
10356
10452
|
|
|
10357
10453
|
// DO NOT EDIT THIS AUTO-GENERATED FILE!
|
|
10358
|
-
const version = '5.3.
|
|
10454
|
+
const version = '5.3.5';
|
|
10359
10455
|
|
|
10360
10456
|
const NONE$1 = 0;
|
|
10361
10457
|
const HALF = 1;
|