klio 1.5.7 → 1.5.9
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/package.json
CHANGED
|
@@ -79,13 +79,22 @@ function getBirthDataFromConfig(userId = null) {
|
|
|
79
79
|
const hour = parseInt(timeParts[0]);
|
|
80
80
|
const minute = parseInt(timeParts[1]);
|
|
81
81
|
|
|
82
|
+
const birthLocation = config.birthData.location;
|
|
83
|
+
if (birthLocation && !birthLocation.timezone && config.currentLocation) {
|
|
84
|
+
const latDiff = Math.abs((birthLocation.latitude || 0) - (config.currentLocation.latitude || 0));
|
|
85
|
+
const lonDiff = Math.abs((birthLocation.longitude || 0) - (config.currentLocation.longitude || 0));
|
|
86
|
+
if (latDiff <= 0.1 && lonDiff <= 0.1 && config.currentLocation.timezone) {
|
|
87
|
+
birthLocation.timezone = config.currentLocation.timezone;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
82
91
|
return {
|
|
83
92
|
year: year,
|
|
84
93
|
month: month,
|
|
85
94
|
day: day,
|
|
86
95
|
hour: hour,
|
|
87
96
|
minute: minute,
|
|
88
|
-
location:
|
|
97
|
+
location: birthLocation
|
|
89
98
|
};
|
|
90
99
|
}
|
|
91
100
|
|
|
@@ -213,13 +222,9 @@ function calculateHouses(julianDay, houseSystem = 'K', useBirthLocation = false,
|
|
|
213
222
|
}
|
|
214
223
|
|
|
215
224
|
// Load the configured location data
|
|
216
|
-
|
|
217
|
-
let config;
|
|
225
|
+
let config = null;
|
|
218
226
|
try {
|
|
219
|
-
|
|
220
|
-
const configData = fs.readFileSync(configPath, 'utf8');
|
|
221
|
-
config = JSON.parse(configData);
|
|
222
|
-
}
|
|
227
|
+
config = loadConfig();
|
|
223
228
|
} catch (error) {
|
|
224
229
|
console.log('No configuration found, using default location (Berlin)');
|
|
225
230
|
}
|
|
@@ -261,39 +266,28 @@ function calculateHouses(julianDay, houseSystem = 'K', useBirthLocation = false,
|
|
|
261
266
|
}
|
|
262
267
|
reject(result.error);
|
|
263
268
|
} else {
|
|
264
|
-
|
|
265
|
-
//
|
|
269
|
+
|
|
270
|
+
// The Swiss Ephemeris returns house cusps in result.house, but indexing varies:
|
|
271
|
+
// some implementations return 0-11, others 1-12 (with 0 unused).
|
|
272
|
+
// Normalize to a 0-based array (0-11) for consistent processing.
|
|
266
273
|
const houseCusps = [];
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
// Probably index 0 = AC, 1-12 = houses
|
|
283
|
-
houseCusps.length = 0;
|
|
284
|
-
for (let i = 1; i <= 12; i++) {
|
|
285
|
-
const key = keys.find(k => parseInt(k) === i);
|
|
286
|
-
if (key !== undefined) {
|
|
287
|
-
houseCusps.push(result.house[key]);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
} else if (keys.length === 12) {
|
|
291
|
-
// Probably directly 0-11 = houses
|
|
292
|
-
houseCusps.length = 0;
|
|
293
|
-
for (let i = 0; i < 12; i++) {
|
|
294
|
-
houseCusps.push(result.house[keys[i]]);
|
|
295
|
-
}
|
|
274
|
+
const numericKeys = Object.keys(result.house)
|
|
275
|
+
.filter(k => !isNaN(k))
|
|
276
|
+
.map(k => parseInt(k, 10))
|
|
277
|
+
.sort((a, b) => a - b);
|
|
278
|
+
|
|
279
|
+
if (numericKeys.length >= 12) {
|
|
280
|
+
const hasOneToTwelve = numericKeys.includes(1) && numericKeys.includes(12);
|
|
281
|
+
const hasZeroToEleven = numericKeys.includes(0) && numericKeys.includes(11) && !numericKeys.includes(12);
|
|
282
|
+
if (hasOneToTwelve && !hasZeroToEleven) {
|
|
283
|
+
for (let i = 1; i <= 12; i++) {
|
|
284
|
+
houseCusps.push(result.house[i]);
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
for (let i = 0; i < 12; i++) {
|
|
288
|
+
houseCusps.push(result.house[i]);
|
|
296
289
|
}
|
|
290
|
+
}
|
|
297
291
|
}
|
|
298
292
|
|
|
299
293
|
// If we still don't have 12 houses (shouldn't happen),
|
|
@@ -302,9 +296,22 @@ function calculateHouses(julianDay, houseSystem = 'K', useBirthLocation = false,
|
|
|
302
296
|
houseCusps.push(0);
|
|
303
297
|
}
|
|
304
298
|
|
|
299
|
+
let eps = null;
|
|
300
|
+
if (Number.isFinite(swisseph.SE_ECL_NUT) && swisseph.SE_ECL_NUT >= 0) {
|
|
301
|
+
const epsResult = swisseph.swe_calc_ut(julianDay, swisseph.SE_ECL_NUT, swisseph.SEFLG_SWIEPH);
|
|
302
|
+
if (epsResult && !epsResult.error && Number.isFinite(epsResult.longitude)) {
|
|
303
|
+
eps = epsResult.longitude;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
305
307
|
const formattedResult = {
|
|
306
308
|
...result,
|
|
307
|
-
house: houseCusps
|
|
309
|
+
house: houseCusps,
|
|
310
|
+
houseSystem,
|
|
311
|
+
latitude,
|
|
312
|
+
longitude,
|
|
313
|
+
armc: Number.isFinite(result.armc) ? result.armc : null,
|
|
314
|
+
eps: Number.isFinite(result.eps) ? result.eps : eps
|
|
308
315
|
};
|
|
309
316
|
|
|
310
317
|
resolve(formattedResult);
|
|
@@ -347,17 +354,54 @@ function longitudeToSignDegree(longitude) {
|
|
|
347
354
|
}
|
|
348
355
|
|
|
349
356
|
// Function to determine the house for a planet
|
|
350
|
-
function getPlanetHouse(planetLongitude,
|
|
357
|
+
function getPlanetHouse(planetLongitude, houseData, planetName = null, planetLatitude = null) {
|
|
358
|
+
const houseCusps = Array.isArray(houseData)
|
|
359
|
+
? houseData
|
|
360
|
+
: (houseData && Array.isArray(houseData.house) ? houseData.house : []);
|
|
361
|
+
const houseMeta = (!Array.isArray(houseData) && houseData) ? houseData : null;
|
|
362
|
+
|
|
351
363
|
// Normalize planet longitude to 0-360 range
|
|
352
364
|
planetLongitude = planetLongitude % 360;
|
|
353
365
|
if (planetLongitude < 0) planetLongitude += 360;
|
|
354
366
|
|
|
367
|
+
// Debug output for Chiron
|
|
368
|
+
const isChiron = planetName && planetName.toLowerCase() === 'chiron';
|
|
369
|
+
|
|
370
|
+
if (
|
|
371
|
+
houseMeta &&
|
|
372
|
+
Number.isFinite(planetLatitude) &&
|
|
373
|
+
Number.isFinite(houseMeta.latitude) &&
|
|
374
|
+
Number.isFinite(houseMeta.armc) &&
|
|
375
|
+
Number.isFinite(houseMeta.eps) &&
|
|
376
|
+
typeof houseMeta.houseSystem === 'string' &&
|
|
377
|
+
swisseph.swe_houses_pos
|
|
378
|
+
) {
|
|
379
|
+
const housePosResult = swisseph.swe_houses_pos(
|
|
380
|
+
houseMeta.armc,
|
|
381
|
+
houseMeta.latitude,
|
|
382
|
+
houseMeta.eps,
|
|
383
|
+
houseMeta.houseSystem,
|
|
384
|
+
planetLongitude,
|
|
385
|
+
planetLatitude
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
if (housePosResult && !housePosResult.error && Number.isFinite(housePosResult.housePosition)) {
|
|
389
|
+
let house = Math.floor(housePosResult.housePosition);
|
|
390
|
+
if (house < 1) {
|
|
391
|
+
house = 12;
|
|
392
|
+
} else if (house > 12) {
|
|
393
|
+
house = ((house - 1) % 12) + 1;
|
|
394
|
+
}
|
|
395
|
+
return house;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
355
399
|
// House cusps are in houseCusps[0] to houseCusps[11]
|
|
356
400
|
// We need to find between which two house cusps the planet lies
|
|
357
401
|
for (let i = 0; i < 12; i++) {
|
|
358
402
|
const currentCusp = houseCusps[i];
|
|
359
403
|
const nextCusp = houseCusps[(i + 1) % 12];
|
|
360
|
-
|
|
404
|
+
|
|
361
405
|
// Normalize house cusps to 0-360 range
|
|
362
406
|
const normalizedCurrentCusp = currentCusp % 360;
|
|
363
407
|
const normalizedNextCusp = nextCusp % 360;
|
|
@@ -376,11 +420,11 @@ function getPlanetHouse(planetLongitude, houseCusps) {
|
|
|
376
420
|
}
|
|
377
421
|
}
|
|
378
422
|
}
|
|
379
|
-
|
|
423
|
+
|
|
380
424
|
// Debug: Show house cusps if no house was found
|
|
381
425
|
console.log('No house found for planet:', planetLongitude);
|
|
382
426
|
console.log('House cusps:', houseCusps);
|
|
383
|
-
|
|
427
|
+
|
|
384
428
|
// Fallback: Should not occur
|
|
385
429
|
return 1;
|
|
386
430
|
}
|
|
@@ -526,6 +570,7 @@ function getAstrologicalData(planetName, customDate = null) {
|
|
|
526
570
|
return {
|
|
527
571
|
planet: planetName,
|
|
528
572
|
longitude,
|
|
573
|
+
latitude: result.latitude,
|
|
529
574
|
sign,
|
|
530
575
|
degreeInSign,
|
|
531
576
|
dignity,
|
|
@@ -1313,7 +1358,7 @@ function detectAspectFigures(dateComponents, houseSystem = null, useBirthData =
|
|
|
1313
1358
|
// Add house information if houses were calculated
|
|
1314
1359
|
if (houses && houses.house) {
|
|
1315
1360
|
const planetLongitude = parseFloat(planetData.degreeInSign) + (signs.indexOf(planetData.sign) * 30);
|
|
1316
|
-
const house = getPlanetHouse(planetLongitude, houses
|
|
1361
|
+
const house = getPlanetHouse(planetLongitude, houses);
|
|
1317
1362
|
figure.planetDetails[planetName].house = house;
|
|
1318
1363
|
}
|
|
1319
1364
|
}
|
|
@@ -1443,7 +1488,7 @@ async function calculatePersonalTransits(transitDate = null, birthData = null) {
|
|
|
1443
1488
|
const transitResults = {};
|
|
1444
1489
|
for (const [name, data] of Object.entries(transitPlanets)) {
|
|
1445
1490
|
const planetLongitude = parseFloat(data.degreeInSign) + (signs.indexOf(data.sign) * 30);
|
|
1446
|
-
const house = getPlanetHouse(planetLongitude, houses.
|
|
1491
|
+
const house = getPlanetHouse(planetLongitude, houses, name, data.latitude);
|
|
1447
1492
|
|
|
1448
1493
|
transitResults[name] = {
|
|
1449
1494
|
...data,
|
|
@@ -1461,7 +1506,7 @@ async function calculatePersonalTransits(transitDate = null, birthData = null) {
|
|
|
1461
1506
|
}
|
|
1462
1507
|
|
|
1463
1508
|
// Function to calculate personal transit aspects
|
|
1464
|
-
function calculatePersonalTransitAspects(transitDate = null, birthData = null, targetPlanet = null) {
|
|
1509
|
+
function calculatePersonalTransitAspects(transitDate = null, birthData = null, targetPlanet = null, useHuberOrbs = true) {
|
|
1465
1510
|
if (!birthData) {
|
|
1466
1511
|
birthData = getBirthDataFromConfig();
|
|
1467
1512
|
if (!birthData) {
|
|
@@ -1500,36 +1545,54 @@ function calculatePersonalTransitAspects(transitDate = null, birthData = null, t
|
|
|
1500
1545
|
|
|
1501
1546
|
// Calculate aspects between transit and birth planets
|
|
1502
1547
|
const aspects = [];
|
|
1503
|
-
|
|
1548
|
+
// Use the same orb model as other aspect calculations; default to Huber orbs
|
|
1549
|
+
const aspectTypes = useHuberOrbs ? [
|
|
1504
1550
|
{ name: 'Conjunction', angle: 0, orb: 8 },
|
|
1505
1551
|
{ name: 'Opposition', angle: 180, orb: 8 },
|
|
1506
1552
|
{ name: 'Square', angle: 90, orb: 6 },
|
|
1507
1553
|
{ name: 'Trine', angle: 120, orb: 6 },
|
|
1508
|
-
{ name: 'Sextile', angle: 60, orb: 4 }
|
|
1554
|
+
{ name: 'Sextile', angle: 60, orb: 4 },
|
|
1555
|
+
{ name: 'Quincunx', angle: 150, orb: 3 }
|
|
1556
|
+
] : [
|
|
1557
|
+
{ name: 'Conjunction', angle: 0, orb: 10 },
|
|
1558
|
+
{ name: 'Opposition', angle: 180, orb: 10 },
|
|
1559
|
+
{ name: 'Square', angle: 90, orb: 8 },
|
|
1560
|
+
{ name: 'Trine', angle: 120, orb: 8 },
|
|
1561
|
+
{ name: 'Sextile', angle: 60, orb: 6 },
|
|
1562
|
+
{ name: 'Quincunx', angle: 150, orb: 4 }
|
|
1509
1563
|
];
|
|
1510
1564
|
|
|
1511
1565
|
// Compare each transit planet with each birth planet
|
|
1512
1566
|
for (const [transitName, transitLongitude] of Object.entries(transitPlanets)) {
|
|
1567
|
+
// If filtering by target planet, only calculate for that transit planet
|
|
1568
|
+
if (targetPlanet && transitName !== targetPlanet) continue;
|
|
1569
|
+
|
|
1513
1570
|
for (const [birthName, birthLongitude] of Object.entries(birthPlanets)) {
|
|
1514
1571
|
// Skip if it's the same planet
|
|
1515
1572
|
if (transitName === birthName) continue;
|
|
1516
1573
|
|
|
1517
|
-
// Calculate the angle
|
|
1518
|
-
|
|
1519
|
-
|
|
1574
|
+
// Calculate the angle between the two planets
|
|
1575
|
+
let rawDiff = transitLongitude - birthLongitude;
|
|
1576
|
+
let angleDiff = ((rawDiff % 360) + 360) % 360;
|
|
1520
1577
|
|
|
1521
|
-
// Check for aspects
|
|
1578
|
+
// Check for aspects using the actual angle
|
|
1522
1579
|
for (const aspect of aspectTypes) {
|
|
1523
|
-
|
|
1580
|
+
// Check both the angle and its complement (360 - angle)
|
|
1581
|
+
const diff1 = Math.abs(angleDiff - aspect.angle);
|
|
1582
|
+
const diff2 = Math.abs((360 - angleDiff) - aspect.angle);
|
|
1583
|
+
const diff = Math.min(diff1, diff2);
|
|
1584
|
+
|
|
1585
|
+
if (diff <= aspect.orb) {
|
|
1524
1586
|
aspects.push({
|
|
1525
1587
|
transitPlanet: transitName,
|
|
1526
1588
|
birthPlanet: birthName,
|
|
1527
1589
|
type: aspect.name,
|
|
1528
|
-
angle:
|
|
1529
|
-
orb:
|
|
1590
|
+
angle: angleDiff.toFixed(2),
|
|
1591
|
+
orb: diff.toFixed(2),
|
|
1530
1592
|
transitLongitude: transitLongitude,
|
|
1531
1593
|
birthLongitude: birthLongitude
|
|
1532
1594
|
});
|
|
1595
|
+
break; // Only match one aspect per planet pair
|
|
1533
1596
|
}
|
|
1534
1597
|
}
|
|
1535
1598
|
}
|
|
@@ -1548,8 +1611,8 @@ function calculatePersonalTransitAspects(transitDate = null, birthData = null, t
|
|
|
1548
1611
|
}
|
|
1549
1612
|
|
|
1550
1613
|
// Function to display personal transit aspects
|
|
1551
|
-
function showPersonalTransitAspects(transitDate = null, birthData = null, targetPlanet = null) {
|
|
1552
|
-
const aspectData = calculatePersonalTransitAspects(transitDate, birthData, targetPlanet);
|
|
1614
|
+
function showPersonalTransitAspects(transitDate = null, birthData = null, targetPlanet = null, useHuberOrbs = true) {
|
|
1615
|
+
const aspectData = calculatePersonalTransitAspects(transitDate, birthData, targetPlanet, useHuberOrbs);
|
|
1553
1616
|
|
|
1554
1617
|
if (!aspectData || aspectData.aspects.length === 0) {
|
|
1555
1618
|
console.log('No personal transit aspects found.');
|
|
@@ -1557,7 +1620,7 @@ function showPersonalTransitAspects(transitDate = null, birthData = null, target
|
|
|
1557
1620
|
}
|
|
1558
1621
|
|
|
1559
1622
|
const transitDateDisplay = transitDate || getCurrentTimeInTimezone();
|
|
1560
|
-
console.log(`Personal Transit Aspects (${transitDateDisplay.day}.${transitDateDisplay.month}.${transitDateDisplay.year}):`);
|
|
1623
|
+
console.log(`Personal Transit Aspects (${transitDateDisplay.day}.${transitDateDisplay.month}.${transitDateDisplay.year}) [${(aspectData && aspectData.aspects.length>0) ? (useHuberOrbs ? 'Huber orbs' : 'Standard orbs') : ''}]:`);
|
|
1561
1624
|
console.log('================================================================================');
|
|
1562
1625
|
console.log('| Transit | Birth | Aspect | Orb | Transit Pos | Birth Pos |');
|
|
1563
1626
|
console.log('================================================================================');
|
|
@@ -1617,12 +1680,12 @@ async function showCombinedAnalysis(planetName, transitDate = null, birthData =
|
|
|
1617
1680
|
// Calculate current planet positions (Transit)
|
|
1618
1681
|
const transitPlanetData = getAstrologicalData(planetName, transitDate);
|
|
1619
1682
|
const transitLongitude = transitPlanetData.longitude;
|
|
1620
|
-
const transitHouse = getPlanetHouse(transitLongitude, houses.
|
|
1683
|
+
const transitHouse = getPlanetHouse(transitLongitude, houses, planetName, transitPlanetData.latitude);
|
|
1621
1684
|
|
|
1622
1685
|
// Calculate birth planet positions (Radix)
|
|
1623
1686
|
const birthPlanetData = getAstrologicalData(planetName, birthData);
|
|
1624
1687
|
const birthLongitude = birthPlanetData.longitude;
|
|
1625
|
-
const birthHouse = getPlanetHouse(birthLongitude, houses.
|
|
1688
|
+
const birthHouse = getPlanetHouse(birthLongitude, houses, planetName, birthPlanetData.latitude);
|
|
1626
1689
|
|
|
1627
1690
|
// Calculate birth aspects for the planet
|
|
1628
1691
|
const birthAspects = calculatePlanetAspects(planetName, birthData, true);
|
|
@@ -1651,7 +1714,8 @@ async function showCombinedAnalysis(planetName, transitDate = null, birthData =
|
|
|
1651
1714
|
console.log('--------------------------------------------------------------------------------');
|
|
1652
1715
|
birthAspects.forEach(aspect => {
|
|
1653
1716
|
const aspectPlanetData = getAstrologicalData(aspect.planet, birthData);
|
|
1654
|
-
const
|
|
1717
|
+
const aspectLongitude = parseFloat(aspectPlanetData.degreeInSign) + (signs.indexOf(aspectPlanetData.sign) * 30);
|
|
1718
|
+
const aspectHouse = getPlanetHouse(aspectLongitude, houses);
|
|
1655
1719
|
console.log(`${aspect.type.padEnd(12)} with ${aspect.planet.padEnd(8)} (${aspectPlanetData.sign} ${aspectPlanetData.degreeInSign}° House ${aspectHouse}) - Orb: ${aspect.orb}°`);
|
|
1656
1720
|
});
|
|
1657
1721
|
console.log('');
|
|
@@ -1663,7 +1727,8 @@ async function showCombinedAnalysis(planetName, transitDate = null, birthData =
|
|
|
1663
1727
|
console.log('--------------------------------------------------------------------------------');
|
|
1664
1728
|
transitAspects.forEach(aspect => {
|
|
1665
1729
|
const birthPlanetData = getAstrologicalData(aspect.birthPlanet, birthData);
|
|
1666
|
-
const
|
|
1730
|
+
const birthLongitude = parseFloat(birthPlanetData.degreeInSign) + (signs.indexOf(birthPlanetData.sign) * 30);
|
|
1731
|
+
const birthHouse = getPlanetHouse(birthLongitude, houses);
|
|
1667
1732
|
console.log(`${aspect.type.padEnd(12)} with ${aspect.birthPlanet.padEnd(8)} (${birthPlanetData.sign} ${birthPlanetData.degreeInSign}° House ${birthHouse}) - Orb: ${aspect.orb}°`);
|
|
1668
1733
|
});
|
|
1669
1734
|
console.log('');
|
|
@@ -2303,7 +2368,7 @@ function analyzeCSVWithDatetime(filePath, planetName = 'moon', houseSystem = 'ko
|
|
|
2303
2368
|
calculateHouses(julianDay, getHouseSystemCode(houseSystem), false)
|
|
2304
2369
|
.then(houses => {
|
|
2305
2370
|
const planetLongitude = parseFloat(astroData.degreeInSign) + (signs.indexOf(astroData.sign) * 30);
|
|
2306
|
-
const house = getPlanetHouse(planetLongitude, houses.
|
|
2371
|
+
const house = getPlanetHouse(planetLongitude, houses, planetName, astroData.latitude);
|
|
2307
2372
|
|
|
2308
2373
|
// Calculate aspects if requested
|
|
2309
2374
|
let aspects = [];
|
|
@@ -2547,7 +2612,7 @@ function analyzeCSVWithDatetime(filePath, planetName = 'moon', houseSystem = 'ko
|
|
|
2547
2612
|
calculateHouses(julianDay, getHouseSystemCode(houseSystem), false)
|
|
2548
2613
|
.then(houses => {
|
|
2549
2614
|
const planetLongitude = parseFloat(astroData.degreeInSign) + (signs.indexOf(astroData.sign) * 30);
|
|
2550
|
-
const house = getPlanetHouse(planetLongitude, houses.
|
|
2615
|
+
const house = getPlanetHouse(planetLongitude, houses, planetName, astroData.latitude);
|
|
2551
2616
|
|
|
2552
2617
|
// Berechne Aspekte, falls angefordert
|
|
2553
2618
|
let aspects = [];
|
|
@@ -11,6 +11,7 @@ const SE_GREG_CAL = nativeSwisseph ? nativeSwisseph.SE_GREG_CAL : 1;
|
|
|
11
11
|
const SEFLG_SWIEPH = nativeSwisseph ? nativeSwisseph.SEFLG_SWIEPH : 2;
|
|
12
12
|
const SEFLG_SPEED = nativeSwisseph ? nativeSwisseph.SEFLG_SPEED : 256;
|
|
13
13
|
const SEFLG_MOSEPH = nativeSwisseph ? nativeSwisseph.SEFLG_MOSEPH : 4;
|
|
14
|
+
const SE_ECL_NUT = nativeSwisseph ? nativeSwisseph.SE_ECL_NUT : -1;
|
|
14
15
|
|
|
15
16
|
let wasmModule = null;
|
|
16
17
|
let wasmGet = null;
|
|
@@ -19,10 +20,17 @@ let wasmReadyPromise = null;
|
|
|
19
20
|
const planetCache = new Map();
|
|
20
21
|
const houseCache = new Map();
|
|
21
22
|
|
|
23
|
+
function isWasmAllowed() {
|
|
24
|
+
return process.env.KLIO_ALLOW_WASM === '1';
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
function ensureReady() {
|
|
23
28
|
if (nativeSwisseph) {
|
|
24
29
|
return;
|
|
25
30
|
}
|
|
31
|
+
if (!isWasmAllowed()) {
|
|
32
|
+
throw new Error('Native swisseph is required. Set KLIO_ALLOW_WASM=1 to enable WASM fallback.');
|
|
33
|
+
}
|
|
26
34
|
if (!wasmModule || !wasmGet) {
|
|
27
35
|
throw new Error('Sweph WASM is not initialized. Call initialize() before use.');
|
|
28
36
|
}
|
|
@@ -32,6 +40,9 @@ async function initialize() {
|
|
|
32
40
|
if (nativeSwisseph) {
|
|
33
41
|
return;
|
|
34
42
|
}
|
|
43
|
+
if (!isWasmAllowed()) {
|
|
44
|
+
throw new Error('Native swisseph is required. Set KLIO_ALLOW_WASM=1 to enable WASM fallback.');
|
|
45
|
+
}
|
|
35
46
|
if (!wasmReadyPromise) {
|
|
36
47
|
wasmReadyPromise = loadSwephWasmModule().then((moduleInstance) => {
|
|
37
48
|
wasmModule = moduleInstance;
|
|
@@ -258,6 +269,17 @@ function swe_houses(julianDay, latitude, longitude, houseSystem, callback) {
|
|
|
258
269
|
return result;
|
|
259
270
|
}
|
|
260
271
|
|
|
272
|
+
function swe_houses_pos(armc, latitude, eps, houseSystem, longitude, planetLatitude, callback) {
|
|
273
|
+
if (nativeSwisseph && nativeSwisseph.swe_houses_pos) {
|
|
274
|
+
return nativeSwisseph.swe_houses_pos(armc, latitude, eps, houseSystem, longitude, planetLatitude, callback);
|
|
275
|
+
}
|
|
276
|
+
const fallback = { error: 'swe_houses_pos not available' };
|
|
277
|
+
if (typeof callback === 'function') {
|
|
278
|
+
callback(fallback);
|
|
279
|
+
}
|
|
280
|
+
return fallback;
|
|
281
|
+
}
|
|
282
|
+
|
|
261
283
|
function swe_set_ephe_path() {
|
|
262
284
|
if (nativeSwisseph && nativeSwisseph.swe_set_ephe_path) {
|
|
263
285
|
return nativeSwisseph.swe_set_ephe_path.apply(nativeSwisseph, arguments);
|
|
@@ -270,10 +292,12 @@ module.exports = {
|
|
|
270
292
|
SEFLG_SWIEPH,
|
|
271
293
|
SEFLG_SPEED,
|
|
272
294
|
SEFLG_MOSEPH,
|
|
295
|
+
SE_ECL_NUT,
|
|
273
296
|
initialize,
|
|
274
297
|
swe_set_ephe_path,
|
|
275
298
|
swe_calc_ut,
|
|
276
299
|
swe_julday,
|
|
277
300
|
swe_revjul,
|
|
278
|
-
swe_houses
|
|
301
|
+
swe_houses,
|
|
302
|
+
swe_houses_pos
|
|
279
303
|
};
|
package/src/cli/cli.js
CHANGED
|
@@ -269,7 +269,7 @@ const createAstrologicalNote = async (planetArg, planet2Arg, options, customDate
|
|
|
269
269
|
const julianDay = getJulianDay(currentDate, shouldUseBirthData(options));
|
|
270
270
|
const houses = await calculateHouses(julianDay, getHouseSystemCode(houseSystem), shouldUseBirthData(options));
|
|
271
271
|
const planetLongitude = parseFloat(planetData.degreeInSign) + (signs.indexOf(planetData.sign) * 30);
|
|
272
|
-
const house = getPlanetHouse(planetLongitude, houses.
|
|
272
|
+
const house = getPlanetHouse(planetLongitude, houses, planetArg, planetData.latitude);
|
|
273
273
|
noteData.house = house;
|
|
274
274
|
noteData.astrologicalSituation += ` in house ${house}`;
|
|
275
275
|
}
|
|
@@ -881,19 +881,22 @@ program
|
|
|
881
881
|
const allAspects = [];
|
|
882
882
|
for (const [planetName] of Object.entries(planets)) {
|
|
883
883
|
const transitPlanetData = getAstrologicalData(planetName, transitDateDisplay);
|
|
884
|
-
const
|
|
885
|
-
const
|
|
884
|
+
const transitLongitude = parseFloat(transitPlanetData.degreeInSign) + (signs.indexOf(transitPlanetData.sign) * 30);
|
|
885
|
+
const transitHouse = getPlanetHouse(transitLongitude, houses, planetName, transitPlanetData.latitude);
|
|
886
|
+
const transitAspectsData = calculatePersonalTransitAspects(transitDateDisplay, birthData, planetName, true);
|
|
886
887
|
const transitAspects = transitAspectsData ? transitAspectsData.aspects : [];
|
|
887
888
|
|
|
888
889
|
// Add planet data to each aspect for later display
|
|
889
890
|
transitAspects.forEach(aspect => {
|
|
891
|
+
const birthPlanetData = getAstrologicalData(aspect.birthPlanet, birthData);
|
|
892
|
+
const birthLongitude = parseFloat(birthPlanetData.degreeInSign) + (signs.indexOf(birthPlanetData.sign) * 30);
|
|
890
893
|
allAspects.push({
|
|
891
894
|
planetName: planetName,
|
|
892
895
|
transitPlanetData: transitPlanetData,
|
|
893
896
|
transitHouse: transitHouse,
|
|
894
897
|
aspect: aspect,
|
|
895
|
-
birthPlanetData:
|
|
896
|
-
birthHouse: getPlanetHouse(
|
|
898
|
+
birthPlanetData: birthPlanetData,
|
|
899
|
+
birthHouse: getPlanetHouse(birthLongitude, houses, aspect.birthPlanet, birthPlanetData.latitude)
|
|
897
900
|
});
|
|
898
901
|
});
|
|
899
902
|
}
|
|
@@ -999,13 +1002,13 @@ program
|
|
|
999
1002
|
// Show personal transit aspects
|
|
1000
1003
|
// Use the specific planet if specified, or all planets
|
|
1001
1004
|
const targetPlanet = planetArg ? planetArg.toLowerCase() : null;
|
|
1002
|
-
showPersonalTransitAspects(transitDate, birthData, targetPlanet);
|
|
1005
|
+
showPersonalTransitAspects(transitDate, birthData, targetPlanet, true);
|
|
1003
1006
|
|
|
1004
1007
|
// Handle AI request for personal transit aspects
|
|
1005
1008
|
if (options.p) {
|
|
1006
1009
|
// Get the transit aspects data for AI
|
|
1007
1010
|
const { calculatePersonalTransitAspects } = require('../astrology/astrologyService');
|
|
1008
|
-
const transitAspectsData = calculatePersonalTransitAspects(transitDate, birthData, targetPlanet);
|
|
1011
|
+
const transitAspectsData = calculatePersonalTransitAspects(transitDate, birthData, targetPlanet, true);
|
|
1009
1012
|
const transitAspects = transitAspectsData ? transitAspectsData.aspects : [];
|
|
1010
1013
|
|
|
1011
1014
|
const aiData = {
|
|
@@ -1664,7 +1667,7 @@ program
|
|
|
1664
1667
|
let house = 'N/A';
|
|
1665
1668
|
if (houses) {
|
|
1666
1669
|
const planetLongitude = parseFloat(data.degreeInSign) + (signs.indexOf(data.sign) * 30);
|
|
1667
|
-
house = getPlanetHouse(planetLongitude, houses.
|
|
1670
|
+
house = getPlanetHouse(planetLongitude, houses, name, data.latitude);
|
|
1668
1671
|
}
|
|
1669
1672
|
|
|
1670
1673
|
const planetNameFormatted = name.charAt(0).toUpperCase() + name.slice(1);
|
|
@@ -1732,7 +1735,7 @@ program
|
|
|
1732
1735
|
let house = 'N/A';
|
|
1733
1736
|
if (houses) {
|
|
1734
1737
|
const planetLongitude = parseFloat(data.degreeInSign) + (signs.indexOf(data.sign) * 30);
|
|
1735
|
-
house = getPlanetHouse(planetLongitude, houses.
|
|
1738
|
+
house = getPlanetHouse(planetLongitude, houses, name, data.latitude);
|
|
1736
1739
|
}
|
|
1737
1740
|
allPlanetData[name] = {
|
|
1738
1741
|
sign: data.sign,
|
|
@@ -2476,7 +2479,8 @@ program
|
|
|
2476
2479
|
houses = await calculateHouses(julianDay, getHouseSystemCode(houseSystem), useBirthLocation);
|
|
2477
2480
|
|
|
2478
2481
|
// Determine the house of the planet
|
|
2479
|
-
const
|
|
2482
|
+
const planetLongitude = parseFloat(data.degreeInSign) + (signs.indexOf(data.sign) * 30);
|
|
2483
|
+
const planetHouse = getPlanetHouse(planetLongitude, houses, planet, data.latitude);
|
|
2480
2484
|
houseInfo = {
|
|
2481
2485
|
house: planetHouse,
|
|
2482
2486
|
houseSystem: options.hs
|
|
@@ -3021,7 +3025,8 @@ program
|
|
|
3021
3025
|
}
|
|
3022
3026
|
|
|
3023
3027
|
// Determine the planet's house
|
|
3024
|
-
const
|
|
3028
|
+
const planetLongitude = parseFloat(data.degreeInSign) + (signs.indexOf(data.sign) * 30);
|
|
3029
|
+
const planetHouse = getPlanetHouse(planetLongitude, houses, data.planet, data.latitude);
|
|
3025
3030
|
const planetNameCapitalized = data.planet.charAt(0).toUpperCase() + data.planet.slice(1);
|
|
3026
3031
|
console.log(`${planetNameCapitalized} is in house ${planetHouse}`);
|
|
3027
3032
|
console.log();
|
package/src/cli/cliService.js
CHANGED
|
@@ -887,16 +887,18 @@ class CLIService {
|
|
|
887
887
|
// Function to calculate Julian Day in UTC for house calculation
|
|
888
888
|
const getJulianDayUTCForHouses = () => {
|
|
889
889
|
let timezoneOffsetMinutes = 0;
|
|
890
|
-
|
|
890
|
+
|
|
891
891
|
if (birthData && birthData.location) {
|
|
892
|
-
|
|
892
|
+
// Use the natal location's timezone, but with the current date (or --d date)
|
|
893
|
+
timezoneOffsetMinutes = getTimezoneOffset(customDate, birthData.location.timezone || 'Europe/Zurich');
|
|
893
894
|
} else if (config && config.currentLocation && config.currentLocation.timezone) {
|
|
894
895
|
timezoneOffsetMinutes = getTimezoneOffset(customDate, config.currentLocation.timezone);
|
|
895
896
|
} else {
|
|
896
897
|
timezoneOffsetMinutes = -new Date().getTimezoneOffset();
|
|
897
898
|
}
|
|
898
|
-
|
|
899
|
-
|
|
899
|
+
|
|
900
|
+
// Always use customDate (current or --d date), not birthData
|
|
901
|
+
return calculateJulianDayUTC(customDate, timezoneOffsetMinutes);
|
|
900
902
|
};
|
|
901
903
|
|
|
902
904
|
// Calculate houses if house system is specified
|
|
@@ -921,12 +923,12 @@ class CLIService {
|
|
|
921
923
|
// Calculate positions of all planets
|
|
922
924
|
for (const [name, planetId] of Object.entries(planets)) {
|
|
923
925
|
const data = getAstrologicalData(name, customDate);
|
|
924
|
-
|
|
926
|
+
|
|
925
927
|
// Determine the house if houses were calculated
|
|
926
928
|
let house = 'N/A';
|
|
927
929
|
if (houses) {
|
|
928
|
-
|
|
929
|
-
house = getPlanetHouse(
|
|
930
|
+
// Use the actual longitude value directly (not reconstructed from sign+degree)
|
|
931
|
+
house = getPlanetHouse(data.longitude, houses, name, data.latitude);
|
|
930
932
|
}
|
|
931
933
|
|
|
932
934
|
const planetNameFormatted = name.charAt(0).toUpperCase() + name.slice(1);
|
|
@@ -735,7 +735,8 @@ async function performSetup(userId = null) {
|
|
|
735
735
|
name: birthGeoData.name,
|
|
736
736
|
country: birthGeoData.country,
|
|
737
737
|
latitude: birthGeoData.latitude,
|
|
738
|
-
longitude: birthGeoData.longitude
|
|
738
|
+
longitude: birthGeoData.longitude,
|
|
739
|
+
timezone: birthGeoData.timezone
|
|
739
740
|
} : null
|
|
740
741
|
},
|
|
741
742
|
aiConfiguration: aiConfig,
|
|
@@ -209,6 +209,7 @@ const command = rawCommand.startsWith('klio ') ? rawCommand.slice(5).trim() : ra
|
|
|
209
209
|
|
|
210
210
|
process.env.KLIO_CAPTURE_ONLY = '1';
|
|
211
211
|
process.env.KLIO_CONFIG_PATH = '/src/.astrocli/config.json';
|
|
212
|
+
process.env.KLIO_ALLOW_WASM = '1';
|
|
212
213
|
try {
|
|
213
214
|
const configText = fs.readFileSync(process.env.KLIO_CONFIG_PATH, 'utf8');
|
|
214
215
|
if (configText) {
|