feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart' show rootBundle;
|
||||
|
||||
import '../models/lenormand_pairs.dart';
|
||||
|
||||
class LenormandPairsRepository {
|
||||
static final LenormandPairsRepository _instance =
|
||||
LenormandPairsRepository._internal();
|
||||
factory LenormandPairsRepository() => _instance;
|
||||
LenormandPairsRepository._internal();
|
||||
|
||||
final Map<int, LenormandCardEntry> _byN = {};
|
||||
List<LenormandTriad> _triads = const [];
|
||||
List<LenormandExtra> _extras = const [];
|
||||
bool _loaded = false;
|
||||
|
||||
bool get isLoaded => _loaded;
|
||||
List<LenormandCardEntry> get cards =>
|
||||
List.unmodifiable(_byN.values.toList()..sort((a, b) => a.n.compareTo(b.n)));
|
||||
List<LenormandTriad> get triads => List.unmodifiable(_triads);
|
||||
List<LenormandExtra> get extras => List.unmodifiable(_extras);
|
||||
|
||||
LenormandCardEntry? byNumber(int n) => _byN[n];
|
||||
|
||||
LenormandCardEntry? byStationId(String id) {
|
||||
if (id.startsWith('card_')) {
|
||||
final n = int.tryParse(id.substring(5));
|
||||
if (n != null) return _byN[n];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
if (_loaded && _byN.isNotEmpty) return;
|
||||
Map<String, dynamic>? decoded;
|
||||
final cwd = Directory.current.path;
|
||||
final candidates = <String>{
|
||||
'assets/data/lenormand_pairs.json',
|
||||
'../assets/data/lenormand_pairs.json',
|
||||
'$cwd/assets/data/lenormand_pairs.json',
|
||||
'$cwd/../assets/data/lenormand_pairs.json',
|
||||
};
|
||||
for (final path in candidates) {
|
||||
try {
|
||||
final file = File(path);
|
||||
if (file.existsSync()) {
|
||||
decoded = json.decode(file.readAsStringSync()) as Map<String, dynamic>;
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('lenormand_pairs.json skip $path: $e');
|
||||
}
|
||||
}
|
||||
if (decoded == null) {
|
||||
try {
|
||||
final jsonStr = await rootBundle.loadString('assets/data/lenormand_pairs.json');
|
||||
decoded = json.decode(jsonStr) as Map<String, dynamic>;
|
||||
} catch (e) {
|
||||
debugPrint('Could not load lenormand_pairs.json: $e');
|
||||
}
|
||||
}
|
||||
if (decoded == null) {
|
||||
_loaded = true;
|
||||
return;
|
||||
}
|
||||
_byN.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;
|
||||
}
|
||||
_triads = (decoded['triads'] as List? ?? const [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map(LenormandTriad.fromMap)
|
||||
.toList();
|
||||
_extras = (decoded['extras'] as List? ?? const [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map(LenormandExtra.fromMap)
|
||||
.toList();
|
||||
_loaded = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user