UNPKG

hebcal-fixed

Version:

An easy to use, richly-featured, perpetual Jewish Calendar API

1,707 lines (1,435 loc) 116 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function(n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function(type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } else { // At least give some kind of context to the user var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); err.context = er; throw err; } } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: args = Array.prototype.slice.call(arguments, 1); handler.apply(this, args); } } else if (isObject(handler)) { args = Array.prototype.slice.call(arguments, 1); listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function(type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else if (listeners) { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.prototype.listenerCount = function(type) { if (this._events) { var evlistener = this._events[type]; if (isFunction(evlistener)) return 1; else if (evlistener) return evlistener.length; } return 0; }; EventEmitter.listenerCount = function(emitter, type) { return emitter.listenerCount(type); }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } },{}],2:[function(require,module,exports){ /* * Convert numbers to gematriya representation, and vice-versa. * * Licensed MIT. * * Copyright (c) 2014 Eyal Schachter * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ (function(){ var letters = {}, numbers = { '': 0, א: 1, ב: 2, ג: 3, ד: 4, ה: 5, ו: 6, ז: 7, ח: 8, ט: 9, י: 10, כ: 20, ל: 30, מ: 40, נ: 50, ס: 60, ע: 70, פ: 80, צ: 90, ק: 100, ר: 200, ש: 300, ת: 400, תק: 500, תר: 600, תש: 700, תת: 800, תתק: 900, תתר: 1000 }, i; for (i in numbers) { letters[numbers[i]] = i; } function gematriya(num, limit) { if (typeof num !== 'number' && typeof num !== 'string') { throw new TypeError('non-number or string given to gematriya()'); } var str = typeof num === 'string'; if (str) { num = num.replace(/('|")/g,''); } num = num.toString().split('').reverse(); if (!str && limit) { num = num.slice(0, limit); } num = num.map(function g(n,i){ if (str) { return limit && numbers[n] < numbers[num[i - 1]] && numbers[n] < 100 ? numbers[n] * 1000 : numbers[n]; } else { if (parseInt(n, 10) * Math.pow(10, i) > 1000) { return g(n, i-3); } return letters[parseInt(n, 10) * Math.pow(10, i)]; } }); if (str) { return num.reduce(function(o,t){ return o + t; }, 0); } else { num = num.reverse().join('').replace(/יה/g,'טו').replace(/יו/g,'טז').split(''); if (num.length === 1) { num.push("'"); } else if (num.length > 1) { num.splice(-1, 0, '"'); } return num.join(''); } } if (typeof module !== 'undefined') { module.exports = gematriya; } else { window.gematriya = gematriya; } })(); },{}],3:[function(require,module,exports){ /* (c) 2011-2015, Vladimir Agafonkin SunCalc is a JavaScript library for calculating sun/moon position and light phases. https://github.com/mourner/suncalc */ (function () { 'use strict'; // shortcuts for easier to read formulas var PI = Math.PI, sin = Math.sin, cos = Math.cos, tan = Math.tan, asin = Math.asin, atan = Math.atan2, acos = Math.acos, rad = PI / 180; // sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas // date/time constants and conversions var dayMs = 1000 * 60 * 60 * 24, J1970 = 2440588, J2000 = 2451545; function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; } function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); } function toDays(date) { return toJulian(date) - J2000; } // general calculations for position var e = rad * 23.4397; // obliquity of the Earth function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); } function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); } function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); } function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); } function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; } function astroRefraction(h) { if (h < 0) // the following formula works for positive altitudes only. h = 0; // if h = -0.08901179 a div/0 would occur. // formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. // 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad: return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179)); } // general sun calculations function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); } function eclipticLongitude(M) { var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center P = rad * 102.9372; // perihelion of the Earth return M + C + P + PI; } function sunCoords(d) { var M = solarMeanAnomaly(d), L = eclipticLongitude(M); return { dec: declination(L, 0), ra: rightAscension(L, 0) }; } var SunCalc = {}; // calculates sun position for a given date and latitude/longitude SunCalc.getPosition = function (date, lat, lng) { var lw = rad * -lng, phi = rad * lat, d = toDays(date), c = sunCoords(d), H = siderealTime(d, lw) - c.ra; return { azimuth: azimuth(H, phi, c.dec), altitude: altitude(H, phi, c.dec) }; }; // sun times configuration (angle, morning name, evening name) var times = SunCalc.times = [ [-0.833, 'sunrise', 'sunset' ], [ -0.3, 'sunriseEnd', 'sunsetStart' ], [ -6, 'dawn', 'dusk' ], [ -12, 'nauticalDawn', 'nauticalDusk'], [ -18, 'nightEnd', 'night' ], [ 6, 'goldenHourEnd', 'goldenHour' ] ]; // adds a custom time to the times config SunCalc.addTime = function (angle, riseName, setName) { times.push([angle, riseName, setName]); }; // calculations for sun times var J0 = 0.0009; function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); } function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; } function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); } function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); } // returns set time for the given sun altitude function getSetJ(h, lw, phi, dec, n, M, L) { var w = hourAngle(h, phi, dec), a = approxTransit(w, lw, n); return solarTransitJ(a, M, L); } // calculates sun times for a given date and latitude/longitude SunCalc.getTimes = function (date, lat, lng) { var lw = rad * -lng, phi = rad * lat, d = toDays(date), n = julianCycle(d, lw), ds = approxTransit(0, lw, n), M = solarMeanAnomaly(ds), L = eclipticLongitude(M), dec = declination(L, 0), Jnoon = solarTransitJ(ds, M, L), i, len, time, Jset, Jrise; var result = { solarNoon: fromJulian(Jnoon), nadir: fromJulian(Jnoon - 0.5) }; for (i = 0, len = times.length; i < len; i += 1) { time = times[i]; Jset = getSetJ(time[0] * rad, lw, phi, dec, n, M, L); Jrise = Jnoon - (Jset - Jnoon); result[time[1]] = fromJulian(Jrise); result[time[2]] = fromJulian(Jset); } return result; }; // moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas function moonCoords(d) { // geocentric ecliptic coordinates of the moon var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude M = rad * (134.963 + 13.064993 * d), // mean anomaly F = rad * (93.272 + 13.229350 * d), // mean distance l = L + rad * 6.289 * sin(M), // longitude b = rad * 5.128 * sin(F), // latitude dt = 385001 - 20905 * cos(M); // distance to the moon in km return { ra: rightAscension(l, b), dec: declination(l, b), dist: dt }; } SunCalc.getMoonPosition = function (date, lat, lng) { var lw = rad * -lng, phi = rad * lat, d = toDays(date), c = moonCoords(d), H = siderealTime(d, lw) - c.ra, h = altitude(H, phi, c.dec), // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. pa = atan(sin(H), tan(phi) * cos(c.dec) - sin(c.dec) * cos(H)); h = h + astroRefraction(h); // altitude correction for refraction return { azimuth: azimuth(H, phi, c.dec), altitude: h, distance: c.dist, parallacticAngle: pa }; }; // calculations for illumination parameters of the moon, // based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and // Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. SunCalc.getMoonIllumination = function (date) { var d = toDays(date || new Date()), s = sunCoords(d), m = moonCoords(d), sdist = 149598000, // distance from Earth to Sun in km phi = acos(sin(s.dec) * sin(m.dec) + cos(s.dec) * cos(m.dec) * cos(s.ra - m.ra)), inc = atan(sdist * sin(phi), m.dist - sdist * cos(phi)), angle = atan(cos(s.dec) * sin(s.ra - m.ra), sin(s.dec) * cos(m.dec) - cos(s.dec) * sin(m.dec) * cos(s.ra - m.ra)); return { fraction: (1 + cos(inc)) / 2, phase: 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI, angle: angle }; }; function hoursLater(date, h) { return new Date(date.valueOf() + h * dayMs / 24); } // calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article SunCalc.getMoonTimes = function (date, lat, lng, inUTC) { var t = new Date(date); if (inUTC) t.setUTCHours(0, 0, 0, 0); else t.setHours(0, 0, 0, 0); var hc = 0.133 * rad, h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc, h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx; // go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set) for (var i = 1; i <= 24; i += 2) { h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc; h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc; a = (h0 + h2) / 2 - h1; b = (h2 - h0) / 2; xe = -b / (2 * a); ye = (a * xe + b) * xe + h1; d = b * b - 4 * a * h1; roots = 0; if (d >= 0) { dx = Math.sqrt(d) / (Math.abs(a) * 2); x1 = xe - dx; x2 = xe + dx; if (Math.abs(x1) <= 1) roots++; if (Math.abs(x2) <= 1) roots++; if (x1 < -1) x1 = x2; } if (roots === 1) { if (h0 < 0) rise = i + x1; else set = i + x1; } else if (roots === 2) { rise = i + (ye < 0 ? x2 : x1); set = i + (ye < 0 ? x1 : x2); } if (rise && set) break; h0 = h2; } var result = {}; if (rise) result.rise = hoursLater(t, rise); if (set) result.set = hoursLater(t, set); if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true; return result; }; // export as Node module / AMD module / browser variable if (typeof exports === 'object' && typeof module !== 'undefined') module.exports = SunCalc; else if (typeof define === 'function' && define.amd) define(SunCalc); else window.SunCalc = SunCalc; }()); },{}],4:[function(require,module,exports){ /* Hebcal - A Jewish Calendar Generator Copyright (C) 1994-2004 Danny Sadinoff Portions Copyright (c) 2002 Michael J. Radwin. All Rights Reserved. https://github.com/hebcal/hebcal-js This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Danny Sadinoff can be reached at danny@sadinoff.com Michael Radwin has made significant contributions as a result of maintaining hebcal.com. The JavaScript code was completely rewritten in 2014 by Eyal Schachter. */ // name, lat, long, Israel var cities = { "Ashdod": [ 31.8, 34.633, true ], "Atlanta": [ 33.75, -84.383, false ], "Austin": [ 30.266, -97.75, false ], "Baghdad": [ 33.233, 44.366, false ], "Beer Sheva": [ 31.25, 34.783, true ], "Berlin": [ 52.516, 13.4, false ], "Baltimore": [ 39.283, -76.6, false ], "Bogota": [ 4.6, -74.083, false ], "Boston": [ 42.333, -71.066, false ], "Buenos Aires": [ -34.616, -58.4, false ], "Buffalo": [ 42.883, -78.866, false ], "Chicago": [ 41.833, -87.75, false ], "Cincinnati": [ 39.1, -84.516, false ], "Cleveland": [ 41.5, -81.683, false ], "Dallas": [ 32.783, -96.8, false ], "Denver": [ 39.733, -104.983, false ], "Detroit": [ 42.333, -83.033, false ], "Eilat": [ 29.55, 34.95, true ], "Gibraltar": [ 36.133, -5.35, false ], "Haifa": [ 32.816, 34.983, true ], "Hawaii": [ 19.5, -155.5, false ], "Houston": [ 29.766, -95.366, false ], "Jerusalem": [ 31.783, 35.233, true ], "Johannesburg": [ -26.166, 28.033, false ], "Kiev": [ 50.466, 30.483, false ], "La Paz": [ -16.5, -68.15, false ], "Livingston": [ 40.283, -74.3, false ], "London": [ 51.5, -0.166, false ], "Los Angeles": [ 34.066, -118.25, false ], "Miami": [ 25.766, -80.2, false ], "Melbourne": [ -37.866, 145.133, false ], "Mexico City": [ 19.4, -99.15, false ], "Montreal": [ 45.5, -73.6, false ], "Moscow": [ 55.75, 37.7, false ], "New York": [ 40.716, -74.016, false ], "Omaha": [ 41.266, -95.933, false ], "Ottawa": [ 45.7, -76.183, false ], "Panama City": [ 8.966, -79.533, false ], "Paris": [ 48.866, 2.333, false ], "Petach Tikvah": [ 32.083, 34.883, true ], "Philadelphia": [ 39.95, -75.166, false ], "Phoenix": [ 33.45, -112.066, false ], "Pittsburgh": [ 40.433, -80, false ], "Saint Louis": [ 38.633, -90.2, false ], "Saint Petersburg": [ 59.883, 30.25, false ], "San Francisco": [ 37.783, -122.416, false ], "Seattle": [ 47.6, -122.333, false ], "Sydney": [ -33.916, 151.283, false ], "Tel Aviv": [ 32.083, 34.766, true ], "Tiberias": [ 32.966, 35.533, true ], "Toronto": [ 43.633, -79.4, false ], "Vancouver": [ 49.266, -123.116, false ], "White Plains": [ 41.033, -73.75, false ], "Washington DC": [ 38.916, -77, false ] }; function getCity(city) { city = city.split(/\s+/).map(function(w,i,c){ if (c.join(' ').toLowerCase() === 'washington dc' && i === 1) { // special case return w.toUpperCase(); } return w[0].toUpperCase() + w.slice(1).toLowerCase(); }).join(' '); return cities[city] || [ 0, 0, false ]; } exports.getCity = getCity; function listCities() { return Object.keys(cities); } exports.listCities = listCities; exports.addCity = function(city, info) { if (!Array.isArray(info)) { throw new TypeError('adding non-array city'); } if (info.length == 5) { var i = info.slice(); info = []; info[0] = (i[0] * 60 + i[1]) / 60; info[1] = (i[2] * 60 + i[3]) / 60; info[2] = i[4]; } if (info.length != 3) { throw new TypeError('length of city array is not 3'); } city = city.split(/\s+/).map(function(w){return w[0].toUpperCase() + w.slice(1).toLowerCase()}).join(' '); cities[city] = info; }; exports.nearest = function(lat, lon) { if (Array.isArray(lat)) { lat = (lat[0] * 60 + lat[1]) / 60; } if (Array.isArray(lon)) { lon = (lon[0] * 60 + lon[1]) / 60; } if (typeof lat != 'number') { throw new TypeError('incorrect lat type passed to nearest()'); } if (typeof lon != 'number') { throw new TypeError('incorrect long type passed to nearest()'); } return listCities().map(function(city){ var i = getCity(city); return { name: city, dist: Math.sqrt( Math.pow(Math.abs(i[0] - lat), 2) + Math.pow(Math.abs(i[1] - lon), 2) ) }; }).reduce(function(close,city){ return close.dist < city.dist ? close : city; }).name; }; },{}],5:[function(require,module,exports){ /* Hebcal - A Jewish Calendar Generator Copyright (C) 1994-2004 Danny Sadinoff Portions Copyright (c) 2002 Michael J. Radwin. All Rights Reserved. https://github.com/hebcal/hebcal-js This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Danny Sadinoff can be reached at danny@sadinoff.com Michael Radwin has made significant contributions as a result of maintaining hebcal.com. The JavaScript code was completely rewritten in 2014 by Eyal Schachter */ window.Hebcal = require('..'); var finished = false, warn = (typeof console != 'undefined' && (console.warn || console.log)) || function(){}; Hebcal.events.on('newListener', function(e){ if (e === 'ready' && !finished && Hebcal.ready) { ready(); } }); Object.defineProperty(Hebcal, 'onready', { configurable: true, get: function() { warn('Getting deprecated property Hebcal.onready'); return Hebcal.events.listeners('ready')[0]; }, set: function(func) { warn('Setting deprecated property Hebcal.onready; use Hebcal.events.on(\'ready\', func) instead'); Hebcal.events.on('ready', func); } }); if (navigator.geolocation) { Hebcal.ready = false; navigator.geolocation.getCurrentPosition(function(p){ Hebcal.defaultLocation = [p.coords.latitude,p.coords.longitude]; ready(); }, ready); } else { ready(); } function ready() { Hebcal.ready = true; finished = Hebcal.events.emit('ready'); } },{"..":10}],6:[function(require,module,exports){ /* Hebcal - A Jewish Calendar Generator Copyright (C) 1994-2004 Danny Sadinoff Portions Copyright (c) 2002 Michael J. Radwin. All Rights Reserved. https://github.com/hebcal/hebcal-js This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Danny Sadinoff can be reached at danny@sadinoff.com Michael Radwin has made significant contributions as a result of maintaining hebcal.com. The JavaScript code was completely rewritten in 2014 by Eyal Schachter. */ var gematriya = require('gematriya'); var charCodeAt = 'charCodeAt'; var months = exports.months = { NISAN : 1, IYYAR : 2, SIVAN : 3, TAMUZ : 4, AV : 5, ELUL : 6, TISHREI : 7, CHESHVAN: 8, KISLEV : 9, TEVET : 10, SHVAT : 11, ADAR_I : 12, ADAR_II : 13 }; var monthNames = [ ["", 0, ""], ["Nisan", 0, "ניסן"], ["Iyyar", 0, "אייר"], ["Sivan", 0, "סיון"], ["Tamuz", 0, "תמוז"], ["Av", 0, "אב"], ["Elul", 0, "אלול"], ["Tishrei", 0, "תשרי"], ["Cheshvan", 0, "חשון"], ["Kislev", 0, "כסלו"], ["Tevet", 0, "טבת"], ["Sh'vat", 0, "שבט"] ]; exports.monthNames = [ monthNames.concat([["Adar", 0, "אדר"],["Nisan", 0, "ניסן"]]), monthNames.concat([["Adar 1", 0, "אדר א'"],["Adar 2", 0, "אדר ב'"],["Nisan", 0, "ניסן"]]) ]; exports.days = { SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6 }; exports.LANG = function(str, opts){ return opts == 'h' && str[2] || (opts == 'a' && str[1] || str[0]); }; function LEAP(x) { return (1 + x * 7) % 19 < 7; } exports.LEAP = LEAP; exports.MONTH_CNT = function(x) { return 12 + LEAP(x); // boolean is cast to 1 or 0 }; exports.daysInMonth = function(month, year) { return 30 - (month == months.IYYAR || month == months.TAMUZ || month == months.ELUL || month == months.TEVET || month == months.ADAR_II || (month == months.ADAR_I && !LEAP(year)) || (month == months.CHESHVAN && !lngChesh(year)) || (month == months.KISLEV && shrtKis(year))); }; exports.monthNum = function(month) { return typeof month === 'number' ? month : month[charCodeAt](0) >= 1488 && month[charCodeAt](0) <= 1514 && /('|")/.test(month) ? gematriya(month) : month[charCodeAt](0) >= 48 && month[charCodeAt](0) <= 57 /* number */ ? parseInt(month, 10) : monthFromName(month); }; exports.dayYearNum = function(str) { return typeof str === 'number' ? str : str[charCodeAt](0) >= 1488 && str[charCodeAt](0) <= 1514 ? gematriya(str, true) : parseInt(str, 10); }; /* Days from sunday prior to start of Hebrew calendar to mean conjunction of Tishrei in Hebrew YEAR */ function hebElapsedDays(hYear){ // borrowed from original JS var m_elapsed = 235 * Math.floor((hYear - 1) / 19) + 12 * ((hYear - 1) % 19) + Math.floor(((((hYear - 1) % 19) * 7) + 1) / 19); var p_elapsed = 204 + (793 * (m_elapsed % 1080)); var h_elapsed = 5 + (12 * m_elapsed) + 793 * Math.floor(m_elapsed / 1080) + Math.floor(p_elapsed / 1080); var parts = (p_elapsed % 1080) + 1080 * (h_elapsed % 24); var day = 1 + 29 * m_elapsed + Math.floor(h_elapsed / 24); var alt_day = day + ((parts >= 19440) || ((2 == (day % 7)) && (parts >= 9924) && !(LEAP (hYear))) || ((1 == (day % 7)) && (parts >= 16789) && LEAP (hYear - 1))); return alt_day + ((alt_day % 7) === 0 || (alt_day % 7) == 3 || (alt_day % 7) == 5); } exports.hebElapsedDays = hebElapsedDays; /* Number of days in the hebrew YEAR */ function daysInYear(year) { return hebElapsedDays(year + 1) - hebElapsedDays(year); } exports.daysInYear = daysInYear; /* true if Cheshvan is long in Hebrew YEAR */ function lngChesh(year) { return (daysInYear(year) % 10) == 5; } exports.lngChesh = lngChesh; /* true if Kislev is short in Hebrew YEAR */ function shrtKis(year) { return (daysInYear(year) % 10) == 3; } exports.shrtKis = shrtKis; function monthFromName(c) { /* the Hebrew months are unique to their second letter N Nisan (November?) I Iyyar E Elul C Cheshvan K Kislev 1 1Adar 2 2Adar Si Sh Sivan, Shvat Ta Ti Te Tamuz, Tishrei, Tevet Av Ad Av, Adar אב אד אי אל אב אדר אייר אלול ח חשון ט טבת כ כסלב נ ניסן ס סיון ש שבט תמ תש תמוז תשרי */ switch (c.toLowerCase()[0]) { case 'n': case 'נ': return (c.toLowerCase()[1] == 'o') ? /* this catches "november" */ 0 : months.NISAN; case 'i': return months.IYYAR; case 'e': return months.ELUL; case 'c': case 'ח': return months.CHESHVAN; case 'k': case 'כ': return months.KISLEV; case 's': switch (c.toLowerCase()[1]) { case 'i': return months.SIVAN; case 'h': return months.SHVAT; default: return 0; } case 't': switch (c.toLowerCase()[1]) { case 'a': return months.TAMUZ; case 'i': return months.TISHREI; case 'e': return months.TEVET; } break; case 'a': switch (c.toLowerCase()[1]) { case 'v': return months.AV; case 'd': if (/(1|[^i]i|a|א)$/i.test(c)) { return months.ADAR_I; } return months.ADAR_II; // else assume sheini } break; case 'ס': return months.SIVAN; case 'ט': return months.TEVET; case 'ש': return months.SHVAT; case 'א': switch (c.toLowerCase()[1]) { case 'ב': return months.AV; case 'ד': if (/(1|[^i]i|a|א)$/i.test(c)) { return months.ADAR_I; } return months.ADAR_II; // else assume sheini case 'י': return months.IYYAR; case 'ל': return months.ELUL; } break; case 'ת': switch (c.toLowerCase()[1]) { case 'מ': return months.TAMUZ; case 'ש': return months.TISHREI; } break; } return 0; }; exports.monthFromName = monthFromName; /* Note: Applying this function to d+6 gives us the DAYNAME on or after an * absolute day d. Similarly, applying it to d+3 gives the DAYNAME nearest to * absolute date d, applying it to d-1 gives the DAYNAME previous to absolute * date d, and applying it to d+7 gives the DAYNAME following absolute date d. **/ exports.dayOnOrBefore = function(day_of_week, absdate) { return absdate - ((absdate - day_of_week) % 7); }; exports.map = function(self, fun, thisp) { // originally written for http://github.com/Scimonster/localbrowse if (self === null || typeof fun != 'function') { throw new TypeError(); } var t = Object(self); var res = {}; for (var i in t) { if (t.hasOwnProperty(i)) { res[i] = fun.call(thisp, t[i], i, t); } } if (Array.isArray(self) || typeof self == 'string') { // came as an array, return an array var arr = []; for (i in res) { arr[Number(i)] = res[i]; } res = filter(arr, true); // for...in isn't guaranteed to give any meaningful order if (typeof self == 'string') { res = res.join(''); } } return res; }; function filter(self, fun, thisp) { if (self === null) { throw new TypeError('self is null'); } switch (typeof fun) { case 'function': break; // do nothing case 'string': case 'number': return self[fun]; // str/num is just the property case 'boolean': // boolean shortcuts to filter only truthy/falsy values if (fun) { fun = function (v) { return v; }; } else { fun = function (v) { return !v; }; } break; case 'object': var funOrig = fun; // save it if (fun instanceof RegExp) { // test the val against the regex fun = function (v) { return funOrig.test(v); }; break; } else if (Array.isArray(fun)) { // keep these keys fun = function (v, k) { return funOrig.indexOf(k) > -1; }; break; } default: throw new TypeError('fun is not a supported type'); } var res = {}; var t = Object(self); for (var i in t) { if (t.hasOwnProperty(i)) { var val = t[i]; // in case fun mutates it if (fun.call(thisp, val, i, t)) { // define property on res in the same manner as it was originally defined var props = Object.getOwnPropertyDescriptor(t, i); props.value = val; Object.defineProperty(res, i, props); } } } if (Array.isArray(self) || typeof self == 'string') { // came as an array, return an array var arr = []; for (i in res) { arr[Number(i)] = res[i]; } res = arr.filter(function (v) { return v; }); // for...in isn't guaranteed to give any meaningful order // can't use c.filter(arr,true) here because that would infitely recurse if (typeof self == 'string') { res = res.join(''); } } return res; } exports.filter = filter; exports.range = function(start, end, step) { step = step || 1; if (step < 0) { step = 0 - step; } var arr = [], i = start; if (start < end) { for (; i <= end; i += step) { arr.push(i); } } else { for (; i >= end; i -= step) { arr.push(i); } } return arr; }; },{"gematriya":2}],7:[function(require,module,exports){ /* Hebcal - A Jewish Calendar Generator Copyright (C) 1994-2004 Danny Sadinoff Portions Copyright (c) 2002 Michael J. Radwin. All Rights Reserved. https://github.com/hebcal/hebcal-js This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Danny Sadinoff can be reached at danny@sadinoff.com Michael Radwin has made significant contributions as a result of maintaining hebcal.com. The JavaScript code was completely rewritten in 2014 by Eyal Schachter. */ var c = require('./common'), greg = require('./greg'), gematriya = require('gematriya'); var shas = [ // sname, aname, hname, blatt [ "Berachot", "Berachos", "ברכות", 64 ], [ "Shabbat", "Shabbos", "שבת", 157 ], [ "Eruvin", "Eruvin", "עירובין", 105 ], [ "Pesachim", 0, "פסחים", 121 ], [ "Shekalim", 0, "שקלים", 22 ], [ "Yoma", 0, "יומא", 88 ], [ "Sukkah", 0, "סוכה", 56 ], [ "Beitzah", 0, "ביצה", 40 ], [ "Rosh Hashana", 0, "ראש השנה", 35 ], [ "Taanit", "Taanis", "תענית", 31 ], [ "Megillah", 0, "מגילה", 32 ], [ "Moed Katan", 0, "מועד קטן", 29 ], [ "Chagigah", 0, "חגיגה", 27 ], [ "Yevamot", "Yevamos", "יבמות", 122 ], [ "Ketubot", "Kesubos", "כתובות", 112 ], [ "Nedarim", 0, "נדרים", 91 ], [ "Nazir", 0, "נזיר", 66 ], [ "Sotah", 0, "סוטה", 49 ], [ "Gitin", 0, "גיטין", 90 ], [ "Kiddushin", 0, "קידושין", 82 ], [ "Baba Kamma", 0, "בבא קמא", 119 ], [ "Baba Metzia", 0, "בבא מציעא", 119 ], [ "Baba Batra", "Baba Basra", "בבא בתרא", 176 ], [ "Sanhedrin", 0, "סנהדרין", 113 ], [ "Makkot", "Makkos", "מכות", 24 ], [ "Shevuot", "Shevuos", "שבועות", 49 ], [ "Avodah Zarah", 0, "עבודה זרה", 76 ], [ "Horayot", "Horayos", "הוריות", 14 ], [ "Zevachim", 0, "זבחים", 120 ], [ "Menachot", "Menachos", "מנחות", 110 ], [ "Chullin", 0, "חולין", 142 ], [ "Bechorot", "Bechoros", "בכורות", 61 ], [ "Arachin", 0, "ערכין", 34 ], [ "Temurah", 0, "תמורה", 34 ], [ "Keritot", "Kerisos", "כריתות", 28 ], [ "Meilah", 0, "מעילה", 22 ], [ "Kinnim", 0, "קנים", 4 ], [ "Tamid", 0, "תמיד", 10 ], [ "Midot", "Midos", "מדות", 4 ], [ "Niddah", 0, "נדה", 73 ] ].map(function(m){ return {name: m.slice(0,3), blatt: m[3]}; }); exports.dafyomi = function(gregdate) { var dafcnt = 40, cno, dno, osday, nsday, total, count, j, cday, blatt; if (!(gregdate instanceof Date)) { throw new TypeError('non-date given to dafyomi'); } osday = greg.greg2abs(new Date(1923, 8, 11)); nsday = greg.greg2abs(new Date(1975, 5, 24)); cday = greg.greg2abs(gregdate); if (cday < osday) { // no cycle; dy didn't start yet return {name: [], blatt: 0}; } if (cday >= nsday) { // "new" cycle cno = 8 + ( (cday - nsday) / 2711 ); dno = (cday - nsday) % 2711; } else { // old cycle cno = 1 + ( (cday - osday) / 2702 ); dno = (cday - osday) % 2702; } // Find the daf taking note that the cycle changed slightly after cycle 7. total = blatt = 0; count = -1; // Fix Shekalim for old cycles if (cno <= 7) { shas[4].blatt = 13; } else { shas[4].blatt = 22; } // Find the daf j = 0; while (j < dafcnt) { count++; total = total + shas[j].blatt - 1; if (dno < total) { blatt = (shas[j].blatt + 1) - (total - dno); // fiddle with the weird ones near the end switch (count) { case 36: blatt = blatt + 21; break; case 37: blatt = blatt + 24; break; case 38: blatt = blatt + 33; break; default: break; } // Bailout j = 1 + dafcnt; } j++; } return {name: shas[count].name, blatt: blatt}; }; exports.dafname = function(daf, o) { return c.LANG(daf.name, o) + ' ' + (o === 'h' ? gematriya(daf.blatt) : daf.blatt); }; },{"./common":6,"./greg":8,"gematriya":2}],8:[function(require,module,exports){ /* Hebcal - A Jewish Calendar Generator Copyright (C) 1994-2004 Danny Sadinoff Portions Copyright (c) 2002 Michael J. Radwin. All Rights Reserved. https://github.com/hebcal/hebcal-js This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Danny Sadinoff can be reached at danny@sadinoff.com Michael Radwin has made significant contributions as a result of maintaining hebcal.com. The JavaScript code was completely rewritten in 2014 by Eyal Schachter. */ var floor = Math.floor, t0t1 = [30, 31], tMonthLengths = [0, 31, 28, 31].concat(t0t1, t0t1, 31, t0t1, t0t1), monthLengths = [ tMonthLengths.slice() ]; tMonthLengths[2]++; monthLengths.push(tMonthLengths); exports.daysInMonth = function(month, year) { // 1 based months return monthLengths[+LEAP(year)][month]; }; exports.monthNames = [ '', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; exports.lookupMonthNum = function(month) { return new Date(month + ' 1').getMonth() + 1; }; function dayOfYear (date) { if (!date instanceof Date) { throw new TypeError('Argument to greg.dayOfYear not a Date'); } var doy = date.getDate() + 31 * date.getMonth(); if (date.getMonth() > 1) { // FEB doy -= floor((4 * (date.getMonth() + 1) + 23) / 10); if (LEAP(date.getFullYear())) { doy++; } } return doy; } exports.dayOfYear = dayOfYear; function LEAP (year) { return !(year % 4) && ( !!(year % 100) || !(year % 400) ); } exports.LEAP = LEAP; exports.greg2abs = function(date) { // "absolute date" var year = date.getFullYear() - 1; return (dayOfYear(date) + // days this year 365 * year + // + days in prior years ( floor(year / 4) - // + Julian Leap years floor(year / 100) + // - century years floor(year / 400))); // + Gregorian leap years }; /* * See the footnote on page 384 of ``Calendrical Calculations, Part II: * Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M. * Clamen, Software--Practice and Experience, Volume 23, Number 4 * (April, 1993), pages 383-404 for an explanation. */ exports.abs2greg = function(theDate) { // calculations copied from original JS code var d0 = theDate - 1; var n400 = floor(d0 / 146097); var d1 = floor(d0 % 146097); var n100 = floor(d1 / 36524); var d2 = d1 % 36524; var n4 = floor(d2 / 1461); var d3 = d2 % 1461; var n1 = floor(d3 / 365); var day = ((d3 % 365) + 1); var year = (400 * n400 + 100 * n100 + 4 * n4 + n1); if (4 == n100 || 4 == n1) { return new Date(year, 11, 31); } return new Date(new Date(++year, 0, day).setFullYear(year)); // new Date() is very smart }; },{}],9:[function(require,module,exports){ /* Hebcal - A Jewish Calendar Generator Copyright (C) 1994-2004 Danny Sadinoff Portions Copyright (c) 2002 Michael J. Radwin. All Rights Reserved. https://github.com/hebcal/hebcal-js This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Danny Sadinoff can be reached at danny@sadinoff.com Michael Radwin has made significant contributions as a result of maintaining hebcal.com. The JavaScript code was completely rewritten in 2014 by Eyal Schachter. */ var c = require('./common'), greg = require('./greg'), suncalc = require('suncalc'), cities = require('./cities'), gematriya = require('gematriya'); suncalc.addTime(-16.1, 'alot_hashachar', 0); suncalc.addTime(-11.5, 'misheyakir', 0); suncalc.addTime(-10.2, 'misheyakir_machmir', 0); suncalc.addTime(-8.5, 0, 'tzeit'); suncalc.addTime(-5.879999999999995, 0, 'tzeitstars'); // for minifying optimizations var getFullYear = 'getFullYear', getMonth = 'getMonth', getDate = 'getDate', getTime = 'getTime', abs = 'abs', hour = 'hour', months = c.months, TISHREI = months.TISHREI, MONTH_CNT = c.MONTH_CNT, daysInMonth = c.daysInMonth, dayOnOrBefore = c.dayOnOrBefore, prototype = HDate.prototype; function HDate(day, month, year) { var me = this; switch (arguments.length) { case 0: return new HDate(new Date()); case 1: if (typeof day == 'undefined') { return new HDate(); } else if (day instanceof Date) { // we were passed a Gregorian date, so convert it var d = abs2hebrew(greg.greg2abs(day)); /*if (d.sunset() < day) { d = d.next(); }*/ return d; } else if (day instanceof HDate) { var d = new HDate(day[getDate](), day[getMonth](), day[getFullYear]()); d.il = day.il; d.setLocation(d.lat, d.long); return d; } else if (typeof day == 'string') { switch (day.toLowerCase().trim()) { case 'today': return new HDate(); case 'yesterday': return new HDate().prev(); case 'tomorrow': return new HDate().next(); } if (/\s/.test(day)) { var s = day.split(/\s+/); if (s.length == 2) { return new HDate(s[0], s[1]); } else if (s.length == 3) { return new HDate(s[0], s[1], s[2]); } else if (s.length == 4) { // should only be if s[1] is Adar if (/i/i.test(s[2])) { // Using I[I] syntax s[2] = s[2].length; } // otherwise using 1|2 syntax return new HDate(s[0], s[1] + s[2], s[3]); } } } else if (typeof day == 'number') { // absolute date return abs2hebrew(day); } throw new TypeError('HDate called with bad argument'); case 2: return new HDate(day, month, (new HDate)[getFullYear]()); case 3: me.day = me.month = 1; me.year = c.dayYearNum(year); me.setMonth(c.monthNum(month)); me.setDate(c.dayYearNum(day)); break; default: throw new TypeError('HDate called with bad arguments'); } return me.setLocation.apply(me, HDate.defaultLocation); } HDate.defaultLocation = [0, 0]; Object.defineProperty(HDate, 'defaultCity', { enumerable: true, configurable: true, g