chart2txt 0.5.2 → 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.
Files changed (59) hide show
  1. package/README.md +101 -34
  2. package/dist/chart2txt.d.ts +9 -0
  3. package/dist/chart2txt.js +30 -0
  4. package/dist/chart2txt.min.js +1 -1
  5. package/dist/config/ChartSettings.d.ts +13 -6
  6. package/dist/config/ChartSettings.js +36 -10
  7. package/dist/constants.d.ts +17 -2
  8. package/dist/constants.js +301 -32
  9. package/dist/core/analysis.d.ts +6 -0
  10. package/dist/core/analysis.js +235 -0
  11. package/dist/core/aspectPatterns.d.ts +10 -0
  12. package/dist/core/aspectPatterns.js +460 -0
  13. package/dist/core/aspects.d.ts +14 -11
  14. package/dist/core/aspects.js +142 -40
  15. package/dist/core/astrology.d.ts +8 -2
  16. package/dist/core/astrology.js +23 -6
  17. package/dist/core/dignities.d.ts +2 -0
  18. package/dist/core/dignities.js +71 -0
  19. package/dist/core/dispositors.d.ts +9 -0
  20. package/dist/core/dispositors.js +57 -0
  21. package/dist/core/grouping.d.ts +9 -0
  22. package/dist/core/grouping.js +45 -0
  23. package/dist/core/signDistributions.d.ts +21 -0
  24. package/dist/core/signDistributions.js +50 -0
  25. package/dist/core/stelliums.d.ts +10 -0
  26. package/dist/core/stelliums.js +108 -0
  27. package/dist/formatters/text/sections/angles.js +4 -4
  28. package/dist/formatters/text/sections/aspectPatterns.d.ts +9 -0
  29. package/dist/formatters/text/sections/aspectPatterns.js +199 -0
  30. package/dist/formatters/text/sections/aspects.d.ts +3 -6
  31. package/dist/formatters/text/sections/aspects.js +35 -49
  32. package/dist/formatters/text/sections/birthdata.js +1 -1
  33. package/dist/formatters/text/sections/dispositors.d.ts +8 -0
  34. package/dist/formatters/text/sections/dispositors.js +19 -0
  35. package/dist/formatters/text/sections/houseOverlays.d.ts +11 -6
  36. package/dist/formatters/text/sections/houseOverlays.js +38 -69
  37. package/dist/formatters/text/sections/houses.d.ts +6 -0
  38. package/dist/formatters/text/sections/houses.js +36 -0
  39. package/dist/formatters/text/sections/metadata.d.ts +2 -0
  40. package/dist/formatters/text/sections/metadata.js +54 -0
  41. package/dist/formatters/text/sections/planets.d.ts +3 -5
  42. package/dist/formatters/text/sections/planets.js +12 -38
  43. package/dist/formatters/text/sections/signDistributions.d.ts +9 -0
  44. package/dist/formatters/text/sections/signDistributions.js +21 -0
  45. package/dist/formatters/text/textFormatter.d.ts +4 -5
  46. package/dist/formatters/text/textFormatter.js +86 -112
  47. package/dist/index.d.ts +7 -4
  48. package/dist/index.js +11 -6
  49. package/dist/types.d.ts +159 -13
  50. package/dist/types.js +15 -0
  51. package/dist/utils/formatting.d.ts +10 -0
  52. package/dist/utils/formatting.js +56 -0
  53. package/dist/utils/houseCalculations.d.ts +10 -0
  54. package/dist/utils/houseCalculations.js +23 -0
  55. package/dist/utils/precision.d.ts +49 -0
  56. package/dist/utils/precision.js +71 -0
  57. package/dist/utils/validation.d.ts +37 -0
  58. package/dist/utils/validation.js +181 -0
  59. package/package.json +2 -1
@@ -0,0 +1,460 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectAspectPatterns = detectAspectPatterns;
4
+ const astrology_1 = require("./astrology");
5
+ /**
6
+ * Create a consistent key for planet+chart combinations
7
+ */
8
+ function createPlanetKey(planetName, chartName) {
9
+ return chartName ? `${planetName}-${chartName}` : planetName;
10
+ }
11
+ /**
12
+ * Create a lookup map for aspect relationships between planets
13
+ */
14
+ function createAspectLookup(aspects) {
15
+ const lookup = new Map();
16
+ aspects.forEach((aspect) => {
17
+ const keyA = createPlanetKey(aspect.planetA, aspect.p1ChartName);
18
+ const keyB = createPlanetKey(aspect.planetB, aspect.p2ChartName);
19
+ if (!lookup.has(keyA)) {
20
+ lookup.set(keyA, new Map());
21
+ }
22
+ if (!lookup.has(keyB)) {
23
+ lookup.set(keyB, new Map());
24
+ }
25
+ lookup.get(keyA).set(keyB, aspect);
26
+ lookup.get(keyB).set(keyA, aspect);
27
+ });
28
+ return lookup;
29
+ }
30
+ /**
31
+ * Convert Point to PlanetPosition for aspect patterns
32
+ * Note: House information is optional for aspect patterns (except stelliums which are handled separately)
33
+ */
34
+ function pointToPlanetPosition(point, houseCusps, chartName) {
35
+ const sign = (0, astrology_1.getDegreeSign)(point.degree);
36
+ // For multi-chart patterns, house information may not be meaningful
37
+ // Only calculate house if houseCusps are provided and we're dealing with a single-chart context
38
+ const house = houseCusps && houseCusps.length === 12
39
+ ? (() => {
40
+ // Simple house calculation without importing the utility
41
+ const normalizedDegree = point.degree % 360;
42
+ for (let i = 0; i < 12; i++) {
43
+ const currentCusp = houseCusps[i];
44
+ const nextCusp = houseCusps[(i + 1) % 12];
45
+ if (nextCusp > currentCusp) {
46
+ // Normal case: house doesn't cross 0°
47
+ if (normalizedDegree >= currentCusp &&
48
+ normalizedDegree < nextCusp) {
49
+ return i + 1;
50
+ }
51
+ }
52
+ else {
53
+ // House crosses 0° (e.g., 350° to 20°)
54
+ if (normalizedDegree >= currentCusp ||
55
+ normalizedDegree < nextCusp) {
56
+ return i + 1;
57
+ }
58
+ }
59
+ }
60
+ return undefined;
61
+ })()
62
+ : undefined;
63
+ return {
64
+ name: point.name,
65
+ degree: point.degree,
66
+ sign,
67
+ house,
68
+ chartName,
69
+ };
70
+ }
71
+ /**
72
+ * Determine the modality (Cardinal, Fixed, Mutable) of a sign
73
+ */
74
+ function getSignModality(sign) {
75
+ const cardinal = ['Aries', 'Cancer', 'Libra', 'Capricorn'];
76
+ const fixed = ['Taurus', 'Leo', 'Scorpio', 'Aquarius'];
77
+ if (cardinal.includes(sign))
78
+ return 'Cardinal';
79
+ if (fixed.includes(sign))
80
+ return 'Fixed';
81
+ return 'Mutable';
82
+ }
83
+ /**
84
+ * Determine the element (Fire, Earth, Air, Water) of a sign
85
+ */
86
+ function getSignElement(sign) {
87
+ const fire = ['Aries', 'Leo', 'Sagittarius'];
88
+ const earth = ['Taurus', 'Virgo', 'Capricorn'];
89
+ const air = ['Gemini', 'Libra', 'Aquarius'];
90
+ if (fire.includes(sign))
91
+ return 'Fire';
92
+ if (earth.includes(sign))
93
+ return 'Earth';
94
+ if (air.includes(sign))
95
+ return 'Air';
96
+ return 'Water';
97
+ }
98
+ /**
99
+ * Check if two planets have a specific aspect type using the pre-calculated aspects
100
+ */
101
+ function hasSpecificAspect(p1, p2, aspectType, aspectLookup) {
102
+ const key1 = createPlanetKey(p1[0].name, p1[1]);
103
+ const key2 = createPlanetKey(p2[0].name, p2[1]);
104
+ const planet1Aspects = aspectLookup.get(key1);
105
+ if (!planet1Aspects)
106
+ return false;
107
+ const aspectData = planet1Aspects.get(key2);
108
+ return aspectData !== undefined && aspectData.aspectType === aspectType;
109
+ }
110
+ /**
111
+ * Get aspect data between two planets if it exists
112
+ */
113
+ function getAspectBetween(p1, p2, aspectLookup) {
114
+ const key1 = createPlanetKey(p1[0].name, p1[1]);
115
+ const key2 = createPlanetKey(p2[0].name, p2[1]);
116
+ const planet1Aspects = aspectLookup.get(key1);
117
+ if (!planet1Aspects)
118
+ return undefined;
119
+ return planet1Aspects.get(key2);
120
+ }
121
+ /**
122
+ * Detect T-Square patterns
123
+ */
124
+ function detectTSquares(unionedPoints, aspectLookup, houseCusps) {
125
+ const patterns = [];
126
+ for (let i = 0; i < unionedPoints.length; i++) {
127
+ for (let j = i + 1; j < unionedPoints.length; j++) {
128
+ // Check for opposition
129
+ if (hasSpecificAspect(unionedPoints[i], unionedPoints[j], 'opposition', aspectLookup)) {
130
+ // Look for a third planet that squares both
131
+ for (let k = 0; k < unionedPoints.length; k++) {
132
+ if (k === i || k === j)
133
+ continue;
134
+ if (hasSpecificAspect(unionedPoints[i], unionedPoints[k], 'square', aspectLookup) &&
135
+ hasSpecificAspect(unionedPoints[j], unionedPoints[k], 'square', aspectLookup)) {
136
+ const [pApex, cApex] = unionedPoints[k];
137
+ const [pOpp1, cOpp1] = unionedPoints[i];
138
+ const [pOpp2, cOpp2] = unionedPoints[j];
139
+ const apex = pointToPlanetPosition(pApex, houseCusps, cApex);
140
+ const opp1 = pointToPlanetPosition(pOpp1, houseCusps, cOpp1);
141
+ const opp2 = pointToPlanetPosition(pOpp2, houseCusps, cOpp2);
142
+ // Get actual orbs from pre-calculated aspects
143
+ const oppAspect = getAspectBetween(unionedPoints[i], unionedPoints[j], aspectLookup);
144
+ const square1Aspect = getAspectBetween(unionedPoints[i], unionedPoints[k], aspectLookup);
145
+ const square2Aspect = getAspectBetween(unionedPoints[j], unionedPoints[k], aspectLookup);
146
+ const averageOrb = (oppAspect.orb + square1Aspect.orb + square2Aspect.orb) / 3;
147
+ // Determine modality from apex planet
148
+ const mode = getSignModality(apex.sign);
149
+ patterns.push({
150
+ type: 'T-Square',
151
+ apex,
152
+ opposition: [opp1, opp2],
153
+ mode,
154
+ averageOrb,
155
+ });
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+ return patterns;
162
+ }
163
+ /**
164
+ * Detect Grand Trine patterns
165
+ */
166
+ function detectGrandTrines(unionedPoints, aspectLookup, houseCusps) {
167
+ const patterns = [];
168
+ for (let i = 0; i < unionedPoints.length; i++) {
169
+ for (let j = i + 1; j < unionedPoints.length; j++) {
170
+ for (let k = j + 1; k < unionedPoints.length; k++) {
171
+ // Check if all three planets form trines with each other
172
+ if (hasSpecificAspect(unionedPoints[i], unionedPoints[j], 'trine', aspectLookup) &&
173
+ hasSpecificAspect(unionedPoints[j], unionedPoints[k], 'trine', aspectLookup) &&
174
+ hasSpecificAspect(unionedPoints[k], unionedPoints[i], 'trine', aspectLookup)) {
175
+ const [p1, c1] = unionedPoints[i];
176
+ const [p2, c2] = unionedPoints[j];
177
+ const [p3, c3] = unionedPoints[k];
178
+ const planet1 = pointToPlanetPosition(p1, houseCusps, c1);
179
+ const planet2 = pointToPlanetPosition(p2, houseCusps, c2);
180
+ const planet3 = pointToPlanetPosition(p3, houseCusps, c3);
181
+ // Get actual orbs from pre-calculated aspects
182
+ const trine1Aspect = getAspectBetween(unionedPoints[i], unionedPoints[j], aspectLookup);
183
+ const trine2Aspect = getAspectBetween(unionedPoints[j], unionedPoints[k], aspectLookup);
184
+ const trine3Aspect = getAspectBetween(unionedPoints[k], unionedPoints[i], aspectLookup);
185
+ const averageOrb = (trine1Aspect.orb + trine2Aspect.orb + trine3Aspect.orb) / 3;
186
+ // Determine element from the planets (should be same element for proper grand trine)
187
+ const element = getSignElement(planet1.sign);
188
+ patterns.push({
189
+ type: 'Grand Trine',
190
+ planets: [planet1, planet2, planet3],
191
+ element,
192
+ averageOrb,
193
+ });
194
+ }
195
+ }
196
+ }
197
+ }
198
+ return patterns;
199
+ }
200
+ /**
201
+ * Detect Grand Cross patterns
202
+ */
203
+ function detectGrandCrosses(unionedPoints, aspectLookup, houseCusps) {
204
+ const patterns = [];
205
+ for (let i = 0; i < unionedPoints.length; i++) {
206
+ for (let j = i + 1; j < unionedPoints.length; j++) {
207
+ for (let k = j + 1; k < unionedPoints.length; k++) {
208
+ for (let l = k + 1; l < unionedPoints.length; l++) {
209
+ const group = [
210
+ unionedPoints[i],
211
+ unionedPoints[j],
212
+ unionedPoints[k],
213
+ unionedPoints[l],
214
+ ];
215
+ // Check if planets form two oppositions and four squares
216
+ const pairs = [
217
+ [0, 1],
218
+ [2, 3],
219
+ ];
220
+ const otherPairs = [
221
+ [0, 2],
222
+ [1, 3],
223
+ [0, 3],
224
+ [1, 2],
225
+ ];
226
+ // Check for two oppositions
227
+ let oppositions = 0;
228
+ let squares = 0;
229
+ const aspectData = [];
230
+ pairs.forEach(([a, b]) => {
231
+ if (hasSpecificAspect(group[a], group[b], 'opposition', aspectLookup)) {
232
+ oppositions++;
233
+ aspectData.push(getAspectBetween(group[a], group[b], aspectLookup));
234
+ }
235
+ });
236
+ otherPairs.forEach(([a, b]) => {
237
+ if (hasSpecificAspect(group[a], group[b], 'square', aspectLookup)) {
238
+ squares++;
239
+ aspectData.push(getAspectBetween(group[a], group[b], aspectLookup));
240
+ }
241
+ });
242
+ if (oppositions === 2 && squares === 4) {
243
+ const [p1, c1] = group[0];
244
+ const [p2, c2] = group[1];
245
+ const [p3, c3] = group[2];
246
+ const [p4, c4] = group[3];
247
+ const planet1 = pointToPlanetPosition(p1, houseCusps, c1);
248
+ const planet2 = pointToPlanetPosition(p2, houseCusps, c2);
249
+ const planet3 = pointToPlanetPosition(p3, houseCusps, c3);
250
+ const planet4 = pointToPlanetPosition(p4, houseCusps, c4);
251
+ // Calculate average orb from actual aspect data
252
+ const totalOrb = aspectData.reduce((sum, aspect) => sum + aspect.orb, 0);
253
+ const averageOrb = totalOrb / aspectData.length;
254
+ const mode = getSignModality(planet1.sign); // Determine from first planet
255
+ patterns.push({
256
+ type: 'Grand Cross',
257
+ planets: [planet1, planet2, planet3, planet4],
258
+ mode,
259
+ averageOrb,
260
+ });
261
+ }
262
+ }
263
+ }
264
+ }
265
+ }
266
+ return patterns;
267
+ }
268
+ /**
269
+ * Detect Yod patterns (two quincunxes to apex planet and one sextile between base planets)
270
+ */
271
+ function detectYods(unionedPoints, aspectLookup, houseCusps) {
272
+ const patterns = [];
273
+ for (let i = 0; i < unionedPoints.length; i++) {
274
+ for (let j = i + 1; j < unionedPoints.length; j++) {
275
+ // Check for sextile between base planets
276
+ if (hasSpecificAspect(unionedPoints[i], unionedPoints[j], 'sextile', aspectLookup)) {
277
+ // Look for apex planet that forms quincunxes with both
278
+ for (let k = 0; k < unionedPoints.length; k++) {
279
+ if (k === i || k === j)
280
+ continue;
281
+ if (hasSpecificAspect(unionedPoints[i], unionedPoints[k], 'quincunx', aspectLookup) &&
282
+ hasSpecificAspect(unionedPoints[j], unionedPoints[k], 'quincunx', aspectLookup)) {
283
+ const [pApex, cApex] = unionedPoints[k];
284
+ const [pBase1, cBase1] = unionedPoints[i];
285
+ const [pBase2, cBase2] = unionedPoints[j];
286
+ const apex = pointToPlanetPosition(pApex, houseCusps, cApex);
287
+ const base1 = pointToPlanetPosition(pBase1, houseCusps, cBase1);
288
+ const base2 = pointToPlanetPosition(pBase2, houseCusps, cBase2);
289
+ // Get actual orbs from pre-calculated aspects
290
+ const sextileAspect = getAspectBetween(unionedPoints[i], unionedPoints[j], aspectLookup);
291
+ const quincunx1Aspect = getAspectBetween(unionedPoints[i], unionedPoints[k], aspectLookup);
292
+ const quincunx2Aspect = getAspectBetween(unionedPoints[j], unionedPoints[k], aspectLookup);
293
+ const averageOrb = (sextileAspect.orb + quincunx1Aspect.orb + quincunx2Aspect.orb) /
294
+ 3;
295
+ patterns.push({
296
+ type: 'Yod',
297
+ apex,
298
+ base: [base1, base2],
299
+ averageOrb,
300
+ });
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }
306
+ return patterns;
307
+ }
308
+ /**
309
+ * Detect Mystic Rectangle patterns (two oppositions with sextiles and trines)
310
+ */
311
+ function detectMysticRectangles(unionedPoints, aspectLookup, houseCusps) {
312
+ const patterns = [];
313
+ for (let i = 0; i < unionedPoints.length; i++) {
314
+ for (let j = i + 1; j < unionedPoints.length; j++) {
315
+ for (let k = j + 1; k < unionedPoints.length; k++) {
316
+ for (let l = k + 1; l < unionedPoints.length; l++) {
317
+ const group = [
318
+ unionedPoints[i],
319
+ unionedPoints[j],
320
+ unionedPoints[k],
321
+ unionedPoints[l],
322
+ ];
323
+ // Check for two oppositions and appropriate sextiles/trines
324
+ const combinations = [
325
+ {
326
+ oppositions: [
327
+ [0, 1],
328
+ [2, 3],
329
+ ],
330
+ sextiles: [
331
+ [0, 2],
332
+ [0, 3],
333
+ [1, 2],
334
+ [1, 3],
335
+ ],
336
+ },
337
+ {
338
+ oppositions: [
339
+ [0, 2],
340
+ [1, 3],
341
+ ],
342
+ sextiles: [
343
+ [0, 1],
344
+ [0, 3],
345
+ [2, 1],
346
+ [2, 3],
347
+ ],
348
+ },
349
+ {
350
+ oppositions: [
351
+ [0, 3],
352
+ [1, 2],
353
+ ],
354
+ sextiles: [
355
+ [0, 1],
356
+ [0, 2],
357
+ [3, 1],
358
+ [3, 2],
359
+ ],
360
+ },
361
+ ];
362
+ for (const combo of combinations) {
363
+ let validOppositions = 0;
364
+ let validSextiles = 0;
365
+ const aspectData = [];
366
+ combo.oppositions.forEach(([a, b]) => {
367
+ if (hasSpecificAspect(group[a], group[b], 'opposition', aspectLookup)) {
368
+ validOppositions++;
369
+ aspectData.push(getAspectBetween(group[a], group[b], aspectLookup));
370
+ }
371
+ });
372
+ combo.sextiles.forEach(([a, b]) => {
373
+ const sextileAspect = getAspectBetween(group[a], group[b], aspectLookup);
374
+ if (sextileAspect &&
375
+ (sextileAspect.aspectType === 'sextile' ||
376
+ sextileAspect.aspectType === 'trine')) {
377
+ validSextiles++;
378
+ aspectData.push(sextileAspect);
379
+ }
380
+ });
381
+ if (validOppositions === 2 && validSextiles === 4) {
382
+ const [p1, c1] = group[combo.oppositions[0][0]];
383
+ const [p2, c2] = group[combo.oppositions[0][1]];
384
+ const [p3, c3] = group[combo.oppositions[1][0]];
385
+ const [p4, c4] = group[combo.oppositions[1][1]];
386
+ const pos1 = pointToPlanetPosition(p1, houseCusps, c1);
387
+ const pos2 = pointToPlanetPosition(p2, houseCusps, c2);
388
+ const pos3 = pointToPlanetPosition(p3, houseCusps, c3);
389
+ const pos4 = pointToPlanetPosition(p4, houseCusps, c4);
390
+ // Calculate average orb from actual aspect data
391
+ const totalOrb = aspectData.reduce((sum, aspect) => sum + aspect.orb, 0);
392
+ const averageOrb = totalOrb / aspectData.length;
393
+ patterns.push({
394
+ type: 'Mystic Rectangle',
395
+ oppositions: [
396
+ [pos1, pos2],
397
+ [pos3, pos4],
398
+ ],
399
+ averageOrb,
400
+ });
401
+ }
402
+ }
403
+ }
404
+ }
405
+ }
406
+ }
407
+ return patterns;
408
+ }
409
+ /**
410
+ * Detect Kite patterns (Grand Trine with one opposition)
411
+ */
412
+ function detectKites(unionedPoints, aspectLookup, houseCusps) {
413
+ const patterns = [];
414
+ const grandTrines = detectGrandTrines(unionedPoints, aspectLookup, houseCusps);
415
+ grandTrines.forEach((grandTrine) => {
416
+ // For each planet in the grand trine, look for opposition to another planet
417
+ grandTrine.planets.forEach((trinePoint) => {
418
+ unionedPoints.forEach((unionedPoint) => {
419
+ const [planet, chartName] = unionedPoint;
420
+ const isPartOfTrine = grandTrine.planets.some((tp) => tp.name === planet.name && tp.chartName === chartName);
421
+ if (!isPartOfTrine) {
422
+ // Find the original UnionedPoint for this trine point
423
+ const trineUnionedPoint = unionedPoints.find(([p, c]) => p.name === trinePoint.name && c === trinePoint.chartName);
424
+ if (trineUnionedPoint &&
425
+ hasSpecificAspect(trineUnionedPoint, unionedPoint, 'opposition', aspectLookup)) {
426
+ const oppositionPlanet = pointToPlanetPosition(planet, houseCusps, chartName);
427
+ const oppositionAspect = getAspectBetween(trineUnionedPoint, unionedPoint, aspectLookup);
428
+ const averageOrb = (grandTrine.averageOrb + oppositionAspect.orb) / 2;
429
+ patterns.push({
430
+ type: 'Kite',
431
+ grandTrine: grandTrine.planets,
432
+ opposition: oppositionPlanet,
433
+ averageOrb,
434
+ });
435
+ }
436
+ }
437
+ });
438
+ });
439
+ });
440
+ return patterns;
441
+ }
442
+ /**
443
+ * Main function to detect aspect patterns (excluding stelliums which are handled separately)
444
+ * This function works with both single-chart and multi-chart scenarios
445
+ * @param planets Array of planets to analyze
446
+ * @param aspects Pre-calculated aspects between planets
447
+ * @param houseCusps Optional house cusps for single-chart reference
448
+ * @param planetChartMap Optional mapping from planet name to chart name for multichart ownership context
449
+ */
450
+ function detectAspectPatterns(unionedPoints, aspects, houseCusps) {
451
+ const patterns = [];
452
+ const aspectLookup = createAspectLookup(aspects);
453
+ patterns.push(...detectTSquares(unionedPoints, aspectLookup, houseCusps));
454
+ patterns.push(...detectGrandTrines(unionedPoints, aspectLookup, houseCusps));
455
+ patterns.push(...detectGrandCrosses(unionedPoints, aspectLookup, houseCusps));
456
+ patterns.push(...detectYods(unionedPoints, aspectLookup, houseCusps));
457
+ patterns.push(...detectMysticRectangles(unionedPoints, aspectLookup, houseCusps));
458
+ patterns.push(...detectKites(unionedPoints, aspectLookup, houseCusps));
459
+ return patterns;
460
+ }
@@ -1,17 +1,20 @@
1
- import { Point, Aspect, AspectData } from '../types';
1
+ import { Aspect, AspectData, UnionedPoint } from '../types';
2
2
  /**
3
- * Identifies aspects between planets in a single chart.
3
+ * Unified aspect calculation function that handles both single-chart and multi-chart scenarios
4
4
  * @param aspectDefinitions Array of aspect types to check for.
5
- * @param planets Array of planet points.
5
+ * @param unionedPlanets Array of UnionedPoint pairs to analyze.
6
+ * @param skipOutOfSignAspects Whether to skip aspects that cross sign boundaries.
7
+ * @param aspectStrengthThresholds Thresholds for classifying aspect strength.
8
+ * @param forceChartType Optional override for chart type determination.
6
9
  * @returns Array of found aspects.
7
10
  */
8
- export declare function calculateAspects(aspectDefinitions: Aspect[], planets: Point[], skipOutOfSignAspects?: boolean): AspectData[];
11
+ export declare function calculateAspects(aspectDefinitions: Aspect[], unionedPlanets: UnionedPoint[], skipOutOfSignAspects?: boolean): AspectData[];
9
12
  /**
10
- * Identifies aspects between planets across two charts.
11
- * PlanetA is always from chart1Planets, PlanetB always from chart2Planets.
12
- * @param aspectDefinitions Array of aspect types to check for.
13
- * @param chart1Planets Array of planet points for the first chart.
14
- * @param chart2Planets Array of planet points for the second chart.
15
- * @returns Array of found aspects.
13
+ * Calculates aspects in a multi-chart context (synastry, transits, etc.)
14
+ * @param aspectDefinitions Array of aspect types to check for
15
+ * @param unionedPlanets Array of UnionedPoint pairs to analyze
16
+ * @param skipOutOfSignAspects Whether to skip aspects that cross sign boundaries
17
+ * @param aspectStrengthThresholds Thresholds for classifying aspect strength
18
+ * @returns Array of found aspects
16
19
  */
17
- export declare function calculateMultichartAspects(aspectDefinitions: Aspect[], chart1Planets: Point[], chart2Planets: Point[], skipOutOfSignAspects?: boolean): AspectData[];
20
+ export declare function calculateMultichartAspects(aspectDefinitions: Aspect[], unionedPlanets: UnionedPoint[], skipOutOfSignAspects?: boolean): AspectData[];