├── .gitignore ├── rashi.js ├── nakshatra.js ├── package.json ├── README.md ├── houses.js ├── index.js ├── position.js ├── constants.js ├── LICENSE └── compatibility.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /rashi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Rashi is defined as the Moon Sign of the Birth Chart 3 | * @param {Object} birthChart 4 | */ 5 | function getRashi(birthChart) { 6 | return birthChart.meta.Mo.rashi; 7 | } 8 | 9 | module.exports = { getRashi }; 10 | -------------------------------------------------------------------------------- /nakshatra.js: -------------------------------------------------------------------------------- 1 | const constants = require("./constants"); 2 | /** 3 | * Nakshatra is defined as position of moon in birthchart, also associated to a Lord and an Animal 4 | * @param {Object} birthChart birthchart obtained from getBirthChart function 5 | */ 6 | function calculateNakshatra(birthChart) { 7 | return { 8 | ...birthChart.meta.Mo.nakshatra, 9 | animal: constants.NAKSHATRA_ANIMALS[birthChart.meta.Mo.nakshatra.name], 10 | }; 11 | } 12 | 13 | function calculateNakshatraCompatibility(animal1, animal2) { 14 | return ( 15 | constants.NAKSHATRA_ANIMAL_SCORE[animal1][animal2] || 16 | constants.NAKSHATRA_ANIMAL_SCORE[animal2][animal1] 17 | ); 18 | } 19 | 20 | module.exports = { calculateNakshatra, calculateNakshatraCompatibility }; 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astroreha", 3 | "version": "1.1.5", 4 | "description": "Astrology Library to get Birth Chart and Navamsa Chart. Compatibility retrieval using the same.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node index.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/rish-0-0/astroreha.git" 12 | }, 13 | "keywords": [ 14 | "Swiss", 15 | "Ephemeris", 16 | "Astrology", 17 | "Jyotish", 18 | "Birth Chart", 19 | "Navamsa Chart", 20 | "Reha" 21 | ], 22 | "author": "Rishabh Anand", 23 | "license": "GPL-2.0", 24 | "bugs": { 25 | "url": "https://github.com/rish-0-0/astroreha/issues" 26 | }, 27 | "homepage": "https://github.com/rish-0-0/astroreha#readme", 28 | "dependencies": { 29 | "ephemeris": "^2.0.0", 30 | "jyotish": "^1.0.1", 31 | "swisseph": "^0.5.14" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reha Astrology 2 | 3 | `Doesn't work in browser environments. Please run on server` 4 | 5 | ```shell 6 | npm i -S astroreha 7 | ``` 8 | 9 | 1. Default House System: `Whole Sign` 10 | 2. Default Ayanamsha Used: `Lahiri` 11 | 3. Compatibility can have maximum 30 points. Default threshold for matching is 12. (>=12) 12 | 13 | ### Get Birth Chart 14 | 15 | ```javascript 16 | const astroreha = require("astroreha"); 17 | 18 | // Get Birth Chart Details 19 | /** 20 | * @param {String} dateString format YYYY-MM-DD 21 | * @param {String} timeString format HH:MM:SS 22 | * @param {Number} lat latitude 23 | * @param {Number} lng longitude 24 | * @param {Number} timezone timezone in hours 25 | */ 26 | const birthChart = astroreha.positioner.getBirthChart("1999-05-22", "08:00:00", 28.6139, 77.209, 5.5); 27 | // Get Rashi 28 | birthChart.meta.Mo.rashi // Rashi is Moon Sign in Indian Astrology 29 | // Get Sun Sign 30 | birthChart.meta.Su.rashi 31 | // Get Grahas in a certain Rashi 32 | birthChart.aries.signs // returns an array of grahas 33 | 34 | // Get compatibility (returns Boolean) 35 | astroreha.compatibility.areCompatible({dateString, timeString, lat, lng, timezone}, {dateString, timeString, lat, lng, timezone}); 36 | ``` 37 | ## Updates for 1.1.5 38 | 1. Changed Getting Navamsa Chart Logic to be more accurate considering floating point inaccuracies 39 | 2. More constants available 40 | 41 | 42 | ## Breaking Changes 43 | 1. Not a default Export anymore 44 | 2. Gives Positioner and Compatibility Feature 45 | 46 | 47 | 48 | ### Verified with [Prokerela.com](https://www.prokerala.com) 49 | -------------------------------------------------------------------------------- /houses.js: -------------------------------------------------------------------------------- 1 | const swisseph = require("swisseph"); 2 | const { getValidatedBirthDetails } = require("jyotish").utils.birthDetails; 3 | /** 4 | * 5 | * @typedef {Object} BirthDetails 6 | * @property {String} dateString - Format: YYYY-MM-DD 7 | * @property {String} timeString - Format: HH:mm:ss 8 | * @property {Number} lat - Latitude 9 | * @property {Number} lng - Longitude 10 | * @property {Number} timezone - Timezone in hours. Eg: 5.5 11 | */ 12 | 13 | /** 14 | * 15 | * @param {BirthDetails} birthDetails 16 | */ 17 | const convertTime = (birthDetails) => { 18 | let utc = swisseph.swe_utc_time_zone( 19 | birthDetails.year, 20 | birthDetails.month, 21 | birthDetails.date, 22 | birthDetails.hour, 23 | birthDetails.min, 24 | birthDetails.sec, 25 | birthDetails.timezone 26 | ); 27 | let retval = swisseph.swe_utc_to_jd( 28 | utc.year, 29 | utc.month, 30 | utc.day, 31 | utc.hour, 32 | utc.minute, 33 | utc.second, 34 | swisseph.SE_GREG_CAL 35 | ); 36 | let et = retval.julianDayET; 37 | tt = retval.julianDayUT; 38 | return { utc, retval, et, tt }; 39 | }; 40 | 41 | /** 42 | * 43 | * @param {BirthDetails} birthDetails birth details 44 | * @param {String} house_type House System. Default: "Whole Sign" = "W" 45 | */ 46 | 47 | function calculateHouses(birthDetails, house_type = "W") { 48 | const { tt } = convertTime(getValidatedBirthDetails(birthDetails)); 49 | return swisseph.swe_houses_ex( 50 | tt, 51 | swisseph.SEFLG_SIDEREAL, 52 | birthDetails.lat, 53 | birthDetails.lng, 54 | house_type 55 | ); 56 | } 57 | 58 | module.exports = { calculateHouses }; 59 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // There are 3 levels of accuracy (also called ephemeris) 2 | /* 3 | Moshier: 0.1 arcsec 4 | Swiss Ephemeris: 0.001 arcsec (requires 90MB of data) 5 | JPL NASA: almost accurate (nothing higher than this): 2.9GB of Data 6 | House System: Whole Sign 'W' (Wikipedia) default could be Equal 'E' 7 | 8 | */ 9 | const positioner = require("./position"); 10 | const compatibility = require("./compatibility"); 11 | // const { 12 | // getUTCPosition, 13 | // getUTCFixedStarPosition, 14 | // getAllPlanets, 15 | // // getBirthChart, 16 | // nakshatras, 17 | // rashis, 18 | // getNavamsaChart, 19 | // } = positioner; 20 | 21 | /** 22 | * 23 | * @param {Object} obj object to print 24 | */ 25 | 26 | function print(obj) { 27 | console.log(JSON.stringify(obj, null, 2)); 28 | } 29 | 30 | if (require.main == module) { 31 | // console.log(getUTCPosition("moon", new Date())); 32 | // console.log(getUTCFixedStarPosition("Aldebaran", new Date())); 33 | // print( 34 | // getAllPlanets( 35 | // new Date("2015-08-10T17:09:01.000+08:00").toDateString(), 36 | // 10.0014, 37 | // 53.5653, 38 | // 0 39 | // ) 40 | // ); 41 | 42 | // // console.log(getBirthChart("1990-07-04", "10:12:00", 29.7604, -95.3698, -5)); // Sophie 43 | // const birthChart = getBirthChart( 44 | // "1999-05-22", 45 | // "08:00:00", 46 | // 28.6139, 47 | // 77.209, 48 | // 5.5 49 | // ); // Sophie 50 | // // print(birthChart.meta.La); 51 | // const sophieNavamsaChart = getNavamsaChart(birthChart); 52 | // // print(sophieNavamsaChart.meta.La); 53 | // // print(compatibility.getHousesOfChart(sophieNavamsaChart)); 54 | const birthChart = positioner.getBirthChart( 55 | "1990-07-04", 56 | "10:12:00", 57 | 29.7604, 58 | -95.3698, 59 | -5 60 | ); // Rishabh 61 | // print(birthChart.meta.La); 62 | // print(compatibility.getHousesOfChart(birthChart)); 63 | // console.log(rashis.getRashi(birthChart)); 64 | // console.log(compatibility.oppositeSignOfBirthCheck(birthChart, birthChartRishabh)); 65 | print(positioner.getNavamsaChart(birthChart)); // Rishabh 66 | // console.log(nakshatras.calculateNakshatraCompatibility("Cat", "Hare")); 67 | // console.log(positioner.whichNavamsa(30*1+12+10/60)); 68 | } 69 | 70 | module.exports = { compatibility, positioner }; 71 | -------------------------------------------------------------------------------- /position.js: -------------------------------------------------------------------------------- 1 | const swisseph = require("swisseph"); 2 | const { ...constants } = require("./constants"); 3 | const ephemeris = require("ephemeris"); 4 | const jyotish = require("jyotish"); 5 | const { calculateHouses } = require("./houses"); 6 | const grahas = require("jyotish/src/grahas"); 7 | const nakshatras = require("./nakshatra"); 8 | const rashis = require("./rashi"); 9 | 10 | /** 11 | * 12 | * @param {String} star eg: 'sun', 'moon' 13 | * @param {Date} date Date when to calculate position 14 | */ 15 | function getUTCPosition(star, date) { 16 | return swisseph.swe_calc_ut( 17 | getJulianDay(date), 18 | constants.DICT[star], 19 | swisseph.SEFLG_EQUATORIAL | swisseph.SEFLG_MOSEPH // Equatorial Coordinates 20 | ); 21 | } 22 | 23 | /** 24 | * 25 | * @param {String} fixedStar fixed star's name 26 | * @param {Date} date date 27 | */ 28 | function getUTCFixedStarPosition(fixedStar, date) { 29 | return swisseph.swe_fixstar_ut(fixedStar, getJulianDay(date), constants.FLAG); 30 | } 31 | 32 | /** 33 | * 34 | * @param {Date} date local date, will be converted to UTC. 35 | */ 36 | function getJulianDay(date) { 37 | const year = date.getUTCFullYear(); 38 | const month = date.getUTCMonth() + 1; 39 | const day = date.getUTCDate(); 40 | const hour = date.getUTCHours(); 41 | return swisseph.swe_julday(year, month, day, hour, swisseph.SE_GREG_CAL); 42 | } 43 | 44 | /** 45 | * 46 | * @param {String} dateString local datetime object string 47 | * @param {Number} longitude longitude of the place 48 | * @param {Number} latitude latitude of the place 49 | * @param {Number} height altitude of the place 50 | */ 51 | 52 | function getAllPlanets(dateString, longitude, latitude, height) { 53 | return ephemeris.getAllPlanets( 54 | new Date(dateString), 55 | longitude, 56 | latitude, 57 | height 58 | ); 59 | } 60 | 61 | /* 62 | Grahas: Sun, Moon, Mercury, Venus, Mars, Jupiter, Saturn, Rahu 63 | Ayanamsha in use is Lahiri (most common) 64 | */ 65 | 66 | /** 67 | * @param {String} dateString format YYYY-MM-DD 68 | * @param {String} timeString format HH:MM:SS 69 | * @param {Number} lat latitude 70 | * @param {Number} lng longitude 71 | * @param {Number} timezone timezone in hours 72 | */ 73 | function getBirthChart(dateString, timeString, lat, lng, timezone) { 74 | // console.log(calculateHouses({ dateString, timeString, lat, lng, timezone })); 75 | const grahaPositions = jyotish.grahas.getGrahasPosition( 76 | { dateString, timeString, lat, lng, timezone }, 77 | { zodiacType: "S", houseType: "W" } 78 | ); 79 | 80 | const birthChart = { 81 | aries: { 82 | rashi: "aries", 83 | signs: [], 84 | }, 85 | taurus: { 86 | rashi: "taurus", 87 | signs: [], 88 | }, 89 | gemini: { 90 | rashi: "gemini", 91 | signs: [], 92 | }, 93 | cancer: { 94 | rashi: "cancer", 95 | signs: [], 96 | }, 97 | leo: { 98 | rashi: "leo", 99 | signs: [], 100 | }, 101 | virgo: { 102 | rashi: "virgo", 103 | signs: [], 104 | }, 105 | libra: { 106 | rashi: "libra", 107 | signs: [], 108 | }, 109 | scorpio: { 110 | rashi: "scorpio", 111 | signs: [], 112 | }, 113 | sagittarius: { 114 | rashi: "sagittarius", 115 | signs: [], 116 | }, 117 | capricorn: { 118 | rashi: "capricorn", 119 | signs: [], 120 | }, 121 | aquarius: { 122 | rashi: "aquarius", 123 | signs: [], 124 | }, 125 | pisces: { 126 | rashi: "pisces", 127 | signs: [], 128 | }, 129 | meta: {}, 130 | }; 131 | 132 | Object.values(grahaPositions).map((graha) => { 133 | birthChart[constants.RASHIS[graha.rashi]].signs.push({ 134 | graha: graha.graha, 135 | nakshatra: graha.nakshatra, 136 | longitude: graha.longitude, 137 | isRetrograde: graha.isRetrograde, 138 | }); 139 | birthChart.meta[graha.graha] = { 140 | rashi: graha.rashi, 141 | graha: graha.graha, 142 | nakshatra: graha.nakshatra, 143 | longitude: graha.longitude, 144 | isRetrograde: graha.isRetrograde, 145 | }; 146 | }); 147 | 148 | return birthChart; 149 | } 150 | 151 | /** 152 | * 153 | * @param {Object} birthChart birthchart obtained from getBirthChart function 154 | */ 155 | 156 | function getNavamsaChart(birthChart) { 157 | const navamsaChart = { 158 | aries: { 159 | rashi: "aries", 160 | signs: [], 161 | }, 162 | taurus: { 163 | rashi: "taurus", 164 | signs: [], 165 | }, 166 | gemini: { 167 | rashi: "gemini", 168 | signs: [], 169 | }, 170 | cancer: { 171 | rashi: "cancer", 172 | signs: [], 173 | }, 174 | leo: { 175 | rashi: "leo", 176 | signs: [], 177 | }, 178 | virgo: { 179 | rashi: "virgo", 180 | signs: [], 181 | }, 182 | libra: { 183 | rashi: "libra", 184 | signs: [], 185 | }, 186 | scorpio: { 187 | rashi: "scorpio", 188 | signs: [], 189 | }, 190 | sagittarius: { 191 | rashi: "sagittarius", 192 | signs: [], 193 | }, 194 | capricorn: { 195 | rashi: "capricorn", 196 | signs: [], 197 | }, 198 | aquarius: { 199 | rashi: "aquarius", 200 | signs: [], 201 | }, 202 | pisces: { 203 | rashi: "pisces", 204 | signs: [], 205 | }, 206 | meta: {}, 207 | }; 208 | Object.values(birthChart).map((rashi) => { 209 | if (rashi.signs == undefined) { 210 | // metadata of birthchart should not be iterated. It won't be a rashi, it will be a graha inside metadata 211 | return; 212 | } 213 | rashi.signs.map((graha) => { 214 | const navamsa = whichNavamsa(graha.longitude); // A number between 1 - 9 215 | const navamsa_group_member = 216 | constants.REVERSE_RASHIS[ 217 | constants.NAVAMSHA_GROUPS[rashi.rashi] 218 | ]; 219 | const position = constants.RASHI_MAP[navamsa_group_member] + 1; 220 | const calculated_navamsa_rashi_position = (position + navamsa - 1 )%12; 221 | const navamsa_rashi = constants.SKEWED_REVERSE_RASHI_MAP[calculated_navamsa_rashi_position]; 222 | navamsaChart[constants.RASHIS[navamsa_rashi]].signs.push(graha); 223 | navamsaChart.meta[graha.graha] = { ...graha, rashi: navamsa_rashi }; 224 | }); 225 | }); 226 | 227 | return navamsaChart; 228 | } 229 | 230 | /** 231 | * 232 | * @param {Number} longitude Decimal Form of Longitude 233 | * @returns {Number} 1-9 234 | */ 235 | function whichNavamsa(longitude) { 236 | const fraction = longitude % 1; 237 | const remainder = Math.floor(longitude) % 30; 238 | const total_rem = remainder + fraction; 239 | let div = 1; 240 | for (var ele of constants.NAVAMSA_DIVISIONS) { 241 | if (total_rem <= ele) break; 242 | div++; 243 | } 244 | 245 | // the div here implies navamsa 246 | return div; 247 | } 248 | 249 | module.exports = { 250 | getUTCPosition, 251 | getJulianDay, 252 | getUTCFixedStarPosition, 253 | getAllPlanets, 254 | getBirthChart, 255 | getNavamsaChart, 256 | whichNavamsa, 257 | nakshatras, 258 | rashis, 259 | }; 260 | -------------------------------------------------------------------------------- /constants.js: -------------------------------------------------------------------------------- 1 | const swisseph = require("swisseph"); 2 | var pathToSwisseph = require.resolve("swisseph/package.json").split("/"); 3 | pathToSwisseph.pop(); 4 | swisseph.swe_set_ephe_path(pathToSwisseph.join("/") + "/ephe"); 5 | 6 | module.exports.FLAG = swisseph.SEFLG_SPEED | swisseph.SEFLG_MOSEPH; 7 | 8 | module.exports.DICT = { 9 | sun: swisseph.SE_SUN, 10 | moon: swisseph.SE_MOON, 11 | mean_node: swisseph.SE_MEAN_NODE, 12 | true_node: swisseph.SE_TRUE_NODE, 13 | mean_apog: swisseph.SE_MEAN_APOG, 14 | oscu_apog: swisseph.SE_OSCU_APOG, 15 | chiron: swisseph.SE_CHIRON, 16 | }; 17 | 18 | module.exports.RASHIS = { 19 | Ar: "aries", 20 | Ta: "taurus", 21 | Ge: "gemini", 22 | Cn: "cancer", 23 | Le: "leo", 24 | Vi: "virgo", 25 | Li: "libra", 26 | Sc: "scorpio", 27 | Sg: "sagittarius", 28 | Cp: "capricorn", 29 | Aq: "aquarius", 30 | Pi: "pisces", 31 | }; 32 | 33 | const RASHI_REVERSE_MAP = { 34 | 0: "Ar", 35 | 1: "Ta", 36 | 2: "Ge", 37 | 3: "Cn", 38 | 4: "Le", 39 | 5: "Vi", 40 | 6: "Li", 41 | 7: "Sc", 42 | 8: "Sg", 43 | 9: "Cp", 44 | 10: "Aq", 45 | 11: "Pi", 46 | }; 47 | 48 | const RASHI_MAP = { 49 | Ar: 0, 50 | Ta: 1, 51 | Ge: 2, 52 | Cn: 3, 53 | Le: 4, 54 | Vi: 5, 55 | Li: 6, 56 | Sc: 7, 57 | Sg: 8, 58 | Cp: 9, 59 | Aq: 10, 60 | Pi: 11, 61 | }; 62 | 63 | module.exports.RASHI_MAP = RASHI_MAP; 64 | 65 | const RASHI_ARRAY = [ 66 | "Ar", 67 | "Ta", 68 | "Ge", 69 | "Cn", 70 | "Le", 71 | "Vi", 72 | "Li", 73 | "Sc", 74 | "Sg", 75 | "Cp", 76 | "Aq", 77 | "Pi", 78 | ]; 79 | 80 | module.exports.RASHI_ARRAY = RASHI_ARRAY; 81 | 82 | module.exports.NAVAMSHA_GROUPS = { 83 | aries: "aries", 84 | taurus: "capricorn", 85 | gemini: "libra", 86 | cancer: "cancer", 87 | leo: "aries", 88 | virgo: "capricorn", 89 | libra: "libra", 90 | scorpio: "cancer", 91 | sagittarius: "aries", 92 | capricorn: "capricorn", 93 | aquarius: "libra", 94 | pisces: "cancer", 95 | }; 96 | 97 | module.exports.REVERSE_RASHIS = { 98 | aries: "Ar", 99 | taurus: "Ta", 100 | gemini: "Ge", 101 | cancer: "Cn", 102 | leo: "Le", 103 | virgo: "Vi", 104 | libra: "Li", 105 | scorpio: "Sc", 106 | sagittarius: "Sg", 107 | capricorn: "Cp", 108 | aquarius: "Aq", 109 | pisces: "Pi", 110 | }; 111 | 112 | /** 113 | * 114 | * @param {String} rashi Rashi name 115 | * @param {Number} num positive number to add to the rashi 116 | */ 117 | module.exports.rashi_calc = (rashi, num) => { 118 | return RASHI_ARRAY[(RASHI_MAP[rashi] + num) % RASHI_ARRAY.length]; 119 | }; 120 | 121 | module.exports.RASHI_LORDS = { 122 | aries: "Ma", 123 | taurus: "Ve", 124 | gemini: "Me", 125 | cancer: "Mo", 126 | leo: "Su", 127 | virgo: "Me", 128 | libra: "Ve", 129 | scorpio: "Ma", 130 | sagittarius: "Ju", 131 | capricorn: "Sa", 132 | aquarius: "Sa", 133 | pisces: "Ju", 134 | }; 135 | 136 | module.exports.PLANET_RELATIONS = { 137 | Su: { 138 | friends: ["Su", "Mo", "Ma", "Ju"], 139 | neutral: ["Me"], 140 | enemies: ["Ve", "Sa"], 141 | }, 142 | Mo: { 143 | friends: ["Mo", "Sun", "Me"], 144 | neutral: ["Ma", "Ju", "Ve", "Sa"], 145 | enemies: [], 146 | }, 147 | Ma: { 148 | friends: ["Ma", "Su", "Mo", "Ju"], 149 | neutral: ["Ve", "Sa"], 150 | enemies: ["Me"], 151 | }, 152 | Me: { 153 | friends: ["Me", "Su", "Ve"], 154 | neutral: ["Ma", "Ju", "Sa"], 155 | enemies: ["Mo"], 156 | }, 157 | Ju: { 158 | friends: ["Ju", "Su", "Mo", "Ma"], 159 | neutral: ["Sa"], 160 | enemies: ["Me", "Ve"], 161 | }, 162 | Ve: { 163 | friends: ["Ve", "Me", "Sa"], 164 | neutral: ["Ma", "Ju"], 165 | enemies: ["Su", "Mo"], 166 | }, 167 | Sa: { 168 | friends: ["Sa", "Me", "Ve"], 169 | neutral: ["Ju"], 170 | enemies: ["Su", "Mo", "Ma"], 171 | }, 172 | }; 173 | 174 | module.exports.NAKSHATRA_ANIMALS = { 175 | Ashwini: "Horse", 176 | Bharani: "Elephant", 177 | Krittika: "Sheep", 178 | Rohini: "Serpent", 179 | Mrigashira: "Serpent", 180 | Ardra: "Dog", 181 | Punarvasu: "Cat", 182 | Pushya: "Sheep", 183 | Ashlesha: "Cat", 184 | Magha: "Rat", 185 | "Purva Phalguni": "Rat", 186 | "Uttara Phalguni": "Cow", 187 | Hasta: "Buffalo", 188 | Chitra: "Tiger", 189 | Swati: "Buffalo", 190 | Vishakha: "Tiger", 191 | Anuradha: "Hare", 192 | Jyestha: "Hare", 193 | Mula: "Dog", 194 | "Purva Aashada": "Monkey", 195 | "Uttara Aashada": "Mongoose", 196 | Shravana: "Monkey", 197 | Dhanishta: "Lion", 198 | Shatabhisha: "Horse", 199 | "Purva Bhadrapada": "Lion", 200 | "Uttara Bhadrapada": "Cow", 201 | Revati: "Elephant", 202 | }; 203 | 204 | module.exports.NAKSHATRA_ANIMAL_SCORE = { 205 | Horse: { 206 | Horse: 4, 207 | }, 208 | Elephant: { 209 | Horse: 2, 210 | Elephant: 4, 211 | }, 212 | Sheep: { 213 | Horse: 2, 214 | Elephant: 3, 215 | Sheep: 4, 216 | }, 217 | Serpent: { 218 | Horse: 3, 219 | Elephant: 3, 220 | Sheep: 2, 221 | Serpent: 4, 222 | }, 223 | Dog: { 224 | Horse: 2, 225 | Elephant: 2, 226 | Sheep: 1, 227 | Serpent: 2, 228 | Dog: 4, 229 | }, 230 | Cat: { 231 | Horse: 2, 232 | Elephant: 2, 233 | Sheep: 2, 234 | Serpent: 1, 235 | Dog: 2, 236 | Cat: 4, 237 | }, 238 | Rat: { 239 | Horse: 2, 240 | Elephant: 2, 241 | Sheep: 1, 242 | Serpent: 1, 243 | Dog: 1, 244 | Cat: 0, 245 | Rat: 4, 246 | }, 247 | Cow: { 248 | Horse: 1, 249 | Elephant: 2, 250 | Sheep: 3, 251 | Serpent: 1, 252 | Dog: 2, 253 | Cat: 2, 254 | Rat: 2, 255 | Cow: 4, 256 | }, 257 | Buffalo: { 258 | Horse: 0, 259 | Elephant: 3, 260 | Sheep: 3, 261 | Serpent: 1, 262 | Dog: 2, 263 | Cat: 2, 264 | Rat: 2, 265 | Cow: 3, 266 | Buffalo: 4, 267 | }, 268 | Tiger: { 269 | Horse: 1, 270 | Elephant: 1, 271 | Sheep: 1, 272 | Serpent: 2, 273 | Dog: 1, 274 | Cat: 1, 275 | Rat: 2, 276 | Cow: 0, 277 | Buffalo: 1, 278 | Tiger: 4, 279 | }, 280 | Hare: { 281 | Horse: 1, 282 | Elephant: 2, 283 | Sheep: 2, 284 | Serpent: 2, 285 | Dog: 0, 286 | Cat: 3, 287 | Rat: 2, 288 | Cow: 3, 289 | Buffalo: 2, 290 | Tiger: 1, 291 | Hare: 4, 292 | }, 293 | Monkey: { 294 | Horse: 3, 295 | Elephant: 3, 296 | Sheep: 0, 297 | Serpent: 2, 298 | Dog: 2, 299 | Cat: 3, 300 | Rat: 2, 301 | Cow: 2, 302 | Buffalo: 2, 303 | Tiger: 1, 304 | Hare: 2, 305 | Monkey: 4, 306 | }, 307 | Mongoose: { 308 | Horse: 2, 309 | Elephant: 2, 310 | Sheep: 3, 311 | Serpent: 0, 312 | Dog: 1, 313 | Cat: 2, 314 | Rat: 1, 315 | Cow: 2, 316 | Buffalo: 2, 317 | Tiger: 2, 318 | Hare: 2, 319 | Monkey: 3, 320 | Mongoose: 4, 321 | }, 322 | Lion: { 323 | Horse: 1, 324 | Elephant: 0, 325 | Sheep: 1, 326 | Serpent: 2, 327 | Dog: 1, 328 | Cat: 1, 329 | Rat: 2, 330 | Cow: 1, 331 | Buffalo: 2, 332 | Tiger: 1, 333 | Hare: 1, 334 | Monkey: 2, 335 | Mongoose: 2, 336 | Lion: 4, 337 | }, 338 | }; 339 | 340 | module.exports.DEFAULT_THRESHOLD = 0.4; 341 | 342 | module.exports.GOOD_HOUSES = [1, 2, 3, 4, 5, 7, 9, 10, 11]; 343 | module.exports.BAD_HOUSES = [6, 8, 12]; 344 | 345 | module.exports.OPPOSITE_SIGNS = { 346 | aries: "libra", 347 | taurus: "scorpio", 348 | gemini: "sagittarius", 349 | cancer: "capricorn", 350 | leo: "aquarius", 351 | virgo: "pisces", 352 | libra: "aries", 353 | scorpio: "taurus", 354 | sagittarius: "gemini", 355 | capricorn: "cancer", 356 | aquarius: "leo", 357 | pisces: "virgo", 358 | }; 359 | 360 | module.exports.GOOD_CONNECTION_TYPES = [1, 3, 5, 7, 9, 11]; 361 | module.exports.BAD_CONNECTION_TYPES = [2, 4, 6, 8, 10, 12]; 362 | 363 | module.exports.MANGLIK = [1, 4, 7, 8, 12]; 364 | 365 | module.exports.swisseph = swisseph; 366 | 367 | module.exports.NAVAMSA_DIVISIONS = [ 368 | 3.3329, 369 | 6.666, 370 | 9.999, 371 | 13.3329, 372 | 16.666, 373 | 19.999, 374 | 23.3329, 375 | 26.666, 376 | 30.0000 377 | ]; 378 | 379 | module.exports.RASHI_REVERSE_MAP = RASHI_REVERSE_MAP; 380 | 381 | module.exports.SKEWED_REVERSE_RASHI_MAP = { 382 | 1: "Ar", 383 | 2: "Ta", 384 | 3: "Ge", 385 | 4: "Cn", 386 | 5: "Le", 387 | 6: "Vi", 388 | 7: "Li", 389 | 8: "Sc", 390 | 9: "Sg", 391 | 10: "Cp", 392 | 11: "Aq", 393 | 0: "Pi", 394 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /compatibility.js: -------------------------------------------------------------------------------- 1 | const constants = require("./constants"); 2 | const { getNavamsaChart, getBirthChart } = require("./position"); 3 | const { 4 | calculateNakshatra, 5 | calculateNakshatraCompatibility, 6 | } = require("./nakshatra"); 7 | /** 8 | * @typedef {Object} birthDetails 9 | * @property {String} dateString - Format: YYYY-MM-DD 10 | * @property {String} timeString - Format: HH:MM:SS 11 | * @property {Number} lat - Latitude 12 | * @property {Number} lng - Longitude 13 | * @property {Number} timezone - Timezone in hours, eg: 5.5 14 | */ 15 | 16 | /** 17 | * Figure out whether two people are compatible (Default threshold=0.4) 18 | * @param {birthDetails} person1 First Person 19 | * @param {birthDetails} person2 Second Person 20 | * @param {Number} [threshold=0.4] - Threshold above which function returns true 21 | * @returns {Boolean} Whether two people are compatible given threshold (Default=0.4) 22 | */ 23 | function areCompatibile( 24 | person1, 25 | person2, 26 | threshold = constants.DEFAULT_THRESHOLD 27 | ) { 28 | const person1BirthChart = getBirthChart( 29 | person1.dateString, 30 | person1.timeString, 31 | person1.lat, 32 | person1.lng, 33 | person1.timezone 34 | ); 35 | const person2BirthChart = getBirthChart( 36 | person2.dateString, 37 | person2.timeString, 38 | person2.lat, 39 | person2.lng, 40 | person2.timezone 41 | ); 42 | const person1NavamsaChart = getNavamsaChart(person1BirthChart); 43 | const person2NavamsaChart = getNavamsaChart(person2BirthChart); 44 | 45 | const person1BirthChartHouses = getHousesOfChart(person1BirthChart); 46 | const person2BirthChartHouses = getHousesOfChart(person2BirthChart); 47 | 48 | const person1NavamsaChartHouses = getHousesOfChart(person1NavamsaChart); 49 | const person2NavamsaChartHouses = getHousesOfChart(person2NavamsaChart); 50 | let total_score = 0; 51 | 52 | let D9_p1N_p2B_match = seventhHouseOfD9Check( 53 | person1NavamsaChart, 54 | person2BirthChart 55 | ); 56 | if (D9_p1N_p2B_match) total_score++; 57 | 58 | let D9_p2N_p1B_match = seventhHouseOfD9Check( 59 | person2NavamsaChart, 60 | person1BirthChart 61 | ); 62 | if (D9_p2N_p1B_match) total_score++; 63 | 64 | if (!total_score) return false; // Navamsa Chart condition 65 | 66 | total_score += oppositeSignOfBirthCheck(person1BirthChart, person2BirthChart); // 7th House Map Match? 67 | 68 | // Are the lords of the rising sign friends 69 | total_score += areFriends( 70 | constants.RASHI_LORDS[constants.RASHIS[person1BirthChart.meta.La.rashi]], 71 | constants.RASHI_LORDS[constants.RASHIS[person2BirthChart.meta.La.rashi]] 72 | ); 73 | // Rising to Rising Connection 74 | total_score += connectionType( 75 | person1BirthChart.meta.La.rashi, 76 | person2BirthChart.meta.La.rashi 77 | ); 78 | 79 | // Moon to Moon connection 80 | 81 | total_score += connectionType( 82 | person1BirthChart.meta.Mo.rashi, 83 | person2BirthChart.meta.Mo.rashi 84 | ); 85 | 86 | // Moon's Ruling Lords Friends 87 | 88 | total_score += areFriends( 89 | constants.RASHI_LORDS[constants.RASHIS[person1BirthChart.meta.Mo.rashi]], 90 | constants.RASHI_LORDS[constants.RASHIS[person2BirthChart.meta.Mo.rashi]] 91 | ); 92 | 93 | // Moon conjunct or opposite sun? 94 | 95 | total_score += Number( 96 | person1BirthChart.meta.Mo.rashi === person2BirthChart.meta.Su.rashi || 97 | person1BirthChart.meta.Su.rashi === person2BirthChart.meta.Mo.rashi 98 | ); 99 | 100 | // Sun to Sun connection 101 | total_score += connectionType( 102 | person1BirthChart.meta.Su.rashi, 103 | person2BirthChart.meta.Su.rashi 104 | ); 105 | 106 | // Sun Illumination one (Which house does partnet's sun fall into?) 107 | 108 | total_score += signInterference(person1BirthChart, person2BirthChart, "Su"); 109 | 110 | // Sun Conjunct 7th House? 111 | 112 | total_score += planetConjunctHouse( 113 | person1BirthChart, 114 | person2BirthChart, 115 | "Su", 116 | 7 117 | ); 118 | 119 | // Venus to Venus Connection 120 | 121 | total_score += connectionType( 122 | person1BirthChart.meta.Ve.rashi, 123 | person2BirthChart.meta.Ve.rashi 124 | ); 125 | 126 | // Are Venus Ruling Lord Friends? 127 | 128 | total_score += areFriends( 129 | constants.RASHI_LORDS[constants.RASHIS[person1BirthChart.meta.Ve.rashi]], 130 | constants.RASHI_LORDS[constants.RASHIS[person2BirthChart.meta.Ve.rashi]] 131 | ); 132 | 133 | // Manglik Connection 134 | 135 | total_score += checkManglikConnection(person1BirthChart, person2BirthChart); 136 | 137 | // Mars Ruling Lord friends? 138 | 139 | total_score += areFriends( 140 | constants.RASHI_LORDS[constants.RASHIS[person1BirthChart.meta.Ma.rashi]], 141 | constants.RASHI_LORDS[constants.RASHIS[person2BirthChart.meta.Ma.rashi]] 142 | ); 143 | 144 | // Mars to Mars Connection 145 | total_score += connectionType( 146 | person1BirthChart.meta.Ma.rashi, 147 | person2BirthChart.meta.Ma.rashi 148 | ); 149 | 150 | // Rahu to Rahu or Ketu to Ketu Connection Correspondence 151 | if ( 152 | checkPlanetCorrespondenceOfPlanetInSecondChart( 153 | person1BirthChart, 154 | person2BirthChart, 155 | "Ra" 156 | ) || 157 | checkPlanetCorrespondenceOfPlanetInSecondChart( 158 | person1BirthChart, 159 | person2BirthChart, 160 | "Ke" 161 | ) 162 | ) { 163 | if ( 164 | checkPlanetCorrespondenceOfPlanetInSecondChart( 165 | person2BirthChart, 166 | person1BirthChart, 167 | "Ra" 168 | ) || 169 | checkPlanetCorrespondenceOfPlanetInSecondChart( 170 | person2BirthChart, 171 | person1BirthChart, 172 | "Ke" 173 | ) 174 | ) { 175 | // Two way connection 176 | total_score += 2; 177 | } else total_score += 1; // One way connection 178 | } else { 179 | if ( 180 | checkPlanetCorrespondenceOfPlanetInSecondChart( 181 | person2BirthChart, 182 | person1BirthChart, 183 | "Ra" 184 | ) || 185 | checkPlanetCorrespondenceOfPlanetInSecondChart( 186 | person2BirthChart, 187 | person1BirthChart, 188 | "Ke" 189 | ) 190 | ) { 191 | total_score += 1; // One way connection 192 | } else { 193 | total_score += 0; 194 | } 195 | } 196 | // Saturn to Saturn Connection 197 | if ( 198 | checkPlanetCorrespondenceOfPlanetInSecondChart( 199 | person1BirthChart, 200 | person2BirthChart, 201 | "Sa" 202 | ) 203 | ) { 204 | if ( 205 | checkPlanetCorrespondenceOfPlanetInSecondChart( 206 | person2BirthChart, 207 | person1BirthChart, 208 | "Sa" 209 | ) 210 | ) { 211 | // Two way connection 212 | total_score += 2; 213 | } else total_score += 1; // One way connection 214 | } else { 215 | if ( 216 | checkPlanetCorrespondenceOfPlanetInSecondChart( 217 | person2BirthChart, 218 | person1BirthChart, 219 | "Sa" 220 | ) 221 | ) { 222 | total_score += 1; // One way connection 223 | } else { 224 | total_score += 0; // No connection 225 | } 226 | } 227 | // Nakshatra Compatibility (Overall) 228 | 229 | const animalOfPerson1 = calculateNakshatra(person1BirthChart).animal; 230 | const animalOfPerson2 = calculateNakshatra(person2BirthChart).animal; 231 | 232 | total_score += calculateNakshatraCompatibility( 233 | animalOfPerson1, 234 | animalOfPerson2 235 | ); 236 | 237 | return total_score / 30 >= threshold; // 30 is total score possible 238 | } 239 | 240 | /** 241 | * Figure out whether two people are compatible (Default threshold=0.4) 242 | * @param {birthDetails} person1 First Person 243 | * @param {birthDetails} person2 Second Person 244 | * @param {Number} [threshold=0.4] - Threshold above which function returns true 245 | * @returns {Boolean} Whether two people are compatible given threshold (Default=0.4) 246 | */ 247 | function getCompatibilityScore( 248 | person1, 249 | person2, 250 | threshold = constants.DEFAULT_THRESHOLD 251 | ) { 252 | const interim = []; 253 | const person1BirthChart = getBirthChart( 254 | person1.dateString, 255 | person1.timeString, 256 | person1.lat, 257 | person1.lng, 258 | person1.timezone 259 | ); 260 | const person2BirthChart = getBirthChart( 261 | person2.dateString, 262 | person2.timeString, 263 | person2.lat, 264 | person2.lng, 265 | person2.timezone 266 | ); 267 | const person1NavamsaChart = getNavamsaChart(person1BirthChart); 268 | const person2NavamsaChart = getNavamsaChart(person2BirthChart); 269 | 270 | const person1BirthChartHouses = getHousesOfChart(person1BirthChart); 271 | const person2BirthChartHouses = getHousesOfChart(person2BirthChart); 272 | 273 | const person1NavamsaChartHouses = getHousesOfChart(person1NavamsaChart); 274 | const person2NavamsaChartHouses = getHousesOfChart(person2NavamsaChart); 275 | let total_score = 0; 276 | 277 | let D9_p1N_p2B_match = seventhHouseOfD9Check( 278 | person1NavamsaChart, 279 | person2BirthChart 280 | ); 281 | if (D9_p1N_p2B_match) total_score++; 282 | 283 | let D9_p2N_p1B_match = seventhHouseOfD9Check( 284 | person2NavamsaChart, 285 | person1BirthChart 286 | ); 287 | if (D9_p2N_p1B_match) total_score++; 288 | interim.push({ after_score: total_score, key: "Seventh House of D9" }); 289 | if (!total_score) return false; // Navamsa Chart condition 290 | 291 | total_score += oppositeSignOfBirthCheck(person1BirthChart, person2BirthChart); // 7th House Map Match? 292 | interim.push({ after_score: total_score, key: "7th House Matching?" }); 293 | 294 | // Are the lords of the rising sign friends 295 | total_score += areFriends( 296 | constants.RASHI_LORDS[constants.RASHIS[person1BirthChart.meta.La.rashi]], 297 | constants.RASHI_LORDS[constants.RASHIS[person2BirthChart.meta.La.rashi]] 298 | ); 299 | 300 | interim.push({ 301 | after_score: total_score, 302 | key: "Are Lords of Rising Sign Friends?", 303 | }); 304 | // Rising to Rising Connection 305 | total_score += connectionType( 306 | person1BirthChart.meta.La.rashi, 307 | person2BirthChart.meta.La.rashi 308 | ); 309 | 310 | interim.push({ 311 | after_score: total_score, 312 | key: "Rising to Rising Connection", 313 | }); 314 | 315 | // Moon to Moon connection 316 | 317 | total_score += connectionType( 318 | person1BirthChart.meta.Mo.rashi, 319 | person2BirthChart.meta.Mo.rashi 320 | ); 321 | interim.push({ after_score: total_score, key: "Moon to Moon Connection" }); 322 | // Moon's Ruling Lords Friends 323 | 324 | total_score += areFriends( 325 | constants.RASHI_LORDS[constants.RASHIS[person1BirthChart.meta.Mo.rashi]], 326 | constants.RASHI_LORDS[constants.RASHIS[person2BirthChart.meta.Mo.rashi]] 327 | ); 328 | interim.push({ after_score: total_score, key: "Moon's Ruling Lord Friends" }); 329 | // Moon conjunct or opposite sun? 330 | 331 | total_score += Number( 332 | person1BirthChart.meta.Mo.rashi === person2BirthChart.meta.Su.rashi || 333 | person1BirthChart.meta.Su.rashi === person2BirthChart.meta.Mo.rashi 334 | ); 335 | interim.push({ 336 | after_score: total_score, 337 | key: "Moon conjunct or opposite Sun?", 338 | }); 339 | 340 | // Sun to Sun connection 341 | total_score += connectionType( 342 | person1BirthChart.meta.Su.rashi, 343 | person2BirthChart.meta.Su.rashi 344 | ); 345 | interim.push({ after_score: total_score, key: "Sun to Sun Connection" }); 346 | 347 | // Sun Illumination one (Which house does partnet's sun fall into?) 348 | 349 | total_score += signInterference(person1BirthChart, person2BirthChart, "Su"); 350 | interim.push({ after_score: total_score, key: "Sun's Illumination thing" }); 351 | // Sun Conjunct 7th House? 352 | 353 | total_score += planetConjunctHouse( 354 | person1BirthChart, 355 | person2BirthChart, 356 | "Su", 357 | 7 358 | ); 359 | interim.push({ 360 | after_score: total_score, 361 | key: "Sun conjunct seventh House?", 362 | }); 363 | // Venus to Venus Connection 364 | 365 | total_score += connectionType( 366 | person1BirthChart.meta.Ve.rashi, 367 | person2BirthChart.meta.Ve.rashi 368 | ); 369 | interim.push({ after_score: total_score, key: "Venus to Venus connection" }); 370 | // Are Venus Ruling Lord Friends? 371 | 372 | total_score += areFriends( 373 | constants.RASHI_LORDS[constants.RASHIS[person1BirthChart.meta.Ve.rashi]], 374 | constants.RASHI_LORDS[constants.RASHIS[person2BirthChart.meta.Ve.rashi]] 375 | ); 376 | interim.push({ 377 | after_score: total_score, 378 | key: "Are venus ruling lord friends?", 379 | }); 380 | 381 | // Manglik Connection 382 | 383 | total_score += checkManglikConnection(person1BirthChart, person2BirthChart); 384 | interim.push({ after_score: total_score, key: "Manglik Connection" }); 385 | // Mars Ruling Lord friends? 386 | 387 | total_score += areFriends( 388 | constants.RASHI_LORDS[constants.RASHIS[person1BirthChart.meta.Ma.rashi]], 389 | constants.RASHI_LORDS[constants.RASHIS[person2BirthChart.meta.Ma.rashi]] 390 | ); 391 | interim.push({ after_score: total_score, key: "Mars Ruling Lord Friends?" }); 392 | // Mars to Mars Connection 393 | total_score += connectionType( 394 | person1BirthChart.meta.Ma.rashi, 395 | person2BirthChart.meta.Ma.rashi 396 | ); 397 | interim.push({ after_score: total_score, key: "Mars to Mars Connection" }); 398 | // Rahu to Rahu or Ketu to Ketu Connection Correspondence 399 | if ( 400 | checkPlanetCorrespondenceOfPlanetInSecondChart( 401 | person1BirthChart, 402 | person2BirthChart, 403 | "Ra" 404 | ) || 405 | checkPlanetCorrespondenceOfPlanetInSecondChart( 406 | person1BirthChart, 407 | person2BirthChart, 408 | "Ke" 409 | ) 410 | ) { 411 | if ( 412 | checkPlanetCorrespondenceOfPlanetInSecondChart( 413 | person2BirthChart, 414 | person1BirthChart, 415 | "Ra" 416 | ) || 417 | checkPlanetCorrespondenceOfPlanetInSecondChart( 418 | person2BirthChart, 419 | person1BirthChart, 420 | "Ke" 421 | ) 422 | ) { 423 | // Two way connection 424 | total_score += 2; 425 | } else total_score += 1; // One way connection 426 | } else { 427 | if ( 428 | checkPlanetCorrespondenceOfPlanetInSecondChart( 429 | person2BirthChart, 430 | person1BirthChart, 431 | "Ra" 432 | ) || 433 | checkPlanetCorrespondenceOfPlanetInSecondChart( 434 | person2BirthChart, 435 | person1BirthChart, 436 | "Ke" 437 | ) 438 | ) { 439 | total_score += 1; // One way connection 440 | } else { 441 | total_score += 0; 442 | } 443 | } 444 | interim.push({ after_score: total_score, key: "Rahu to Rahu...." }); 445 | // Saturn to Saturn Connection 446 | if ( 447 | checkPlanetCorrespondenceOfPlanetInSecondChart( 448 | person1BirthChart, 449 | person2BirthChart, 450 | "Sa" 451 | ) 452 | ) { 453 | if ( 454 | checkPlanetCorrespondenceOfPlanetInSecondChart( 455 | person2BirthChart, 456 | person1BirthChart, 457 | "Sa" 458 | ) 459 | ) { 460 | // Two way connection 461 | total_score += 2; 462 | } else total_score += 1; // One way connection 463 | } else { 464 | if ( 465 | checkPlanetCorrespondenceOfPlanetInSecondChart( 466 | person2BirthChart, 467 | person1BirthChart, 468 | "Sa" 469 | ) 470 | ) { 471 | total_score += 1; // One way connection 472 | } else { 473 | total_score += 0; // No connection 474 | } 475 | } 476 | interim.push({ 477 | after_score: total_score, 478 | key: "Saturn to Saturn stuff", 479 | }); 480 | // Nakshatra Compatibility (Overall) 481 | 482 | const animalOfPerson1 = calculateNakshatra(person1BirthChart).animal; 483 | const animalOfPerson2 = calculateNakshatra(person2BirthChart).animal; 484 | 485 | total_score += calculateNakshatraCompatibility( 486 | animalOfPerson1, 487 | animalOfPerson2 488 | ); 489 | interim.push({ after_score: total_score, key: "Nakshatra stuff" }); 490 | 491 | return { interim, total_score }; 492 | } 493 | 494 | /** 495 | * 496 | * @param {Object} chart birthChart 497 | * @returns {Object} key value: house: rashi 498 | */ 499 | function getHousesOfChart(chart) { 500 | const ascendantRashi = chart.meta.La.rashi; 501 | // const getAscendantRashiCode = constants.REVERSE_RASHIS[ascendantRashi]; 502 | const getAscendantRashiOriginalIndex = constants.RASHI_MAP[ascendantRashi]; 503 | const houses = {}; 504 | var j = 0; 505 | for (var i = getAscendantRashiOriginalIndex; i < 12; ++i) { 506 | houses[j + 1] = constants.RASHI_ARRAY[i]; 507 | ++j; 508 | } 509 | j = 0; 510 | if (getAscendantRashiOriginalIndex) { 511 | for (var i = getAscendantRashiOriginalIndex - 1; i >= 0; i--) { 512 | houses[12 - j] = constants.RASHI_ARRAY[i]; 513 | ++j; 514 | } 515 | } 516 | 517 | return houses; 518 | } 519 | 520 | function getReverseHousesOfChart(houses) { 521 | const reverseHouses = {}; 522 | 523 | Object.keys(houses).map((it) => (reverseHouses[houses[it]] = it)); 524 | 525 | return reverseHouses; 526 | } 527 | 528 | function seventhHouseOfD9Check(navamsaChart1, birthChart2) { 529 | const firstPersonGetHouses = getHousesOfChart(navamsaChart1); 530 | const seventhHouseRashi = firstPersonGetHouses[7]; 531 | const convertRashiCodeToReadable = constants.RASHIS[seventhHouseRashi]; 532 | const getRashiLordOfSeventhHouse = 533 | constants.RASHI_LORDS[convertRashiCodeToReadable]; 534 | const whereD9SeventhHouseRashiLordSits = 535 | navamsaChart1.meta[getRashiLordOfSeventhHouse].rashi; 536 | 537 | const secondPersonGetHouses = getHousesOfChart(birthChart2); 538 | const secondPersonGetRashis = getReverseHousesOfChart(secondPersonGetHouses); 539 | const firstPersonsD9LordHouseNumberInSecondPersonsBirthChart = 540 | secondPersonGetRashis[whereD9SeventhHouseRashiLordSits]; 541 | 542 | return ( 543 | constants.GOOD_HOUSES.indexOf( 544 | Number(firstPersonsD9LordHouseNumberInSecondPersonsBirthChart) 545 | ) > 0 546 | ); 547 | } 548 | 549 | function oppositeSignOfBirthCheck(birthChart1, birthChart2) { 550 | const firstPersonHouses = getHousesOfChart(birthChart1); 551 | const secondPersonHouses = getHousesOfChart(birthChart2); 552 | 553 | const firstPersonSeventhHouseSign = firstPersonHouses[7]; 554 | const secondPersonSeventhHouseSign = secondPersonHouses[7]; 555 | 556 | const rulingLordOfFirstPersonSeventhHouseSign = 557 | constants.RASHI_LORDS[constants.RASHIS[firstPersonSeventhHouseSign]]; 558 | const rulingLordOfSecondPersonSeventhHouseSign = 559 | constants.RASHI_LORDS[constants.RASHIS[secondPersonSeventhHouseSign]]; 560 | 561 | const signOfRulingLordOfFirstPerson = 562 | birthChart1.meta[rulingLordOfFirstPersonSeventhHouseSign].rashi; 563 | const signOfRulingLordOfSecondPerson = 564 | birthChart2.meta[rulingLordOfSecondPersonSeventhHouseSign].rashi; 565 | 566 | const oppositeSignOfRulingLordSignFirstPerson = 567 | constants.OPPOSITE_SIGNS[constants.RASHIS[signOfRulingLordOfFirstPerson]]; 568 | const oppositeSignOfRulingLordSignSecondPerson = 569 | constants.OPPOSITE_SIGNS[constants.RASHIS[signOfRulingLordOfSecondPerson]]; 570 | 571 | // console.log( 572 | // signOfRulingLordOfSecondPerson, 573 | // signOfRulingLordOfFirstPerson, 574 | // oppositeSignOfRulingLordSignSecondPerson, 575 | // oppositeSignOfRulingLordSignFirstPerson 576 | // ); 577 | 578 | let total_score = 0; 579 | 580 | // First Person's rising, sun or moon signs 581 | if ( 582 | constants.RASHIS[birthChart1.meta.La.rashi] === 583 | oppositeSignOfRulingLordSignSecondPerson || 584 | constants.RASHIS[birthChart1.meta.Su.rashi] === 585 | oppositeSignOfRulingLordSignSecondPerson || 586 | constants.RASHIS[birthChart1.meta.Mo.rashi] === 587 | oppositeSignOfRulingLordSignSecondPerson 588 | ) { 589 | total_score += 2; 590 | } 591 | 592 | if ( 593 | constants.RASHIS[birthChart2.meta.La.rashi] === 594 | oppositeSignOfRulingLordSignFirstPerson || 595 | constants.RASHIS[birthChart2.meta.Su.rashi] === 596 | oppositeSignOfRulingLordSignFirstPerson || 597 | constants.RASHIS[birthChart2.meta.Mo.rashi] === 598 | oppositeSignOfRulingLordSignFirstPerson 599 | ) { 600 | total_score += 2; 601 | } 602 | 603 | return total_score; 604 | } 605 | 606 | function areFriends(planet1, planet2) { 607 | const isFriend = constants.PLANET_RELATIONS[planet1].friends.indexOf(planet2); 608 | if (isFriend) { 609 | return 2; 610 | } 611 | const isNeutral = constants.PLANET_RELATIONS[planet1].neutral.indexOf( 612 | planet2 613 | ); 614 | if (isNeutral) return 1; 615 | return 0; 616 | } 617 | 618 | function connectionType(sign1, sign2) { 619 | const sign1_map = constants.RASHI_MAP[sign1] + 1; 620 | const sign2_map = constants.RASHI_MAP[sign2] + 1; 621 | let result; 622 | // Result is shortest path from sign1 to sign2 623 | if (sign1_map <= 7 && sign2_map >= 7) { 624 | result = sign2_map - (12 - sign1_map) + 1; 625 | } else if (sign1_map >= 7 && sign2_map <= 7) { 626 | result = sign1_map - (12 - sign2_map) + 1; 627 | } else { 628 | result = Math.abs(sign1_map - sign2_map) + 1; 629 | } 630 | if (constants.GOOD_CONNECTION_TYPES.indexOf(result)) { 631 | return 1; // point 632 | } 633 | return 0; 634 | } 635 | 636 | function signInterference(birthChart1, birthChart2, planet) { 637 | const firstPersonHouses = getHousesOfChart(birthChart1); 638 | const firstPersonReverseHouses = getReverseHousesOfChart(firstPersonHouses); 639 | 640 | const secondPersonHouses = getHousesOfChart(birthChart2); 641 | const secondPersonReverseHouses = getReverseHousesOfChart(secondPersonHouses); 642 | 643 | const firstPersonInterfereSecondPersonPlanetHouse = 644 | firstPersonReverseHouses[birthChart2.meta[planet].rashi]; // Interfere the planets in one other's charts 645 | const secondPersonInterfereFirstPersonPlanetHouse = 646 | secondPersonReverseHouses[birthChart1.meta[planet].rashi]; // Interfere the planets in one other's charts 647 | let score = 0; 648 | if ( 649 | constants.GOOD_HOUSES.indexOf( 650 | Number(firstPersonInterfereSecondPersonPlanetHouse) 651 | ) 652 | ) { 653 | score++; 654 | } 655 | 656 | if ( 657 | constants.GOOD_HOUSES.indexOf( 658 | Number(secondPersonInterfereFirstPersonPlanetHouse) 659 | ) 660 | ) { 661 | score++; 662 | } 663 | 664 | return score; 665 | } 666 | 667 | function planetConjunctHouse(birthChart1, birthChart2, planet, house) { 668 | const person1Houses = getHousesOfChart(birthChart1); 669 | const person2Houses = getHousesOfChart(birthChart2); 670 | 671 | const person1ReverseHouses = getReverseHousesOfChart(person1Houses); 672 | const person2ReverseHouses = getReverseHousesOfChart(person2Houses); 673 | 674 | return Number( 675 | person1ReverseHouses[birthChart2.meta[planet].rashi] == house || 676 | person2ReverseHouses[birthChart1.meta[planet].rashi] == house 677 | ); 678 | } 679 | 680 | function checkManglikConnection(birthChart1, birthChart2) { 681 | const person1Houses = getHousesOfChart(birthChart1); 682 | const person2Houses = getHousesOfChart(birthChart2); 683 | 684 | const person1ReverseHouses = getReverseHousesOfChart(person1Houses); 685 | const person2ReverseHouses = getReverseHousesOfChart(person2Houses); 686 | 687 | const person1MangalRashi = birthChart1.meta.Ma.rashi; 688 | const person2MangalRashi = birthChart2.meta.Ma.rashi; 689 | 690 | const person1MangalBhava = person1ReverseHouses[person1MangalRashi]; 691 | const person2MangalBhava = person2ReverseHouses[person2MangalRashi]; 692 | 693 | if (constants.MANGLIK.indexOf(Number(person1MangalBhava))) { 694 | if (constants.MANGLIK.indexOf(Number(person2MangalBhava))) { 695 | // Both Manglik 696 | return 1; 697 | } 698 | // One is Manglik 699 | return 0; 700 | } else { 701 | if (constants.MANGLIK.indexOf(Number(person2MangalBhava))) { 702 | // One is Manglik 703 | return 0; 704 | } 705 | // Both are Manglik 706 | return 1; 707 | } 708 | } 709 | 710 | function checkPlanetCorrespondenceOfPlanetInSecondChart( 711 | birthChart1, 712 | birthChart2, 713 | planet 714 | ) { 715 | const rashiOfPlanetBC1 = birthChart1.meta[planet].rashi; 716 | const signsInBC2 = birthChart2[constants.RASHIS[rashiOfPlanetBC1]].signs; 717 | 718 | if (signsInBC2.length) { 719 | return true; 720 | } 721 | return false; 722 | } 723 | 724 | module.exports = { 725 | areCompatibile, 726 | getHousesOfChart, 727 | seventhHouseOfD9Check, 728 | oppositeSignOfBirthCheck, 729 | areFriends, 730 | connectionType, 731 | signInterference, 732 | planetConjunctHouse, 733 | checkPlanetCorrespondenceOfPlanetInSecondChart, 734 | getCompatibilityScore, 735 | calculateNakshatra, 736 | calculateNakshatraCompatibility, 737 | }; 738 | --------------------------------------------------------------------------------