chart2txt 0.4.0 → 0.5.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.
@@ -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)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.calculateAspects=function(e,t){const n=[];if(!t||t.length<2)return n;for(let r=0;r<t.length;r++)for(let a=r+1;a<t.length;a++){const s=t[r],o=t[a];let u=Math.abs(s.degree-o.degree);u>180&&(u=360-u);let i=null;for(const t of e){const e=Math.abs(u-t.angle);e<=t.orb&&(!i||e<i.orb)&&(i={planetA:s.name,planetB:o.name,aspectType:t.name,orb:e})}i&&n.push(i)}return n},t.calculateMultichartAspects=function(e,t,n){const r=[];if(!t||!n||0===t.length||0===n.length)return r;for(const a of t)for(const t of n){let n=Math.abs(a.degree-t.degree);n>180&&(n=360-n);let s=null;for(const r of e){const e=Math.abs(n-r.angle);e<=r.orb&&(!s||e<s.orb)&&(s={planetA:a.name,planetB:t.name,aspectType:r.name,orb:e})}s&&r.push(s)}return r}},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 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.includeHouseDegree=t.includeHouseDegree,this.aspectDefinitions=t.aspectDefinitions||r.DEFAULT_ASPECTS,this.aspectCategories=t.aspectCategories||r.DEFAULT_ASPECT_CATEGORIES,this.dateFormat=t.dateFormat}}},234:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generatePlanetsOutput=function(e,t,n){const a=["[PLANETS]"];e.forEach((e=>{const n=(0,r.getDegreeSign)(e.degree),s=Math.floor((0,r.getDegreeInSign)(e.degree)),o=void 0!==e.speed&&e.speed<0?" Rx":"";let u=`${e.name}: ${s}° ${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],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 0}(e.degree,t);n>0&&(u+=`, House ${n}`)}a.push(u)})),0===e.length&&a.push("No planets listed.");return a};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 void 0!==e.chart1}},723:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.formatChartToText=function(e,t={}){const n=new r.ChartSettings(t),h=[];let g,d="natal";if("chart1"in e){const t=e;g=t.chart1.houseSystemName,t.chart2&&t.transit?d="synastry_with_transit":t.chart2?d="synastry":t.transit&&(d="natal_with_transit")}else g=e.houseSystemName;h.push(...(0,s.generateMetadataOutput)(n,d,g)),h.push("");const f=(e,t)=>{h.push(...(0,o.generateChartHeaderOutput)(e.name,t)),h.push(...(0,u.generateBirthdataOutput)(e.location,e.timestamp,n)),h.push(...(0,i.generateAnglesOutput)(e.ascendant,e.midheaven)),h.push(...(0,c.generatePlanetsOutput)(e.planets,e.houseCusps,n));const r=(0,a.calculateAspects)(n.aspectDefinitions,e.planets);h.push(...(0,p.generateAspectsOutput)("[ASPECTS]",r,n)),h.push("")};if("chart1"in e){const t=e,r=t.chart1,s=r.name||"Chart 1";if(f(r),t.chart2){const e=t.chart2,u=e.name||"Chart 2";f(e),h.push(...(0,o.generateChartHeaderOutput)(`${s}-${u}`,"SYNASTRY"));const i=(0,a.calculateMultichartAspects)(n.aspectDefinitions,r.planets,e.planets);h.push(...(0,p.generateAspectsOutput)("[PLANET-PLANET ASPECTS]",i,n,s,u)),h.push(""),h.push(...(0,l.generateHouseOverlaysOutput)(r,e,n)),h.push("")}if(t.transit){const e=t.transit,i=e.name||"Current";S=e,h.push(...(0,o.generateChartHeaderOutput)(S.name||"Current","TRANSIT")),h.push(...(0,u.generateBirthdataOutput)(S.location,S.timestamp,n,"[DATETIME]")),h.push(...(0,c.generatePlanetsOutput)(S.planets,S.houseCusps,n)),h.push("");const l=(0,a.calculateMultichartAspects)(n.aspectDefinitions,r.planets,e.planets);if(h.push(...(0,p.generateAspectsOutput)(`[TRANSIT ASPECTS: ${s}]`,l,n,s,i,!0)),h.push(""),t.chart2){const r=t.chart2.name||"Chart 2",s=(0,a.calculateMultichartAspects)(n.aspectDefinitions,t.chart2.planets,e.planets);h.push(...(0,p.generateAspectsOutput)(`[TRANSIT ASPECTS: ${r}]`,s,n,r,i,!0)),h.push("")}}}else f(e);var S;return h.join("\n").trimEnd()};const r=n(230),a=n(75),s=n(388),o=n(172),u=n(888),i=n(945),c=n(234),p=n(784),l=n(756)},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],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 0}Object.defineProperty(t,"__esModule",{value:!0}),t.generateHouseOverlaysOutput=function(e,t,r){const a=["[HOUSE OVERLAYS]"],s=e.name||"Chart 1",o=t.name||"Chart 2";t.houseCusps&&12===t.houseCusps.length?(a.push(`${s}'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?a.push(`${e.name}: House ${r}`):a.push(`${e.name}: (Could not determine house in ${o})`)})):a.push("(No planets listed for overlay)")):a.push(`${s}'s planets in ${o}'s houses: (${o} house cusps not available)`);a.push(""),e.houseCusps&&12===e.houseCusps.length?(a.push(`${o}'s planets in ${s}'s houses:`),t.planets&&t.planets.length>0?t.planets.forEach((t=>{const r=n(t.degree,e.houseCusps);r>0?a.push(`${t.name}: House ${r}`):a.push(`${t.name}: (Could not determine house in ${s})`)})):a.push("(No planets listed for overlay)")):a.push(`${o}'s planets in ${s}'s houses: (${s} house cusps not available)`);return a}},784:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateAspectsOutput=function(e,t,n,r,a,s=!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,a=n<=e.maxOrb;return r&&a}));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;s?n=`transiting ${e.planetB}`:a&&(n=`${a}'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,a="[BIRTHDATA]"){if(!t)return[`${a} Not available`];const s=(0,r.formatDateCustom)(t,n.dateFormat),o=(0,r.formatTime)(t);return[`${a} ${e||"Unknown Location"}, ${s}, ${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(),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.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,includeHouseDegree:!1,includeAscendant:!0,aspectDefinitions:t.DEFAULT_ASPECTS,aspectCategories:t.DEFAULT_ASPECT_CATEGORIES,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 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={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);if(Math.abs(e-r)!==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})()));
@@ -2,7 +2,9 @@ import { Settings, PartialSettings, AspectCategory, Aspect } from '../types';
2
2
  export declare class ChartSettings implements Settings {
3
3
  includeSignDegree: boolean;
4
4
  includeAscendant: boolean;
5
+ houseSystemName: string;
5
6
  includeHouseDegree: boolean;
7
+ skipOutOfSignAspects: boolean;
6
8
  aspectDefinitions: Aspect[];
7
9
  aspectCategories: AspectCategory[];
8
10
  dateFormat: string;
@@ -7,11 +7,13 @@ class ChartSettings {
7
7
  const mergedSettings = { ...constants_1.DEFAULT_SETTINGS, ...customSettings };
8
8
  this.includeSignDegree = mergedSettings.includeSignDegree;
9
9
  this.includeAscendant = mergedSettings.includeAscendant;
10
+ this.houseSystemName = mergedSettings.houseSystemName;
10
11
  this.includeHouseDegree = mergedSettings.includeHouseDegree;
11
12
  this.aspectDefinitions =
12
13
  mergedSettings.aspectDefinitions || constants_1.DEFAULT_ASPECTS; // Ensure array is not undefined
13
14
  this.aspectCategories =
14
15
  mergedSettings.aspectCategories || constants_1.DEFAULT_ASPECT_CATEGORIES; // Ensure array is not undefined
16
+ this.skipOutOfSignAspects = mergedSettings.skipOutOfSignAspects;
15
17
  this.dateFormat = mergedSettings.dateFormat;
16
18
  }
17
19
  }
package/dist/constants.js CHANGED
@@ -30,11 +30,13 @@ exports.DEFAULT_SETTINGS = {
30
30
  // sign settings
31
31
  includeSignDegree: true, // For planets list: "Sun: 8° Cancer" vs "Sun: Cancer"
32
32
  // house settings
33
+ houseSystemName: 'whole_sign',
33
34
  includeHouseDegree: false, // New format shows "House X", not degree in house for planets list
34
35
  // point settings
35
36
  includeAscendant: true, // Legacy, ASC/MC now have dedicated [ANGLES] section
36
37
  // orb + aspect settings
37
38
  aspectDefinitions: exports.DEFAULT_ASPECTS,
38
39
  aspectCategories: exports.DEFAULT_ASPECT_CATEGORIES,
40
+ skipOutOfSignAspects: true,
39
41
  dateFormat: 'MM/DD/YYYY', // As per example output
40
42
  };
@@ -5,7 +5,7 @@ import { Point, Aspect, AspectData } from '../types';
5
5
  * @param planets Array of planet points.
6
6
  * @returns Array of found aspects.
7
7
  */
8
- export declare function calculateAspects(aspectDefinitions: Aspect[], planets: Point[]): AspectData[];
8
+ export declare function calculateAspects(aspectDefinitions: Aspect[], planets: Point[], skipOutOfSignAspects?: boolean): AspectData[];
9
9
  /**
10
10
  * Identifies aspects between planets across two charts.
11
11
  * PlanetA is always from chart1Planets, PlanetB always from chart2Planets.
@@ -14,4 +14,4 @@ export declare function calculateAspects(aspectDefinitions: Aspect[], planets: P
14
14
  * @param chart2Planets Array of planet points for the second chart.
15
15
  * @returns Array of found aspects.
16
16
  */
17
- export declare function calculateMultichartAspects(aspectDefinitions: Aspect[], chart1Planets: Point[], chart2Planets: Point[]): AspectData[];
17
+ export declare function calculateMultichartAspects(aspectDefinitions: Aspect[], chart1Planets: Point[], chart2Planets: Point[], skipOutOfSignAspects?: boolean): AspectData[];
@@ -2,13 +2,41 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.calculateAspects = calculateAspects;
4
4
  exports.calculateMultichartAspects = calculateMultichartAspects;
5
+ function findTightestAspect(aspectDefinitions, planetA, planetB, skipOutOfSignAspects) {
6
+ let diff = Math.abs(planetA.degree - planetB.degree);
7
+ if (diff > 180)
8
+ diff = 360 - diff;
9
+ let tightestAspect = null;
10
+ for (const aspectType of aspectDefinitions) {
11
+ const orb = Math.abs(diff - aspectType.angle);
12
+ if (skipOutOfSignAspects) {
13
+ const planetASign = Math.floor(planetA.degree / 30);
14
+ const planetBSign = Math.floor(planetB.degree / 30);
15
+ const aspectSignDiff = Math.floor(aspectType.angle / 30);
16
+ if (Math.abs(planetASign - planetBSign) !== aspectSignDiff) {
17
+ continue;
18
+ }
19
+ }
20
+ if (orb <= aspectType.orb) {
21
+ if (!tightestAspect || orb < tightestAspect.orb) {
22
+ tightestAspect = {
23
+ planetA: planetA.name,
24
+ planetB: planetB.name,
25
+ aspectType: aspectType.name,
26
+ orb,
27
+ };
28
+ }
29
+ }
30
+ }
31
+ return tightestAspect;
32
+ }
5
33
  /**
6
34
  * Identifies aspects between planets in a single chart.
7
35
  * @param aspectDefinitions Array of aspect types to check for.
8
36
  * @param planets Array of planet points.
9
37
  * @returns Array of found aspects.
10
38
  */
11
- function calculateAspects(aspectDefinitions, planets) {
39
+ function calculateAspects(aspectDefinitions, planets, skipOutOfSignAspects = true) {
12
40
  const aspects = [];
13
41
  if (!planets || planets.length < 2)
14
42
  return aspects;
@@ -16,26 +44,9 @@ function calculateAspects(aspectDefinitions, planets) {
16
44
  for (let j = i + 1; j < planets.length; j++) {
17
45
  const planetA = planets[i];
18
46
  const planetB = planets[j];
19
- let diff = Math.abs(planetA.degree - planetB.degree);
20
- if (diff > 180)
21
- diff = 360 - diff;
22
- // Find the tightest valid aspect
23
- let tightestAspect = null;
24
- for (const aspectType of aspectDefinitions) {
25
- const orb = Math.abs(diff - aspectType.angle);
26
- if (orb <= aspectType.orb) {
27
- if (!tightestAspect || orb < tightestAspect.orb) {
28
- tightestAspect = {
29
- planetA: planetA.name,
30
- planetB: planetB.name,
31
- aspectType: aspectType.name,
32
- orb,
33
- };
34
- }
35
- }
36
- }
37
- if (tightestAspect) {
38
- aspects.push(tightestAspect);
47
+ const aspect = findTightestAspect(aspectDefinitions, planetA, planetB, skipOutOfSignAspects);
48
+ if (aspect) {
49
+ aspects.push(aspect);
39
50
  }
40
51
  }
41
52
  }
@@ -49,7 +60,7 @@ function calculateAspects(aspectDefinitions, planets) {
49
60
  * @param chart2Planets Array of planet points for the second chart.
50
61
  * @returns Array of found aspects.
51
62
  */
52
- function calculateMultichartAspects(aspectDefinitions, chart1Planets, chart2Planets) {
63
+ function calculateMultichartAspects(aspectDefinitions, chart1Planets, chart2Planets, skipOutOfSignAspects = true) {
53
64
  const aspects = [];
54
65
  if (!chart1Planets ||
55
66
  !chart2Planets ||
@@ -59,26 +70,9 @@ function calculateMultichartAspects(aspectDefinitions, chart1Planets, chart2Plan
59
70
  }
60
71
  for (const p1 of chart1Planets) {
61
72
  for (const p2 of chart2Planets) {
62
- let diff = Math.abs(p1.degree - p2.degree);
63
- if (diff > 180)
64
- diff = 360 - diff;
65
- // Find the tightest valid aspect
66
- let tightestAspect = null;
67
- for (const aspectType of aspectDefinitions) {
68
- const orb = Math.abs(diff - aspectType.angle);
69
- if (orb <= aspectType.orb) {
70
- if (!tightestAspect || orb < tightestAspect.orb) {
71
- tightestAspect = {
72
- planetA: p1.name, // From chart1
73
- planetB: p2.name, // From chart2
74
- aspectType: aspectType.name,
75
- orb,
76
- };
77
- }
78
- }
79
- }
80
- if (tightestAspect) {
81
- aspects.push(tightestAspect);
73
+ const aspect = findTightestAspect(aspectDefinitions, p1, p2, skipOutOfSignAspects);
74
+ if (aspect) {
75
+ aspects.push(aspect);
82
76
  }
83
77
  }
84
78
  }
@@ -36,8 +36,8 @@ function getHouseForPoint(pointDegree, houseCusps) {
36
36
  */
37
37
  function generateHouseOverlaysOutput(chart1, chart2, settings) {
38
38
  const output = ['[HOUSE OVERLAYS]'];
39
- const c1Name = chart1.name || 'Chart 1';
40
- const c2Name = chart2.name || 'Chart 2';
39
+ const c1Name = chart1.name;
40
+ const c2Name = chart2.name;
41
41
  // Chart 1's planets in Chart 2's houses
42
42
  if (chart2.houseCusps && chart2.houseCusps.length === 12) {
43
43
  output.push(`${c1Name}'s planets in ${c2Name}'s houses:`);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.formatChartToText = formatChartToText;
4
+ const types_1 = require("../../types");
4
5
  const ChartSettings_1 = require("../../config/ChartSettings");
5
6
  const aspects_1 = require("../../core/aspects");
6
7
  const metadata_1 = require("./sections/metadata");
@@ -10,6 +11,95 @@ const angles_1 = require("./sections/angles");
10
11
  const planets_1 = require("./sections/planets");
11
12
  const aspects_2 = require("./sections/aspects");
12
13
  const houseOverlays_1 = require("./sections/houseOverlays");
14
+ const processSingleChartOutput = (settings, chartData, chartTitlePrefix) => {
15
+ const outputLines = [];
16
+ outputLines.push(...(0, chartHeader_1.generateChartHeaderOutput)(chartData.name, chartTitlePrefix));
17
+ outputLines.push(...(0, birthdata_1.generateBirthdataOutput)(chartData.location, chartData.timestamp, settings));
18
+ outputLines.push(...(0, angles_1.generateAnglesOutput)(chartData.ascendant, chartData.midheaven));
19
+ outputLines.push(...(0, planets_1.generatePlanetsOutput)(chartData.planets, chartData.houseCusps, settings));
20
+ const aspects = (0, aspects_1.calculateAspects)(settings.aspectDefinitions, chartData.planets, settings.skipOutOfSignAspects);
21
+ // For single chart, p1ChartName and p2ChartName are not needed for aspect string generation
22
+ outputLines.push(...(0, aspects_2.generateAspectsOutput)('[ASPECTS]', aspects, settings));
23
+ outputLines.push('');
24
+ return outputLines;
25
+ };
26
+ const processChartPairOutput = (settings, chart1, chart2) => {
27
+ const outputLines = [];
28
+ const header = chart1.chartType === 'event' && chart2.chartType === 'event'
29
+ ? 'EVENT_RELATIONSHIP'
30
+ : chart1.chartType === 'event' || chart2.chartType === 'event'
31
+ ? 'NATAL_EVENT'
32
+ : 'SYNASTRY';
33
+ outputLines.push(...(0, chartHeader_1.generateChartHeaderOutput)(`${chart1.name}-${chart2.name}`, header));
34
+ const synastryAspects = (0, aspects_1.calculateMultichartAspects)(settings.aspectDefinitions, chart1.planets, chart2.planets, settings.skipOutOfSignAspects);
35
+ outputLines.push(...(0, aspects_2.generateAspectsOutput)('[PLANET-PLANET ASPECTS]', synastryAspects, settings, chart1.name, chart2.name));
36
+ outputLines.push('');
37
+ outputLines.push(...(0, houseOverlays_1.generateHouseOverlaysOutput)(chart1, chart2, settings));
38
+ outputLines.push('');
39
+ return outputLines;
40
+ };
41
+ const processTransitChartInfoOutput = (settings, transitData) => {
42
+ const outputLines = [];
43
+ outputLines.push(...(0, chartHeader_1.generateChartHeaderOutput)(transitData.name, 'TRANSIT'));
44
+ outputLines.push(...(0, birthdata_1.generateBirthdataOutput)(transitData.location, transitData.timestamp, settings, '[DATETIME]'));
45
+ // For transit chart's own planets, houses are usually not shown unless it's a full natal chart for that moment.
46
+ outputLines.push(...(0, planets_1.generatePlanetsOutput)(transitData.planets, transitData.houseCusps, settings));
47
+ outputLines.push('');
48
+ return outputLines;
49
+ };
50
+ const determineChartType = (data) => {
51
+ let baseChartString = 'natal';
52
+ let suffixString = '';
53
+ const natalCharts = data.filter(({ chartType }) => chartType !== 'transit' && chartType !== 'event');
54
+ const eventCharts = data.filter(({ chartType }) => chartType === 'event');
55
+ const transitCharts = data.filter(({ chartType }) => chartType === 'transit');
56
+ if (transitCharts.length > 1) {
57
+ throw new Error('Must provide at most one transit chart');
58
+ }
59
+ const hasTransit = transitCharts.length > 0;
60
+ // first determine suffix
61
+ if (natalCharts.length > 0) {
62
+ if (eventCharts.length === 0) {
63
+ if (hasTransit) {
64
+ suffixString = '_with_transit';
65
+ }
66
+ }
67
+ else if (eventCharts.length === 1) {
68
+ suffixString = hasTransit ? '_with_event_and_transit' : '_with_event';
69
+ }
70
+ else {
71
+ suffixString = hasTransit ? '_with_events_and_transit' : '_with_events';
72
+ }
73
+ }
74
+ else {
75
+ // base event charts can have transits
76
+ if (hasTransit) {
77
+ suffixString = '_with_transit';
78
+ }
79
+ }
80
+ // then determine base string
81
+ if (natalCharts.length === 0) {
82
+ if (eventCharts.length === 0) {
83
+ throw new Error('Must provide at least one non-transit chart');
84
+ }
85
+ else if (eventCharts.length === 1) {
86
+ baseChartString = 'event';
87
+ }
88
+ else {
89
+ baseChartString = 'multi_event';
90
+ }
91
+ }
92
+ else if (natalCharts.length === 1) {
93
+ baseChartString = 'natal';
94
+ }
95
+ else if (natalCharts.length === 2) {
96
+ baseChartString = 'synastry';
97
+ }
98
+ else {
99
+ baseChartString = 'group_synastry';
100
+ }
101
+ return baseChartString + suffixString;
102
+ };
13
103
  /**
14
104
  * Orchestrates the generation of a complete astrological chart report in text format.
15
105
  * @param data The chart data, can be for a single chart or multiple charts (synastry, transits).
@@ -18,81 +108,44 @@ const houseOverlays_1 = require("./sections/houseOverlays");
18
108
  */
19
109
  function formatChartToText(data, partialSettings = {}) {
20
110
  const settings = new ChartSettings_1.ChartSettings(partialSettings);
111
+ const houseSystemName = settings.houseSystemName;
21
112
  const outputLines = [];
22
- let baseChartType = 'natal';
23
- let primaryHouseSystemName;
24
- if ('chart1' in data) {
25
- // Check if it's MultiChartData
26
- const multiData = data;
27
- primaryHouseSystemName = multiData.chart1.houseSystemName; // Use chart1's house system name for overall metadata
28
- if (multiData.chart2 && multiData.transit)
29
- baseChartType = 'synastry_with_transit';
30
- else if (multiData.chart2)
31
- baseChartType = 'synastry';
32
- else if (multiData.transit)
33
- baseChartType = 'natal_with_transit';
34
- }
35
- else {
36
- // Single ChartData object
37
- primaryHouseSystemName = data.houseSystemName;
113
+ if (!(0, types_1.isMultiChartData)(data)) {
114
+ // single chart or event, legacy usage
115
+ if (data.chartType === 'transit') {
116
+ throw new Error('Single chart data must not be transit.');
117
+ }
118
+ outputLines.push(...(0, metadata_1.generateMetadataOutput)(settings, data.chartType || 'natal', houseSystemName));
119
+ outputLines.push(''); // Blank line after metadata
120
+ outputLines.push(...processSingleChartOutput(settings, data));
121
+ return outputLines.join('\n').trimEnd();
38
122
  }
39
- outputLines.push(...(0, metadata_1.generateMetadataOutput)(settings, baseChartType, primaryHouseSystemName));
123
+ // multi-chart analysis proceeds from here on
124
+ // generate metadata
125
+ const chartType = determineChartType(data);
126
+ outputLines.push(...(0, metadata_1.generateMetadataOutput)(settings, chartType, houseSystemName));
40
127
  outputLines.push(''); // Blank line after metadata
41
- const processSingleChartOutput = (chartData, chartTitlePrefix) => {
42
- outputLines.push(...(0, chartHeader_1.generateChartHeaderOutput)(chartData.name, chartTitlePrefix));
43
- outputLines.push(...(0, birthdata_1.generateBirthdataOutput)(chartData.location, chartData.timestamp, settings));
44
- outputLines.push(...(0, angles_1.generateAnglesOutput)(chartData.ascendant, chartData.midheaven));
45
- outputLines.push(...(0, planets_1.generatePlanetsOutput)(chartData.planets, chartData.houseCusps, settings));
46
- const aspects = (0, aspects_1.calculateAspects)(settings.aspectDefinitions, chartData.planets);
47
- // For single chart, p1ChartName and p2ChartName are not needed for aspect string generation
48
- outputLines.push(...(0, aspects_2.generateAspectsOutput)('[ASPECTS]', aspects, settings));
49
- outputLines.push('');
50
- };
51
- const processTransitChartInfoOutput = (transitData) => {
52
- outputLines.push(...(0, chartHeader_1.generateChartHeaderOutput)(transitData.name || 'Current', 'TRANSIT'));
53
- outputLines.push(...(0, birthdata_1.generateBirthdataOutput)(transitData.location, transitData.timestamp, settings, '[DATETIME]'));
54
- // For transit chart's own planets, houses are usually not shown unless it's a full natal chart for that moment.
55
- outputLines.push(...(0, planets_1.generatePlanetsOutput)(transitData.planets, transitData.houseCusps, settings));
56
- outputLines.push('');
57
- };
58
- if ('chart1' in data) {
59
- // MultiChartData
60
- const multiData = data;
61
- const chart1 = multiData.chart1;
62
- const chart1Name = chart1.name || 'Chart 1';
63
- processSingleChartOutput(chart1);
64
- if (multiData.chart2) {
65
- const chart2 = multiData.chart2;
66
- const chart2Name = chart2.name || 'Chart 2';
67
- processSingleChartOutput(chart2);
68
- // Synastry Section
69
- outputLines.push(...(0, chartHeader_1.generateChartHeaderOutput)(`${chart1Name}-${chart2Name}`, 'SYNASTRY'));
70
- const synastryAspects = (0, aspects_1.calculateMultichartAspects)(settings.aspectDefinitions, chart1.planets, chart2.planets);
71
- outputLines.push(...(0, aspects_2.generateAspectsOutput)('[PLANET-PLANET ASPECTS]', synastryAspects, settings, chart1Name, chart2Name));
72
- outputLines.push('');
73
- outputLines.push(...(0, houseOverlays_1.generateHouseOverlaysOutput)(chart1, chart2, settings));
74
- outputLines.push('');
128
+ const nonTransitCharts = data.filter(({ chartType }) => chartType !== 'transit');
129
+ const transitChart = data.find(({ chartType }) => chartType === 'transit');
130
+ // first, process each chart individually
131
+ for (const chart of nonTransitCharts) {
132
+ outputLines.push(...processSingleChartOutput(settings, chart));
133
+ }
134
+ // then, process each pairwise chart
135
+ for (let i = 0; i < nonTransitCharts.length; i++) {
136
+ for (let j = i + 1; j < nonTransitCharts.length; j++) {
137
+ outputLines.push(...processChartPairOutput(settings, nonTransitCharts[i], nonTransitCharts[j]));
75
138
  }
76
- if (multiData.transit) {
77
- const transit = multiData.transit;
78
- const transitName = transit.name || 'Current'; // Used for p2ChartName in transit aspects
79
- processTransitChartInfoOutput(transit);
139
+ }
140
+ // finally, process transit against each non-transit chart
141
+ if (transitChart) {
142
+ outputLines.push(...processTransitChartInfoOutput(settings, transitChart));
143
+ for (const chart of nonTransitCharts) {
80
144
  // Transit Aspects to Chart 1
81
- const transitAspectsC1 = (0, aspects_1.calculateMultichartAspects)(settings.aspectDefinitions, chart1.planets, transit.planets);
82
- outputLines.push(...(0, aspects_2.generateAspectsOutput)(`[TRANSIT ASPECTS: ${chart1Name}]`, transitAspectsC1, settings, chart1Name, transitName, true));
145
+ const transitAspectsC1 = (0, aspects_1.calculateMultichartAspects)(settings.aspectDefinitions, chart.planets, transitChart.planets, settings.skipOutOfSignAspects);
146
+ outputLines.push(...(0, aspects_2.generateAspectsOutput)(`[TRANSIT ASPECTS: ${chart.name}]`, transitAspectsC1, settings, chart.name, transitChart.name, true));
83
147
  outputLines.push('');
84
- if (multiData.chart2) {
85
- const chart2Name = multiData.chart2.name || 'Chart 2';
86
- // Transit Aspects to Chart 2
87
- const transitAspectsC2 = (0, aspects_1.calculateMultichartAspects)(settings.aspectDefinitions, multiData.chart2.planets, transit.planets);
88
- outputLines.push(...(0, aspects_2.generateAspectsOutput)(`[TRANSIT ASPECTS: ${chart2Name}]`, transitAspectsC2, settings, chart2Name, transitName, true));
89
- outputLines.push('');
90
- }
91
148
  }
92
149
  }
93
- else {
94
- // Single ChartData object
95
- processSingleChartOutput(data);
96
- }
97
150
  return outputLines.join('\n').trimEnd();
98
151
  }
package/dist/types.d.ts CHANGED
@@ -4,7 +4,7 @@ export interface Point {
4
4
  speed?: number;
5
5
  }
6
6
  export interface ChartData {
7
- name?: string;
7
+ name: string;
8
8
  planets: Point[];
9
9
  ascendant?: number;
10
10
  midheaven?: number;
@@ -13,12 +13,9 @@ export interface ChartData {
13
13
  houseSystemName?: string;
14
14
  timestamp?: Date;
15
15
  location?: string;
16
+ chartType?: 'natal' | 'event' | 'transit';
16
17
  }
17
- export interface MultiChartData {
18
- chart1: ChartData;
19
- chart2?: ChartData;
20
- transit?: ChartData;
21
- }
18
+ export type MultiChartData = ChartData[];
22
19
  export declare function isMultiChartData(obj: ChartData | MultiChartData): obj is MultiChartData;
23
20
  export interface Aspect {
24
21
  name: string;
@@ -39,9 +36,11 @@ export interface AspectCategory {
39
36
  export interface Settings {
40
37
  includeSignDegree: boolean;
41
38
  includeAscendant: boolean;
39
+ houseSystemName: string;
42
40
  includeHouseDegree: boolean;
43
41
  aspectDefinitions: Aspect[];
44
42
  aspectCategories: AspectCategory[];
43
+ skipOutOfSignAspects: boolean;
45
44
  dateFormat: string;
46
45
  }
47
46
  export type PartialSettings = Partial<Settings>;
package/dist/types.js CHANGED
@@ -2,6 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isMultiChartData = isMultiChartData;
4
4
  function isMultiChartData(obj) {
5
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
- return obj.chart1 !== undefined;
5
+ return Array.isArray(obj);
7
6
  }
package/package.json CHANGED
@@ -1,45 +1,47 @@
1
- {
2
- "name": "chart2txt",
3
- "version": "0.4.0",
4
- "description": "Convert astrological chart data to human-readable text",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "browser": "dist/chart2txt.min.js",
8
- "scripts": {
9
- "build": "tsc && webpack",
10
- "build:tsc": "tsc",
11
- "build:webpack": "webpack",
12
- "test": "jest",
13
- "lint": "eslint src/**/*.ts",
14
- "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\""
15
- },
16
- "keywords": [
17
- "astrology",
18
- "chart",
19
- "text"
20
- ],
21
- "homepage": "https://github.com/simpolism/chart2txt",
22
- "author": "simpolism <simpolism@gmail.com>",
23
- "license": "MIT",
24
- "devDependencies": {
25
- "@types/jest": "^29.5.0",
26
- "@types/node": "^18.0.0",
27
- "@typescript-eslint/eslint-plugin": "^5.0.0",
28
- "@typescript-eslint/parser": "^5.0.0",
29
- "eslint": "^8.0.0",
30
- "eslint-config-prettier": "^8.0.0",
31
- "jest": "^29.0.0",
32
- "prettier": "^2.0.0",
33
- "ts-jest": "^29.1.0",
34
- "ts-loader": "^9.4.4",
35
- "typescript": "^5.0.0",
36
- "webpack": "^5.88.2",
37
- "webpack-cli": "^5.1.4",
38
- "terser-webpack-plugin": "^5.3.9"
39
- },
40
- "files": [
41
- "dist",
42
- "LICENSE",
43
- "README.md"
44
- ]
45
- }
1
+ {
2
+ "name": "chart2txt",
3
+ "version": "0.5.1",
4
+ "description": "Convert astrological chart data to human-readable text",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "browser": "dist/chart2txt.min.js",
8
+ "scripts": {
9
+ "build": "tsc && webpack",
10
+ "build:tsc": "tsc",
11
+ "build:webpack": "webpack",
12
+ "test": "jest",
13
+ "test:config": "ts-node test-configurations.ts",
14
+ "lint": "eslint src/**/*.ts",
15
+ "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\""
16
+ },
17
+ "keywords": [
18
+ "astrology",
19
+ "chart",
20
+ "text"
21
+ ],
22
+ "homepage": "https://github.com/simpolism/chart2txt",
23
+ "author": "simpolism <simpolism@gmail.com>",
24
+ "license": "MIT",
25
+ "devDependencies": {
26
+ "@types/jest": "^29.5.0",
27
+ "@types/node": "^18.0.0",
28
+ "@typescript-eslint/eslint-plugin": "^5.0.0",
29
+ "@typescript-eslint/parser": "^5.0.0",
30
+ "eslint": "^8.0.0",
31
+ "eslint-config-prettier": "^8.0.0",
32
+ "jest": "^29.0.0",
33
+ "prettier": "^2.0.0",
34
+ "terser-webpack-plugin": "^5.3.9",
35
+ "ts-jest": "^29.1.0",
36
+ "ts-loader": "^9.4.4",
37
+ "ts-node": "^10.9.2",
38
+ "typescript": "^5.0.0",
39
+ "webpack": "^5.88.2",
40
+ "webpack-cli": "^5.1.4"
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "LICENSE",
45
+ "README.md"
46
+ ]
47
+ }