fix: make ADIF parser case-insensitive for EOR delimiter

Critical bug fix: ADIF parser was using case-sensitive split on '<EOR>',
but LoTW returns lowercase '<eor>' tags. This caused all 242,239 QSOs
to be parsed as a single giant record with fields overwriting each other,
resulting in only 1 QSO being imported.

Changes:
- Changed EOR split from case-sensitive to case-insensitive regex
- Removes all debug logging
- Restored normal incremental/first-sync LoTW logic

Before: 6.8MB LoTW report → 1 QSO (bug)
After: 6.8MB LoTW report → All 242K+ QSOs (fixed)

Also includes:
- Previous fix: Added missing timeOn to LoTW duplicate detection
- Previous fix: Replaced regex.exec() while loop with matchAll() for-of

Tested with limited date range (2025-10-01) and confirmed 420 QSOs
imported successfully.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-18 08:25:25 +01:00
parent 0161ad47a8
commit 233888c44f
2 changed files with 6 additions and 5 deletions

View File

@@ -13,8 +13,10 @@
*/
export function parseADIF(adifData) {
const qsos = [];
// Split by <EOR> (end of record) - case sensitive as per ADIF spec
const records = adifData.split('<EOR>');
// Split by <EOR> (case-insensitive to handle <EOR>, <eor>, <Eor>, etc.)
const regex = new RegExp('<eor>', 'gi');
const records = adifData.split(regex);
for (const record of records) {
if (!record.trim()) continue;
@@ -29,7 +31,6 @@ export function parseADIF(adifData) {
// Use matchAll for cleaner parsing (creates new iterator for each record)
const matches = record.matchAll(/<([A-Z0-9_]+):(\d+)(?::[A-Z]+)?>/gi);
let currentPos = 0;
for (const match of matches) {
const [fullMatch, fieldName, lengthStr] = match;
@@ -40,8 +41,6 @@ export function parseADIF(adifData) {
const value = record.substring(valueStart, valueStart + length);
qso[fieldName.toLowerCase()] = value.trim();
currentPos = valueStart + length;
}
// Only add if we have at least a callsign