@gracefullight/saju 1.2.0 → 1.3.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.
@@ -81,6 +81,7 @@ describe("relations", () => {
81
81
  it("aggregates all relations", () => {
82
82
  const result = analyzeRelations("甲子", "庚午", "丙寅", "壬申");
83
83
  expect(result.all.length).toBe(result.combinations.length +
84
+ result.stemClashes.length +
84
85
  result.clashes.length +
85
86
  result.harms.length +
86
87
  result.punishments.length +
@@ -14,17 +14,21 @@ describe("yongshen", () => {
14
14
  expect(result.allElements[result.primary.key].isYongShen).toBe(true);
15
15
  });
16
16
  it("identifies kishen elements correctly", () => {
17
- const result = analyzeYongShen("甲子", "丙寅", "甲辰", "乙亥");
18
- const hasKiShen = Object.values(result.allElements).some((e) => e.isKiShen);
19
- expect(hasKiShen).toBe(true);
17
+ // Use a balanced chart where 억부 method is used (not formation)
18
+ const result = analyzeYongShen("甲子", "丙寅", "庚申", "丁亥");
19
+ if (result.method.key !== "formation") {
20
+ const hasKiShen = Object.values(result.allElements).some((e) => e.isKiShen);
21
+ expect(hasKiShen).toBe(true);
22
+ }
20
23
  });
21
24
  it("uses 억부 method for 중화 strength (조후 is adjustment, not primary)", () => {
22
25
  const result = analyzeYongShen("甲子", "丙寅", "庚申", "丁亥");
23
26
  expect(["balance", "formation"]).toContain(result.method.key);
24
27
  });
25
- it("uses 억부 method for extreme strength", () => {
28
+ it("uses formation method for extreme strength with 종강격", () => {
29
+ // All wood: extremely strong with no controller (metal) → 종강격
26
30
  const result = analyzeYongShen("甲寅", "甲寅", "甲寅", "甲寅");
27
- expect(result.method.key).toBe("balance");
31
+ expect(result.method.key).toBe("formation");
28
32
  });
29
33
  it("includes johuAdjustment field in result", () => {
30
34
  const result = analyzeYongShen("甲子", "丙寅", "甲辰", "乙亥");
@@ -1 +1 @@
1
- {"version":3,"file":"four-pillars.d.ts","sourceRoot":"","sources":["../../src/core/four-pillars.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"four-pillars.d.ts","sourceRoot":"","sources":["../../src/core/four-pillars.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,45 @@ export const TRADITIONAL_PRESET = {
13
13
  };
14
14
  export const presetA = STANDARD_PRESET;
15
15
  export const presetB = TRADITIONAL_PRESET;
16
+ /**
17
+ * Korea DST period: 1987-05-10 02:00 ~ 1988-10-08 03:00 (UTC+10)
18
+ * Returns the effective timezone offset in hours for a Korean datetime.
19
+ */
20
+ function getEffectiveKSTOffset(adapter, dtLocal) {
21
+ const y = adapter.getYear(dtLocal);
22
+ const m = adapter.getMonth(dtLocal);
23
+ const d = adapter.getDay(dtLocal);
24
+ const h = adapter.getHour(dtLocal);
25
+ // KDT start: 1987-05-10 02:00 KST (becomes 03:00 KDT)
26
+ // KDT end: 1988-10-08 03:00 KDT (becomes 02:00 KST)
27
+ const afterStart = y > 1987 || (y === 1987 && (m > 5 || (m === 5 && (d > 10 || (d === 10 && h >= 2)))));
28
+ const beforeEnd = y < 1988 || (y === 1988 && (m < 10 || (m === 10 && (d < 8 || (d === 8 && h < 3)))));
29
+ return afterStart && beforeEnd ? 10 : 9;
30
+ }
31
+ /**
32
+ * Approximate ΔT (TT - UT) in seconds.
33
+ * Based on polynomial expressions from Meeus / USNO.
34
+ */
35
+ function deltaT(year) {
36
+ if (year >= 2005 && year < 2050) {
37
+ const t = year - 2000;
38
+ return 62.92 + 0.32217 * t + 0.005589 * t * t;
39
+ }
40
+ if (year >= 1986 && year < 2005) {
41
+ const t = year - 2000;
42
+ return (63.86 +
43
+ 0.3345 * t -
44
+ 0.060374 * t * t +
45
+ 0.0017275 * t * t * t +
46
+ 0.000651814 * t * t * t * t +
47
+ 0.00002373599 * t * t * t * t * t);
48
+ }
49
+ if (year >= 1900 && year < 1986) {
50
+ const t = year - 1900;
51
+ return -0.02 + 0.000297 * t * t;
52
+ }
53
+ return 0;
54
+ }
16
55
  function normDeg(x) {
17
56
  x %= 360;
18
57
  return x < 0 ? x + 360 : x;
@@ -38,7 +77,10 @@ function sunApparentLongitude(adapter, dtUtc) {
38
77
  const A = Math.floor(y / 100);
39
78
  const B = 2 - A + Math.floor(A / 4);
40
79
  const JD = Math.floor(365.25 * (y + 4716)) + Math.floor(30.6001 * (m + 1)) + d + B - 1524.5;
41
- const T = (JD - 2451545.0) / 36525.0;
80
+ // Apply ΔT correction for TT
81
+ const dtSeconds = deltaT(y);
82
+ const JD_TT = JD + dtSeconds / 86400.0;
83
+ const T = (JD_TT - 2451545.0) / 36525.0;
42
84
  const L0 = normDeg(280.46646 + 36000.76983 * T + 0.0003032 * T * T);
43
85
  const M = normDeg(357.52911 + 35999.05029 * T - 0.0001537 * T * T);
44
86
  const deg2rad = (deg) => (deg * Math.PI) / 180;
@@ -171,7 +213,8 @@ export function hourPillar(dtLocal, { adapter, longitudeDeg, tzOffsetHours = 9,
171
213
  return { pillar: STEMS[hs] + BRANCHES[hb], adjustedDt: dtUsed, effectiveDate: effDate };
172
214
  }
173
215
  export function getFourPillars(dtLocal, { adapter, longitudeDeg, tzOffsetHours = 9, preset = presetA, }) {
174
- const effectiveLongitude = longitudeDeg ?? tzOffsetHours * 15;
216
+ const effectiveTzOffset = tzOffsetHours === 9 ? getEffectiveKSTOffset(adapter, dtLocal) : tzOffsetHours;
217
+ const effectiveLongitude = longitudeDeg ?? effectiveTzOffset * 15;
175
218
  const dayBoundary = preset.dayBoundary ?? "midnight";
176
219
  const useMeanSolarTimeForHour = preset.useMeanSolarTimeForHour ?? false;
177
220
  const useMeanSolarTimeForBoundary = preset.useMeanSolarTimeForBoundary ?? false;
@@ -181,14 +224,14 @@ export function getFourPillars(dtLocal, { adapter, longitudeDeg, tzOffsetHours =
181
224
  adapter,
182
225
  dayBoundary,
183
226
  longitudeDeg: effectiveLongitude,
184
- tzOffsetHours,
227
+ tzOffsetHours: effectiveTzOffset,
185
228
  useMeanSolarTimeForBoundary,
186
229
  });
187
230
  const d = dayPillarFromDate(effDate);
188
231
  const h = hourPillar(dtLocal, {
189
232
  adapter,
190
233
  longitudeDeg: effectiveLongitude,
191
- tzOffsetHours,
234
+ tzOffsetHours: effectiveTzOffset,
192
235
  useMeanSolarTimeForHour,
193
236
  dayBoundary,
194
237
  useMeanSolarTimeForBoundary,
@@ -1,4 +1,5 @@
1
1
  import type { DateAdapter } from "../adapters/date-adapter";
2
+ import { type SolarTermKey } from "../core/solar-terms";
2
3
  import type { Gender, Polarity } from "../types";
3
4
  export type { Gender };
4
5
  export interface LuckPillar {
@@ -45,6 +46,11 @@ export interface MonthlyLuckResult {
45
46
  stem: string;
46
47
  branch: string;
47
48
  pillar: string;
49
+ solarTerm: {
50
+ key: SolarTermKey;
51
+ korean: string;
52
+ hanja: string;
53
+ };
48
54
  }
49
55
  export declare function calculateMonthlyLuck(year: number, fromMonth: number, toMonth: number): MonthlyLuckResult[];
50
56
  export interface DailyLuckResult {
@@ -1 +1 @@
1
- {"version":3,"file":"luck.d.ts","sourceRoot":"","sources":["../../src/core/luck.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"luck.d.ts","sourceRoot":"","sources":["../../src/core/luck.ts"],"names":[],"mappings":"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"}
package/dist/core/luck.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { getSolarTermLabel } from "../core/solar-terms";
1
2
  import { getStemPolarity } from "../core/ten-gods";
2
3
  import { BRANCHES, getPillarIndex, jdnFromDate, pillarFromIndex, STEMS } from "../utils";
3
4
  export function calculateMajorLuck(birthDateTime, gender, yearPillar, monthPillar, options) {
@@ -79,6 +80,20 @@ export function getCurrentMajorLuck(majorLuck, age) {
79
80
  }
80
81
  return null;
81
82
  }
83
+ const MONTH_JIE_KEYS = [
84
+ "springBegins",
85
+ "awakeningInsects",
86
+ "pureBrightness",
87
+ "summerBegins",
88
+ "grainInEar",
89
+ "minorHeat",
90
+ "autumnBegins",
91
+ "whiteDew",
92
+ "coldDew",
93
+ "winterBegins",
94
+ "majorSnow",
95
+ "minorCold",
96
+ ];
82
97
  export function calculateMonthlyLuck(year, fromMonth, toMonth) {
83
98
  const results = [];
84
99
  const yearIdx60 = (((year - 1984) % 60) + 60) % 60;
@@ -92,12 +107,19 @@ export function calculateMonthlyLuck(year, fromMonth, toMonth) {
92
107
  const stem = STEMS[stemIdx];
93
108
  const branch = BRANCHES[branchIdx];
94
109
  const pillar = stem + branch;
110
+ const jieKey = MONTH_JIE_KEYS[monthOffset % 12];
111
+ const jieLabel = getSolarTermLabel(jieKey);
95
112
  results.push({
96
113
  year,
97
114
  month,
98
115
  stem,
99
116
  branch,
100
117
  pillar,
118
+ solarTerm: {
119
+ key: jieLabel.key,
120
+ korean: jieLabel.korean,
121
+ hanja: jieLabel.hanja,
122
+ },
101
123
  });
102
124
  }
103
125
  return results;
@@ -106,7 +128,7 @@ export function calculateDailyLuck(year, month, fromDay, toDay) {
106
128
  const results = [];
107
129
  for (let day = fromDay; day <= toDay; day++) {
108
130
  const jdn = jdnFromDate(year, month, day);
109
- const idx60 = (((jdn + 49) % 60) + 60) % 60;
131
+ const idx60 = (((jdn - 11) % 60) + 60) % 60;
110
132
  const stem = STEMS[idx60 % 10];
111
133
  const branch = BRANCHES[idx60 % 12];
112
134
  const pillar = stem + branch;
@@ -123,7 +145,7 @@ export function calculateDailyLuck(year, month, fromDay, toDay) {
123
145
  }
124
146
  export function getDayPillar(year, month, day) {
125
147
  const jdn = jdnFromDate(year, month, day);
126
- const idx60 = (((jdn + 49) % 60) + 60) % 60;
148
+ const idx60 = (((jdn - 11) % 60) + 60) % 60;
127
149
  return STEMS[idx60 % 10] + BRANCHES[idx60 % 12];
128
150
  }
129
151
  export function getMonthPillar(year, month) {
@@ -0,0 +1,16 @@
1
+ import type { Element } from "../types";
2
+ export interface NayinResult {
3
+ element: Element;
4
+ korean: string;
5
+ hanja: string;
6
+ }
7
+ export declare function getNayin(pillarIdx60: number): NayinResult;
8
+ export declare function getNayinFromPillar(pillar: string): NayinResult;
9
+ export interface FourPillarsNayin {
10
+ year: NayinResult;
11
+ month: NayinResult;
12
+ day: NayinResult;
13
+ hour: NayinResult;
14
+ }
15
+ export declare function analyzeFourPillarsNayin(yearPillar: string, monthPillar: string, dayPillar: string, hourPillar: string): FourPillarsNayin;
16
+ //# sourceMappingURL=nayin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nayin.d.ts","sourceRoot":"","sources":["../../src/core/nayin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAkEvC,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAMzD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAG9D;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,WAAW,CAAC;IACnB,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,gBAAgB,CAOlB"}
@@ -0,0 +1,83 @@
1
+ import { getPillarIndex } from "../utils";
2
+ const NAYIN_TABLE = {
3
+ 0: { element: "metal", korean: "해중금", hanja: "海中金" },
4
+ 1: { element: "metal", korean: "해중금", hanja: "海中金" },
5
+ 2: { element: "fire", korean: "노중화", hanja: "爐中火" },
6
+ 3: { element: "fire", korean: "노중화", hanja: "爐中火" },
7
+ 4: { element: "wood", korean: "대림목", hanja: "大林木" },
8
+ 5: { element: "wood", korean: "대림목", hanja: "大林木" },
9
+ 6: { element: "earth", korean: "노방토", hanja: "路傍土" },
10
+ 7: { element: "earth", korean: "노방토", hanja: "路傍土" },
11
+ 8: { element: "metal", korean: "검봉금", hanja: "劍鋒金" },
12
+ 9: { element: "metal", korean: "검봉금", hanja: "劍鋒金" },
13
+ 10: { element: "fire", korean: "산두화", hanja: "山頭火" },
14
+ 11: { element: "fire", korean: "산두화", hanja: "山頭火" },
15
+ 12: { element: "water", korean: "간하수", hanja: "澗下水" },
16
+ 13: { element: "water", korean: "간하수", hanja: "澗下水" },
17
+ 14: { element: "earth", korean: "성두토", hanja: "城頭土" },
18
+ 15: { element: "earth", korean: "성두토", hanja: "城頭土" },
19
+ 16: { element: "metal", korean: "백랍금", hanja: "白蠟金" },
20
+ 17: { element: "metal", korean: "백랍금", hanja: "白蠟金" },
21
+ 18: { element: "wood", korean: "양류목", hanja: "楊柳木" },
22
+ 19: { element: "wood", korean: "양류목", hanja: "楊柳木" },
23
+ 20: { element: "water", korean: "천천수", hanja: "泉中水" },
24
+ 21: { element: "water", korean: "천천수", hanja: "泉中水" },
25
+ 22: { element: "earth", korean: "옥상토", hanja: "屋上土" },
26
+ 23: { element: "earth", korean: "옥상토", hanja: "屋上土" },
27
+ 24: { element: "fire", korean: "벽력화", hanja: "霹靂火" },
28
+ 25: { element: "fire", korean: "벽력화", hanja: "霹靂火" },
29
+ 26: { element: "wood", korean: "송백목", hanja: "松柏木" },
30
+ 27: { element: "wood", korean: "송백목", hanja: "松柏木" },
31
+ 28: { element: "water", korean: "장류수", hanja: "長流水" },
32
+ 29: { element: "water", korean: "장류수", hanja: "長流水" },
33
+ 30: { element: "metal", korean: "사중금", hanja: "砂中金" },
34
+ 31: { element: "metal", korean: "사중금", hanja: "砂中金" },
35
+ 32: { element: "fire", korean: "산하화", hanja: "山下火" },
36
+ 33: { element: "fire", korean: "산하화", hanja: "山下火" },
37
+ 34: { element: "wood", korean: "평지목", hanja: "平地木" },
38
+ 35: { element: "wood", korean: "평지목", hanja: "平地木" },
39
+ 36: { element: "earth", korean: "벽상토", hanja: "壁上土" },
40
+ 37: { element: "earth", korean: "벽상토", hanja: "壁上土" },
41
+ 38: { element: "metal", korean: "금박금", hanja: "金箔金" },
42
+ 39: { element: "metal", korean: "금박금", hanja: "金箔金" },
43
+ 40: { element: "fire", korean: "복등화", hanja: "覆燈火" },
44
+ 41: { element: "fire", korean: "복등화", hanja: "覆燈火" },
45
+ 42: { element: "water", korean: "천하수", hanja: "天河水" },
46
+ 43: { element: "water", korean: "천하수", hanja: "天河水" },
47
+ 44: { element: "earth", korean: "대역토", hanja: "大驛土" },
48
+ 45: { element: "earth", korean: "대역토", hanja: "大驛土" },
49
+ 46: { element: "metal", korean: "채광금", hanja: "釵釧金" },
50
+ 47: { element: "metal", korean: "채광금", hanja: "釵釧金" },
51
+ 48: { element: "wood", korean: "상자목", hanja: "桑柘木" },
52
+ 49: { element: "wood", korean: "상자목", hanja: "桑柘木" },
53
+ 50: { element: "water", korean: "대계수", hanja: "大溪水" },
54
+ 51: { element: "water", korean: "대계수", hanja: "大溪水" },
55
+ 52: { element: "earth", korean: "사중토", hanja: "砂中土" },
56
+ 53: { element: "earth", korean: "사중토", hanja: "砂中土" },
57
+ 54: { element: "fire", korean: "천상화", hanja: "天上火" },
58
+ 55: { element: "fire", korean: "천상화", hanja: "天上火" },
59
+ 56: { element: "wood", korean: "석류목", hanja: "石榴木" },
60
+ 57: { element: "wood", korean: "석류목", hanja: "石榴木" },
61
+ 58: { element: "water", korean: "대해수", hanja: "大海水" },
62
+ 59: { element: "water", korean: "대해수", hanja: "大海水" },
63
+ };
64
+ export function getNayin(pillarIdx60) {
65
+ const normalized = ((pillarIdx60 % 60) + 60) % 60;
66
+ const pairIdx = Math.floor(normalized / 2) * 2;
67
+ const entry = NAYIN_TABLE[pairIdx];
68
+ if (!entry)
69
+ throw new Error(`Invalid pillar index: ${pillarIdx60}`);
70
+ return { element: entry.element, korean: entry.korean, hanja: entry.hanja };
71
+ }
72
+ export function getNayinFromPillar(pillar) {
73
+ const idx = getPillarIndex(pillar);
74
+ return getNayin(idx);
75
+ }
76
+ export function analyzeFourPillarsNayin(yearPillar, monthPillar, dayPillar, hourPillar) {
77
+ return {
78
+ year: getNayin(getPillarIndex(yearPillar)),
79
+ month: getNayin(getPillarIndex(monthPillar)),
80
+ day: getNayin(getPillarIndex(dayPillar)),
81
+ hour: getNayin(getPillarIndex(hourPillar)),
82
+ };
83
+ }
@@ -1,6 +1,6 @@
1
1
  import type { Element, ElementLabel } from "../core/ten-gods";
2
2
  import type { Label } from "../types";
3
- export declare const RELATION_TYPE_KEYS: readonly ["stemCombination", "sixCombination", "tripleCombination", "directionalCombination", "clash", "harm", "punishment", "destruction"];
3
+ export declare const RELATION_TYPE_KEYS: readonly ["stemCombination", "stemClash", "sixCombination", "halfCombination", "tripleCombination", "directionalCombination", "clash", "harm", "punishment", "destruction"];
4
4
  export type RelationTypeKey = (typeof RELATION_TYPE_KEYS)[number];
5
5
  export interface RelationTypeLabel extends Label<RelationTypeKey> {
6
6
  }
@@ -20,11 +20,17 @@ export type StemCombinationResult = {
20
20
  resultElement: Element;
21
21
  };
22
22
  export declare const STEM_COMBINATIONS: StemCombinationResult[];
23
+ export declare const STEM_CLASHES: [string, string][];
23
24
  export type BranchCombinationResult = {
24
25
  branches: [string, string];
25
26
  resultElement: Element;
26
27
  };
27
28
  export declare const BRANCH_SIX_COMBINATIONS: BranchCombinationResult[];
29
+ export type HalfCombinationResult = {
30
+ branches: [string, string];
31
+ resultElement: Element;
32
+ };
33
+ export declare const BRANCH_HALF_COMBINATIONS: HalfCombinationResult[];
28
34
  export type TripleCombinationResult = {
29
35
  branches: [string, string, string];
30
36
  resultElement: Element;
@@ -46,6 +52,11 @@ export interface StemCombination {
46
52
  transformStatus: TransformationStatusLabel;
47
53
  transformReason: string;
48
54
  }
55
+ export interface StemClash {
56
+ type: RelationTypeLabel;
57
+ pair: [string, string];
58
+ positions: [string, string];
59
+ }
49
60
  export interface BranchSixCombination {
50
61
  type: RelationTypeLabel;
51
62
  pair: [string, string];
@@ -54,6 +65,12 @@ export interface BranchSixCombination {
54
65
  transformStatus: TransformationStatusLabel;
55
66
  transformReason: string;
56
67
  }
68
+ export interface BranchHalfCombination {
69
+ type: RelationTypeLabel;
70
+ pair: [string, string];
71
+ positions: [string, string];
72
+ resultElement: ElementLabel;
73
+ }
57
74
  export interface BranchTripleCombination {
58
75
  type: RelationTypeLabel;
59
76
  branches: string[];
@@ -93,9 +110,10 @@ export interface BranchDestruction {
93
110
  pair: [string, string];
94
111
  positions: [string, string];
95
112
  }
96
- export type Relation = StemCombination | BranchSixCombination | BranchTripleCombination | BranchDirectionalCombination | BranchClash | BranchHarm | BranchPunishment | BranchDestruction;
113
+ export type Relation = StemCombination | StemClash | BranchSixCombination | BranchHalfCombination | BranchTripleCombination | BranchDirectionalCombination | BranchClash | BranchHarm | BranchPunishment | BranchDestruction;
97
114
  export interface RelationsResult {
98
- combinations: (StemCombination | BranchSixCombination | BranchTripleCombination | BranchDirectionalCombination)[];
115
+ combinations: (StemCombination | BranchSixCombination | BranchHalfCombination | BranchTripleCombination | BranchDirectionalCombination)[];
116
+ stemClashes: StemClash[];
99
117
  clashes: BranchClash[];
100
118
  harms: BranchHarm[];
101
119
  punishments: BranchPunishment[];
@@ -1 +1 @@
1
- {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/core/relations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/core/relations.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import { getBranchElement, getElementLabel, getStemElement } from "../core/ten-gods";
2
2
  export const RELATION_TYPE_KEYS = [
3
3
  "stemCombination",
4
+ "stemClash",
4
5
  "sixCombination",
6
+ "halfCombination",
5
7
  "tripleCombination",
6
8
  "directionalCombination",
7
9
  "clash",
@@ -11,7 +13,9 @@ export const RELATION_TYPE_KEYS = [
11
13
  ];
12
14
  const RELATION_TYPE_DATA = {
13
15
  stemCombination: { korean: "천간합", hanja: "天干合" },
16
+ stemClash: { korean: "천간충", hanja: "天干沖" },
14
17
  sixCombination: { korean: "육합", hanja: "六合" },
18
+ halfCombination: { korean: "반합", hanja: "半合" },
15
19
  tripleCombination: { korean: "삼합", hanja: "三合" },
16
20
  directionalCombination: { korean: "방합", hanja: "方合" },
17
21
  clash: { korean: "충", hanja: "沖" },
@@ -57,6 +61,12 @@ export const STEM_COMBINATIONS = [
57
61
  { stems: ["丁", "壬"], resultElement: "wood" },
58
62
  { stems: ["戊", "癸"], resultElement: "fire" },
59
63
  ];
64
+ export const STEM_CLASHES = [
65
+ ["甲", "庚"],
66
+ ["乙", "辛"],
67
+ ["丙", "壬"],
68
+ ["丁", "癸"],
69
+ ];
60
70
  export const BRANCH_SIX_COMBINATIONS = [
61
71
  { branches: ["子", "丑"], resultElement: "earth" },
62
72
  { branches: ["寅", "亥"], resultElement: "wood" },
@@ -65,6 +75,16 @@ export const BRANCH_SIX_COMBINATIONS = [
65
75
  { branches: ["巳", "申"], resultElement: "water" },
66
76
  { branches: ["午", "未"], resultElement: "earth" },
67
77
  ];
78
+ export const BRANCH_HALF_COMBINATIONS = [
79
+ { branches: ["寅", "午"], resultElement: "fire" },
80
+ { branches: ["午", "戌"], resultElement: "fire" },
81
+ { branches: ["巳", "酉"], resultElement: "metal" },
82
+ { branches: ["酉", "丑"], resultElement: "metal" },
83
+ { branches: ["申", "子"], resultElement: "water" },
84
+ { branches: ["子", "辰"], resultElement: "water" },
85
+ { branches: ["亥", "卯"], resultElement: "wood" },
86
+ { branches: ["卯", "未"], resultElement: "wood" },
87
+ ];
68
88
  export const BRANCH_TRIPLE_COMBINATIONS = [
69
89
  { branches: ["寅", "午", "戌"], resultElement: "fire" },
70
90
  { branches: ["申", "子", "辰"], resultElement: "water" },
@@ -194,6 +214,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
194
214
  const allStemChars = stems.map((s) => s.char);
195
215
  const allBranchChars = branches.map((b) => b.char);
196
216
  const combinations = [];
217
+ const stemClashes = [];
197
218
  const clashes = [];
198
219
  const harms = [];
199
220
  const punishments = [];
@@ -216,6 +237,16 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
216
237
  });
217
238
  }
218
239
  }
240
+ for (const clash of STEM_CLASHES) {
241
+ if ((s1.char === clash[0] && s2.char === clash[1]) ||
242
+ (s1.char === clash[1] && s2.char === clash[0])) {
243
+ stemClashes.push({
244
+ type: getRelationTypeLabel("stemClash"),
245
+ pair: [s1.char, s2.char],
246
+ positions: [s1.position, s2.position],
247
+ });
248
+ }
249
+ }
219
250
  }
220
251
  }
221
252
  for (let i = 0; i < branches.length; i++) {
@@ -236,6 +267,17 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
236
267
  });
237
268
  }
238
269
  }
270
+ for (const halfCombo of BRANCH_HALF_COMBINATIONS) {
271
+ if ((b1.char === halfCombo.branches[0] && b2.char === halfCombo.branches[1]) ||
272
+ (b1.char === halfCombo.branches[1] && b2.char === halfCombo.branches[0])) {
273
+ combinations.push({
274
+ type: getRelationTypeLabel("halfCombination"),
275
+ pair: [b1.char, b2.char],
276
+ positions: [b1.position, b2.position],
277
+ resultElement: getElementLabel(halfCombo.resultElement),
278
+ });
279
+ }
280
+ }
239
281
  for (const clash of BRANCH_CLASHES) {
240
282
  if ((b1.char === clash[0] && b2.char === clash[1]) ||
241
283
  (b1.char === clash[1] && b2.char === clash[0])) {
@@ -268,17 +310,23 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
268
310
  }
269
311
  }
270
312
  }
271
- const branchChars = branches.map((b) => b.char);
272
313
  for (const combo of BRANCH_TRIPLE_COMBINATIONS) {
273
- const matched = combo.branches.filter((b) => branchChars.includes(b));
314
+ const matched = [];
315
+ const usedIndices = new Set();
316
+ for (const target of combo.branches) {
317
+ const idx = branches.findIndex((b, i) => b.char === target && !usedIndices.has(i));
318
+ if (idx !== -1) {
319
+ usedIndices.add(idx);
320
+ matched.push({ char: target, position: branches[idx].position });
321
+ }
322
+ }
274
323
  if (matched.length >= 2) {
275
- // biome-ignore lint/style/noNonNullAssertion: matched is filtered from branchChars, find is guaranteed
276
- const positions = matched.map((m) => branches.find((b) => b.char === m).position);
324
+ const positions = matched.map((m) => m.position);
277
325
  const isComplete = matched.length === 3;
278
326
  const transform = checkTransformationCondition(combo.resultElement, monthBranch, allBranchChars, isComplete);
279
327
  combinations.push({
280
328
  type: getRelationTypeLabel("tripleCombination"),
281
- branches: matched,
329
+ branches: matched.map((m) => m.char),
282
330
  positions,
283
331
  resultElement: getElementLabel(combo.resultElement),
284
332
  isComplete,
@@ -288,15 +336,22 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
288
336
  }
289
337
  }
290
338
  for (const combo of BRANCH_DIRECTIONAL_COMBINATIONS) {
291
- const matched = combo.branches.filter((b) => branchChars.includes(b));
339
+ const matched = [];
340
+ const usedIndices = new Set();
341
+ for (const target of combo.branches) {
342
+ const idx = branches.findIndex((b, i) => b.char === target && !usedIndices.has(i));
343
+ if (idx !== -1) {
344
+ usedIndices.add(idx);
345
+ matched.push({ char: target, position: branches[idx].position });
346
+ }
347
+ }
292
348
  if (matched.length >= 2) {
293
- // biome-ignore lint/style/noNonNullAssertion: matched is filtered from branchChars, find is guaranteed
294
- const positions = matched.map((m) => branches.find((b) => b.char === m).position);
349
+ const positions = matched.map((m) => m.position);
295
350
  const isComplete = matched.length === 3;
296
351
  const transform = checkTransformationCondition(combo.resultElement, monthBranch, allBranchChars, isComplete);
297
352
  combinations.push({
298
353
  type: getRelationTypeLabel("directionalCombination"),
299
- branches: matched,
354
+ branches: matched.map((m) => m.char),
300
355
  positions,
301
356
  resultElement: getElementLabel(combo.resultElement),
302
357
  isComplete,
@@ -305,6 +360,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
305
360
  });
306
361
  }
307
362
  }
363
+ const branchChars = branches.map((b) => b.char);
308
364
  for (const punishment of BRANCH_PUNISHMENTS) {
309
365
  const matched = punishment.branches.filter((b) => branchChars.includes(b));
310
366
  const isTriple = punishment.branches.length === 3;
@@ -343,9 +399,17 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
343
399
  });
344
400
  }
345
401
  }
346
- const all = [...combinations, ...clashes, ...harms, ...punishments, ...destructions];
402
+ const all = [
403
+ ...combinations,
404
+ ...stemClashes,
405
+ ...clashes,
406
+ ...harms,
407
+ ...punishments,
408
+ ...destructions,
409
+ ];
347
410
  return {
348
411
  combinations,
412
+ stemClashes,
349
413
  clashes,
350
414
  harms,
351
415
  punishments,
@@ -1,5 +1,5 @@
1
1
  import type { Label, PillarPosition } from "../types";
2
- export declare const SINSALS: readonly ["peachBlossom", "skyHorse", "floweryCanopy", "ghostGate", "solitaryStar", "widowStar", "heavenlyVirtue", "monthlyVirtue", "skyNoble", "moonNoble", "literaryNoble", "academicHall", "bloodKnife", "sixHarms", "whiteCloth", "heavenlyDoctor", "suspendedNeedle", "kuiGang", "sheepBlade", "redFlame", "taijiNoble", "goldenCarriage", "officialStar", "hiddenWealth", "officialAcademicHall", "whiteTiger", "heavenlyGate", "heavenlyKitchen", "literaryCurve", "imperialPardon", "lostSpirit", "robbery", "disaster", "generalStar", "saddleMount", "redPhoenix", "heavenlyJoy", "gongmang", "wonjin"];
2
+ export declare const SINSALS: readonly ["peachBlossom", "skyHorse", "floweryCanopy", "ghostGate", "solitaryStar", "widowStar", "heavenlyVirtue", "monthlyVirtue", "skyNoble", "moonNoble", "literaryNoble", "academicHall", "bloodKnife", "sixHarms", "whiteCloth", "heavenlyDoctor", "suspendedNeedle", "kuiGang", "sheepBlade", "redFlame", "taijiNoble", "goldenCarriage", "officialStar", "hiddenWealth", "officialAcademicHall", "whiteTiger", "heavenlyGate", "heavenlyKitchen", "literaryCurve", "imperialPardon", "lostSpirit", "robbery", "disaster", "heavenlyKiller", "earthlyKiller", "yearKiller", "monthKiller", "generalStar", "saddleMount", "redPhoenix", "heavenlyJoy", "gongmang", "wonjin"];
3
3
  export type SinsalKey = (typeof SINSALS)[number];
4
4
  export type SinsalType = "auspicious" | "inauspicious" | "neutral";
5
5
  export interface SinsalLabel extends Label<SinsalKey> {
@@ -1 +1 @@
1
- {"version":3,"file":"sinsals.d.ts","sourceRoot":"","sources":["../../src/core/sinsals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAErD,eAAO,MAAM,OAAO,mlBAwCV,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,cAAc,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,WAAY,SAAQ,KAAK,CAAC,SAAS,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;CAClB;AA+dD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;CACvD;AA6CD,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,YAAY,CA+Sd;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAC9B,SAAS,EACT;IACE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;CAClB,CA6NF,CAAC;AAEF,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,WAAW,CAS1D"}
1
+ {"version":3,"file":"sinsals.d.ts","sourceRoot":"","sources":["../../src/core/sinsals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAErD,eAAO,MAAM,OAAO,mpBA4CV,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,cAAc,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,WAAY,SAAQ,KAAK,CAAC,SAAS,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;CAClB;AA+hBD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;CACvD;AA6CD,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,YAAY,CAuWd;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAC9B,SAAS,EACT;IACE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;CAClB,CAqPF,CAAC;AAEF,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,WAAW,CAS1D"}
@@ -32,6 +32,10 @@ export const SINSALS = [
32
32
  "lostSpirit",
33
33
  "robbery",
34
34
  "disaster",
35
+ "heavenlyKiller",
36
+ "earthlyKiller",
37
+ "yearKiller",
38
+ "monthKiller",
35
39
  "generalStar",
36
40
  "saddleMount",
37
41
  "redPhoenix",
@@ -420,6 +424,66 @@ const DISASTER_MAP = {
420
424
  卯: "酉",
421
425
  未: "酉",
422
426
  };
427
+ // 천살 (년지/일지 기준 삼합 → 지지에서 체크)
428
+ const HEAVENLY_KILLER_MAP = {
429
+ 寅: "丑",
430
+ 午: "丑",
431
+ 戌: "丑",
432
+ 巳: "辰",
433
+ 酉: "辰",
434
+ 丑: "辰",
435
+ 申: "未",
436
+ 子: "未",
437
+ 辰: "未",
438
+ 亥: "戌",
439
+ 卯: "戌",
440
+ 未: "戌",
441
+ };
442
+ // 지살 (년지/일지 기준 삼합 → 지지에서 체크)
443
+ const EARTHLY_KILLER_MAP = {
444
+ 寅: "寅",
445
+ 午: "寅",
446
+ 戌: "寅",
447
+ 巳: "巳",
448
+ 酉: "巳",
449
+ 丑: "巳",
450
+ 申: "申",
451
+ 子: "申",
452
+ 辰: "申",
453
+ 亥: "亥",
454
+ 卯: "亥",
455
+ 未: "亥",
456
+ };
457
+ // 연살 (년지/일지 기준 삼합 → 지지에서 체크)
458
+ const YEAR_KILLER_MAP = {
459
+ 寅: "卯",
460
+ 午: "卯",
461
+ 戌: "卯",
462
+ 巳: "午",
463
+ 酉: "午",
464
+ 丑: "午",
465
+ 申: "酉",
466
+ 子: "酉",
467
+ 辰: "酉",
468
+ 亥: "子",
469
+ 卯: "子",
470
+ 未: "子",
471
+ };
472
+ // 월살 (년지/일지 기준 삼합 → 지지에서 체크)
473
+ const MONTH_KILLER_MAP = {
474
+ 寅: "辰",
475
+ 午: "辰",
476
+ 戌: "辰",
477
+ 巳: "未",
478
+ 酉: "未",
479
+ 丑: "未",
480
+ 申: "戌",
481
+ 子: "戌",
482
+ 辰: "戌",
483
+ 亥: "丑",
484
+ 卯: "丑",
485
+ 未: "丑",
486
+ };
423
487
  // 장성 (년지/일지 기준 삼합의 왕지)
424
488
  const GENERAL_STAR_MAP = {
425
489
  寅: "午",
@@ -582,6 +646,18 @@ export function analyzeSinsals(yearPillar, monthPillar, dayPillar, hourPillar) {
582
646
  // 재살 (년지/일지 기준)
583
647
  matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, DISASTER_MAP, "disaster"));
584
648
  matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, DISASTER_MAP, "disaster"));
649
+ // 천살 (년지/일지 기준)
650
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, HEAVENLY_KILLER_MAP, "heavenlyKiller"));
651
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, HEAVENLY_KILLER_MAP, "heavenlyKiller"));
652
+ // 지살 (년지/일지 기준)
653
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, EARTHLY_KILLER_MAP, "earthlyKiller"));
654
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, EARTHLY_KILLER_MAP, "earthlyKiller"));
655
+ // 연살 (년지/일지 기준)
656
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, YEAR_KILLER_MAP, "yearKiller"));
657
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, YEAR_KILLER_MAP, "yearKiller"));
658
+ // 월살 (년지/일지 기준)
659
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, MONTH_KILLER_MAP, "monthKiller"));
660
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, MONTH_KILLER_MAP, "monthKiller"));
585
661
  // 장성살 (년지/일지 기준)
586
662
  matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, GENERAL_STAR_MAP, "generalStar"));
587
663
  matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, GENERAL_STAR_MAP, "generalStar"));
@@ -804,6 +880,30 @@ export const SINSAL_INFO = {
804
880
  meaning: "재난, 감금, 소송",
805
881
  type: "inauspicious",
806
882
  },
883
+ heavenlyKiller: {
884
+ korean: "천살",
885
+ hanja: "天煞",
886
+ meaning: "천재지변, 불의의 사고",
887
+ type: "inauspicious",
888
+ },
889
+ earthlyKiller: {
890
+ korean: "지살",
891
+ hanja: "地煞",
892
+ meaning: "이동 중 사고, 지진, 함몰",
893
+ type: "inauspicious",
894
+ },
895
+ yearKiller: {
896
+ korean: "연살",
897
+ hanja: "年煞",
898
+ meaning: "질병, 관재, 구설",
899
+ type: "inauspicious",
900
+ },
901
+ monthKiller: {
902
+ korean: "월살",
903
+ hanja: "月煞",
904
+ meaning: "가정불화, 부부갈등",
905
+ type: "inauspicious",
906
+ },
807
907
  generalStar: {
808
908
  korean: "장성살",
809
909
  hanja: "將星煞",
@@ -1 +1 @@
1
- {"version":3,"file":"solar-terms.d.ts","sourceRoot":"","sources":["../../src/core/solar-terms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,eAAO,MAAM,eAAe,iXAyBlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,WAAW,cAAe,SAAQ,KAAK,CAAC,YAAY,CAAC;IACzD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,QAAA,MAAM,eAAe,EAAE,MAAM,CAAC,YAAY,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA0B7F,CAAC;AAEJ,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,cAAc,CAGnE;AAED,eAAO,MAAM,WAAW,kBAAuD,CAAC;AAEhF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC7E,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC;AAE7E,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,YAAY,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,OAAO,EAAE,SAAS,CAAC;IACnB,+CAA+C;IAC/C,WAAW,EAAE,iBAAiB,CAAC;IAC/B,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,+CAA+C;IAC/C,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,iGAAiG;IACjG,OAAO,EAAE,SAAS,CAAC;IACnB,2BAA2B;IAC3B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,OAAO,EAAE,SAAS,CAAC;IACnB,uBAAuB;IACvB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;CACvB;AAuMD,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,OAAO,EAAE,CAAC,EACV,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;CAAE,GACvC,aAAa,CA0Ef;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,MAAM,EACZ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnE,KAAK,CAAC;IACP,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC,CAuBD"}
1
+ {"version":3,"file":"solar-terms.d.ts","sourceRoot":"","sources":["../../src/core/solar-terms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,eAAO,MAAM,eAAe,iXAyBlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,WAAW,cAAe,SAAQ,KAAK,CAAC,YAAY,CAAC;IACzD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,QAAA,MAAM,eAAe,EAAE,MAAM,CAAC,YAAY,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA0B7F,CAAC;AAEJ,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,cAAc,CAGnE;AAED,eAAO,MAAM,WAAW,kBAAuD,CAAC;AAEhF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC7E,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC;AAE7E,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,YAAY,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,OAAO,EAAE,SAAS,CAAC;IACnB,+CAA+C;IAC/C,WAAW,EAAE,iBAAiB,CAAC;IAC/B,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,+CAA+C;IAC/C,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,iGAAiG;IACjG,OAAO,EAAE,SAAS,CAAC;IACnB,2BAA2B;IAC3B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,OAAO,EAAE,SAAS,CAAC;IACnB,uBAAuB;IACvB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;CACvB;AAqOD,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,OAAO,EAAE,CAAC,EACV,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;CAAE,GACvC,aAAa,CA0Ef;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,MAAM,EACZ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnE,KAAK,CAAC;IACP,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC,CAuBD"}
@@ -55,6 +55,30 @@ export function getSolarTermLabel(key) {
55
55
  return { key, ...data };
56
56
  }
57
57
  export const SOLAR_TERMS = SOLAR_TERM_KEYS.map((key) => getSolarTermLabel(key));
58
+ /**
59
+ * Approximate ΔT (TT - UT) in seconds.
60
+ * Based on polynomial expressions from Meeus / USNO.
61
+ */
62
+ function deltaT(year) {
63
+ if (year >= 2005 && year < 2050) {
64
+ const t = year - 2000;
65
+ return 62.92 + 0.32217 * t + 0.005589 * t * t;
66
+ }
67
+ if (year >= 1986 && year < 2005) {
68
+ const t = year - 2000;
69
+ return (63.86 +
70
+ 0.3345 * t -
71
+ 0.060374 * t * t +
72
+ 0.0017275 * t * t * t +
73
+ 0.000651814 * t * t * t * t +
74
+ 0.00002373599 * t * t * t * t * t);
75
+ }
76
+ if (year >= 1900 && year < 1986) {
77
+ const t = year - 1900;
78
+ return -0.02 + 0.000297 * t * t;
79
+ }
80
+ return 0;
81
+ }
58
82
  function normDeg(x) {
59
83
  x %= 360;
60
84
  return x < 0 ? x + 360 : x;
@@ -71,7 +95,10 @@ function sunApparentLongitude(adapter, dtUtc) {
71
95
  const A = Math.floor(y / 100);
72
96
  const B = 2 - A + Math.floor(A / 4);
73
97
  const JD = Math.floor(365.25 * (y + 4716)) + Math.floor(30.6001 * (m + 1)) + d + B - 1524.5;
74
- const T = (JD - 2451545.0) / 36525.0;
98
+ // Apply ΔT correction for TT
99
+ const dtSeconds = deltaT(y);
100
+ const JD_TT = JD + dtSeconds / 86400.0;
101
+ const T = (JD_TT - 2451545.0) / 36525.0;
75
102
  const L0 = normDeg(280.46646 + 36000.76983 * T + 0.0003032 * T * T);
76
103
  const M = normDeg(357.52911 + 35999.05029 * T - 0.0001537 * T * T);
77
104
  const deg2rad = (deg) => (deg * Math.PI) / 180;
@@ -1 +1 @@
1
- {"version":3,"file":"strength.d.ts","sourceRoot":"","sources":["../../src/core/strength.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,eAAO,MAAM,mBAAmB,sIAUtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,gBAAgB,CAAC;CAAG;AActE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,GAAG,kBAAkB,CAG/E;AAgLD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CAsGhB"}
1
+ {"version":3,"file":"strength.d.ts","sourceRoot":"","sources":["../../src/core/strength.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,eAAO,MAAM,mBAAmB,sIAUtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,gBAAgB,CAAC;CAAG;AActE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,GAAG,kBAAkB,CAG/E;AAgLD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CA6HhB"}
@@ -1,3 +1,4 @@
1
+ import { findBranchClash, findStemCombination } from "../core/relations";
1
2
  import { getStemElement, getStemPolarity, getTenGodKey, } from "../core/ten-gods";
2
3
  export const STRENGTH_LEVEL_KEYS = [
3
4
  "extremelyWeak",
@@ -188,7 +189,29 @@ export function analyzeStrength(yearPillar, monthPillar, dayPillar, hourPillar)
188
189
  for (const branch of allBranches) {
189
190
  tonggeun += calculateRootStrength(dayMaster, branch);
190
191
  }
192
+ // Clash reduction: if day branch is clashed, reduce root strength
193
+ let clashReduction = 0;
194
+ for (const branch of allBranches) {
195
+ if (branch !== dayPillar[1] && findBranchClash(dayPillar[1], branch)) {
196
+ clashReduction += 0.3;
197
+ }
198
+ }
199
+ tonggeun = Math.max(0, tonggeun - clashReduction);
191
200
  const allStems = [yearPillar[0], monthPillar[0], dayPillar[0], hourPillar[0]];
201
+ // Stem combination: check if daymaster is in a stem combination
202
+ let stemComboBonus = 0;
203
+ const otherStems = [yearPillar[0], monthPillar[0], hourPillar[0]];
204
+ for (const stem of otherStems) {
205
+ const combo = findStemCombination(dayMaster, stem);
206
+ if (combo) {
207
+ if (combo.resultElement === dayMasterElement) {
208
+ stemComboBonus += 0.2; // Combination strengthens day master element
209
+ }
210
+ else {
211
+ stemComboBonus -= 0.1; // Combination transforms away from day master
212
+ }
213
+ }
214
+ }
192
215
  const monthHiddenStems = HIDDEN_STEM_WEIGHTS[monthBranch] || [];
193
216
  let transparentBonus = 0;
194
217
  for (const hs of monthHiddenStems) {
@@ -205,7 +228,6 @@ export function analyzeStrength(yearPillar, monthPillar, dayPillar, hourPillar)
205
228
  deukji += calculateRootStrength(dayMaster, branch);
206
229
  }
207
230
  let deukse = 0;
208
- const otherStems = [yearPillar[0], monthPillar[0], hourPillar[0]];
209
231
  for (const stem of otherStems) {
210
232
  const tenGod = getTenGodKey(dayMaster, stem);
211
233
  if (isHelpfulTenGod(tenGod)) {
@@ -239,6 +261,7 @@ export function analyzeStrength(yearPillar, monthPillar, dayPillar, hourPillar)
239
261
  score += deukse * 8;
240
262
  score += helpCount * 5;
241
263
  score -= weakenCount * 6;
264
+ score += stemComboBonus * 10;
242
265
  score = Math.round(score * 10) / 10;
243
266
  let levelKey;
244
267
  if (score <= 10)
@@ -1 +1 @@
1
- {"version":3,"file":"yongshen.d.ts","sourceRoot":"","sources":["../../src/core/yongshen.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,YAAY,EAIlB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3F,MAAM,WAAW,mBAAoB,SAAQ,KAAK,CAAC,iBAAiB,CAAC;CAAG;AAUxE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,iBAAiB,GAAG,mBAAmB,CAGlF;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzE,cAAc,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,8BAA8B;IAC9B,kBAAkB,CAAC,EAAE;QACnB,OAAO,EAAE,YAAY,CAAC;QACtB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAC;KAChC,CAAC;CACH;AAED,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AA2JrC,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CA2FhB;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG;IACnE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CA0BA"}
1
+ {"version":3,"file":"yongshen.d.ts","sourceRoot":"","sources":["../../src/core/yongshen.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,YAAY,EAIlB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3F,MAAM,WAAW,mBAAoB,SAAQ,KAAK,CAAC,iBAAiB,CAAC;CAAG;AAUxE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,iBAAiB,GAAG,mBAAmB,CAGlF;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzE,cAAc,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,8BAA8B;IAC9B,kBAAkB,CAAC,EAAE;QACnB,OAAO,EAAE,YAAY,CAAC;QACtB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAC;KAChC,CAAC;CACH;AAED,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAoLrC,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CA2FhB;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG;IACnE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CA0BA"}
@@ -103,17 +103,18 @@ function getYokbuYongShen(dayMasterElement, level) {
103
103
  return { primary, secondary };
104
104
  }
105
105
  function hasSpecialFormation(dayMasterElement, level, allElements) {
106
+ const elementCounts = {
107
+ wood: 0,
108
+ fire: 0,
109
+ earth: 0,
110
+ metal: 0,
111
+ water: 0,
112
+ };
113
+ for (const elem of allElements) {
114
+ elementCounts[elem]++;
115
+ }
106
116
  if (level.key === "extremelyWeak") {
107
- const elementCounts = {
108
- wood: 0,
109
- fire: 0,
110
- earth: 0,
111
- metal: 0,
112
- water: 0,
113
- };
114
- for (const elem of allElements) {
115
- elementCounts[elem]++;
116
- }
117
+ // Find dominant non-daymaster element
117
118
  let dominantElement = null;
118
119
  let maxCount = 0;
119
120
  for (const [elem, count] of Object.entries(elementCounts)) {
@@ -123,7 +124,29 @@ function hasSpecialFormation(dayMasterElement, level, allElements) {
123
124
  }
124
125
  }
125
126
  if (dominantElement && maxCount >= 3) {
126
- return { isSpecial: true, type: "종격", followElement: dominantElement };
127
+ // Determine specific 종격 type
128
+ const dmControls = CONTROLS[dayMasterElement];
129
+ const dmControlledBy = CONTROLLED_BY[dayMasterElement];
130
+ const dmGenerates = GENERATES[dayMasterElement];
131
+ let type = "종격";
132
+ if (dominantElement === dmControls) {
133
+ type = "종재격"; // Follow Wealth
134
+ }
135
+ else if (dominantElement === dmControlledBy) {
136
+ type = "종살격"; // Follow Killings
137
+ }
138
+ else if (dominantElement === dmGenerates) {
139
+ type = "종아격"; // Follow Children/Output
140
+ }
141
+ return { isSpecial: true, type, followElement: dominantElement };
142
+ }
143
+ }
144
+ if (level.key === "extremelyStrong") {
145
+ // 종강격: extremely strong with no controllers present
146
+ const controllerElement = CONTROLLED_BY[dayMasterElement];
147
+ const hasController = elementCounts[controllerElement] > 0;
148
+ if (!hasController) {
149
+ return { isSpecial: true, type: "종강격", followElement: dayMasterElement };
127
150
  }
128
151
  }
129
152
  return { isSpecial: false, type: null, followElement: null };
@@ -156,7 +179,7 @@ export function analyzeYongShen(yearPillar, monthPillar, dayPillar, hourPillar)
156
179
  primaryKey = specialFormation.followElement;
157
180
  secondaryKey = GENERATES[specialFormation.followElement];
158
181
  methodKey = "formation";
159
- reasoning = `종격 성립. ${getElementLabel(specialFormation.followElement).korean} 세력을 따름`;
182
+ reasoning = `${specialFormation.type} 성립. ${getElementLabel(specialFormation.followElement).korean} 세력을 따름`;
160
183
  const yokbu = getYokbuYongShen(dayMasterElement, strength.level);
161
184
  alternativeBalance = { primary: yokbu.primary, secondary: yokbu.secondary };
162
185
  }
package/dist/index.d.ts CHANGED
@@ -2,7 +2,8 @@ export type { DateAdapter } from "./adapters/date-adapter";
2
2
  export { applyMeanSolarTime, BRANCHES, dayPillarFromDate, effectiveDayDate, getFourPillars, hourPillar, monthPillar, presetA, presetB, STANDARD_PRESET, STEMS, TRADITIONAL_PRESET, yearPillar, } from "./core/four-pillars";
3
3
  export { calculateDailyLuck, calculateMajorLuck, calculateMonthlyLuck, calculateYearlyLuck, type DailyLuckResult, type Gender, getCurrentMajorLuck, getDayPillar, getMonthPillar, getYearPillar, type LuckPillar, type MajorLuckResult, type MonthlyLuckResult, type StartAgeDetail, type YearlyLuckResult, } from "./core/luck";
4
4
  export { getLunarDate, getSolarDate, type LunarDate } from "./core/lunar";
5
- export { analyzeRelations, BRANCH_CLASHES, BRANCH_DESTRUCTIONS, BRANCH_DIRECTIONAL_COMBINATIONS, BRANCH_HARMS, BRANCH_PUNISHMENTS, BRANCH_SIX_COMBINATIONS, BRANCH_TRIPLE_COMBINATIONS, type BranchClash, type BranchDestruction, type BranchDirectionalCombination, type BranchHarm, type BranchPunishment, type BranchSixCombination, type BranchTripleCombination, findBranchClash, findBranchSixCombination, findStemCombination, type Relation, type RelationsResult, STEM_COMBINATIONS, type StemCombination, } from "./core/relations";
5
+ export { analyzeFourPillarsNayin, type FourPillarsNayin, getNayin, getNayinFromPillar, type NayinResult, } from "./core/nayin";
6
+ export { analyzeRelations, BRANCH_CLASHES, BRANCH_DESTRUCTIONS, BRANCH_DIRECTIONAL_COMBINATIONS, BRANCH_HALF_COMBINATIONS, BRANCH_HARMS, BRANCH_PUNISHMENTS, BRANCH_SIX_COMBINATIONS, BRANCH_TRIPLE_COMBINATIONS, type BranchClash, type BranchDestruction, type BranchDirectionalCombination, type BranchHalfCombination, type BranchHarm, type BranchPunishment, type BranchSixCombination, type BranchTripleCombination, findBranchClash, findBranchSixCombination, findStemCombination, type Relation, type RelationsResult, STEM_CLASHES, STEM_COMBINATIONS, type StemClash, type StemCombination, } from "./core/relations";
6
7
  export { analyzeSinsals, getSinsalLabel, SINSAL_INFO, SINSALS, type SinsalKey, type SinsalLabel, type SinsalMatch, type SinsalResult, type SinsalType, } from "./core/sinsals";
7
8
  export { analyzeSolarTerms, getSolarTermLabel, getSolarTermsForYear, SOLAR_TERM_KEYS, SOLAR_TERMS, type SolarTerm, type SolarTermDateInfo, type SolarTermHanja, type SolarTermInfo, type SolarTermKey, type SolarTermLabel, type SolarTermName, } from "./core/solar-terms";
8
9
  export { analyzeStrength, getStrengthLevelLabel, STRENGTH_LEVEL_KEYS, type StrengthFactors, type StrengthLevelKey, type StrengthLevelLabel, type StrengthResult, } from "./core/strength";
@@ -14,6 +15,7 @@ import type { DateAdapter } from "./adapters/date-adapter";
14
15
  import { type presetA } from "./core/four-pillars";
15
16
  import { type Gender, type MajorLuckResult, type YearlyLuckResult } from "./core/luck";
16
17
  import type { LunarDate } from "./core/lunar";
18
+ import { type FourPillarsNayin } from "./core/nayin";
17
19
  import { type RelationsResult } from "./core/relations";
18
20
  import { type SinsalResult } from "./core/sinsals";
19
21
  import { type SolarTermInfo } from "./core/solar-terms";
@@ -33,6 +35,7 @@ export interface SajuResult {
33
35
  strength: StrengthResult;
34
36
  relations: RelationsResult;
35
37
  yongShen: YongShenResult;
38
+ nayin: FourPillarsNayin;
36
39
  solarTerms: SolarTermInfo;
37
40
  majorLuck: MajorLuckResult;
38
41
  yearlyLuck: YearlyLuckResult[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  export { applyMeanSolarTime, BRANCHES, dayPillarFromDate, effectiveDayDate, getFourPillars, hourPillar, monthPillar, presetA, presetB, STANDARD_PRESET, STEMS, TRADITIONAL_PRESET, yearPillar, } from "./core/four-pillars";
2
2
  export { calculateDailyLuck, calculateMajorLuck, calculateMonthlyLuck, calculateYearlyLuck, getCurrentMajorLuck, getDayPillar, getMonthPillar, getYearPillar, } from "./core/luck";
3
3
  export { getLunarDate, getSolarDate } from "./core/lunar";
4
- export { analyzeRelations, BRANCH_CLASHES, BRANCH_DESTRUCTIONS, BRANCH_DIRECTIONAL_COMBINATIONS, BRANCH_HARMS, BRANCH_PUNISHMENTS, BRANCH_SIX_COMBINATIONS, BRANCH_TRIPLE_COMBINATIONS, findBranchClash, findBranchSixCombination, findStemCombination, STEM_COMBINATIONS, } from "./core/relations";
4
+ export { analyzeFourPillarsNayin, getNayin, getNayinFromPillar, } from "./core/nayin";
5
+ export { analyzeRelations, BRANCH_CLASHES, BRANCH_DESTRUCTIONS, BRANCH_DIRECTIONAL_COMBINATIONS, BRANCH_HALF_COMBINATIONS, BRANCH_HARMS, BRANCH_PUNISHMENTS, BRANCH_SIX_COMBINATIONS, BRANCH_TRIPLE_COMBINATIONS, findBranchClash, findBranchSixCombination, findStemCombination, STEM_CLASHES, STEM_COMBINATIONS, } from "./core/relations";
5
6
  export { analyzeSinsals, getSinsalLabel, SINSAL_INFO, SINSALS, } from "./core/sinsals";
6
7
  export { analyzeSolarTerms, getSolarTermLabel, getSolarTermsForYear, SOLAR_TERM_KEYS, SOLAR_TERMS, } from "./core/solar-terms";
7
8
  export { analyzeStrength, getStrengthLevelLabel, STRENGTH_LEVEL_KEYS, } from "./core/strength";
@@ -10,6 +11,7 @@ export { analyzeTwelveStages, getTwelveStageLabel, TWELVE_STAGES, } from "./core
10
11
  export { analyzeYongShen, getElementRecommendations, getYongShenMethodLabel, } from "./core/yongshen";
11
12
  import { getFourPillars } from "./core/four-pillars";
12
13
  import { calculateMajorLuck, calculateYearlyLuck, } from "./core/luck";
14
+ import { analyzeFourPillarsNayin } from "./core/nayin";
13
15
  import { analyzeRelations } from "./core/relations";
14
16
  import { analyzeSinsals } from "./core/sinsals";
15
17
  import { analyzeSolarTerms } from "./core/solar-terms";
@@ -30,6 +32,7 @@ export function getSaju(dtLocal, options) {
30
32
  const strength = analyzeStrength(year, month, day, hour);
31
33
  const relations = analyzeRelations(year, month, day, hour);
32
34
  const yongShen = analyzeYongShen(year, month, day, hour);
35
+ const nayin = analyzeFourPillarsNayin(year, month, day, hour);
33
36
  const solarTerms = analyzeSolarTerms(dtLocal, { adapter });
34
37
  const twelveStages = analyzeTwelveStages(year, month, day, hour);
35
38
  const sinsals = analyzeSinsals(year, month, day, hour);
@@ -40,6 +43,7 @@ export function getSaju(dtLocal, options) {
40
43
  strength,
41
44
  relations,
42
45
  yongShen,
46
+ nayin,
43
47
  solarTerms,
44
48
  majorLuck: calculateMajorLuck(dtLocal, options.gender, year, month, {
45
49
  adapter,
@@ -49,7 +49,7 @@ export function jdnFromDate(year, month, day) {
49
49
  32045);
50
50
  }
51
51
  export function dayPillarIndexFromJdn(jdn) {
52
- return (((jdn + 49) % 60) + 60) % 60;
52
+ return (((jdn - 11) % 60) + 60) % 60;
53
53
  }
54
54
  export function isYangStem(stem) {
55
55
  return ["甲", "丙", "戊", "庚", "壬"].includes(stem);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gracefullight/saju",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Four Pillars (四柱) calculator with flexible date adapter support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",