mingpan 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +118 -0
  3. package/dist/core/bazi/BaziCore.d.ts +112 -0
  4. package/dist/core/bazi/BaziCore.d.ts.map +1 -0
  5. package/dist/core/bazi/BaziCore.js +606 -0
  6. package/dist/core/bazi/BaziCore.js.map +1 -0
  7. package/dist/core/bazi/SolarTermCalculator.d.ts +46 -0
  8. package/dist/core/bazi/SolarTermCalculator.d.ts.map +1 -0
  9. package/dist/core/bazi/SolarTermCalculator.js +452 -0
  10. package/dist/core/bazi/SolarTermCalculator.js.map +1 -0
  11. package/dist/core/bazi/TrueSolarTime.d.ts +64 -0
  12. package/dist/core/bazi/TrueSolarTime.d.ts.map +1 -0
  13. package/dist/core/bazi/TrueSolarTime.js +210 -0
  14. package/dist/core/bazi/TrueSolarTime.js.map +1 -0
  15. package/dist/core/bazi/ephemerisData.d.ts +10 -0
  16. package/dist/core/bazi/ephemerisData.d.ts.map +1 -0
  17. package/dist/core/bazi/ephemerisData.js +88 -0
  18. package/dist/core/bazi/ephemerisData.js.map +1 -0
  19. package/dist/core/bazi/index.d.ts +8 -0
  20. package/dist/core/bazi/index.d.ts.map +1 -0
  21. package/dist/core/bazi/index.js +30 -0
  22. package/dist/core/bazi/index.js.map +1 -0
  23. package/dist/core/bazi/types.d.ts +116 -0
  24. package/dist/core/bazi/types.d.ts.map +1 -0
  25. package/dist/core/bazi/types.js +7 -0
  26. package/dist/core/bazi/types.js.map +1 -0
  27. package/dist/core/calendar/SolarTermsCalculator.d.ts +33 -0
  28. package/dist/core/calendar/SolarTermsCalculator.d.ts.map +1 -0
  29. package/dist/core/calendar/SolarTermsCalculator.js +111 -0
  30. package/dist/core/calendar/SolarTermsCalculator.js.map +1 -0
  31. package/dist/core/calendar/astronomicalCalendar.d.ts +74 -0
  32. package/dist/core/calendar/astronomicalCalendar.d.ts.map +1 -0
  33. package/dist/core/calendar/astronomicalCalendar.js +276 -0
  34. package/dist/core/calendar/astronomicalCalendar.js.map +1 -0
  35. package/dist/core/calendar/calendar.d.ts +81 -0
  36. package/dist/core/calendar/calendar.d.ts.map +1 -0
  37. package/dist/core/calendar/calendar.js +223 -0
  38. package/dist/core/calendar/calendar.js.map +1 -0
  39. package/dist/core/calendar/constants.d.ts +151 -0
  40. package/dist/core/calendar/constants.d.ts.map +1 -0
  41. package/dist/core/calendar/constants.js +97 -0
  42. package/dist/core/calendar/constants.js.map +1 -0
  43. package/dist/core/calendar/julian.d.ts +54 -0
  44. package/dist/core/calendar/julian.d.ts.map +1 -0
  45. package/dist/core/calendar/julian.js +142 -0
  46. package/dist/core/calendar/julian.js.map +1 -0
  47. package/dist/core/calendar/lunarCalendar.d.ts +79 -0
  48. package/dist/core/calendar/lunarCalendar.d.ts.map +1 -0
  49. package/dist/core/calendar/lunarCalendar.js +164 -0
  50. package/dist/core/calendar/lunarCalendar.js.map +1 -0
  51. package/dist/core/calendar/solarTerms.d.ts +105 -0
  52. package/dist/core/calendar/solarTerms.d.ts.map +1 -0
  53. package/dist/core/calendar/solarTerms.js +487 -0
  54. package/dist/core/calendar/solarTerms.js.map +1 -0
  55. package/dist/core/constants/bazi.d.ts +138 -0
  56. package/dist/core/constants/bazi.d.ts.map +1 -0
  57. package/dist/core/constants/bazi.js +332 -0
  58. package/dist/core/constants/bazi.js.map +1 -0
  59. package/dist/core/constants/index.d.ts +6 -0
  60. package/dist/core/constants/index.d.ts.map +1 -0
  61. package/dist/core/constants/index.js +37 -0
  62. package/dist/core/constants/index.js.map +1 -0
  63. package/dist/core/constants/positions.d.ts +27 -0
  64. package/dist/core/constants/positions.d.ts.map +1 -0
  65. package/dist/core/constants/positions.js +39 -0
  66. package/dist/core/constants/positions.js.map +1 -0
  67. package/dist/core/ziwei/BrightnessSystem.d.ts +53 -0
  68. package/dist/core/ziwei/BrightnessSystem.d.ts.map +1 -0
  69. package/dist/core/ziwei/BrightnessSystem.js +278 -0
  70. package/dist/core/ziwei/BrightnessSystem.js.map +1 -0
  71. package/dist/core/ziwei/IztroAdapter.d.ts +78 -0
  72. package/dist/core/ziwei/IztroAdapter.d.ts.map +1 -0
  73. package/dist/core/ziwei/IztroAdapter.js +314 -0
  74. package/dist/core/ziwei/IztroAdapter.js.map +1 -0
  75. package/dist/core/ziwei/MutagenCore.d.ts +81 -0
  76. package/dist/core/ziwei/MutagenCore.d.ts.map +1 -0
  77. package/dist/core/ziwei/MutagenCore.js +246 -0
  78. package/dist/core/ziwei/MutagenCore.js.map +1 -0
  79. package/dist/index.d.ts +13 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +1101 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/output/fortuneTextRenderer.d.ts +63 -0
  84. package/dist/output/fortuneTextRenderer.d.ts.map +1 -0
  85. package/dist/output/fortuneTextRenderer.js +384 -0
  86. package/dist/output/fortuneTextRenderer.js.map +1 -0
  87. package/dist/output/listTextRenderer.d.ts +298 -0
  88. package/dist/output/listTextRenderer.d.ts.map +1 -0
  89. package/dist/output/listTextRenderer.js +942 -0
  90. package/dist/output/listTextRenderer.js.map +1 -0
  91. package/dist/services/bazi/BaziService.d.ts +83 -0
  92. package/dist/services/bazi/BaziService.d.ts.map +1 -0
  93. package/dist/services/bazi/BaziService.js +635 -0
  94. package/dist/services/bazi/BaziService.js.map +1 -0
  95. package/dist/services/bazi/analyzers/ClimateAnalyzer.d.ts +31 -0
  96. package/dist/services/bazi/analyzers/ClimateAnalyzer.d.ts.map +1 -0
  97. package/dist/services/bazi/analyzers/ClimateAnalyzer.js +194 -0
  98. package/dist/services/bazi/analyzers/ClimateAnalyzer.js.map +1 -0
  99. package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.d.ts +16 -0
  100. package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.d.ts.map +1 -0
  101. package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.js +60 -0
  102. package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.js.map +1 -0
  103. package/dist/services/bazi/analyzers/NaYinAnalyzer.d.ts +33 -0
  104. package/dist/services/bazi/analyzers/NaYinAnalyzer.d.ts.map +1 -0
  105. package/dist/services/bazi/analyzers/NaYinAnalyzer.js +209 -0
  106. package/dist/services/bazi/analyzers/NaYinAnalyzer.js.map +1 -0
  107. package/dist/services/bazi/analyzers/PatternAnalyzer.d.ts +159 -0
  108. package/dist/services/bazi/analyzers/PatternAnalyzer.d.ts.map +1 -0
  109. package/dist/services/bazi/analyzers/PatternAnalyzer.js +1150 -0
  110. package/dist/services/bazi/analyzers/PatternAnalyzer.js.map +1 -0
  111. package/dist/services/bazi/analyzers/RelationsAnalyzer.d.ts +114 -0
  112. package/dist/services/bazi/analyzers/RelationsAnalyzer.d.ts.map +1 -0
  113. package/dist/services/bazi/analyzers/RelationsAnalyzer.js +704 -0
  114. package/dist/services/bazi/analyzers/RelationsAnalyzer.js.map +1 -0
  115. package/dist/services/bazi/analyzers/ShenShaAnalyzer.d.ts +236 -0
  116. package/dist/services/bazi/analyzers/ShenShaAnalyzer.d.ts.map +1 -0
  117. package/dist/services/bazi/analyzers/ShenShaAnalyzer.js +2079 -0
  118. package/dist/services/bazi/analyzers/ShenShaAnalyzer.js.map +1 -0
  119. package/dist/services/bazi/analyzers/StrengthAnalyzer.d.ts +181 -0
  120. package/dist/services/bazi/analyzers/StrengthAnalyzer.d.ts.map +1 -0
  121. package/dist/services/bazi/analyzers/StrengthAnalyzer.js +1119 -0
  122. package/dist/services/bazi/analyzers/StrengthAnalyzer.js.map +1 -0
  123. package/dist/services/bazi/analyzers/TenGodsAnalyzer.d.ts +78 -0
  124. package/dist/services/bazi/analyzers/TenGodsAnalyzer.d.ts.map +1 -0
  125. package/dist/services/bazi/analyzers/TenGodsAnalyzer.js +383 -0
  126. package/dist/services/bazi/analyzers/TenGodsAnalyzer.js.map +1 -0
  127. package/dist/services/bazi/analyzers/TraditionalAnalyzer.d.ts +46 -0
  128. package/dist/services/bazi/analyzers/TraditionalAnalyzer.d.ts.map +1 -0
  129. package/dist/services/bazi/analyzers/TraditionalAnalyzer.js +260 -0
  130. package/dist/services/bazi/analyzers/TraditionalAnalyzer.js.map +1 -0
  131. package/dist/services/bazi/analyzers/YongShenAnalyzer.d.ts +70 -0
  132. package/dist/services/bazi/analyzers/YongShenAnalyzer.d.ts.map +1 -0
  133. package/dist/services/bazi/analyzers/YongShenAnalyzer.js +858 -0
  134. package/dist/services/bazi/analyzers/YongShenAnalyzer.js.map +1 -0
  135. package/dist/services/bazi/calculators/DaYunCalculator.d.ts +71 -0
  136. package/dist/services/bazi/calculators/DaYunCalculator.d.ts.map +1 -0
  137. package/dist/services/bazi/calculators/DaYunCalculator.js +496 -0
  138. package/dist/services/bazi/calculators/DaYunCalculator.js.map +1 -0
  139. package/dist/services/bazi/calculators/LiuNianCalculator.d.ts +88 -0
  140. package/dist/services/bazi/calculators/LiuNianCalculator.d.ts.map +1 -0
  141. package/dist/services/bazi/calculators/LiuNianCalculator.js +546 -0
  142. package/dist/services/bazi/calculators/LiuNianCalculator.js.map +1 -0
  143. package/dist/services/bazi/calculators/LiuRiCalculator.d.ts +66 -0
  144. package/dist/services/bazi/calculators/LiuRiCalculator.d.ts.map +1 -0
  145. package/dist/services/bazi/calculators/LiuRiCalculator.js +497 -0
  146. package/dist/services/bazi/calculators/LiuRiCalculator.js.map +1 -0
  147. package/dist/services/bazi/calculators/LiuYueCalculator.d.ts +50 -0
  148. package/dist/services/bazi/calculators/LiuYueCalculator.d.ts.map +1 -0
  149. package/dist/services/bazi/calculators/LiuYueCalculator.js +338 -0
  150. package/dist/services/bazi/calculators/LiuYueCalculator.js.map +1 -0
  151. package/dist/services/bazi/calculators/LuckCycleCalculator.d.ts +123 -0
  152. package/dist/services/bazi/calculators/LuckCycleCalculator.d.ts.map +1 -0
  153. package/dist/services/bazi/calculators/LuckCycleCalculator.js +414 -0
  154. package/dist/services/bazi/calculators/LuckCycleCalculator.js.map +1 -0
  155. package/dist/services/bazi/index.d.ts +21 -0
  156. package/dist/services/bazi/index.d.ts.map +1 -0
  157. package/dist/services/bazi/index.js +83 -0
  158. package/dist/services/bazi/index.js.map +1 -0
  159. package/dist/services/bazi/types.d.ts +597 -0
  160. package/dist/services/bazi/types.d.ts.map +1 -0
  161. package/dist/services/bazi/types.js +123 -0
  162. package/dist/services/bazi/types.js.map +1 -0
  163. package/dist/services/ziwei/ZiweiService.d.ts +86 -0
  164. package/dist/services/ziwei/ZiweiService.d.ts.map +1 -0
  165. package/dist/services/ziwei/ZiweiService.js +343 -0
  166. package/dist/services/ziwei/ZiweiService.js.map +1 -0
  167. package/dist/services/ziwei/calculators/BrightnessCalculator.d.ts +38 -0
  168. package/dist/services/ziwei/calculators/BrightnessCalculator.d.ts.map +1 -0
  169. package/dist/services/ziwei/calculators/BrightnessCalculator.js +142 -0
  170. package/dist/services/ziwei/calculators/BrightnessCalculator.js.map +1 -0
  171. package/dist/services/ziwei/calculators/DailyCalculator.d.ts +27 -0
  172. package/dist/services/ziwei/calculators/DailyCalculator.d.ts.map +1 -0
  173. package/dist/services/ziwei/calculators/DailyCalculator.js +55 -0
  174. package/dist/services/ziwei/calculators/DailyCalculator.js.map +1 -0
  175. package/dist/services/ziwei/calculators/DecadeCalculator.d.ts +46 -0
  176. package/dist/services/ziwei/calculators/DecadeCalculator.d.ts.map +1 -0
  177. package/dist/services/ziwei/calculators/DecadeCalculator.js +181 -0
  178. package/dist/services/ziwei/calculators/DecadeCalculator.js.map +1 -0
  179. package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.d.ts +28 -0
  180. package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.d.ts.map +1 -0
  181. package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.js +84 -0
  182. package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.js.map +1 -0
  183. package/dist/services/ziwei/calculators/HourlyCalculator.d.ts +41 -0
  184. package/dist/services/ziwei/calculators/HourlyCalculator.d.ts.map +1 -0
  185. package/dist/services/ziwei/calculators/HourlyCalculator.js +139 -0
  186. package/dist/services/ziwei/calculators/HourlyCalculator.js.map +1 -0
  187. package/dist/services/ziwei/calculators/MinorLimitCalculator.d.ts +30 -0
  188. package/dist/services/ziwei/calculators/MinorLimitCalculator.d.ts.map +1 -0
  189. package/dist/services/ziwei/calculators/MinorLimitCalculator.js +90 -0
  190. package/dist/services/ziwei/calculators/MinorLimitCalculator.js.map +1 -0
  191. package/dist/services/ziwei/calculators/MonthlyCalculator.d.ts +39 -0
  192. package/dist/services/ziwei/calculators/MonthlyCalculator.d.ts.map +1 -0
  193. package/dist/services/ziwei/calculators/MonthlyCalculator.js +128 -0
  194. package/dist/services/ziwei/calculators/MonthlyCalculator.js.map +1 -0
  195. package/dist/services/ziwei/calculators/MutagenCalculator.d.ts +20 -0
  196. package/dist/services/ziwei/calculators/MutagenCalculator.d.ts.map +1 -0
  197. package/dist/services/ziwei/calculators/MutagenCalculator.js +121 -0
  198. package/dist/services/ziwei/calculators/MutagenCalculator.js.map +1 -0
  199. package/dist/services/ziwei/calculators/PalaceDynamicCalculator.d.ts +35 -0
  200. package/dist/services/ziwei/calculators/PalaceDynamicCalculator.d.ts.map +1 -0
  201. package/dist/services/ziwei/calculators/PalaceDynamicCalculator.js +55 -0
  202. package/dist/services/ziwei/calculators/PalaceDynamicCalculator.js.map +1 -0
  203. package/dist/services/ziwei/calculators/YearlyCalculator.d.ts +35 -0
  204. package/dist/services/ziwei/calculators/YearlyCalculator.d.ts.map +1 -0
  205. package/dist/services/ziwei/calculators/YearlyCalculator.js +119 -0
  206. package/dist/services/ziwei/calculators/YearlyCalculator.js.map +1 -0
  207. package/dist/services/ziwei/index.d.ts +15 -0
  208. package/dist/services/ziwei/index.d.ts.map +1 -0
  209. package/dist/services/ziwei/index.js +48 -0
  210. package/dist/services/ziwei/index.js.map +1 -0
  211. package/dist/services/ziwei/transformers/PalaceTransformer.d.ts +62 -0
  212. package/dist/services/ziwei/transformers/PalaceTransformer.d.ts.map +1 -0
  213. package/dist/services/ziwei/transformers/PalaceTransformer.js +153 -0
  214. package/dist/services/ziwei/transformers/PalaceTransformer.js.map +1 -0
  215. package/dist/services/ziwei/types.d.ts +185 -0
  216. package/dist/services/ziwei/types.d.ts.map +1 -0
  217. package/dist/services/ziwei/types.js +54 -0
  218. package/dist/services/ziwei/types.js.map +1 -0
  219. package/dist/shared/logger.d.ts +51 -0
  220. package/dist/shared/logger.d.ts.map +1 -0
  221. package/dist/shared/logger.js +136 -0
  222. package/dist/shared/logger.js.map +1 -0
  223. package/dist/shared/types.d.ts +91 -0
  224. package/dist/shared/types.d.ts.map +1 -0
  225. package/dist/shared/types.js +7 -0
  226. package/dist/shared/types.js.map +1 -0
  227. package/dist/utils/ageCalculator.d.ts +30 -0
  228. package/dist/utils/ageCalculator.d.ts.map +1 -0
  229. package/dist/utils/ageCalculator.js +51 -0
  230. package/dist/utils/ageCalculator.js.map +1 -0
  231. package/package.json +54 -0
@@ -0,0 +1,704 @@
1
+ "use strict";
2
+ /**
3
+ * Relations Analyzer
4
+ * Comprehensive stem and branch relation system from taro-bazi
5
+ * Implements complete Heavenly Stem Combinations and Earthly Branch Relations
6
+ * Returns language-agnostic data with translation keys for internationalization
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.RelationsAnalyzer = void 0;
10
+ const positions_1 = require("../../../core/constants/positions");
11
+ class RelationsAnalyzer {
12
+ // Position indices for distance calculation
13
+ static POSITION_INDEX = positions_1.POSITION_INDICES;
14
+ /**
15
+ * Calculate relation type based on positions
16
+ * Returns positional relationship (相/隔/遥/争/双) and spacing
17
+ */
18
+ static getRelationByPosition(positions1, positions2) {
19
+ // 转换中文位置名称为内部键
20
+ const convertedPositions1 = positions1.map(pos => {
21
+ const key = (0, positions_1.getPositionKeyByName)(pos);
22
+ return key || pos; // 如果已经是英文键则保持不变
23
+ });
24
+ const convertedPositions2 = positions2.map(pos => {
25
+ const key = (0, positions_1.getPositionKeyByName)(pos);
26
+ return key || pos;
27
+ });
28
+ const totalCount = convertedPositions1.length + convertedPositions2.length;
29
+ if (totalCount === 2) {
30
+ const idx1 = this.POSITION_INDEX[convertedPositions1[0]];
31
+ const idx2 = this.POSITION_INDEX[convertedPositions2[0]];
32
+ const spacing = Math.abs(idx1 - idx2);
33
+ if (spacing === 1)
34
+ return { positionType: '相', spacing }; // Adjacent
35
+ if (spacing === 2)
36
+ return { positionType: '隔', spacing }; // Separated
37
+ if (spacing === 3)
38
+ return { positionType: '遥', spacing }; // Distant
39
+ }
40
+ else if (totalCount === 3) {
41
+ // One side has 2, other has 1
42
+ const multiPositions = convertedPositions1.length > 1 ? convertedPositions1 : convertedPositions2;
43
+ const singlePosition = convertedPositions1.length === 1 ? convertedPositions1[0] : convertedPositions2[0];
44
+ const idx1 = this.POSITION_INDEX[multiPositions[0]];
45
+ const idx2 = this.POSITION_INDEX[multiPositions[1]];
46
+ const idx3 = this.POSITION_INDEX[singlePosition];
47
+ const spacing1 = Math.abs(idx1 - idx3);
48
+ const spacing2 = Math.abs(idx2 - idx3);
49
+ if (spacing1 === 1 && spacing2 === 1) {
50
+ return { positionType: '争', spacing: 1 }; // Competing
51
+ }
52
+ else if (spacing1 === 1 || spacing2 === 1) {
53
+ return { positionType: '相', spacing: 1 }; // Adjacent
54
+ }
55
+ else {
56
+ return { positionType: '遥', spacing: Math.min(spacing1, spacing2) };
57
+ }
58
+ }
59
+ else if (totalCount === 4) {
60
+ if (convertedPositions1.length === convertedPositions2.length) {
61
+ const idx1 = this.POSITION_INDEX[convertedPositions1[0]];
62
+ const idx2 = this.POSITION_INDEX[convertedPositions1[1]];
63
+ const spacing = Math.abs(idx1 - idx2);
64
+ if (spacing === 1)
65
+ return { positionType: '相', spacing };
66
+ return { positionType: '双', spacing }; // Double
67
+ }
68
+ else {
69
+ const singlePosition = convertedPositions1.length === 1 ? convertedPositions1[0] : convertedPositions2[0];
70
+ const idx = this.POSITION_INDEX[singlePosition];
71
+ if (idx === 1 || idx === 2) { // Month or Day position
72
+ return { positionType: '相', spacing: 1 };
73
+ }
74
+ return { positionType: '争', spacing: 1 };
75
+ }
76
+ }
77
+ return { positionType: '遥', spacing: 3 };
78
+ }
79
+ /**
80
+ * Apply position strength modifier based on position type
81
+ * Adjacent relations are stronger, distant ones are weaker
82
+ */
83
+ static applyPositionModifier(baseStrength, positionType) {
84
+ switch (positionType) {
85
+ case '相': // Adjacent - full strength
86
+ return baseStrength;
87
+ case '争': // Competing - slightly reduced (multiple branches competing)
88
+ return Math.round(baseStrength * 0.9);
89
+ case '双': // Double - slightly enhanced (reinforced relationship)
90
+ return Math.min(10, Math.round(baseStrength * 1.1));
91
+ case '隔': // Separated - moderately reduced
92
+ return Math.round(baseStrength * 0.8);
93
+ case '遥': // Distant - more reduced but still significant
94
+ return Math.round(baseStrength * 0.6);
95
+ default:
96
+ return baseStrength;
97
+ }
98
+ }
99
+ /**
100
+ * Comprehensive analysis of all stem and branch relationships using taro-bazi system
101
+ */
102
+ static analyze(chart) {
103
+ const stems = [
104
+ { stem: chart.year.stem, position: '年柱' },
105
+ { stem: chart.month.stem, position: '月柱' },
106
+ { stem: chart.day.stem, position: '日柱' },
107
+ { stem: chart.hour.stem, position: '時柱' }
108
+ ];
109
+ const branches = [
110
+ { branch: chart.year.branch, position: '年柱' },
111
+ { branch: chart.month.branch, position: '月柱' },
112
+ { branch: chart.day.branch, position: '日柱' },
113
+ { branch: chart.hour.branch, position: '時柱' }
114
+ ];
115
+ const result = {
116
+ // Heavenly Stem Relations
117
+ stemCombinations: this.findStemCombinations(stems),
118
+ // Earthly Branch Relations
119
+ sixHarmonies: this.findSixHarmonies(branches),
120
+ sixConflicts: this.findSixConflicts(branches),
121
+ sixHarms: this.findSixHarms(branches),
122
+ threePunishments: this.findThreePunishments(branches),
123
+ threeHarmonies: this.findThreeHarmonies(branches),
124
+ sixDestructions: this.findSixDestructions(branches),
125
+ threeMeetings: this.findThreeMeetings(branches),
126
+ overview: {
127
+ totalRelations: 0,
128
+ positiveCount: 0,
129
+ negativeCount: 0,
130
+ dominantPattern: '',
131
+ harmonyScore: 0,
132
+ hasStemCombinations: false
133
+ }
134
+ };
135
+ // Calculate overview statistics
136
+ result.overview = this.calculateOverview(result);
137
+ return result;
138
+ }
139
+ /**
140
+ * Heavenly Stem Five Combinations (天干五合)
141
+ * Based on the reference document 八字教程-冲合刑害会.md
142
+ */
143
+ static findStemCombinations(stems) {
144
+ const combinations = [];
145
+ // Five combination pairs with their resulting elements and meanings
146
+ const fiveCombinationPairs = [
147
+ {
148
+ stems: ['甲', '己'],
149
+ element: '土',
150
+ strength: 8,
151
+ description: '甲己合化土',
152
+ meaning: '中正之合' // 中正之合
153
+ },
154
+ {
155
+ stems: ['乙', '庚'],
156
+ element: '金',
157
+ strength: 8,
158
+ description: '乙庚合化金',
159
+ meaning: '仁義之合' // 仁義之合
160
+ },
161
+ {
162
+ stems: ['丙', '辛'],
163
+ element: '水',
164
+ strength: 7,
165
+ description: '丙辛合化水',
166
+ meaning: '威制之合' // 威制之合
167
+ },
168
+ {
169
+ stems: ['丁', '壬'],
170
+ element: '木',
171
+ strength: 6,
172
+ description: '丁壬合化木',
173
+ meaning: '淫慝之合' // 淫慝之合
174
+ },
175
+ {
176
+ stems: ['戊', '癸'],
177
+ element: '火',
178
+ strength: 6,
179
+ description: '戊癸合化火',
180
+ meaning: '無情之合' // 無情之合
181
+ }
182
+ ];
183
+ for (const combination of fiveCombinationPairs) {
184
+ const found1 = stems.find(s => s.stem === combination.stems[0]);
185
+ const found2 = stems.find(s => s.stem === combination.stems[1]);
186
+ if (found1 && found2) {
187
+ combinations.push({
188
+ stems: [found1.stem, found2.stem],
189
+ positions: [found1.position, found2.position],
190
+ type: 'fiveCombination',
191
+ element: combination.element,
192
+ impact: '正面',
193
+ strength: combination.strength,
194
+ description: combination.description,
195
+ meaning: combination.meaning
196
+ });
197
+ }
198
+ }
199
+ return combinations;
200
+ }
201
+ /**
202
+ * Six Harmonies (六合) - Most favorable relationships
203
+ * Precise implementation from taro-bazi
204
+ */
205
+ static findSixHarmonies(branches) {
206
+ const harmonies = [];
207
+ // Taro-bazi's exact six harmony pairs with their elements
208
+ const sixHarmonyPairs = [
209
+ { branches: ['子', '丑'], element: '土', strength: 8, description: '子丑合化土' },
210
+ { branches: ['寅', '亥'], element: '木', strength: 9, description: '寅亥合化木' },
211
+ { branches: ['卯', '戌'], element: '火', strength: 7, description: '卯戌合化火' },
212
+ { branches: ['辰', '酉'], element: '金', strength: 8, description: '辰酉合化金' },
213
+ { branches: ['巳', '申'], element: '水', strength: 6, description: '巳申合化水' },
214
+ { branches: ['午', '未'], element: '火', strength: 9, description: '午未合化火' }
215
+ ];
216
+ for (const harmony of sixHarmonyPairs) {
217
+ const found1 = branches.find(b => b.branch === harmony.branches[0]);
218
+ const found2 = branches.find(b => b.branch === harmony.branches[1]);
219
+ if (found1 && found2) {
220
+ const { positionType, spacing } = this.getRelationByPosition([found1.position], [found2.position]);
221
+ harmonies.push({
222
+ branches: [found1.branch, found2.branch],
223
+ positions: [found1.position, found2.position],
224
+ type: 'sixHarmony',
225
+ impact: '正面',
226
+ strength: this.applyPositionModifier(harmony.strength, positionType),
227
+ element: harmony.element,
228
+ description: harmony.description,
229
+ positionType,
230
+ spacing
231
+ });
232
+ }
233
+ }
234
+ return harmonies;
235
+ }
236
+ /**
237
+ * Six Conflicts (六沖) - Direct opposition relationships
238
+ */
239
+ static findSixConflicts(branches) {
240
+ const conflicts = [];
241
+ const sixConflictPairs = [
242
+ { branches: ['子', '午'], strength: 10, description: '子午相沖' },
243
+ { branches: ['丑', '未'], strength: 8, description: '丑未相沖' },
244
+ { branches: ['寅', '申'], strength: 9, description: '寅申相沖' },
245
+ { branches: ['卯', '酉'], strength: 9, description: '卯酉相沖' },
246
+ { branches: ['辰', '戌'], strength: 7, description: '辰戌相沖' },
247
+ { branches: ['巳', '亥'], strength: 8, description: '巳亥相沖' }
248
+ ];
249
+ for (const conflict of sixConflictPairs) {
250
+ const found1 = branches.find(b => b.branch === conflict.branches[0]);
251
+ const found2 = branches.find(b => b.branch === conflict.branches[1]);
252
+ if (found1 && found2) {
253
+ const { positionType, spacing } = this.getRelationByPosition([found1.position], [found2.position]);
254
+ conflicts.push({
255
+ branches: [found1.branch, found2.branch],
256
+ positions: [found1.position, found2.position],
257
+ type: 'sixConflict',
258
+ impact: '负面',
259
+ strength: this.applyPositionModifier(conflict.strength, positionType),
260
+ description: conflict.description,
261
+ positionType,
262
+ spacing
263
+ });
264
+ }
265
+ }
266
+ return conflicts;
267
+ }
268
+ /**
269
+ * Six Harms (六害) - Mutual harm relationships
270
+ */
271
+ static findSixHarms(branches) {
272
+ const harms = [];
273
+ const sixHarmPairs = [
274
+ { branches: ['子', '未'], strength: 7, description: '子未相害' },
275
+ { branches: ['丑', '午'], strength: 6, description: '丑午相害' },
276
+ { branches: ['寅', '巳'], strength: 8, description: '寅巳相害' },
277
+ { branches: ['卯', '辰'], strength: 5, description: '卯辰相害' },
278
+ { branches: ['申', '亥'], strength: 7, description: '申亥相害' },
279
+ { branches: ['酉', '戌'], strength: 6, description: '酉戌相害' }
280
+ ];
281
+ for (const harm of sixHarmPairs) {
282
+ const found1 = branches.find(b => b.branch === harm.branches[0]);
283
+ const found2 = branches.find(b => b.branch === harm.branches[1]);
284
+ if (found1 && found2) {
285
+ const { positionType, spacing } = this.getRelationByPosition([found1.position], [found2.position]);
286
+ harms.push({
287
+ branches: [found1.branch, found2.branch],
288
+ positions: [found1.position, found2.position],
289
+ type: 'sixHarm',
290
+ impact: '负面',
291
+ strength: this.applyPositionModifier(harm.strength, positionType),
292
+ description: harm.description,
293
+ positionType,
294
+ spacing
295
+ });
296
+ }
297
+ }
298
+ return harms;
299
+ }
300
+ /**
301
+ * Three Punishments (三刑) - Complex punishment relationships
302
+ * Implements taro-bazi's complete punishment system
303
+ */
304
+ static findThreePunishments(branches) {
305
+ const punishments = [];
306
+ // Self punishments (自刑)
307
+ const selfPunishments = ['辰', '午', '酉', '亥'];
308
+ for (const selfBranch of selfPunishments) {
309
+ const found = branches.filter(b => b.branch === selfBranch);
310
+ if (found.length > 1) {
311
+ // For self punishments, we analyze pairs
312
+ for (let i = 0; i < found.length - 1; i++) {
313
+ for (let j = i + 1; j < found.length; j++) {
314
+ const { positionType, spacing } = this.getRelationByPosition([found[i].position], [found[j].position]);
315
+ punishments.push({
316
+ branches: [found[i].branch, found[j].branch],
317
+ positions: [found[i].position, found[j].position],
318
+ type: 'threePunishment',
319
+ subtype: 'selfPunishment',
320
+ impact: '负面',
321
+ strength: this.applyPositionModifier(6, positionType),
322
+ description: `${selfBranch}${selfBranch}自刑`,
323
+ positionType,
324
+ spacing
325
+ });
326
+ }
327
+ }
328
+ }
329
+ }
330
+ // Ungrateful punishment (無恩之刑): 子-卯
331
+ const zi = branches.find(b => b.branch === '子');
332
+ const mao = branches.find(b => b.branch === '卯');
333
+ if (zi && mao) {
334
+ const { positionType, spacing } = this.getRelationByPosition([zi.position], [mao.position]);
335
+ punishments.push({
336
+ branches: [zi.branch, mao.branch],
337
+ positions: [zi.position, mao.position],
338
+ type: 'threePunishment',
339
+ subtype: 'ungratefulPunishment',
340
+ impact: '负面',
341
+ strength: this.applyPositionModifier(8, positionType),
342
+ description: '子卯無恩之刑',
343
+ positionType,
344
+ spacing
345
+ });
346
+ }
347
+ // Bullying punishment (恃勢之刑): 寅巳相刑, 巳申相刑, 申寅相刑
348
+ const yin = branches.find(b => b.branch === '寅');
349
+ const si = branches.find(b => b.branch === '巳');
350
+ const shen = branches.find(b => b.branch === '申');
351
+ // Check each punishment pair separately
352
+ if (yin && si) {
353
+ const { positionType, spacing } = this.getRelationByPosition([yin.position], [si.position]);
354
+ punishments.push({
355
+ branches: [yin.branch, si.branch],
356
+ positions: [yin.position, si.position],
357
+ type: 'threePunishment',
358
+ subtype: 'bullyingPunishment',
359
+ impact: '负面',
360
+ strength: this.applyPositionModifier(8, positionType),
361
+ description: '寅巳恃勢之刑',
362
+ positionType,
363
+ spacing
364
+ });
365
+ }
366
+ if (si && shen) {
367
+ const { positionType, spacing } = this.getRelationByPosition([si.position], [shen.position]);
368
+ punishments.push({
369
+ branches: [si.branch, shen.branch],
370
+ positions: [si.position, shen.position],
371
+ type: 'threePunishment',
372
+ subtype: 'bullyingPunishment',
373
+ impact: '负面',
374
+ strength: this.applyPositionModifier(8, positionType),
375
+ description: '巳申恃勢之刑',
376
+ positionType,
377
+ spacing
378
+ });
379
+ }
380
+ if (shen && yin) {
381
+ const { positionType, spacing } = this.getRelationByPosition([shen.position], [yin.position]);
382
+ punishments.push({
383
+ branches: [shen.branch, yin.branch],
384
+ positions: [shen.position, yin.position],
385
+ type: 'threePunishment',
386
+ subtype: 'bullyingPunishment',
387
+ impact: '负面',
388
+ strength: this.applyPositionModifier(8, positionType),
389
+ description: '申寅恃勢之刑',
390
+ positionType,
391
+ spacing
392
+ });
393
+ }
394
+ // Uncivilized punishment (無禮之刑): 丑戌相刑, 戌未相刑, 未丑相刑
395
+ const chou = branches.find(b => b.branch === '丑');
396
+ const xu = branches.find(b => b.branch === '戌');
397
+ const wei = branches.find(b => b.branch === '未');
398
+ // Check each punishment pair separately
399
+ if (chou && xu) {
400
+ const { positionType, spacing } = this.getRelationByPosition([chou.position], [xu.position]);
401
+ punishments.push({
402
+ branches: [chou.branch, xu.branch],
403
+ positions: [chou.position, xu.position],
404
+ type: 'threePunishment',
405
+ subtype: 'uncivilizedPunishment',
406
+ impact: '负面',
407
+ strength: this.applyPositionModifier(7, positionType),
408
+ description: '丑戌無禮之刑',
409
+ positionType,
410
+ spacing
411
+ });
412
+ }
413
+ if (xu && wei) {
414
+ const { positionType, spacing } = this.getRelationByPosition([xu.position], [wei.position]);
415
+ punishments.push({
416
+ branches: [xu.branch, wei.branch],
417
+ positions: [xu.position, wei.position],
418
+ type: 'threePunishment',
419
+ subtype: 'uncivilizedPunishment',
420
+ impact: '负面',
421
+ strength: this.applyPositionModifier(7, positionType),
422
+ description: '戌未無禮之刑',
423
+ positionType,
424
+ spacing
425
+ });
426
+ }
427
+ if (wei && chou) {
428
+ const { positionType, spacing } = this.getRelationByPosition([wei.position], [chou.position]);
429
+ punishments.push({
430
+ branches: [wei.branch, chou.branch],
431
+ positions: [wei.position, chou.position],
432
+ type: 'threePunishment',
433
+ subtype: 'uncivilizedPunishment',
434
+ impact: '负面',
435
+ strength: this.applyPositionModifier(7, positionType),
436
+ description: '未丑無禮之刑',
437
+ positionType,
438
+ spacing
439
+ });
440
+ }
441
+ return punishments;
442
+ }
443
+ /**
444
+ * Three Harmonies (三合) - Elemental triangle harmonies
445
+ */
446
+ static findThreeHarmonies(branches) {
447
+ const harmonies = [];
448
+ const threeHarmonyGroups = [
449
+ { branches: ['申', '子', '辰'], element: '水', strength: 10, description: '申子辰三合水局' },
450
+ { branches: ['亥', '卯', '未'], element: '木', strength: 10, description: '亥卯未三合木局' },
451
+ { branches: ['寅', '午', '戌'], element: '火', strength: 10, description: '寅午戌三合火局' },
452
+ { branches: ['巳', '酉', '丑'], element: '金', strength: 10, description: '巳酉丑三合金局' }
453
+ ];
454
+ for (const group of threeHarmonyGroups) {
455
+ const foundBranches = branches.filter(b => group.branches.includes(b.branch));
456
+ if (foundBranches.length >= 2) {
457
+ // Even partial three harmonies are significant
458
+ const baseStrength = foundBranches.length === 3 ? group.strength : group.strength - 2;
459
+ // Calculate position analysis for multi-branch relations
460
+ const positions = foundBranches.map(f => f.position);
461
+ let positionType = '遥';
462
+ let minSpacing = 3;
463
+ // Check spacing between all pairs
464
+ for (let i = 0; i < positions.length - 1; i++) {
465
+ for (let j = i + 1; j < positions.length; j++) {
466
+ // 转换中文位置名称为内部键
467
+ const key_i = (0, positions_1.getPositionKeyByName)(positions[i]) || positions[i];
468
+ const key_j = (0, positions_1.getPositionKeyByName)(positions[j]) || positions[j];
469
+ const spacing = Math.abs(this.POSITION_INDEX[key_i] - this.POSITION_INDEX[key_j]);
470
+ if (spacing < minSpacing) {
471
+ minSpacing = spacing;
472
+ if (spacing === 1)
473
+ positionType = '相';
474
+ else if (spacing === 2)
475
+ positionType = '隔';
476
+ }
477
+ }
478
+ }
479
+ // Special case for three-way harmonies
480
+ if (foundBranches.length === 3) {
481
+ const indices = positions.map(p => {
482
+ const key = (0, positions_1.getPositionKeyByName)(p) || p;
483
+ return this.POSITION_INDEX[key];
484
+ }).sort((a, b) => a - b);
485
+ if (indices[2] - indices[0] === 2) {
486
+ positionType = '争'; // Concentrated three-way harmony
487
+ }
488
+ }
489
+ harmonies.push({
490
+ branches: foundBranches.map(f => f.branch),
491
+ positions: foundBranches.map(f => f.position),
492
+ type: 'threeHarmony',
493
+ impact: '正面',
494
+ strength: this.applyPositionModifier(baseStrength, positionType),
495
+ element: group.element,
496
+ description: group.description,
497
+ positionType,
498
+ spacing: minSpacing
499
+ });
500
+ }
501
+ }
502
+ return harmonies;
503
+ }
504
+ /**
505
+ * Six Destructions (六破) - Destructive relationships
506
+ */
507
+ static findSixDestructions(branches) {
508
+ const destructions = [];
509
+ // Correct six destruction pairs based on traditional BaZi
510
+ const sixDestructionPairs = [
511
+ { branches: ['子', '酉'], strength: 6, description: '子酉相破' },
512
+ { branches: ['卯', '午'], strength: 6, description: '卯午相破' },
513
+ { branches: ['辰', '丑'], strength: 5, description: '辰丑相破' },
514
+ { branches: ['戌', '未'], strength: 5, description: '戌未相破' },
515
+ { branches: ['巳', '寅'], strength: 7, description: '巳寅相破' },
516
+ { branches: ['申', '亥'], strength: 7, description: '申亥相破' }
517
+ ];
518
+ for (const destruction of sixDestructionPairs) {
519
+ const found1 = branches.find(b => b.branch === destruction.branches[0]);
520
+ const found2 = branches.find(b => b.branch === destruction.branches[1]);
521
+ if (found1 && found2) {
522
+ const { positionType, spacing } = this.getRelationByPosition([found1.position], [found2.position]);
523
+ destructions.push({
524
+ branches: [found1.branch, found2.branch],
525
+ positions: [found1.position, found2.position],
526
+ type: 'sixDestruction',
527
+ impact: '负面',
528
+ strength: this.applyPositionModifier(destruction.strength, positionType),
529
+ description: destruction.description,
530
+ positionType,
531
+ spacing
532
+ });
533
+ }
534
+ }
535
+ return destructions;
536
+ }
537
+ /**
538
+ * Three Meetings (三會) - Directional season gatherings
539
+ */
540
+ static findThreeMeetings(branches) {
541
+ const meetings = [];
542
+ const threeMeetingGroups = [
543
+ { branches: ['亥', '子', '丑'], element: '水', season: 'winter', strength: 8, description: '亥子丑三會水局' },
544
+ { branches: ['寅', '卯', '辰'], element: '木', season: 'spring', strength: 8, description: '寅卯辰三會木局' },
545
+ { branches: ['巳', '午', '未'], element: '火', season: 'summer', strength: 8, description: '巳午未三會火局' },
546
+ { branches: ['申', '酉', '戌'], element: '金', season: 'autumn', strength: 8, description: '申酉戌三會金局' }
547
+ ];
548
+ for (const group of threeMeetingGroups) {
549
+ const foundBranches = branches.filter(b => group.branches.includes(b.branch));
550
+ if (foundBranches.length >= 2) {
551
+ const baseStrength = foundBranches.length === 3 ? group.strength : group.strength - 2;
552
+ // Calculate position analysis for multi-branch relations
553
+ const positions = foundBranches.map(f => f.position);
554
+ let positionType = '遥';
555
+ let minSpacing = 3;
556
+ // Check spacing between all pairs
557
+ for (let i = 0; i < positions.length - 1; i++) {
558
+ for (let j = i + 1; j < positions.length; j++) {
559
+ // 转换中文位置名称为内部键
560
+ const key_i = (0, positions_1.getPositionKeyByName)(positions[i]) || positions[i];
561
+ const key_j = (0, positions_1.getPositionKeyByName)(positions[j]) || positions[j];
562
+ const spacing = Math.abs(this.POSITION_INDEX[key_i] - this.POSITION_INDEX[key_j]);
563
+ if (spacing < minSpacing) {
564
+ minSpacing = spacing;
565
+ if (spacing === 1)
566
+ positionType = '相';
567
+ else if (spacing === 2)
568
+ positionType = '隔';
569
+ }
570
+ }
571
+ }
572
+ // Special case for three meetings - consecutive positions are especially powerful
573
+ if (foundBranches.length === 3) {
574
+ const indices = positions.map(p => {
575
+ const key = (0, positions_1.getPositionKeyByName)(p) || p;
576
+ return this.POSITION_INDEX[key];
577
+ }).sort((a, b) => a - b);
578
+ if (indices[2] - indices[0] === 2 && indices[1] - indices[0] === 1) {
579
+ positionType = '争'; // Perfect seasonal meeting
580
+ }
581
+ }
582
+ meetings.push({
583
+ branches: foundBranches.map(f => f.branch),
584
+ positions: foundBranches.map(f => f.position),
585
+ type: 'threeMeeting',
586
+ impact: '正面',
587
+ strength: this.applyPositionModifier(baseStrength, positionType),
588
+ element: group.element,
589
+ description: group.description,
590
+ positionType,
591
+ spacing: minSpacing
592
+ });
593
+ }
594
+ }
595
+ return meetings;
596
+ }
597
+ /**
598
+ * Calculate comprehensive overview statistics
599
+ */
600
+ static calculateOverview(result) {
601
+ const allBranchRelations = [
602
+ ...result.sixHarmonies,
603
+ ...result.sixConflicts,
604
+ ...result.sixHarms,
605
+ ...result.threePunishments,
606
+ ...result.threeHarmonies,
607
+ ...result.sixDestructions,
608
+ ...result.threeMeetings
609
+ ];
610
+ const totalRelations = allBranchRelations.length + result.stemCombinations.length;
611
+ const positiveCount = allBranchRelations.filter(r => r.impact === '正面').length + result.stemCombinations.length;
612
+ const negativeCount = allBranchRelations.filter(r => r.impact === '负面').length;
613
+ // Calculate harmony score (0-100)
614
+ let harmonyScore = 50; // Base score
615
+ // Add points for positive branch relations
616
+ allBranchRelations.forEach(relation => {
617
+ if (relation.impact === '正面') {
618
+ harmonyScore += relation.strength;
619
+ }
620
+ else if (relation.impact === '负面') {
621
+ harmonyScore -= relation.strength;
622
+ }
623
+ });
624
+ // Add points for stem combinations (always positive)
625
+ result.stemCombinations.forEach(combination => {
626
+ harmonyScore += combination.strength;
627
+ });
628
+ // Normalize to 0-100 range
629
+ harmonyScore = Math.max(0, Math.min(100, harmonyScore));
630
+ // Determine dominant pattern
631
+ let dominantPattern = '平衡';
632
+ if (result.stemCombinations.length >= 2) {
633
+ dominantPattern = '天干五合';
634
+ }
635
+ else if (result.threeHarmonies.length > 0) {
636
+ dominantPattern = '三合局';
637
+ }
638
+ else if (result.sixHarmonies.length >= 2) {
639
+ dominantPattern = '六合';
640
+ }
641
+ else if (result.sixConflicts.length >= 2) {
642
+ dominantPattern = '六沖';
643
+ }
644
+ else if (result.threePunishments.length > 0) {
645
+ dominantPattern = '三刑';
646
+ }
647
+ else if (positiveCount > negativeCount) {
648
+ dominantPattern = '和諧';
649
+ }
650
+ else if (negativeCount > positiveCount) {
651
+ dominantPattern = '衝突';
652
+ }
653
+ return {
654
+ totalRelations,
655
+ positiveCount,
656
+ negativeCount,
657
+ dominantPattern,
658
+ harmonyScore,
659
+ hasStemCombinations: result.stemCombinations.length > 0
660
+ };
661
+ }
662
+ /**
663
+ * Get relationship strength modifier for fortune calculations
664
+ * Used by other analyzers to factor in branch relationships
665
+ */
666
+ static getRelationshipModifier(result) {
667
+ const { harmonyScore, dominantPattern } = result.overview;
668
+ // Base modifier from harmony score
669
+ let modifier = (harmonyScore - 50) / 50; // Range: -1 to +1
670
+ // Additional modifiers for special patterns
671
+ if (dominantPattern === 'threeHarmony')
672
+ modifier += 0.3;
673
+ if (dominantPattern === 'sixHarmony')
674
+ modifier += 0.2;
675
+ if (dominantPattern === 'sixConflict')
676
+ modifier -= 0.3;
677
+ if (dominantPattern === 'threePunishment')
678
+ modifier -= 0.4;
679
+ return Math.max(-1, Math.min(1, modifier));
680
+ }
681
+ /**
682
+ * Check if specific relationship type exists
683
+ * Utility method for other analyzers
684
+ */
685
+ static hasRelationType(result, type) {
686
+ // Check stem combinations
687
+ if (type === 'fiveCombination' || type === 'stemCombination') {
688
+ return result.stemCombinations.length > 0;
689
+ }
690
+ // Check branch relations
691
+ const allBranchRelations = [
692
+ ...result.sixHarmonies,
693
+ ...result.sixConflicts,
694
+ ...result.sixHarms,
695
+ ...result.threePunishments,
696
+ ...result.threeHarmonies,
697
+ ...result.sixDestructions,
698
+ ...result.threeMeetings
699
+ ];
700
+ return allBranchRelations.some(relation => relation.type === type);
701
+ }
702
+ }
703
+ exports.RelationsAnalyzer = RelationsAnalyzer;
704
+ //# sourceMappingURL=RelationsAnalyzer.js.map