@gracefullight/saju 0.4.1 → 0.5.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.
- package/dist/__tests__/relations.test.js +6 -6
- package/dist/__tests__/saju.test.js +3 -3
- package/dist/__tests__/sinsals.test.js +5 -5
- package/dist/__tests__/solar-terms.test.js +26 -16
- package/dist/__tests__/strength.test.js +2 -2
- package/dist/__tests__/ten-gods.test.js +6 -6
- package/dist/__tests__/twelve-stages.test.js +6 -6
- package/dist/__tests__/yongshen.test.js +3 -3
- package/dist/core/relations.d.ts +36 -19
- package/dist/core/relations.d.ts.map +1 -1
- package/dist/core/relations.js +105 -33
- package/dist/core/sinsals.d.ts +16 -6
- package/dist/core/sinsals.d.ts.map +1 -1
- package/dist/core/sinsals.js +19 -8
- package/dist/core/solar-terms.d.ts +19 -105
- package/dist/core/solar-terms.d.ts.map +1 -1
- package/dist/core/solar-terms.js +56 -29
- package/dist/core/strength.d.ts +9 -1
- package/dist/core/strength.d.ts.map +1 -1
- package/dist/core/strength.js +38 -11
- package/dist/core/ten-gods.d.ts +36 -64
- package/dist/core/ten-gods.d.ts.map +1 -1
- package/dist/core/ten-gods.js +109 -119
- package/dist/core/twelve-stages.d.ts +19 -8
- package/dist/core/twelve-stages.d.ts.map +1 -1
- package/dist/core/twelve-stages.js +34 -24
- package/dist/core/yongshen.d.ts +12 -6
- package/dist/core/yongshen.d.ts.map +1 -1
- package/dist/core/yongshen.js +55 -37
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/types/common.d.ts +8 -0
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/core/relations.js
CHANGED
|
@@ -1,4 +1,55 @@
|
|
|
1
|
-
import { getBranchElement, getStemElement } from "./ten-gods";
|
|
1
|
+
import { getBranchElement, getElementLabel, getStemElement } from "./ten-gods";
|
|
2
|
+
export const RELATION_TYPE_KEYS = [
|
|
3
|
+
"stemCombination",
|
|
4
|
+
"sixCombination",
|
|
5
|
+
"tripleCombination",
|
|
6
|
+
"directionalCombination",
|
|
7
|
+
"clash",
|
|
8
|
+
"harm",
|
|
9
|
+
"punishment",
|
|
10
|
+
"destruction",
|
|
11
|
+
];
|
|
12
|
+
const RELATION_TYPE_DATA = {
|
|
13
|
+
stemCombination: { korean: "천간합", hanja: "天干合" },
|
|
14
|
+
sixCombination: { korean: "육합", hanja: "六合" },
|
|
15
|
+
tripleCombination: { korean: "삼합", hanja: "三合" },
|
|
16
|
+
directionalCombination: { korean: "방합", hanja: "方合" },
|
|
17
|
+
clash: { korean: "충", hanja: "沖" },
|
|
18
|
+
harm: { korean: "해", hanja: "害" },
|
|
19
|
+
punishment: { korean: "형", hanja: "刑" },
|
|
20
|
+
destruction: { korean: "파", hanja: "破" },
|
|
21
|
+
};
|
|
22
|
+
export function getRelationTypeLabel(key) {
|
|
23
|
+
const data = RELATION_TYPE_DATA[key];
|
|
24
|
+
return { key, ...data };
|
|
25
|
+
}
|
|
26
|
+
export const TRANSFORMATION_STATUS_KEYS = [
|
|
27
|
+
"combined",
|
|
28
|
+
"halfCombined",
|
|
29
|
+
"transformed",
|
|
30
|
+
"notTransformed",
|
|
31
|
+
];
|
|
32
|
+
const TRANSFORMATION_STATUS_DATA = {
|
|
33
|
+
combined: { korean: "합", hanja: "合" },
|
|
34
|
+
halfCombined: { korean: "반합", hanja: "半合" },
|
|
35
|
+
transformed: { korean: "화", hanja: "化" },
|
|
36
|
+
notTransformed: { korean: "불화", hanja: "不化" },
|
|
37
|
+
};
|
|
38
|
+
export function getTransformationStatusLabel(key) {
|
|
39
|
+
const data = TRANSFORMATION_STATUS_DATA[key];
|
|
40
|
+
return { key, ...data };
|
|
41
|
+
}
|
|
42
|
+
export const PUNISHMENT_TYPE_KEYS = ["ungrateful", "power", "rude", "self"];
|
|
43
|
+
const PUNISHMENT_TYPE_DATA = {
|
|
44
|
+
ungrateful: { korean: "무은지형", hanja: "無恩之刑" },
|
|
45
|
+
power: { korean: "시세지형", hanja: "恃勢之刑" },
|
|
46
|
+
rude: { korean: "무례지형", hanja: "無禮之刑" },
|
|
47
|
+
self: { korean: "자형", hanja: "自刑" },
|
|
48
|
+
};
|
|
49
|
+
export function getPunishmentTypeLabel(key) {
|
|
50
|
+
const data = PUNISHMENT_TYPE_DATA[key];
|
|
51
|
+
return { key, ...data };
|
|
52
|
+
}
|
|
2
53
|
export const STEM_COMBINATIONS = [
|
|
3
54
|
{ stems: ["甲", "己"], resultElement: "earth" },
|
|
4
55
|
{ stems: ["乙", "庚"], resultElement: "metal" },
|
|
@@ -43,13 +94,13 @@ export const BRANCH_HARMS = [
|
|
|
43
94
|
["酉", "戌"],
|
|
44
95
|
];
|
|
45
96
|
export const BRANCH_PUNISHMENTS = [
|
|
46
|
-
{ branches: ["寅", "巳", "申"], type: "
|
|
47
|
-
{ branches: ["丑", "戌", "未"], type: "
|
|
48
|
-
{ branches: ["子", "卯"], type: "
|
|
49
|
-
{ branches: ["辰", "辰"], type: "
|
|
50
|
-
{ branches: ["午", "午"], type: "
|
|
51
|
-
{ branches: ["酉", "酉"], type: "
|
|
52
|
-
{ branches: ["亥", "亥"], type: "
|
|
97
|
+
{ branches: ["寅", "巳", "申"], type: "ungrateful" },
|
|
98
|
+
{ branches: ["丑", "戌", "未"], type: "power" },
|
|
99
|
+
{ branches: ["子", "卯"], type: "rude" },
|
|
100
|
+
{ branches: ["辰", "辰"], type: "self" },
|
|
101
|
+
{ branches: ["午", "午"], type: "self" },
|
|
102
|
+
{ branches: ["酉", "酉"], type: "self" },
|
|
103
|
+
{ branches: ["亥", "亥"], type: "self" },
|
|
53
104
|
];
|
|
54
105
|
export const BRANCH_DESTRUCTIONS = [
|
|
55
106
|
["子", "酉"],
|
|
@@ -80,15 +131,27 @@ function checkTransformationCondition(resultElement, monthBranch, allBranches, i
|
|
|
80
131
|
const resultElementCount = branchElements.filter((e) => e === resultElement).length;
|
|
81
132
|
const hasStrengthSupport = resultElementCount >= 2;
|
|
82
133
|
if (!isComplete) {
|
|
83
|
-
return {
|
|
134
|
+
return {
|
|
135
|
+
status: getTransformationStatusLabel("halfCombined"),
|
|
136
|
+
reason: "불완전 합 - 일부 지지 부재",
|
|
137
|
+
};
|
|
84
138
|
}
|
|
85
139
|
if (hasMonthSupport) {
|
|
86
|
-
return {
|
|
140
|
+
return {
|
|
141
|
+
status: getTransformationStatusLabel("transformed"),
|
|
142
|
+
reason: `월령(${monthBranch})이 ${resultElement}을(를) 지지`,
|
|
143
|
+
};
|
|
87
144
|
}
|
|
88
145
|
if (hasStrengthSupport) {
|
|
89
|
-
return {
|
|
146
|
+
return {
|
|
147
|
+
status: getTransformationStatusLabel("transformed"),
|
|
148
|
+
reason: `${resultElement} 기세 충분(${resultElementCount}개)`,
|
|
149
|
+
};
|
|
90
150
|
}
|
|
91
|
-
return {
|
|
151
|
+
return {
|
|
152
|
+
status: getTransformationStatusLabel("notTransformed"),
|
|
153
|
+
reason: "월령 및 기세 미충족으로 화 불성립",
|
|
154
|
+
};
|
|
92
155
|
}
|
|
93
156
|
function checkStemTransformationCondition(resultElement, monthBranch, allStems) {
|
|
94
157
|
const supportedElements = MONTH_BRANCH_ELEMENT_SUPPORT[monthBranch] || [];
|
|
@@ -97,12 +160,21 @@ function checkStemTransformationCondition(resultElement, monthBranch, allStems)
|
|
|
97
160
|
const resultElementCount = stemElements.filter((e) => e === resultElement).length;
|
|
98
161
|
const hasStrengthSupport = resultElementCount >= 2;
|
|
99
162
|
if (hasMonthSupport) {
|
|
100
|
-
return {
|
|
163
|
+
return {
|
|
164
|
+
status: getTransformationStatusLabel("transformed"),
|
|
165
|
+
reason: `월령(${monthBranch})이 ${resultElement}을(를) 지지`,
|
|
166
|
+
};
|
|
101
167
|
}
|
|
102
168
|
if (hasStrengthSupport) {
|
|
103
|
-
return {
|
|
169
|
+
return {
|
|
170
|
+
status: getTransformationStatusLabel("transformed"),
|
|
171
|
+
reason: `${resultElement} 기세 충분(${resultElementCount}개)`,
|
|
172
|
+
};
|
|
104
173
|
}
|
|
105
|
-
return {
|
|
174
|
+
return {
|
|
175
|
+
status: getTransformationStatusLabel("notTransformed"),
|
|
176
|
+
reason: "월령 및 기세 미충족으로 화 불성립",
|
|
177
|
+
};
|
|
106
178
|
}
|
|
107
179
|
export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar) {
|
|
108
180
|
const monthBranch = monthPillar[1];
|
|
@@ -134,10 +206,10 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
134
206
|
(s1.char === combo.stems[1] && s2.char === combo.stems[0])) {
|
|
135
207
|
const transform = checkStemTransformationCondition(combo.resultElement, monthBranch, allStemChars);
|
|
136
208
|
combinations.push({
|
|
137
|
-
type: "
|
|
209
|
+
type: getRelationTypeLabel("stemCombination"),
|
|
138
210
|
pair: [s1.char, s2.char],
|
|
139
211
|
positions: [s1.position, s2.position],
|
|
140
|
-
resultElement: combo.resultElement,
|
|
212
|
+
resultElement: getElementLabel(combo.resultElement),
|
|
141
213
|
transformStatus: transform.status,
|
|
142
214
|
transformReason: transform.reason,
|
|
143
215
|
});
|
|
@@ -154,10 +226,10 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
154
226
|
(b1.char === combo.branches[1] && b2.char === combo.branches[0])) {
|
|
155
227
|
const transform = checkTransformationCondition(combo.resultElement, monthBranch, allBranchChars, true);
|
|
156
228
|
combinations.push({
|
|
157
|
-
type: "
|
|
229
|
+
type: getRelationTypeLabel("sixCombination"),
|
|
158
230
|
pair: [b1.char, b2.char],
|
|
159
231
|
positions: [b1.position, b2.position],
|
|
160
|
-
resultElement: combo.resultElement,
|
|
232
|
+
resultElement: getElementLabel(combo.resultElement),
|
|
161
233
|
transformStatus: transform.status,
|
|
162
234
|
transformReason: transform.reason,
|
|
163
235
|
});
|
|
@@ -167,7 +239,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
167
239
|
if ((b1.char === clash[0] && b2.char === clash[1]) ||
|
|
168
240
|
(b1.char === clash[1] && b2.char === clash[0])) {
|
|
169
241
|
clashes.push({
|
|
170
|
-
type: "
|
|
242
|
+
type: getRelationTypeLabel("clash"),
|
|
171
243
|
pair: [b1.char, b2.char],
|
|
172
244
|
positions: [b1.position, b2.position],
|
|
173
245
|
});
|
|
@@ -177,7 +249,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
177
249
|
if ((b1.char === harm[0] && b2.char === harm[1]) ||
|
|
178
250
|
(b1.char === harm[1] && b2.char === harm[0])) {
|
|
179
251
|
harms.push({
|
|
180
|
-
type: "
|
|
252
|
+
type: getRelationTypeLabel("harm"),
|
|
181
253
|
pair: [b1.char, b2.char],
|
|
182
254
|
positions: [b1.position, b2.position],
|
|
183
255
|
});
|
|
@@ -187,7 +259,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
187
259
|
if ((b1.char === dest[0] && b2.char === dest[1]) ||
|
|
188
260
|
(b1.char === dest[1] && b2.char === dest[0])) {
|
|
189
261
|
destructions.push({
|
|
190
|
-
type: "
|
|
262
|
+
type: getRelationTypeLabel("destruction"),
|
|
191
263
|
pair: [b1.char, b2.char],
|
|
192
264
|
positions: [b1.position, b2.position],
|
|
193
265
|
});
|
|
@@ -204,10 +276,10 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
204
276
|
const isComplete = matched.length === 3;
|
|
205
277
|
const transform = checkTransformationCondition(combo.resultElement, monthBranch, allBranchChars, isComplete);
|
|
206
278
|
combinations.push({
|
|
207
|
-
type: "
|
|
279
|
+
type: getRelationTypeLabel("tripleCombination"),
|
|
208
280
|
branches: matched,
|
|
209
281
|
positions,
|
|
210
|
-
resultElement: combo.resultElement,
|
|
282
|
+
resultElement: getElementLabel(combo.resultElement),
|
|
211
283
|
isComplete,
|
|
212
284
|
transformStatus: transform.status,
|
|
213
285
|
transformReason: transform.reason,
|
|
@@ -222,10 +294,10 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
222
294
|
const isComplete = matched.length === 3;
|
|
223
295
|
const transform = checkTransformationCondition(combo.resultElement, monthBranch, allBranchChars, isComplete);
|
|
224
296
|
combinations.push({
|
|
225
|
-
type: "
|
|
297
|
+
type: getRelationTypeLabel("directionalCombination"),
|
|
226
298
|
branches: matched,
|
|
227
299
|
positions,
|
|
228
|
-
resultElement: combo.resultElement,
|
|
300
|
+
resultElement: getElementLabel(combo.resultElement),
|
|
229
301
|
isComplete,
|
|
230
302
|
transformStatus: transform.status,
|
|
231
303
|
transformReason: transform.reason,
|
|
@@ -235,17 +307,17 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
235
307
|
for (const punishment of BRANCH_PUNISHMENTS) {
|
|
236
308
|
const matched = punishment.branches.filter((b) => branchChars.includes(b));
|
|
237
309
|
const isTriple = punishment.branches.length === 3;
|
|
238
|
-
const isSelfPunishment = punishment.type === "
|
|
310
|
+
const isSelfPunishment = punishment.type === "self";
|
|
239
311
|
if (isSelfPunishment) {
|
|
240
312
|
const count = branchChars.filter((b) => b === punishment.branches[0]).length;
|
|
241
313
|
if (count >= 2) {
|
|
242
314
|
punishments.push({
|
|
243
|
-
type: "
|
|
315
|
+
type: getRelationTypeLabel("punishment"),
|
|
244
316
|
branches: Array(count).fill(punishment.branches[0]),
|
|
245
317
|
positions: branches
|
|
246
318
|
.filter((b) => b.char === punishment.branches[0])
|
|
247
319
|
.map((b) => b.position),
|
|
248
|
-
punishmentType: punishment.type,
|
|
320
|
+
punishmentType: getPunishmentTypeLabel(punishment.type),
|
|
249
321
|
});
|
|
250
322
|
}
|
|
251
323
|
}
|
|
@@ -253,20 +325,20 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
|
|
|
253
325
|
// biome-ignore lint/style/noNonNullAssertion: matched is filtered from branchChars, find is guaranteed
|
|
254
326
|
const positions = matched.map((m) => branches.find((b) => b.char === m).position);
|
|
255
327
|
punishments.push({
|
|
256
|
-
type: "
|
|
328
|
+
type: getRelationTypeLabel("punishment"),
|
|
257
329
|
branches: matched,
|
|
258
330
|
positions,
|
|
259
|
-
punishmentType: punishment.type,
|
|
331
|
+
punishmentType: getPunishmentTypeLabel(punishment.type),
|
|
260
332
|
});
|
|
261
333
|
}
|
|
262
334
|
else if (!isTriple && matched.length === 2) {
|
|
263
335
|
// biome-ignore lint/style/noNonNullAssertion: matched is filtered from branchChars, find is guaranteed
|
|
264
336
|
const positions = matched.map((m) => branches.find((b) => b.char === m).position);
|
|
265
337
|
punishments.push({
|
|
266
|
-
type: "
|
|
338
|
+
type: getRelationTypeLabel("punishment"),
|
|
267
339
|
branches: matched,
|
|
268
340
|
positions,
|
|
269
|
-
punishmentType: punishment.type,
|
|
341
|
+
punishmentType: getPunishmentTypeLabel(punishment.type),
|
|
270
342
|
});
|
|
271
343
|
}
|
|
272
344
|
}
|
package/dist/core/sinsals.d.ts
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
|
-
import type { PillarPosition } from "../types";
|
|
1
|
+
import type { Label, PillarPosition } from "../types";
|
|
2
2
|
export declare const SINSALS: readonly ["peachBlossom", "skyHorse", "floweryCanopy", "ghostGate", "solitaryStar", "widowStar", "heavenlyVirtue", "monthlyVirtue", "skyNoble", "moonNoble", "literaryNoble", "academicHall", "bloodKnife", "sixHarms", "whiteCloth", "heavenlyDoctor"];
|
|
3
|
-
export type
|
|
3
|
+
export type SinsalKey = (typeof SINSALS)[number];
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated Use SinsalKey instead
|
|
6
|
+
*/
|
|
7
|
+
export type Sinsal = SinsalKey;
|
|
8
|
+
export type SinsalType = "auspicious" | "inauspicious" | "neutral";
|
|
9
|
+
export interface SinsalLabel extends Label<SinsalKey> {
|
|
10
|
+
meaning: string;
|
|
11
|
+
type: SinsalType;
|
|
12
|
+
}
|
|
4
13
|
export interface SinsalMatch {
|
|
5
|
-
sinsal:
|
|
14
|
+
sinsal: SinsalLabel;
|
|
6
15
|
position: PillarPosition;
|
|
7
16
|
}
|
|
8
17
|
export interface SinsalResult {
|
|
9
18
|
matches: SinsalMatch[];
|
|
10
|
-
summary: Partial<Record<
|
|
19
|
+
summary: Partial<Record<SinsalKey, PillarPosition[]>>;
|
|
11
20
|
}
|
|
12
21
|
export declare function analyzeSinsals(yearPillar: string, monthPillar: string, dayPillar: string, hourPillar: string): SinsalResult;
|
|
13
|
-
export declare const SINSAL_INFO: Record<
|
|
22
|
+
export declare const SINSAL_INFO: Record<SinsalKey, {
|
|
14
23
|
korean: string;
|
|
15
24
|
hanja: string;
|
|
16
25
|
meaning: string;
|
|
17
|
-
type:
|
|
26
|
+
type: SinsalType;
|
|
18
27
|
}>;
|
|
28
|
+
export declare function getSinsalLabel(key: SinsalKey): SinsalLabel;
|
|
19
29
|
//# sourceMappingURL=sinsals.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sinsals.d.ts","sourceRoot":"","sources":["../../src/core/sinsals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
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,yPAiBV,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,SAAS,CAAC;AAE/B,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+LD,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,CAqId;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,CAmFF,CAAC;AAEF,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,WAAW,CAS1D"}
|
package/dist/core/sinsals.js
CHANGED
|
@@ -192,26 +192,26 @@ const HEAVENLY_DOCTOR_MAP = {
|
|
|
192
192
|
戌: "酉",
|
|
193
193
|
亥: "戌",
|
|
194
194
|
};
|
|
195
|
-
function checkBranchBasedSinsal(baseBranch, targetBranches, positions, map,
|
|
195
|
+
function checkBranchBasedSinsal(baseBranch, targetBranches, positions, map, sinsalKey) {
|
|
196
196
|
const matches = [];
|
|
197
197
|
const targetSinsal = map[baseBranch];
|
|
198
198
|
if (targetSinsal) {
|
|
199
199
|
targetBranches.forEach((branch, idx) => {
|
|
200
200
|
if (branch === targetSinsal) {
|
|
201
|
-
matches.push({ sinsal, position: positions[idx] });
|
|
201
|
+
matches.push({ sinsal: getSinsalLabel(sinsalKey), position: positions[idx] });
|
|
202
202
|
}
|
|
203
203
|
});
|
|
204
204
|
}
|
|
205
205
|
return matches;
|
|
206
206
|
}
|
|
207
|
-
function checkStemBasedSinsal(baseStem, targetBranches, positions, map,
|
|
207
|
+
function checkStemBasedSinsal(baseStem, targetBranches, positions, map, sinsalKey) {
|
|
208
208
|
const matches = [];
|
|
209
209
|
const targetSinsal = map[baseStem];
|
|
210
210
|
if (targetSinsal) {
|
|
211
211
|
const targets = Array.isArray(targetSinsal) ? targetSinsal : [targetSinsal];
|
|
212
212
|
targetBranches.forEach((branch, idx) => {
|
|
213
213
|
if (targets.includes(branch)) {
|
|
214
|
-
matches.push({ sinsal, position: positions[idx] });
|
|
214
|
+
matches.push({ sinsal: getSinsalLabel(sinsalKey), position: positions[idx] });
|
|
215
215
|
}
|
|
216
216
|
});
|
|
217
217
|
}
|
|
@@ -244,13 +244,14 @@ export function analyzeSinsals(yearPillar, monthPillar, dayPillar, hourPillar) {
|
|
|
244
244
|
matches.push(...checkStemBasedSinsal(dayStem, allBranches, positions, ACADEMIC_HALL_MAP, "academicHall"));
|
|
245
245
|
matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, BLOOD_KNIFE_MAP, "bloodKnife"));
|
|
246
246
|
matches.push(...checkBranchBasedSinsal(monthBranch, allBranches, positions, HEAVENLY_DOCTOR_MAP, "heavenlyDoctor"));
|
|
247
|
-
const uniqueMatches = matches.filter((match, index, self) => index ===
|
|
247
|
+
const uniqueMatches = matches.filter((match, index, self) => index ===
|
|
248
|
+
self.findIndex((m) => m.sinsal.key === match.sinsal.key && m.position === match.position));
|
|
248
249
|
const summary = {};
|
|
249
250
|
for (const match of uniqueMatches) {
|
|
250
|
-
if (!summary[match.sinsal]) {
|
|
251
|
-
summary[match.sinsal] = [];
|
|
251
|
+
if (!summary[match.sinsal.key]) {
|
|
252
|
+
summary[match.sinsal.key] = [];
|
|
252
253
|
}
|
|
253
|
-
summary[match.sinsal]?.push(match.position);
|
|
254
|
+
summary[match.sinsal.key]?.push(match.position);
|
|
254
255
|
}
|
|
255
256
|
return { matches: uniqueMatches, summary };
|
|
256
257
|
}
|
|
@@ -337,3 +338,13 @@ export const SINSAL_INFO = {
|
|
|
337
338
|
type: "auspicious",
|
|
338
339
|
},
|
|
339
340
|
};
|
|
341
|
+
export function getSinsalLabel(key) {
|
|
342
|
+
const info = SINSAL_INFO[key];
|
|
343
|
+
return {
|
|
344
|
+
key,
|
|
345
|
+
korean: info.korean,
|
|
346
|
+
hanja: info.hanja,
|
|
347
|
+
meaning: info.meaning,
|
|
348
|
+
type: info.type,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
@@ -1,110 +1,23 @@
|
|
|
1
1
|
import type { DateAdapter } from "../adapters/date-adapter";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
readonly longitude: 315;
|
|
18
|
-
}, {
|
|
19
|
-
readonly name: "우수";
|
|
20
|
-
readonly hanja: "雨水";
|
|
21
|
-
readonly longitude: 330;
|
|
22
|
-
}, {
|
|
23
|
-
readonly name: "경칩";
|
|
24
|
-
readonly hanja: "驚蟄";
|
|
25
|
-
readonly longitude: 345;
|
|
26
|
-
}, {
|
|
27
|
-
readonly name: "춘분";
|
|
28
|
-
readonly hanja: "春分";
|
|
29
|
-
readonly longitude: 0;
|
|
30
|
-
}, {
|
|
31
|
-
readonly name: "청명";
|
|
32
|
-
readonly hanja: "淸明";
|
|
33
|
-
readonly longitude: 15;
|
|
34
|
-
}, {
|
|
35
|
-
readonly name: "곡우";
|
|
36
|
-
readonly hanja: "穀雨";
|
|
37
|
-
readonly longitude: 30;
|
|
38
|
-
}, {
|
|
39
|
-
readonly name: "입하";
|
|
40
|
-
readonly hanja: "立夏";
|
|
41
|
-
readonly longitude: 45;
|
|
42
|
-
}, {
|
|
43
|
-
readonly name: "소만";
|
|
44
|
-
readonly hanja: "小滿";
|
|
45
|
-
readonly longitude: 60;
|
|
46
|
-
}, {
|
|
47
|
-
readonly name: "망종";
|
|
48
|
-
readonly hanja: "芒種";
|
|
49
|
-
readonly longitude: 75;
|
|
50
|
-
}, {
|
|
51
|
-
readonly name: "하지";
|
|
52
|
-
readonly hanja: "夏至";
|
|
53
|
-
readonly longitude: 90;
|
|
54
|
-
}, {
|
|
55
|
-
readonly name: "소서";
|
|
56
|
-
readonly hanja: "小暑";
|
|
57
|
-
readonly longitude: 105;
|
|
58
|
-
}, {
|
|
59
|
-
readonly name: "대서";
|
|
60
|
-
readonly hanja: "大暑";
|
|
61
|
-
readonly longitude: 120;
|
|
62
|
-
}, {
|
|
63
|
-
readonly name: "입추";
|
|
64
|
-
readonly hanja: "立秋";
|
|
65
|
-
readonly longitude: 135;
|
|
66
|
-
}, {
|
|
67
|
-
readonly name: "처서";
|
|
68
|
-
readonly hanja: "處暑";
|
|
69
|
-
readonly longitude: 150;
|
|
70
|
-
}, {
|
|
71
|
-
readonly name: "백로";
|
|
72
|
-
readonly hanja: "白露";
|
|
73
|
-
readonly longitude: 165;
|
|
74
|
-
}, {
|
|
75
|
-
readonly name: "추분";
|
|
76
|
-
readonly hanja: "秋分";
|
|
77
|
-
readonly longitude: 180;
|
|
78
|
-
}, {
|
|
79
|
-
readonly name: "한로";
|
|
80
|
-
readonly hanja: "寒露";
|
|
81
|
-
readonly longitude: 195;
|
|
82
|
-
}, {
|
|
83
|
-
readonly name: "상강";
|
|
84
|
-
readonly hanja: "霜降";
|
|
85
|
-
readonly longitude: 210;
|
|
86
|
-
}, {
|
|
87
|
-
readonly name: "입동";
|
|
88
|
-
readonly hanja: "立冬";
|
|
89
|
-
readonly longitude: 225;
|
|
90
|
-
}, {
|
|
91
|
-
readonly name: "소설";
|
|
92
|
-
readonly hanja: "小雪";
|
|
93
|
-
readonly longitude: 240;
|
|
94
|
-
}, {
|
|
95
|
-
readonly name: "대설";
|
|
96
|
-
readonly hanja: "大雪";
|
|
97
|
-
readonly longitude: 255;
|
|
98
|
-
}, {
|
|
99
|
-
readonly name: "동지";
|
|
100
|
-
readonly hanja: "冬至";
|
|
101
|
-
readonly longitude: 270;
|
|
102
|
-
}];
|
|
103
|
-
export type SolarTermName = (typeof SOLAR_TERMS)[number]["name"];
|
|
104
|
-
export type SolarTermHanja = (typeof SOLAR_TERMS)[number]["hanja"];
|
|
2
|
+
import type { Label } from "../types";
|
|
3
|
+
export declare const SOLAR_TERM_KEYS: readonly ["minorCold", "majorCold", "springBegins", "rainWater", "awakeningInsects", "vernalEquinox", "pureBrightness", "grainRain", "summerBegins", "grainBuds", "grainInEar", "summerSolstice", "minorHeat", "majorHeat", "autumnBegins", "heatStops", "whiteDew", "autumnalEquinox", "coldDew", "frostDescends", "winterBegins", "minorSnow", "majorSnow", "winterSolstice"];
|
|
4
|
+
export type SolarTermKey = (typeof SOLAR_TERM_KEYS)[number];
|
|
5
|
+
export interface SolarTermLabel extends Label<SolarTermKey> {
|
|
6
|
+
longitude: number;
|
|
7
|
+
}
|
|
8
|
+
declare const SOLAR_TERM_DATA: Record<SolarTermKey, {
|
|
9
|
+
korean: string;
|
|
10
|
+
hanja: string;
|
|
11
|
+
longitude: number;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function getSolarTermLabel(key: SolarTermKey): SolarTermLabel;
|
|
14
|
+
export declare const SOLAR_TERMS: SolarTermLabel[];
|
|
15
|
+
export type SolarTermName = (typeof SOLAR_TERM_DATA)[SolarTermKey]["korean"];
|
|
16
|
+
export type SolarTermHanja = (typeof SOLAR_TERM_DATA)[SolarTermKey]["hanja"];
|
|
105
17
|
export interface SolarTerm {
|
|
106
|
-
|
|
107
|
-
|
|
18
|
+
key: SolarTermKey;
|
|
19
|
+
korean: string;
|
|
20
|
+
hanja: string;
|
|
108
21
|
longitude: number;
|
|
109
22
|
}
|
|
110
23
|
export interface SolarTermDateInfo {
|
|
@@ -152,4 +65,5 @@ export declare function getSolarTermsForYear<T>(adapter: DateAdapter<T>, year: n
|
|
|
152
65
|
term: SolarTerm;
|
|
153
66
|
date: SolarTermDateInfo;
|
|
154
67
|
}>;
|
|
68
|
+
export {};
|
|
155
69
|
//# sourceMappingURL=solar-terms.d.ts.map
|
|
@@ -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;
|
|
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,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,aAAa,CA0EvF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,KAAK,CAAC;IACP,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC,CAuBD"}
|
package/dist/core/solar-terms.js
CHANGED
|
@@ -1,33 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{ name: "입동", hanja: "立冬", longitude: 225 },
|
|
27
|
-
{ name: "소설", hanja: "小雪", longitude: 240 },
|
|
28
|
-
{ name: "대설", hanja: "大雪", longitude: 255 },
|
|
29
|
-
{ name: "동지", hanja: "冬至", longitude: 270 },
|
|
1
|
+
export const SOLAR_TERM_KEYS = [
|
|
2
|
+
"minorCold",
|
|
3
|
+
"majorCold",
|
|
4
|
+
"springBegins",
|
|
5
|
+
"rainWater",
|
|
6
|
+
"awakeningInsects",
|
|
7
|
+
"vernalEquinox",
|
|
8
|
+
"pureBrightness",
|
|
9
|
+
"grainRain",
|
|
10
|
+
"summerBegins",
|
|
11
|
+
"grainBuds",
|
|
12
|
+
"grainInEar",
|
|
13
|
+
"summerSolstice",
|
|
14
|
+
"minorHeat",
|
|
15
|
+
"majorHeat",
|
|
16
|
+
"autumnBegins",
|
|
17
|
+
"heatStops",
|
|
18
|
+
"whiteDew",
|
|
19
|
+
"autumnalEquinox",
|
|
20
|
+
"coldDew",
|
|
21
|
+
"frostDescends",
|
|
22
|
+
"winterBegins",
|
|
23
|
+
"minorSnow",
|
|
24
|
+
"majorSnow",
|
|
25
|
+
"winterSolstice",
|
|
30
26
|
];
|
|
27
|
+
const SOLAR_TERM_DATA = {
|
|
28
|
+
minorCold: { korean: "소한", hanja: "小寒", longitude: 285 },
|
|
29
|
+
majorCold: { korean: "대한", hanja: "大寒", longitude: 300 },
|
|
30
|
+
springBegins: { korean: "입춘", hanja: "立春", longitude: 315 },
|
|
31
|
+
rainWater: { korean: "우수", hanja: "雨水", longitude: 330 },
|
|
32
|
+
awakeningInsects: { korean: "경칩", hanja: "驚蟄", longitude: 345 },
|
|
33
|
+
vernalEquinox: { korean: "춘분", hanja: "春分", longitude: 0 },
|
|
34
|
+
pureBrightness: { korean: "청명", hanja: "淸明", longitude: 15 },
|
|
35
|
+
grainRain: { korean: "곡우", hanja: "穀雨", longitude: 30 },
|
|
36
|
+
summerBegins: { korean: "입하", hanja: "立夏", longitude: 45 },
|
|
37
|
+
grainBuds: { korean: "소만", hanja: "小滿", longitude: 60 },
|
|
38
|
+
grainInEar: { korean: "망종", hanja: "芒種", longitude: 75 },
|
|
39
|
+
summerSolstice: { korean: "하지", hanja: "夏至", longitude: 90 },
|
|
40
|
+
minorHeat: { korean: "소서", hanja: "小暑", longitude: 105 },
|
|
41
|
+
majorHeat: { korean: "대서", hanja: "大暑", longitude: 120 },
|
|
42
|
+
autumnBegins: { korean: "입추", hanja: "立秋", longitude: 135 },
|
|
43
|
+
heatStops: { korean: "처서", hanja: "處暑", longitude: 150 },
|
|
44
|
+
whiteDew: { korean: "백로", hanja: "白露", longitude: 165 },
|
|
45
|
+
autumnalEquinox: { korean: "추분", hanja: "秋分", longitude: 180 },
|
|
46
|
+
coldDew: { korean: "한로", hanja: "寒露", longitude: 195 },
|
|
47
|
+
frostDescends: { korean: "상강", hanja: "霜降", longitude: 210 },
|
|
48
|
+
winterBegins: { korean: "입동", hanja: "立冬", longitude: 225 },
|
|
49
|
+
minorSnow: { korean: "소설", hanja: "小雪", longitude: 240 },
|
|
50
|
+
majorSnow: { korean: "대설", hanja: "大雪", longitude: 255 },
|
|
51
|
+
winterSolstice: { korean: "동지", hanja: "冬至", longitude: 270 },
|
|
52
|
+
};
|
|
53
|
+
export function getSolarTermLabel(key) {
|
|
54
|
+
const data = SOLAR_TERM_DATA[key];
|
|
55
|
+
return { key, ...data };
|
|
56
|
+
}
|
|
57
|
+
export const SOLAR_TERMS = SOLAR_TERM_KEYS.map((key) => getSolarTermLabel(key));
|
|
31
58
|
function normDeg(x) {
|
|
32
59
|
x %= 360;
|
|
33
60
|
return x < 0 ? x + 360 : x;
|
package/dist/core/strength.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import type { Label } from "../types";
|
|
2
|
+
export declare const STRENGTH_LEVEL_KEYS: readonly ["extremelyWeak", "veryWeak", "weak", "neutralWeak", "neutral", "neutralStrong", "strong", "veryStrong", "extremelyStrong"];
|
|
3
|
+
export type StrengthLevelKey = (typeof STRENGTH_LEVEL_KEYS)[number];
|
|
4
|
+
export interface StrengthLevelLabel extends Label<StrengthLevelKey> {
|
|
5
|
+
}
|
|
6
|
+
export declare function getStrengthLevelLabel(key: StrengthLevelKey): StrengthLevelLabel;
|
|
7
|
+
/** @deprecated Use StrengthLevelKey instead */
|
|
1
8
|
export type StrengthLevel = "극약" | "태약" | "신약" | "중화신약" | "중화" | "중화신강" | "신강" | "태강" | "극왕";
|
|
9
|
+
/** @deprecated Use STRENGTH_LEVEL_KEYS instead */
|
|
2
10
|
export declare const STRENGTH_LEVELS: StrengthLevel[];
|
|
3
11
|
export interface StrengthFactors {
|
|
4
12
|
deukryeong: number;
|
|
@@ -9,7 +17,7 @@ export interface StrengthFactors {
|
|
|
9
17
|
weakenCount: number;
|
|
10
18
|
}
|
|
11
19
|
export interface StrengthResult {
|
|
12
|
-
level:
|
|
20
|
+
level: StrengthLevelLabel;
|
|
13
21
|
score: number;
|
|
14
22
|
factors: StrengthFactors;
|
|
15
23
|
description: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strength.d.ts","sourceRoot":"","sources":["../../src/core/strength.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"strength.d.ts","sourceRoot":"","sources":["../../src/core/strength.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGrC,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;AAED,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GACrB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,MAAM,GACN,IAAI,GACJ,MAAM,GACN,IAAI,GACJ,IAAI,GACJ,IAAI,CAAC;AAET,kDAAkD;AAClD,eAAO,MAAM,eAAe,EAAE,aAAa,EAU1C,CAAC;AAsKF,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;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CAsGhB"}
|