chart2txt 0.6.0 → 0.7.1

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 (49) hide show
  1. package/README.md +103 -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 +10 -6
  6. package/dist/config/ChartSettings.js +22 -11
  7. package/dist/constants.d.ts +17 -2
  8. package/dist/constants.js +303 -34
  9. package/dist/core/analysis.d.ts +6 -0
  10. package/dist/core/analysis.js +237 -0
  11. package/dist/core/aspectPatterns.d.ts +8 -3
  12. package/dist/core/aspectPatterns.js +234 -218
  13. package/dist/core/aspects.d.ts +14 -11
  14. package/dist/core/aspects.js +49 -32
  15. package/dist/core/dignities.d.ts +2 -27
  16. package/dist/core/dignities.js +56 -121
  17. package/dist/core/dispositors.d.ts +7 -19
  18. package/dist/core/dispositors.js +152 -126
  19. package/dist/core/grouping.d.ts +9 -0
  20. package/dist/core/grouping.js +45 -0
  21. package/dist/core/signDistributions.d.ts +20 -30
  22. package/dist/core/signDistributions.js +25 -122
  23. package/dist/core/stelliums.d.ts +10 -0
  24. package/dist/core/stelliums.js +108 -0
  25. package/dist/formatters/text/sections/aspectPatterns.d.ts +3 -1
  26. package/dist/formatters/text/sections/aspectPatterns.js +118 -94
  27. package/dist/formatters/text/sections/aspects.d.ts +3 -6
  28. package/dist/formatters/text/sections/aspects.js +35 -52
  29. package/dist/formatters/text/sections/dispositors.d.ts +4 -3
  30. package/dist/formatters/text/sections/dispositors.js +12 -8
  31. package/dist/formatters/text/sections/houseOverlays.d.ts +11 -6
  32. package/dist/formatters/text/sections/houseOverlays.js +37 -44
  33. package/dist/formatters/text/sections/metadata.d.ts +2 -0
  34. package/dist/formatters/text/sections/metadata.js +54 -0
  35. package/dist/formatters/text/sections/planets.d.ts +3 -5
  36. package/dist/formatters/text/sections/planets.js +11 -22
  37. package/dist/formatters/text/sections/signDistributions.d.ts +9 -25
  38. package/dist/formatters/text/sections/signDistributions.js +9 -55
  39. package/dist/formatters/text/textFormatter.d.ts +4 -5
  40. package/dist/formatters/text/textFormatter.js +86 -142
  41. package/dist/index.d.ts +7 -4
  42. package/dist/index.js +11 -6
  43. package/dist/types.d.ts +102 -15
  44. package/dist/types.js +15 -0
  45. package/dist/utils/formatting.d.ts +4 -0
  46. package/dist/utils/formatting.js +43 -0
  47. package/dist/utils/houseCalculations.d.ts +10 -13
  48. package/dist/utils/houseCalculations.js +15 -57
  49. package/package.json +1 -1
package/README.md CHANGED
@@ -1,14 +1,21 @@
1
1
  # chart2txt
2
2
 
3
- A TypeScript library that converts astrological chart data to human-readable text.
3
+ An **automated text-based astrological pattern detection utility** designed primarily for LLM consumption with secondary human readability. This TypeScript library converts complex astrological chart data into structured, standardized text reports or raw JSON data.
4
4
 
5
5
  [![npm version](https://badge.fury.io/js/chart2txt.svg)](https://badge.fury.io/js/chart2txt)
6
6
 
7
+ ## Purpose & Design Philosophy
8
+
9
+ chart2txt is designed as an **automated pattern detection engine** that transforms astrological chart data into consistent, structured formats. A primary goal is to provide a clear separation between the analysis engine (which produces a structured `AstrologicalReport` object) and the text formatter. This allows developers to either use the raw JSON for their own applications or generate an LLM-readable (and human-readable) text report.
10
+
7
11
  ## Features
8
12
 
9
- - Convert planet positions to text descriptions of their zodiac signs
10
- - Calculate and describe house placements when an ascendant is provided
11
- - Calculate and describe aspects between planets
13
+ - **Single & Multi-Chart Analysis**: Natal, event, synastry, and transit chart processing.
14
+ - **Comprehensive Aspect Detection**: Including all major and minor aspects.
15
+ - **Advanced Aspect Patterns**: T-Square, Grand Trine, Yod, Stellium, and more.
16
+ - **Configurable Orb System**: Use presets or define your own aspect strength thresholds.
17
+ - **Sign Distributions**: Element, modality, and polarity analysis.
18
+ - **Dual Output**: Generate either a structured JSON `AstrologicalReport` or a formatted text string.
12
19
 
13
20
  ## Installation
14
21
 
@@ -16,44 +23,112 @@ A TypeScript library that converts astrological chart data to human-readable tex
16
23
  npm install chart2txt
17
24
  ```
18
25
 
19
- ## Usage
26
+ ## Usage Workflows
27
+
28
+ There are two primary ways to use `chart2txt`, depending on your needs.
29
+
30
+ ### 1. Simple Workflow (All-in-One)
31
+
32
+ This is the easiest way to get a text report. The `chart2txt()` function handles everything: analysis, default aspect grouping, and formatting.
20
33
 
21
34
  ```typescript
22
35
  import { chart2txt } from 'chart2txt';
23
36
 
24
- const chartData = {
37
+ const natalChart = {
38
+ name: "John Doe",
25
39
  planets: [
26
- { name: 'Sun', degree: 35 }, // 5° Taurus
27
- { name: 'Moon', degree: 120 }, // 0° Leo
28
- { name: 'Mercury', degree: 75 } // 15° Gemini
40
+ { name: 'Sun', degree: 35.5 },
41
+ { name: 'Moon', degree: 120.25 },
29
42
  ],
30
- ascendant: 0 // 0° Aries
31
- };
32
-
33
- const settings = {
34
- // modified settings go here
35
43
  };
36
44
 
37
- const textDescription = chart2txt(chartData, settings);
38
- console.log(textDescription);
45
+ // Get a report with default settings
46
+ const reportText = chart2txt(natalChart);
47
+ console.log(reportText);
48
+
49
+ // Override the default aspect grouping
50
+ const reportWithCustomGrouping = chart2txt(natalChart, {
51
+ aspectStrengthThresholds: {
52
+ tight: 1.0,
53
+ moderate: 5.0
54
+ }
55
+ });
56
+ console.log(reportWithCustomGrouping);
39
57
  ```
40
58
 
41
- ### Settings
59
+ ### 2. Advanced Workflow (Analyze -> Group -> Format)
42
60
 
43
- The conversion to text is configurable through the settings object. Any number of provided settings can be specified, and will overwrite the defaults when provided. Explanations of each setting can be found in the [types.ts](src/types.ts) file, and the default settings can be found in the [constants.ts](src/constants.ts) file. See the [tests file](tests/index.test.ts) for example uses of each setting.
61
+ This workflow gives you complete control over the process. It is recommended for applications that need to inspect or modify the analysis data before formatting.
44
62
 
45
- **NOTE**: Overriding aspects must be done by replacing the entire object, i.e. by modifying the following data object to suit your needs:
63
+ This is the workflow demonstrated in the live example page.
46
64
 
47
- ```javascript
48
- [
49
- { name: 'conjunction', angle: 0, orb: 5 },
50
- { name: 'opposition', angle: 180, orb: 5 },
51
- { name: 'trine', angle: 120, orb: 5 },
52
- { name: 'square', angle: 90, orb: 5 },
53
- { name: 'sextile', angle: 60, orb: 3 },
54
- ]
65
+ ```typescript
66
+ import { analyzeCharts, formatReportToText, AstrologicalReport, AspectData } from 'chart2txt';
67
+
68
+ const synastryData = [
69
+ { name: "Person A", planets: [{ name: 'Sun', degree: 45 }] },
70
+ { name: "Person B", planets: [{ name: 'Sun', degree: 225 }] }
71
+ ];
72
+
73
+ // 1. ANALYZE: Get the raw, ungrouped report object.
74
+ const report: AstrologicalReport = analyzeCharts(synastryData, {
75
+ includeAspectPatterns: true
76
+ });
77
+
78
+ // 2. CUSTOM GROUPING: Apply your own business logic.
79
+ // Here, you can implement any grouping strategy you want. For this example,
80
+ // we'll group aspects into "Hard" and "Soft" categories.
81
+
82
+ const hardAspects: AspectData[] = [];
83
+ const softAspects: AspectData[] = [];
84
+
85
+ report.pairwiseAnalyses[0].synastryAspects.forEach(aspect => {
86
+ if (['square', 'opposition'].includes(aspect.aspectType)) {
87
+ hardAspects.push(aspect);
88
+ } else {
89
+ softAspects.push(aspect);
90
+ }
91
+ });
92
+
93
+ // Create a Map to preserve category order.
94
+ const myGroupedAspects = new Map<string, AspectData[]>();
95
+ myGroupedAspects.set('[HARD ASPECTS]', hardAspects);
96
+ myGroupedAspects.set('[SOFT ASPECTS]', softAspects);
97
+
98
+ // Inject your custom-grouped map back into the report object.
99
+ report.pairwiseAnalyses[0].groupedSynastryAspects = myGroupedAspects;
100
+
101
+ // 3. FORMAT: Generate the text from your modified report object.
102
+ const reportText = formatReportToText(report);
103
+ console.log(reportText);
55
104
  ```
56
105
 
106
+ ## API Reference
107
+
108
+ ### Core Functions
109
+
110
+ * `chart2txt(data, [settings])`: The all-in-one function.
111
+ * `analyzeCharts(data, [settings])`: Performs analysis and returns a raw `AstrologicalReport`.
112
+ * `formatReportToText(report)`: Formats a (potentially modified) `AstrologicalReport` into a string.
113
+ * `groupAspects(aspects, settings)`: The default aspect grouping logic used by `chart2txt()`.
114
+
115
+ ### Configuration (`Settings`)
116
+
117
+ The `Settings` object is composed of three parts:
118
+
119
+ * **`AnalysisSettings`**: For `analyzeCharts()`
120
+ * `aspectDefinitions`: Aspect orbs. Can be a preset string (`'traditional'`, `'modern'`, `'tight'`, `'wide'`) or a custom array.
121
+ * `skipOutOfSignAspects`: `boolean`
122
+ * `includeAspectPatterns`: `boolean`
123
+ * `includeSignDistributions`: `boolean`
124
+ * `includeDispositors`: `boolean | 'finals'` - Controls dispositor tree output. `true` shows all chains, `false` disables, `'finals'` shows only final dispositors and deduplicated cycles.
125
+ * `includeHouseOverlays`: `boolean` - Controls house overlays section in synastry charts.
126
+ * **`GroupingSettings`**: For `groupAspects()` or the simple `chart2txt()` workflow.
127
+ * `aspectStrengthThresholds`: An object to define orb limits for default grouping, e.g., `{ tight: 2.0, moderate: 4.0 }`.
128
+ * **`FormattingSettings`**: For `formatReportToText()`
129
+ * `dateFormat`: `string`
130
+ * `houseSystemName`: `string`
131
+
57
132
  ## Development
58
133
 
59
134
  ```bash
@@ -65,14 +140,8 @@ npm test
65
140
 
66
141
  # Build the library
67
142
  npm run build
68
-
69
- # Lint code
70
- npm run lint
71
-
72
- # Format code
73
- npm run format
74
143
  ```
75
144
 
76
145
  ## License
77
146
 
78
- MIT
147
+ MIT
@@ -0,0 +1,9 @@
1
+ import { ChartData, MultiChartData, PartialSettings } from './types';
2
+ /**
3
+ * The main, all-in-one function to generate a complete astrological report text.
4
+ * It performs analysis, default aspect grouping, and text formatting in one step.
5
+ * @param data The chart data for one or more charts.
6
+ * @param partialSettings Optional settings to override defaults.
7
+ * @returns A string representing the full chart report.
8
+ */
9
+ export declare function chart2txt(data: ChartData | MultiChartData, partialSettings?: PartialSettings): string;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chart2txt = chart2txt;
4
+ const analysis_1 = require("./core/analysis");
5
+ const grouping_1 = require("./core/grouping");
6
+ const textFormatter_1 = require("./formatters/text/textFormatter");
7
+ /**
8
+ * The main, all-in-one function to generate a complete astrological report text.
9
+ * It performs analysis, default aspect grouping, and text formatting in one step.
10
+ * @param data The chart data for one or more charts.
11
+ * @param partialSettings Optional settings to override defaults.
12
+ * @returns A string representing the full chart report.
13
+ */
14
+ function chart2txt(data, partialSettings = {}) {
15
+ // 1. Analyze the chart data to get a raw report.
16
+ const analysisReport = (0, analysis_1.analyzeCharts)(data, partialSettings);
17
+ // 2. Apply default grouping logic to the raw aspects.
18
+ const settings = analysisReport.settings;
19
+ analysisReport.chartAnalyses.forEach((ca) => {
20
+ ca.groupedAspects = (0, grouping_1.groupAspects)(ca.aspects, settings);
21
+ });
22
+ analysisReport.pairwiseAnalyses.forEach((pa) => {
23
+ pa.groupedSynastryAspects = (0, grouping_1.groupAspects)(pa.synastryAspects, settings);
24
+ });
25
+ analysisReport.transitAnalyses.forEach((ta) => {
26
+ ta.groupedAspects = (0, grouping_1.groupAspects)(ta.aspects, settings);
27
+ });
28
+ // 3. Format the now-grouped report into text.
29
+ return (0, textFormatter_1.formatReportToText)(analysisReport);
30
+ }
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.chart2txt=t():e.chart2txt=t()}(this,(()=>(()=>{"use strict";var e={75:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.calculateAspects=function(e,t,n=!0){const r=[];if(!t||t.length<2)return r;for(let a=0;a<t.length;a++)for(let s=a+1;s<t.length;s++){const i=o(e,t[a],t[s],n);i&&r.push(i)}return r},t.calculateMultichartAspects=function(e,t,n,r=!0){const a=[];if(!t||!n||0===t.length||0===n.length)return a;for(const s of t)for(const t of n){const n=o(e,s,t,r);n&&a.push(n)}return a};const r=n(904),a=n(318);function s(e){const t=e<=180?e:360-e;switch(t){case 0:return 0;case 30:return 1;case 60:return 2;case 90:return 3;case 120:return 4;case 150:return 5;case 180:return 6;default:return Math.round(t/30)}}function i(e,t,n){if(void 0===e.speed||void 0===t.speed)return"exact";const s=e.speed,i=t.speed,o=(0,r.normalizeDegree)(e.degree),u=(0,r.normalizeDegree)(t.degree);let l=Math.abs(o-u);l>180&&(l=360-l);const c=Math.abs(l-n);if((0,a.isExactAspect)(c))return"exact";if(0===s-i)return"exact";const p=(0,r.normalizeDegree)(o+.1*s),h=(0,r.normalizeDegree)(u+.1*i),d=Math.abs(l-n);let f=Math.abs(p-h);f>180&&(f=360-f);return Math.abs(f-n)<d?"applying":"separating"}function o(e,t,n,o){const u=(0,a.roundDegrees)((0,r.normalizeDegree)(t.degree)),l=(0,a.roundDegrees)((0,r.normalizeDegree)(n.degree));let c=Math.abs(u-l);c>180&&(c=360-c);let p=null;for(const r of e){const e=(0,a.roundDegrees)(Math.abs(c-r.angle));if(o){const e=Math.floor(u/30),t=Math.floor(l/30),n=s(r.angle);let a=Math.abs(e-t);if(a>6&&(a=12-a),a!==n)continue}if(e<=r.orb&&(!p||e<p.orb)){const a=i(t,n,r.angle);p={planetA:t.name,planetB:n.name,aspectType:r.name,orb:e,application:a}}}return p}},82:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateDispositorsOutput=function(e){const t=["[DISPOSITOR TREE]"];if(0===e.length)return t.push("No planets available for dispositor analysis."),t;const n=(0,r.analyzeDispositors)(e),a=(0,r.formatDispositorAnalysis)(n);return t.push(...a),t};const r=n(729)},109:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateElementDistributionOutput=function(e,t,n){const a=[t?`[ELEMENT DISTRIBUTION: ${t}]`:"[ELEMENT DISTRIBUTION]"];if(0===e.length)return a.push("No planets available for element analysis."),a;const s=(0,r.analyzeSignDistributions)(e,n),i=(0,r.formatElementDistribution)(s.elements);return a.push(...i),a},t.generateModalityDistributionOutput=function(e,t,n){const a=[t?`[MODALITY DISTRIBUTION: ${t}]`:"[MODALITY DISTRIBUTION]"];if(0===e.length)return a.push("No planets available for modality analysis."),a;const s=(0,r.analyzeSignDistributions)(e,n),i=(0,r.formatModalityDistribution)(s.modalities);return a.push(...i),a},t.generatePolarityOutput=function(e,t,n){const a=[t?`[POLARITY: ${t}]`:"[POLARITY]"];if(0===e.length)return a.push("No planets available for polarity analysis."),a;const s=(0,r.analyzeSignDistributions)(e,n),i=(0,r.formatPolarityDistribution)(s.polarities);return a.push(...i),a};const r=n(858)},156:function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var a=Object.getOwnPropertyDescriptor(t,n);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,a)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),a=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),t.ChartSettings=t.ZODIAC_SIGNS=t.DEFAULT_ASPECT_CATEGORIES=t.DEFAULT_ASPECTS=t.DEFAULT_SETTINGS=t.chart2txt=void 0;var s=n(723);Object.defineProperty(t,"chart2txt",{enumerable:!0,get:function(){return s.formatChartToText}}),a(n(613),t);var i=n(921);Object.defineProperty(t,"DEFAULT_SETTINGS",{enumerable:!0,get:function(){return i.DEFAULT_SETTINGS}}),Object.defineProperty(t,"DEFAULT_ASPECTS",{enumerable:!0,get:function(){return i.DEFAULT_ASPECTS}}),Object.defineProperty(t,"DEFAULT_ASPECT_CATEGORIES",{enumerable:!0,get:function(){return i.DEFAULT_ASPECT_CATEGORIES}}),Object.defineProperty(t,"ZODIAC_SIGNS",{enumerable:!0,get:function(){return i.ZODIAC_SIGNS}});var o=n(230);Object.defineProperty(t,"ChartSettings",{enumerable:!0,get:function(){return o.ChartSettings}});const u=n(723);t.default=u.formatChartToText},172:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateChartHeaderOutput=function(e,t="CHART"){return[`[${t}: ${e||"Unknown"}]`]}},175:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getOrdinal=function(e){const t=["th","st","nd","rd"],n=e%100;return e+(t[(n-20)%10]||t[n]||t[0])}},230:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ChartSettings=void 0;const r=n(921);t.ChartSettings=class{constructor(e={}){const t={...r.DEFAULT_SETTINGS,...e};this.includeSignDegree=t.includeSignDegree,this.includeAscendant=t.includeAscendant,this.houseSystemName=t.houseSystemName,this.includeHouseDegree=t.includeHouseDegree,this.aspectDefinitions=t.aspectDefinitions||r.DEFAULT_ASPECTS,this.aspectCategories=t.aspectCategories||r.DEFAULT_ASPECT_CATEGORIES,this.skipOutOfSignAspects=t.skipOutOfSignAspects,this.includeAspectPatterns=t.includeAspectPatterns,this.dateFormat=t.dateFormat}}},234:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generatePlanetsOutput=function(e,t,n){const o=["[PLANETS]"];e.forEach((e=>{const n=(0,r.getDegreeSign)(e.degree),u=Math.floor((0,r.getDegreeInSign)(e.degree)),l=void 0!==e.speed&&e.speed<0?" Retrograde":"",c=(0,a.formatPlanetWithDignities)(e,t);let p=`${e.name}: ${u}° ${n}${l}`;if(c&&(p+=` ${c}`),t&&12===t.length){const n=(0,i.getHouseForPoint)(e.degree,t);n&&(p+=`, ${(0,s.getOrdinal)(n)} house`)}o.push(p)})),0===e.length&&o.push("No planets listed.");return o};const r=n(904),a=n(400),s=n(175),i=n(600)},318:(e,t)=>{function n(e,n,r=t.DEFAULT_EPSILON){return Math.abs(e-n)<r}function r(e,n=t.DEFAULT_EPSILON){return Math.abs(e)<n}function a(e,r,a=t.DEFAULT_EPSILON){return n(e,r,a)}Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_EPSILON=void 0,t.floatEquals=n,t.isNearZero=r,t.roundDegrees=function(e){return Math.round(1e4*e)/1e4},t.degreeEquals=a,t.isOnCusp=function(e,t,n=.001){return a(e,t,n)},t.isExactAspect=function(e,t=.1){return r(e,t)},t.DEFAULT_EPSILON=1e-4},371:(e,t)=>{function n(e){return e&&"object"==typeof e?"string"!=typeof e.name||""===e.name.trim()?"Point name must be a non-empty string":"number"==typeof e.degree&&isFinite(e.degree)?void 0===e.speed||"number"==typeof e.speed&&isFinite(e.speed)?null:`Point ${e.name} has invalid speed value: ${e.speed}`:`Point ${e.name} has invalid degree value: ${e.degree}`:"Point must be an object"}function r(e){if(!Array.isArray(e))return"Points must be an array";for(let t=0;t<e.length;t++){const r=n(e[t]);if(r)return`Point at index ${t}: ${r}`}const t=e.map((e=>e.name)),r=t.filter(((e,n)=>t.indexOf(e)!==n));return r.length>0?`Duplicate point names found: ${r.join(", ")}`:null}function a(e){if(void 0===e)return null;if(!Array.isArray(e))return"House cusps must be an array";if(12!==e.length)return`House cusps must contain exactly 12 values, got ${e.length}`;for(let t=0;t<e.length;t++)if("number"!=typeof e[t]||!isFinite(e[t]))return`House cusp ${t+1} has invalid value: ${e[t]}`;return null}function s(e){if(!e||"object"!=typeof e)return"Chart data must be an object";if("string"!=typeof e.name||""===e.name.trim())return"Chart name must be a non-empty string";const t=r(e.planets);if(t)return`Planets validation failed: ${t}`;if(void 0!==e.ascendant&&("number"!=typeof e.ascendant||!isFinite(e.ascendant)))return`Ascendant has invalid value: ${e.ascendant}`;if(void 0!==e.midheaven&&("number"!=typeof e.midheaven||!isFinite(e.midheaven)))return`Midheaven has invalid value: ${e.midheaven}`;const n=a(e.houseCusps);if(n)return`House cusps validation failed: ${n}`;if(void 0!==e.points){const t=r(e.points);if(t)return`Additional points validation failed: ${t}`}if(void 0!==e.timestamp&&(!(e.timestamp instanceof Date)||isNaN(e.timestamp.getTime())))return"Timestamp must be a valid Date object";if(void 0!==e.location&&"string"!=typeof e.location)return"Location must be a string";if(void 0!==e.chartType){const t=["natal","event","transit"];if(!t.includes(e.chartType))return`Chart type must be one of: ${t.join(", ")}`}return null}function i(e){if(!Array.isArray(e))return"Multi-chart data must be an array";if(0===e.length)return"Multi-chart data must contain at least one chart";if(e.length>10)return"Multi-chart data cannot contain more than 10 charts";for(let t=0;t<e.length;t++){const n=s(e[t]);if(n)return`Chart at index ${t} (${e[t]?.name||"unnamed"}): ${n}`}const t=e.map((e=>e.name)),n=t.filter(((e,n)=>t.indexOf(e)!==n));if(n.length>0)return`Duplicate chart names found: ${n.join(", ")}`;return e.filter((e=>"transit"===e.chartType)).length>1?"Cannot have more than one transit chart":null}Object.defineProperty(t,"__esModule",{value:!0}),t.validatePoint=n,t.validatePoints=r,t.validateHouseCusps=a,t.validateChartData=s,t.validateMultiChartData=i,t.validateInputData=function(e){if(!e)return"Data is required";return Array.isArray(e)?i(e):s(e)}},388:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateMetadataOutput=function(e,t,n){const r=["[METADATA]",`chart_type: ${t}`];n&&r.push(`house_system: ${n}`);return r.push(`date_format: ${e.dateFormat}`),r}},400:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getPlanetDignities=s,t.getSignRulers=i,t.formatPlanetWithDignities=function(e,t){const n=(0,r.getDegreeSign)(e.degree),a=s(e.name,n),o=i(n);let u="";a.length>0&&a.includes("Domicile")?u=`[${a.join(", ")}]`:a.length>0&&o.length>0?u=`[${a.join(", ")} | Ruler: ${o.join(", ")}]`:o.length>0&&(u=`[Ruler: ${o.join(", ")}]`);return u};const r=n(904),a={Aries:{rulers:["Mars"],exaltation:"Sun",detriment:"Venus",fall:"Saturn"},Taurus:{rulers:["Venus"],exaltation:"Moon",detriment:"Mars",fall:"Uranus"},Gemini:{rulers:["Mercury"],detriment:"Jupiter"},Cancer:{rulers:["Moon"],exaltation:"Jupiter",detriment:"Saturn",fall:"Mars"},Leo:{rulers:["Sun"],detriment:"Saturn",fall:"Neptune"},Virgo:{rulers:["Mercury"],exaltation:"Mercury",detriment:"Jupiter",fall:"Venus"},Libra:{rulers:["Venus"],exaltation:"Saturn",detriment:"Mars",fall:"Sun"},Scorpio:{rulers:["Mars"],detriment:"Venus",fall:"Moon"},Sagittarius:{rulers:["Jupiter"],detriment:"Mercury"},Capricorn:{rulers:["Saturn"],exaltation:"Mars",detriment:"Moon",fall:"Jupiter"},Aquarius:{rulers:["Saturn"],detriment:"Sun",fall:"Neptune"},Pisces:{rulers:["Jupiter"],exaltation:"Venus",detriment:"Mercury",fall:"Mercury"}};function s(e,t){const n=[],r=t.trim(),s=a[r];return s?(s.rulers.includes(e)&&n.push("Domicile"),s.exaltation===e&&n.push("Exaltation"),s.detriment===e&&n.push("Detriment"),s.fall&&s.fall===e&&n.push("Fall"),n):n}function i(e){const t=e.trim(),n=a[t];return n?n.rulers:[]}},600:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.validateHouseCusps=s,t.getHouseForPoint=function(e,t){if(!s(t))return null;if(!isFinite(e))return null;const n=(0,a.roundDegrees)((0,r.normalizeDegree)(e)),i=t.map((e=>(0,a.roundDegrees)((0,r.normalizeDegree)(e))));for(let e=0;e<12;e++)if((0,a.isOnCusp)(n,i[e]))return e+1;for(let e=0;e<12;e++){const t=i[e],r=i[(e+1)%12];if(t<r){if(n>t&&n<r)return e+1}else if(n>t||n<r)return e+1}return console.warn(`Point at ${n}° does not fall in any house`),null};const r=n(904),a=n(318);function s(e){if(!e||12!==e.length)return!1;for(const t of e)if(!isFinite(t))return!1;return!0}},613:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isMultiChartData=function(e){return Array.isArray(e)}},668:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateHousesOutput=function(e){const t=["[HOUSE CUSPS]"];if(!e||12!==e.length)return t.push("House cusps not available"),t;for(let n=0;n<6;n++){const s=n,i=n+6,o=e[s],u=e[i],l=(0,r.getDegreeSign)(o),c=Math.floor((0,r.getDegreeInSign)(o)),p=(0,a.getOrdinal)(s+1)+" house",h=(0,r.getDegreeSign)(u),d=Math.floor((0,r.getDegreeInSign)(u)),f=(0,a.getOrdinal)(i+1)+" house",g=`${p}: ${c}° ${l}`.padEnd(24),m=`${f}: ${d}° ${h}`;t.push(`${g} ${m}`)}return t};const r=n(904),a=n(175)},723:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.formatChartToText=function(e,t={}){const n=(0,s.validateInputData)(e);if(n)throw new Error(`Invalid chart data: ${n}`);const o=new a.ChartSettings(t),c=o.houseSystemName,p=[];if(!(0,r.isMultiChartData)(e)){if("transit"===e.chartType)throw new Error("Single chart data must not be transit.");return p.push(...(0,l.generateMetadataOutput)(o,e.chartType||"natal",c)),p.push(""),p.push(...A(o,e)),p.join("\n").trimEnd()}const h=$(e);p.push(...(0,l.generateMetadataOutput)(o,h,c)),p.push("");const d=e.filter((({chartType:e})=>"transit"!==e)),f=e.find((({chartType:e})=>"transit"===e));for(const e of d)p.push(...A(o,e));for(let e=0;e<d.length;e++)for(let t=e+1;t<d.length;t++)p.push(...v(o,d[e],d[t]));if(f){p.push(...y(o,f));for(const e of d){const t=(0,i.calculateMultichartAspects)(o.aspectDefinitions,u(e),u(f),o.skipOutOfSignAspects);p.push(...(0,m.generateAspectsOutput)(`[TRANSIT ASPECTS: ${e.name}]`,t,o,e.name,f.name,!0)),p.push("")}}return p.join("\n").trimEnd()};const r=n(613),a=n(230),s=n(371),i=n(75),o=n(919);function u(e){const t=[...e.planets];return void 0!==e.ascendant&&t.push({name:"Ascendant",degree:e.ascendant}),void 0!==e.midheaven&&t.push({name:"Midheaven",degree:e.midheaven}),t}const l=n(388),c=n(172),p=n(888),h=n(945),d=n(668),f=n(234),g=n(82),m=n(784),S=n(762),b=n(756),O=n(109),A=(e,t,n)=>{const r=[];r.push(...(0,c.generateChartHeaderOutput)(t.name,n)),r.push(...(0,p.generateBirthdataOutput)(t.location,t.timestamp,e)),r.push(...(0,h.generateAnglesOutput)(t.ascendant,t.midheaven)),r.push(...(0,d.generateHousesOutput)(t.houseCusps)),r.push(...(0,f.generatePlanetsOutput)(t.planets,t.houseCusps,e)),r.push(...(0,g.generateDispositorsOutput)(t.planets)),r.push(...(0,O.generateElementDistributionOutput)(t.planets,void 0,t.ascendant)),r.push(...(0,O.generateModalityDistributionOutput)(t.planets,void 0,t.ascendant)),r.push(...(0,O.generatePolarityOutput)(t.planets,void 0,t.ascendant));const a=(0,i.calculateAspects)(e.aspectDefinitions,u(t),e.skipOutOfSignAspects);if(r.push(...(0,m.generateAspectsOutput)("[ASPECTS]",a,e)),e.includeAspectPatterns){const e=(0,o.detectAspectPatterns)(t.planets,t.houseCusps);r.push(...(0,S.generateAspectPatternsOutput)(e))}return r.push(""),r},v=(e,t,n)=>{const r=[],a="event"===t.chartType&&"event"===n.chartType?"EVENT_RELATIONSHIP":"event"===t.chartType||"event"===n.chartType?"NATAL_EVENT":"SYNASTRY";r.push(...(0,c.generateChartHeaderOutput)(`${t.name}-${n.name}`,a));const s=(0,i.calculateMultichartAspects)(e.aspectDefinitions,u(t),u(n),e.skipOutOfSignAspects);return r.push(...(0,m.generateAspectsOutput)("[PLANET-PLANET ASPECTS]",s,e,t.name,n.name)),r.push(""),r.push(...(0,b.generateHouseOverlaysOutput)(t,n,e)),r.push(""),r},y=(e,t)=>{const n=[];return n.push(...(0,c.generateChartHeaderOutput)(t.name,"TRANSIT")),n.push(...(0,p.generateBirthdataOutput)(t.location,t.timestamp,e,"[DATETIME]")),n.push(...(0,f.generatePlanetsOutput)(t.planets,t.houseCusps,e)),n.push(""),n},$=e=>{let t="natal",n="";const r=e.filter((({chartType:e})=>"transit"!==e&&"event"!==e)),a=e.filter((({chartType:e})=>"event"===e)),s=e.filter((({chartType:e})=>"transit"===e));if(s.length>1)throw new Error("Must provide at most one transit chart");const i=s.length>0;if(r.length>0?0===a.length?i&&(n="_with_transit"):n=1===a.length?i?"_with_event_and_transit":"_with_event":i?"_with_events_and_transit":"_with_events":i&&(n="_with_transit"),0===r.length){if(0===a.length)throw new Error("Must provide at least one non-transit chart");t=1===a.length?"event":"multi_event"}else t=1===r.length?"natal":2===r.length?"synastry":"group_synastry";return t+n}},729:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.analyzeDispositors=function(e){const t=new Map,n=new Map;e.forEach((e=>{const s=(0,r.getDegreeSign)(e.degree),i=(0,a.getSignRulers)(s);t.set(e.name,i),i.forEach((t=>{n.has(t)||n.set(t,[]),n.get(t).push(e.name)}))}));const s=[],i=new Set(e.map((e=>e.name)));e.forEach((e=>{const n=t.get(e.name)||[],r=n.includes(e.name),a=n.length>0&&!n.some((e=>i.has(e)));(r||a)&&s.push(e.name)}));return{chains:e.map((e=>({planet:e.name,disposedBy:t.get(e.name)||[],disposes:n.get(e.name)||[]}))),finalDispositors:s}},t.formatDispositorAnalysis=function(e){const t=[];return e.chains.forEach((n=>{const r=s(n.planet,e.chains).join(" → ");t.push(`${n.planet} → ${r}`)})),t};const r=n(904),a=n(400);function s(e,t,n=[]){const r=t.find((t=>t.planet===e));if(!r||0===r.disposedBy.length)return["(final)"];const a=r.disposedBy.filter((e=>t.some((t=>t.planet===e))));if(0===a.length)return["(final)"];const i=a[0];if(i===e)return["(final)"];if(n.includes(i))return["(cycle)"];const o=[...n,e];return[i,...s(i,t,o)]}},756:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateHouseOverlaysOutput=function(e,t,n){const s=["[HOUSE OVERLAYS]"],i=e.name,o=t.name;t.houseCusps&&12===t.houseCusps.length?(s.push(`${i}'s planets in ${o}'s houses:`),e.planets&&e.planets.length>0?e.planets.forEach((e=>{const n=(0,a.getHouseForPoint)(e.degree,t.houseCusps);n?s.push(`- ${e.name}: ${(0,r.getOrdinal)(n)}`):s.push(`- ${e.name}: (Could not determine house in ${o})`)})):s.push("(No planets listed for overlay)")):s.push(`${i}'s planets in ${o}'s houses: (${o} house cusps not available)`);s.push(""),e.houseCusps&&12===e.houseCusps.length?(s.push(`${o}'s planets in ${i}'s houses:`),t.planets&&t.planets.length>0?t.planets.forEach((t=>{const n=(0,a.getHouseForPoint)(t.degree,e.houseCusps);n?s.push(`- ${t.name}: ${(0,r.getOrdinal)(n)}`):s.push(`- ${t.name}: (Could not determine house in ${i})`)})):s.push("(No planets listed for overlay)")):s.push(`${o}'s planets in ${i}'s houses: (${i} house cusps not available)`);return s};const r=n(175),a=n(600)},762:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateAspectPatternsOutput=function(e){const t=["[ASPECT PATTERNS]"];if(0===e.length)return t.push("No aspect patterns detected."),t;const n=["T-Square","Grand Trine","Grand Cross","Stellium","Yod","Mystic Rectangle","Kite"];e.sort(((e,t)=>n.indexOf(e.type)-n.indexOf(t.type))).forEach((e=>{switch(e.type){case"T-Square":t.push(...function(e){if("T-Square"!==e.type)return[];const t=["T-Square:"];return t.push(` - Apex: ${s(e.apex)}`),t.push(` - Opposition: ${s(e.opposition[0])} - ${s(e.opposition[1])}`),t.push(` - Mode: ${e.mode}`),t.push(` - Average orb: ${e.averageOrb.toFixed(1)}°`),t.push(""),t}(e));break;case"Grand Trine":t.push(...function(e){if("Grand Trine"!==e.type)return[];const t=["Grand Trine:"];return e.planets.forEach(((e,n)=>{t.push(` - Planet ${n+1}: ${s(e)}`)})),t.push(` - Element: ${e.element}`),t.push(` - Average orb: ${e.averageOrb.toFixed(1)}°`),t.push(""),t}(e));break;case"Stellium":t.push(...function(e){if("Stellium"!==e.type)return[];const t=["Stellium:"],n=e.planets.map((e=>e.name)).join(", ");t.push(` - Planets: ${n}`),e.sign&&t.push(` - Sign: ${e.sign}`);if(e.houses.length>0){const n=1===e.houses.length?`${(0,a.getOrdinal)(e.houses[0])}`:e.houses.map((e=>(0,a.getOrdinal)(e))).join("-");t.push(` - Houses: ${n}`)}return t.push(` - Span: ${e.span.toFixed(1)}°`),t.push(""),t}(e));break;case"Grand Cross":t.push(...function(e){if("Grand Cross"!==e.type)return[];const t=["Grand Cross:"];return e.planets.forEach(((e,n)=>{t.push(` - Planet ${n+1}: ${s(e)}`)})),t.push(` - Mode: ${e.mode}`),t.push(` - Average orb: ${e.averageOrb.toFixed(1)}°`),t.push(""),t}(e));break;case"Yod":t.push(...function(e){if("Yod"!==e.type)return[];const t=["Yod:"];return t.push(` - Apex: ${s(e.apex)}`),t.push(` - Base planet 1: ${s(e.base[0])}`),t.push(` - Base planet 2: ${s(e.base[1])}`),t.push(` - Average orb: ${e.averageOrb.toFixed(1)}°`),t.push(""),t}(e));break;case"Mystic Rectangle":t.push(...function(e){if("Mystic Rectangle"!==e.type)return[];const t=["Mystic Rectangle:"];return t.push(` - Opposition 1: ${s(e.oppositions[0][0])} - ${s(e.oppositions[0][1])}`),t.push(` - Opposition 2: ${s(e.oppositions[1][0])} - ${s(e.oppositions[1][1])}`),t.push(` - Average orb: ${e.averageOrb.toFixed(1)}°`),t.push(""),t}(e));break;case"Kite":t.push(...function(e){if("Kite"!==e.type)return[];const t=["Kite:"],n=e.grandTrine.map((e=>e.name)).join(", ");return t.push(` - Grand Trine planets: ${n}`),t.push(` - Opposition planet: ${s(e.opposition)}`),t.push(` - Average orb: ${e.averageOrb.toFixed(1)}°`),t.push(""),t}(e))}})),""===t[t.length-1]&&t.pop();return t};const r=n(904),a=n(175);function s(e){const t=Math.floor((0,r.getDegreeInSign)(e.degree)),n=e.house?` (${(0,a.getOrdinal)(e.house)} house)`:"";return`${e.name} ${t}° ${e.sign}${n}`}},784:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateAspectsOutput=function(e,t,n,r,a,s=!1){const i=[e];let o=!1;n.aspectCategories.forEach((e=>{const n=t.filter((t=>{const n=t.orb,r=void 0===e.minOrb||n>e.minOrb,a=n<=e.maxOrb;return r&&a}));if(n.length>0){o=!0;let t=`orb under ${e.maxOrb.toFixed(1)}°`;void 0!==e.minOrb&&(t=e.minOrb<e.maxOrb?`orb ${e.minOrb.toFixed(1)}-${e.maxOrb.toFixed(1)}°`:`orb over ${e.minOrb.toFixed(1)}° & under ${e.maxOrb.toFixed(1)}°`),i.push(`[${e.name}: ${t}]`),n.sort(((e,t)=>e.orb-t.orb)),n.forEach((e=>{const t=r?`${r}'s ${e.planetA}`:e.planetA;let n=e.planetB;s?n=`transiting ${e.planetB}`:a&&(n=`${a}'s ${e.planetB}`);const o=e.application&&"exact"!==e.application?` (${e.application})`:"";i.push(`${t} ${e.aspectType} ${n}: ${e.orb.toFixed(1)}°${o}`)}))}})),!o&&t.length>0?i.push("No aspects within defined categories."):0===t.length&&i.push("None");return i}},858:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.analyzeSignDistributions=function(e,t){const n={Fire:[],Earth:[],Air:[],Water:[]},o={Cardinal:0,Fixed:0,Mutable:0},u={Masculine:0,Feminine:0};if(e.forEach((e=>{const t=(0,r.getDegreeSign)(e.degree),l=a[t],c=s[t],p=i[t];l&&n[l].push(e.name),c&&o[c]++,p&&u[p]++})),void 0!==t){const e=(0,r.getDegreeSign)(t),l=a[e],c=s[e],p=i[e];l&&n[l].push("Ascendant"),c&&o[c]++,p&&u[p]++}return{elements:n,modalities:o,polarities:u}},t.formatElementDistribution=function(e){const t=[];return Object.entries(e).forEach((([e,n])=>{if(n.length>0){const r=n.join(", ");t.push(`${e}: ${n.length} (${r})`)}})),t},t.formatModalityDistribution=function(e){const t=[];return Object.entries(e).forEach((([e,n])=>{n>0&&t.push(`${e}: ${n}`)})),t},t.formatPolarityDistribution=function(e){const t=[];e.Masculine>0&&t.push(`Masculine (Active): ${e.Masculine}`);e.Feminine>0&&t.push(`Feminine (Receptive): ${e.Feminine}`);return t};const r=n(904),a={Aries:"Fire",Leo:"Fire",Sagittarius:"Fire",Taurus:"Earth",Virgo:"Earth",Capricorn:"Earth",Gemini:"Air",Libra:"Air",Aquarius:"Air",Cancer:"Water",Scorpio:"Water",Pisces:"Water"},s={Aries:"Cardinal",Cancer:"Cardinal",Libra:"Cardinal",Capricorn:"Cardinal",Taurus:"Fixed",Leo:"Fixed",Scorpio:"Fixed",Aquarius:"Fixed",Gemini:"Mutable",Virgo:"Mutable",Sagittarius:"Mutable",Pisces:"Mutable"},i={Aries:"Masculine",Gemini:"Masculine",Leo:"Masculine",Libra:"Masculine",Sagittarius:"Masculine",Aquarius:"Masculine",Taurus:"Feminine",Cancer:"Feminine",Virgo:"Feminine",Scorpio:"Feminine",Capricorn:"Feminine",Pisces:"Feminine"}},888:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateBirthdataOutput=function(e,t,n,a="[BIRTHDATA]"){if(!t)return[`${a} Not available`];const s=(0,r.formatDateCustom)(t,n.dateFormat),i=(0,r.formatTime)(t);return[`${a} ${e||"Unknown Location"} | ${s} | ${i}`]};const r=n(889)},889:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.formatDateCustom=function(e,t){const n=e.getMonth()+1,r=e.getDate(),a=e.getFullYear();switch(t.toUpperCase()){case"MM/DD/YYYY":return`${n.toString().padStart(2,"0")}/${r.toString().padStart(2,"0")}/${a}`;case"DD/MM/YYYY":return`${r.toString().padStart(2,"0")}/${n.toString().padStart(2,"0")}/${a}`;case"YYYY-MM-DD":return`${a}-${n.toString().padStart(2,"0")}-${r.toString().padStart(2,"0")}`;default:return console.warn(`Unrecognized date format: ${t}. Falling back to toLocaleDateString().`),e.toLocaleDateString()}},t.formatTime=function(e){return e.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!0})}},904:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.normalizeDegree=a,t.getDegreeSign=function(e){const t=a(e),n=Math.floor(t/30);if(n<0||n>=r.ZODIAC_SIGNS.length)return console.error(`Invalid sign index computed: ${n} for normalized degree ${t}`),"Unknown Sign";return r.ZODIAC_SIGNS[n]},t.getDegreeInSign=function(e){return a(e)%30};const r=n(921);function a(e){if(!isFinite(e))throw new Error(`Invalid degree value: ${e}`);let t=e%360;return t<0&&(t+=360),t}},919:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.detectAspectPatterns=function(e,t){const n=[];return n.push(...function(e,t,n=8){const r=[];for(let a=0;a<e.length;a++)for(let l=a+1;l<e.length;l++)if(u(e[a],e[l],180,n))for(let c=0;c<e.length;c++)if(c!==a&&c!==l&&u(e[a],e[c],90,n)&&u(e[l],e[c],90,n)){const n=i(e[c],t),u=i(e[a],t),p=i(e[l],t),h=(s(e[a],e[l],180)+s(e[a],e[c],90)+s(e[l],e[c],90))/3,d=o(n.sign);r.push({type:"T-Square",apex:n,opposition:[u,p],mode:d,averageOrb:h})}return r}(e,t)),n.push(...l(e,t)),n.push(...function(e,t,n=3){const s=[],o=new Map;if(e.forEach((e=>{const t=(0,r.getDegreeSign)(e.degree);o.has(t)||o.set(t,[]),o.get(t).push(e)})),o.forEach(((e,r)=>{if(e.length>=n){const n=e.map((e=>i(e,t))),a=n.map((e=>e.house)).filter((e=>void 0!==e)),o=e.map((e=>e.degree)),u=Math.max(...o)-Math.min(...o);s.push({type:"Stellium",planets:n,sign:r,houses:[...new Set(a)].sort(),span:u})}})),t){const r=new Map;e.forEach((e=>{const n=(0,a.getHouseForPoint)(e.degree,t);n&&(r.has(n)||r.set(n,[]),r.get(n).push(e))})),r.forEach(((e,r)=>{if(e.length>=n){const n=e.map((e=>i(e,t))),a=e.map((e=>e.degree)),o=Math.max(...a)-Math.min(...a);s.find((e=>"Stellium"===e.type&&e.planets.some((e=>n.some((t=>t.name===e.name))))))||s.push({type:"Stellium",planets:n,houses:[r],span:o})}}))}return s}(e,t)),n.push(...function(e,t,n=8){const r=[];for(let a=0;a<e.length;a++)for(let l=a+1;l<e.length;l++)for(let c=l+1;c<e.length;c++)for(let p=c+1;p<e.length;p++){const h=[[a,l],[c,p]],d=[[a,c],[l,p],[a,p],[l,c]];let f=0,g=0;if(h.forEach((([t,r])=>{u(e[t],e[r],180,n)&&f++})),d.forEach((([t,r])=>{u(e[t],e[r],90,n)&&g++})),2===f&&4===g){const n=i(e[a],t),u=i(e[l],t),f=i(e[c],t),g=i(e[p],t);let m=0,S=0;h.forEach((([t,n])=>{m+=s(e[t],e[n],180),S++})),d.forEach((([t,n])=>{m+=s(e[t],e[n],90),S++}));const b=m/S,O=o(n.sign);r.push({type:"Grand Cross",planets:[n,u,f,g],mode:O,averageOrb:b})}}return r}(e,t)),n.push(...function(e,t,n=5){const r=[];for(let a=0;a<e.length;a++)for(let o=a+1;o<e.length;o++)if(u(e[a],e[o],60,n))for(let l=0;l<e.length;l++)if(l!==a&&l!==o&&u(e[a],e[l],150,n)&&u(e[o],e[l],150,n)){const n=i(e[l],t),u=i(e[a],t),c=i(e[o],t),p=(s(e[a],e[o],60)+s(e[a],e[l],150)+s(e[o],e[l],150))/3;r.push({type:"Yod",apex:n,base:[u,c],averageOrb:p})}return r}(e,t)),n.push(...function(e,t,n=8){const r=[];for(let a=0;a<e.length;a++)for(let o=a+1;o<e.length;o++)for(let l=o+1;l<e.length;l++)for(let c=l+1;c<e.length;c++){const p=[{oppositions:[[a,o],[l,c]],sextiles:[[a,l],[a,c],[o,l],[o,c]]},{oppositions:[[a,l],[o,c]],sextiles:[[a,o],[a,c],[l,o],[l,c]]},{oppositions:[[a,c],[o,l]],sextiles:[[a,o],[a,l],[c,o],[c,l]]}];for(const a of p){let o=0,l=0;if(a.oppositions.forEach((([t,r])=>{u(e[t],e[r],180,n)&&o++})),a.sextiles.forEach((([t,r])=>{(u(e[t],e[r],60,n)||u(e[t],e[r],120,n))&&l++})),2===o&&4===l){const n=i(e[a.oppositions[0][0]],t),o=i(e[a.oppositions[0][1]],t),u=i(e[a.oppositions[1][0]],t),l=i(e[a.oppositions[1][1]],t);let c=0,p=0;a.oppositions.forEach((([t,n])=>{c+=s(e[t],e[n],180),p++})),a.sextiles.forEach((([t,n])=>{const r=s(e[t],e[n],60),a=s(e[t],e[n],120);c+=Math.min(r,a),p++}));const h=c/p;r.push({type:"Mystic Rectangle",oppositions:[[n,o],[u,l]],averageOrb:h})}}}return r}(e,t)),n.push(...function(e,t,n=8){const r=[];return l(e,t,n).forEach((a=>{a.planets.forEach((o=>{e.forEach((l=>{if(!a.planets.some((e=>e.name===l.name))){const c=e.find((e=>e.name===o.name));if(c&&u(c,l,180,n)){const e=i(l,t),n=s(c,l,180),o=(a.averageOrb+n)/2;r.push({type:"Kite",grandTrine:a.planets,opposition:e,averageOrb:o})}}}))}))})),r}(e,t)),n};const r=n(904),a=n(600);function s(e,t,n){const a=(0,r.normalizeDegree)(e.degree),s=(0,r.normalizeDegree)(t.degree);let i=Math.abs(a-s);return i>180&&(i=360-i),Math.abs(i-n)}function i(e,t){const n=(0,r.getDegreeSign)(e.degree),s=t&&(0,a.getHouseForPoint)(e.degree,t)||void 0;return{name:e.name,degree:e.degree,sign:n,house:s}}function o(e){return["Aries","Cancer","Libra","Capricorn"].includes(e)?"Cardinal":["Taurus","Leo","Scorpio","Aquarius"].includes(e)?"Fixed":"Mutable"}function u(e,t,n,r){return s(e,t,n)<=r}function l(e,t,n=8){const r=[];for(let o=0;o<e.length;o++)for(let l=o+1;l<e.length;l++)for(let c=l+1;c<e.length;c++)if(u(e[o],e[l],120,n)&&u(e[l],e[c],120,n)&&u(e[c],e[o],120,n)){const n=i(e[o],t),u=i(e[l],t),p=i(e[c],t),h=(s(e[o],e[l],120)+s(e[l],e[c],120)+s(e[c],e[o],120))/3,d=(a=n.sign,["Aries","Leo","Sagittarius"].includes(a)?"Fire":["Taurus","Virgo","Capricorn"].includes(a)?"Earth":["Gemini","Libra","Aquarius"].includes(a)?"Air":"Water");r.push({type:"Grand Trine",planets:[n,u,p],element:d,averageOrb:h})}var a;return r}},921:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_SETTINGS=t.DEFAULT_ASPECT_CATEGORIES=t.DEFAULT_ASPECTS=t.ZODIAC_SIGNS=void 0,t.ZODIAC_SIGNS=["Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn","Aquarius","Pisces"],t.DEFAULT_ASPECTS=[{name:"conjunction",angle:0,orb:5},{name:"opposition",angle:180,orb:5},{name:"trine",angle:120,orb:5},{name:"square",angle:90,orb:5},{name:"sextile",angle:60,orb:3}],t.DEFAULT_ASPECT_CATEGORIES=[{name:"TIGHT ASPECTS",maxOrb:2},{name:"MODERATE ASPECTS",minOrb:2,maxOrb:4}],t.DEFAULT_SETTINGS={includeSignDegree:!0,houseSystemName:"whole_sign",includeHouseDegree:!1,includeAscendant:!0,aspectDefinitions:t.DEFAULT_ASPECTS,aspectCategories:t.DEFAULT_ASPECT_CATEGORIES,skipOutOfSignAspects:!0,includeAspectPatterns:!1,dateFormat:"MM/DD/YYYY"}},945:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateAnglesOutput=function(e,t){const n=["[ANGLES]"];void 0!==e?n.push(`Ascendant: ${Math.floor((0,r.getDegreeInSign)(e))}° ${(0,r.getDegreeSign)(e)}`):n.push("Ascendant: Not available");void 0!==t?n.push(`Midheaven: ${Math.floor((0,r.getDegreeInSign)(t))}° ${(0,r.getDegreeSign)(t)}`):n.push("Midheaven: Not available");return n};const r=n(904)}},t={};var n=function n(r){var a=t[r];if(void 0!==a)return a.exports;var s=t[r]={exports:{}};return e[r].call(s.exports,s,s.exports,n),s.exports}(156);return n=n.default})()));
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.chart2txt=t():e.chart2txt=t()}(this,(()=>(()=>{"use strict";var e={6:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.analyzeCharts=function(e,t={}){const n=(0,i.validateInputData)(e);if(n)throw new Error(`Invalid chart data: ${n}`);const b=new a.ChartSettings(t),y=(0,r.isMultiChartData)(e)?e:[e],T=y.filter((e=>"transit"!==e.chartType)),O=y.find((e=>"transit"===e.chartType)),M=[...T,...O?[O]:[]],_=[],D=d(M,!0);for(const e of M){const t=d([e]),n=(0,s.calculateAspects)(b.resolvedAspectDefinitions,t,b.skipOutOfSignAspects);_.push(...n)}for(let e=0;e<M.length;e++)for(let t=e+1;t<M.length;t++){const n=M[t],r=[...d([M[e]]),...d([n])],a=(0,s.calculateMultichartAspects)(b.resolvedAspectDefinitions,r,b.skipOutOfSignAspects);_.push(...a)}const C=b.includeAspectPatterns?(0,o.detectAspectPatterns)(D,_):[],E=[],v=[],$=[];let P,I;for(const e of M){const t=_.filter((t=>t.p1ChartName===e.name&&t.p2ChartName===e.name)),n=S(C,1,1).filter((t=>A(t,e.name))),r=b.includeAspectPatterns?(0,u.detectStelliums)(h(e),e.houseCusps):[];E.push({chart:e,placements:{planets:(0,c.getPlanetPositions)(e.planets,e.houseCusps)},aspects:t,patterns:n,stelliums:r,signDistributions:b.includeSignDistributions?(0,l.calculateSignDistributions)(e.planets,e.ascendant):{elements:{},modalities:{},polarities:{}},dispositors:"transit"!==e.chartType?(0,p.calculateDispositors)(e.planets,b.includeDispositors):{}})}if(T.length>=2)for(let e=0;e<T.length;e++)for(let t=e+1;t<T.length;t++){const n=T[e],r=T[t],a=_.filter((e=>e.p1ChartName===n.name&&e.p2ChartName===r.name||e.p1ChartName===r.name&&e.p2ChartName===n.name)),i=S(C,2,2).filter((e=>A(e,n.name)&&A(e,r.name)));v.push({chart1:n,chart2:r,synastryAspects:a,compositePatterns:i,houseOverlays:b.includeHouseOverlays?(0,f.calculateHouseOverlays)(n,r):{chart1InChart2Houses:{},chart2InChart1Houses:{}}})}if(T.length>2){const e=S(C,3).filter((e=>!g(e).has(O?.name||"TRANSIT_PLACEHOLDER")));e.length>0&&(P={charts:T,patterns:e})}if(O){for(const e of T){const t=_.filter((t=>t.p1ChartName===e.name&&t.p2ChartName===O.name||t.p1ChartName===O.name&&t.p2ChartName===e.name)),n=S(C,2,2).filter((t=>A(t,e.name)&&A(t,O.name)));$.push({natalChart:e,transitChart:O,aspects:t,patterns:n})}if(T.length>0){const e=(j=C,N=[O.name],j.filter((e=>N.some((t=>A(e,t)))))).filter((e=>m(e)>=3));e.length>0&&(I={charts:M,patterns:e})}}var j,N;return{settings:b,chartAnalyses:E,pairwiseAnalyses:v,globalAnalysis:P,transitAnalyses:$,globalTransitAnalysis:I}};const r=n(613),a=n(230),i=n(371),s=n(75),o=n(919),u=n(390),c=n(175),l=n(858),p=n(729),f=n(600);function h(e){const t=["Ascendant","Midheaven","North Node","South Node"];return e.planets.filter((e=>!t.includes(e.name)))}function d(e,t=!1){return e.flatMap((e=>(t?h(e):function(e){const t=[...e.planets];return void 0!==e.ascendant&&t.push({name:"Ascendant",degree:e.ascendant}),void 0!==e.midheaven&&t.push({name:"Midheaven",degree:e.midheaven}),t}(e)).map((t=>[t,e.name]))))}function g(e){const t=new Set,n=[],r=e=>{e&&n.push(e)};switch(e.type){case"T-Square":r(e.apex),e.opposition.forEach(r);break;case"Grand Trine":case"Grand Cross":e.planets.forEach(r);break;case"Yod":r(e.apex),e.base.forEach(r);break;case"Mystic Rectangle":e.oppositions.flat().forEach(r);break;case"Kite":e.grandTrine.forEach(r),r(e.opposition)}return n.forEach((e=>{e.chartName&&t.add(e.chartName)})),t}function m(e){return g(e).size}function A(e,t){return g(e).has(t)}function S(e,t,n=1/0){return e.filter((e=>{const r=m(e);return r>=t&&r<=n}))}},75:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.calculateAspects=function(e,t,n=!0){const r=[];if(!t||t.length<2)return r;for(let a=0;a<t.length;a++)for(let i=a+1;i<t.length;i++){const[s,u]=t[a],[c,l]=t[i],p=o(e,s,c,n,u,l);p&&r.push(p)}return r},t.calculateMultichartAspects=function(e,t,n=!0){const r=[];for(let a=0;a<t.length;a++)for(let i=a+1;i<t.length;i++){const[s,u]=t[a],[c,l]=t[i];if(u!==l){const t=o(e,s,c,n,u,l);t&&r.push(t)}}return r};const r=n(904),a=n(318);function i(e){const t=e<=180?e:360-e;switch(t){case 0:return 0;case 30:return 1;case 60:return 2;case 90:return 3;case 120:return 4;case 150:return 5;case 180:return 6;default:return Math.round(t/30)}}function s(e,t,n){if(void 0===e.speed||void 0===t.speed)return"exact";const i=e.speed,s=t.speed,o=(0,r.normalizeDegree)(e.degree),u=(0,r.normalizeDegree)(t.degree);let c=Math.abs(o-u);c>180&&(c=360-c);const l=Math.abs(c-n);if((0,a.isExactAspect)(l))return"exact";if(0===i-s)return"exact";const p=(0,r.normalizeDegree)(o+.1*i),f=(0,r.normalizeDegree)(u+.1*s),h=Math.abs(c-n);let d=Math.abs(p-f);d>180&&(d=360-d);return Math.abs(d-n)<h?"applying":"separating"}function o(e,t,n,o,u,c){const l=(0,a.roundDegrees)((0,r.normalizeDegree)(t.degree)),p=(0,a.roundDegrees)((0,r.normalizeDegree)(n.degree));let f=Math.abs(l-p);f>180&&(f=360-f);let h=null;for(const r of e){const e=(0,a.roundDegrees)(Math.abs(f-r.angle));if(o){const e=Math.floor(l/30),t=Math.floor(p/30),n=i(r.angle);let a=Math.abs(e-t);if(a>6&&(a=12-a),a!==n)continue}if(e<=r.orb&&(!h||e<h.orb)){const a=s(t,n,r.angle);h={planetA:t.name,planetB:n.name,p1ChartName:u,p2ChartName:c,aspectType:r.name,orb:e,application:a}}}return h}},82:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateDispositorsOutput=function(e){if(e.summary)return[`[DISPOSITORS] ${e.summary}`];const t=["[DISPOSITOR TREE]"];if(0===Object.keys(e).length)return t.push("No dispositor data available."),t;for(const n in e)t.push(e[n]);return t}},109:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateElementDistributionOutput=function(e){const t=["[ELEMENT DISTRIBUTION]"];return t.push(...(0,r.formatElementDistribution)(e)),t},t.generateModalityDistributionOutput=function(e){const t=["[MODALITY DISTRIBUTION]"];return t.push(...(0,r.formatModalityDistribution)(e)),t},t.generatePolarityOutput=function(e){const t=["[POLARITY]"];return t.push(...(0,r.formatPolarityDistribution)(e)),t};const r=n(858)},156:function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var a=Object.getOwnPropertyDescriptor(t,n);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,a)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),a=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),t.ChartSettings=t.ZODIAC_SIGNS=t.DEFAULT_ASPECTS=t.DEFAULT_SETTINGS=t.formatReportToText=t.groupAspects=t.analyzeCharts=t.chart2txt=void 0;var i=n(666);Object.defineProperty(t,"chart2txt",{enumerable:!0,get:function(){return i.chart2txt}});var s=n(6);Object.defineProperty(t,"analyzeCharts",{enumerable:!0,get:function(){return s.analyzeCharts}});var o=n(865);Object.defineProperty(t,"groupAspects",{enumerable:!0,get:function(){return o.groupAspects}});var u=n(723);Object.defineProperty(t,"formatReportToText",{enumerable:!0,get:function(){return u.formatReportToText}}),a(n(613),t);var c=n(921);Object.defineProperty(t,"DEFAULT_SETTINGS",{enumerable:!0,get:function(){return c.DEFAULT_SETTINGS}}),Object.defineProperty(t,"DEFAULT_ASPECTS",{enumerable:!0,get:function(){return c.DEFAULT_ASPECTS}}),Object.defineProperty(t,"ZODIAC_SIGNS",{enumerable:!0,get:function(){return c.ZODIAC_SIGNS}});var l=n(230);Object.defineProperty(t,"ChartSettings",{enumerable:!0,get:function(){return l.ChartSettings}});const p=n(666);t.default=p.chart2txt},172:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateChartHeaderOutput=function(e,t="CHART"){return[`[${t}: ${e||"Unknown"}]`]}},175:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getOrdinal=function(e){const t=["th","st","nd","rd"],n=e%100;return e+(t[(n-20)%10]||t[n]||t[0])},t.getSign=a,t.getHouse=i,t.getPlanetPositions=function(e,t){return e.map((e=>{const n=(e.degree%360+360)%360;const r={name:e.name,degree:n,sign:a(n),speed:e.speed};return t&&(r.house=i(n,t)),r}))};const r=n(921);function a(e){const t=Math.floor(e/30);return r.ZODIAC_SIGNS[t]}function i(e,t){for(let n=0;n<12;n++){const r=t[n],a=t[(n+1)%12];if(r<a){if(e>=r&&e<a)return n+1}else if(e>=r||e<a)return n+1}return-1}},230:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ChartSettings=void 0;const r=n(921);t.ChartSettings=class{constructor(e={}){const t={...r.DEFAULT_SETTINGS,...e};Object.assign(this,t)}get resolvedAspectDefinitions(){if(Array.isArray(this.aspectDefinitions))return this.aspectDefinitions;switch(this.aspectDefinitions){case"traditional":return r.SIMPLE_TRADITIONAL_ORBS;case"modern":return r.SIMPLE_MODERN_ORBS;case"tight":return r.SIMPLE_TIGHT_ORBS;case"wide":return r.SIMPLE_WIDE_ORBS;default:return r.DEFAULT_SETTINGS.aspectDefinitions}}}},234:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generatePlanetsOutput=function(e){const t=["[PLANETS]"];e.forEach((e=>{const n=(0,a.formatPlanetWithDignities)(e),i=e.speed&&e.speed<0?" Retrograde":"";let s=`${e.name}: ${Math.floor(e.degree%30)}° ${e.sign}${i} ${n}`;e.house&&(s+=`, ${(0,r.getOrdinal)(e.house)} house`),t.push(s.replace(/\s+/g," ").trim())})),0===e.length&&t.push("No planets listed.");return t};const r=n(175),a=n(400)},318:(e,t)=>{function n(e,n,r=t.DEFAULT_EPSILON){return Math.abs(e-n)<r}function r(e,n=t.DEFAULT_EPSILON){return Math.abs(e)<n}function a(e,r,a=t.DEFAULT_EPSILON){return n(e,r,a)}Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_EPSILON=void 0,t.floatEquals=n,t.isNearZero=r,t.roundDegrees=function(e){return Math.round(1e4*e)/1e4},t.degreeEquals=a,t.isOnCusp=function(e,t,n=.001){return a(e,t,n)},t.isExactAspect=function(e,t=.1){return r(e,t)},t.DEFAULT_EPSILON=1e-4},371:(e,t)=>{function n(e){return e&&"object"==typeof e?"string"!=typeof e.name||""===e.name.trim()?"Point name must be a non-empty string":"number"==typeof e.degree&&isFinite(e.degree)?void 0===e.speed||"number"==typeof e.speed&&isFinite(e.speed)?null:`Point ${e.name} has invalid speed value: ${e.speed}`:`Point ${e.name} has invalid degree value: ${e.degree}`:"Point must be an object"}function r(e){if(!Array.isArray(e))return"Points must be an array";for(let t=0;t<e.length;t++){const r=n(e[t]);if(r)return`Point at index ${t}: ${r}`}const t=e.map((e=>e.name)),r=t.filter(((e,n)=>t.indexOf(e)!==n));return r.length>0?`Duplicate point names found: ${r.join(", ")}`:null}function a(e){if(void 0===e)return null;if(!Array.isArray(e))return"House cusps must be an array";if(12!==e.length)return`House cusps must contain exactly 12 values, got ${e.length}`;for(let t=0;t<e.length;t++)if("number"!=typeof e[t]||!isFinite(e[t]))return`House cusp ${t+1} has invalid value: ${e[t]}`;return null}function i(e){if(!e||"object"!=typeof e)return"Chart data must be an object";if("string"!=typeof e.name||""===e.name.trim())return"Chart name must be a non-empty string";const t=r(e.planets);if(t)return`Planets validation failed: ${t}`;if(void 0!==e.ascendant&&("number"!=typeof e.ascendant||!isFinite(e.ascendant)))return`Ascendant has invalid value: ${e.ascendant}`;if(void 0!==e.midheaven&&("number"!=typeof e.midheaven||!isFinite(e.midheaven)))return`Midheaven has invalid value: ${e.midheaven}`;const n=a(e.houseCusps);if(n)return`House cusps validation failed: ${n}`;if(void 0!==e.points){const t=r(e.points);if(t)return`Additional points validation failed: ${t}`}if(void 0!==e.timestamp&&(!(e.timestamp instanceof Date)||isNaN(e.timestamp.getTime())))return"Timestamp must be a valid Date object";if(void 0!==e.location&&"string"!=typeof e.location)return"Location must be a string";if(void 0!==e.chartType){const t=["natal","event","transit"];if(!t.includes(e.chartType))return`Chart type must be one of: ${t.join(", ")}`}return null}function s(e){if(!Array.isArray(e))return"Multi-chart data must be an array";if(0===e.length)return"Multi-chart data must contain at least one chart";if(e.length>10)return"Multi-chart data cannot contain more than 10 charts";for(let t=0;t<e.length;t++){const n=i(e[t]);if(n)return`Chart at index ${t} (${e[t]?.name||"unnamed"}): ${n}`}const t=e.map((e=>e.name)),n=t.filter(((e,n)=>t.indexOf(e)!==n));if(n.length>0)return`Duplicate chart names found: ${n.join(", ")}`;return e.filter((e=>"transit"===e.chartType)).length>1?"Cannot have more than one transit chart":null}Object.defineProperty(t,"__esModule",{value:!0}),t.validatePoint=n,t.validatePoints=r,t.validateHouseCusps=a,t.validateChartData=i,t.validateMultiChartData=s,t.validateInputData=function(e){if(!e)return"Data is required";return Array.isArray(e)?s(e):i(e)}},388:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.determineChartType=function(e){let t="natal",n="";const r=e.filter((({chartType:e})=>"transit"!==e&&"event"!==e)),a=e.filter((({chartType:e})=>"event"===e)),i=e.filter((({chartType:e})=>"transit"===e));if(i.length>1)throw new Error("Must provide at most one transit chart");const s=i.length>0;r.length>0?0===a.length?s&&(n="_with_transit"):n=1===a.length?s?"_with_event_and_transit":"_with_event":s?"_with_events_and_transit":"_with_events":s&&(n="_with_transit");if(0===r.length){if(0===a.length)throw new Error("Must provide at least one non-transit chart");t=1===a.length?"event":"multi_event"}else t=1===r.length?"natal":2===r.length?"synastry":"group_synastry";return t+n},t.generateMetadataOutput=function(e,t,n){const r=["[METADATA]",`chart_type: ${t}`];n&&r.push(`house_system: ${n}`);return r.push(`date_format: ${e.dateFormat}`),r}},390:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.detectStelliums=function(e,t,n=3){const i=[],o=new Map;if(e.forEach((e=>{const t=(0,r.getDegreeSign)(e.degree);o.has(t)||o.set(t,[]),o.get(t).push(e)})),o.forEach(((e,r)=>{if(e.length>=n){const n=e.map((e=>s(e,t))),a=n.map((e=>e.house)).filter((e=>void 0!==e)),o=e.map((e=>e.degree)),u=Math.max(...o)-Math.min(...o);i.push({type:"Stellium",planets:n,sign:r,houses:[...new Set(a)].sort(),span:u})}})),t){const r=new Map;e.forEach((e=>{const n=(0,a.getHouseForPoint)(e.degree,t);n&&(r.has(n)||r.set(n,[]),r.get(n).push(e))})),r.forEach(((e,r)=>{if(e.length>=n){const n=e.map((e=>s(e,t))),a=e.map((e=>e.degree)),o=Math.max(...a)-Math.min(...a);i.find((e=>"Stellium"===e.type&&e.planets.some((e=>n.some((t=>t.name===e.name))))))||i.push({type:"Stellium",planets:n,houses:[r],span:o})}}))}return i},t.formatStellium=function(e){const t=e.planets.map((e=>e.name)).join(", ");let n="";e.sign&&(n=e.sign);if(e.houses&&e.houses.length>0){const t=1===e.houses.length?`${(0,i.getOrdinal)(e.houses[0])} House`:e.houses.map((e=>`${(0,i.getOrdinal)(e)} House`)).join("-");n+=n?` (${t})`:t}const r=n?` in ${n}`:"";return[`Stellium (${e.span.toFixed(1)}°): ${t}${r}`]};const r=n(904),a=n(600),i=n(175);function s(e,t){const n=(0,r.getDegreeSign)(e.degree),i=t&&(0,a.getHouseForPoint)(e.degree,t)||void 0;return{name:e.name,degree:e.degree,sign:n,house:i}}},400:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.formatPlanetWithDignities=function(e){const t=e.sign,n=a[e.name],i=r.ZODIAC_SIGN_DATA.find((e=>e.name===t))?.ruler,s=[];n&&n[t]&&s.push(...n[t]);let o=s.join(", ");i&&e.name!==i&&(o?o+=` | Ruler: ${i}`:o=`Ruler: ${i}`);if(o)return`[${o}]`;return""};const r=n(921),a={Sun:{Leo:["Domicile"],Aries:["Exaltation"],Aquarius:["Detriment"],Libra:["Fall"]},Moon:{Cancer:["Domicile"],Taurus:["Exaltation"],Capricorn:["Detriment"],Scorpio:["Fall"]},Mercury:{Gemini:["Domicile"],Virgo:["Domicile","Exaltation"],Pisces:["Detriment","Fall"],Sagittarius:["Detriment"]},Venus:{Taurus:["Domicile"],Libra:["Domicile"],Scorpio:["Detriment"],Aries:["Fall"],Virgo:["Fall"]},Mars:{Aries:["Domicile"],Scorpio:["Domicile"],Libra:["Detriment"],Cancer:["Fall"]},Jupiter:{Sagittarius:["Domicile"],Pisces:["Domicile"],Gemini:["Detriment"],Virgo:["Fall"]},Saturn:{Capricorn:["Domicile"],Aquarius:["Domicile"],Cancer:["Detriment"],Leo:["Fall"]}}},600:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.calculateHouseOverlays=function(e,t){const n={};if(t.houseCusps)for(const a of e.planets)n[a.name]=(0,r.getHouse)(a.degree,t.houseCusps);const a={};if(e.houseCusps)for(const n of t.planets)a[n.name]=(0,r.getHouse)(n.degree,e.houseCusps);return{chart1InChart2Houses:n,chart2InChart1Houses:a}},t.getHouseForPoint=function(e,t){return(0,r.getHouse)(e,t)};const r=n(175)},613:(e,t)=>{var n,r;Object.defineProperty(t,"__esModule",{value:!0}),t.PlanetCategory=t.AspectClassification=void 0,t.isMultiChartData=function(e){return Array.isArray(e)},function(e){e.Major="major",e.Minor="minor",e.Esoteric="esoteric"}(n||(t.AspectClassification=n={})),function(e){e.Luminaries="luminaries",e.Personal="personal",e.Social="social",e.Outer="outer",e.Angles="angles"}(r||(t.PlanetCategory=r={}))},666:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.chart2txt=function(e,t={}){const n=(0,r.analyzeCharts)(e,t),s=n.settings;return n.chartAnalyses.forEach((e=>{e.groupedAspects=(0,a.groupAspects)(e.aspects,s)})),n.pairwiseAnalyses.forEach((e=>{e.groupedSynastryAspects=(0,a.groupAspects)(e.synastryAspects,s)})),n.transitAnalyses.forEach((e=>{e.groupedAspects=(0,a.groupAspects)(e.aspects,s)})),(0,i.formatReportToText)(n)};const r=n(6),a=n(865),i=n(723)},668:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateHousesOutput=function(e){const t=["[HOUSE CUSPS]"];if(!e||12!==e.length)return t.push("House cusps not available"),t;for(let n=0;n<6;n++){const i=n,s=n+6,o=e[i],u=e[s],c=(0,r.getDegreeSign)(o),l=Math.floor((0,r.getDegreeInSign)(o)),p=(0,a.getOrdinal)(i+1)+" house",f=(0,r.getDegreeSign)(u),h=Math.floor((0,r.getDegreeInSign)(u)),d=(0,a.getOrdinal)(s+1)+" house",g=`${p}: ${l}° ${c}`.padEnd(24),m=`${d}: ${h}° ${f}`;t.push(`${g} ${m}`)}return t};const r=n(904),a=n(175)},723:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.formatReportToText=function(e){const{chartAnalyses:t,pairwiseAnalyses:n,globalAnalysis:s,transitAnalyses:o,globalTransitAnalysis:c}=e,f=e.settings,h=[],d=t.map((e=>e.chart)),S=(0,r.determineChartType)(d);h.push(...(0,r.generateMetadataOutput)(f,S,f.houseSystemName)),h.push("");const b=t.filter((e=>"transit"!==e.chart.chartType));for(const e of b)h.push(...g(e,f));for(const e of n)h.push(...m(e,f));s&&h.push(...A(s,!1));if(o.length>0){const e=t.find((e=>"transit"===e.chart.chartType));e&&(h.push(...(0,a.generateChartHeaderOutput)(e.chart.name,"TRANSIT")),h.push(...(0,i.generateBirthdataOutput)(e.chart.location,e.chart.timestamp,f,"[DATETIME]")),h.push(...(0,u.generatePlanetsOutput)(e.placements.planets)),h.push(""));for(const e of o)h.push(...(0,l.generateAspectsOutput)(`[TRANSIT ASPECTS: ${e.natalChart.name}]`,e.groupedAspects,e.natalChart.name,e.transitChart.name,!0)),f.includeAspectPatterns&&h.push(...(0,p.generateAspectPatternsOutput)(e.patterns,`Transit to ${e.natalChart.name}`,!0)),h.push("")}c&&h.push(...A(c,!0));return h.join("\n").trimEnd()};const r=n(388),a=n(172),i=n(888),s=n(945),o=n(668),u=n(234),c=n(82),l=n(784),p=n(762),f=n(756),h=n(109),d=n(390),g=(e,t,n)=>{const r=[],{chart:f,groupedAspects:g,patterns:m,stelliums:A,signDistributions:S,dispositors:b,placements:y}=e;return r.push(...(0,a.generateChartHeaderOutput)(f.name,n)),r.push(...(0,i.generateBirthdataOutput)(f.location,f.timestamp,t)),r.push(...(0,s.generateAnglesOutput)(f.ascendant,f.midheaven)),r.push(...(0,o.generateHousesOutput)(f.houseCusps)),r.push(...(0,u.generatePlanetsOutput)(y.planets)),t.includeDispositors&&r.push(...(0,c.generateDispositorsOutput)(b)),t.includeSignDistributions&&(r.push(...(0,h.generateElementDistributionOutput)(S.elements)),r.push(...(0,h.generateModalityDistributionOutput)(S.modalities)),r.push(...(0,h.generatePolarityOutput)(S.polarities))),r.push(...(0,l.generateAspectsOutput)("[ASPECTS]",g)),t.includeAspectPatterns&&(r.push(...(0,p.generateAspectPatternsOutput)(m,void 0,!1)),A.length>0?A.forEach((e=>{r.push(...(0,d.formatStellium)(e))})):r.push("No Stelliums detected.")),r.push(""),r},m=(e,t)=>{const n=[],{chart1:r,chart2:i,groupedSynastryAspects:s,compositePatterns:o,houseOverlays:u}=e,c="event"===r.chartType&&"event"===i.chartType?"EVENT_RELATIONSHIP":"event"===r.chartType||"event"===i.chartType?"NATAL_EVENT":"SYNASTRY";return n.push(...(0,a.generateChartHeaderOutput)(`${r.name}-${i.name}`,c)),n.push(...(0,l.generateAspectsOutput)("[PLANET-PLANET ASPECTS]",s,r.name,i.name)),t.includeAspectPatterns&&o.length>0&&n.push(...(0,p.generateAspectPatternsOutput)(o,`${r.name}-${i.name} Composite`,!0)),n.push(""),t.includeHouseOverlays&&(n.push(...(0,f.generateHouseOverlaysOutput)(u,r.name,i.name)),n.push("")),n},A=(e,t=!1)=>{const n=[],{charts:r,patterns:a}=e;if(a.length>0){const e=r.map((e=>e.name)).join("-");let i=`${e} Global Composite`;t&&(i=`${e} Global Transit Composite`),n.push(...(0,p.generateAspectPatternsOutput)(a,i,!0)),n.push("")}return n}},729:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.calculateDispositors=function(e,t=!0){if(!1===t)return{};const n={};e.forEach((e=>{n[e.name]=function(e){const t=(0,a.getSign)(e.degree),n=r.ZODIAC_SIGN_DATA.find((e=>e.name===t));return n?n.ruler:"Unknown"}(e)}));const i={};if(e.forEach((e=>{i[e.name]||function(e,t,n){if(n[e])return n[e];const r=[e];let a=e;for(;;){const i=t[a];if(!i||!t.hasOwnProperty(i)){const t={path:[...r,i],isCycle:!1,isFinal:!1,isBroken:!0};return n[e]=t}if(i===a){const t={path:r,isCycle:!1,isFinal:!0,isBroken:!1};return n[e]=t}if(r.includes(i)){const e=r.indexOf(i),t=r.slice(e),a={path:[...r,i],isCycle:!0,isFinal:!1,isBroken:!1};return t.forEach((e=>{n[e]=a})),a}if(n[i]){const t=n[i],a=[...r,...t.path],s={...t,path:a};return n[e]=s}r.push(i),a=i}}(e.name,n,i)})),"finals"===t){const t=new Set,r=new Map;e.forEach((e=>{n[e.name]===e.name&&t.add(e.name)}));for(const e in i){const t=i[e];if(t.isCycle){const e=t.path[t.path.length-1],n=t.path.indexOf(e),a=t.path.slice(n,-1),i=[...new Set(a)].sort().join("|");r.has(i)||r.set(i,a)}}const a=[];if(t.size>0&&a.push(`Final dispositors: ${[...t].sort().join(", ")}`),r.size>0){const e=[...r.values()].map((e=>{const t=[...new Set(e)].sort()[0],n=e.indexOf(t);return[...[...e.slice(n),...e.slice(0,n)],t].join(" → ")})).sort();a.push(`Cycles: ${e.join(", ")}`)}return 0===a.length?{summary:"No final dispositors or cycles found"}:{summary:a.join("; ")}}const s={};return e.forEach((e=>{const t=e.name,r=[t];let a=t;for(;;){const e=n[a];if(!e||!n.hasOwnProperty(e)){s[t]=`${r.join(" → ")} → ${e} (not in chart)`;break}if(e===a){s[t]=`${r.join(" → ")} → (final)`;break}if(r.includes(e)){s[t]=`${r.join(" → ")} → ${e} (cycle)`;break}r.push(e),a=e}})),s};const r=n(921),a=n(175)},756:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateHouseOverlaysOutput=function(e,t,n){const r=["[HOUSE OVERLAYS]"];r.push(`${t}'s planets in ${n}'s houses:`),Object.keys(e.chart1InChart2Houses).length>0?r.push(a(e.chart1InChart2Houses)):r.push(`(${n} house cusps not available)`);r.push(`${n}'s planets in ${t}'s houses:`),Object.keys(e.chart2InChart1Houses).length>0?r.push(a(e.chart2InChart1Houses)):r.push(`(${t} house cusps not available)`);return r};const r=n(175);function a(e){const t={};for(const n in e){const r=e[n];t[r]||(t[r]=[]),t[r].push(n)}return Object.keys(t).map(Number).sort(((e,t)=>e-t)).map((e=>{const n=t[e].join(", ");return`${(0,r.getOrdinal)(e)}: ${n}`})).join(" | ")}},762:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateAspectPatternsOutput=function(e,t,n=!0){const r=[t?`[ASPECT PATTERNS: ${t}]`:"[ASPECT PATTERNS]"];if(0===e.length)return r.push("No T-Squares detected."),r.push("No Grand Trines detected."),r;const a=e.filter((t=>"Grand Trine"!==t.type||!function(e,t){return"Grand Trine"===e.type&&t.some((t=>{if("Kite"!==t.type)return!1;const n=e=>`${e.chartName||""}-${e.name}-${e.degree}`,r=t.grandTrine.map(n),a=e.planets.map(n);return r.length===a.length&&r.every((e=>a.includes(e)))}))}(t,e))),s=["T-Square","Grand Trine","Grand Cross","Yod","Mystic Rectangle","Kite"];a.sort(((e,t)=>s.indexOf(e.type)-s.indexOf(t.type))).forEach((e=>{switch(e.type){case"T-Square":r.push(...function(e,t=!0){if("T-Square"!==e.type)return[];const n=i(e.apex,!1,t),r=i(e.opposition[0],!1,t),a=i(e.opposition[1],!1,t);return[`T-Square (${e.mode}, ${e.averageOrb.toFixed(1)}°): ${n} ← ${r} ↔ ${a}`]}(e,n));break;case"Grand Trine":r.push(...function(e,t=!0){if("Grand Trine"!==e.type)return[];const n=e.planets.map((e=>i(e,!1,t))).join(" △ ");return[`Grand Trine (${e.element}, ${e.averageOrb.toFixed(1)}°): ${n}`]}(e,n));break;case"Grand Cross":r.push(...function(e,t=!0){if("Grand Cross"!==e.type)return[];const n=e.planets.map((e=>i(e,!1,t))).join(" ⨯ ");return[`Grand Cross (${e.mode}, ${e.averageOrb.toFixed(1)}°): ${n}`]}(e,n));break;case"Yod":r.push(...function(e,t=!0){if("Yod"!==e.type)return[];const n=i(e.apex,!1,t),r=i(e.base[0],!1,t),a=i(e.base[1],!1,t);return[`Yod (${e.averageOrb.toFixed(1)}°): ${n} ← ${r} • ${a}`]}(e,n));break;case"Mystic Rectangle":r.push(...function(e,t=!0){if("Mystic Rectangle"!==e.type)return[];const n=i(e.oppositions[0][0],!1,t),r=i(e.oppositions[0][1],!1,t),a=i(e.oppositions[1][0],!1,t),s=i(e.oppositions[1][1],!1,t);return[`Mystic Rectangle (${e.averageOrb.toFixed(1)}°): ${n} ↔ ${r} | ${a} ↔ ${s}`]}(e,n));break;case"Kite":r.push(...function(e,t=!0){if("Kite"!==e.type)return[];const n=e.grandTrine.map((e=>i(e,!1,t))).join(" △ "),r=i(e.opposition,!1,t),a=e.grandTrine[0].sign?function(e){const t=["Taurus","Virgo","Capricorn"],n=["Gemini","Libra","Aquarius"],r=["Cancer","Scorpio","Pisces"];return["Aries","Leo","Sagittarius"].includes(e)?"Fire":t.includes(e)?"Earth":n.includes(e)?"Air":r.includes(e)?"Water":""}(e.grandTrine[0].sign):"";return[`Kite (${a?`${a}, `:""}${e.averageOrb.toFixed(1)}°): [${n}] ← ${r}`]}(e,n))}})),""===r[r.length-1]&&r.pop();return r};const r=n(904),a=n(175);function i(e,t=!1,n=!0){const i=Math.floor((0,r.getDegreeInSign)(e.degree)),s=t&&e.house?` (${(0,a.getOrdinal)(e.house)} house)`:"";return`${n&&e.chartName?`${e.chartName}'s `:""}${e.name} ${i}° ${e.sign}${s}`}},784:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateAspectsOutput=function(e,t,n,r,a=!1){const i=[e];if(!t||0===t.size)return i.push("None"),i;return t.forEach(((e,t)=>{i.push(t),e.forEach((e=>{i.push(function(e,t,n,r=!1){const a=t?`${t}'s ${e.planetA}`:e.planetA;let i=e.planetB;r?i=`transiting ${e.planetB}`:n&&(i=`${n}'s ${e.planetB}`);const s=e.application&&"exact"!==e.application?` (${e.application})`:"";return`${a} ${e.aspectType} ${i}: ${e.orb.toFixed(1)}°${s}`}(e,n,r,a))}))})),i}},858:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.calculateSignDistributions=function(e,t){const n=[...e];void 0!==t&&n.push({name:"Ascendant",degree:t});const i={Fire:[],Earth:[],Air:[],Water:[]},s={Cardinal:0,Fixed:0,Mutable:0},o={Masculine:0,Feminine:0};for(const e of n){const t=(0,r.getSign)(e.degree),n=a.ZODIAC_SIGN_DATA.find((e=>e.name===t));n&&(i[n.element].push(e.name),s[n.modality]++,o[n.polarity]++)}return{elements:i,modalities:s,polarities:o}},t.formatElementDistribution=function(e){return[Object.entries(e).map((([e,t])=>0===t.length?`${e}: 0`:`${e}: ${t.length} (${t.join(", ")})`)).join(" | ")]},t.formatModalityDistribution=function(e){return[Object.entries(e).map((([e,t])=>`${e}: ${t}`)).join(" | ")]},t.formatPolarityDistribution=function(e){return[Object.entries(e).map((([e,t])=>`${e}: ${t}`)).join(" | ")]};const r=n(175),a=n(921)},865:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.groupAspects=function(e,t){const n=new Map,r=t.aspectStrengthThresholds,a=[],i=[],s=[];if(e.forEach((e=>{e.orb<=r.tight?a.push(e):e.orb<=r.moderate?i.push(e):s.push(e)})),a.sort(((e,t)=>e.orb-t.orb)),i.sort(((e,t)=>e.orb-t.orb)),s.sort(((e,t)=>e.orb-t.orb)),a.length>0){const e=`[TIGHT ASPECTS: orb under ${r.tight.toFixed(1)}°]`;n.set(e,a)}if(i.length>0){const e=`[MODERATE ASPECTS: orb ${r.tight.toFixed(1)}-${r.moderate.toFixed(1)}°]`;n.set(e,i)}if(s.length>0){const e=`[WIDE ASPECTS: orb over ${r.moderate.toFixed(1)}°]`;n.set(e,s)}return n}},888:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateBirthdataOutput=function(e,t,n,a="[BIRTHDATA]"){if(!t)return[`${a} Not available`];const i=(0,r.formatDateCustom)(t,n.dateFormat),s=(0,r.formatTime)(t);return[`${a} ${e||"Unknown Location"} | ${i} | ${s}`]};const r=n(889)},889:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.formatDateCustom=function(e,t){const n=e.getMonth()+1,r=e.getDate(),a=e.getFullYear();switch(t.toUpperCase()){case"MM/DD/YYYY":return`${n.toString().padStart(2,"0")}/${r.toString().padStart(2,"0")}/${a}`;case"DD/MM/YYYY":return`${r.toString().padStart(2,"0")}/${n.toString().padStart(2,"0")}/${a}`;case"YYYY-MM-DD":return`${a}-${n.toString().padStart(2,"0")}-${r.toString().padStart(2,"0")}`;default:return console.warn(`Unrecognized date format: ${t}. Falling back to toLocaleDateString().`),e.toLocaleDateString()}},t.formatTime=function(e){return e.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!0})}},904:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.normalizeDegree=a,t.getDegreeSign=function(e){const t=a(e),n=Math.floor(t/30);if(n<0||n>=r.ZODIAC_SIGNS.length)return console.error(`Invalid sign index computed: ${n} for normalized degree ${t}`),"Unknown Sign";return r.ZODIAC_SIGNS[n]},t.getDegreeInSign=function(e){return a(e)%30};const r=n(921);function a(e){if(!isFinite(e))throw new Error(`Invalid degree value: ${e}`);let t=e%360;return t<0&&(t+=360),t}},919:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.detectAspectPatterns=function(e,t,n){const r=[],l=function(e){const t=new Map;return e.forEach((e=>{const n=a(e.planetA,e.p1ChartName),r=a(e.planetB,e.p2ChartName);t.has(n)||t.set(n,new Map),t.has(r)||t.set(r,new Map),t.get(n).set(r,e),t.get(r).set(n,e)})),t}(t);return r.push(...function(e,t,n){const r=[];for(let a=0;a<e.length;a++)for(let c=a+1;c<e.length;c++)if(o(e[a],e[c],"opposition",t))for(let l=0;l<e.length;l++)if(l!==a&&l!==c&&o(e[a],e[l],"square",t)&&o(e[c],e[l],"square",t)){const[o,p]=e[l],[f,h]=e[a],[d,g]=e[c],m=i(o,n,p),A=i(f,n,h),S=i(d,n,g),b=u(e[a],e[c],t),y=u(e[a],e[l],t),T=u(e[c],e[l],t),O=(b.orb+y.orb+T.orb)/3,M=s(m.sign);r.push({type:"T-Square",apex:m,opposition:[A,S],mode:M,averageOrb:O})}return r}(e,l,n)),r.push(...c(e,l,n)),r.push(...function(e,t,n){const r=[];for(let a=0;a<e.length;a++)for(let c=a+1;c<e.length;c++)for(let l=c+1;l<e.length;l++)for(let p=l+1;p<e.length;p++){const f=[e[a],e[c],e[l],e[p]],h=[[0,2],[1,3],[0,3],[1,2]];let d=0,g=0;const m=[];if([[0,1],[2,3]].forEach((([e,n])=>{o(f[e],f[n],"opposition",t)&&(d++,m.push(u(f[e],f[n],t)))})),h.forEach((([e,n])=>{o(f[e],f[n],"square",t)&&(g++,m.push(u(f[e],f[n],t)))})),2===d&&4===g){const[e,t]=f[0],[a,o]=f[1],[u,c]=f[2],[l,p]=f[3],h=i(e,n,t),d=i(a,n,o),g=i(u,n,c),A=i(l,n,p),S=m.reduce(((e,t)=>e+t.orb),0)/m.length,b=s(h.sign);r.push({type:"Grand Cross",planets:[h,d,g,A],mode:b,averageOrb:S})}}return r}(e,l,n)),r.push(...function(e,t,n){const r=[];for(let a=0;a<e.length;a++)for(let s=a+1;s<e.length;s++)if(o(e[a],e[s],"sextile",t))for(let c=0;c<e.length;c++)if(c!==a&&c!==s&&o(e[a],e[c],"quincunx",t)&&o(e[s],e[c],"quincunx",t)){const[o,l]=e[c],[p,f]=e[a],[h,d]=e[s],g=i(o,n,l),m=i(p,n,f),A=i(h,n,d),S=u(e[a],e[s],t),b=u(e[a],e[c],t),y=u(e[s],e[c],t),T=(S.orb+b.orb+y.orb)/3;r.push({type:"Yod",apex:g,base:[m,A],averageOrb:T})}return r}(e,l,n)),r.push(...function(e,t,n){const r=[];for(let a=0;a<e.length;a++)for(let s=a+1;s<e.length;s++)for(let c=s+1;c<e.length;c++)for(let l=c+1;l<e.length;l++){const p=[e[a],e[s],e[c],e[l]],f=[{oppositions:[[0,1],[2,3]],sextiles:[[0,2],[0,3],[1,2],[1,3]]},{oppositions:[[0,2],[1,3]],sextiles:[[0,1],[0,3],[2,1],[2,3]]},{oppositions:[[0,3],[1,2]],sextiles:[[0,1],[0,2],[3,1],[3,2]]}];for(const e of f){let a=0,s=0;const c=[];if(e.oppositions.forEach((([e,n])=>{o(p[e],p[n],"opposition",t)&&(a++,c.push(u(p[e],p[n],t)))})),e.sextiles.forEach((([e,n])=>{const r=u(p[e],p[n],t);!r||"sextile"!==r.aspectType&&"trine"!==r.aspectType||(s++,c.push(r))})),2===a&&4===s){const[t,a]=p[e.oppositions[0][0]],[s,o]=p[e.oppositions[0][1]],[u,l]=p[e.oppositions[1][0]],[f,h]=p[e.oppositions[1][1]],d=i(t,n,a),g=i(s,n,o),m=i(u,n,l),A=i(f,n,h),S=c.reduce(((e,t)=>e+t.orb),0)/c.length;r.push({type:"Mystic Rectangle",oppositions:[[d,g],[m,A]],averageOrb:S})}}}return r}(e,l,n)),r.push(...function(e,t,n){const r=[];return c(e,t,n).forEach((a=>{a.planets.forEach((s=>{e.forEach((c=>{const[l,p]=c;if(!a.planets.some((e=>e.name===l.name&&e.chartName===p))){const f=e.find((([e,t])=>e.name===s.name&&t===s.chartName));if(f&&o(f,c,"opposition",t)){const e=i(l,n,p),s=u(f,c,t),o=(a.averageOrb+s.orb)/2;r.push({type:"Kite",grandTrine:a.planets,opposition:e,averageOrb:o})}}}))}))})),r}(e,l,n)),r};const r=n(904);function a(e,t){return t?`${e}-${t}`:e}function i(e,t,n){const a=(0,r.getDegreeSign)(e.degree),i=t&&12===t.length?(()=>{const n=e.degree%360;for(let e=0;e<12;e++){const r=t[e],a=t[(e+1)%12];if(a>r){if(n>=r&&n<a)return e+1}else if(n>=r||n<a)return e+1}})():void 0;return{name:e.name,degree:e.degree,sign:a,house:i,chartName:n}}function s(e){return["Aries","Cancer","Libra","Capricorn"].includes(e)?"Cardinal":["Taurus","Leo","Scorpio","Aquarius"].includes(e)?"Fixed":"Mutable"}function o(e,t,n,r){const i=a(e[0].name,e[1]),s=a(t[0].name,t[1]),o=r.get(i);if(!o)return!1;const u=o.get(s);return void 0!==u&&u.aspectType===n}function u(e,t,n){const r=a(e[0].name,e[1]),i=a(t[0].name,t[1]),s=n.get(r);if(s)return s.get(i)}function c(e,t,n){const r=[];for(let s=0;s<e.length;s++)for(let c=s+1;c<e.length;c++)for(let l=c+1;l<e.length;l++)if(o(e[s],e[c],"trine",t)&&o(e[c],e[l],"trine",t)&&o(e[l],e[s],"trine",t)){const[o,p]=e[s],[f,h]=e[c],[d,g]=e[l],m=i(o,n,p),A=i(f,n,h),S=i(d,n,g),b=u(e[s],e[c],t),y=u(e[c],e[l],t),T=u(e[l],e[s],t),O=(b.orb+y.orb+T.orb)/3,M=(a=m.sign,["Aries","Leo","Sagittarius"].includes(a)?"Fire":["Taurus","Virgo","Capricorn"].includes(a)?"Earth":["Gemini","Libra","Aquarius"].includes(a)?"Air":"Water");r.push({type:"Grand Trine",planets:[m,A,S],element:M,averageOrb:O})}var a;return r}},921:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_SETTINGS=t.DEFAULT_ASPECT_STRENGTH_THRESHOLDS=t.WIDE_ASPECTS=t.TIGHT_ASPECTS=t.MODERN_ASPECTS=t.TRADITIONAL_ASPECTS=t.SIMPLE_WIDE_ORBS=t.SIMPLE_TIGHT_ORBS=t.SIMPLE_MODERN_ORBS=t.SIMPLE_TRADITIONAL_ORBS=t.DEFAULT_ASPECTS=t.ZODIAC_SIGNS=t.ZODIAC_SIGN_DATA=void 0;const r=n(613);t.ZODIAC_SIGN_DATA=[{name:"Aries",element:"Fire",modality:"Cardinal",polarity:"Masculine",ruler:"Mars"},{name:"Taurus",element:"Earth",modality:"Fixed",polarity:"Feminine",ruler:"Venus"},{name:"Gemini",element:"Air",modality:"Mutable",polarity:"Masculine",ruler:"Mercury"},{name:"Cancer",element:"Water",modality:"Cardinal",polarity:"Feminine",ruler:"Moon"},{name:"Leo",element:"Fire",modality:"Fixed",polarity:"Masculine",ruler:"Sun"},{name:"Virgo",element:"Earth",modality:"Mutable",polarity:"Feminine",ruler:"Mercury"},{name:"Libra",element:"Air",modality:"Fixed",polarity:"Masculine",ruler:"Venus"},{name:"Scorpio",element:"Water",modality:"Fixed",polarity:"Feminine",ruler:"Mars"},{name:"Sagittarius",element:"Fire",modality:"Mutable",polarity:"Masculine",ruler:"Jupiter"},{name:"Capricorn",element:"Earth",modality:"Cardinal",polarity:"Feminine",ruler:"Saturn"},{name:"Aquarius",element:"Air",modality:"Fixed",polarity:"Masculine",ruler:"Saturn"},{name:"Pisces",element:"Water",modality:"Mutable",polarity:"Feminine",ruler:"Jupiter"}],t.ZODIAC_SIGNS=t.ZODIAC_SIGN_DATA.map((e=>e.name)),t.DEFAULT_ASPECTS=[{name:"conjunction",angle:0,orb:5,classification:r.AspectClassification.Major},{name:"opposition",angle:180,orb:5,classification:r.AspectClassification.Major},{name:"trine",angle:120,orb:5,classification:r.AspectClassification.Major},{name:"square",angle:90,orb:5,classification:r.AspectClassification.Major},{name:"sextile",angle:60,orb:3,classification:r.AspectClassification.Minor},{name:"quincunx",angle:150,orb:2,classification:r.AspectClassification.Minor}],t.SIMPLE_TRADITIONAL_ORBS=[{name:"conjunction",angle:0,orb:10,classification:r.AspectClassification.Major},{name:"opposition",angle:180,orb:10,classification:r.AspectClassification.Major},{name:"trine",angle:120,orb:8,classification:r.AspectClassification.Major},{name:"square",angle:90,orb:8,classification:r.AspectClassification.Major},{name:"sextile",angle:60,orb:6,classification:r.AspectClassification.Minor},{name:"quincunx",angle:150,orb:4,classification:r.AspectClassification.Minor}],t.SIMPLE_MODERN_ORBS=[{name:"conjunction",angle:0,orb:8,classification:r.AspectClassification.Major},{name:"opposition",angle:180,orb:8,classification:r.AspectClassification.Major},{name:"trine",angle:120,orb:6,classification:r.AspectClassification.Major},{name:"square",angle:90,orb:6,classification:r.AspectClassification.Major},{name:"sextile",angle:60,orb:4,classification:r.AspectClassification.Minor},{name:"quincunx",angle:150,orb:3,classification:r.AspectClassification.Minor}],t.SIMPLE_TIGHT_ORBS=[{name:"conjunction",angle:0,orb:4,classification:r.AspectClassification.Major},{name:"opposition",angle:180,orb:4,classification:r.AspectClassification.Major},{name:"trine",angle:120,orb:3,classification:r.AspectClassification.Major},{name:"square",angle:90,orb:3,classification:r.AspectClassification.Major},{name:"sextile",angle:60,orb:2,classification:r.AspectClassification.Minor},{name:"quincunx",angle:150,orb:1,classification:r.AspectClassification.Minor}],t.SIMPLE_WIDE_ORBS=[{name:"conjunction",angle:0,orb:12,classification:r.AspectClassification.Major},{name:"opposition",angle:180,orb:12,classification:r.AspectClassification.Major},{name:"trine",angle:120,orb:10,classification:r.AspectClassification.Major},{name:"square",angle:90,orb:10,classification:r.AspectClassification.Major},{name:"sextile",angle:60,orb:8,classification:r.AspectClassification.Minor},{name:"quincunx",angle:150,orb:6,classification:r.AspectClassification.Minor},{name:"semi-sextile",angle:30,orb:4,classification:r.AspectClassification.Minor}],t.TRADITIONAL_ASPECTS=t.SIMPLE_TRADITIONAL_ORBS,t.MODERN_ASPECTS=t.SIMPLE_MODERN_ORBS,t.TIGHT_ASPECTS=t.SIMPLE_TIGHT_ORBS,t.WIDE_ASPECTS=t.SIMPLE_WIDE_ORBS,t.DEFAULT_ASPECT_STRENGTH_THRESHOLDS={tight:2,moderate:4},t.DEFAULT_SETTINGS={aspectDefinitions:t.DEFAULT_ASPECTS,skipOutOfSignAspects:!0,includeAspectPatterns:!1,includeSignDistributions:!0,includeDispositors:!0,includeHouseOverlays:!0,aspectStrengthThresholds:t.DEFAULT_ASPECT_STRENGTH_THRESHOLDS,houseSystemName:"whole_sign",dateFormat:"MM/DD/YYYY"}},945:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateAnglesOutput=function(e,t){const n=["[ANGLES]"];void 0!==e?n.push(`Ascendant: ${Math.floor((0,r.getDegreeInSign)(e))}° ${(0,r.getDegreeSign)(e)}`):n.push("Ascendant: Not available");void 0!==t?n.push(`Midheaven: ${Math.floor((0,r.getDegreeInSign)(t))}° ${(0,r.getDegreeSign)(t)}`):n.push("Midheaven: Not available");return n};const r=n(904)}},t={};var n=function n(r){var a=t[r];if(void 0!==a)return a.exports;var i=t[r]={exports:{}};return e[r].call(i.exports,i,i.exports,n),i.exports}(156);return n})()));
@@ -1,13 +1,17 @@
1
- import { Settings, PartialSettings, AspectCategory, Aspect } from '../types';
1
+ import { Settings, PartialSettings, Aspect, AspectStrengthThresholds } from '../types';
2
2
  export declare class ChartSettings implements Settings {
3
- includeSignDegree: boolean;
4
- includeAscendant: boolean;
5
3
  houseSystemName: string;
6
- includeHouseDegree: boolean;
7
4
  skipOutOfSignAspects: boolean;
8
- aspectDefinitions: Aspect[];
9
- aspectCategories: AspectCategory[];
5
+ aspectDefinitions: Aspect[] | 'traditional' | 'modern' | 'tight' | 'wide';
6
+ aspectStrengthThresholds: AspectStrengthThresholds;
10
7
  includeAspectPatterns: boolean;
8
+ includeSignDistributions: boolean;
9
+ includeDispositors: boolean | 'finals';
10
+ includeHouseOverlays: boolean;
11
11
  dateFormat: string;
12
12
  constructor(customSettings?: PartialSettings);
13
+ /**
14
+ * Gets the resolved aspect definitions (handles preset strings)
15
+ */
16
+ get resolvedAspectDefinitions(): Aspect[];
13
17
  }
@@ -5,17 +5,28 @@ const constants_1 = require("../constants");
5
5
  class ChartSettings {
6
6
  constructor(customSettings = {}) {
7
7
  const mergedSettings = { ...constants_1.DEFAULT_SETTINGS, ...customSettings };
8
- this.includeSignDegree = mergedSettings.includeSignDegree;
9
- this.includeAscendant = mergedSettings.includeAscendant;
10
- this.houseSystemName = mergedSettings.houseSystemName;
11
- this.includeHouseDegree = mergedSettings.includeHouseDegree;
12
- this.aspectDefinitions =
13
- mergedSettings.aspectDefinitions || constants_1.DEFAULT_ASPECTS; // Ensure array is not undefined
14
- this.aspectCategories =
15
- mergedSettings.aspectCategories || constants_1.DEFAULT_ASPECT_CATEGORIES; // Ensure array is not undefined
16
- this.skipOutOfSignAspects = mergedSettings.skipOutOfSignAspects;
17
- this.includeAspectPatterns = mergedSettings.includeAspectPatterns;
18
- this.dateFormat = mergedSettings.dateFormat;
8
+ Object.assign(this, mergedSettings);
9
+ }
10
+ /**
11
+ * Gets the resolved aspect definitions (handles preset strings)
12
+ */
13
+ get resolvedAspectDefinitions() {
14
+ if (Array.isArray(this.aspectDefinitions)) {
15
+ return this.aspectDefinitions;
16
+ }
17
+ // Handle preset strings
18
+ switch (this.aspectDefinitions) {
19
+ case 'traditional':
20
+ return constants_1.SIMPLE_TRADITIONAL_ORBS;
21
+ case 'modern':
22
+ return constants_1.SIMPLE_MODERN_ORBS;
23
+ case 'tight':
24
+ return constants_1.SIMPLE_TIGHT_ORBS;
25
+ case 'wide':
26
+ return constants_1.SIMPLE_WIDE_ORBS;
27
+ default:
28
+ return constants_1.DEFAULT_SETTINGS.aspectDefinitions;
29
+ }
19
30
  }
20
31
  }
21
32
  exports.ChartSettings = ChartSettings;
@@ -1,5 +1,20 @@
1
- import { Aspect, Settings, AspectCategory } from './types';
1
+ import { Aspect, Settings, AspectStrengthThresholds } from './types';
2
+ export declare const ZODIAC_SIGN_DATA: {
3
+ name: string;
4
+ element: string;
5
+ modality: string;
6
+ polarity: string;
7
+ ruler: string;
8
+ }[];
2
9
  export declare const ZODIAC_SIGNS: string[];
3
10
  export declare const DEFAULT_ASPECTS: Aspect[];
4
- export declare const DEFAULT_ASPECT_CATEGORIES: AspectCategory[];
11
+ export declare const SIMPLE_TRADITIONAL_ORBS: Aspect[];
12
+ export declare const SIMPLE_MODERN_ORBS: Aspect[];
13
+ export declare const SIMPLE_TIGHT_ORBS: Aspect[];
14
+ export declare const SIMPLE_WIDE_ORBS: Aspect[];
15
+ export declare const TRADITIONAL_ASPECTS: Aspect[];
16
+ export declare const MODERN_ASPECTS: Aspect[];
17
+ export declare const TIGHT_ASPECTS: Aspect[];
18
+ export declare const WIDE_ASPECTS: Aspect[];
19
+ export declare const DEFAULT_ASPECT_STRENGTH_THRESHOLDS: AspectStrengthThresholds;
5
20
  export declare const DEFAULT_SETTINGS: Settings;