feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets
This commit is contained in:
+556
-3
@@ -1,3 +1,83 @@
|
||||
import 'culture_branch.dart';
|
||||
|
||||
class SymbolLayer {
|
||||
final String system;
|
||||
final String title;
|
||||
final String law;
|
||||
|
||||
const SymbolLayer({
|
||||
required this.system,
|
||||
required this.title,
|
||||
required this.law,
|
||||
});
|
||||
|
||||
factory SymbolLayer.fromMap(Map<String, dynamic> map) {
|
||||
return SymbolLayer(
|
||||
system: map['system'] as String? ?? '',
|
||||
title: map['title'] as String? ?? '',
|
||||
law: map['law'] as String? ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
'system': system,
|
||||
'title': title,
|
||||
'law': law,
|
||||
};
|
||||
}
|
||||
|
||||
class SymbolSource {
|
||||
final String system;
|
||||
final String ref;
|
||||
final double weight;
|
||||
|
||||
const SymbolSource({
|
||||
required this.system,
|
||||
required this.ref,
|
||||
required this.weight,
|
||||
});
|
||||
|
||||
factory SymbolSource.fromMap(Map<String, dynamic> map) {
|
||||
return SymbolSource(
|
||||
system: map['system'] as String? ?? '',
|
||||
ref: map['ref'] as String? ?? '',
|
||||
weight: (map['weight'] as num?)?.toDouble() ?? 1.0,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
'system': system,
|
||||
'ref': ref,
|
||||
'weight': weight,
|
||||
};
|
||||
}
|
||||
|
||||
class SymbolGrammar {
|
||||
final String operator;
|
||||
final String valence;
|
||||
final String modifies;
|
||||
|
||||
const SymbolGrammar({
|
||||
this.operator = 'substance',
|
||||
this.valence = 'liminal',
|
||||
this.modifies = '',
|
||||
});
|
||||
|
||||
factory SymbolGrammar.fromMap(Map<String, dynamic> map) {
|
||||
return SymbolGrammar(
|
||||
operator: map['operator'] as String? ?? 'substance',
|
||||
valence: map['valence'] as String? ?? 'liminal',
|
||||
modifies: map['modifies'] as String? ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
'operator': operator,
|
||||
'valence': valence,
|
||||
'modifies': modifies,
|
||||
};
|
||||
}
|
||||
|
||||
class WordItem {
|
||||
final int id; // Base index 0..999
|
||||
final int sessionNumber; // Dynamic randomized session number 0..999
|
||||
@@ -6,6 +86,27 @@ class WordItem {
|
||||
final double frequency;
|
||||
final String category;
|
||||
final String description;
|
||||
final String emoji;
|
||||
|
||||
// Enriched Oracle Knowledge Base fields
|
||||
final String family;
|
||||
final String operator;
|
||||
final String valence;
|
||||
final List<String> jurisdictions;
|
||||
final String lookup; // 'A', 'B', 'C'
|
||||
final bool hasCanon;
|
||||
final String core;
|
||||
final String oracle;
|
||||
final List<SymbolLayer> layers;
|
||||
final String shadow;
|
||||
final String asks;
|
||||
final String step;
|
||||
final List<String> binds;
|
||||
final List<SymbolSource> sources;
|
||||
final SymbolGrammar? grammar;
|
||||
final bool isUserEdited;
|
||||
final Map<String, String> cultures;
|
||||
final Map<String, String> languages;
|
||||
|
||||
const WordItem({
|
||||
required this.id,
|
||||
@@ -15,6 +116,25 @@ class WordItem {
|
||||
required this.frequency,
|
||||
this.category = '',
|
||||
this.description = '',
|
||||
this.emoji = '',
|
||||
this.family = '',
|
||||
this.operator = 'substance',
|
||||
this.valence = 'liminal',
|
||||
this.jurisdictions = const [],
|
||||
this.lookup = 'C',
|
||||
this.hasCanon = false,
|
||||
this.core = '',
|
||||
this.oracle = '',
|
||||
this.layers = const [],
|
||||
this.shadow = '',
|
||||
this.asks = '',
|
||||
this.step = '',
|
||||
this.binds = const [],
|
||||
this.sources = const [],
|
||||
this.grammar,
|
||||
this.isUserEdited = false,
|
||||
this.cultures = const {},
|
||||
this.languages = const {},
|
||||
});
|
||||
|
||||
WordItem copyWith({
|
||||
@@ -25,6 +145,25 @@ class WordItem {
|
||||
double? frequency,
|
||||
String? category,
|
||||
String? description,
|
||||
String? emoji,
|
||||
String? family,
|
||||
String? operator,
|
||||
String? valence,
|
||||
List<String>? jurisdictions,
|
||||
String? lookup,
|
||||
bool? hasCanon,
|
||||
String? core,
|
||||
String? oracle,
|
||||
List<SymbolLayer>? layers,
|
||||
String? shadow,
|
||||
String? asks,
|
||||
String? step,
|
||||
List<String>? binds,
|
||||
List<SymbolSource>? sources,
|
||||
SymbolGrammar? grammar,
|
||||
bool? isUserEdited,
|
||||
Map<String, String>? cultures,
|
||||
Map<String, String>? languages,
|
||||
}) {
|
||||
return WordItem(
|
||||
id: id ?? this.id,
|
||||
@@ -34,9 +173,110 @@ class WordItem {
|
||||
frequency: frequency ?? this.frequency,
|
||||
category: category ?? this.category,
|
||||
description: description ?? this.description,
|
||||
emoji: emoji ?? this.emoji,
|
||||
family: family ?? this.family,
|
||||
operator: operator ?? this.operator,
|
||||
valence: valence ?? this.valence,
|
||||
jurisdictions: jurisdictions ?? this.jurisdictions,
|
||||
lookup: lookup ?? this.lookup,
|
||||
hasCanon: hasCanon ?? this.hasCanon,
|
||||
core: core ?? this.core,
|
||||
oracle: oracle ?? this.oracle,
|
||||
layers: layers ?? this.layers,
|
||||
shadow: shadow ?? this.shadow,
|
||||
asks: asks ?? this.asks,
|
||||
step: step ?? this.step,
|
||||
binds: binds ?? this.binds,
|
||||
sources: sources ?? this.sources,
|
||||
grammar: grammar ?? this.grammar,
|
||||
isUserEdited: isUserEdited ?? this.isUserEdited,
|
||||
cultures: cultures ?? this.cultures,
|
||||
languages: languages ?? this.languages,
|
||||
);
|
||||
}
|
||||
|
||||
/// Enrich existing WordItem with data from oracle_kb.json entry
|
||||
WordItem enrichWithKb(Map<String, dynamic> kb) {
|
||||
final rawLayers = kb['layers'] as List<dynamic>? ?? [];
|
||||
final parsedLayers = rawLayers
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map((m) => SymbolLayer.fromMap(m))
|
||||
.toList();
|
||||
|
||||
final rawSourcesList = kb['sources'] is List ? (kb['sources'] as List) : [];
|
||||
final parsedSources = rawSourcesList
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map((m) => SymbolSource.fromMap(m))
|
||||
.toList();
|
||||
|
||||
final rawJurisdictions = kb['jurisdictions'] is List
|
||||
? (kb['jurisdictions'] as List).map((e) => e.toString()).toList()
|
||||
: <String>[];
|
||||
|
||||
final rawBinds = kb['binds'] is List
|
||||
? (kb['binds'] as List).map((e) => e.toString()).toList()
|
||||
: (kb['binds'] is String ? [kb['binds'].toString()] : <String>[]);
|
||||
|
||||
final rawGrammar = kb['grammar'] as Map<String, dynamic>?;
|
||||
|
||||
final rawKbCultures = kb['cultures'] as Map<String, dynamic>?;
|
||||
final parsedKbCultures = rawKbCultures != null
|
||||
? rawKbCultures.map((k, v) => MapEntry(k.toString(), v.toString()))
|
||||
: <String, String>{};
|
||||
|
||||
final rawKbLanguages = kb['languages'] as Map<String, dynamic>?;
|
||||
final parsedKbLanguages = rawKbLanguages != null
|
||||
? rawKbLanguages.map((k, v) => MapEntry(k.toString(), v.toString()))
|
||||
: <String, String>{};
|
||||
|
||||
final kbCore = (kb['core'] as String? ?? '').trim();
|
||||
final kbOracle = (kb['oracle'] as String? ?? '').trim();
|
||||
final kbHasCanon = (kb['has_canon'] as bool? ?? false) || (kbCore.isNotEmpty && kbOracle.isNotEmpty);
|
||||
|
||||
return copyWith(
|
||||
partOfSpeech: partOfSpeech.isNotEmpty ? partOfSpeech : ((kb['pos'] as String?) ?? partOfSpeech),
|
||||
category: (kb['category'] as String?)?.isNotEmpty == true ? kb['category'] as String : category,
|
||||
family: kb['family'] as String? ?? family,
|
||||
operator: kb['operator'] as String? ?? operator,
|
||||
valence: kb['valence'] as String? ?? valence,
|
||||
jurisdictions: rawJurisdictions.isNotEmpty ? rawJurisdictions : jurisdictions,
|
||||
lookup: kb['lookup'] as String? ?? lookup,
|
||||
hasCanon: kbHasCanon,
|
||||
core: kbCore,
|
||||
oracle: kbOracle,
|
||||
layers: parsedLayers,
|
||||
shadow: kb['shadow'] as String? ?? shadow,
|
||||
asks: kb['asks'] as String? ?? asks,
|
||||
step: kb['step'] as String? ?? step,
|
||||
binds: rawBinds,
|
||||
sources: parsedSources,
|
||||
emoji: (kb['emoji'] as String?)?.isNotEmpty == true ? kb['emoji'] as String : emoji,
|
||||
grammar: rawGrammar != null ? SymbolGrammar.fromMap(rawGrammar) : grammar,
|
||||
cultures: parsedKbCultures.isNotEmpty ? parsedKbCultures : cultures,
|
||||
languages: parsedKbLanguages.isNotEmpty ? parsedKbLanguages : languages,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns description stripped of raw metadata bracket tags like [Таро: ...]
|
||||
String get cleanDescription {
|
||||
final clean = description.replaceAll(RegExp(r'\[[^\]]+\]\s*'), '').trim();
|
||||
return clean.isNotEmpty ? clean : description;
|
||||
}
|
||||
|
||||
/// Культурные ветви знака: явная редакция (cultures) приоритетна,
|
||||
/// иначе — автоматическое разложение толкования по традициям.
|
||||
Map<String, String> get resolvedCultures {
|
||||
if (cultures.isNotEmpty) return cultures;
|
||||
return extractCulturalBranches('$oracle\n\n$shadow\n\n$cleanDescription');
|
||||
}
|
||||
|
||||
/// Primary poetic/canonical essence: core if available, otherwise clean description
|
||||
String get displayMeaning {
|
||||
if (core.isNotEmpty) return core;
|
||||
if (cleanDescription.isNotEmpty) return cleanDescription;
|
||||
return description;
|
||||
}
|
||||
|
||||
String get formattedSessionNumber => sessionNumber.toString().padLeft(3, '0');
|
||||
String get formattedId => formattedSessionNumber;
|
||||
|
||||
@@ -49,21 +289,334 @@ class WordItem {
|
||||
'frequency': frequency,
|
||||
'category': category,
|
||||
'description': description,
|
||||
'emoji': emoji,
|
||||
'family': family,
|
||||
'operator': operator,
|
||||
'valence': valence,
|
||||
'jurisdictions': jurisdictions,
|
||||
'lookup': lookup,
|
||||
'hasCanon': hasCanon,
|
||||
'core': core,
|
||||
'oracle': oracle,
|
||||
'layers': layers.map((l) => l.toMap()).toList(),
|
||||
'shadow': shadow,
|
||||
'asks': asks,
|
||||
'step': step,
|
||||
'binds': binds,
|
||||
'sources': sources.map((s) => s.toMap()).toList(),
|
||||
'grammar': grammar?.toMap(),
|
||||
'cultures': cultures,
|
||||
'languages': languages,
|
||||
};
|
||||
}
|
||||
|
||||
factory WordItem.fromMap(Map<String, dynamic> map) {
|
||||
final rawLayers = map['layers'] as List<dynamic>? ?? [];
|
||||
final parsedLayers = rawLayers
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map((m) => SymbolLayer.fromMap(m))
|
||||
.toList();
|
||||
|
||||
final rawSources = map['sources'] as List<dynamic>? ?? [];
|
||||
final parsedSources = rawSources
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map((m) => SymbolSource.fromMap(m))
|
||||
.toList();
|
||||
|
||||
final rawJurisdictions = (map['jurisdictions'] as List<dynamic>? ?? [])
|
||||
.map((e) => e.toString())
|
||||
.toList();
|
||||
|
||||
final rawBinds = (map['binds'] as List<dynamic>? ?? [])
|
||||
.map((e) => e.toString())
|
||||
.toList();
|
||||
|
||||
final rawGrammar = map['grammar'] as Map<String, dynamic>?;
|
||||
|
||||
final rawCultures = map['cultures'] as Map<String, dynamic>?;
|
||||
final parsedCultures = rawCultures != null
|
||||
? rawCultures.map((k, v) => MapEntry(k.toString(), v.toString()))
|
||||
: <String, String>{};
|
||||
|
||||
final rawLanguages = map['languages'] as Map<String, dynamic>?;
|
||||
final parsedLanguages = rawLanguages != null
|
||||
? rawLanguages.map((k, v) => MapEntry(k.toString(), v.toString()))
|
||||
: <String, String>{};
|
||||
|
||||
return WordItem(
|
||||
id: map['id'] as int,
|
||||
sessionNumber: map['sessionNumber'] as int? ?? (map['id'] as int),
|
||||
word: map['word'] as String,
|
||||
partOfSpeech: map['partOfSpeech'] as String,
|
||||
frequency: (map['frequency'] as num).toDouble(),
|
||||
partOfSpeech: map['partOfSpeech'] as String? ?? '',
|
||||
frequency: (map['frequency'] as num?)?.toDouble() ?? 50.0,
|
||||
category: map['category'] as String? ?? '',
|
||||
description: map['description'] as String? ?? '',
|
||||
emoji: map['emoji'] as String? ?? '',
|
||||
family: map['family'] as String? ?? '',
|
||||
operator: map['operator'] as String? ?? 'substance',
|
||||
valence: map['valence'] as String? ?? 'liminal',
|
||||
jurisdictions: rawJurisdictions,
|
||||
lookup: map['lookup'] as String? ?? 'C',
|
||||
hasCanon: map['hasCanon'] as bool? ?? false,
|
||||
core: map['core'] as String? ?? '',
|
||||
oracle: map['oracle'] as String? ?? '',
|
||||
layers: parsedLayers,
|
||||
shadow: map['shadow'] as String? ?? '',
|
||||
asks: map['asks'] as String? ?? '',
|
||||
step: map['step'] as String? ?? '',
|
||||
binds: rawBinds,
|
||||
sources: parsedSources,
|
||||
grammar: rawGrammar != null ? SymbolGrammar.fromMap(rawGrammar) : null,
|
||||
isUserEdited: map['isUserEdited'] as bool? ?? false,
|
||||
cultures: parsedCultures,
|
||||
languages: parsedLanguages,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => '#$formattedSessionNumber: $word ($partOfSpeech)';
|
||||
String toString() => '#: ()';
|
||||
}
|
||||
|
||||
extension WordItemLocalization on WordItem {
|
||||
String get localizedValence => localizeValence(valence);
|
||||
String get localizedOperator => localizeOperator(operator);
|
||||
String get localizedFamily => localizeFamily(family);
|
||||
|
||||
static String localizeValence(String v) {
|
||||
switch (v.trim().toLowerCase()) {
|
||||
case 'active':
|
||||
return 'Активная';
|
||||
case 'receptive':
|
||||
return 'Восприимчивая';
|
||||
case 'liminal':
|
||||
return 'Лиминальная';
|
||||
case 'stable':
|
||||
return 'Устойчивая';
|
||||
case 'cutting':
|
||||
return 'Отсекающая';
|
||||
case 'binding':
|
||||
return 'Связующая';
|
||||
case 'solar':
|
||||
return 'Солярная';
|
||||
case 'lunar':
|
||||
return 'Лунарная';
|
||||
case 'light':
|
||||
return 'Светлая';
|
||||
case 'dark':
|
||||
return 'Теневая';
|
||||
case 'neutral':
|
||||
return 'Нейтральная';
|
||||
case 'chthonic':
|
||||
return 'Хтоническая';
|
||||
default:
|
||||
final s = v.trim();
|
||||
if (s.isEmpty) return '';
|
||||
return s[0].toUpperCase() + s.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
static String localizeOperator(String op) {
|
||||
switch (op.trim().toLowerCase()) {
|
||||
case 'substance':
|
||||
return 'Субстанция';
|
||||
case 'act':
|
||||
return 'Действие';
|
||||
case 'relation':
|
||||
return 'Связь';
|
||||
case 'shifter':
|
||||
return 'Сдвиг';
|
||||
case 'qualifier':
|
||||
return 'Качество';
|
||||
case 'filter':
|
||||
return 'Фильтр';
|
||||
case 'pronoun':
|
||||
return 'Указатель';
|
||||
case 'number':
|
||||
return 'Число';
|
||||
case 'nexus':
|
||||
return 'Узел';
|
||||
case 'vector':
|
||||
return 'Вектор';
|
||||
case 'catalyst':
|
||||
return 'Катализатор';
|
||||
default:
|
||||
final s = op.trim();
|
||||
if (s.isEmpty) return '';
|
||||
return s[0].toUpperCase() + s.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
static String localizeFamily(String f) {
|
||||
switch (f.trim().toLowerCase()) {
|
||||
case 'totem':
|
||||
return 'Тотем';
|
||||
case 'sacred_symbol':
|
||||
return 'Сакральный символ';
|
||||
case 'sacred_place':
|
||||
return 'Сакральное место';
|
||||
case 'element':
|
||||
return 'Стихия';
|
||||
case 'cosmos':
|
||||
return 'Космос';
|
||||
case 'body':
|
||||
return 'Тело';
|
||||
case 'moral':
|
||||
return 'Этика';
|
||||
case 'quality':
|
||||
return 'Качество';
|
||||
case 'time_calendar':
|
||||
return 'Календарь';
|
||||
case 'time_cycle':
|
||||
return 'Цикл времени';
|
||||
case 'cult_object':
|
||||
return 'Культ';
|
||||
case 'person_archetype':
|
||||
return 'Архетип';
|
||||
case 'social':
|
||||
return 'Социум';
|
||||
case 'speech':
|
||||
return 'Речь';
|
||||
case 'circumstance':
|
||||
return 'Обстоятельство';
|
||||
case 'conjunction':
|
||||
return 'Связка';
|
||||
case 'preposition':
|
||||
return 'Отношение';
|
||||
case 'polarity':
|
||||
return 'Полярность';
|
||||
case 'verb_transform':
|
||||
return 'Трансформация';
|
||||
case 'particle':
|
||||
return 'Частица';
|
||||
case 'determiner':
|
||||
return 'Определитель';
|
||||
case 'adverb_index':
|
||||
return 'Индекс';
|
||||
case 'misc':
|
||||
return 'Разное';
|
||||
default:
|
||||
final s = f.trim();
|
||||
if (s.isEmpty) return '';
|
||||
return s[0].toUpperCase() + s.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
static String localizeSystem(String sys) {
|
||||
switch (sys.trim().toLowerCase()) {
|
||||
case 'tarot':
|
||||
return 'Таро';
|
||||
case 'runes':
|
||||
return 'Руны';
|
||||
case 'lenormand':
|
||||
return 'Ленорман';
|
||||
case 'iching':
|
||||
case 'i ching':
|
||||
return 'И Цзин';
|
||||
case 'astrology':
|
||||
return 'Астрология';
|
||||
case 'alchemy':
|
||||
return 'Алхимия';
|
||||
case 'kabbalah':
|
||||
return 'Каббала';
|
||||
case 'ogham':
|
||||
return 'Огам';
|
||||
case 'cosmology':
|
||||
return 'Космология';
|
||||
case 'slavic':
|
||||
return 'Славянский канон';
|
||||
case 'bestiary':
|
||||
return 'Бестиарий';
|
||||
case 'dream':
|
||||
return 'Сновидения';
|
||||
case 'geomancy':
|
||||
return 'Геомантия';
|
||||
default:
|
||||
final s = sys.trim();
|
||||
if (s.isEmpty) return '';
|
||||
return s[0].toUpperCase() + s.substring(1);
|
||||
}
|
||||
}
|
||||
static String cleanTagDetail(String det) {
|
||||
var s = det.trim();
|
||||
// Remove Latin transliterations like (Cancer / Вода / Луна) -> (Вода · Луна)
|
||||
s = s.replaceAllMapped(RegExp(r'\([A-Za-z]+\s*[/·]\s*([^)]+)\)'), (m) => '(${m.group(1)})');
|
||||
s = s.replaceAll(' / ', ' · ');
|
||||
// Geomancy 12 Puer (Юноша) -> 12 Юноша
|
||||
s = s.replaceAllMapped(RegExp(r'(\d+\s+)[A-Za-z\s_]+\(([А-Яа-яЁё\s·-]+)\)'), (m) => '${m.group(1)}${m.group(2)}');
|
||||
// Alchemy Огонь (Ignis) -> Огонь
|
||||
if (!RegExp(r'[ᚠ-ᛪ]').hasMatch(s)) {
|
||||
s = s.replaceAllMapped(RegExp(r'([А-Яа-яЁё\s]+)\s*\([A-Za-z\s_]+\)'), (m) => m.group(1)!);
|
||||
}
|
||||
// Runes: (Kenaz / ᚲ) -> (ᚲ)
|
||||
s = s.replaceAllMapped(RegExp(r'\([A-Za-z]+\s*[/·]\s*([ᚠ-ᛪ])\)'), (m) => '(${m.group(1)})');
|
||||
// Clean leftover English in parens
|
||||
s = s.replaceAll(RegExp(r'\([A-Za-z\s_]+\)'), '');
|
||||
return s.trim();
|
||||
}
|
||||
|
||||
static String localizeSourceRef(String system, String ref) {
|
||||
final r = ref.trim().toLowerCase();
|
||||
const map = <String, String>{
|
||||
// Runes
|
||||
'fehu': 'Феху (ᚠ)', 'uruz': 'Уруз (ᚢ)', 'thurisaz': 'Турисаз (ᚦ)', 'ansuz': 'Ансуз (ᚨ)',
|
||||
'raidho': 'Райдо (ᚱ)', 'kenaz': 'Кеназ (ᚲ)', 'gebo': 'Гебо (ᚷ)', 'wunjo': 'Вуньо (ᚹ)',
|
||||
'hagalaz': 'Хагалаз (ᚺ)', 'nauthiz': 'Наутиз (ᚾ)', 'isa': 'Иса (ᛁ)', 'jera': 'Йера (ᛃ)',
|
||||
'eihwaz': 'Эйваз (ᛇ)', 'perthro': 'Перт (ᛈ)', 'algiz': 'Альгиз (ᛉ)', 'sowilo': 'Совило (ᛊ)',
|
||||
'tiwaz': 'Тейваз (ᛏ)', 'berkano': 'Беркана (ᛒ)', 'ehwaz': 'Эваз (ᛖ)', 'mannaz': 'Манназ (ᛗ)',
|
||||
'laguz': 'Лагуз (ᛚ)', 'ingwaz': 'Ингваз (ᛜ)', 'dagaz': 'Дагаз (ᛞ)', 'othala': 'Отала (ᛟ)',
|
||||
// Tarot
|
||||
'wands': 'Жезлы (Огонь)', 'pentacles': 'Пентакли (Земля)', 'cups': 'Кубки (Вода)', 'swords': 'Мечи (Воздух)',
|
||||
'fool': 'Шут (0)', 'magician': 'Маг (I)', 'priestess': 'Жрица (II)', 'empress': 'Императрица (III)',
|
||||
'emperor': 'Император (IV)', 'hierophant': 'Иерофант (V)', 'lovers': 'Влюблённые (VI)', 'chariot': 'Колесница (VII)',
|
||||
'strength': 'Сила (VIII)', 'hermit': 'Отшельник (IX)', 'wheel': 'Колесо Фортуны (X)', 'justice': 'Справедливость (XI)',
|
||||
'hanged': 'Повешенный (XII)', 'death': 'Смерть (XIII)', 'temperance': 'Умеренность (XIV)', 'devil': 'Дьявол (XV)',
|
||||
'tower': 'Башня (XVI)', 'star': 'Звезда (XVII)', 'moon': 'Луна', 'sun': 'Солнце',
|
||||
'judgement': 'Суд (XX)', 'world': 'Мир (XXI)',
|
||||
// I Ching
|
||||
'li': 'Ли ☲ (Огонь)', 'kan': 'Кань ☵ (Вода)', 'xun': 'Сюнь ☴ (Ветер)', 'kun': 'Кунь ☷ (Земля)',
|
||||
'qian': 'Цянь ☰ (Небо)', 'zhen': 'Чжэнь ☳ (Гром)', 'gen': 'Гэнь ☶ (Гора)', 'dui': 'Дуй ☱ (Водоём)',
|
||||
'kan_repeat': 'Кань ䷜ (Повторная опасность)', 'pi': 'Пи ䷋ (Упадок)', 'tai': 'Тай ䷊ (Расцвет)',
|
||||
'gu': 'Гу ䷑ (Исправление)', 'fu': 'Фу ䷗ (Возврат)', 'meng': 'Мэн ䷃ (Юность)', 'ge': 'Гэ ䷰ (Смена)',
|
||||
'wei_ji': 'Вэй-цзи ䷿ (Ещё не конец)',
|
||||
// Alchemy
|
||||
'ignis': 'Огонь', 'aqua': 'Вода', 'aer': 'Воздух', 'terra': 'Земля',
|
||||
'sulfur': 'Сера (Душа)', 'mercury': 'Ртуть (Дух)', 'sal': 'Соль (Тело)',
|
||||
'albedo': 'Альбедо (Белизна)', 'nigredo': 'Нигредо (Чернота)', 'rubedo': 'Рубедо (Краснота)',
|
||||
'ash': 'Пепел', 'luna': 'Луна (Серебро)', 'egg': 'Философское Яйцо', 'vessel': 'Сосуд Гермеса', 'forge': 'Горн',
|
||||
// Astrology
|
||||
'comet': 'Комета', 'eclipse': 'Затмение', 'dawn': 'Рассвет', 'dusk': 'Закат',
|
||||
'zenith': 'Зенит', 'nadir': 'Надир', 'constellation': 'Созвездие', 'planet': 'Планета', 'meteor': 'Метеор',
|
||||
'equinox': 'Равноденствие', 'orbit': 'Орбита', 'libra': 'Весы', 'aries': 'Овен', 'taurus': 'Телец',
|
||||
'gemini': 'Близнецы', 'cancer': 'Рак', 'leo': 'Лев', 'virgo': 'Дева', 'scorpio': 'Скорпион',
|
||||
'sagittarius': 'Стрелец', 'capricorn': 'Козерог', 'aquarius': 'Водолей', 'pisces': 'Рыбы',
|
||||
// Bestiary
|
||||
'dog': 'Собака (Страж)', 'snake': 'Змея (Мудрость)', 'eagle': 'Орёл (Высота)', 'wolf': 'Волк (Чутьё)',
|
||||
'raven': 'Ворон (Память)', 'lion': 'Лев (Царственность)', 'owl': 'Сова (Ночное зрение)',
|
||||
'serpent_feather': 'Пернатый Змей', 'dragon': 'Дракон', 'phoenix': 'Феникс', 'bear': 'Медведь (Сила)',
|
||||
'fox': 'Лиса (Хитрость)', 'stag': 'Олень (Благородство)', 'horse': 'Конь (Порыв)', 'spider': 'Паук (Нить судьбы)',
|
||||
// Virtues & Archetypes
|
||||
'courage': 'Мужество', 'charity': 'Милосердие', 'karma': 'Карма / Воздаяние', 'guilt': 'Вина',
|
||||
'shame': 'Стыд', 'pride': 'Гордыня', 'humility': 'Смирение', 'envy': 'Зависть', 'vow': 'Обет',
|
||||
'greed': 'Алчность', 'gluttony': 'Чревоугодие', 'sloth': 'Уныние', 'wrath': 'Гнев', 'lust': 'Страсть',
|
||||
'donor': 'Даритель', 'dispatcher': 'Отправитель', 'shadow': 'Тень', 'hero': 'Герой', 'self': 'Самость',
|
||||
'helper': 'Помощник', 'witch': 'Ведунья', 'princess': 'Царевна', 'exile': 'Изгнанник',
|
||||
'false_hero': 'Ложный герой', 'judge': 'Судия', 'trickster': 'Трикстер',
|
||||
// Slavic
|
||||
'mesyats': 'Месяц ясный', 'oak': 'Священный Дуб', 'willow': 'Плакучая Ива', 'birch': 'Берёза',
|
||||
'ivy_field': 'Чисто поле', 'crossroads': 'Перепутье', 'threshold': 'Порог', 'well': 'Студёный колодец', 'hearth': 'Родной очаг',
|
||||
// Ogham
|
||||
'dair': 'Дуб (Даир / ᚇ)', 'sail': 'Ива (Салье / ᚄ)', 'beith': 'Берёза (Бэйт / ᚁ)', 'gort': 'Плющ (Горт / ᚌ)',
|
||||
// Symbols & Dreams
|
||||
'fire': 'Огонь', 'water': 'Вода', 'air': 'Воздух', 'earth': 'Земля',
|
||||
'key': 'Ключ от врат', 'spark': 'Живая искра', 'path': 'Тропа / Путь', 'book': 'Книга судеб',
|
||||
'blood': 'Кровь / Род', 'heart': 'Сердце',
|
||||
'fire_d': 'Сон об огне', 'water_d': 'Сон о глубине', 'death_d': 'Сон о переходе', 'key_d': 'Сон о тайне',
|
||||
'path_d': 'Сон о странствии', 'child_d': 'Сон о дитяти', 'mirror_d': 'Сон о зеркале', 'wolf_d': 'Сон о звере',
|
||||
'dream_fire': 'Сон об огне',
|
||||
};
|
||||
if (map.containsKey(r)) return map[r]!;
|
||||
final s = ref.trim().replaceAll('_', ' ');
|
||||
if (s.isEmpty) return '';
|
||||
return s[0].toUpperCase() + s.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user