# Vedic astrology API

Sidereal charts, nakshatras, vargas, KP sub-lords and dashas with nine ayanamsas, computed by @zodiacs/engine/vedic on your own machine.

Engine 1.0.0: On npm.
Archive identity and release status: https://zodiacs.org/developers/engine/

## A sidereal chart

@zodiacs/engine/vedic turns a chart into sidereal longitudes with one of nine ayanamsas, lahiri, fagan-bradley, krishnamurti, raman, yukteswar, true-chitra, true-revati, true-pushya and galactic-center, or one of your own. The ayanamsa is taken at the chart's own instant, nutation included.

The birth details here are synthetic.

~~~javascript
import { siderealChart, nakshatraOf } from '@zodiacs/engine/vedic';
const chart = siderealChart({
  utc: '2000-01-01T12:00:00Z',
  latitude: 28.6139,
  longitude: 77.209,
  houseSystem: 'whole',
}, 'lahiri');
const moon = chart.bodies.find(({ body }) => body === 'Moon');
const { name, pada, lord } = nakshatraOf(moon);
console.log('Lahiri', chart.ayanamsaValue.true.toFixed(4), 'Moon', moon.lon.toFixed(4), name, pada, lord);
~~~

## What else it computes

nakshatraOf gives the nakshatra, its lord and the pada of a sidereal longitude; vargaOf the sixteen vargas of BPHS 6.2–4; kpLordsOf the KP lords; and vimshottariDasha, yoginiDasha and ashtottariDasha the dasha periods from the Moon.

## Where it runs

The Compute API answers in the tropical zodiac only, so Vedic calculation runs in your own process, with no request leaving it. Python has the sidereal modes of Swiss Ephemeris through pyswisseph, under AGPL-3.0.

## Install the release

~~~sh
npm install @zodiacs/engine@1.0.0
~~~

npm's 1.0.0 tarball is byte-identical to the archive the engine repository carries. To install those bytes from the carrier, with their digest checked before npm sees them, run this in the project's directory instead:

~~~sh
( set -eu
# POSIX shell — macOS, Linux or WSL. Not PowerShell. It runs in a subshell, so
# a failure stops the install without closing your terminal.
BASE=$(pwd)
FILE='zodiacs-engine-1.0.0.tgz'
# Run it in your project's directory. Without a package.json here, npm would
# install into the nearest parent directory that has one.
if test ! -f package.json; then
  echo "Stop: there is no package.json here. Run this in your project's directory, or create one first with: npm init -y" >&2
  exit 1
fi
if test -e "$FILE" || test -L "$FILE"; then
  echo "Stop: $FILE already exists here. Move or delete it, then run this again." >&2
  exit 1
fi
# A download that fails verification is removed, so the guard above does not
# then block the retry. Once npm takes over the archive stays: npm reports its
# own failures, and the file is what you would retry with.
trap 'status=$?; if test "$status" -ne 0; then rm -f "$BASE/$FILE"; fi; exit $status' EXIT

curl --disable --fail --silent --show-error --location --proto '=https' --max-time 120 \
  'https://raw.githubusercontent.com/zodiacs-org/engine/38d31854e5716454921b6ce8a211788a0984328e/artifacts/zodiacs-engine-1.0.0.tgz' -o "$FILE"

node --input-type=module <<'JS'
import { readFileSync } from 'node:fs';
import { createHash } from 'node:crypto';
const file = 'zodiacs-engine-1.0.0.tgz';
const expected = 'c4d3754de899fb98882331e6d7b9ce3ce77fb2072baeb002aa0ef8c77b0ab0f6';
const bytes = readFileSync(file);
const actual = createHash('sha256').update(bytes).digest('hex');
if (actual !== expected) {
  console.error(`Stop: this is not the published archive.\n  expected ${expected}\n  got      ${actual}`);
  console.error('Nothing was installed.');
  process.exit(1);
}
console.log(`Archive verified: ${actual}`);
JS

trap - EXIT
npm install --ignore-scripts "./$FILE"
echo "Installed @zodiacs/engine@1.0.0 from the verified archive."
)
~~~

## References

- [Calculation conventions](https://zodiacs.org/developers/docs/conventions/)
- [Engine reference](https://zodiacs.org/developers/engine/reference/)
