feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets
This commit is contained in:
@@ -0,0 +1,662 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build I Ching canon: 8 Ba Gua trigrams + 64 King Wen hexagrams.
|
||||
|
||||
Updates:
|
||||
oracle_enricher/data/traditions_canon.json
|
||||
assets/data/traditions_canon.json
|
||||
lexicon_viewer.html (embedded TRADITIONS_CANON)
|
||||
oracle_enricher/data/sources/iching.yaml
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
CANON_PATH = ROOT / "oracle_enricher" / "data" / "traditions_canon.json"
|
||||
ASSET_PATH = ROOT / "assets" / "data" / "traditions_canon.json"
|
||||
HTML_PATH = ROOT / "lexicon_viewer.html"
|
||||
LEXICON_PATH = ROOT / "oracle_enricher" / "data" / "lexicon.json"
|
||||
DART_PATH = ROOT / "lib" / "data" / "words_data.dart"
|
||||
YAML_PATH = ROOT / "oracle_enricher" / "data" / "sources" / "iching.yaml"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 8 trigrams (Ba Gua)
|
||||
# ---------------------------------------------------------------------------
|
||||
TRIGRAMS = [
|
||||
{
|
||||
"id": "qian",
|
||||
"name": "Триграмма ☰ Цянь (Творчество / Небо)",
|
||||
"symbol": "☰",
|
||||
"group": "Ба Гуа · Отец",
|
||||
"lore": "Первичная созидающая сила неба: неутомимая крепость духа, высшая воля, свет, лидерство и власть закона.",
|
||||
"names": ["небо", "небосвод", "творец", "воля", "свет"],
|
||||
"aspects": ["чистый ян", "несокрушимая сила", "непрерывное движение", "семя замысла", "свет духа"],
|
||||
"shadow": ["гордыня", "выжигание без опоры", "тирания жесткости"],
|
||||
"yaml_name": "Творчество (Небо)",
|
||||
"hanzi": "乾",
|
||||
},
|
||||
{
|
||||
"id": "kun",
|
||||
"name": "Триграмма ☷ Кунь (Исполнение / Земля)",
|
||||
"symbol": "☷",
|
||||
"group": "Ба Гуа · Мать",
|
||||
"lore": "Самоотверженное принятие, великое земное плодородие, мягкость, питание всех существ, верность и покой.",
|
||||
"names": ["земля", "мать", "покой", "лоно"],
|
||||
"aspects": ["чистый инь", "восприимчивость", "питающее лоно", "преданное следование", "уступчивость"],
|
||||
"shadow": ["косность", "инертность", "потеря формы"],
|
||||
"yaml_name": "Исполнение (Земля)",
|
||||
"hanzi": "坤",
|
||||
},
|
||||
{
|
||||
"id": "zhen",
|
||||
"name": "Триграмма ☳ Чжэнь (Возбуждение / Гром)",
|
||||
"symbol": "☳",
|
||||
"group": "Ба Гуа · Старший сын",
|
||||
"lore": "Пробуждающий удар грома, импульсивный прорыв весны, сокрушение оцепенения, страх, ведущий к осмотрительности.",
|
||||
"names": ["гром", "молния", "удар"],
|
||||
"aspects": ["возбуждение", "внезапный толчок", "раскат небес", "шок пробуждения", "первое движение"],
|
||||
"shadow": ["паника", "сотрясение без плода", "слепая ярость"],
|
||||
"yaml_name": "Пробуждение (Гром)",
|
||||
"hanzi": "震",
|
||||
},
|
||||
{
|
||||
"id": "kan",
|
||||
"name": "Триграмма ☵ Кань (Погружение / Вода)",
|
||||
"symbol": "☵",
|
||||
"group": "Ба Гуа · Средний сын",
|
||||
"lore": "Опасность стремнины, глубина бездны, неостановимый бег воды, верность своей природе среди теснин.",
|
||||
"names": ["вода", "бездна", "опасность"],
|
||||
"aspects": ["глубина", "текучесть в расселинах", "опасный поток", "искренность сердца в испытании", "неиссякаемый исток"],
|
||||
"shadow": ["утопление в страхе", "холод отчаяния", "затягивающий водоворот"],
|
||||
"yaml_name": "Погружение (Вода)",
|
||||
"hanzi": "坎",
|
||||
},
|
||||
{
|
||||
"id": "gen",
|
||||
"name": "Триграмма ☶ Гэнь (Пребывание / Гора)",
|
||||
"symbol": "☶",
|
||||
"group": "Ба Гуа · Младший сын",
|
||||
"lore": "Неподвижность священной горы, способность вовремя остановиться, завершение движения, крепость духа.",
|
||||
"names": ["гора", "скала", "покой", "спина"],
|
||||
"aspects": ["незыблемая остановка", "покой спины", "граница движения", "молчание скалы", "завершение фазы"],
|
||||
"shadow": ["каменный застой", "глухота к переменам", "черствость"],
|
||||
"yaml_name": "Пребывание (Гора)",
|
||||
"hanzi": "艮",
|
||||
},
|
||||
{
|
||||
"id": "xun",
|
||||
"name": "Триграмма ☴ Сюнь (Утончение / Ветер)",
|
||||
"symbol": "☴",
|
||||
"group": "Ба Гуа · Старшая дочь",
|
||||
"lore": "Мягкое всепроникающее дыхание ветра, гибкость древесных ветвей, постепенное незаметное влияние.",
|
||||
"names": ["ветер", "дыхание", "воздух", "дерево"],
|
||||
"aspects": ["проникновение", "мягкая гибкость", "незаметное влияние", "постоянство дыхания", "корни дерева"],
|
||||
"shadow": ["размывание границ", "уклончивость", "бессилие удара"],
|
||||
"yaml_name": "Утончение (Ветер)",
|
||||
"hanzi": "巽",
|
||||
},
|
||||
{
|
||||
"id": "li",
|
||||
"name": "Триграмма ☲ Ли (Сцепление / Огонь)",
|
||||
"symbol": "☲",
|
||||
"group": "Ба Гуа · Средняя дочь",
|
||||
"lore": "Очищающее пламя, свет познания, ясность видения, тепло очага, зависимость пламени от питающей древесины.",
|
||||
"names": ["огонь", "пламя", "сияние", "свет"],
|
||||
"aspects": ["ясность видения", "солярный свет", "преображающее тепло", "приверженность истине", "зависимость от топлива"],
|
||||
"shadow": ["выгорание", "ослепляющая иллюзия", "пожирающая страсть"],
|
||||
"yaml_name": "Сцепление (Огонь)",
|
||||
"hanzi": "離",
|
||||
},
|
||||
{
|
||||
"id": "dui",
|
||||
"name": "Триграмма ☱ Дуй (Разрешение / Озеро)",
|
||||
"symbol": "☱",
|
||||
"group": "Ба Гуа · Младшая дочь",
|
||||
"lore": "Зеркальная гладь спокойного озера, открытая радость общения, благожелательность, поэзия и вдохновение.",
|
||||
"names": ["озеро", "радость", "смех", "рот", "зеркало"],
|
||||
"aspects": ["зеркало вод", "открытая радость", "плодотворный диалог", "улыбка сердца", "чистое отражение"],
|
||||
"shadow": ["пустая болтовня", "разлив соблазна", "легкомыслие"],
|
||||
"yaml_name": "Разрешение (Озеро)",
|
||||
"hanzi": "兌",
|
||||
},
|
||||
]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 64 hexagrams — King Wen order, Shchutsky Russian names
|
||||
# group key before ' · ' becomes the atlas section header
|
||||
# ---------------------------------------------------------------------------
|
||||
def _hex(n: int) -> str:
|
||||
return chr(0x4DC0 + (n - 1))
|
||||
|
||||
|
||||
def _grp(n: int) -> str:
|
||||
start = ((n - 1) // 8) * 8 + 1
|
||||
end = start + 7
|
||||
return f"Книга Перемен · {start:02d}–{end:02d}"
|
||||
|
||||
|
||||
HEX_HANZI = {
|
||||
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: "大畜", 27: "頤", 28: "大過", 29: "坎", 30: "離", 31: "咸", 32: "恆",
|
||||
33: "遯", 34: "大壯", 35: "晉", 36: "明夷", 37: "家人", 38: "睽", 39: "蹇", 40: "解",
|
||||
41: "損", 42: "益", 43: "夬", 44: "姤", 45: "萃", 46: "升", 47: "困", 48: "井",
|
||||
49: "革", 50: "鼎", 51: "震", 52: "艮", 53: "漸", 54: "歸妹", 55: "豐", 56: "旅",
|
||||
57: "巽", 58: "兌", 59: "渙", 60: "節", 61: "中孚", 62: "小過", 63: "既濟", 64: "未濟",
|
||||
}
|
||||
|
||||
|
||||
HEXAGRAMS = [
|
||||
dict(n=1, pid="qian", ru="Творчество", py="Цянь",
|
||||
lore="Небо над небом: чистый ян без перерыва. Неутомимое творчество, крепость духа и ход, который сам себе закон. Знак велит держаться замысла до конца и не искать опоры внизу.",
|
||||
names=["творец", "небо", "воля", "свет", "небосвод"],
|
||||
aspects=["сухое небо", "непрерывное творчество", "настойчивость до конца", "свет духа", "закон силы"],
|
||||
shadow=["жёсткость без земли", "гордыня творца", "выжигание без опоры"]),
|
||||
dict(n=2, pid="kun", ru="Исполнение", py="Кунь",
|
||||
lore="Земля над землёй: чистое принятие. Плодородие, преданное следование и сила кобылы, которая несёт, не выбирая всадника. Знак велит служить и вынашивать, а не захватывать ход.",
|
||||
names=["земля", "мать", "покой"],
|
||||
aspects=["чистый приём", "вместилище", "плодородие", "следование", "кобыла пути"],
|
||||
shadow=["инертность", "косность", "потеря формы"]),
|
||||
dict(n=3, pid="zhun", ru="Начальная трудность", py="Чжунь",
|
||||
lore="Вода над громом: росток ещё под мерзлой землёй. Первые всходы требуют корней, а не рывка. Знак держит хаос перед порядком и верность зародышу.",
|
||||
names=["росток", "семя", "начать", "бездна", "гром"],
|
||||
aspects=["пробивание мерзлой земли", "накопление корней", "верность зародышу", "хаос перед порядком"],
|
||||
shadow=["преждевременный рывок", "увядание на корню", "страх перед миром"]),
|
||||
dict(n=4, pid="meng", ru="Недоразвитость", py="Мэн",
|
||||
lore="Гора над водой: родник у подножия, закрытый туманом. Ученичество, искренний вопрос и поиск учителя. Знак рассеивает неведение только тому, кто спрашивает трижды и слушает.",
|
||||
names=["ученик", "туман", "учиться", "гора", "источник"],
|
||||
aspects=["родник у горы", "искреннее вопрошание", "смирение ученичества", "поиск учителя"],
|
||||
shadow=["упрямое невежество", "дерзость дилетанта", "пустые споры"]),
|
||||
dict(n=5, pid="xu", ru="Необходимость ждать", py="Сюй",
|
||||
lore="Вода над небом: облака ещё не стали дождём. Священное ожидание, накопление и пир веры, пока час не созрел. Знак велит не торопить тучу.",
|
||||
names=["ждать", "терпение", "туча", "дождь", "пир"],
|
||||
aspects=["облака в ожидании дождя", "накопление потенциала", "священный пир веры", "созревание часа"],
|
||||
shadow=["парализующая лень", "отчаяние ожидания", "упущенный момент"]),
|
||||
dict(n=6, pid="song", ru="Суд", py="Сун",
|
||||
lore="Небо над водой: верх и глубина разошлись. Тяжба, проверка совести и поиск беспристрастного суда. Знак велит остановиться на полпути и признать предел правоты.",
|
||||
names=["суд", "закон", "справедливость", "спор"],
|
||||
aspects=["расхождение Неба и Воды", "проверка совести", "беспристрастный суд", "признание предела"],
|
||||
shadow=["бесконечная вражда", "жажда мести", "гордыня правоты"]),
|
||||
dict(n=7, pid="shi", ru="Войско", py="Ши",
|
||||
lore="Земля над водой: скрытая сила в недрах. Дисциплина, единая цель и зрелый полководец. Знак даёт справедливость силы и требует, чтобы войско служило порядку, а не жажде крови.",
|
||||
names=["войско", "воин", "солдат", "земля", "вода"],
|
||||
aspects=["скрытая сила воды в земле", "суровая дисциплина", "единство цели", "зрелый полководец"],
|
||||
shadow=["жестокость приказа", "напрасные жертвы", "войско без вождя"]),
|
||||
dict(n=8, pid="bi", ru="Приближение", py="Би",
|
||||
lore="Вода над землёй: добровольное единение. Союз, взаимная опора и выбор соратников. Знак зовёт встать рядом вовремя — опоздание к союзу уже тень.",
|
||||
names=["союз", "близкий", "связь", "вода", "земля"],
|
||||
aspects=["вода орошает землю", "добровольное единение", "верность союзу", "выбор соратников"],
|
||||
shadow=["опоздание к союзу", "фальшивая лесть", "зависимость"]),
|
||||
dict(n=9, pid="xiao_xu", ru="Воспитание малым", py="Сяо-чу",
|
||||
lore="Ветер над небом: малая туча ещё не льёт. Сдерживание великого малым, накопление капли за каплей. Знак учит мягкой узде, а не удару.",
|
||||
names=["ветер", "небо", "терпение", "дыхание"],
|
||||
aspects=["малая туча на небе", "сдерживание великого", "накопление по капле", "мягкая узда"],
|
||||
shadow=["бессилие узды", "мелочный контроль", "туча без дождя"]),
|
||||
dict(n=10, pid="lu", ru="Поступь", py="Люй",
|
||||
lore="Небо над озером: ступать по хвосту тигра и не быть укушенным. Осторожный шаг в присутствии силы. Знак требует меры в каждом ходе.",
|
||||
names=["шаг", "ход", "путь", "тигр", "мера"],
|
||||
aspects=["ступня на хвосте тигра", "осторожный этикет", "мера каждого хода", "опасная близость силы"],
|
||||
shadow=["дерзость шага", "укус тигра", "потеря лица"]),
|
||||
dict(n=11, pid="tai", ru="Расцвет", py="Тай",
|
||||
lore="Земля над небом: священный брак низа и верха. Малое уходит, великое приходит. Золотой век согласия, плодородие и расцвет — пока не забыли об упадке.",
|
||||
names=["мир", "изобилие", "весна", "благодать", "земля"],
|
||||
aspects=["земля над небом", "золотой век согласия", "малое уходит великое приходит", "плодородие сил"],
|
||||
shadow=["беспечность благополучия", "забывчивость об упадке", "сытая слепота"]),
|
||||
dict(n=12, pid="pi", ru="Упадок", py="Пи",
|
||||
lore="Небо над землёй: миры удалились друг от друга. Застой, сокрытие мудреца и сбережение зерна. Знак велит не служить недостойным и ждать поворота.",
|
||||
names=["уныние", "слабость", "отчаяние", "небо", "земля"],
|
||||
aspects=["разрыв связи миров", "сокрытие мудреца", "сбережение зерна", "терпеливая аскеза"],
|
||||
shadow=["отчаяние как дом", "подчинение недостойным", "утрата веры"]),
|
||||
dict(n=13, pid="tong_ren", ru="Родня", py="Тун-жэнь",
|
||||
lore="Небо над огнём: люди одного света собираются в открытом поле. Содружество по духу, а не по крови. Знак требует широкого круга и прямого сердца.",
|
||||
names=["род", "брат", "союз", "огонь", "небо"],
|
||||
aspects=["содружество в открытом поле", "единство по духу", "широкий круг", "прямое сердце"],
|
||||
shadow=["клан против чужих", "ложное братство", "огонь кружка"]),
|
||||
dict(n=14, pid="da_you", ru="Великое обладание", py="Да-ю",
|
||||
lore="Огонь над небом: солнце в зените владеет всем, что видит. Богатство, ясность и великая мера. Знак велит держать изобилие светлым, иначе оно слепит.",
|
||||
names=["изобилие", "золото", "успех", "огонь", "небо"],
|
||||
aspects=["солнце в зените", "владение ясностью", "великая мера", "светлое богатство"],
|
||||
shadow=["слепящая роскошь", "жадность к свету", "обладание без меры"]),
|
||||
dict(n=15, pid="qian_mod", ru="Смирение", py="Цянь",
|
||||
lore="Земля над горой: высокая внутри, низкая снаружи. Смирение как закон силы, которая не выпирает. Знак уравнивает избыток и восполняет недостаток.",
|
||||
names=["смирение", "гора", "земля"],
|
||||
aspects=["высокая внутри низкая снаружи", "уравнивание избытка", "сила без выпирания", "скромный ход"],
|
||||
shadow=["ложное смирение", "самоуничижение", "гора под спудом"]),
|
||||
dict(n=16, pid="yu", ru="Вольность", py="Юй",
|
||||
lore="Гром над землёй: музыка предвидения, радость готовности. Знак зовёт собирать войско в настроении праздника — вольность, которая знает срок удара.",
|
||||
names=["радость", "гром", "свобода", "земля"],
|
||||
aspects=["гром над землёй", "музыка предвидения", "радость готовности", "сбор войска в празднике"],
|
||||
shadow=["разгул без срока", "праздность вместо удара", "ложная вольность"]),
|
||||
dict(n=17, pid="sui", ru="Последование", py="Суй",
|
||||
lore="Озеро над громом: радость следует за возбуждением. Знак велит идти за тем, что истинно движется, и отпускать то, что уже не ведёт.",
|
||||
names=["идти", "вести", "радость", "гром"],
|
||||
aspects=["радость за возбуждением", "следование истинному движению", "отпускание мёртвого вождя"],
|
||||
shadow=["слепое следование", "стадный ход", "потеря своего удара"]),
|
||||
dict(n=18, pid="gu", ru="Исправление порчи", py="Гу",
|
||||
lore="Гора над ветром: ветер заперт и гниёт. Расчистка наследственных завалов, три дня до и три дня после. Знак требует чистить порчу, а не жить в ней.",
|
||||
names=["скверна", "яд", "целитель", "гора", "ветер"],
|
||||
aspects=["ветер под горой", "расчистка наследства", "три дня до и после", "очищающая реформа"],
|
||||
shadow=["отравление прошлым", "страх растревожить гниль", "бессилие перед традицией"]),
|
||||
dict(n=19, pid="lin", ru="Посещение", py="Линь",
|
||||
lore="Земля над озером: приближение великого к малому. Надзор, забота и срок восьмого месяца. Знак даёт приход силы — и предупреждает, что приход не вечен.",
|
||||
names=["гость", "озеро", "земля", "приближение"],
|
||||
aspects=["приближение великого", "надзор и забота", "срок восьмого месяца", "приход силы"],
|
||||
shadow=["навязчивый надзор", "гость, который не уходит", "забота как захват"]),
|
||||
dict(n=20, pid="guan", ru="Созерцание", py="Гуань",
|
||||
lore="Ветер над землёй: башня взора, чистота помыслов перед жертвой. Знак ставит пример без слов — созерцать закон космоса и быть видимым как маяк.",
|
||||
names=["созерцание", "взгляд", "маяк", "ветер", "земля"],
|
||||
aspects=["башня визионерского взора", "чистота перед жертвой", "безмолвный пример", "постижение космоса"],
|
||||
shadow=["праздное любопытство", "оторванность от действия", "холод наблюдателя"]),
|
||||
dict(n=21, pid="shi_he", ru="Стиснутые зубы", py="Ши-хэ",
|
||||
lore="Огонь над громом: стиснуть и перекусить преграду. Судебная ясность, удар по помехе, глоток правды. Знак велит разгрызть узел, а не обходить его.",
|
||||
names=["удар", "закон", "огонь", "гром", "суд"],
|
||||
aspects=["перекусить преграду", "судебная ясность", "удар по помехе", "глоток правды"],
|
||||
shadow=["ломание зубов о камень", "жестокость приговора", "гнев вместо суда"]),
|
||||
dict(n=22, pid="bi_grace", ru="Убранство", py="Би",
|
||||
lore="Гора над огнём: огонь освещает форму горы. Красота как оболочка сути, не как суть. Знак даёт убранство малому и велит не принимать позолоту за кость.",
|
||||
names=["сияние", "маска", "гора", "огонь", "форма"],
|
||||
aspects=["огонь освещает гору", "красота как оболочка", "убранство малого", "форма без подмены сути"],
|
||||
shadow=["позолота вместо кости", "суета украшения", "маска, съевшая лицо"]),
|
||||
dict(n=23, pid="bo", ru="Разорение", py="Бо",
|
||||
lore="Гора над землёй: верх осыпается, остаётся ложе. Сдирание ветхой формы, конец цикла, обнажение основы. Знак велит не удерживать то, что уже осыпается.",
|
||||
names=["угасание", "гора", "земля", "конец"],
|
||||
aspects=["осыпание верха", "сдирание ветхой формы", "обнажение основы", "конец цикла"],
|
||||
shadow=["цепляться за осыпь", "разрушение без остатка", "паника конца"]),
|
||||
dict(n=24, pid="fu", ru="Возврат", py="Фу",
|
||||
lore="Земля над громом: первый ян в глубине тьмы. Поворот колеса, семь дней обновления, закрытые врата покоя. Знак велит дать ростку срок и не рвать его на свет.",
|
||||
names=["вернуться", "искра", "цикл", "гром", "земля"],
|
||||
aspects=["первый ян во тьме", "поворот колеса года", "семь дней обновления", "покой закрытых врат"],
|
||||
shadow=["поспешность незрелого света", "страх темноты", "рецидив старой ошибки"]),
|
||||
dict(n=25, pid="wu_wang", ru="Беспорочность", py="У-ван",
|
||||
lore="Небо над громом: движение без кривды. Невинный удар, который не рассчитывает выгоду. Знак бережёт чистоту намерения и гасит ход, затеянный ради добычи.",
|
||||
names=["чистота", "небо", "гром", "истина"],
|
||||
aspects=["движение без кривды", "невинный удар", "чистота намерения", "ход не ради добычи"],
|
||||
shadow=["наивность как слепота", "удар без расчёта", "чистота как предлог"]),
|
||||
dict(n=26, pid="da_xu", ru="Воспитание великим", py="Да-чу",
|
||||
lore="Гора над небом: небо удержано в горе. Великое накопление, кормление мудрости, сила в упряжи. Знак велит копить и воспитывать, а не выпускать всё сразу.",
|
||||
names=["гора", "небо", "сила", "мудрость"],
|
||||
aspects=["небо удержано в горе", "великое накопление", "кормление мудрости", "сила в упряжи"],
|
||||
shadow=["скупость накопления", "сила без выпуска", "гора как тюрьма неба"]),
|
||||
dict(n=27, pid="yi_jaws", ru="Питание", py="И",
|
||||
lore="Гора над громом: челюсти, которые кормят или пожирают. Знак спрашивает, чем ты питаешь себя и других — речью, хлебом, вниманием — и велит смотреть на рот.",
|
||||
names=["хлеб", "голод", "рот", "гора", "гром"],
|
||||
aspects=["челюсти питания", "чем кормишь себя", "речь как пища", "взгляд на рот"],
|
||||
shadow=["пожирание", "пустой рот", "питание чужим"]),
|
||||
dict(n=28, pid="da_guo", ru="Переразвитие великого", py="Да-го",
|
||||
lore="Озеро над ветром: балка прогнулась под тяжестью крыши. Избыток великого, крайний срок подпорок. Знак велит действовать сейчас: стоять или рухнуть.",
|
||||
names=["озеро", "ветер", "дерево", "верёвка"],
|
||||
aspects=["прогнувшаяся балка", "избыток великого", "крайний срок подпорок", "стоять или рухнуть"],
|
||||
shadow=["обвал крыши", "упрямство в избытке", "поздняя подпорка"]),
|
||||
dict(n=29, pid="kan_hex", ru="Повторная опасность", py="Кань",
|
||||
lore="Вода над водой: бездна в бездне. Испытание верности через риск, стремление не замирать в омуте. Знак закаливает сердце, если оно остаётся искренним в порогах.",
|
||||
names=["бездна", "опасность", "вода"],
|
||||
aspects=["вода над водой", "испытание через риск", "не останавливаться в стремнине", "глубинная закалка"],
|
||||
shadow=["ужас глубины", "паника в порогах", "предательство себя"]),
|
||||
dict(n=30, pid="li_hex", ru="Сияние", py="Ли",
|
||||
lore="Огонь над огнём: двойная ясность, зависимость от топлива. Сцепление света с тем, что его кормит. Знак даёт видение и велит не выгореть посреди дня.",
|
||||
names=["огонь", "сияние", "свет", "пламя"],
|
||||
aspects=["двойная ясность", "сцепление с топливом", "видение дня", "свет, который держится за опору"],
|
||||
shadow=["выгорание середины", "ослепление", "пожар без очага"]),
|
||||
dict(n=31, pid="xian", ru="Взаимодействие", py="Сянь",
|
||||
lore="Озеро над горой: влияние, которое сходит сверху на неподвижное. Притяжение, отклик сердца, священный брак чувств. Знак велит принять воздействие и ответить без захвата.",
|
||||
names=["любовь", "встреча", "союз", "озеро", "гора"],
|
||||
aspects=["влияние сверху на гору", "притяжение сердец", "священный отклик", "принять и ответить"],
|
||||
shadow=["захват чувством", "слепая влюблённость", "влияние как власть"]),
|
||||
dict(n=32, pid="heng", ru="Постоянство", py="Хэн",
|
||||
lore="Гром над ветром: долгий брак движения и проникновения. Выдержка, клятва на срок, ритм, который не срывается. Знак велит держать курс, а не искать новый ветер каждый час.",
|
||||
names=["цикл", "клятва", "вечность", "гром", "ветер"],
|
||||
aspects=["долгий брак грома и ветра", "выдержка", "клятва на срок", "ритм без срыва"],
|
||||
shadow=["рутина вместо верности", "упрямство курса", "клятва мёртвому"]),
|
||||
dict(n=33, pid="dun", ru="Бегство", py="Дунь",
|
||||
lore="Небо над горой: мудрец отступает, пока сила тьмы ещё мала. Стратегический уход, сохранение ядра. Знак велит уйти вовремя — не геройствовать на гиблом поле.",
|
||||
names=["бежать", "гора", "небо", "изгнанник"],
|
||||
aspects=["отступление мудреца", "уход пока тьма мала", "сохранение ядра", "стратегический тыл"],
|
||||
shadow=["паническое бегство", "уход от срока", "оставление поля слишком рано"]),
|
||||
dict(n=34, pid="da_zhuang", ru="Мощь великого", py="Да-чжуан",
|
||||
lore="Гром над небом: сила в зените, рога баранов. Великая мощь требует прямоты — иначе рога застрянут в изгороди. Знак даёт удар и велит не бодать без пути.",
|
||||
names=["сила", "гром", "небо", "баран"],
|
||||
aspects=["сила в зените", "рога баранов", "прямота удара", "мощь, которая знает путь"],
|
||||
shadow=["бодание изгороди", "слепая мощь", "сила без прямоты"]),
|
||||
dict(n=35, pid="jin", ru="Восход", py="Цзинь",
|
||||
lore="Огонь над землёй: солнце всходит над почвой. Продвижение, признание, свет, который уже виден всем. Знак даёт восход заслуги — и предупреждает не принимать рассвет за полдень.",
|
||||
names=["рассвет", "свет", "огонь", "земля", "успех"],
|
||||
aspects=["солнце над почвой", "продвижение заслуги", "свет, видимый всем", "восход, не полдень"],
|
||||
shadow=["жажда признания", "рассвет как корона", "свет без корня"]),
|
||||
dict(n=36, pid="ming_yi", ru="Поражение света", py="Мин-и",
|
||||
lore="Земля над огнём: свет ранен и спрятан в земле. Затмение, мудрость в изгнании, крыло, которое прячут. Знак велит хранить ясность внутри, когда снаружи правят тьма и рана.",
|
||||
names=["затмение", "тьма", "рана", "земля", "огонь"],
|
||||
aspects=["свет спрятан в земле", "мудрость в изгнании", "спрятанное крыло", "ясность внутри раны"],
|
||||
shadow=["угасание духа", "сотрудничество с тьмой", "рана как характер"]),
|
||||
dict(n=37, pid="jia_ren", ru="Домашние", py="Цзя-жэнь",
|
||||
lore="Ветер над огнём: огонь очага, ветер речей семьи. Порядок дома, роли, слово, которое держит кров. Знак велит начать правление с собственного очага.",
|
||||
names=["дом", "семья", "очаг", "ветер", "огонь"],
|
||||
aspects=["огонь очага", "ветер семейных речей", "порядок ролей", "правление с дома"],
|
||||
shadow=["тирания дома", "сплетня очага", "семья как клетка"]),
|
||||
dict(n=38, pid="kui", ru="Разлад", py="Куй",
|
||||
lore="Огонь над озером: два света смотрят врозь. Отчуждение, несходство, огонь и озеро не смешиваются. Знак учит малому согласию внутри большого разлада — и не требует слияния силой.",
|
||||
names=["враг", "огонь", "озеро", "двойник"],
|
||||
aspects=["два света врозь", "отчуждение", "малое согласие в разладе", "несходство без слияния"],
|
||||
shadow=["вражда ради вражды", "принудительное слияние", "огонь, высушивший озеро"]),
|
||||
dict(n=39, pid="jian", ru="Препятствие", py="Цзянь",
|
||||
lore="Вода над горой: стремнина на хребте. Преграда, которая велит идти не вперёд, а за советом. Знак останавливает прямой ход и открывает юг — путь к мудрому.",
|
||||
names=["гора", "вода", "пропасть", "скала"],
|
||||
aspects=["стремнина на хребте", "преграда прямого хода", "идти за советом", "юг к мудрому"],
|
||||
shadow=["упрямство в тупике", "штурм пропасти", "отказ от совета"]),
|
||||
dict(n=40, pid="xie", ru="Разрешение", py="Се",
|
||||
lore="Гром над водой: гроза разряжает бездну. Снятие пут, прощение, стрела, вынутая из раны. Знак велит освободить вовремя — держать узел после грозы уже порча.",
|
||||
names=["гром", "вода", "свобода", "прощение"],
|
||||
aspects=["гроза над бездной", "снятие пут", "стрела из раны", "освобождение в срок"],
|
||||
shadow=["разрешение слишком рано", "месть вместо прощения", "узел, который не развязали"]),
|
||||
dict(n=41, pid="sun", ru="Убыль", py="Сунь",
|
||||
lore="Гора над озером: озеро отдаёт воде горе. Уменьшение низа ради верха, искренняя жертва двух чаш. Знак велит убавить простое, чтобы укрепить главное — и знать меру убыли.",
|
||||
names=["жертва", "отлив", "гора", "озеро", "мера"],
|
||||
aspects=["озеро отдаёт горе", "убыль низа ради верха", "две чаши жертвы", "мера уменьшения"],
|
||||
shadow=["самоистязание", "убыль без укрепления", "жертва впустую"]),
|
||||
dict(n=42, pid="yi_increase", ru="Прибыль", py="И",
|
||||
lore="Ветер над громом: верхи убавляются, низы прибывают. Дар свыше, прилив сил, пора сеять. Знак велит брать прибыль в работу, пока ветер несёт семя.",
|
||||
names=["дар", "изобилие", "прилив", "ветер", "гром"],
|
||||
aspects=["верхи убавляются низы прибывают", "дар свыше", "пора сеять", "прибыль в работу"],
|
||||
shadow=["жадность к дару", "прибыль без сева", "ветер, разнёсший семя"]),
|
||||
dict(n=43, pid="guai", ru="Выход", py="Гуай",
|
||||
lore="Озеро над небом: прорыв плотины, решительное объявление. Пять ян вытесняют последнее инь. Знак велит говорить правду в лицо и не применять тайного оружия.",
|
||||
names=["выход", "озеро", "небо", "правда"],
|
||||
aspects=["прорыв плотины", "решительное объявление", "пять ян против одного инь", "правда в лицо"],
|
||||
shadow=["слом плотины без берега", "насилие выхода", "тайное оружие"]),
|
||||
dict(n=44, pid="gou", ru="Перечение", py="Гоу",
|
||||
lore="Небо над ветром: встреча с тем, чего не звали. Один инь входит снизу в пять ян. Знак предупреждает: не выдавать за жениха то, что пришло как искушение.",
|
||||
names=["встреча", "искушение", "ветер", "небо"],
|
||||
aspects=["встреча незваного", "один инь в пяти ян", "искушение снизу", "не выдавать за союз"],
|
||||
shadow=["брак с порчей", "слепое влечение", "ветер, подточивший небо"]),
|
||||
dict(n=45, pid="cui", ru="Воссоединение", py="Цуй",
|
||||
lore="Озеро над землёй: воды собираются в низине. Сбор людей, жертва вождю, большое собрание. Знак велит соединиться вокруг достойного центра — иначе толпа станет болотом.",
|
||||
names=["союз", "встреча", "озеро", "земля", "пир"],
|
||||
aspects=["воды в низине", "сбор людей", "жертва вождю", "центр собрания"],
|
||||
shadow=["толпа без центра", "болото собрания", "вождь как идол"]),
|
||||
dict(n=46, pid="sheng", ru="Подъём", py="Шэн",
|
||||
lore="Земля над ветром: дерево растёт из почвы, не торопя день. Постепенный подъём, покорность земле, шаг за шагом вверх. Знак велит расти из корня, а не прыгать на вершину.",
|
||||
names=["рост", "дерево", "земля", "ветер"],
|
||||
aspects=["дерево из почвы", "постепенный подъём", "шаг за шагом", "рост из корня"],
|
||||
shadow=["прыжок без корня", "подъём чужими плечами", "спешка роста"]),
|
||||
dict(n=47, pid="kun_exhaust", ru="Истощение", py="Кунь",
|
||||
lore="Озеро над водой: озеро утекло, осталась яма. Сжатие, нужда, слово, которое не слышат. Знак велит хранить внутреннюю правду, когда внешняя сила иссякла.",
|
||||
names=["голод", "нужда", "озеро", "вода"],
|
||||
aspects=["утекающее озеро", "сжатие сил", "слово, которое не слышат", "правда внутри нужды"],
|
||||
shadow=["отчаяние ямы", "молчание как смерть", "нужда как закон"]),
|
||||
dict(n=48, pid="jing", ru="Колодец", py="Цзин",
|
||||
lore="Вода над ветром: вода поднимается по дереву. Неиссякаемый исток общины, кувшин у устья, глубина, которую не переносят с места на место. Знак велит беречь колодец, а не менять город.",
|
||||
names=["колодец", "источник", "родник", "вода", "дерево"],
|
||||
aspects=["вода по дереву", "исток общины", "непереносимая глубина", "кувшин у устья"],
|
||||
shadow=["заиленный колодец", "разбитый кувшин", "жадность к воде"]),
|
||||
dict(n=49, pid="ge", ru="Смена", py="Гэ",
|
||||
lore="Озеро над огнём: огонь вскипает в озере, змея меняет кожу. Переворот календаря, линька порядка. Знак велит менять шкуру, когда срок созрел, и иметь проект на место старого.",
|
||||
names=["змей", "лава", "феникс", "озеро", "огонь"],
|
||||
aspects=["огонь в озере", "смена шкуры", "обновление календаря", "линька порядка"],
|
||||
shadow=["бунт ради бунта", "разрушение без проекта", "запоздалое обновление"]),
|
||||
dict(n=50, pid="ding", ru="Котел", py="Дин",
|
||||
lore="Огонь над ветром: дерево кормит огонь под треножником. Священный котёл, превращение грубого в пищу духа, три ножки устойчивости. Знак велит варить культуру, а не опрокидывать сосуд.",
|
||||
names=["котёл", "сосуд", "алтарь", "огонь", "ветер"],
|
||||
aspects=["огонь под деревом", "алхимический сосуд", "жертвенная трапеза", "три ножки треножника"],
|
||||
shadow=["опрокинутый котёл", "осквернение пищи", "пустая ритуальность"]),
|
||||
dict(n=51, pid="zhen_hex", ru="Возбуждение", py="Чжэнь",
|
||||
lore="Гром над громом: двойной удар, священный страх. Пробуждение, осмотрительность после раската, жертвенное вино, которое не проливают. Знак трясёт, чтобы вернуть в себя.",
|
||||
names=["гром", "молния", "удар"],
|
||||
aspects=["двойной гром", "священный страх", "осмотрительность после раската", "пробуждение в себя"],
|
||||
shadow=["паника раската", "пролитое вино", "страх как характер"]),
|
||||
dict(n=52, pid="gen_hex", ru="Сосредоточенность", py="Гэнь",
|
||||
lore="Гора над горой: спина к спине, остановка каждой черты. Молчание, предел движения, храм покоя. Знак велит остановиться в своём месте и не следить за чужим телом.",
|
||||
names=["гора", "покой", "спина"],
|
||||
aspects=["гора над горой", "остановка каждой черты", "молчание спины", "предел движения"],
|
||||
shadow=["застой как добродетель", "глухота покоя", "остановка чужой жизни"]),
|
||||
dict(n=53, pid="jian_gradual", ru="Течение", py="Цзянь",
|
||||
lore="Ветер над горой: дерево на склоне растёт годами. Постепенность брака, дикого гуся, ступеней. Знак велит идти как течение — не прыжком, а укоренением на каждой полке склона.",
|
||||
names=["течение", "путь", "гора", "ветер", "дерево"],
|
||||
aspects=["дерево на склоне", "постепенность", "дикий гусь ступенями", "укоренение на полке"],
|
||||
shadow=["прыжок через ступень", "застой под видом постепенности", "течение в никуда"]),
|
||||
dict(n=54, pid="gui_mei", ru="Невеста", py="Гуй-мэй",
|
||||
lore="Гром над озером: младшая идёт в дом. Неравный союз, срок, который нельзя назначать самой. Знак предупреждает о браке без места и о радости, которая не стала правом.",
|
||||
names=["жена", "дочь", "озеро", "гром"],
|
||||
aspects=["младшая идёт в дом", "неравный союз", "срок не по своей воле", "радость без права"],
|
||||
shadow=["брак без места", "самовольный союз", "радость, ставшая унижением"]),
|
||||
dict(n=55, pid="feng", ru="Изобилие", py="Фэн",
|
||||
lore="Гром над огнём: полнота дня, которая уже держит тень. Изобилие в зените, ясность среди затмения, встреча царя. Знак велит действовать в полный час — после зенита свет сядет.",
|
||||
names=["изобилие", "гром", "огонь", "полдень"],
|
||||
aspects=["полнота дня", "ясность среди затмения", "встреча в зените", "час, который не длится"],
|
||||
shadow=["слепота изобилия", "зенит как вечность", "пир после света"]),
|
||||
dict(n=56, pid="lu_wander", ru="Странствие", py="Люй",
|
||||
lore="Огонь над горой: костёр на хребте, ночлег не свой. Странник, мера гостя, гнездо, которое не строят. Знак велит идти легко, не ссориться на постоялом дворе и помнить, что огонь чужой.",
|
||||
names=["странник", "путь", "огонь", "гора", "гость"],
|
||||
aspects=["костёр на хребте", "мера гостя", "гнездо, которое не строят", "лёгкий ход"],
|
||||
shadow=["ссора на постоялом дворе", "захват чужого очага", "странствие как бегство"]),
|
||||
dict(n=57, pid="xun_hex", ru="Проникновение", py="Сюнь",
|
||||
lore="Ветер над ветром: двойное проникновение без удара. Приказ, который разносится как дыхание, корень в щели камня. Знак побеждает гибкостью и повтором, не единоборством.",
|
||||
names=["ветер", "дыхание", "дерево"],
|
||||
aspects=["двойной ветер", "приказ как дыхание", "корень в щели", "гибкость и повтор"],
|
||||
shadow=["размывание воли", "уклончивость", "бессилие удара"]),
|
||||
dict(n=58, pid="dui_hex", ru="Радость", py="Дуй",
|
||||
lore="Озеро над озером: двойная радость открытых уст. Обмен речью, обучение через удовольствие, зеркало вод. Знак даёт радость как закон — и предупреждает о разливе болтовни.",
|
||||
names=["радость", "озеро", "смех", "рот"],
|
||||
aspects=["двойное озеро", "открытые уста", "обучение через радость", "зеркало вод"],
|
||||
shadow=["пустая болтовня", "разлив соблазна", "радость как бегство"]),
|
||||
dict(n=59, pid="huan", ru="Раздробление", py="Хуань",
|
||||
lore="Ветер над водой: ветер разгоняет лёд реки. Рассеяние эго, храм как общее тело, растворение затора. Знак велит разобрать сплочённую тьму — не копить её в себе.",
|
||||
names=["ветер", "вода", "туман", "храм"],
|
||||
aspects=["ветер разгоняет лёд", "рассеяние эго", "храм как общее тело", "растворение затора"],
|
||||
shadow=["распад без сбора", "растворение себя", "ветер, разнёсший храм"]),
|
||||
dict(n=60, pid="jie", ru="Ограничение", py="Цзе",
|
||||
lore="Вода над озером: озеро знает свой берег. Мера, устав, сладкое ограничение, которое не превращает жизнь в тюрьму. Знак велит поставить предел — и не затягивать узел до удушья.",
|
||||
names=["мера", "закон", "озеро", "вода", "берег"],
|
||||
aspects=["озеро знает берег", "сладкое ограничение", "устав меры", "предел без тюрьмы"],
|
||||
shadow=["удушье устава", "мера как клетка", "берег, съевший озеро"]),
|
||||
dict(n=61, pid="zhong_fu", ru="Внутренняя правда", py="Чжун-фу",
|
||||
lore="Ветер над озером: пустота в середине держит целое. Искренность, которая двигает даже свинью и рыбу. Знак велит совпасть внутри — внешний обряд без ядра пуст.",
|
||||
names=["правда", "истина", "сердце", "ветер", "озеро"],
|
||||
aspects=["пустота в середине", "искренность, движущая тварь", "ядро вместо обряда", "совпадение внутри"],
|
||||
shadow=["правда как поза", "пустота без ядра", "обряд без сердца"]),
|
||||
dict(n=62, pid="xiao_guo", ru="Переразвитие малого", py="Сяо-го",
|
||||
lore="Гром над горой: птица не должна взлетать слишком высоко. Малое превышение, внимание к низу, птица в гнезде. Знак велит скромный ход: лучше недолет, чем срыв в вышине.",
|
||||
names=["гром", "гора", "мера", "птицы"],
|
||||
aspects=["птица не слишком высоко", "малое превышение", "внимание к низу", "гнездо важнее взлёта"],
|
||||
shadow=["срыв в вышине", "мелочность как добродетель", "полёт без гнезда"]),
|
||||
dict(n=63, pid="ji_ji", ru="Уже конец", py="Цзи-цзи",
|
||||
lore="Вода над огнём: каждая черта на месте, переправа свершилась. Совершенный порядок на пике цикла. Знак велит бдительность лисы на льду: конец уже содержит начало распада.",
|
||||
names=["итог", "мост", "берег", "конец", "вода"],
|
||||
aspects=["вода над огнём", "успешная переправа", "строгий порядок черт", "бдительность лисы на льду"],
|
||||
shadow=["самоуспокоение", "начало распада", "подмоченный хвост"]),
|
||||
dict(n=64, pid="wei_ji", ru="Ещё не конец", py="Вэй-цзи",
|
||||
lore="Огонь над водой: огонь стремится вверх, вода вниз — дело не закрыто. Лисенок ещё в реке. Знак держит вечную незавершённость как потенциал: не объявлять финал, пока хвост мокр.",
|
||||
names=["цикл", "путь", "порог", "начало", "огонь"],
|
||||
aspects=["огонь над водой", "вечная незавершённость", "лисёнок в реке", "потенциал нового шага"],
|
||||
shadow=["бессилие довести", "вечные колебания", "страх финальной точки"]),
|
||||
]
|
||||
|
||||
|
||||
def load_lexicon():
|
||||
lex = json.loads(LEXICON_PATH.read_text(encoding="utf-8"))
|
||||
by_word = {e["word"]: e for e in lex}
|
||||
return lex, by_word
|
||||
|
||||
|
||||
def load_dart_desc():
|
||||
text = DART_PATH.read_text(encoding="utf-8")
|
||||
desc = {}
|
||||
for m in re.finditer(
|
||||
r'word:\s*"([^"]+)"[\s\S]*?description:\s*"([^"]*)"',
|
||||
text,
|
||||
):
|
||||
desc[m.group(1)] = m.group(2)
|
||||
return desc
|
||||
|
||||
|
||||
def payload(entry: dict, dart_desc: dict) -> dict:
|
||||
word = entry["word"]
|
||||
return {
|
||||
"id": entry["id"],
|
||||
"word": word,
|
||||
"emoji": entry.get("emoji", ""),
|
||||
"pos": entry.get("pos", ""),
|
||||
"category": entry.get("category", ""),
|
||||
"desc": dart_desc.get(word, ""),
|
||||
}
|
||||
|
||||
|
||||
def resolve(names: list[str], by_word: dict, dart_desc: dict):
|
||||
found = []
|
||||
seen = set()
|
||||
for n in names:
|
||||
if not n or n in seen:
|
||||
continue
|
||||
entry = by_word.get(n)
|
||||
if entry:
|
||||
seen.add(n)
|
||||
found.append(payload(entry, dart_desc))
|
||||
primary = found[0] if found else None
|
||||
cluster = found[1:]
|
||||
return primary, cluster
|
||||
|
||||
|
||||
def yaml_quote(s: str) -> str:
|
||||
if any(c in s for c in ":#{}[]&*!|>'\"%@`"):
|
||||
return json.dumps(s, ensure_ascii=False)
|
||||
return s
|
||||
|
||||
|
||||
def yaml_list(items: list[str], indent: int) -> str:
|
||||
pad = " " * indent
|
||||
lines = []
|
||||
for it in items:
|
||||
lines.append(f"{pad}- {yaml_quote(it)}")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def build_yaml(trigrams, hexagrams) -> str:
|
||||
chunks = []
|
||||
for t in trigrams:
|
||||
chunks.append(
|
||||
"\n".join(
|
||||
[
|
||||
f"- id: {t['id']}",
|
||||
f" name: {yaml_quote(t['yaml_name'])}",
|
||||
" names_ru:",
|
||||
yaml_list(t["names"], 4),
|
||||
" aspects:",
|
||||
yaml_list(t["aspects"], 4),
|
||||
" shadow:",
|
||||
yaml_list(t["shadow"], 4),
|
||||
"",
|
||||
]
|
||||
)
|
||||
)
|
||||
for h in hexagrams:
|
||||
hid = f"hex_{h['n']:02d}_{h['pid']}"
|
||||
name = f"{h['n']}. {h['ru']} ({h['py']})"
|
||||
chunks.append(
|
||||
"\n".join(
|
||||
[
|
||||
f"- id: {hid}",
|
||||
f" name: {yaml_quote(name)}",
|
||||
" names_ru:",
|
||||
yaml_list(h["names"], 4),
|
||||
" aspects:",
|
||||
yaml_list(h["aspects"], 4),
|
||||
" shadow:",
|
||||
yaml_list(h["shadow"], 4),
|
||||
"",
|
||||
]
|
||||
)
|
||||
)
|
||||
return "\n".join(chunks).rstrip() + "\n"
|
||||
|
||||
|
||||
def build_stations(by_word, dart_desc):
|
||||
stations = []
|
||||
missing = []
|
||||
|
||||
for t in TRIGRAMS:
|
||||
primary, cluster = resolve(t["names"], by_word, dart_desc)
|
||||
if primary is None:
|
||||
missing.append(t["id"])
|
||||
stations.append(
|
||||
{
|
||||
"id": t["id"],
|
||||
"name": t["name"],
|
||||
"symbol": t["symbol"],
|
||||
"hanzi": t.get("hanzi", ""),
|
||||
"group": t["group"],
|
||||
"lore": t["lore"],
|
||||
"primary": primary,
|
||||
"cluster": cluster,
|
||||
}
|
||||
)
|
||||
|
||||
for h in HEXAGRAMS:
|
||||
primary, cluster = resolve(h["names"], by_word, dart_desc)
|
||||
hid = f"hex_{h['n']:02d}_{h['pid']}"
|
||||
if primary is None:
|
||||
missing.append(hid)
|
||||
stations.append(
|
||||
{
|
||||
"id": hid,
|
||||
"name": f"Гексаграмма {h['n']:02d} {_hex(h['n'])} {h['py']} ({h['ru']})",
|
||||
"symbol": _hex(h["n"]),
|
||||
"hanzi": HEX_HANZI.get(h["n"], ""),
|
||||
"group": _grp(h["n"]),
|
||||
"lore": h["lore"],
|
||||
"primary": primary,
|
||||
"cluster": cluster,
|
||||
}
|
||||
)
|
||||
|
||||
return stations, missing
|
||||
|
||||
|
||||
def patch_html(canon: dict) -> None:
|
||||
html = HTML_PATH.read_text(encoding="utf-8")
|
||||
start = html.find(" const TRADITIONS_CANON = ")
|
||||
end = html.find(" const WORDS_DATA = ")
|
||||
if start < 0 or end < 0 or end <= start:
|
||||
raise SystemExit("не нашёл TRADITIONS_CANON / WORDS_DATA в lexicon_viewer.html")
|
||||
blob = " const TRADITIONS_CANON = " + json.dumps(canon, ensure_ascii=False, indent=2) + ";\n\n"
|
||||
HTML_PATH.write_text(html[:start] + blob + html[end:], encoding="utf-8")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
_, by_word = load_lexicon()
|
||||
dart_desc = load_dart_desc()
|
||||
print(f"lexicon={len(by_word)} dart_desc={len(dart_desc)}")
|
||||
|
||||
stations, missing = build_stations(by_word, dart_desc)
|
||||
if missing:
|
||||
print("WARNING no primary:", ", ".join(missing))
|
||||
|
||||
iching = {
|
||||
"id": "iching",
|
||||
"name": "И Цзин (Книга Перемен)",
|
||||
"icon": "☯️",
|
||||
"count": len(stations),
|
||||
"description": "8 триграмм Ба Гуа и 64 гексаграммы Книги Перемен в порядке царя Вэня: первородные силы Инь и Ян и полные оракульные фигуры из двух триграмм.",
|
||||
"stations": stations,
|
||||
}
|
||||
|
||||
canon = json.loads(CANON_PATH.read_text(encoding="utf-8"))
|
||||
canon["iching"] = iching
|
||||
text = json.dumps(canon, ensure_ascii=False, indent=2) + "\n"
|
||||
CANON_PATH.write_text(text, encoding="utf-8")
|
||||
ASSET_PATH.write_text(text, encoding="utf-8")
|
||||
patch_html(canon)
|
||||
YAML_PATH.write_text(build_yaml(TRIGRAMS, HEXAGRAMS), encoding="utf-8")
|
||||
|
||||
n_tri = sum(1 for s in stations if s["id"] in {t["id"] for t in TRIGRAMS})
|
||||
n_hex = len(stations) - n_tri
|
||||
n_prim = sum(1 for s in stations if s.get("primary"))
|
||||
print(f"iching stations={len(stations)} trigrams={n_tri} hexagrams={n_hex} with_primary={n_prim}")
|
||||
print("wrote", CANON_PATH.relative_to(ROOT))
|
||||
print("wrote", ASSET_PATH.relative_to(ROOT))
|
||||
print("patched", HTML_PATH.relative_to(ROOT))
|
||||
print("wrote", YAML_PATH.relative_to(ROOT))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user