feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets

This commit is contained in:
2026-10-09 15:26:58 +05:00
parent 7f91366201
commit 0b12e4583b
244 changed files with 611461 additions and 1617 deletions
+68
View File
@@ -0,0 +1,68 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart' show rootBundle;
import '../models/lenormand_pairs.dart';
/// Same shape as Lenormand pairs JSON: n, name, meaning, pairs[].
class TarotMajorsRepository {
static final TarotMajorsRepository _instance = TarotMajorsRepository._internal();
factory TarotMajorsRepository() => _instance;
TarotMajorsRepository._internal();
final Map<int, LenormandCardEntry> _byN = {};
final Map<String, LenormandCardEntry> _byId = {};
bool _loaded = false;
bool get isLoaded => _loaded;
List<LenormandCardEntry> get cards =>
List.unmodifiable(_byN.values.toList()..sort((a, b) => a.n.compareTo(b.n)));
LenormandCardEntry? byNumber(int n) => _byN[n];
LenormandCardEntry? byCanonId(String id) => _byId[id];
Future<void> init() async {
if (_loaded && _byN.isNotEmpty) return;
Map<String, dynamic>? decoded;
final cwd = Directory.current.path;
for (final path in {
'assets/data/tarot_majors.json',
'../assets/data/tarot_majors.json',
'$cwd/assets/data/tarot_majors.json',
'$cwd/../assets/data/tarot_majors.json',
}) {
try {
final file = File(path);
if (file.existsSync()) {
decoded = json.decode(file.readAsStringSync()) as Map<String, dynamic>;
break;
}
} catch (e) {
debugPrint('tarot_majors.json skip $path: $e');
}
}
if (decoded == null) {
try {
final jsonStr = await rootBundle.loadString('assets/data/tarot_majors.json');
decoded = json.decode(jsonStr) as Map<String, dynamic>;
} catch (e) {
debugPrint('Could not load tarot_majors.json: $e');
}
}
if (decoded == null) {
_loaded = true;
return;
}
_byN.clear();
_byId.clear();
for (final raw in (decoded['cards'] as List? ?? const [])) {
if (raw is! Map<String, dynamic>) continue;
final card = LenormandCardEntry.fromMap(raw);
_byN[card.n] = card;
_byId[card.id] = card;
}
_loaded = true;
}
}