chart2txt 0.6.0 → 0.7.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 +101 -34
- package/dist/chart2txt.d.ts +9 -0
- package/dist/chart2txt.js +30 -0
- package/dist/chart2txt.min.js +1 -1
- package/dist/config/ChartSettings.d.ts +12 -6
- package/dist/config/ChartSettings.js +36 -11
- package/dist/constants.d.ts +17 -2
- package/dist/constants.js +301 -34
- package/dist/core/analysis.d.ts +6 -0
- package/dist/core/analysis.js +235 -0
- package/dist/core/aspectPatterns.d.ts +8 -3
- package/dist/core/aspectPatterns.js +234 -218
- package/dist/core/aspects.d.ts +14 -11
- package/dist/core/aspects.js +49 -32
- package/dist/core/dignities.d.ts +2 -27
- package/dist/core/dignities.js +56 -121
- package/dist/core/dispositors.d.ts +6 -19
- package/dist/core/dispositors.js +45 -131
- package/dist/core/grouping.d.ts +9 -0
- package/dist/core/grouping.js +45 -0
- package/dist/core/signDistributions.d.ts +20 -30
- package/dist/core/signDistributions.js +22 -122
- package/dist/core/stelliums.d.ts +10 -0
- package/dist/core/stelliums.js +108 -0
- package/dist/formatters/text/sections/aspectPatterns.d.ts +3 -1
- package/dist/formatters/text/sections/aspectPatterns.js +118 -94
- package/dist/formatters/text/sections/aspects.d.ts +3 -6
- package/dist/formatters/text/sections/aspects.js +35 -52
- package/dist/formatters/text/sections/dispositors.d.ts +4 -3
- package/dist/formatters/text/sections/dispositors.js +7 -8
- package/dist/formatters/text/sections/houseOverlays.d.ts +11 -6
- package/dist/formatters/text/sections/houseOverlays.js +37 -44
- package/dist/formatters/text/sections/metadata.d.ts +2 -0
- package/dist/formatters/text/sections/metadata.js +54 -0
- package/dist/formatters/text/sections/planets.d.ts +3 -5
- package/dist/formatters/text/sections/planets.js +11 -22
- package/dist/formatters/text/sections/signDistributions.d.ts +9 -25
- package/dist/formatters/text/sections/signDistributions.js +9 -55
- package/dist/formatters/text/textFormatter.d.ts +4 -5
- package/dist/formatters/text/textFormatter.js +81 -141
- package/dist/index.d.ts +7 -4
- package/dist/index.js +11 -6
- package/dist/types.d.ts +100 -15
- package/dist/types.js +15 -0
- package/dist/utils/formatting.d.ts +4 -0
- package/dist/utils/formatting.js +43 -0
- package/dist/utils/houseCalculations.d.ts +10 -13
- package/dist/utils/houseCalculations.js +15 -57
- package/package.json +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.groupAspects = groupAspects;
|
|
4
|
+
/**
|
|
5
|
+
* Provides a default grouping of aspects into "Tight", "Moderate", and "Wide" categories
|
|
6
|
+
* based on orb thresholds. This is used by the simple chart2txt() function.
|
|
7
|
+
* @param aspects The raw list of aspects to group.
|
|
8
|
+
* @param settings The chart settings, containing aspectStrengthThresholds.
|
|
9
|
+
* @returns A map of category names to aspect data arrays.
|
|
10
|
+
*/
|
|
11
|
+
function groupAspects(aspects, settings) {
|
|
12
|
+
const grouped = new Map();
|
|
13
|
+
const thresholds = settings.aspectStrengthThresholds;
|
|
14
|
+
const tight = [];
|
|
15
|
+
const moderate = [];
|
|
16
|
+
const wide = [];
|
|
17
|
+
aspects.forEach((aspect) => {
|
|
18
|
+
if (aspect.orb <= thresholds.tight) {
|
|
19
|
+
tight.push(aspect);
|
|
20
|
+
}
|
|
21
|
+
else if (aspect.orb <= thresholds.moderate) {
|
|
22
|
+
moderate.push(aspect);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
wide.push(aspect);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
// Sort each category by orb tightness
|
|
29
|
+
tight.sort((a, b) => a.orb - b.orb);
|
|
30
|
+
moderate.sort((a, b) => a.orb - b.orb);
|
|
31
|
+
wide.sort((a, b) => a.orb - b.orb);
|
|
32
|
+
if (tight.length > 0) {
|
|
33
|
+
const title = `[TIGHT ASPECTS: orb under ${thresholds.tight.toFixed(1)}°]`;
|
|
34
|
+
grouped.set(title, tight);
|
|
35
|
+
}
|
|
36
|
+
if (moderate.length > 0) {
|
|
37
|
+
const title = `[MODERATE ASPECTS: orb ${thresholds.tight.toFixed(1)}-${thresholds.moderate.toFixed(1)}°]`;
|
|
38
|
+
grouped.set(title, moderate);
|
|
39
|
+
}
|
|
40
|
+
if (wide.length > 0) {
|
|
41
|
+
const title = `[WIDE ASPECTS: orb over ${thresholds.moderate.toFixed(1)}°]`;
|
|
42
|
+
grouped.set(title, wide);
|
|
43
|
+
}
|
|
44
|
+
return grouped;
|
|
45
|
+
}
|
|
@@ -1,31 +1,21 @@
|
|
|
1
1
|
import { Point } from '../types';
|
|
2
|
-
export
|
|
3
|
-
elements:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export declare function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export declare function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* @param modalities Modality distribution data
|
|
23
|
-
* @returns Array of formatted strings
|
|
24
|
-
*/
|
|
25
|
-
export declare function formatModalityDistribution(modalities: Record<string, number>): string[];
|
|
26
|
-
/**
|
|
27
|
-
* Formats polarity distribution for display
|
|
28
|
-
* @param polarities Polarity distribution data
|
|
29
|
-
* @returns Array of formatted strings
|
|
30
|
-
*/
|
|
31
|
-
export declare function formatPolarityDistribution(polarities: Record<string, number>): string[];
|
|
2
|
+
export declare function calculateSignDistributions(planets: Point[], ascendant?: number): {
|
|
3
|
+
elements: {
|
|
4
|
+
[key: string]: string[];
|
|
5
|
+
};
|
|
6
|
+
modalities: {
|
|
7
|
+
[key: string]: number;
|
|
8
|
+
};
|
|
9
|
+
polarities: {
|
|
10
|
+
[key: string]: number;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export declare function formatElementDistribution(elements: {
|
|
14
|
+
[key: string]: string[];
|
|
15
|
+
}): string[];
|
|
16
|
+
export declare function formatModalityDistribution(modalities: {
|
|
17
|
+
[key: string]: number;
|
|
18
|
+
}): string[];
|
|
19
|
+
export declare function formatPolarityDistribution(polarities: {
|
|
20
|
+
[key: string]: number;
|
|
21
|
+
}): string[];
|
|
@@ -1,60 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.calculateSignDistributions = calculateSignDistributions;
|
|
4
4
|
exports.formatElementDistribution = formatElementDistribution;
|
|
5
5
|
exports.formatModalityDistribution = formatModalityDistribution;
|
|
6
6
|
exports.formatPolarityDistribution = formatPolarityDistribution;
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Virgo: 'Earth',
|
|
15
|
-
Capricorn: 'Earth',
|
|
16
|
-
Gemini: 'Air',
|
|
17
|
-
Libra: 'Air',
|
|
18
|
-
Aquarius: 'Air',
|
|
19
|
-
Cancer: 'Water',
|
|
20
|
-
Scorpio: 'Water',
|
|
21
|
-
Pisces: 'Water',
|
|
22
|
-
};
|
|
23
|
-
const SIGN_MODALITIES = {
|
|
24
|
-
Aries: 'Cardinal',
|
|
25
|
-
Cancer: 'Cardinal',
|
|
26
|
-
Libra: 'Cardinal',
|
|
27
|
-
Capricorn: 'Cardinal',
|
|
28
|
-
Taurus: 'Fixed',
|
|
29
|
-
Leo: 'Fixed',
|
|
30
|
-
Scorpio: 'Fixed',
|
|
31
|
-
Aquarius: 'Fixed',
|
|
32
|
-
Gemini: 'Mutable',
|
|
33
|
-
Virgo: 'Mutable',
|
|
34
|
-
Sagittarius: 'Mutable',
|
|
35
|
-
Pisces: 'Mutable',
|
|
36
|
-
};
|
|
37
|
-
const SIGN_POLARITIES = {
|
|
38
|
-
Aries: 'Masculine',
|
|
39
|
-
Gemini: 'Masculine',
|
|
40
|
-
Leo: 'Masculine',
|
|
41
|
-
Libra: 'Masculine',
|
|
42
|
-
Sagittarius: 'Masculine',
|
|
43
|
-
Aquarius: 'Masculine',
|
|
44
|
-
Taurus: 'Feminine',
|
|
45
|
-
Cancer: 'Feminine',
|
|
46
|
-
Virgo: 'Feminine',
|
|
47
|
-
Scorpio: 'Feminine',
|
|
48
|
-
Capricorn: 'Feminine',
|
|
49
|
-
Pisces: 'Feminine',
|
|
50
|
-
};
|
|
51
|
-
/**
|
|
52
|
-
* Analyzes the distribution of planets across elements, modalities, and polarities
|
|
53
|
-
* @param planets Array of planet points
|
|
54
|
-
* @param includeAscendant Optional ascendant degree to include in analysis
|
|
55
|
-
* @returns Sign distribution analysis
|
|
56
|
-
*/
|
|
57
|
-
function analyzeSignDistributions(planets, includeAscendant) {
|
|
7
|
+
const formatting_1 = require("../utils/formatting");
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
function calculateSignDistributions(planets, ascendant) {
|
|
10
|
+
const points = [...planets];
|
|
11
|
+
if (ascendant !== undefined) {
|
|
12
|
+
points.push({ name: 'Ascendant', degree: ascendant });
|
|
13
|
+
}
|
|
58
14
|
const elements = {
|
|
59
15
|
Fire: [],
|
|
60
16
|
Earth: [],
|
|
@@ -66,85 +22,29 @@ function analyzeSignDistributions(planets, includeAscendant) {
|
|
|
66
22
|
Fixed: 0,
|
|
67
23
|
Mutable: 0,
|
|
68
24
|
};
|
|
69
|
-
const polarities = {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const modality = SIGN_MODALITIES[sign];
|
|
78
|
-
const polarity = SIGN_POLARITIES[sign];
|
|
79
|
-
if (element) {
|
|
80
|
-
elements[element].push(planet.name);
|
|
81
|
-
}
|
|
82
|
-
if (modality) {
|
|
83
|
-
modalities[modality]++;
|
|
84
|
-
}
|
|
85
|
-
if (polarity) {
|
|
86
|
-
polarities[polarity]++;
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
// Process ascendant if provided
|
|
90
|
-
if (includeAscendant !== undefined) {
|
|
91
|
-
const ascSign = (0, astrology_1.getDegreeSign)(includeAscendant);
|
|
92
|
-
const ascElement = SIGN_ELEMENTS[ascSign];
|
|
93
|
-
const ascModality = SIGN_MODALITIES[ascSign];
|
|
94
|
-
const ascPolarity = SIGN_POLARITIES[ascSign];
|
|
95
|
-
if (ascElement) {
|
|
96
|
-
elements[ascElement].push('Ascendant');
|
|
97
|
-
}
|
|
98
|
-
if (ascModality) {
|
|
99
|
-
modalities[ascModality]++;
|
|
100
|
-
}
|
|
101
|
-
if (ascPolarity) {
|
|
102
|
-
polarities[ascPolarity]++;
|
|
25
|
+
const polarities = { Masculine: 0, Feminine: 0 };
|
|
26
|
+
for (const point of points) {
|
|
27
|
+
const sign = (0, formatting_1.getSign)(point.degree);
|
|
28
|
+
const signInfo = constants_1.ZODIAC_SIGN_DATA.find((s) => s.name === sign);
|
|
29
|
+
if (signInfo) {
|
|
30
|
+
elements[signInfo.element].push(point.name);
|
|
31
|
+
modalities[signInfo.modality]++;
|
|
32
|
+
polarities[signInfo.polarity]++;
|
|
103
33
|
}
|
|
104
34
|
}
|
|
105
35
|
return { elements, modalities, polarities };
|
|
106
36
|
}
|
|
107
|
-
/**
|
|
108
|
-
* Formats element distribution for display
|
|
109
|
-
* @param elements Element distribution data
|
|
110
|
-
* @returns Array of formatted strings
|
|
111
|
-
*/
|
|
112
37
|
function formatElementDistribution(elements) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const planetList = planets.join(', ');
|
|
117
|
-
output.push(`${element}: ${planets.length} (${planetList})`);
|
|
38
|
+
return Object.entries(elements).map(([element, planets]) => {
|
|
39
|
+
if (planets.length === 0) {
|
|
40
|
+
return `${element}: 0`;
|
|
118
41
|
}
|
|
42
|
+
return `${element}: ${planets.length} (${planets.join(', ')})`;
|
|
119
43
|
});
|
|
120
|
-
return output;
|
|
121
44
|
}
|
|
122
|
-
/**
|
|
123
|
-
* Formats modality distribution for display
|
|
124
|
-
* @param modalities Modality distribution data
|
|
125
|
-
* @returns Array of formatted strings
|
|
126
|
-
*/
|
|
127
45
|
function formatModalityDistribution(modalities) {
|
|
128
|
-
|
|
129
|
-
Object.entries(modalities).forEach(([modality, count]) => {
|
|
130
|
-
if (count > 0) {
|
|
131
|
-
output.push(`${modality}: ${count}`);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
return output;
|
|
46
|
+
return Object.entries(modalities).map(([modality, count]) => `${modality}: ${count}`);
|
|
135
47
|
}
|
|
136
|
-
/**
|
|
137
|
-
* Formats polarity distribution for display
|
|
138
|
-
* @param polarities Polarity distribution data
|
|
139
|
-
* @returns Array of formatted strings
|
|
140
|
-
*/
|
|
141
48
|
function formatPolarityDistribution(polarities) {
|
|
142
|
-
|
|
143
|
-
if (polarities['Masculine'] > 0) {
|
|
144
|
-
output.push(`Masculine (Active): ${polarities['Masculine']}`);
|
|
145
|
-
}
|
|
146
|
-
if (polarities['Feminine'] > 0) {
|
|
147
|
-
output.push(`Feminine (Receptive): ${polarities['Feminine']}`);
|
|
148
|
-
}
|
|
149
|
-
return output;
|
|
49
|
+
return Object.entries(polarities).map(([polarity, count]) => `${polarity}: ${count}`);
|
|
150
50
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Point, Stellium } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Detect Stellium patterns (3+ planets in same sign or adjacent houses)
|
|
4
|
+
* This function requires house information and is specific to single-chart analysis
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectStelliums(planets: Point[], houseCusps?: number[], minPlanets?: number): Stellium[];
|
|
7
|
+
/**
|
|
8
|
+
* Format a Stellium pattern for display in compact format
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatStellium(pattern: Stellium): string[];
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectStelliums = detectStelliums;
|
|
4
|
+
exports.formatStellium = formatStellium;
|
|
5
|
+
const astrology_1 = require("./astrology");
|
|
6
|
+
const houseCalculations_1 = require("../utils/houseCalculations");
|
|
7
|
+
const formatting_1 = require("../utils/formatting");
|
|
8
|
+
/**
|
|
9
|
+
* Convert Point to PlanetPosition
|
|
10
|
+
*/
|
|
11
|
+
function pointToPlanetPosition(point, houseCusps) {
|
|
12
|
+
const sign = (0, astrology_1.getDegreeSign)(point.degree);
|
|
13
|
+
const house = houseCusps
|
|
14
|
+
? (0, houseCalculations_1.getHouseForPoint)(point.degree, houseCusps) || undefined
|
|
15
|
+
: undefined;
|
|
16
|
+
return {
|
|
17
|
+
name: point.name,
|
|
18
|
+
degree: point.degree,
|
|
19
|
+
sign,
|
|
20
|
+
house,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detect Stellium patterns (3+ planets in same sign or adjacent houses)
|
|
25
|
+
* This function requires house information and is specific to single-chart analysis
|
|
26
|
+
*/
|
|
27
|
+
function detectStelliums(planets, houseCusps, minPlanets = 3) {
|
|
28
|
+
const patterns = [];
|
|
29
|
+
// Group by sign
|
|
30
|
+
const signGroups = new Map();
|
|
31
|
+
planets.forEach((planet) => {
|
|
32
|
+
const sign = (0, astrology_1.getDegreeSign)(planet.degree);
|
|
33
|
+
if (!signGroups.has(sign)) {
|
|
34
|
+
signGroups.set(sign, []);
|
|
35
|
+
}
|
|
36
|
+
signGroups.get(sign).push(planet);
|
|
37
|
+
});
|
|
38
|
+
// Check sign-based stelliums
|
|
39
|
+
signGroups.forEach((planetsInSign, sign) => {
|
|
40
|
+
if (planetsInSign.length >= minPlanets) {
|
|
41
|
+
const planetPositions = planetsInSign.map((p) => pointToPlanetPosition(p, houseCusps));
|
|
42
|
+
const houses = planetPositions
|
|
43
|
+
.map((p) => p.house)
|
|
44
|
+
.filter((h) => h !== undefined);
|
|
45
|
+
const degrees = planetsInSign.map((p) => p.degree);
|
|
46
|
+
const span = Math.max(...degrees) - Math.min(...degrees);
|
|
47
|
+
patterns.push({
|
|
48
|
+
type: 'Stellium',
|
|
49
|
+
planets: planetPositions,
|
|
50
|
+
sign,
|
|
51
|
+
houses: [...new Set(houses)].sort(),
|
|
52
|
+
span,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Check house-based stelliums (if house cusps available)
|
|
57
|
+
if (houseCusps) {
|
|
58
|
+
const houseGroups = new Map();
|
|
59
|
+
planets.forEach((planet) => {
|
|
60
|
+
const house = (0, houseCalculations_1.getHouseForPoint)(planet.degree, houseCusps);
|
|
61
|
+
if (house) {
|
|
62
|
+
if (!houseGroups.has(house)) {
|
|
63
|
+
houseGroups.set(house, []);
|
|
64
|
+
}
|
|
65
|
+
houseGroups.get(house).push(planet);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
houseGroups.forEach((planetsInHouse, house) => {
|
|
69
|
+
if (planetsInHouse.length >= minPlanets) {
|
|
70
|
+
const planetPositions = planetsInHouse.map((p) => pointToPlanetPosition(p, houseCusps));
|
|
71
|
+
const degrees = planetsInHouse.map((p) => p.degree);
|
|
72
|
+
const span = Math.max(...degrees) - Math.min(...degrees);
|
|
73
|
+
// Only add if not already covered by sign stellium
|
|
74
|
+
const existingSignStellium = patterns.find((p) => p.type === 'Stellium' &&
|
|
75
|
+
p.planets.some((planet) => planetPositions.some((pp) => pp.name === planet.name)));
|
|
76
|
+
if (!existingSignStellium) {
|
|
77
|
+
patterns.push({
|
|
78
|
+
type: 'Stellium',
|
|
79
|
+
planets: planetPositions,
|
|
80
|
+
houses: [house],
|
|
81
|
+
span,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return patterns;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format a Stellium pattern for display in compact format
|
|
91
|
+
*/
|
|
92
|
+
function formatStellium(pattern) {
|
|
93
|
+
const planetNames = pattern.planets.map((p) => p.name).join(', ');
|
|
94
|
+
let location = '';
|
|
95
|
+
if (pattern.sign) {
|
|
96
|
+
location = pattern.sign;
|
|
97
|
+
}
|
|
98
|
+
if (pattern.houses && pattern.houses.length > 0) {
|
|
99
|
+
const houseStr = pattern.houses.length === 1
|
|
100
|
+
? `${(0, formatting_1.getOrdinal)(pattern.houses[0])} House`
|
|
101
|
+
: pattern.houses.map((h) => `${(0, formatting_1.getOrdinal)(h)} House`).join('-');
|
|
102
|
+
location += location ? ` (${houseStr})` : houseStr;
|
|
103
|
+
}
|
|
104
|
+
const locationStr = location ? ` in ${location}` : '';
|
|
105
|
+
return [
|
|
106
|
+
`Stellium (${pattern.span.toFixed(1)}°): ${planetNames}${locationStr}`,
|
|
107
|
+
];
|
|
108
|
+
}
|
|
@@ -2,6 +2,8 @@ import { AspectPattern } from '../../../types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Generates the [ASPECT PATTERNS] section of the chart output.
|
|
4
4
|
* @param patterns Array of detected aspect patterns
|
|
5
|
+
* @param customTitle Optional custom title for the section
|
|
6
|
+
* @param showChartNames Whether to show chart names for planets (false for single charts, true for multi-chart)
|
|
5
7
|
* @returns An array of strings for the output.
|
|
6
8
|
*/
|
|
7
|
-
export declare function generateAspectPatternsOutput(patterns: AspectPattern[]): string[];
|
|
9
|
+
export declare function generateAspectPatternsOutput(patterns: AspectPattern[], customTitle?: string, showChartNames?: boolean): string[];
|