ether-to-astro 1.0.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/.env.example +13 -0
- package/.github/pull_request_template.md +16 -0
- package/.github/workflows/release.yml +35 -0
- package/.github/workflows/test.yml +32 -0
- package/AGENTS.md +99 -0
- package/LICENSE +18 -0
- package/NOTICE.md +45 -0
- package/README.md +301 -0
- package/SETUP.md +70 -0
- package/TESTING_SUMMARY.md +238 -0
- package/TEST_SUITE_STATUS.md +218 -0
- package/biome.json +48 -0
- package/dist/astro-service.d.ts +98 -0
- package/dist/astro-service.js +496 -0
- package/dist/chart-types.d.ts +52 -0
- package/dist/chart-types.js +51 -0
- package/dist/charts.d.ts +125 -0
- package/dist/charts.js +324 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +472 -0
- package/dist/constants.d.ts +81 -0
- package/dist/constants.js +76 -0
- package/dist/eclipses.d.ts +85 -0
- package/dist/eclipses.js +184 -0
- package/dist/ephemeris.d.ts +120 -0
- package/dist/ephemeris.js +379 -0
- package/dist/formatter.d.ts +2 -0
- package/dist/formatter.js +22 -0
- package/dist/houses.d.ts +82 -0
- package/dist/houses.js +169 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +150 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.js +31 -0
- package/dist/logger.d.ts +25 -0
- package/dist/logger.js +73 -0
- package/dist/profile-store.d.ts +48 -0
- package/dist/profile-store.js +156 -0
- package/dist/riseset.d.ts +82 -0
- package/dist/riseset.js +185 -0
- package/dist/storage.d.ts +10 -0
- package/dist/storage.js +40 -0
- package/dist/time-utils.d.ts +68 -0
- package/dist/time-utils.js +136 -0
- package/dist/tool-registry.d.ts +35 -0
- package/dist/tool-registry.js +307 -0
- package/dist/tool-result.d.ts +175 -0
- package/dist/tool-result.js +188 -0
- package/dist/transits.d.ts +108 -0
- package/dist/transits.js +263 -0
- package/dist/types.d.ts +450 -0
- package/dist/types.js +161 -0
- package/example-usage.md +131 -0
- package/natal-chart.json +187 -0
- package/package.json +61 -0
- package/scripts/download-ephemeris.js +115 -0
- package/setup.sh +21 -0
- package/src/astro-service.ts +710 -0
- package/src/chart-types.ts +125 -0
- package/src/charts.ts +399 -0
- package/src/cli.ts +694 -0
- package/src/constants.ts +89 -0
- package/src/eclipses.ts +226 -0
- package/src/ephemeris.ts +437 -0
- package/src/formatter.ts +25 -0
- package/src/houses.ts +202 -0
- package/src/index.ts +170 -0
- package/src/loader.ts +36 -0
- package/src/logger.ts +104 -0
- package/src/profile-store.ts +285 -0
- package/src/riseset.ts +229 -0
- package/src/time-utils.ts +167 -0
- package/src/tool-registry.ts +357 -0
- package/src/tool-result.ts +283 -0
- package/src/transits.ts +352 -0
- package/src/types.ts +547 -0
- package/tests/README.md +173 -0
- package/tests/TESTING_STRATEGY.md +178 -0
- package/tests/fixtures/bowen-yang-chart.ts +69 -0
- package/tests/fixtures/calculate-expected.ts +81 -0
- package/tests/fixtures/expected-results.ts +117 -0
- package/tests/fixtures/generate-expected-simple.ts +94 -0
- package/tests/helpers/date-fixtures.ts +15 -0
- package/tests/helpers/ephem.ts +11 -0
- package/tests/helpers/temp.ts +9 -0
- package/tests/setup.ts +11 -0
- package/tests/unit/astro-service.test.ts +323 -0
- package/tests/unit/chart-types.test.ts +18 -0
- package/tests/unit/charts-errors.test.ts +42 -0
- package/tests/unit/charts.test.ts +157 -0
- package/tests/unit/cli-commands.test.ts +82 -0
- package/tests/unit/cli-profiles.test.ts +128 -0
- package/tests/unit/cli.test.ts +191 -0
- package/tests/unit/constants.test.ts +26 -0
- package/tests/unit/correctness-critical.test.ts +408 -0
- package/tests/unit/eclipses.test.ts +108 -0
- package/tests/unit/ephemeris.test.ts +213 -0
- package/tests/unit/error-handling.test.ts +116 -0
- package/tests/unit/formatter.test.ts +29 -0
- package/tests/unit/houses-errors.test.ts +27 -0
- package/tests/unit/houses-validation.test.ts +164 -0
- package/tests/unit/houses.test.ts +205 -0
- package/tests/unit/profile-store.test.ts +163 -0
- package/tests/unit/real-user-charts.test.ts +148 -0
- package/tests/unit/riseset.test.ts +106 -0
- package/tests/unit/solver-edges.test.ts +197 -0
- package/tests/unit/time-utils-temporal.test.ts +303 -0
- package/tests/unit/time-utils.test.ts +173 -0
- package/tests/unit/tool-registry.test.ts +222 -0
- package/tests/unit/tool-result.test.ts +45 -0
- package/tests/unit/transit-correctness.test.ts +78 -0
- package/tests/unit/transits.test.ts +238 -0
- package/tests/validation/README.md +32 -0
- package/tests/validation/adapters/astrolog.ts +306 -0
- package/tests/validation/adapters/internal.ts +184 -0
- package/tests/validation/compare/eclipses.ts +47 -0
- package/tests/validation/compare/houses.ts +76 -0
- package/tests/validation/compare/positions.ts +104 -0
- package/tests/validation/compare/riseSet.ts +48 -0
- package/tests/validation/compare/roots.ts +90 -0
- package/tests/validation/compare/transits.ts +69 -0
- package/tests/validation/fixtures/astrolog-parity/core.ts +194 -0
- package/tests/validation/fixtures/eclipses/core.ts +14 -0
- package/tests/validation/fixtures/houses/core.ts +47 -0
- package/tests/validation/fixtures/positions/core.ts +159 -0
- package/tests/validation/fixtures/rise-set/core.ts +20 -0
- package/tests/validation/fixtures/roots/core.ts +47 -0
- package/tests/validation/fixtures/transits/core.ts +61 -0
- package/tests/validation/fixtures/transits/dst.ts +21 -0
- package/tests/validation/oracle.spec.ts +129 -0
- package/tests/validation/utils/denseRootOracle.ts +269 -0
- package/tests/validation/utils/fixtureTypes.ts +146 -0
- package/tests/validation/utils/report.ts +60 -0
- package/tests/validation/utils/tolerances.ts +23 -0
- package/tests/validation/validation.spec.ts +836 -0
- package/tools/color-picker.html +388 -0
- package/tsconfig.json +17 -0
- package/vitest.config.ts +31 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { EphemerisCalculator } from './ephemeris.js';
|
|
2
|
+
import type { EclipseInfo } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Calculator for solar and lunar eclipses
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Finds upcoming solar and lunar eclipses using Swiss Ephemeris.
|
|
8
|
+
* Returns basic eclipse information including type and timing.
|
|
9
|
+
* TODO: Enhance with richer phase timing and visibility data.
|
|
10
|
+
*/
|
|
11
|
+
export declare class EclipseCalculator {
|
|
12
|
+
/** Ephemeris calculator instance */
|
|
13
|
+
private ephem;
|
|
14
|
+
/**
|
|
15
|
+
* Create a new eclipse calculator
|
|
16
|
+
*
|
|
17
|
+
* @param ephem - Initialized ephemeris calculator
|
|
18
|
+
* @throws Error if ephemeris is not initialized
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* The ephemeris calculator must be initialized before passing
|
|
22
|
+
* to the EclipseCalculator constructor.
|
|
23
|
+
*/
|
|
24
|
+
constructor(ephem: EphemerisCalculator);
|
|
25
|
+
private callSolarEclipseWhenGlob;
|
|
26
|
+
/**
|
|
27
|
+
* Find the next solar eclipse after a given date
|
|
28
|
+
*
|
|
29
|
+
* @param startJD - Julian Day to start searching from
|
|
30
|
+
* @returns Solar eclipse info or null if none found
|
|
31
|
+
* @throws Error if ephemeris not initialized
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Searches globally for the next solar eclipse. Returns basic
|
|
35
|
+
* information about the eclipse type and maximum time.
|
|
36
|
+
*/
|
|
37
|
+
findNextSolarEclipse(startJD: number): EclipseInfo | null;
|
|
38
|
+
/**
|
|
39
|
+
* Find the next lunar eclipse after a given date
|
|
40
|
+
*
|
|
41
|
+
* @param startJD - Julian Day to start searching from
|
|
42
|
+
* @returns Lunar eclipse info or null if none found
|
|
43
|
+
* @throws Error if ephemeris not initialized
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* Searches globally for the next lunar eclipse. Returns basic
|
|
47
|
+
* information about the eclipse type and maximum time.
|
|
48
|
+
*/
|
|
49
|
+
findNextLunarEclipse(startJD: number): EclipseInfo | null;
|
|
50
|
+
/**
|
|
51
|
+
* Get the next eclipses (both solar and lunar) after a given date
|
|
52
|
+
*
|
|
53
|
+
* @param startJD - Julian Day to start searching from
|
|
54
|
+
* @returns Array of upcoming eclipses sorted by date
|
|
55
|
+
* @throws Error if ephemeris not initialized
|
|
56
|
+
*
|
|
57
|
+
* @remarks
|
|
58
|
+
* Finds the next solar and lunar eclipses. Returns them in
|
|
59
|
+
* chronological order. May return only one type if the other
|
|
60
|
+
* is too far in the future.
|
|
61
|
+
*/
|
|
62
|
+
getNextEclipses(startJD: number): Promise<EclipseInfo[] | null>;
|
|
63
|
+
/**
|
|
64
|
+
* Get solar eclipse type from Swiss Ephemeris return code
|
|
65
|
+
*
|
|
66
|
+
* @param returnCode - Swiss Ephemeris solar eclipse return code
|
|
67
|
+
* @returns Human-readable eclipse type string
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* Maps Swiss Ephemeris numeric codes to descriptive types.
|
|
71
|
+
* TODO: Should use constrained union types for better type safety.
|
|
72
|
+
*/
|
|
73
|
+
private getSolarEclipseType;
|
|
74
|
+
/**
|
|
75
|
+
* Get lunar eclipse type from Swiss Ephemeris return code
|
|
76
|
+
*
|
|
77
|
+
* @param returnCode - Swiss Ephemeris lunar eclipse return code
|
|
78
|
+
* @returns Human-readable eclipse type string
|
|
79
|
+
*
|
|
80
|
+
* @remarks
|
|
81
|
+
* Maps Swiss Ephemeris numeric codes to descriptive types.
|
|
82
|
+
* TODO: Should use constrained union types for better type safety.
|
|
83
|
+
*/
|
|
84
|
+
private getLunarEclipseType;
|
|
85
|
+
}
|
package/dist/eclipses.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { constants as Constants } from 'sweph';
|
|
2
|
+
import { ErrorCategory } from './constants.js';
|
|
3
|
+
import { logger } from './logger.js';
|
|
4
|
+
function isEclipseWhenResult(value) {
|
|
5
|
+
if (typeof value !== 'object' || value == null)
|
|
6
|
+
return false;
|
|
7
|
+
const obj = value;
|
|
8
|
+
return (typeof obj.flag === 'number' &&
|
|
9
|
+
typeof obj.error === 'string' &&
|
|
10
|
+
Array.isArray(obj.data) &&
|
|
11
|
+
obj.data.every((v) => typeof v === 'number'));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Calculator for solar and lunar eclipses
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Finds upcoming solar and lunar eclipses using Swiss Ephemeris.
|
|
18
|
+
* Returns basic eclipse information including type and timing.
|
|
19
|
+
* TODO: Enhance with richer phase timing and visibility data.
|
|
20
|
+
*/
|
|
21
|
+
export class EclipseCalculator {
|
|
22
|
+
/** Ephemeris calculator instance */
|
|
23
|
+
ephem;
|
|
24
|
+
/**
|
|
25
|
+
* Create a new eclipse calculator
|
|
26
|
+
*
|
|
27
|
+
* @param ephem - Initialized ephemeris calculator
|
|
28
|
+
* @throws Error if ephemeris is not initialized
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* The ephemeris calculator must be initialized before passing
|
|
32
|
+
* to the EclipseCalculator constructor.
|
|
33
|
+
*/
|
|
34
|
+
constructor(ephem) {
|
|
35
|
+
this.ephem = ephem;
|
|
36
|
+
}
|
|
37
|
+
callSolarEclipseWhenGlob(startJD) {
|
|
38
|
+
if (!this.ephem.eph) {
|
|
39
|
+
throw new Error('Ephemeris not initialized');
|
|
40
|
+
}
|
|
41
|
+
// sweph typings currently declare `backwards` as number, but runtime expects boolean.
|
|
42
|
+
const callable = this.ephem.eph.sol_eclipse_when_glob;
|
|
43
|
+
const raw = callable(startJD, Constants.SEFLG_SWIEPH, 0, false);
|
|
44
|
+
if (!isEclipseWhenResult(raw)) {
|
|
45
|
+
throw new Error('Unexpected sol_eclipse_when_glob result shape');
|
|
46
|
+
}
|
|
47
|
+
return raw;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Find the next solar eclipse after a given date
|
|
51
|
+
*
|
|
52
|
+
* @param startJD - Julian Day to start searching from
|
|
53
|
+
* @returns Solar eclipse info or null if none found
|
|
54
|
+
* @throws Error if ephemeris not initialized
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* Searches globally for the next solar eclipse. Returns basic
|
|
58
|
+
* information about the eclipse type and maximum time.
|
|
59
|
+
*/
|
|
60
|
+
findNextSolarEclipse(startJD) {
|
|
61
|
+
if (!this.ephem.eph) {
|
|
62
|
+
throw new Error('Ephemeris not initialized');
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const result = this.callSolarEclipseWhenGlob(startJD);
|
|
66
|
+
if (result.error || !result.data || result.data.length < 1) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const eclipseType = this.getSolarEclipseType(result.flag);
|
|
70
|
+
return {
|
|
71
|
+
type: 'solar',
|
|
72
|
+
date: this.ephem.julianDayToDate(result.data[0]),
|
|
73
|
+
eclipseType,
|
|
74
|
+
maxTime: this.ephem.julianDayToDate(result.data[0]),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
logger.error('Solar eclipse calculation failed', ErrorCategory.CALCULATION, e instanceof Error ? e : new Error(String(e)));
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Find the next lunar eclipse after a given date
|
|
84
|
+
*
|
|
85
|
+
* @param startJD - Julian Day to start searching from
|
|
86
|
+
* @returns Lunar eclipse info or null if none found
|
|
87
|
+
* @throws Error if ephemeris not initialized
|
|
88
|
+
*
|
|
89
|
+
* @remarks
|
|
90
|
+
* Searches globally for the next lunar eclipse. Returns basic
|
|
91
|
+
* information about the eclipse type and maximum time.
|
|
92
|
+
*/
|
|
93
|
+
findNextLunarEclipse(startJD) {
|
|
94
|
+
if (!this.ephem.eph) {
|
|
95
|
+
throw new Error('Ephemeris not initialized');
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const result = this.ephem.eph.lun_eclipse_when(startJD, Constants.SEFLG_SWIEPH, 0, false);
|
|
99
|
+
if (result.error || !result.data || result.data.length < 1) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const eclipseType = this.getLunarEclipseType(result.flag);
|
|
103
|
+
return {
|
|
104
|
+
type: 'lunar',
|
|
105
|
+
date: this.ephem.julianDayToDate(result.data[0]),
|
|
106
|
+
eclipseType,
|
|
107
|
+
maxTime: this.ephem.julianDayToDate(result.data[0]),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
logger.error('Lunar eclipse calculation failed', ErrorCategory.CALCULATION, e instanceof Error ? e : new Error(String(e)));
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get the next eclipses (both solar and lunar) after a given date
|
|
117
|
+
*
|
|
118
|
+
* @param startJD - Julian Day to start searching from
|
|
119
|
+
* @returns Array of upcoming eclipses sorted by date
|
|
120
|
+
* @throws Error if ephemeris not initialized
|
|
121
|
+
*
|
|
122
|
+
* @remarks
|
|
123
|
+
* Finds the next solar and lunar eclipses. Returns them in
|
|
124
|
+
* chronological order. May return only one type if the other
|
|
125
|
+
* is too far in the future.
|
|
126
|
+
*/
|
|
127
|
+
async getNextEclipses(startJD) {
|
|
128
|
+
if (!this.ephem.eph) {
|
|
129
|
+
throw new Error('Ephemeris not initialized');
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const solarEclipse = this.findNextSolarEclipse(startJD);
|
|
133
|
+
const lunarEclipse = this.findNextLunarEclipse(startJD);
|
|
134
|
+
const eclipses = await Promise.all([solarEclipse, lunarEclipse]);
|
|
135
|
+
const filteredEclipses = eclipses.filter((eclipse) => eclipse !== null);
|
|
136
|
+
if (filteredEclipses.length === 0) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
return filteredEclipses.sort((a, b) => a.date.getTime() - b.date.getTime());
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
logger.error('Eclipse calculation failed', ErrorCategory.CALCULATION, e instanceof Error ? e : new Error(String(e)));
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get solar eclipse type from Swiss Ephemeris return code
|
|
148
|
+
*
|
|
149
|
+
* @param returnCode - Swiss Ephemeris solar eclipse return code
|
|
150
|
+
* @returns Human-readable eclipse type string
|
|
151
|
+
*
|
|
152
|
+
* @remarks
|
|
153
|
+
* Maps Swiss Ephemeris numeric codes to descriptive types.
|
|
154
|
+
* TODO: Should use constrained union types for better type safety.
|
|
155
|
+
*/
|
|
156
|
+
getSolarEclipseType(returnCode) {
|
|
157
|
+
if (returnCode & Constants.SE_ECL_TOTAL)
|
|
158
|
+
return 'Total';
|
|
159
|
+
if (returnCode & Constants.SE_ECL_ANNULAR)
|
|
160
|
+
return 'Annular';
|
|
161
|
+
if (returnCode & Constants.SE_ECL_PARTIAL)
|
|
162
|
+
return 'Partial';
|
|
163
|
+
return 'Unknown';
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get lunar eclipse type from Swiss Ephemeris return code
|
|
167
|
+
*
|
|
168
|
+
* @param returnCode - Swiss Ephemeris lunar eclipse return code
|
|
169
|
+
* @returns Human-readable eclipse type string
|
|
170
|
+
*
|
|
171
|
+
* @remarks
|
|
172
|
+
* Maps Swiss Ephemeris numeric codes to descriptive types.
|
|
173
|
+
* TODO: Should use constrained union types for better type safety.
|
|
174
|
+
*/
|
|
175
|
+
getLunarEclipseType(returnCode) {
|
|
176
|
+
if (returnCode & Constants.SE_ECL_TOTAL)
|
|
177
|
+
return 'Total';
|
|
178
|
+
if (returnCode & Constants.SE_ECL_PARTIAL)
|
|
179
|
+
return 'Partial';
|
|
180
|
+
if (returnCode & Constants.SE_ECL_PENUMBRAL)
|
|
181
|
+
return 'Penumbral';
|
|
182
|
+
return 'Unknown';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import sweph from 'sweph';
|
|
2
|
+
import { type PlanetPosition } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Ephemeris calculator wrapper for native Swiss Ephemeris (sweph)
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Provides a high-level interface for planetary calculations using the
|
|
8
|
+
* Swiss Ephemeris Node bindings. Handles initialization,
|
|
9
|
+
* coordinate conversions, and common astrological calculations.
|
|
10
|
+
*
|
|
11
|
+
* All longitudes are tropical (not sidereal) and geocentric.
|
|
12
|
+
*/
|
|
13
|
+
export declare class EphemerisCalculator {
|
|
14
|
+
/** Native sweph module instance */
|
|
15
|
+
eph: typeof sweph | null;
|
|
16
|
+
/**
|
|
17
|
+
* Initialize the Swiss Ephemeris native module
|
|
18
|
+
*
|
|
19
|
+
* @returns Promise that resolves when initialization is complete
|
|
20
|
+
* @throws Error if module setup fails
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* Must be called before any other methods. Loads the Swiss Ephemeris
|
|
24
|
+
* data files and prepares the calculation engine.
|
|
25
|
+
*/
|
|
26
|
+
init(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Convert a JavaScript Date to Julian Day
|
|
29
|
+
*
|
|
30
|
+
* @param date - Date to convert (should be in UTC)
|
|
31
|
+
* @returns Julian Day number
|
|
32
|
+
* @throws Error if ephemeris not initialized
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* Julian Day is a continuous count of days since noon Universal Time
|
|
36
|
+
* on January 1, 4713 BCE. It's the standard time system for astronomical
|
|
37
|
+
* calculations.
|
|
38
|
+
*/
|
|
39
|
+
dateToJulianDay(date: Date): number;
|
|
40
|
+
/**
|
|
41
|
+
* Normalize angle to 0-360 degree range
|
|
42
|
+
*
|
|
43
|
+
* @param angle - Angle in degrees (may be negative or > 360)
|
|
44
|
+
* @returns Normalized angle in degrees (0-360)
|
|
45
|
+
*
|
|
46
|
+
* @remarks
|
|
47
|
+
* Uses modulo arithmetic to handle negative angles correctly.
|
|
48
|
+
* Example: -10° becomes 350°, 370° becomes 10°.
|
|
49
|
+
*/
|
|
50
|
+
private normalizeAngle;
|
|
51
|
+
/**
|
|
52
|
+
* Get position of a single planet at a specific time
|
|
53
|
+
*
|
|
54
|
+
* @param planetId - Swiss Ephemeris planet ID (from PLANETS constant)
|
|
55
|
+
* @param jd - Julian Day for the calculation
|
|
56
|
+
* @returns Planet position with all relevant data
|
|
57
|
+
* @throws Error if ephemeris not initialized or invalid planet ID
|
|
58
|
+
*
|
|
59
|
+
* @remarks
|
|
60
|
+
* Returns tropical, geocentric coordinates. Includes zodiac sign
|
|
61
|
+
* calculation and retrograde status.
|
|
62
|
+
*/
|
|
63
|
+
getPlanetPosition(planetId: number, jd: number): PlanetPosition;
|
|
64
|
+
/**
|
|
65
|
+
* Get positions for multiple planets at a specific time
|
|
66
|
+
*
|
|
67
|
+
* @param planetIds - Array of Swiss Ephemeris planet IDs
|
|
68
|
+
* @param jd - Julian Day for the calculation
|
|
69
|
+
* @returns Array of planet positions in the same order as planetIds
|
|
70
|
+
* @throws Error if ephemeris not initialized
|
|
71
|
+
*
|
|
72
|
+
* @remarks
|
|
73
|
+
* Convenience wrapper that maps over planetIds and calls getPlanetPosition for each.
|
|
74
|
+
*/
|
|
75
|
+
getAllPlanets(jd: number, planetIds: number[]): PlanetPosition[];
|
|
76
|
+
/**
|
|
77
|
+
* Calculate angular distance between two planets
|
|
78
|
+
*
|
|
79
|
+
* @param lon1 - First planet's longitude
|
|
80
|
+
* @param lon2 - Second planet's longitude
|
|
81
|
+
* @returns Angular distance in degrees (0-180)
|
|
82
|
+
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* Always returns the shorter arc between the two planets.
|
|
85
|
+
* For example, 350° and 10° have a distance of 20°, not 340°.
|
|
86
|
+
*/
|
|
87
|
+
calculateAspectAngle(lon1: number, lon2: number): number;
|
|
88
|
+
/**
|
|
89
|
+
* Find all exact times when planet reaches a specific longitude
|
|
90
|
+
*
|
|
91
|
+
* @param planetId - Swiss Ephemeris planet ID
|
|
92
|
+
* @param targetLongitude - Target longitude in degrees (will be normalized to 0-360)
|
|
93
|
+
* @param startJD - Start of search window (Julian Day)
|
|
94
|
+
* @param endJD - End of search window (Julian Day)
|
|
95
|
+
* @param tolerance - Desired precision in degrees (default: 0.01°)
|
|
96
|
+
* @returns Array of Julian Days where crossings occur, sorted earliest-first, or empty array if none
|
|
97
|
+
* @throws Error if ephemeris not initialized or invalid inputs
|
|
98
|
+
*
|
|
99
|
+
* @remarks
|
|
100
|
+
* Uses multi-stage search: coarse scan for root detection, then bracket/minimum refinement.
|
|
101
|
+
* Endpoint-near-zero cases are collected directly as candidate roots.
|
|
102
|
+
* Only sign-change intervals are refined via bisection.
|
|
103
|
+
* Local minima of |diff| are refined to catch tangential no-sign-change roots.
|
|
104
|
+
* Returns all detected crossings in the interval, deduplicated within 1 minute,
|
|
105
|
+
* and sorted earliest-first. No guarantees are made outside the searched interval.
|
|
106
|
+
*/
|
|
107
|
+
findExactTransitTimes(planetId: number, targetLongitude: number, startJD: number, endJD: number, tolerance?: number): number[];
|
|
108
|
+
/**
|
|
109
|
+
* Convert Julian Day to JavaScript Date
|
|
110
|
+
*
|
|
111
|
+
* @param jd - Julian Day number
|
|
112
|
+
* @returns JavaScript Date in UTC
|
|
113
|
+
* @throws Error if ephemeris not initialized
|
|
114
|
+
*
|
|
115
|
+
* @remarks
|
|
116
|
+
* The returned Date is always in UTC regardless of the original
|
|
117
|
+
* timezone of the calculation.
|
|
118
|
+
*/
|
|
119
|
+
julianDayToDate(jd: number): Date;
|
|
120
|
+
}
|