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
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,110 @@ 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
+ * **`GroupingSettings`**: For `groupAspects()` or the simple `chart2txt()` workflow.
125
+ * `aspectStrengthThresholds`: An object to define orb limits for default grouping, e.g., `{ tight: 2.0, moderate: 4.0 }`.
126
+ * **`FormattingSettings`**: For `formatReportToText()`
127
+ * `dateFormat`: `string`
128
+ * `houseSystemName`: `string`
129
+
57
130
  ## Development
58
131
 
59
132
  ```bash
@@ -65,14 +138,8 @@ npm test
65
138
 
66
139
  # Build the library
67
140
  npm run build
68
-
69
- # Lint code
70
- npm run lint
71
-
72
- # Format code
73
- npm run format
74
141
  ```
75
142
 
76
143
  ## License
77
144
 
78
- MIT
145
+ 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)=>{function n(e,t,n,r){let s=Math.abs(t.degree-n.degree);s>180&&(s=360-s);let a=null;for(const o of e){const e=Math.abs(s-o.angle);if(r){const e=Math.floor(t.degree/30),r=Math.floor(n.degree/30),s=Math.floor(o.angle/30);let a=Math.abs(e-r);if(a>6&&(a=12-a),a!==s)continue}e<=o.orb&&(!a||e<a.orb)&&(a={planetA:t.name,planetB:n.name,aspectType:o.name,orb:e})}return a}Object.defineProperty(t,"__esModule",{value:!0}),t.calculateAspects=function(e,t,r=!0){const s=[];if(!t||t.length<2)return s;for(let a=0;a<t.length;a++)for(let o=a+1;o<t.length;o++){const u=n(e,t[a],t[o],r);u&&s.push(u)}return s},t.calculateMultichartAspects=function(e,t,r,s=!0){const a=[];if(!t||!r||0===t.length||0===r.length)return a;for(const o of t)for(const t of r){const r=n(e,o,t,s);r&&a.push(r)}return a}},156:function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var s=Object.getOwnPropertyDescriptor(t,n);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,s)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),s=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 a=n(723);Object.defineProperty(t,"chart2txt",{enumerable:!0,get:function(){return a.formatChartToText}}),s(n(613),t);var o=n(921);Object.defineProperty(t,"DEFAULT_SETTINGS",{enumerable:!0,get:function(){return o.DEFAULT_SETTINGS}}),Object.defineProperty(t,"DEFAULT_ASPECTS",{enumerable:!0,get:function(){return o.DEFAULT_ASPECTS}}),Object.defineProperty(t,"DEFAULT_ASPECT_CATEGORIES",{enumerable:!0,get:function(){return o.DEFAULT_ASPECT_CATEGORIES}}),Object.defineProperty(t,"ZODIAC_SIGNS",{enumerable:!0,get:function(){return o.ZODIAC_SIGNS}});var u=n(230);Object.defineProperty(t,"ChartSettings",{enumerable:!0,get:function(){return u.ChartSettings}});const i=n(723);t.default=i.formatChartToText},172:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateChartHeaderOutput=function(e,t="CHART"){return[`[${t}: ${e||"Unknown"}]`]}},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.dateFormat=t.dateFormat}}},234:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generatePlanetsOutput=function(e,t,n){const s=["[PLANETS]"];e.forEach((e=>{const n=(0,r.getDegreeSign)(e.degree),a=Math.floor((0,r.getDegreeInSign)(e.degree)),o=void 0!==e.speed&&e.speed<0?" Rx":"";let u=`${e.name}: ${a}° ${n}${o}`;if(t&&12===t.length){const n=function(e,t){if(!t||12!==t.length)return 0;for(let n=0;n<12;n++){const r=t[n],s=t[(n+1)%12];if(r<s){if(e>=r&&e<s)return n+1}else if(e>=r||e<s)return n+1}return 0}(e.degree,t);n>0&&(u+=`, House ${n}`)}s.push(u)})),0===e.length&&s.push("No planets listed.");return s};const r=n(904)},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}},613:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isMultiChartData=function(e){return Array.isArray(e)}},723:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.formatChartToText=function(e,t={}){const n=new s.ChartSettings(t),u=n.houseSystemName,i=[];if(!(0,r.isMultiChartData)(e)){if("transit"===e.chartType)throw new Error("Single chart data must not be transit.");return i.push(...(0,o.generateMetadataOutput)(n,e.chartType||"natal",u)),i.push(""),i.push(...g(n,e)),i.join("\n").trimEnd()}const c=S(e);i.push(...(0,o.generateMetadataOutput)(n,c,u)),i.push("");const p=e.filter((({chartType:e})=>"transit"!==e)),h=e.find((({chartType:e})=>"transit"===e));for(const e of p)i.push(...g(n,e));for(let e=0;e<p.length;e++)for(let t=e+1;t<p.length;t++)i.push(...f(n,p[e],p[t]));if(h){i.push(...d(n,h));for(const e of p){const t=(0,a.calculateMultichartAspects)(n.aspectDefinitions,e.planets,h.planets,n.skipOutOfSignAspects);i.push(...(0,l.generateAspectsOutput)(`[TRANSIT ASPECTS: ${e.name}]`,t,n,e.name,h.name,!0)),i.push("")}}return i.join("\n").trimEnd()};const r=n(613),s=n(230),a=n(75),o=n(388),u=n(172),i=n(888),c=n(945),p=n(234),l=n(784),h=n(756),g=(e,t,n)=>{const r=[];r.push(...(0,u.generateChartHeaderOutput)(t.name,n)),r.push(...(0,i.generateBirthdataOutput)(t.location,t.timestamp,e)),r.push(...(0,c.generateAnglesOutput)(t.ascendant,t.midheaven)),r.push(...(0,p.generatePlanetsOutput)(t.planets,t.houseCusps,e));const s=(0,a.calculateAspects)(e.aspectDefinitions,t.planets,e.skipOutOfSignAspects);return r.push(...(0,l.generateAspectsOutput)("[ASPECTS]",s,e)),r.push(""),r},f=(e,t,n)=>{const r=[],s="event"===t.chartType&&"event"===n.chartType?"EVENT_RELATIONSHIP":"event"===t.chartType||"event"===n.chartType?"NATAL_EVENT":"SYNASTRY";r.push(...(0,u.generateChartHeaderOutput)(`${t.name}-${n.name}`,s));const o=(0,a.calculateMultichartAspects)(e.aspectDefinitions,t.planets,n.planets,e.skipOutOfSignAspects);return r.push(...(0,l.generateAspectsOutput)("[PLANET-PLANET ASPECTS]",o,e,t.name,n.name)),r.push(""),r.push(...(0,h.generateHouseOverlaysOutput)(t,n,e)),r.push(""),r},d=(e,t)=>{const n=[];return n.push(...(0,u.generateChartHeaderOutput)(t.name,"TRANSIT")),n.push(...(0,i.generateBirthdataOutput)(t.location,t.timestamp,e,"[DATETIME]")),n.push(...(0,p.generatePlanetsOutput)(t.planets,t.houseCusps,e)),n.push(""),n},S=e=>{let t="natal",n="";const r=e.filter((({chartType:e})=>"transit"!==e&&"event"!==e)),s=e.filter((({chartType:e})=>"event"===e)),a=e.filter((({chartType:e})=>"transit"===e));if(a.length>1)throw new Error("Must provide at most one transit chart");const o=a.length>0;if(r.length>0?0===s.length?o&&(n="_with_transit"):n=1===s.length?o?"_with_event_and_transit":"_with_event":o?"_with_events_and_transit":"_with_events":o&&(n="_with_transit"),0===r.length){if(0===s.length)throw new Error("Must provide at least one non-transit chart");t=1===s.length?"event":"multi_event"}else t=1===r.length?"natal":2===r.length?"synastry":"group_synastry";return t+n}},756:(e,t)=>{function n(e,t){if(!t||12!==t.length)return 0;for(let n=0;n<12;n++){const r=t[n],s=t[(n+1)%12];if(r<s){if(e>=r&&e<s)return n+1}else if(e>=r||e<s)return n+1}return 0}Object.defineProperty(t,"__esModule",{value:!0}),t.generateHouseOverlaysOutput=function(e,t,r){const s=["[HOUSE OVERLAYS]"],a=e.name,o=t.name;t.houseCusps&&12===t.houseCusps.length?(s.push(`${a}'s planets in ${o}'s houses:`),e.planets&&e.planets.length>0?e.planets.forEach((e=>{const r=n(e.degree,t.houseCusps);r>0?s.push(`${e.name}: House ${r}`):s.push(`${e.name}: (Could not determine house in ${o})`)})):s.push("(No planets listed for overlay)")):s.push(`${a}'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 ${a}'s houses:`),t.planets&&t.planets.length>0?t.planets.forEach((t=>{const r=n(t.degree,e.houseCusps);r>0?s.push(`${t.name}: House ${r}`):s.push(`${t.name}: (Could not determine house in ${a})`)})):s.push("(No planets listed for overlay)")):s.push(`${o}'s planets in ${a}'s houses: (${a} house cusps not available)`);return s}},784:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateAspectsOutput=function(e,t,n,r,s,a=!1){const o=[e];let u=!1;n.aspectCategories.forEach((e=>{const n=t.filter((t=>{const n=t.orb,r=void 0===e.minOrb||n>e.minOrb,s=n<=e.maxOrb;return r&&s}));if(n.length>0){u=!0;let t=`orb < ${e.maxOrb.toFixed(1)}°`;void 0!==e.minOrb&&(t=e.minOrb<e.maxOrb?`orb ${e.minOrb.toFixed(1)}-${e.maxOrb.toFixed(1)}°`:`orb > ${e.minOrb.toFixed(1)}° & < ${e.maxOrb.toFixed(1)}°`),o.push(`[${e.name.toUpperCase()}: ${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;a?n=`transiting ${e.planetB}`:s&&(n=`${s}'s ${e.planetB}`),o.push(`${t} ${e.aspectType} ${n}: ${e.orb.toFixed(1)}°`)}))}})),!u&&t.length>0?o.push("No aspects within defined categories."):0===t.length&&o.push("None");return o}},888:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateBirthdataOutput=function(e,t,n,s="[BIRTHDATA]"){if(!t)return[`${s} Not available`];const a=(0,r.formatDateCustom)(t,n.dateFormat),o=(0,r.formatTime)(t);return[`${s} ${e||"Unknown Location"}, ${a}, ${o}`]};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(),s=e.getFullYear();switch(t.toUpperCase()){case"MM/DD/YYYY":return`${n.toString().padStart(2,"0")}/${r.toString().padStart(2,"0")}/${s}`;case"DD/MM/YYYY":return`${r.toString().padStart(2,"0")}/${n.toString().padStart(2,"0")}/${s}`;case"YYYY-MM-DD":return`${s}-${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.getDegreeSign=function(e){const t=Math.floor(e/30)%12;if(t<0||t>=r.ZODIAC_SIGNS.length)return console.error(`Invalid sign index computed: ${t} for degree ${e}`),"Unknown Sign";return r.ZODIAC_SIGNS[t]},t.getDegreeInSign=function(e){return e%30};const r=n(921)},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:"MAJOR",maxOrb:2},{name:"MODERATE",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,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(`ASC: ${Math.floor((0,r.getDegreeInSign)(e))}° ${(0,r.getDegreeSign)(e)}`):n.push("ASC: Not available");void 0!==t?n.push(`MC: ${Math.floor((0,r.getDegreeInSign)(t))}° ${(0,r.getDegreeSign)(t)}`):n.push("MC: Not available");return n};const r=n(904)}},t={};var n=function n(r){var s=t[r];if(void 0!==s)return s.exports;var a=t[r]={exports:{}};return e[r].call(a.exports,a,a.exports,n),a.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 E=b.includeAspectPatterns?(0,o.detectAspectPatterns)(D,_):[],C=[],v=[],$=[];let P,I;for(const e of M){const t=_.filter((t=>t.p1ChartName===e.name&&t.p2ChartName===e.name)),n=S(E,1,1).filter((t=>A(t,e.name))),r=b.includeAspectPatterns?(0,u.detectStelliums)(h(e),e.houseCusps):[];C.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):{}})}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(E,2,2).filter((e=>A(e,n.name)&&A(e,r.name)));v.push({chart1:n,chart2:r,synastryAspects:a,compositePatterns:i,houseOverlays:(0,f.calculateHouseOverlays)(n,r)})}if(T.length>2){const e=S(E,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(E,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=(N=E,j=[O.name],N.filter((e=>j.some((t=>A(e,t)))))).filter((e=>m(e)>=3));e.length>0&&(I={charts:M,patterns:e})}}var N,j;return{settings:b,chartAnalyses:C,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){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}}toJSON(){return{houseSystemName:this.houseSystemName,skipOutOfSignAspects:this.skipOutOfSignAspects,aspectDefinitions:this.aspectDefinitions,aspectStrengthThresholds:this.aspectStrengthThresholds,includeAspectPatterns:this.includeAspectPatterns,includeSignDistributions:this.includeSignDistributions,dateFormat:this.dateFormat}}}},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)),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(""),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){const t={};e.forEach((e=>{t[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 n={};return e.forEach((e=>{const r=[e.name];let a=e.name,i=`${a}`;for(;;){const e=t[a];if(!e||!t.hasOwnProperty(e)){i+=` → ${e} (not in chart)`;break}if(e===a){i+=" → (final)";break}if(r.includes(e)){i+=` → ${e} (cycle)`;break}r.push(e),i+=` → ${e}`,a=e}n[e.name]=i})),n};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(", ")})`))},t.formatModalityDistribution=function(e){return Object.entries(e).map((([e,t])=>`${e}: ${t}`))},t.formatPolarityDistribution=function(e){return Object.entries(e).map((([e,t])=>`${e}: ${t}`))};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,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,12 +1,19 @@
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;
7
+ includeAspectPatterns: boolean;
8
+ includeSignDistributions: boolean;
10
9
  dateFormat: string;
11
10
  constructor(customSettings?: PartialSettings);
11
+ /**
12
+ * Gets the resolved aspect definitions (handles preset strings)
13
+ */
14
+ get resolvedAspectDefinitions(): Aspect[];
15
+ /**
16
+ * Returns a plain JSON object representation of the settings.
17
+ */
18
+ toJSON(): Settings;
12
19
  }
@@ -5,16 +5,42 @@ 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.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
+ }
30
+ }
31
+ /**
32
+ * Returns a plain JSON object representation of the settings.
33
+ */
34
+ toJSON() {
35
+ return {
36
+ houseSystemName: this.houseSystemName,
37
+ skipOutOfSignAspects: this.skipOutOfSignAspects,
38
+ aspectDefinitions: this.aspectDefinitions,
39
+ aspectStrengthThresholds: this.aspectStrengthThresholds,
40
+ includeAspectPatterns: this.includeAspectPatterns,
41
+ includeSignDistributions: this.includeSignDistributions,
42
+ dateFormat: this.dateFormat,
43
+ };
18
44
  }
19
45
  }
20
46
  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;