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
|
@@ -6,164 +6,188 @@ const formatting_1 = require("../../../utils/formatting");
|
|
|
6
6
|
/**
|
|
7
7
|
* Format a planet position for display
|
|
8
8
|
*/
|
|
9
|
-
function formatPlanetPosition(planet) {
|
|
9
|
+
function formatPlanetPosition(planet, includeHouse = false, showChartNames = true) {
|
|
10
10
|
const degInSign = Math.floor((0, astrology_1.getDegreeInSign)(planet.degree));
|
|
11
|
-
const houseStr = planet.house ? ` (${(0, formatting_1.getOrdinal)(planet.house)} house)` : '';
|
|
12
|
-
|
|
11
|
+
const houseStr = includeHouse && planet.house ? ` (${(0, formatting_1.getOrdinal)(planet.house)} house)` : '';
|
|
12
|
+
const chartPrefix = showChartNames && planet.chartName ? `${planet.chartName}'s ` : '';
|
|
13
|
+
return `${chartPrefix}${planet.name} ${degInSign}° ${planet.sign}${houseStr}`;
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
|
-
* Format a T-Square pattern
|
|
16
|
+
* Format a T-Square pattern in compact format
|
|
16
17
|
*/
|
|
17
|
-
function formatTSquare(pattern) {
|
|
18
|
+
function formatTSquare(pattern, showChartNames = true) {
|
|
18
19
|
if (pattern.type !== 'T-Square')
|
|
19
20
|
return [];
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return output;
|
|
21
|
+
const apex = formatPlanetPosition(pattern.apex, false, showChartNames);
|
|
22
|
+
const opp1 = formatPlanetPosition(pattern.opposition[0], false, showChartNames);
|
|
23
|
+
const opp2 = formatPlanetPosition(pattern.opposition[1], false, showChartNames);
|
|
24
|
+
return [
|
|
25
|
+
`T-Square (${pattern.mode}, ${pattern.averageOrb.toFixed(1)}°): ${apex} ← ${opp1} ↔ ${opp2}`,
|
|
26
|
+
];
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
* Format a Grand Trine pattern
|
|
29
|
+
* Format a Grand Trine pattern in compact format
|
|
30
30
|
*/
|
|
31
|
-
function formatGrandTrine(pattern) {
|
|
31
|
+
function formatGrandTrine(pattern, showChartNames = true) {
|
|
32
32
|
if (pattern.type !== 'Grand Trine')
|
|
33
33
|
return [];
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
output.push('');
|
|
41
|
-
return output;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Format a Stellium pattern
|
|
45
|
-
*/
|
|
46
|
-
function formatStellium(pattern) {
|
|
47
|
-
if (pattern.type !== 'Stellium')
|
|
48
|
-
return [];
|
|
49
|
-
const output = ['Stellium:'];
|
|
50
|
-
const planetNames = pattern.planets.map((p) => p.name).join(', ');
|
|
51
|
-
output.push(` - Planets: ${planetNames}`);
|
|
52
|
-
if (pattern.sign) {
|
|
53
|
-
output.push(` - Sign: ${pattern.sign}`);
|
|
54
|
-
}
|
|
55
|
-
if (pattern.houses.length > 0) {
|
|
56
|
-
const houseStr = pattern.houses.length === 1
|
|
57
|
-
? `${(0, formatting_1.getOrdinal)(pattern.houses[0])}`
|
|
58
|
-
: pattern.houses.map((h) => (0, formatting_1.getOrdinal)(h)).join('-');
|
|
59
|
-
output.push(` - Houses: ${houseStr}`);
|
|
60
|
-
}
|
|
61
|
-
output.push(` - Span: ${pattern.span.toFixed(1)}°`);
|
|
62
|
-
output.push('');
|
|
63
|
-
return output;
|
|
34
|
+
const planets = pattern.planets
|
|
35
|
+
.map((p) => formatPlanetPosition(p, false, showChartNames))
|
|
36
|
+
.join(' △ ');
|
|
37
|
+
return [
|
|
38
|
+
`Grand Trine (${pattern.element}, ${pattern.averageOrb.toFixed(1)}°): ${planets}`,
|
|
39
|
+
];
|
|
64
40
|
}
|
|
65
41
|
/**
|
|
66
|
-
* Format a Grand Cross pattern
|
|
42
|
+
* Format a Grand Cross pattern in compact format
|
|
67
43
|
*/
|
|
68
|
-
function formatGrandCross(pattern) {
|
|
44
|
+
function formatGrandCross(pattern, showChartNames = true) {
|
|
69
45
|
if (pattern.type !== 'Grand Cross')
|
|
70
46
|
return [];
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
output.push('');
|
|
78
|
-
return output;
|
|
47
|
+
const planets = pattern.planets
|
|
48
|
+
.map((p) => formatPlanetPosition(p, false, showChartNames))
|
|
49
|
+
.join(' ⨯ ');
|
|
50
|
+
return [
|
|
51
|
+
`Grand Cross (${pattern.mode}, ${pattern.averageOrb.toFixed(1)}°): ${planets}`,
|
|
52
|
+
];
|
|
79
53
|
}
|
|
80
54
|
/**
|
|
81
|
-
* Format a Yod pattern
|
|
55
|
+
* Format a Yod pattern in compact format
|
|
82
56
|
*/
|
|
83
|
-
function formatYod(pattern) {
|
|
57
|
+
function formatYod(pattern, showChartNames = true) {
|
|
84
58
|
if (pattern.type !== 'Yod')
|
|
85
59
|
return [];
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return output;
|
|
60
|
+
const apex = formatPlanetPosition(pattern.apex, false, showChartNames);
|
|
61
|
+
const base1 = formatPlanetPosition(pattern.base[0], false, showChartNames);
|
|
62
|
+
const base2 = formatPlanetPosition(pattern.base[1], false, showChartNames);
|
|
63
|
+
return [
|
|
64
|
+
`Yod (${pattern.averageOrb.toFixed(1)}°): ${apex} ← ${base1} • ${base2}`,
|
|
65
|
+
];
|
|
93
66
|
}
|
|
94
67
|
/**
|
|
95
|
-
* Format a Mystic Rectangle pattern
|
|
68
|
+
* Format a Mystic Rectangle pattern in compact format
|
|
96
69
|
*/
|
|
97
|
-
function formatMysticRectangle(pattern) {
|
|
70
|
+
function formatMysticRectangle(pattern, showChartNames = true) {
|
|
98
71
|
if (pattern.type !== 'Mystic Rectangle')
|
|
99
72
|
return [];
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
73
|
+
const opp1_1 = formatPlanetPosition(pattern.oppositions[0][0], false, showChartNames);
|
|
74
|
+
const opp1_2 = formatPlanetPosition(pattern.oppositions[0][1], false, showChartNames);
|
|
75
|
+
const opp2_1 = formatPlanetPosition(pattern.oppositions[1][0], false, showChartNames);
|
|
76
|
+
const opp2_2 = formatPlanetPosition(pattern.oppositions[1][1], false, showChartNames);
|
|
77
|
+
return [
|
|
78
|
+
`Mystic Rectangle (${pattern.averageOrb.toFixed(1)}°): ${opp1_1} ↔ ${opp1_2} | ${opp2_1} ↔ ${opp2_2}`,
|
|
79
|
+
];
|
|
106
80
|
}
|
|
107
81
|
/**
|
|
108
|
-
* Format a Kite pattern
|
|
82
|
+
* Format a Kite pattern in compact format
|
|
109
83
|
*/
|
|
110
|
-
function formatKite(pattern) {
|
|
84
|
+
function formatKite(pattern, showChartNames = true) {
|
|
111
85
|
if (pattern.type !== 'Kite')
|
|
112
86
|
return [];
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
87
|
+
const grandTrineStr = pattern.grandTrine
|
|
88
|
+
.map((p) => formatPlanetPosition(p, false, showChartNames))
|
|
89
|
+
.join(' △ ');
|
|
90
|
+
const oppositionPlanet = formatPlanetPosition(pattern.opposition, false, showChartNames);
|
|
91
|
+
// Get the element from the first planet's sign for context
|
|
92
|
+
const element = pattern.grandTrine[0].sign
|
|
93
|
+
? getElementFromSign(pattern.grandTrine[0].sign)
|
|
94
|
+
: '';
|
|
95
|
+
const elementStr = element ? `${element}, ` : '';
|
|
96
|
+
return [
|
|
97
|
+
`Kite (${elementStr}${pattern.averageOrb.toFixed(1)}°): [${grandTrineStr}] ← ${oppositionPlanet}`,
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Helper function to get element from sign
|
|
102
|
+
*/
|
|
103
|
+
function getElementFromSign(sign) {
|
|
104
|
+
const fireSigns = ['Aries', 'Leo', 'Sagittarius'];
|
|
105
|
+
const earthSigns = ['Taurus', 'Virgo', 'Capricorn'];
|
|
106
|
+
const airSigns = ['Gemini', 'Libra', 'Aquarius'];
|
|
107
|
+
const waterSigns = ['Cancer', 'Scorpio', 'Pisces'];
|
|
108
|
+
if (fireSigns.includes(sign))
|
|
109
|
+
return 'Fire';
|
|
110
|
+
if (earthSigns.includes(sign))
|
|
111
|
+
return 'Earth';
|
|
112
|
+
if (airSigns.includes(sign))
|
|
113
|
+
return 'Air';
|
|
114
|
+
if (waterSigns.includes(sign))
|
|
115
|
+
return 'Water';
|
|
116
|
+
return '';
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Check if a Grand Trine is part of any Kite pattern within the same analysis context
|
|
120
|
+
* Uses exact planet identity matching (chart name + planet name + degree)
|
|
121
|
+
*/
|
|
122
|
+
function isGrandTrinePartOfKite(grandTrine, patterns) {
|
|
123
|
+
if (grandTrine.type !== 'Grand Trine')
|
|
124
|
+
return false;
|
|
125
|
+
return patterns.some((pattern) => {
|
|
126
|
+
if (pattern.type !== 'Kite')
|
|
127
|
+
return false;
|
|
128
|
+
// Create unique identifiers for exact planet identity matching
|
|
129
|
+
const createPlanetId = (p) => `${p.chartName || ''}-${p.name}-${p.degree}`;
|
|
130
|
+
const kiteGrandTrinePlanets = pattern.grandTrine.map(createPlanetId);
|
|
131
|
+
const grandTrinePlanets = grandTrine.planets.map(createPlanetId);
|
|
132
|
+
// Check if the sets of planets are identical (same planets, same count)
|
|
133
|
+
return (kiteGrandTrinePlanets.length === grandTrinePlanets.length &&
|
|
134
|
+
kiteGrandTrinePlanets.every((kp) => grandTrinePlanets.includes(kp)));
|
|
135
|
+
});
|
|
120
136
|
}
|
|
121
137
|
/**
|
|
122
138
|
* Generates the [ASPECT PATTERNS] section of the chart output.
|
|
123
139
|
* @param patterns Array of detected aspect patterns
|
|
140
|
+
* @param customTitle Optional custom title for the section
|
|
141
|
+
* @param showChartNames Whether to show chart names for planets (false for single charts, true for multi-chart)
|
|
124
142
|
* @returns An array of strings for the output.
|
|
125
143
|
*/
|
|
126
|
-
function generateAspectPatternsOutput(patterns) {
|
|
127
|
-
const output = [
|
|
144
|
+
function generateAspectPatternsOutput(patterns, customTitle, showChartNames = true) {
|
|
145
|
+
const output = [
|
|
146
|
+
customTitle ? `[ASPECT PATTERNS: ${customTitle}]` : '[ASPECT PATTERNS]',
|
|
147
|
+
];
|
|
128
148
|
if (patterns.length === 0) {
|
|
129
|
-
output.push('No
|
|
149
|
+
output.push('No T-Squares detected.');
|
|
150
|
+
output.push('No Grand Trines detected.');
|
|
130
151
|
return output;
|
|
131
152
|
}
|
|
153
|
+
// Filter out Grand Trines that are part of Kites to avoid duplication
|
|
154
|
+
const filteredPatterns = patterns.filter((pattern) => {
|
|
155
|
+
if (pattern.type === 'Grand Trine') {
|
|
156
|
+
return !isGrandTrinePartOfKite(pattern, patterns);
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
});
|
|
132
160
|
// Sort patterns by type for consistent output
|
|
133
161
|
const sortOrder = [
|
|
134
162
|
'T-Square',
|
|
135
163
|
'Grand Trine',
|
|
136
164
|
'Grand Cross',
|
|
137
|
-
'Stellium',
|
|
138
165
|
'Yod',
|
|
139
166
|
'Mystic Rectangle',
|
|
140
167
|
'Kite',
|
|
141
168
|
];
|
|
142
|
-
const sortedPatterns =
|
|
169
|
+
const sortedPatterns = filteredPatterns.sort((a, b) => {
|
|
143
170
|
return sortOrder.indexOf(a.type) - sortOrder.indexOf(b.type);
|
|
144
171
|
});
|
|
145
172
|
sortedPatterns.forEach((pattern) => {
|
|
146
173
|
switch (pattern.type) {
|
|
147
174
|
case 'T-Square':
|
|
148
|
-
output.push(...formatTSquare(pattern));
|
|
175
|
+
output.push(...formatTSquare(pattern, showChartNames));
|
|
149
176
|
break;
|
|
150
177
|
case 'Grand Trine':
|
|
151
|
-
output.push(...formatGrandTrine(pattern));
|
|
152
|
-
break;
|
|
153
|
-
case 'Stellium':
|
|
154
|
-
output.push(...formatStellium(pattern));
|
|
178
|
+
output.push(...formatGrandTrine(pattern, showChartNames));
|
|
155
179
|
break;
|
|
156
180
|
case 'Grand Cross':
|
|
157
|
-
output.push(...formatGrandCross(pattern));
|
|
181
|
+
output.push(...formatGrandCross(pattern, showChartNames));
|
|
158
182
|
break;
|
|
159
183
|
case 'Yod':
|
|
160
|
-
output.push(...formatYod(pattern));
|
|
184
|
+
output.push(...formatYod(pattern, showChartNames));
|
|
161
185
|
break;
|
|
162
186
|
case 'Mystic Rectangle':
|
|
163
|
-
output.push(...formatMysticRectangle(pattern));
|
|
187
|
+
output.push(...formatMysticRectangle(pattern, showChartNames));
|
|
164
188
|
break;
|
|
165
189
|
case 'Kite':
|
|
166
|
-
output.push(...formatKite(pattern));
|
|
190
|
+
output.push(...formatKite(pattern, showChartNames));
|
|
167
191
|
break;
|
|
168
192
|
}
|
|
169
193
|
});
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { AspectData } from '../../../types';
|
|
2
|
-
import { ChartSettings } from '../../../config/ChartSettings';
|
|
3
2
|
/**
|
|
4
|
-
* Generates aspect sections
|
|
3
|
+
* Generates aspect sections from a pre-grouped map of aspects.
|
|
5
4
|
* @param title The main title for this aspect block (e.g., "[ASPECTS]").
|
|
6
|
-
* @param
|
|
7
|
-
* @param settings The chart settings, containing aspect categories.
|
|
5
|
+
* @param groupedAspects A map of category names to aspect data arrays.
|
|
8
6
|
* @param p1ChartName Optional: Name of the first chart/entity for synastry/transit aspects.
|
|
9
7
|
* @param p2ChartName Optional: Name of the second chart/entity for synastry aspects.
|
|
10
8
|
* @param p2IsTransit Optional: Boolean indicating if p2 represents transiting points.
|
|
11
9
|
* @returns An array of strings for the output.
|
|
12
10
|
*/
|
|
13
|
-
export declare function generateAspectsOutput(title: string,
|
|
14
|
-
p2IsTransit?: boolean): string[];
|
|
11
|
+
export declare function generateAspectsOutput(title: string, groupedAspects?: Map<string, AspectData[]>, p1ChartName?: string, p2ChartName?: string, p2IsTransit?: boolean): string[];
|
|
@@ -2,66 +2,49 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateAspectsOutput = generateAspectsOutput;
|
|
4
4
|
/**
|
|
5
|
-
* Generates
|
|
5
|
+
* Generates the output for a single aspect line.
|
|
6
|
+
* @param asp The aspect data.
|
|
7
|
+
* @param p1ChartName Optional name of the first chart.
|
|
8
|
+
* @param p2ChartName Optional name of the second chart.
|
|
9
|
+
* @param p2IsTransit Optional flag if the second chart is for transits.
|
|
10
|
+
* @returns A formatted string for the aspect.
|
|
11
|
+
*/
|
|
12
|
+
function formatAspectLine(asp, p1ChartName, p2ChartName, p2IsTransit = false) {
|
|
13
|
+
const p1NameStr = p1ChartName
|
|
14
|
+
? `${p1ChartName}'s ${asp.planetA}`
|
|
15
|
+
: asp.planetA;
|
|
16
|
+
let p2NameStr = asp.planetB;
|
|
17
|
+
if (p2IsTransit) {
|
|
18
|
+
p2NameStr = `transiting ${asp.planetB}`;
|
|
19
|
+
}
|
|
20
|
+
else if (p2ChartName) {
|
|
21
|
+
p2NameStr = `${p2ChartName}'s ${asp.planetB}`;
|
|
22
|
+
}
|
|
23
|
+
const applicationStr = asp.application && asp.application !== 'exact'
|
|
24
|
+
? ` (${asp.application})`
|
|
25
|
+
: '';
|
|
26
|
+
return `${p1NameStr} ${asp.aspectType} ${p2NameStr}: ${asp.orb.toFixed(1)}°${applicationStr}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Generates aspect sections from a pre-grouped map of aspects.
|
|
6
30
|
* @param title The main title for this aspect block (e.g., "[ASPECTS]").
|
|
7
|
-
* @param
|
|
8
|
-
* @param settings The chart settings, containing aspect categories.
|
|
31
|
+
* @param groupedAspects A map of category names to aspect data arrays.
|
|
9
32
|
* @param p1ChartName Optional: Name of the first chart/entity for synastry/transit aspects.
|
|
10
33
|
* @param p2ChartName Optional: Name of the second chart/entity for synastry aspects.
|
|
11
34
|
* @param p2IsTransit Optional: Boolean indicating if p2 represents transiting points.
|
|
12
35
|
* @returns An array of strings for the output.
|
|
13
36
|
*/
|
|
14
|
-
function generateAspectsOutput(title,
|
|
15
|
-
p2IsTransit = false) {
|
|
37
|
+
function generateAspectsOutput(title, groupedAspects, p1ChartName, p2ChartName, p2IsTransit = false) {
|
|
16
38
|
const output = [title];
|
|
17
|
-
|
|
18
|
-
settings.aspectCategories.forEach((category) => {
|
|
19
|
-
const categoryAspects = aspects.filter((asp) => {
|
|
20
|
-
const orb = asp.orb;
|
|
21
|
-
const minOrbCheck = category.minOrb === undefined ? true : orb > category.minOrb;
|
|
22
|
-
const maxOrbCheck = orb <= category.maxOrb;
|
|
23
|
-
return minOrbCheck && maxOrbCheck;
|
|
24
|
-
});
|
|
25
|
-
if (categoryAspects.length > 0) {
|
|
26
|
-
aspectsFoundInAnyCategory = true;
|
|
27
|
-
let orbRangeStr = `orb under ${category.maxOrb.toFixed(1)}°`;
|
|
28
|
-
if (category.minOrb !== undefined) {
|
|
29
|
-
// Ensure minOrb is less than maxOrb for sensible range string
|
|
30
|
-
orbRangeStr =
|
|
31
|
-
category.minOrb < category.maxOrb
|
|
32
|
-
? `orb ${category.minOrb.toFixed(1)}-${category.maxOrb.toFixed(1)}°`
|
|
33
|
-
: `orb over ${category.minOrb.toFixed(1)}° & under ${category.maxOrb.toFixed(1)}°`; // Fallback for unusual category def
|
|
34
|
-
}
|
|
35
|
-
output.push(`[${category.name}: ${orbRangeStr}]`);
|
|
36
|
-
categoryAspects.sort((a, b) => a.orb - b.orb); // Sort by orb tightness
|
|
37
|
-
categoryAspects.forEach((asp) => {
|
|
38
|
-
const p1NameStr = p1ChartName
|
|
39
|
-
? `${p1ChartName}'s ${asp.planetA}`
|
|
40
|
-
: asp.planetA;
|
|
41
|
-
let p2NameStr = asp.planetB;
|
|
42
|
-
if (p2IsTransit) {
|
|
43
|
-
// For "Transit Aspects: Alice", p1 is Alice, p2 is the transiting planet.
|
|
44
|
-
// Example: "Alice's Mercury opposition transiting Neptune: 0.3°" - here p2ChartName is not used for the planet itself.
|
|
45
|
-
p2NameStr = `transiting ${asp.planetB}`;
|
|
46
|
-
}
|
|
47
|
-
else if (p2ChartName) {
|
|
48
|
-
// For "Synastry: Alice-Bob", "Planet-Planet Aspects"
|
|
49
|
-
// Example: "Alice's Mercury opposition Bob's Neptune: 0.3°"
|
|
50
|
-
p2NameStr = `${p2ChartName}'s ${asp.planetB}`;
|
|
51
|
-
}
|
|
52
|
-
// If neither p2IsTransit nor p2ChartName, it's a natal chart aspect, e.g. "Venus opposition Pluto: 1.2°"
|
|
53
|
-
const applicationStr = asp.application && asp.application !== 'exact'
|
|
54
|
-
? ` (${asp.application})`
|
|
55
|
-
: '';
|
|
56
|
-
output.push(`${p1NameStr} ${asp.aspectType} ${p2NameStr}: ${asp.orb.toFixed(1)}°${applicationStr}`);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
if (!aspectsFoundInAnyCategory && aspects.length > 0) {
|
|
61
|
-
output.push('No aspects within defined categories.');
|
|
62
|
-
}
|
|
63
|
-
else if (aspects.length === 0) {
|
|
39
|
+
if (!groupedAspects || groupedAspects.size === 0) {
|
|
64
40
|
output.push('None');
|
|
41
|
+
return output;
|
|
65
42
|
}
|
|
43
|
+
groupedAspects.forEach((categoryAspects, categoryName) => {
|
|
44
|
+
output.push(categoryName); // The category name is the pre-formatted key from the map
|
|
45
|
+
categoryAspects.forEach((asp) => {
|
|
46
|
+
output.push(formatAspectLine(asp, p1ChartName, p2ChartName, p2IsTransit));
|
|
47
|
+
});
|
|
48
|
+
});
|
|
66
49
|
return output;
|
|
67
50
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Point } from '../../../types';
|
|
2
1
|
/**
|
|
3
2
|
* Generates the [DISPOSITOR TREE] section of the chart output.
|
|
4
|
-
* @param
|
|
3
|
+
* @param dispositors A map of planet names to their full dispositor chain string.
|
|
5
4
|
* @returns An array of strings for the output.
|
|
6
5
|
*/
|
|
7
|
-
export declare function generateDispositorsOutput(
|
|
6
|
+
export declare function generateDispositorsOutput(dispositors: {
|
|
7
|
+
[key: string]: string;
|
|
8
|
+
}): string[];
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateDispositorsOutput = generateDispositorsOutput;
|
|
4
|
-
const dispositors_1 = require("../../../core/dispositors");
|
|
5
4
|
/**
|
|
6
5
|
* Generates the [DISPOSITOR TREE] section of the chart output.
|
|
7
|
-
* @param
|
|
6
|
+
* @param dispositors A map of planet names to their full dispositor chain string.
|
|
8
7
|
* @returns An array of strings for the output.
|
|
9
8
|
*/
|
|
10
|
-
function generateDispositorsOutput(
|
|
9
|
+
function generateDispositorsOutput(dispositors) {
|
|
11
10
|
const output = ['[DISPOSITOR TREE]'];
|
|
12
|
-
if (
|
|
13
|
-
output.push('No
|
|
11
|
+
if (Object.keys(dispositors).length === 0) {
|
|
12
|
+
output.push('No dispositor data available.');
|
|
14
13
|
return output;
|
|
15
14
|
}
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
for (const planet in dispositors) {
|
|
16
|
+
output.push(dispositors[planet]);
|
|
17
|
+
}
|
|
19
18
|
return output;
|
|
20
19
|
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { ChartData } from '../../../types';
|
|
2
|
-
import { ChartSettings } from '../../../config/ChartSettings';
|
|
3
1
|
/**
|
|
4
2
|
* Generates the [HOUSE OVERLAYS] section for synastry.
|
|
5
|
-
* @param
|
|
6
|
-
* @param
|
|
7
|
-
* @param
|
|
3
|
+
* @param overlays The pre-calculated house overlay data.
|
|
4
|
+
* @param chart1Name The name of the first chart.
|
|
5
|
+
* @param chart2Name The name of the second chart.
|
|
8
6
|
* @returns An array of strings for the output.
|
|
9
7
|
*/
|
|
10
|
-
export declare function generateHouseOverlaysOutput(
|
|
8
|
+
export declare function generateHouseOverlaysOutput(overlays: {
|
|
9
|
+
chart1InChart2Houses: {
|
|
10
|
+
[key: string]: number;
|
|
11
|
+
};
|
|
12
|
+
chart2InChart1Houses: {
|
|
13
|
+
[key: string]: number;
|
|
14
|
+
};
|
|
15
|
+
}, chart1Name: string, chart2Name: string): string[];
|
|
@@ -2,60 +2,53 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateHouseOverlaysOutput = generateHouseOverlaysOutput;
|
|
4
4
|
const formatting_1 = require("../../../utils/formatting");
|
|
5
|
-
const houseCalculations_1 = require("../../../utils/houseCalculations");
|
|
6
5
|
/**
|
|
7
6
|
* Generates the [HOUSE OVERLAYS] section for synastry.
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
10
|
-
* @param
|
|
7
|
+
* @param overlays The pre-calculated house overlay data.
|
|
8
|
+
* @param chart1Name The name of the first chart.
|
|
9
|
+
* @param chart2Name The name of the second chart.
|
|
11
10
|
* @returns An array of strings for the output.
|
|
12
11
|
*/
|
|
13
|
-
function generateHouseOverlaysOutput(
|
|
12
|
+
function generateHouseOverlaysOutput(overlays, chart1Name, chart2Name) {
|
|
14
13
|
const output = ['[HOUSE OVERLAYS]'];
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (chart2.houseCusps && chart2.houseCusps.length === 12) {
|
|
19
|
-
output.push(`${c1Name}'s planets in ${c2Name}'s houses:`);
|
|
20
|
-
if (chart1.planets && chart1.planets.length > 0) {
|
|
21
|
-
chart1.planets.forEach((planet) => {
|
|
22
|
-
const houseNumber = (0, houseCalculations_1.getHouseForPoint)(planet.degree, chart2.houseCusps);
|
|
23
|
-
if (houseNumber) {
|
|
24
|
-
output.push(`- ${planet.name}: ${(0, formatting_1.getOrdinal)(houseNumber)}`);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
output.push(`- ${planet.name}: (Could not determine house in ${c2Name})`);
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
output.push('(No planets listed for overlay)');
|
|
33
|
-
}
|
|
14
|
+
output.push(`${chart1Name}'s planets in ${chart2Name}'s houses:`);
|
|
15
|
+
if (Object.keys(overlays.chart1InChart2Houses).length > 0) {
|
|
16
|
+
output.push(formatHouseOverlayCompact(overlays.chart1InChart2Houses));
|
|
34
17
|
}
|
|
35
18
|
else {
|
|
36
|
-
output.push(
|
|
19
|
+
output.push(`(${chart2Name} house cusps not available)`);
|
|
37
20
|
}
|
|
38
|
-
output.push('
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
output.push(`${c2Name}'s planets in ${c1Name}'s houses:`);
|
|
42
|
-
if (chart2.planets && chart2.planets.length > 0) {
|
|
43
|
-
chart2.planets.forEach((planet) => {
|
|
44
|
-
const houseNumber = (0, houseCalculations_1.getHouseForPoint)(planet.degree, chart1.houseCusps);
|
|
45
|
-
if (houseNumber) {
|
|
46
|
-
output.push(`- ${planet.name}: ${(0, formatting_1.getOrdinal)(houseNumber)}`);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
output.push(`- ${planet.name}: (Could not determine house in ${c1Name})`);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
output.push('(No planets listed for overlay)');
|
|
55
|
-
}
|
|
21
|
+
output.push(`${chart2Name}'s planets in ${chart1Name}'s houses:`);
|
|
22
|
+
if (Object.keys(overlays.chart2InChart1Houses).length > 0) {
|
|
23
|
+
output.push(formatHouseOverlayCompact(overlays.chart2InChart1Houses));
|
|
56
24
|
}
|
|
57
25
|
else {
|
|
58
|
-
output.push(
|
|
26
|
+
output.push(`(${chart1Name} house cusps not available)`);
|
|
59
27
|
}
|
|
60
28
|
return output;
|
|
61
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Formats house overlays in a compact format, grouping by house.
|
|
32
|
+
* @param overlays Object mapping planet names to house numbers.
|
|
33
|
+
* @returns A compact string representation.
|
|
34
|
+
*/
|
|
35
|
+
function formatHouseOverlayCompact(overlays) {
|
|
36
|
+
// Group planets by house
|
|
37
|
+
const houseGroups = {};
|
|
38
|
+
for (const planet in overlays) {
|
|
39
|
+
const house = overlays[planet];
|
|
40
|
+
if (!houseGroups[house]) {
|
|
41
|
+
houseGroups[house] = [];
|
|
42
|
+
}
|
|
43
|
+
houseGroups[house].push(planet);
|
|
44
|
+
}
|
|
45
|
+
// Sort houses numerically and format
|
|
46
|
+
const sortedHouses = Object.keys(houseGroups)
|
|
47
|
+
.map(Number)
|
|
48
|
+
.sort((a, b) => a - b);
|
|
49
|
+
const houseStrings = sortedHouses.map((house) => {
|
|
50
|
+
const planets = houseGroups[house].join(', ');
|
|
51
|
+
return `${(0, formatting_1.getOrdinal)(house)}: ${planets}`;
|
|
52
|
+
});
|
|
53
|
+
return houseStrings.join(' | ');
|
|
54
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { ChartSettings } from '../../../config/ChartSettings';
|
|
2
|
+
import { MultiChartData } from '../../../types';
|
|
3
|
+
export declare function determineChartType(data: MultiChartData): string;
|
|
2
4
|
/**
|
|
3
5
|
* Generates the [METADATA] section of the chart output.
|
|
4
6
|
* @param settings The chart settings.
|
|
@@ -1,6 +1,60 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.determineChartType = determineChartType;
|
|
3
4
|
exports.generateMetadataOutput = generateMetadataOutput;
|
|
5
|
+
function determineChartType(data) {
|
|
6
|
+
let baseChartString = 'natal';
|
|
7
|
+
let suffixString = '';
|
|
8
|
+
const natalCharts = data.filter(({ chartType }) => chartType !== 'transit' && chartType !== 'event');
|
|
9
|
+
const eventCharts = data.filter(({ chartType }) => chartType === 'event');
|
|
10
|
+
const transitCharts = data.filter(({ chartType }) => chartType === 'transit');
|
|
11
|
+
if (transitCharts.length > 1) {
|
|
12
|
+
throw new Error('Must provide at most one transit chart');
|
|
13
|
+
}
|
|
14
|
+
const hasTransit = transitCharts.length > 0;
|
|
15
|
+
// first determine suffix
|
|
16
|
+
if (natalCharts.length > 0) {
|
|
17
|
+
if (eventCharts.length === 0) {
|
|
18
|
+
if (hasTransit) {
|
|
19
|
+
suffixString = '_with_transit';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else if (eventCharts.length === 1) {
|
|
23
|
+
suffixString = hasTransit ? '_with_event_and_transit' : '_with_event';
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
suffixString = hasTransit ? '_with_events_and_transit' : '_with_events';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// base event charts can have transits
|
|
31
|
+
if (hasTransit) {
|
|
32
|
+
suffixString = '_with_transit';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// then determine base string
|
|
36
|
+
if (natalCharts.length === 0) {
|
|
37
|
+
if (eventCharts.length === 0) {
|
|
38
|
+
throw new Error('Must provide at least one non-transit chart');
|
|
39
|
+
}
|
|
40
|
+
else if (eventCharts.length === 1) {
|
|
41
|
+
baseChartString = 'event';
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
baseChartString = 'multi_event';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (natalCharts.length === 1) {
|
|
48
|
+
baseChartString = 'natal';
|
|
49
|
+
}
|
|
50
|
+
else if (natalCharts.length === 2) {
|
|
51
|
+
baseChartString = 'synastry';
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
baseChartString = 'group_synastry';
|
|
55
|
+
}
|
|
56
|
+
return baseChartString + suffixString;
|
|
57
|
+
}
|
|
4
58
|
/**
|
|
5
59
|
* Generates the [METADATA] section of the chart output.
|
|
6
60
|
* @param settings The chart settings.
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ChartSettings } from '../../../config/ChartSettings';
|
|
1
|
+
import { PlanetPosition } from '../../../types';
|
|
3
2
|
/**
|
|
4
3
|
* Generates the [PLANETS] section of the chart output.
|
|
5
|
-
* @param
|
|
6
|
-
* @param houseCusps Array of 12 house cusp degrees, or undefined if not available.
|
|
4
|
+
* @param placements Array of planet positions.
|
|
7
5
|
* @param settings The chart settings.
|
|
8
6
|
* @returns An array of strings for the output.
|
|
9
7
|
*/
|
|
10
|
-
export declare function generatePlanetsOutput(
|
|
8
|
+
export declare function generatePlanetsOutput(placements: PlanetPosition[]): string[];
|