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
+157
View File
@@ -0,0 +1,157 @@
import 'dart:convert';
/// Represents the daily record for a specific calendar date in the Word of the Day practice.
/// Supports both Single Word Mode (1 resonant archetype) and Triptych Mode (Morning, Day, Evening).
class WordOfDayRecord {
final String dateKey; // 'yyyy-MM-dd'
final int wordId; // base id for Single Word Mode
final bool isRevealed; // whether Single Word is revealed
final bool isStepCompleted; // whether Single Word step is checked off
final String diaryNote; // user reflection on daily synchronicity
final DateTime? revealedAt;
final DateTime? completedAt;
// Triptych fields (3 words: Morning, Day, Evening)
final bool isTriptychMode;
final int morningWordId;
final int dayWordId;
final int eveningWordId;
final bool isMorningRevealed;
final bool isDayRevealed;
final bool isEveningRevealed;
final bool isDayStepCompleted;
final DateTime? morningRevealedAt;
final DateTime? dayRevealedAt;
final DateTime? eveningRevealedAt;
const WordOfDayRecord({
required this.dateKey,
required this.wordId,
this.isRevealed = false,
this.isStepCompleted = false,
this.diaryNote = '',
this.revealedAt,
this.completedAt,
this.isTriptychMode = false,
this.morningWordId = 0,
this.dayWordId = 0,
this.eveningWordId = 0,
this.isMorningRevealed = false,
this.isDayRevealed = false,
this.isEveningRevealed = false,
this.isDayStepCompleted = false,
this.morningRevealedAt,
this.dayRevealedAt,
this.eveningRevealedAt,
});
bool get isAnyRevealed =>
isRevealed || isMorningRevealed || isDayRevealed || isEveningRevealed;
bool get areAllTriptychRevealed =>
isMorningRevealed && isDayRevealed && isEveningRevealed;
bool get isAnyStepCompleted => isStepCompleted || isDayStepCompleted;
WordOfDayRecord copyWith({
String? dateKey,
int? wordId,
bool? isRevealed,
bool? isStepCompleted,
String? diaryNote,
DateTime? revealedAt,
DateTime? completedAt,
bool? isTriptychMode,
int? morningWordId,
int? dayWordId,
int? eveningWordId,
bool? isMorningRevealed,
bool? isDayRevealed,
bool? isEveningRevealed,
bool? isDayStepCompleted,
DateTime? morningRevealedAt,
DateTime? dayRevealedAt,
DateTime? eveningRevealedAt,
}) {
return WordOfDayRecord(
dateKey: dateKey ?? this.dateKey,
wordId: wordId ?? this.wordId,
isRevealed: isRevealed ?? this.isRevealed,
isStepCompleted: isStepCompleted ?? this.isStepCompleted,
diaryNote: diaryNote ?? this.diaryNote,
revealedAt: revealedAt ?? this.revealedAt,
completedAt: completedAt ?? this.completedAt,
isTriptychMode: isTriptychMode ?? this.isTriptychMode,
morningWordId: morningWordId ?? this.morningWordId,
dayWordId: dayWordId ?? this.dayWordId,
eveningWordId: eveningWordId ?? this.eveningWordId,
isMorningRevealed: isMorningRevealed ?? this.isMorningRevealed,
isDayRevealed: isDayRevealed ?? this.isDayRevealed,
isEveningRevealed: isEveningRevealed ?? this.isEveningRevealed,
isDayStepCompleted: isDayStepCompleted ?? this.isDayStepCompleted,
morningRevealedAt: morningRevealedAt ?? this.morningRevealedAt,
dayRevealedAt: dayRevealedAt ?? this.dayRevealedAt,
eveningRevealedAt: eveningRevealedAt ?? this.eveningRevealedAt,
);
}
Map<String, dynamic> toMap() => {
'dateKey': dateKey,
'wordId': wordId,
'isRevealed': isRevealed,
'isStepCompleted': isStepCompleted,
'diaryNote': diaryNote,
if (revealedAt != null) 'revealedAt': revealedAt!.toIso8601String(),
if (completedAt != null) 'completedAt': completedAt!.toIso8601String(),
'isTriptychMode': isTriptychMode,
'morningWordId': morningWordId,
'dayWordId': dayWordId,
'eveningWordId': eveningWordId,
'isMorningRevealed': isMorningRevealed,
'isDayRevealed': isDayRevealed,
'isEveningRevealed': isEveningRevealed,
'isDayStepCompleted': isDayStepCompleted,
if (morningRevealedAt != null)
'morningRevealedAt': morningRevealedAt!.toIso8601String(),
if (dayRevealedAt != null)
'dayRevealedAt': dayRevealedAt!.toIso8601String(),
if (eveningRevealedAt != null)
'eveningRevealedAt': eveningRevealedAt!.toIso8601String(),
};
factory WordOfDayRecord.fromMap(Map<String, dynamic> map) => WordOfDayRecord(
dateKey: map['dateKey'] as String? ?? '',
wordId: (map['wordId'] as num?)?.toInt() ?? 0,
isRevealed: map['isRevealed'] as bool? ?? false,
isStepCompleted: map['isStepCompleted'] as bool? ?? false,
diaryNote: map['diaryNote'] as String? ?? '',
revealedAt: map['revealedAt'] != null
? DateTime.tryParse(map['revealedAt'] as String)
: null,
completedAt: map['completedAt'] != null
? DateTime.tryParse(map['completedAt'] as String)
: null,
isTriptychMode: map['isTriptychMode'] as bool? ?? false,
morningWordId: (map['morningWordId'] as num?)?.toInt() ?? 0,
dayWordId: (map['dayWordId'] as num?)?.toInt() ?? 0,
eveningWordId: (map['eveningWordId'] as num?)?.toInt() ?? 0,
isMorningRevealed: map['isMorningRevealed'] as bool? ?? false,
isDayRevealed: map['isDayRevealed'] as bool? ?? false,
isEveningRevealed: map['isEveningRevealed'] as bool? ?? false,
isDayStepCompleted: map['isDayStepCompleted'] as bool? ?? false,
morningRevealedAt: map['morningRevealedAt'] != null
? DateTime.tryParse(map['morningRevealedAt'] as String)
: null,
dayRevealedAt: map['dayRevealedAt'] != null
? DateTime.tryParse(map['dayRevealedAt'] as String)
: null,
eveningRevealedAt: map['eveningRevealedAt'] != null
? DateTime.tryParse(map['eveningRevealedAt'] as String)
: null,
);
String toJson() => json.encode(toMap());
factory WordOfDayRecord.fromJson(String source) =>
WordOfDayRecord.fromMap(json.decode(source) as Map<String, dynamic>);
}