UNPKG

@hebcal/core

Version:

A perpetual Jewish Calendar API

304 lines (301 loc) 9.6 kB
/*! @hebcal/core v5.10.1, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */ import { Locale, gematriya } from '@hebcal/hdate'; import { Event, flags } from './event.js'; import './locale.js'; const sefirot = { en: { infix: 'within ', infix26: 'within ', words: [ '', 'Lovingkindness', 'Might', 'Beauty', 'Eternity', 'Splendor', 'Foundation', 'Majesty', ], pfxWords: null, }, he: { infix: null, infix26: null, words: [ '', 'חֶֽסֶד', 'גְּבוּרָה', 'תִּפְאֶֽרֶת', 'נֶּֽצַח', 'הוֹד', 'יְּסוֹד', 'מַלְכוּת', ], pfxWords: [ '', 'שֶׁבְּחֶֽסֶד', 'שֶׁבִּגְבוּרָה', 'שֶׁבְּתִפְאֶֽרֶת', 'שֶׁבְּנֶֽצַח', 'שֶׁבְּהוֹד', 'שֶׁבִּיְסוֹד', 'שֶׁבְּמַלְכוּת', ], }, translit: { infix: "sheb'", infix26: 'shebi', words: [ '', 'Chesed', 'Gevurah', 'Tiferet', 'Netzach', 'Hod', 'Yesod', 'Malkhut', ], pfxWords: null, }, }; function checkDay(omerDay) { if (omerDay < 1 || omerDay > 49) { throw new RangeError(`Invalid Omer day ${omerDay}`); } } function getWeeks(omerDay) { const weekNum = Math.floor((omerDay - 1) / 7) + 1; const daysWithinWeeks = omerDay % 7 || 7; return [weekNum, daysWithinWeeks]; } function omerTodayIsEn(omerDay) { const [weekNumber, daysWithinWeeks] = getWeeks(omerDay); const totalDaysStr = omerDay === 1 ? 'day' : 'days'; let str = `Today is ${omerDay} ${totalDaysStr}`; if (weekNumber > 1 || omerDay === 7) { const day7 = daysWithinWeeks === 7; const numWeeks = day7 ? weekNumber : weekNumber - 1; const weeksStr = numWeeks === 1 ? 'week' : 'weeks'; str += `, which is ${numWeeks} ${weeksStr}`; if (!day7) { const daysStr = daysWithinWeeks === 1 ? 'day' : 'days'; str += ` and ${daysWithinWeeks} ${daysStr}`; } } return str + ' of the Omer'; } // adapted from pip hdate package (GPL) // https://github.com/py-libhdate/py-libhdate/blob/master/hdate/date.py const tens = ['', 'עֲשָׂרָה', 'עֶשְׂרִים', 'שְׁלוֹשִׁים', 'אַרְבָּעִים']; const ones = [ '', 'אֶחָד', 'שְׁנַיִם', 'שְׁלוֹשָׁה', 'אַרְבָּעָה', 'חֲמִשָּׁה', 'שִׁשָּׁה', 'שִׁבְעָה', 'שְׁמוֹנָה', 'תִּשְׁעָה', ]; const shnei = 'שְׁנֵי'; const yamim = 'יָמִים'; const shneiYamim = shnei + ' ' + yamim; const shavuot = 'שָׁבוּעוֹת'; const yom = 'יוֹם'; const yomEchad = yom + ' ' + ones[1]; const asar = 'עָשָׂר'; function omerTodayIsHe(omerDay) { const ten = Math.floor(omerDay / 10); const one = omerDay % 10; let str = 'הַיּוֹם '; if (omerDay === 11) { str += 'אַחַד ' + asar; } else if (omerDay === 12) { str += 'שְׁנֵים ' + asar; } else if (12 < omerDay && omerDay < 20) { str += ones[one] + ' ' + asar; } else if (omerDay > 9) { str += ones[one]; if (one) { str += ' '; str += ten === 3 ? 'וּ' : 'וְ'; } } if (omerDay > 2) { if (omerDay > 20 || omerDay === 10 || omerDay === 20) { str += tens[ten]; } if (omerDay < 11) { str += ones[one] + ' ' + yamim + ' '; } else { str += ' ' + yom + ' '; } } else if (omerDay === 1) { str += yomEchad + ' '; } else { // omer == 2 str += shneiYamim + ' '; } if (omerDay > 6) { str = str.trim(); // remove trailing space before comma str += ', שֶׁהֵם '; const weeks = Math.floor(omerDay / 7); const days = omerDay % 7; if (weeks > 2) { str += ones[weeks] + ' ' + shavuot + ' '; } else if (weeks === 1) { str += 'שָׁבֽוּעַ' + ' ' + ones[1] + ' '; } else { // weeks == 2 str += shnei + ' ' + shavuot + ' '; } if (days) { if (days === 2 || days === 3) { str += 'וּ'; } else if (days === 5) { str += 'וַ'; } else { str += 'וְ'; } if (days > 2) { str += ones[days] + ' ' + yamim + ' '; } else if (days === 1) { str += yomEchad + ' '; } else { // days == 2 str += shneiYamim + ' '; } } } str += 'לָעֽוֹמֶר'; return str.normalize(); } /** Represents a day 1-49 of counting the Omer from Pesach to Shavuot */ class OmerEvent extends Event { /** * @param date * @param omerDay */ constructor(date, omerDay) { super(date, `Omer ${omerDay}`, flags.OMER_COUNT); checkDay(omerDay); this.weekNumber = Math.floor((omerDay - 1) / 7) + 1; this.daysWithinWeeks = omerDay % 7 || 7; this.omer = omerDay; } /** * Returns the sefira. For example, on day 8: * * חֶֽסֶד שֶׁבִּגְבוּרָה * * Chesed shebiGevurah * * Lovingkindness within Might * @param lang `en` (English), `he` (Hebrew with nikud), or `translit` (Hebrew in Sephardic transliteration) * @returns a string such as `Lovingkindness within Might` or `חֶֽסֶד שֶׁבִּגְבוּרָה` */ sefira(lang = 'en') { if (lang !== 'he' && lang !== 'translit') { lang = 'en'; } const [weekNum, daysWithinWeeks] = getWeeks(this.omer); const config = sefirot[lang]; const pfxWords = config.pfxWords; const words = config.words; const week = pfxWords ? pfxWords[weekNum] : words[weekNum]; const dayWithinWeek = words[daysWithinWeeks]; const infix = pfxWords ? '' : weekNum === 2 || weekNum === 6 ? config.infix26 : config.infix; return (dayWithinWeek + ' ' + infix + week).normalize(); } /** * @param [locale] Optional locale name (defaults to active locale). */ render(locale) { locale = locale !== null && locale !== void 0 ? locale : Locale.getLocaleName(); if (typeof locale === 'string') { locale = locale.toLowerCase(); } const isHebrewLocale = locale === 'he' || locale === 'he-x-nonikud' || locale === 'h'; const omer = this.omer; const nth = isHebrewLocale ? gematriya(omer) : Locale.ordinal(omer, locale); return nth + ' ' + Locale.gettext('day of the Omer', locale); } /** * Returns translation of "Omer day 22" without ordinal numbers. * @param [locale] Optional locale name (defaults to active locale). */ renderBrief(locale) { return (Locale.gettext('Omer', locale) + ' ' + Locale.gettext('day', locale) + ' ' + this.omer); } /** * Returns an emoji number symbol with a circle, for example `㊲` * from the “Enclosed CJK Letters and Months” block of the Unicode standard * @returns a single Unicode character from `①` through `㊾` */ getEmoji() { if (typeof this.emoji === 'string') return this.emoji; let codePoint; const omerDay = this.omer; if (omerDay <= 20) { codePoint = 9312 + omerDay - 1; } else if (omerDay <= 35) { // between 21 and 35 inclusive codePoint = 12881 + omerDay - 21; } else { // between 36 and 49 inclusive codePoint = 12977 + omerDay - 36; } return String.fromCodePoint(codePoint); } getWeeks() { const day7 = this.daysWithinWeeks === 7; return day7 ? this.weekNumber : this.weekNumber - 1; } getDaysWithinWeeks() { return this.daysWithinWeeks; } /** * Returns a sentence with that evening's omer count * @returns a string such as `Today is 10 days, which is 1 week and 3 days of the Omer` * or `הַיוֹם עֲשָׂרָה יָמִים, שְׁהֵם שָׁבוּעַ אֶחָד וְשְׁלוֹשָׁה יָמִים לָעוֹמֶר` */ getTodayIs(locale) { locale = locale !== null && locale !== void 0 ? locale : Locale.getLocaleName(); if (typeof locale === 'string') { locale = locale.toLowerCase(); } const isHebrew = locale === 'he' || locale === 'he-x-nonikud'; const str = isHebrew ? omerTodayIsHe(this.omer) : omerTodayIsEn(this.omer); if (locale === 'he-x-nonikud') { return Locale.hebrewStripNikkud(str); } return str; } url() { return `https://www.hebcal.com/omer/${this.getDate().getFullYear()}/${this.omer}`; } } export { OmerEvent }; //# sourceMappingURL=omer.js.map