caelus 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/chart.d.ts +76 -9
- package/dist/src/chart.js +147 -15
- package/dist/src/derived.d.ts +0 -15
- package/dist/src/derived.js +4 -39
- package/dist/src/rajayoga.js +1 -0
- package/dist/src/yogas.d.ts +2 -2
- package/dist/src/yogas.js +16 -1
- package/package.json +1 -1
package/dist/src/chart.d.ts
CHANGED
|
@@ -10,6 +10,37 @@ export declare const SIGNS: string[];
|
|
|
10
10
|
export declare const ASPECTS: Record<string, number>;
|
|
11
11
|
export declare const DEFAULT_ORBS: Record<string, number>;
|
|
12
12
|
export type HouseSystem = "placidus" | "porphyry" | "equal" | "whole_sign" | "koch" | "regiomontanus" | "campanus" | "alcabitius" | "morinus" | "meridian" | "polich_page" | "vehlow";
|
|
13
|
+
/** The canonical house-system ids, in a stable order (also used for error text). */
|
|
14
|
+
export declare const HOUSE_SYSTEMS: readonly HouseSystem[];
|
|
15
|
+
/** Resolve a forgiving house-system string (any case, spaces or hyphens, or a
|
|
16
|
+
* known alias) to a canonical {@link HouseSystem}, or throw listing the valid
|
|
17
|
+
* ids. Lets MCP, share links, and hand-written calls pass "whole sign",
|
|
18
|
+
* "Whole_Sign", "whole", etc. without tripping the strict union. */
|
|
19
|
+
export declare function normalizeHouseSystem(raw: string): HouseSystem;
|
|
20
|
+
export type Element = "fire" | "earth" | "air" | "water";
|
|
21
|
+
export type Modality = "cardinal" | "fixed" | "mutable";
|
|
22
|
+
/** Triplicity (element) of a sign: `"fire"`, `"earth"`, `"air"`, or `"water"`. */
|
|
23
|
+
export declare function element(sign: number | string): Element;
|
|
24
|
+
/** Quadruplicity (modality) of a sign: `"cardinal"`, `"fixed"`, or `"mutable"`. */
|
|
25
|
+
export declare function modality(sign: number | string): Modality;
|
|
26
|
+
/** 1-based quadrant (I–IV) of a 1-based house number: houses 1–3 -> 1, etc. */
|
|
27
|
+
export declare function quadrant(house: number): number;
|
|
28
|
+
/**
|
|
29
|
+
* Essential dignities a body holds in a sign: any of `"domicile"`,
|
|
30
|
+
* `"exaltation"`, `"detriment"`, `"fall"` (the last two are the signs opposite
|
|
31
|
+
* domicile and exaltation). Empty when the body is peregrine there or has no
|
|
32
|
+
* classical rulership (the outer planets, Chiron, the nodes).
|
|
33
|
+
*
|
|
34
|
+
* @param body Body id, e.g. `"mars"`.
|
|
35
|
+
* @param sign A sign index `0`–`11` (Aries = 0) or its name, e.g. `"Aries"`.
|
|
36
|
+
* @returns The dignities held, in the order above; empty if none.
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* dignities("mars", "Aries"); // ["domicile"]
|
|
40
|
+
* dignities("sun", "Libra"); // ["fall"]
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function dignities(body: string, sign: number | string): string[];
|
|
13
44
|
export type Ayanamsa = keyof typeof AYANAMSA_J2000 & string;
|
|
14
45
|
export type Zodiac = "tropical" | `sidereal:${string}`;
|
|
15
46
|
export interface Observer {
|
|
@@ -58,6 +89,33 @@ export interface Position {
|
|
|
58
89
|
/** Equatorial declination, true equinox of date, degrees. */
|
|
59
90
|
dec: number;
|
|
60
91
|
}
|
|
92
|
+
/** A {@link Position} enriched with chart-relative placement, as returned per
|
|
93
|
+
* body by {@link Engine.chart} and {@link Engine.chartAt}. */
|
|
94
|
+
export interface ChartBody extends Position {
|
|
95
|
+
/** 1-based house the body falls in, by the chart's cusps (1–12). */
|
|
96
|
+
house: number;
|
|
97
|
+
/** Essential dignities held in the body's sign (see {@link dignities});
|
|
98
|
+
* empty when peregrine or for bodies without classical rulerships. */
|
|
99
|
+
dignities: string[];
|
|
100
|
+
}
|
|
101
|
+
/** Default chart bodies that are Chebyshev-packed, so they can fall outside
|
|
102
|
+
* their fitted range (and be omitted from a chart). Opt-in asteroids are
|
|
103
|
+
* packed too, but arrive as arbitrary ids through the string index. */
|
|
104
|
+
export type PackedBody = "chiron";
|
|
105
|
+
/** Bodies guaranteed to be in every chart: the analytic Sun–Pluto and the lunar
|
|
106
|
+
* nodes, which resolve across all supported epochs. (Chiron is Chebyshev-packed
|
|
107
|
+
* and can fall outside its fitted range, so it is *not* guaranteed.) */
|
|
108
|
+
export type AlwaysBody = Exclude<Body, PackedBody>;
|
|
109
|
+
/**
|
|
110
|
+
* A chart's bodies, keyed by id. The analytic core ({@link AlwaysBody}) is
|
|
111
|
+
* always present and needs no presence check. {@link PackedBody} bodies (Chiron)
|
|
112
|
+
* and any opt-in extras requested via {@link ChartOptions.bodies} may be absent
|
|
113
|
+
* when the instant is outside their fitted range (see {@link Chart.unavailable}),
|
|
114
|
+
* so those accesses are typed `ChartBody | undefined` and must be guarded.
|
|
115
|
+
*/
|
|
116
|
+
export type ChartBodies = Record<AlwaysBody, ChartBody> & Partial<Record<PackedBody, ChartBody>> & {
|
|
117
|
+
[id: string]: ChartBody | undefined;
|
|
118
|
+
};
|
|
61
119
|
/** One aspect between two bodies in a {@link Chart}. */
|
|
62
120
|
export interface Aspect {
|
|
63
121
|
/** First body id. */
|
|
@@ -81,8 +139,14 @@ export interface Chart {
|
|
|
81
139
|
houseSystem: HouseSystem;
|
|
82
140
|
/** The house system originally requested, before any polar fallback. */
|
|
83
141
|
houseSystemRequested: HouseSystem;
|
|
84
|
-
/** Apparent
|
|
85
|
-
|
|
142
|
+
/** Apparent position per body, enriched with house and dignities, keyed by
|
|
143
|
+
* body id. See {@link ChartBody}. */
|
|
144
|
+
bodies: ChartBodies;
|
|
145
|
+
/** Body ids that were requested but omitted because the instant falls outside
|
|
146
|
+
* their fitted range (e.g. Chiron and other Chebyshev-packed bodies before
|
|
147
|
+
* ~1850 or after ~2150). Empty for the usual modern dates. The analytic
|
|
148
|
+
* bodies (Sun through Pluto and the nodes) are always present. */
|
|
149
|
+
unavailable: string[];
|
|
86
150
|
/** Chart angles in degrees: Ascendant, Midheaven, Vertex, East Point. */
|
|
87
151
|
angles: {
|
|
88
152
|
asc: number;
|
|
@@ -235,10 +299,10 @@ export declare class Engine {
|
|
|
235
299
|
* instant and place.
|
|
236
300
|
*
|
|
237
301
|
* The first six arguments are calendar fields in **UT** — not local civil
|
|
238
|
-
* time, and not a Julian Day. Passing a JD in `y` builds an instant
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
302
|
+
* time, and not a Julian Day. Passing a JD in `y` builds an absurd instant and
|
|
303
|
+
* throws `RangeError`; use {@link Engine.chartAt} for a chart from a JD. For a
|
|
304
|
+
* birth time given in a local time zone, resolve it to UT first (see the
|
|
305
|
+
* `caelus-birth` package).
|
|
242
306
|
*
|
|
243
307
|
* @param y Year in UT, e.g. `1990` — a calendar year, not a Julian Day.
|
|
244
308
|
* @param mo Month, `1`–`12`.
|
|
@@ -254,9 +318,12 @@ export declare class Engine {
|
|
|
254
318
|
* custom orbs. Defaults to Placidus houses in the tropical zodiac.
|
|
255
319
|
* @returns A {@link Chart}: `bodies`, `cusps`, `angles`, and `aspects`, plus
|
|
256
320
|
* `jdUt` and the house system actually used (Placidus and Koch fall back to
|
|
257
|
-
* whole-sign above the polar circles).
|
|
258
|
-
*
|
|
259
|
-
*
|
|
321
|
+
* whole-sign above the polar circles). A body outside its fitted range
|
|
322
|
+
* (e.g. Chiron before ~1850) is omitted from `bodies` and listed in
|
|
323
|
+
* `unavailable` rather than failing the whole chart.
|
|
324
|
+
* @throws RangeError only if the instant itself is absurd — far outside any
|
|
325
|
+
* supported epoch — which almost always means a Julian Day was passed where
|
|
326
|
+
* calendar fields belong.
|
|
260
327
|
* @example
|
|
261
328
|
* ```ts
|
|
262
329
|
* // 1990-06-10 14:30 UT at Tampa, FL (27.95° N, 82.46° W), Placidus houses
|
package/dist/src/chart.js
CHANGED
|
@@ -23,7 +23,92 @@ export const ASPECTS = {
|
|
|
23
23
|
export const DEFAULT_ORBS = {
|
|
24
24
|
conjunction: 8, sextile: 4, square: 7, trine: 7, opposition: 8,
|
|
25
25
|
};
|
|
26
|
+
/** The canonical house-system ids, in a stable order (also used for error text). */
|
|
27
|
+
export const HOUSE_SYSTEMS = [
|
|
28
|
+
"placidus", "porphyry", "equal", "whole_sign", "koch", "regiomontanus",
|
|
29
|
+
"campanus", "alcabitius", "morinus", "meridian", "polich_page", "vehlow",
|
|
30
|
+
];
|
|
31
|
+
// Short or alternate names that normalization (lowercase + space/hyphen -> "_")
|
|
32
|
+
// can't reach on its own. "whole sign", "Polich Page", etc. already normalize to
|
|
33
|
+
// their canonical id, so only genuinely different spellings live here.
|
|
34
|
+
const HOUSE_ALIASES = {
|
|
35
|
+
whole: "whole_sign", signs: "whole_sign", wholesign: "whole_sign",
|
|
36
|
+
equal_house: "equal", porphyrius: "porphyry", placidean: "placidus",
|
|
37
|
+
};
|
|
38
|
+
/** Resolve a forgiving house-system string (any case, spaces or hyphens, or a
|
|
39
|
+
* known alias) to a canonical {@link HouseSystem}, or throw listing the valid
|
|
40
|
+
* ids. Lets MCP, share links, and hand-written calls pass "whole sign",
|
|
41
|
+
* "Whole_Sign", "whole", etc. without tripping the strict union. */
|
|
42
|
+
export function normalizeHouseSystem(raw) {
|
|
43
|
+
const key = raw.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
44
|
+
if (HOUSE_SYSTEMS.includes(key))
|
|
45
|
+
return key;
|
|
46
|
+
const alias = HOUSE_ALIASES[key];
|
|
47
|
+
if (alias)
|
|
48
|
+
return alias;
|
|
49
|
+
throw new Error(`unknown house system '${raw}' (valid: ${HOUSE_SYSTEMS.join(", ")})`);
|
|
50
|
+
}
|
|
51
|
+
const ELEMENTS = ["fire", "earth", "air", "water"];
|
|
52
|
+
const MODALITIES = ["cardinal", "fixed", "mutable"];
|
|
53
|
+
/** Sign index `0`–`11` (Aries = 0) from an index or a sign name (`"Aries"`). */
|
|
54
|
+
function signIndex(sign) {
|
|
55
|
+
return typeof sign === "number" ? mod(Math.floor(sign), 12) : SIGNS.indexOf(sign);
|
|
56
|
+
}
|
|
57
|
+
/** Triplicity (element) of a sign: `"fire"`, `"earth"`, `"air"`, or `"water"`. */
|
|
58
|
+
export function element(sign) {
|
|
59
|
+
return ELEMENTS[mod(signIndex(sign), 4)];
|
|
60
|
+
}
|
|
61
|
+
/** Quadruplicity (modality) of a sign: `"cardinal"`, `"fixed"`, or `"mutable"`. */
|
|
62
|
+
export function modality(sign) {
|
|
63
|
+
return MODALITIES[mod(signIndex(sign), 3)];
|
|
64
|
+
}
|
|
65
|
+
/** 1-based quadrant (I–IV) of a 1-based house number: houses 1–3 -> 1, etc. */
|
|
66
|
+
export function quadrant(house) {
|
|
67
|
+
return Math.floor(mod(house - 1, 12) / 3) + 1;
|
|
68
|
+
}
|
|
69
|
+
// ----------------------------------------------------------- essential dignities
|
|
70
|
+
const DOMICILE = {
|
|
71
|
+
sun: [4], moon: [3], mercury: [2, 5], venus: [1, 6],
|
|
72
|
+
mars: [0, 7], jupiter: [8, 11], saturn: [9, 10],
|
|
73
|
+
};
|
|
74
|
+
const EXALTATION = {
|
|
75
|
+
sun: 0, moon: 1, mercury: 5, venus: 11, mars: 9, jupiter: 3, saturn: 6,
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Essential dignities a body holds in a sign: any of `"domicile"`,
|
|
79
|
+
* `"exaltation"`, `"detriment"`, `"fall"` (the last two are the signs opposite
|
|
80
|
+
* domicile and exaltation). Empty when the body is peregrine there or has no
|
|
81
|
+
* classical rulership (the outer planets, Chiron, the nodes).
|
|
82
|
+
*
|
|
83
|
+
* @param body Body id, e.g. `"mars"`.
|
|
84
|
+
* @param sign A sign index `0`–`11` (Aries = 0) or its name, e.g. `"Aries"`.
|
|
85
|
+
* @returns The dignities held, in the order above; empty if none.
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* dignities("mars", "Aries"); // ["domicile"]
|
|
89
|
+
* dignities("sun", "Libra"); // ["fall"]
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export function dignities(body, sign) {
|
|
93
|
+
const idx = signIndex(sign);
|
|
94
|
+
const dom = DOMICILE[body] ?? [];
|
|
95
|
+
const out = [];
|
|
96
|
+
if (dom.includes(idx))
|
|
97
|
+
out.push("domicile");
|
|
98
|
+
if (EXALTATION[body] === idx)
|
|
99
|
+
out.push("exaltation");
|
|
100
|
+
if (dom.map((d) => mod(d + 6, 12)).includes(idx))
|
|
101
|
+
out.push("detriment");
|
|
102
|
+
if (body in EXALTATION && mod(EXALTATION[body] + 6, 12) === idx)
|
|
103
|
+
out.push("fall");
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
26
106
|
const KM_PER_AU = 149597870.7;
|
|
107
|
+
// A generous window for the analytic models. Every real chart, however
|
|
108
|
+
// historical, sits well inside it; an instant far outside almost always means a
|
|
109
|
+
// Julian Day was passed to chart() where calendar fields belong.
|
|
110
|
+
const JD_SANE_MIN = -2_000_000; // ~ 10000 BC
|
|
111
|
+
const JD_SANE_MAX = 9_000_000; // ~ 20000 AD
|
|
27
112
|
function parseZodiac(zodiac) {
|
|
28
113
|
if (zodiac === "tropical")
|
|
29
114
|
return null;
|
|
@@ -339,10 +424,10 @@ export class Engine {
|
|
|
339
424
|
* instant and place.
|
|
340
425
|
*
|
|
341
426
|
* The first six arguments are calendar fields in **UT** — not local civil
|
|
342
|
-
* time, and not a Julian Day. Passing a JD in `y` builds an instant
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
427
|
+
* time, and not a Julian Day. Passing a JD in `y` builds an absurd instant and
|
|
428
|
+
* throws `RangeError`; use {@link Engine.chartAt} for a chart from a JD. For a
|
|
429
|
+
* birth time given in a local time zone, resolve it to UT first (see the
|
|
430
|
+
* `caelus-birth` package).
|
|
346
431
|
*
|
|
347
432
|
* @param y Year in UT, e.g. `1990` — a calendar year, not a Julian Day.
|
|
348
433
|
* @param mo Month, `1`–`12`.
|
|
@@ -358,9 +443,12 @@ export class Engine {
|
|
|
358
443
|
* custom orbs. Defaults to Placidus houses in the tropical zodiac.
|
|
359
444
|
* @returns A {@link Chart}: `bodies`, `cusps`, `angles`, and `aspects`, plus
|
|
360
445
|
* `jdUt` and the house system actually used (Placidus and Koch fall back to
|
|
361
|
-
* whole-sign above the polar circles).
|
|
362
|
-
*
|
|
363
|
-
*
|
|
446
|
+
* whole-sign above the polar circles). A body outside its fitted range
|
|
447
|
+
* (e.g. Chiron before ~1850) is omitted from `bodies` and listed in
|
|
448
|
+
* `unavailable` rather than failing the whole chart.
|
|
449
|
+
* @throws RangeError only if the instant itself is absurd — far outside any
|
|
450
|
+
* supported epoch — which almost always means a Julian Day was passed where
|
|
451
|
+
* calendar fields belong.
|
|
364
452
|
* @example
|
|
365
453
|
* ```ts
|
|
366
454
|
* // 1990-06-10 14:30 UT at Tampa, FL (27.95° N, 82.46° W), Placidus houses
|
|
@@ -393,8 +481,12 @@ export class Engine {
|
|
|
393
481
|
* @see {@link Engine.chart} for the calendar-field entry point.
|
|
394
482
|
*/
|
|
395
483
|
chartAt(jdUt, lat, lonEast, opts = "placidus") {
|
|
484
|
+
if (!Number.isFinite(jdUt) || jdUt < JD_SANE_MIN || jdUt > JD_SANE_MAX) {
|
|
485
|
+
throw new RangeError(`chart instant (jd ${jdUt}) is far outside the supported range; if you ` +
|
|
486
|
+
`meant a calendar date, pass year/month/day to chart() rather than a Julian Day.`);
|
|
487
|
+
}
|
|
396
488
|
const o = typeof opts === "string" ? { houseSystem: opts } : opts;
|
|
397
|
-
const houseSystem = o.houseSystem ?? "placidus";
|
|
489
|
+
const houseSystem = normalizeHouseSystem(o.houseSystem ?? "placidus");
|
|
398
490
|
const zodiac = o.zodiac ?? "tropical";
|
|
399
491
|
const mode = parseZodiac(zodiac);
|
|
400
492
|
const calc = {
|
|
@@ -406,8 +498,22 @@ export class Engine {
|
|
|
406
498
|
...BODIES, ...(o.bodies ?? []).filter((b) => !BODIES.includes(b)),
|
|
407
499
|
];
|
|
408
500
|
const bodies = {};
|
|
409
|
-
|
|
410
|
-
|
|
501
|
+
const unavailable = [];
|
|
502
|
+
for (const b of names) {
|
|
503
|
+
try {
|
|
504
|
+
bodies[b] = this.position(b, jdUt, calc);
|
|
505
|
+
}
|
|
506
|
+
catch (e) {
|
|
507
|
+
// A Chebyshev-packed body (Chiron, fitted asteroids) outside its fitted
|
|
508
|
+
// range throws RangeError. Omit it and report it rather than discarding
|
|
509
|
+
// the whole chart; the analytic bodies still resolve. Any other error
|
|
510
|
+
// (e.g. a missing data pack) is a real fault and propagates.
|
|
511
|
+
if (e instanceof RangeError)
|
|
512
|
+
unavailable.push(b);
|
|
513
|
+
else
|
|
514
|
+
throw e;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
411
517
|
const [asc, mc, armc, eps] = H.angles(this.data, jdUt, lat, lonEast);
|
|
412
518
|
const [vtx, east] = H.vertexEastPoint(armc, lat * DEG, eps);
|
|
413
519
|
const phi = lat * DEG;
|
|
@@ -454,7 +560,7 @@ export class Engine {
|
|
|
454
560
|
cusps = H.housesVehlow(armc, phi, eps);
|
|
455
561
|
}
|
|
456
562
|
else {
|
|
457
|
-
throw new Error(`unknown house system '${houseSystem}'`);
|
|
563
|
+
throw new Error(`unknown house system '${houseSystem}' (valid: ${HOUSE_SYSTEMS.join(", ")})`);
|
|
458
564
|
}
|
|
459
565
|
}
|
|
460
566
|
catch (err) {
|
|
@@ -477,21 +583,44 @@ export class Engine {
|
|
|
477
583
|
else {
|
|
478
584
|
cuspsDeg = cusps.map(outDeg);
|
|
479
585
|
}
|
|
586
|
+
// Enrich each position with chart-relative placement (house) and the
|
|
587
|
+
// essential dignities of its sign, so callers don't recompute from cusps.
|
|
588
|
+
const chartBodies = {};
|
|
589
|
+
for (const b of names) {
|
|
590
|
+
const p = bodies[b];
|
|
591
|
+
if (!p)
|
|
592
|
+
continue; // omitted: outside its fitted range (see `unavailable`)
|
|
593
|
+
chartBodies[b] = {
|
|
594
|
+
...p,
|
|
595
|
+
house: houseIndex(p.lon, cuspsDeg),
|
|
596
|
+
dignities: dignities(b, Math.floor(mod(p.lon, 360) / 30)),
|
|
597
|
+
};
|
|
598
|
+
}
|
|
480
599
|
return {
|
|
481
600
|
jdUt,
|
|
482
601
|
zodiac,
|
|
483
602
|
houseSystem: used,
|
|
484
603
|
houseSystemRequested: houseSystem,
|
|
485
|
-
bodies,
|
|
604
|
+
bodies: chartBodies,
|
|
605
|
+
unavailable,
|
|
486
606
|
angles: {
|
|
487
607
|
asc: outDeg(asc), mc: outDeg(mc),
|
|
488
608
|
vertex: outDeg(vtx), eastPoint: outDeg(east),
|
|
489
609
|
},
|
|
490
610
|
cusps: cuspsDeg,
|
|
491
|
-
aspects: findAspects(
|
|
611
|
+
aspects: findAspects(chartBodies, o.orbs ?? DEFAULT_ORBS),
|
|
492
612
|
};
|
|
493
613
|
}
|
|
494
614
|
}
|
|
615
|
+
/** 1-based house for an ecliptic longitude (degrees) given the twelve cusp
|
|
616
|
+
* longitudes (degrees), wrapping across 0. */
|
|
617
|
+
function houseIndex(lon, cusps) {
|
|
618
|
+
for (let i = 0; i < 12; i++) {
|
|
619
|
+
if (mod(lon - cusps[i], 360) < mod(cusps[(i + 1) % 12] - cusps[i], 360))
|
|
620
|
+
return i + 1;
|
|
621
|
+
}
|
|
622
|
+
return 12;
|
|
623
|
+
}
|
|
495
624
|
export function findAspects(bodies, orbs = DEFAULT_ORBS) {
|
|
496
625
|
const out = [];
|
|
497
626
|
const names = Object.keys(bodies).filter((b) => !NOT_ASPECTABLE.has(b));
|
|
@@ -511,8 +640,11 @@ export function findAspects(bodies, orbs = DEFAULT_ORBS) {
|
|
|
511
640
|
return out;
|
|
512
641
|
}
|
|
513
642
|
export function fmtLon(deg) {
|
|
514
|
-
|
|
515
|
-
|
|
643
|
+
// Normalize first: a raw or rounded longitude (e.g. exactly 360, or a small
|
|
644
|
+
// negative) would otherwise index SIGNS out of range and render "undefined".
|
|
645
|
+
const norm = mod(deg, 360);
|
|
646
|
+
const sign = SIGNS[Math.floor(norm / 30)];
|
|
647
|
+
const d = mod(norm, 30);
|
|
516
648
|
const m = mod(d, 1) * 60;
|
|
517
649
|
return `${String(Math.floor(d)).padStart(2)}°${String(Math.floor(m)).padStart(2, "0")}' ${sign}`;
|
|
518
650
|
}
|
package/dist/src/derived.d.ts
CHANGED
|
@@ -109,21 +109,6 @@ export declare function declinationAspects(engine: Engine, bodies: BodyId[], jd:
|
|
|
109
109
|
/** |declination| minus the mean obliquity, degrees. Positive = out of bounds. */
|
|
110
110
|
export declare function outOfBoundsMargin(engine: Engine, body: BodyId, jd: number): number;
|
|
111
111
|
export declare function outOfBounds(engine: Engine, body: BodyId, jd: number): boolean;
|
|
112
|
-
/**
|
|
113
|
-
* Essential dignities a body holds in a sign: any of `"domicile"`,
|
|
114
|
-
* `"exaltation"`, `"detriment"`, `"fall"` (the last two are the signs opposite
|
|
115
|
-
* domicile and exaltation). Empty when the body is peregrine there.
|
|
116
|
-
*
|
|
117
|
-
* @param body Body id, e.g. `"mars"`.
|
|
118
|
-
* @param sign A sign index `0`–`11` (Aries = 0) or its name, e.g. `"Aries"`.
|
|
119
|
-
* @returns The dignities held, in the order above; empty if none.
|
|
120
|
-
* @example
|
|
121
|
-
* ```ts
|
|
122
|
-
* dignities("mars", "Aries"); // ["domicile"]
|
|
123
|
-
* dignities("sun", "Libra"); // ["fall"]
|
|
124
|
-
* ```
|
|
125
|
-
*/
|
|
126
|
-
export declare function dignities(body: string, sign: number | string): string[];
|
|
127
112
|
export declare function dignityOf(engine: Engine, body: BodyId, jd: number, zodiac?: Zodiac): string[];
|
|
128
113
|
/** Diurnal when the Sun is above the horizon at the given place. */
|
|
129
114
|
export declare function isDayChart(engine: Engine, jd: number, lat: number, lonEast: number): boolean;
|
package/dist/src/derived.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* golden fixtures pin the two together.
|
|
10
10
|
*/
|
|
11
11
|
import { mod, meanObliquity, jdTT, DEG } from "./core.js";
|
|
12
|
-
import {
|
|
12
|
+
import { dignities } from "./chart.js";
|
|
13
13
|
import { crossings } from "./events.js";
|
|
14
14
|
import { azAlt } from "./pheno.js";
|
|
15
15
|
export const TROPICAL_YEAR = 365.24219; // mean tropical year, days
|
|
@@ -198,44 +198,9 @@ export function outOfBounds(engine, body, jd) {
|
|
|
198
198
|
return outOfBoundsMargin(engine, body, jd) > 0;
|
|
199
199
|
}
|
|
200
200
|
// ----------------------------------------------------------- dignities
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
};
|
|
205
|
-
const EXALTATION = {
|
|
206
|
-
sun: 0, moon: 1, mercury: 5, venus: 11, mars: 9, jupiter: 3, saturn: 6,
|
|
207
|
-
};
|
|
208
|
-
function signIndex(sign) {
|
|
209
|
-
return typeof sign === "number" ? sign : SIGNS.indexOf(sign);
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Essential dignities a body holds in a sign: any of `"domicile"`,
|
|
213
|
-
* `"exaltation"`, `"detriment"`, `"fall"` (the last two are the signs opposite
|
|
214
|
-
* domicile and exaltation). Empty when the body is peregrine there.
|
|
215
|
-
*
|
|
216
|
-
* @param body Body id, e.g. `"mars"`.
|
|
217
|
-
* @param sign A sign index `0`–`11` (Aries = 0) or its name, e.g. `"Aries"`.
|
|
218
|
-
* @returns The dignities held, in the order above; empty if none.
|
|
219
|
-
* @example
|
|
220
|
-
* ```ts
|
|
221
|
-
* dignities("mars", "Aries"); // ["domicile"]
|
|
222
|
-
* dignities("sun", "Libra"); // ["fall"]
|
|
223
|
-
* ```
|
|
224
|
-
*/
|
|
225
|
-
export function dignities(body, sign) {
|
|
226
|
-
const idx = signIndex(sign);
|
|
227
|
-
const dom = DOMICILE[body] ?? [];
|
|
228
|
-
const out = [];
|
|
229
|
-
if (dom.includes(idx))
|
|
230
|
-
out.push("domicile");
|
|
231
|
-
if (EXALTATION[body] === idx)
|
|
232
|
-
out.push("exaltation");
|
|
233
|
-
if (dom.map((d) => mod(d + 6, 12)).includes(idx))
|
|
234
|
-
out.push("detriment");
|
|
235
|
-
if (body in EXALTATION && mod(EXALTATION[body] + 6, 12) === idx)
|
|
236
|
-
out.push("fall");
|
|
237
|
-
return out;
|
|
238
|
-
}
|
|
201
|
+
// The pure `dignities(body, sign)` table now lives in chart.ts (with the other
|
|
202
|
+
// sign primitives); re-exported through the package index from there. This
|
|
203
|
+
// engine-aware wrapper resolves a body's sign at an instant first.
|
|
239
204
|
export function dignityOf(engine, body, jd, zodiac = "tropical") {
|
|
240
205
|
const lon = engine.longitude(body, jd, { zodiac });
|
|
241
206
|
return dignities(body, mod(Math.floor(lon / 30), 12));
|
package/dist/src/rajayoga.js
CHANGED
|
@@ -9,6 +9,7 @@ export const TRIKONAS = [1, 5, 9];
|
|
|
9
9
|
export const DHANA_HOUSES = [2, 5, 9, 11];
|
|
10
10
|
const PURE_KENDRAS = [4, 7, 10];
|
|
11
11
|
const PURE_TRIKONAS = [5, 9];
|
|
12
|
+
// The seven classical grahas: all analytic, so always present in a chart.
|
|
12
13
|
const PLANETS = ["sun", "moon", "mars", "mercury", "jupiter", "venus", "saturn"];
|
|
13
14
|
/** The traditional ruler of a sign index (0 = Aries). */
|
|
14
15
|
export function signLord(sign) {
|
package/dist/src/yogas.d.ts
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* variant-laden yogas (Kemadruma, lordship-based raja/dhana) are left to a later
|
|
13
13
|
* step. Mirrors the Python reference (astroengine/yogas.py).
|
|
14
14
|
*/
|
|
15
|
-
import { Engine,
|
|
16
|
-
export declare const YOGA_PLANETS:
|
|
15
|
+
import { Engine, Zodiac, AlwaysBody } from "./chart.js";
|
|
16
|
+
export declare const YOGA_PLANETS: readonly AlwaysBody[];
|
|
17
17
|
export interface Yoga {
|
|
18
18
|
yoga: string;
|
|
19
19
|
planets: string[];
|
package/dist/src/yogas.js
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* astroengine yogas -- classical Vedic yogas (planetary combinations) judged on
|
|
3
|
+
* the sidereal rasi (D1) chart.
|
|
4
|
+
*
|
|
5
|
+
* Covers the well-defined, placement-based yogas with no textual variation: the
|
|
6
|
+
* five Pancha Mahapurusha yogas (a non-luminary in its own sign or exaltation
|
|
7
|
+
* AND in a kendra from the Ascendant -- Ruchaka/Mars, Bhadra/Mercury,
|
|
8
|
+
* Hamsa/Jupiter, Malavya/Venus, Shasha/Saturn); Gajakesari (Jupiter in a kendra
|
|
9
|
+
* from the Moon); Budha-Aditya (Sun and Mercury in one sign); and
|
|
10
|
+
* Chandra-Mangala (Moon and Mars in one sign). Own-sign/exaltation use the
|
|
11
|
+
* engine's `dignities`; houses are whole-sign from the Ascendant. The
|
|
12
|
+
* variant-laden yogas (Kemadruma, lordship-based raja/dhana) are left to a later
|
|
13
|
+
* step. Mirrors the Python reference (astroengine/yogas.py).
|
|
14
|
+
*/
|
|
15
|
+
import { dignities } from "./chart.js";
|
|
2
16
|
/** Pancha Mahapurusha: [yoga name, planet]. */
|
|
3
17
|
const MAHAPURUSHA = [
|
|
4
18
|
["Ruchaka", "mars"], ["Bhadra", "mercury"], ["Hamsa", "jupiter"],
|
|
5
19
|
["Malavya", "venus"], ["Shasha", "saturn"],
|
|
6
20
|
];
|
|
7
21
|
const KENDRA = new Set([1, 4, 7, 10]);
|
|
22
|
+
// The seven classical grahas: all analytic, so always present in a chart.
|
|
8
23
|
export const YOGA_PLANETS = ["sun", "moon", "mars", "mercury", "jupiter", "venus", "saturn"];
|
|
9
24
|
/** The placement yogas present in a chart. `signs` maps each of the seven
|
|
10
25
|
* classical planets to its 0-based sign index; `ascSign` is the Ascendant's
|