caelus 0.11.0 → 0.13.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/README.md +1 -1
- package/accuracy.json +1 -1
- package/dist/src/chart.d.ts +193 -13
- package/dist/src/chart.js +163 -13
- package/dist/src/compiler.d.ts +44 -3
- package/dist/src/compiler.js +44 -3
- package/dist/src/core.d.ts +33 -2
- package/dist/src/core.js +33 -2
- package/dist/src/derived.d.ts +91 -2
- package/dist/src/derived.js +91 -2
- package/dist/src/directions.d.ts +27 -0
- package/dist/src/directions.js +69 -0
- package/dist/src/eclipses.d.ts +17 -1
- package/dist/src/eclipses.js +17 -1
- package/dist/src/events.d.ts +53 -7
- package/dist/src/events.js +53 -7
- package/dist/src/features.d.ts +69 -7
- package/dist/src/features.js +69 -7
- package/dist/src/firdaria.d.ts +49 -0
- package/dist/src/firdaria.js +62 -0
- package/dist/src/houses.d.ts +13 -4
- package/dist/src/houses.js +13 -4
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.js +9 -0
- package/dist/src/lots.d.ts +18 -0
- package/dist/src/lots.js +52 -0
- package/dist/src/pheno.d.ts +16 -2
- package/dist/src/pheno.js +16 -2
- package/dist/src/profections.d.ts +27 -0
- package/dist/src/profections.js +49 -0
- package/dist/src/query.d.ts +47 -6
- package/dist/src/query.js +47 -6
- package/dist/src/releasing.d.ts +32 -0
- package/dist/src/releasing.js +109 -0
- package/dist/src/turbo.d.ts +35 -1
- package/dist/src/turbo.js +35 -1
- package/dist/src/vargas.d.ts +32 -0
- package/dist/src/vargas.js +52 -0
- package/dist/src/vedic.d.ts +66 -0
- package/dist/src/vedic.js +101 -0
- package/dist/src/yogas.d.ts +26 -0
- package/dist/src/yogas.js +39 -0
- package/dist/src/yogini.d.ts +54 -0
- package/dist/src/yogini.js +63 -0
- package/package.json +1 -1
package/dist/src/features.d.ts
CHANGED
|
@@ -1,19 +1,63 @@
|
|
|
1
1
|
import { Engine, BodyId, Zodiac } from "./chart.js";
|
|
2
2
|
import { RankedMoment } from "./scan.js";
|
|
3
3
|
export declare const DEFAULT_BODIES: string[];
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
4
|
+
/**
|
|
5
|
+
* Build a feature vector from explicit `(longitude, weight)` pairs: each pair
|
|
6
|
+
* contributes a weighted unit-circle point `[w·cos(lon), w·sin(lon)]`. The
|
|
7
|
+
* low-level primitive behind {@link chartFeatures}; most callers want that.
|
|
8
|
+
*
|
|
9
|
+
* @param weightedLons `[longitudeDeg, weight]` pairs, in the order they should
|
|
10
|
+
* appear in the vector.
|
|
11
|
+
* @returns A flat vector, two entries per pair.
|
|
12
|
+
*/
|
|
6
13
|
export declare function featureVector(weightedLons: [number, number][]): number[];
|
|
7
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Cosine similarity of two feature vectors, in `[-1, 1]`. For vectors from
|
|
16
|
+
* {@link chartFeatures} this is a weighted mean of `cos(Δlongitude)` per body:
|
|
17
|
+
* `1` when the configurations coincide, falling off as bodies diverge.
|
|
18
|
+
*
|
|
19
|
+
* @param a First feature vector.
|
|
20
|
+
* @param b Second feature vector (compared over the shorter length).
|
|
21
|
+
* @returns Similarity in `[-1, 1]`; `0` if either vector is all zeros.
|
|
22
|
+
*/
|
|
8
23
|
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
9
24
|
export interface FeatureOptions {
|
|
10
25
|
bodies?: BodyId[];
|
|
11
26
|
weights?: Record<string, number>;
|
|
12
27
|
zodiac?: Zodiac;
|
|
13
28
|
}
|
|
14
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Encode the sky at an instant as a feature vector: each body's ecliptic
|
|
31
|
+
* longitude becomes a weighted unit-circle point. The deterministic substrate
|
|
32
|
+
* for matching and searching chart configurations — compare two with
|
|
33
|
+
* {@link cosineSimilarity}, or rank a time range against one with
|
|
34
|
+
* {@link searchConfigurations}.
|
|
35
|
+
*
|
|
36
|
+
* @param engine The engine used to evaluate positions.
|
|
37
|
+
* @param jdUt Julian Day in UT.
|
|
38
|
+
* @param opts `bodies` (ordered; defaults to the ten major bodies), per-body
|
|
39
|
+
* `weights`, and `zodiac` (tropical by default).
|
|
40
|
+
* @returns A flat vector `[w·cos(lon), w·sin(lon), ...]`, two entries per body
|
|
41
|
+
* in `bodies` order.
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const target = chartFeatures(engine, julianDay(2000, 1, 1));
|
|
45
|
+
* const now = chartFeatures(engine, julianDay(2025, 6, 1));
|
|
46
|
+
* cosineSimilarity(now, target); // 1 = identical configuration
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
15
49
|
export declare function chartFeatures(engine: Engine, jdUt: number, opts?: FeatureOptions): number[];
|
|
16
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* Similarity between the sky at `jdUt` and a target feature vector — shorthand
|
|
52
|
+
* for `cosineSimilarity(chartFeatures(engine, jdUt, opts), target)`. The scoring
|
|
53
|
+
* function {@link searchConfigurations} maximizes.
|
|
54
|
+
*
|
|
55
|
+
* @param engine The engine used to evaluate positions.
|
|
56
|
+
* @param jdUt Julian Day in UT.
|
|
57
|
+
* @param target A target feature vector from {@link chartFeatures}.
|
|
58
|
+
* @param opts {@link FeatureOptions} — must match those used to build `target`.
|
|
59
|
+
* @returns Cosine similarity in `[-1, 1]`.
|
|
60
|
+
*/
|
|
17
61
|
export declare function configurationFit(engine: Engine, jdUt: number, target: number[], opts?: FeatureOptions): number;
|
|
18
62
|
export interface SearchConfigOptions extends FeatureOptions {
|
|
19
63
|
start: number;
|
|
@@ -21,6 +65,24 @@ export interface SearchConfigOptions extends FeatureOptions {
|
|
|
21
65
|
step: number;
|
|
22
66
|
limit?: number;
|
|
23
67
|
}
|
|
24
|
-
/**
|
|
25
|
-
*
|
|
68
|
+
/**
|
|
69
|
+
* Rank the instants in `[start, end]` by how closely the sky resembles a
|
|
70
|
+
* `target` feature vector, best first — a realization search over the feature
|
|
71
|
+
* space. Build `target` with {@link chartFeatures} (e.g. from a natal chart).
|
|
72
|
+
*
|
|
73
|
+
* @param engine The engine used to evaluate positions.
|
|
74
|
+
* @param target A target feature vector from {@link chartFeatures}.
|
|
75
|
+
* @param opts `start`/`end` (Julian Days, UT) and `step` (days) define the
|
|
76
|
+
* scan, `limit` caps the results, plus the {@link FeatureOptions} (`bodies`,
|
|
77
|
+
* `weights`, `zodiac`) — which must match those used to build `target`.
|
|
78
|
+
* @returns Ranked `{ jd, score }` moments, highest similarity first.
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* const natal = chartFeatures(engine, julianDay(1990, 6, 10, 14, 30));
|
|
82
|
+
* const matches = searchConfigurations(engine, natal, {
|
|
83
|
+
* start: julianDay(2025, 1, 1), end: julianDay(2026, 1, 1), step: 1, limit: 5,
|
|
84
|
+
* });
|
|
85
|
+
* matches[0].jd; // best-matching instant
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
26
88
|
export declare function searchConfigurations(engine: Engine, target: number[], opts: SearchConfigOptions): RankedMoment[];
|
package/dist/src/features.js
CHANGED
|
@@ -13,8 +13,15 @@ import { DEG } from "./core.js";
|
|
|
13
13
|
import { rankMoments } from "./scan.js";
|
|
14
14
|
export const DEFAULT_BODIES = ["sun", "moon", "mercury", "venus", "mars",
|
|
15
15
|
"jupiter", "saturn", "uranus", "neptune", "pluto"];
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
16
|
+
/**
|
|
17
|
+
* Build a feature vector from explicit `(longitude, weight)` pairs: each pair
|
|
18
|
+
* contributes a weighted unit-circle point `[w·cos(lon), w·sin(lon)]`. The
|
|
19
|
+
* low-level primitive behind {@link chartFeatures}; most callers want that.
|
|
20
|
+
*
|
|
21
|
+
* @param weightedLons `[longitudeDeg, weight]` pairs, in the order they should
|
|
22
|
+
* appear in the vector.
|
|
23
|
+
* @returns A flat vector, two entries per pair.
|
|
24
|
+
*/
|
|
18
25
|
export function featureVector(weightedLons) {
|
|
19
26
|
const out = [];
|
|
20
27
|
for (const [lon, w] of weightedLons) {
|
|
@@ -23,7 +30,15 @@ export function featureVector(weightedLons) {
|
|
|
23
30
|
}
|
|
24
31
|
return out;
|
|
25
32
|
}
|
|
26
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Cosine similarity of two feature vectors, in `[-1, 1]`. For vectors from
|
|
35
|
+
* {@link chartFeatures} this is a weighted mean of `cos(Δlongitude)` per body:
|
|
36
|
+
* `1` when the configurations coincide, falling off as bodies diverge.
|
|
37
|
+
*
|
|
38
|
+
* @param a First feature vector.
|
|
39
|
+
* @param b Second feature vector (compared over the shorter length).
|
|
40
|
+
* @returns Similarity in `[-1, 1]`; `0` if either vector is all zeros.
|
|
41
|
+
*/
|
|
27
42
|
export function cosineSimilarity(a, b) {
|
|
28
43
|
let dot = 0, na = 0, nb = 0;
|
|
29
44
|
const n = Math.min(a.length, b.length);
|
|
@@ -36,7 +51,26 @@ export function cosineSimilarity(a, b) {
|
|
|
36
51
|
return 0;
|
|
37
52
|
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
38
53
|
}
|
|
39
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Encode the sky at an instant as a feature vector: each body's ecliptic
|
|
56
|
+
* longitude becomes a weighted unit-circle point. The deterministic substrate
|
|
57
|
+
* for matching and searching chart configurations — compare two with
|
|
58
|
+
* {@link cosineSimilarity}, or rank a time range against one with
|
|
59
|
+
* {@link searchConfigurations}.
|
|
60
|
+
*
|
|
61
|
+
* @param engine The engine used to evaluate positions.
|
|
62
|
+
* @param jdUt Julian Day in UT.
|
|
63
|
+
* @param opts `bodies` (ordered; defaults to the ten major bodies), per-body
|
|
64
|
+
* `weights`, and `zodiac` (tropical by default).
|
|
65
|
+
* @returns A flat vector `[w·cos(lon), w·sin(lon), ...]`, two entries per body
|
|
66
|
+
* in `bodies` order.
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const target = chartFeatures(engine, julianDay(2000, 1, 1));
|
|
70
|
+
* const now = chartFeatures(engine, julianDay(2025, 6, 1));
|
|
71
|
+
* cosineSimilarity(now, target); // 1 = identical configuration
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
40
74
|
export function chartFeatures(engine, jdUt, opts = {}) {
|
|
41
75
|
const bodies = opts.bodies ?? DEFAULT_BODIES;
|
|
42
76
|
const zodiac = opts.zodiac ?? "tropical";
|
|
@@ -46,12 +80,40 @@ export function chartFeatures(engine, jdUt, opts = {}) {
|
|
|
46
80
|
]);
|
|
47
81
|
return featureVector(wl);
|
|
48
82
|
}
|
|
49
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* Similarity between the sky at `jdUt` and a target feature vector — shorthand
|
|
85
|
+
* for `cosineSimilarity(chartFeatures(engine, jdUt, opts), target)`. The scoring
|
|
86
|
+
* function {@link searchConfigurations} maximizes.
|
|
87
|
+
*
|
|
88
|
+
* @param engine The engine used to evaluate positions.
|
|
89
|
+
* @param jdUt Julian Day in UT.
|
|
90
|
+
* @param target A target feature vector from {@link chartFeatures}.
|
|
91
|
+
* @param opts {@link FeatureOptions} — must match those used to build `target`.
|
|
92
|
+
* @returns Cosine similarity in `[-1, 1]`.
|
|
93
|
+
*/
|
|
50
94
|
export function configurationFit(engine, jdUt, target, opts = {}) {
|
|
51
95
|
return cosineSimilarity(chartFeatures(engine, jdUt, opts), target);
|
|
52
96
|
}
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
97
|
+
/**
|
|
98
|
+
* Rank the instants in `[start, end]` by how closely the sky resembles a
|
|
99
|
+
* `target` feature vector, best first — a realization search over the feature
|
|
100
|
+
* space. Build `target` with {@link chartFeatures} (e.g. from a natal chart).
|
|
101
|
+
*
|
|
102
|
+
* @param engine The engine used to evaluate positions.
|
|
103
|
+
* @param target A target feature vector from {@link chartFeatures}.
|
|
104
|
+
* @param opts `start`/`end` (Julian Days, UT) and `step` (days) define the
|
|
105
|
+
* scan, `limit` caps the results, plus the {@link FeatureOptions} (`bodies`,
|
|
106
|
+
* `weights`, `zodiac`) — which must match those used to build `target`.
|
|
107
|
+
* @returns Ranked `{ jd, score }` moments, highest similarity first.
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const natal = chartFeatures(engine, julianDay(1990, 6, 10, 14, 30));
|
|
111
|
+
* const matches = searchConfigurations(engine, natal, {
|
|
112
|
+
* start: julianDay(2025, 1, 1), end: julianDay(2026, 1, 1), step: 1, limit: 5,
|
|
113
|
+
* });
|
|
114
|
+
* matches[0].jd; // best-matching instant
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
55
117
|
export function searchConfigurations(engine, target, opts) {
|
|
56
118
|
return rankMoments({ start: opts.start, end: opts.end, step: opts.step, limit: opts.limit }, (jd) => configurationFit(engine, jd, target, opts));
|
|
57
119
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* astroengine firdaria -- the Persian/medieval system of planetary time-lord
|
|
3
|
+
* periods (firdariyyat).
|
|
4
|
+
*
|
|
5
|
+
* Life divides into nine periods totalling 75 years: the seven planets in the
|
|
6
|
+
* firdaria order, then the two lunar nodes. A day chart begins with the Sun, a
|
|
7
|
+
* night chart with the Moon; both follow the same cycle (Sun, Venus, Mercury,
|
|
8
|
+
* Moon, Saturn, Jupiter, Mars) and close with the North and South Nodes. Each
|
|
9
|
+
* planetary period splits into seven equal sub-periods led by the seven planets
|
|
10
|
+
* from that period's lord; node periods have no sub-divisions. Pure time
|
|
11
|
+
* arithmetic on the natal moment and the chart's sect. Mirrors the Python
|
|
12
|
+
* reference (astroengine/firdaria.py); the golden fixtures pin the two together.
|
|
13
|
+
*/
|
|
14
|
+
import { Engine } from "./chart.js";
|
|
15
|
+
/** The firdaria cycle of the seven planets. */
|
|
16
|
+
export declare const FIRDARIA_ORDER: readonly ["sun", "venus", "mercury", "moon", "saturn", "jupiter", "mars"];
|
|
17
|
+
/** Period length in years for each of the seven planets. */
|
|
18
|
+
export declare const FIRDARIA_YEARS: Record<(typeof FIRDARIA_ORDER)[number], number>;
|
|
19
|
+
/** The two nodes close the sequence with no sub-periods (70 + 5 = 75 years). */
|
|
20
|
+
export declare const NODE_PERIODS: ReadonlyArray<readonly [string, number]>;
|
|
21
|
+
/** The nine major firdaria periods in order, as `[lord, years]` pairs. */
|
|
22
|
+
export declare function firdariaSequence(day: boolean): Array<[string, number]>;
|
|
23
|
+
export interface FirdariaSub {
|
|
24
|
+
lord: string;
|
|
25
|
+
start: number;
|
|
26
|
+
end: number;
|
|
27
|
+
}
|
|
28
|
+
export interface FirdariaPeriod {
|
|
29
|
+
lord: string;
|
|
30
|
+
years: number;
|
|
31
|
+
start: number;
|
|
32
|
+
end: number;
|
|
33
|
+
sub: FirdariaSub[];
|
|
34
|
+
}
|
|
35
|
+
/** The full firdaria timeline from birth. */
|
|
36
|
+
export declare function firdaria(day: boolean, natalJd: number, yearLength?: number): FirdariaPeriod[];
|
|
37
|
+
/** The major and sub firdar lord active at `targetJd`; both null outside the
|
|
38
|
+
* 75-year span. */
|
|
39
|
+
export declare function firdariaActive(day: boolean, natalJd: number, targetJd: number, yearLength?: number): {
|
|
40
|
+
major: string | null;
|
|
41
|
+
sub: string | null;
|
|
42
|
+
};
|
|
43
|
+
/** The active firdar at `targetJd`, taking the chart's sect from the natal
|
|
44
|
+
* moment and place. */
|
|
45
|
+
export declare function firdariaAt(engine: Engine, natalJd: number, targetJd: number, lat: number, lonEast: number, yearLength?: number): {
|
|
46
|
+
day: boolean;
|
|
47
|
+
major: string | null;
|
|
48
|
+
sub: string | null;
|
|
49
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { TROPICAL_YEAR, isDayChart } from "./derived.js";
|
|
2
|
+
/** The firdaria cycle of the seven planets. */
|
|
3
|
+
export const FIRDARIA_ORDER = [
|
|
4
|
+
"sun", "venus", "mercury", "moon", "saturn", "jupiter", "mars",
|
|
5
|
+
];
|
|
6
|
+
/** Period length in years for each of the seven planets. */
|
|
7
|
+
export const FIRDARIA_YEARS = {
|
|
8
|
+
sun: 10, venus: 8, mercury: 13, moon: 9, saturn: 11, jupiter: 12, mars: 7,
|
|
9
|
+
};
|
|
10
|
+
/** The two nodes close the sequence with no sub-periods (70 + 5 = 75 years). */
|
|
11
|
+
export const NODE_PERIODS = [
|
|
12
|
+
["north_node", 3], ["south_node", 2],
|
|
13
|
+
];
|
|
14
|
+
/** The nine major firdaria periods in order, as `[lord, years]` pairs. */
|
|
15
|
+
export function firdariaSequence(day) {
|
|
16
|
+
const start = day ? 0 : FIRDARIA_ORDER.indexOf("moon");
|
|
17
|
+
const planets = [];
|
|
18
|
+
for (let i = 0; i < 7; i++) {
|
|
19
|
+
const lord = FIRDARIA_ORDER[(start + i) % 7];
|
|
20
|
+
planets.push([lord, FIRDARIA_YEARS[lord]]);
|
|
21
|
+
}
|
|
22
|
+
return [...planets, ...NODE_PERIODS.map((p) => [p[0], p[1]])];
|
|
23
|
+
}
|
|
24
|
+
/** The full firdaria timeline from birth. */
|
|
25
|
+
export function firdaria(day, natalJd, yearLength = TROPICAL_YEAR) {
|
|
26
|
+
const out = [];
|
|
27
|
+
let t = natalJd;
|
|
28
|
+
for (const [lord, years] of firdariaSequence(day)) {
|
|
29
|
+
const span = years * yearLength;
|
|
30
|
+
const major = { lord, years, start: t, end: t + span, sub: [] };
|
|
31
|
+
const li = FIRDARIA_ORDER.indexOf(lord);
|
|
32
|
+
if (li >= 0) {
|
|
33
|
+
const subSpan = span / 7;
|
|
34
|
+
let st = t;
|
|
35
|
+
for (let k = 0; k < 7; k++) {
|
|
36
|
+
const sl = FIRDARIA_ORDER[(li + k) % 7];
|
|
37
|
+
major.sub.push({ lord: sl, start: st, end: st + subSpan });
|
|
38
|
+
st += subSpan;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
out.push(major);
|
|
42
|
+
t += span;
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
/** The major and sub firdar lord active at `targetJd`; both null outside the
|
|
47
|
+
* 75-year span. */
|
|
48
|
+
export function firdariaActive(day, natalJd, targetJd, yearLength = TROPICAL_YEAR) {
|
|
49
|
+
for (const major of firdaria(day, natalJd, yearLength)) {
|
|
50
|
+
if (major.start <= targetJd && targetJd < major.end) {
|
|
51
|
+
const sub = major.sub.find((s) => s.start <= targetJd && targetJd < s.end);
|
|
52
|
+
return { major: major.lord, sub: sub ? sub.lord : null };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { major: null, sub: null };
|
|
56
|
+
}
|
|
57
|
+
/** The active firdar at `targetJd`, taking the chart's sect from the natal
|
|
58
|
+
* moment and place. */
|
|
59
|
+
export function firdariaAt(engine, natalJd, targetJd, lat, lonEast, yearLength = TROPICAL_YEAR) {
|
|
60
|
+
const day = isDayChart(engine, natalJd, lat, lonEast);
|
|
61
|
+
return { day, ...firdariaActive(day, natalJd, targetJd, yearLength) };
|
|
62
|
+
}
|
package/dist/src/houses.d.ts
CHANGED
|
@@ -41,9 +41,18 @@ export declare function housesPolichPage(armc: number, phi: number, eps: number)
|
|
|
41
41
|
/** Vehlow: equal houses with the ASC at the middle of house 1. */
|
|
42
42
|
export declare function housesVehlow(armc: number, phi: number, eps: number): number[];
|
|
43
43
|
/**
|
|
44
|
-
* Placidus cusps via the classic iterative
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
44
|
+
* Placidus house cusps via the classic iterative semi-arc scheme: for all four
|
|
45
|
+
* intermediate cusps RA = ARMC + offset + f·AD with AD = asin(tan φ · tan δ);
|
|
46
|
+
* offsets 30/60/120/150, f = 1/3, 2/3, 2/3, 1/3. Undefined above the polar
|
|
47
|
+
* circles, as Placidus itself is.
|
|
48
|
+
*
|
|
49
|
+
* Low-level: {@link Engine.chart} calls this for you when the house system is
|
|
50
|
+
* `"placidus"`, falling back to whole-sign near the poles. Inputs and outputs
|
|
51
|
+
* are in **radians**.
|
|
52
|
+
*
|
|
53
|
+
* @param armc Right ascension of the MC, in radians.
|
|
54
|
+
* @param phi Geographic latitude, in radians.
|
|
55
|
+
* @param eps Obliquity of the ecliptic, in radians.
|
|
56
|
+
* @returns The twelve cusp longitudes in radians, house 1 (Ascendant) first.
|
|
48
57
|
*/
|
|
49
58
|
export declare function housesPlacidus(armc: number, phi: number, eps: number): number[];
|
package/dist/src/houses.js
CHANGED
|
@@ -257,10 +257,19 @@ export function housesVehlow(armc, phi, eps) {
|
|
|
257
257
|
return Array.from({ length: 12 }, (_, i) => mod(asc - 15 * DEG + i * 30 * DEG, TWO_PI));
|
|
258
258
|
}
|
|
259
259
|
/**
|
|
260
|
-
* Placidus cusps via the classic iterative
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
260
|
+
* Placidus house cusps via the classic iterative semi-arc scheme: for all four
|
|
261
|
+
* intermediate cusps RA = ARMC + offset + f·AD with AD = asin(tan φ · tan δ);
|
|
262
|
+
* offsets 30/60/120/150, f = 1/3, 2/3, 2/3, 1/3. Undefined above the polar
|
|
263
|
+
* circles, as Placidus itself is.
|
|
264
|
+
*
|
|
265
|
+
* Low-level: {@link Engine.chart} calls this for you when the house system is
|
|
266
|
+
* `"placidus"`, falling back to whole-sign near the poles. Inputs and outputs
|
|
267
|
+
* are in **radians**.
|
|
268
|
+
*
|
|
269
|
+
* @param armc Right ascension of the MC, in radians.
|
|
270
|
+
* @param phi Geographic latitude, in radians.
|
|
271
|
+
* @param eps Obliquity of the ecliptic, in radians.
|
|
272
|
+
* @returns The twelve cusp longitudes in radians, house 1 (Ascendant) first.
|
|
264
273
|
*/
|
|
265
274
|
export function housesPlacidus(armc, phi, eps) {
|
|
266
275
|
const cusp = (offsetDeg, f) => {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -15,3 +15,12 @@ export * from "./astrocartography.js";
|
|
|
15
15
|
export * from "./ephemeris.js";
|
|
16
16
|
export * from "./features.js";
|
|
17
17
|
export * from "./compiler.js";
|
|
18
|
+
export * from "./lots.js";
|
|
19
|
+
export * from "./profections.js";
|
|
20
|
+
export * from "./firdaria.js";
|
|
21
|
+
export * from "./releasing.js";
|
|
22
|
+
export * from "./vedic.js";
|
|
23
|
+
export * from "./directions.js";
|
|
24
|
+
export * from "./vargas.js";
|
|
25
|
+
export * from "./yogini.js";
|
|
26
|
+
export * from "./yogas.js";
|
package/dist/src/index.js
CHANGED
|
@@ -15,3 +15,12 @@ export * from "./astrocartography.js";
|
|
|
15
15
|
export * from "./ephemeris.js";
|
|
16
16
|
export * from "./features.js";
|
|
17
17
|
export * from "./compiler.js";
|
|
18
|
+
export * from "./lots.js";
|
|
19
|
+
export * from "./profections.js";
|
|
20
|
+
export * from "./firdaria.js";
|
|
21
|
+
export * from "./releasing.js";
|
|
22
|
+
export * from "./vedic.js";
|
|
23
|
+
export * from "./directions.js";
|
|
24
|
+
export * from "./vargas.js";
|
|
25
|
+
export * from "./yogini.js";
|
|
26
|
+
export * from "./yogas.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Engine, Zodiac } from "./chart.js";
|
|
2
|
+
/** The seven Hermetic lots, in their conventional order. */
|
|
3
|
+
export declare const HERMETIC_LOTS: readonly ["fortune", "spirit", "eros", "necessity", "courage", "victory", "nemesis"];
|
|
4
|
+
export type HermeticLot = (typeof HERMETIC_LOTS)[number];
|
|
5
|
+
/** Lot of Fortune: Asc + Moon - Sun by day, Asc + Sun - Moon by night. */
|
|
6
|
+
export declare function lotFortune(asc: number, sun: number, moon: number, day: boolean): number;
|
|
7
|
+
/** Lot of Spirit (the reverse of Fortune): Asc + Sun - Moon by day. */
|
|
8
|
+
export declare function lotSpirit(asc: number, sun: number, moon: number, day: boolean): number;
|
|
9
|
+
/** The seven Hermetic lots from the Ascendant, sect, and the seven planets'
|
|
10
|
+
* longitudes (degrees). Pure arithmetic. */
|
|
11
|
+
export declare function hermeticLots(asc: number, day: boolean, sun: number, moon: number, mercury: number, venus: number, mars: number, jupiter: number, saturn: number): Record<HermeticLot, number>;
|
|
12
|
+
export interface ChartLots extends Record<HermeticLot, number> {
|
|
13
|
+
/** True when the Sun is above the horizon (a diurnal chart). */
|
|
14
|
+
day: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** The seven Hermetic lots of a chart: compute the Ascendant and sect, then the
|
|
17
|
+
* lots from the seven planets' longitudes. */
|
|
18
|
+
export declare function lots(engine: Engine, jdUt: number, lat: number, lonEast: number, zodiac?: Zodiac): ChartLots;
|
package/dist/src/lots.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* astroengine lots -- Hellenistic lots (Arabic parts), sect-aware.
|
|
3
|
+
*
|
|
4
|
+
* A lot is an arc cast from the Ascendant equal to the arc between two chart
|
|
5
|
+
* points, reversing direction between a day and a night chart. Arithmetic on
|
|
6
|
+
* apparent longitudes already checked against Swiss Ephemeris. Mirrors the
|
|
7
|
+
* Python reference (astroengine/lots.py); the golden fixtures pin the two
|
|
8
|
+
* together. Fortune and Spirit are symmetric about the Ascendant, so
|
|
9
|
+
* `(fortune + spirit) === 2 * asc` (mod 360).
|
|
10
|
+
*/
|
|
11
|
+
import { mod } from "./core.js";
|
|
12
|
+
import { isDayChart } from "./derived.js";
|
|
13
|
+
/** The seven Hermetic lots, in their conventional order. */
|
|
14
|
+
export const HERMETIC_LOTS = [
|
|
15
|
+
"fortune", "spirit", "eros", "necessity", "courage", "victory", "nemesis",
|
|
16
|
+
];
|
|
17
|
+
/** Asc + (a - b) by day, Asc + (b - a) by night, wrapped to [0, 360). */
|
|
18
|
+
function lot(asc, a, b, day) {
|
|
19
|
+
return mod(asc + (day ? a - b : b - a), 360);
|
|
20
|
+
}
|
|
21
|
+
/** Lot of Fortune: Asc + Moon - Sun by day, Asc + Sun - Moon by night. */
|
|
22
|
+
export function lotFortune(asc, sun, moon, day) {
|
|
23
|
+
return lot(asc, moon, sun, day);
|
|
24
|
+
}
|
|
25
|
+
/** Lot of Spirit (the reverse of Fortune): Asc + Sun - Moon by day. */
|
|
26
|
+
export function lotSpirit(asc, sun, moon, day) {
|
|
27
|
+
return lot(asc, sun, moon, day);
|
|
28
|
+
}
|
|
29
|
+
/** The seven Hermetic lots from the Ascendant, sect, and the seven planets'
|
|
30
|
+
* longitudes (degrees). Pure arithmetic. */
|
|
31
|
+
export function hermeticLots(asc, day, sun, moon, mercury, venus, mars, jupiter, saturn) {
|
|
32
|
+
const fortune = lotFortune(asc, sun, moon, day);
|
|
33
|
+
const spirit = lotSpirit(asc, sun, moon, day);
|
|
34
|
+
return {
|
|
35
|
+
fortune,
|
|
36
|
+
spirit,
|
|
37
|
+
eros: lot(asc, venus, spirit, day),
|
|
38
|
+
necessity: lot(asc, fortune, mercury, day),
|
|
39
|
+
courage: lot(asc, fortune, mars, day),
|
|
40
|
+
victory: lot(asc, jupiter, spirit, day),
|
|
41
|
+
nemesis: lot(asc, fortune, saturn, day),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** The seven Hermetic lots of a chart: compute the Ascendant and sect, then the
|
|
45
|
+
* lots from the seven planets' longitudes. */
|
|
46
|
+
export function lots(engine, jdUt, lat, lonEast, zodiac = "tropical") {
|
|
47
|
+
const asc = engine.chartAt(jdUt, lat, lonEast, { zodiac }).angles.asc;
|
|
48
|
+
const day = isDayChart(engine, jdUt, lat, lonEast);
|
|
49
|
+
const lon = (b) => engine.longitude(b, jdUt, { zodiac });
|
|
50
|
+
const h = hermeticLots(asc, day, lon("sun"), lon("moon"), lon("mercury"), lon("venus"), lon("mars"), lon("jupiter"), lon("saturn"));
|
|
51
|
+
return { day, ...h };
|
|
52
|
+
}
|
package/dist/src/pheno.d.ts
CHANGED
|
@@ -19,8 +19,22 @@ export interface Pheno {
|
|
|
19
19
|
diameter: number;
|
|
20
20
|
magnitude: number;
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
22
|
+
/**
|
|
23
|
+
* Photometric and apparent-geometry quantities for a body at an instant: its
|
|
24
|
+
* phase angle, illuminated fraction, elongation from the Sun, apparent disc
|
|
25
|
+
* diameter, and apparent visual magnitude.
|
|
26
|
+
*
|
|
27
|
+
* @param engine The engine used to evaluate positions.
|
|
28
|
+
* @param body A body with known physical dimensions (Sun, Moon, the planets).
|
|
29
|
+
* @param jdUt Julian Day (UT).
|
|
30
|
+
* @returns A {@link Pheno}: `phaseAngle` (deg), `phase` (lit fraction `0`–`1`),
|
|
31
|
+
* `elongation` (deg), `diameter` (deg), and `magnitude`.
|
|
32
|
+
* @throws Error if `body` has no photometric data.
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* pheno(engine, "venus", julianDay(2025, 6, 1)).phase; // illuminated fraction
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
24
38
|
export declare function pheno(engine: Engine, body: BodyId, jdUt: number): Pheno;
|
|
25
39
|
/** Apparent minus mean solar time, minutes (Meeus ch. 28). */
|
|
26
40
|
export declare function equationOfTime(engine: Engine, jdUt: number): number;
|
package/dist/src/pheno.js
CHANGED
|
@@ -66,8 +66,22 @@ function magnitude(body, a, r, dlt, jde, lonDeg, latDeg) {
|
|
|
66
66
|
return x - 1.01;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
/**
|
|
70
|
-
*
|
|
69
|
+
/**
|
|
70
|
+
* Photometric and apparent-geometry quantities for a body at an instant: its
|
|
71
|
+
* phase angle, illuminated fraction, elongation from the Sun, apparent disc
|
|
72
|
+
* diameter, and apparent visual magnitude.
|
|
73
|
+
*
|
|
74
|
+
* @param engine The engine used to evaluate positions.
|
|
75
|
+
* @param body A body with known physical dimensions (Sun, Moon, the planets).
|
|
76
|
+
* @param jdUt Julian Day (UT).
|
|
77
|
+
* @returns A {@link Pheno}: `phaseAngle` (deg), `phase` (lit fraction `0`–`1`),
|
|
78
|
+
* `elongation` (deg), `diameter` (deg), and `magnitude`.
|
|
79
|
+
* @throws Error if `body` has no photometric data.
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* pheno(engine, "venus", julianDay(2025, 6, 1)).phase; // illuminated fraction
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
71
85
|
export function pheno(engine, body, jdUt) {
|
|
72
86
|
if (DIAMETER_KM[body] === undefined) {
|
|
73
87
|
throw new Error(`pheno not available for '${body}'`);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Engine, Zodiac } from "./chart.js";
|
|
2
|
+
/** Traditional (domicile) ruler of each sign, Aries..Pisces. */
|
|
3
|
+
export declare const SIGN_RULERS: readonly ["mars", "venus", "mercury", "moon", "sun", "mercury", "venus", "mars", "jupiter", "saturn", "saturn", "jupiter"];
|
|
4
|
+
/** Traditional (domicile) ruler of a sign index (0 = Aries). */
|
|
5
|
+
export declare function signRuler(sign: number): string;
|
|
6
|
+
export interface ProfectedSign {
|
|
7
|
+
sign: string;
|
|
8
|
+
sign_index: number;
|
|
9
|
+
/** 1-based whole-sign house from the natal Ascendant. */
|
|
10
|
+
house: number;
|
|
11
|
+
/** Traditional (domicile) lord of the profected sign. */
|
|
12
|
+
lord: string;
|
|
13
|
+
}
|
|
14
|
+
/** The whole-sign profection `steps` signs after the Ascendant sign. */
|
|
15
|
+
export declare function profectedSign(ascSign: number, steps: number): ProfectedSign;
|
|
16
|
+
export interface Profection {
|
|
17
|
+
age_years: number;
|
|
18
|
+
/** 1-based month within the profection year. */
|
|
19
|
+
month: number;
|
|
20
|
+
annual: ProfectedSign;
|
|
21
|
+
monthly: ProfectedSign;
|
|
22
|
+
}
|
|
23
|
+
/** Annual and monthly profection at `targetJd` for a natal Ascendant sign. */
|
|
24
|
+
export declare function profection(ascSign: number, natalJd: number, targetJd: number, yearLength?: number): Profection;
|
|
25
|
+
/** Profection from a natal chart: take the Ascendant sign from the natal chart,
|
|
26
|
+
* then profect to `targetJd`. */
|
|
27
|
+
export declare function profectionAt(engine: Engine, natalJd: number, targetJd: number, lat: number, lonEast: number, zodiac?: Zodiac, yearLength?: number): Profection;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* astroengine profections -- annual and monthly profections, a Hellenistic
|
|
3
|
+
* time-lord technique.
|
|
4
|
+
*
|
|
5
|
+
* The Ascendant advances one whole sign per year of life; the profected sign's
|
|
6
|
+
* traditional (domicile) ruler is the lord of the year. Within the year the
|
|
7
|
+
* monthly profection advances one further sign per 1/12 of the year. Pure
|
|
8
|
+
* arithmetic on a date difference and the natal Ascendant sign. Mirrors the
|
|
9
|
+
* Python reference (astroengine/profections.py); the golden fixtures pin the
|
|
10
|
+
* two together. Whole-sign frame: the sign N signs after the Ascendant is the
|
|
11
|
+
* (N+1)th house. The profection year is a fixed length (the tropical year by
|
|
12
|
+
* default); birthday-exact profections would key off the solar return.
|
|
13
|
+
*/
|
|
14
|
+
import { mod } from "./core.js";
|
|
15
|
+
import { SIGNS } from "./chart.js";
|
|
16
|
+
import { TROPICAL_YEAR } from "./derived.js";
|
|
17
|
+
/** Traditional (domicile) ruler of each sign, Aries..Pisces. */
|
|
18
|
+
export const SIGN_RULERS = [
|
|
19
|
+
"mars", "venus", "mercury", "moon", "sun", "mercury",
|
|
20
|
+
"venus", "mars", "jupiter", "saturn", "saturn", "jupiter",
|
|
21
|
+
];
|
|
22
|
+
/** Traditional (domicile) ruler of a sign index (0 = Aries). */
|
|
23
|
+
export function signRuler(sign) {
|
|
24
|
+
return SIGN_RULERS[mod(sign, 12)];
|
|
25
|
+
}
|
|
26
|
+
/** The whole-sign profection `steps` signs after the Ascendant sign. */
|
|
27
|
+
export function profectedSign(ascSign, steps) {
|
|
28
|
+
const sign = mod(ascSign + steps, 12);
|
|
29
|
+
return { sign: SIGNS[sign], sign_index: sign, house: mod(steps, 12) + 1, lord: signRuler(sign) };
|
|
30
|
+
}
|
|
31
|
+
/** Annual and monthly profection at `targetJd` for a natal Ascendant sign. */
|
|
32
|
+
export function profection(ascSign, natalJd, targetJd, yearLength = TROPICAL_YEAR) {
|
|
33
|
+
const age = (targetJd - natalJd) / yearLength;
|
|
34
|
+
const years = Math.floor(age);
|
|
35
|
+
const month = Math.floor((age - years) * 12); // 0..11
|
|
36
|
+
return {
|
|
37
|
+
age_years: years,
|
|
38
|
+
month: month + 1,
|
|
39
|
+
annual: profectedSign(ascSign, years),
|
|
40
|
+
monthly: profectedSign(ascSign, years + month),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Profection from a natal chart: take the Ascendant sign from the natal chart,
|
|
44
|
+
* then profect to `targetJd`. */
|
|
45
|
+
export function profectionAt(engine, natalJd, targetJd, lat, lonEast, zodiac = "tropical", yearLength = TROPICAL_YEAR) {
|
|
46
|
+
const asc = engine.chartAt(natalJd, lat, lonEast, { zodiac }).angles.asc;
|
|
47
|
+
const ascSign = mod(Math.floor(asc / 30), 12);
|
|
48
|
+
return profection(ascSign, natalJd, targetJd, yearLength);
|
|
49
|
+
}
|