Tools for amateur radio log processing and format conversion.
Slovenska različica / Slovenian version ↓
| Tool | Type | Purpose |
|---|---|---|
edi2adif.html |
Browser app | Convert REG1TEST EDI v1 contest logs to ADIF and CSV formats |
edi-crosscheck.html |
Browser app | Crosscheck a new EDI log against historical logs + optional OEVSV IARU R1 baseline — flags locator mismatches and callsign typos |
vhf-logger/vhf-logger.html |
Browser app | Real-time VHF/UHF/SHF contest logger with live crosscheck hints, QRB/bearing display, and REG1TEST EDI export |
adif-merge.html |
Browser app | Merge multiple ADIF log files — deduplication, filter by band/mode/source, inline editing, export to ADIF and CSV |
adif-stats.html |
Browser app | Analyse an ADIF log — statistics by band/mode/continent/country/time, DXCC per band, activity heatmap, band×hour propagation matrix, QRB distribution, HTML export |
adif2cab.html |
Browser app | Convert an ADIF log to Cabrillo v3 contest format; CQ WW SSB/CW/RTTY, IARU HF, IARU VHF, CQ WPX SSB/CW, ARRL DX, Generic |
edi-validator.html |
Browser app | Standalone EDI file validator: spec compliance, ZRS mandatory fields, QRB deviation check |
adif-qrz-filter.js |
Node.js CLI | Filter an ADIF log to keep only QSOs with BURO-accepting stations |
build-baseline.js |
Node.js CLI | Build crosscheck-baseline.json from OEVSV IARU R1 contest CSV exports for use with edi-crosscheck.html and vhf-logger/vhf-logger.html |
edi2adif.html)Converts REG1TEST EDI v1 contest logs to ADIF and other formats. Open the file in any modern browser — no installation required.
.edi files simultaneouslyEDI PBand value |
ADIF band |
|---|---|
| 50 MHz, 6m | 6m |
| 144 / 145 MHz, 2m | 2m |
| 430 / 432 MHz, 70 cm | 70cm |
| 1.2 / 1.3 GHz, 1296 MHz, 23 cm | 23cm |
| 2.3 GHz, 2320 MHz, 13 cm | 13cm |
| 3.4 GHz, 3400 MHz, 9 cm | 9cm |
| 5.7 GHz, 5760 MHz, 6 cm | 6cm |
| 10 GHz, 10368 MHz, 3 cm | 3cm |
| 24 GHz, 24048 MHz, 1.25 cm | 1.25cm |
| 47 GHz, 6 mm | 6mm |
Supported modes: SSB · CW · FM · AM · RTTY · SSTV · ATV
edi2adif.html (single file, ~42 KB).edi files onto the drop zone, or click Choose filesNo internet connection required after the page loads (except for Google Fonts). All processing happens in your browser — no files or QSO data are uploaded anywhere.
edi-crosscheck.html)Browser tool that compares a new EDI contest log against a statistical database built from historical EDI logs. Helps catch locator mismatches and callsign typos before submitting the log. Open the file in any modern browser — no installation required.
crosscheck-baseline.json is present next to the HTML and the page is served over HTTP, a prebuilt baseline of 3 000+ IARU R1 contest stations (call → locator, derived from public OEVSV CSV exports) is loaded automatically on startup. This gives a useful crosscheck even without any of your own EDI history.Note on
file://opening: modern browsers blockfetch()fromfile://URLs for security. If you double-click the HTML, the baseline silently fails to load and the tool works exactly like v1.3 (your EDI history only). To use the baseline, serve over HTTP (python3 -m http.server) — see How to Use below.
| Badge | Colour | Condition |
|---|---|---|
LOC! |
Red | Locator differs from historical mode; mode confidence ≥ threshold and new locator was never seen before |
LOC? |
Amber | Locator differs from historical mode; lower confidence or new locator appeared before (operator moved) |
LOC? |
Amber | QSO has no locator but the callsign exists in history — suggests the historical mode locator |
CALL? |
Amber | Callsign not in history; similar callsign found globally (Levenshtein distance 1–2) |
LOC-CALL? |
Blue | Callsign not in history; similar callsign found from the same locator (composite heuristic) |
? |
Grey | Callsign not in history; no similar callsign found |
✓ |
Green | Callsign in history, locator matches historical mode |
Portable and mobile suffixes (/P, /M, /MM, etc.) are stripped before lookup — S59DGO/P is matched against S59DGO history. Italian regional suffixes (/IV3, /I2, etc.) and numerical district suffixes (/1, /2) are also stripped. Prefix-slash callsigns (OE/S59DGO) are kept unchanged.
The locator check requires at least 3 historical appearances by default, but this is configurable via the Min. appearances slider (1–10). The Confidence slider (10–100%) controls the high vs medium severity cutoff. Both sliders can be adjusted after loading a new log — click Re-run to apply the new thresholds without reloading the file.
crosscheck-baseline.json is present. Each baseline entry weighs 3× a single EDI QSO (authoritative own-locator declarations from robotically-validated contest logs). Display chips still show raw counts to remain intuitive.IK3GOY → IW3GOA when both are from JN65DM)edi-crosscheck.html (single file, ~50 KB). Optionally also download crosscheck-baseline.json (~220 KB) for the OEVSV baseline.fetch() from file://):
cd /path/to/HamLogTools
python3 -m http.server 8080
# then open: http://localhost:8080/edi-crosscheck.html
For double-click file:// use, the tool still works fully — just without the baseline.
No internet connection required. All processing is local in your browser.
vhf-logger/vhf-logger.html)Real-time contest logger for VHF/UHF/SHF bands. Stores sessions in localStorage — no server required.
Open the file in any modern browser (for baseline support, serve over HTTP).
➜ Open vhf-logger/vhf-logger.html
crosscheck-baseline.json (same database as edi-crosscheck.html); baseline loaded automatically on startup over HTTPbaseCall() normalization so S59DGO/P is correctly matched against S59DGO; per-band, excludes the QSO currently being editedlocalStoragelocalStorage[REG1TEST;1] header, SPowe/SAnte/STXEq/SRXEq/SAntH equipment fields, PSect category, full C* score summary block (CQSOs, CQSOP, CWWLs, CWWLB, CExcs, CExcB, CDXCs, CDXCB, CToSc, CODXC), and correct 15-field QSO records (dupe flag at col 14 per spec)localStorage persistence100dvh layout avoids iOS Safari toolbar overlap; touch targets ≥ 32 × 32 pxvhf-logger/vhf-logger.html (~60 KB). The baseline vhf-logger/crosscheck-baseline.json is included in the same subfolder and is loaded automatically.cd /path/to/HamLogTools
python3 -m http.server 8080
# then open: http://localhost:8080/vhf-logger/vhf-logger.html
Without the baseline the logger still works fully for dupe detection, EDI export, and QRB calculation.
No internet connection required after the page loads. All data stays in your browser’s localStorage.
adif-merge.html)Merges multiple ADIF log files into a single deduplicated log. Open the file in any modern browser — no installation required.
.adi / .adif files simultaneously; load additional files at any timeAPP_ADIFMERGE_SRC tag annotates each record with the source filename (stripped on re-merge to prevent duplication)localStorage persistenceadif-merge.html (single file, ~35 KB).adi or .adif files onto the drop zone, or click Choose filesNo internet connection required. All processing happens in your browser — no files or QSO data are uploaded anywhere.
adif-stats.html)Analyses a single ADIF log file and presents statistics in an interactive dashboard. Open the file in any modern browser — no installation required.
.adi / .adif file onto the drop zone, or click to browseDISTANCE field or calculates from GRIDSQUARE + MY_GRIDSQUARE via haversinelocalStorage persistenceadif-stats.html (single file, ~60 KB).adi or .adif file onto the drop zone, or click Choose fileNo internet connection required. All processing happens in your browser — no files or QSO data are uploaded anywhere.
adif2cab.html)Converts an ADIF log file to Cabrillo v3 contest format. Open the file in any modern browser — no installation required.
.adi / .adif file onto the drop zone, or click to browsePH (SSB/AM), CW, FM (separate category), RY (RTTY), DG (all other digital)FREQ field (MHz → kHz); falls back to band-centre kHz if absentCQZONE), IARU HF → ITU zone / HQ (ITUZ), IARU VHF → Maidenhead locator (GRIDSQUARE, uppercased), CQ WPX → serial number (STX/SRX_STRING), ARRL DX → state/province (STATE), Generic → exchange string (SRX_STRING / SRX)localStorage persistenceadif2cab.html (single file).adi or .adif file onto the drop zone, or click Choose fileNo internet connection required. All processing happens in your browser — no files or QSO data are uploaded anywhere.
edi-validator.html)Validates a REG1TEST EDI v1 log file against the EDI specification and ZRS mandatory field requirements. Open the file in any modern browser — no installation required.
.edi file onto the drop zone, or click to browse[REG1TEST;1] header, [Remarks] section, [QSORecords;N] count declaration, [END;...] footerTCall, TLocator, RAZ, RClub, etc.)TDate format (YYYYMMDD;YYYYMMDD), PWWLo Maidenhead format and length, PBand known valuePSect, PClub, RName, RHBBS, or SPowe are emptyYYMMDD, calendar day validity (leap year aware), time HHMM, mode code 0–9 (0 = “none of below”), RST format per mode (SSB/AM/FM → 2 digits; CW/RTTY → 3 digits), dupe flag (D or empty)TDate header rangePWWLo to QSO locator; warns if deviation exceeds 10%error (spec violation), warn (ZRS requirement or deviation), or info (recommendation)localStorage persistenceedi-validator.html (single file).edi file onto the drop zone, or click Choose fileNo internet connection required. All processing happens in your browser — no files are uploaded anywhere.
build-baseline.js)Node.js CLI script that builds crosscheck-baseline.json from a directory of OEVSV IARU R1 contest CSV exports. Used to occasionally refresh the prebuilt baseline that edi-crosscheck.html loads on startup.
Source: OEVSV IARU R1 contest results database at https://iaru.oevsv.at/v_upld/prg_list.php. Each contest has a CSV export button containing (at minimum) Call and WWL columns. Download multiple contests’ CSVs into one directory, then run the script.
# 1. Create a directory for your CSV downloads:
mkdir iaru_oevsv_csv
# 2. Download CSV exports from OEVSV for the contests you want to include.
# Save them into iaru_oevsv_csv/ (any filenames are fine).
# 3. Build the baseline:
node build-baseline.js
# Output: ./crosscheck-baseline.json
node build-baseline.js # defaults
node build-baseline.js --in ./iaru_oevsv_csv # custom input dir
node build-baseline.js --out ./crosscheck-baseline.json
node build-baseline.js --min-appearances 5 # stricter quality filter
node build-baseline.js --min-appearances 1 # keep everything (no filter)
node build-baseline.js --pretty # indented JSON for inspection
node build-baseline.js --verbose # per-file row stats
| Option | Default | Description |
|---|---|---|
--in DIR |
./iaru_oevsv_csv |
Directory containing CSV files |
--out FILE |
./crosscheck-baseline.json |
Output JSON path |
--min-appearances N |
3 |
Minimum total contest entries to include a callsign |
--pretty |
off | Pretty-print JSON output |
--verbose |
off | Per-file processing stats |
*.csv files in the input directory (encoding auto-detection: UTF-8 → ISO-8859-1 fallback)LL Squares columns)/MM or /AM suffix is dropped (always unpredictable)baseCall() (same logic as the HTML tool), band via BAND_MAP, locator to first-4-upper + last-2-lower--min-appearancesv = build date, src, n.calls, n.entries, n.files, band index, calls dict)The baseline ages because operators may move QTH or new operators emerge. Recommended cadence: rebuild every 3–6 months, or after major IARU R1 contests (IARU R1 VHF, UHF/SHF, Marconi Memorial). Each rebuild:
# 1. Download fresh CSVs into iaru_oevsv_csv/ (add new contests, optionally remove old ones)
# 2. Rebuild:
node build-baseline.js
# 3. The script writes crosscheck-baseline.json and mirrors it to vhf-logger/crosscheck-baseline.json.
# Both HTML tools pick up the new file automatically on next page load.
Compact JSON, ~220 KB for a typical IARU R1 dataset (3 000+ callsigns, 16 bands):
{
"v": "2026-05-13",
"src": "iaru.oevsv.at",
"minAppearances": 3,
"n": { "calls": 3240, "entries": 10564, "files": 35 },
"b": ["6m", "4m", "2m", "70cm", "23cm", ...],
"c": {
"DK0NA": { "2": [["JO50ti", 16]], "3": [["JO50ti", 16]], ... },
"S59P": { "2": [["JN86ao", 15]], ... },
...
}
}
Each call entry is { bandIndex: [[locator, count, portableFlag?], ...] }, sorted by count descending. A third element 1 marks the locator as exclusively portable (/P or /M only).
adif-qrz-filter.js)Node.js CLI tool that filters an ADIF log to keep only QSOs with stations that accept
QSL cards via the QSL Bureau. For each unique callsign it queries the QRZ.com XML API;
if the QSO has a QSL_VIA field, the manager’s callsign is checked too.
Results are cached locally for 7 days.
QSL_VIA from ADIF and checks the manager’s bureau status too.qrz-cache.json) avoids re-querying the same callsigns--include-unknown to keep)# Login with username/password
node adif-qrz-filter.js contest.adi --username=S59ABC --password=secret
# Use an existing session key
node adif-qrz-filter.js contest.adi --key=a1b2c3d4
# Custom output path and delay
node adif-qrz-filter.js contest.adi --key=a1b2c3d4 --output=buro.adi --delay=800
# Keep callsigns not found in QRZ
node adif-qrz-filter.js contest.adi --key=a1b2c3d4 --include-unknown
Options:
| Option | Default | Description |
|---|---|---|
--username=USER |
— | QRZ.com username (requires --password) |
--password=PASS |
— | QRZ.com password |
--key=SESSION |
— | Existing QRZ session key (skip login) |
--output=FILE |
input-buro.adi |
Output ADIF filename |
--delay=MS |
1200 |
Delay between QRZ API calls in milliseconds |
--cache=FILE |
.qrz-cache.json |
Local cache file path |
--include-unknown |
off | Keep QSOs for callsigns not found in QRZ |
Note: Callsign data is sent to QRZ.com during the run. See QRZ.com privacy policy.
Business-logic unit tests run in Node.js (v18+), no extra dependencies:
# EDI → ADIF converter
node --test --test-reporter=spec edi2adif.test.js
# EDI Crosscheck
node --test --test-reporter=spec edi-crosscheck.test.js
# ADIF Merge
node --test --test-reporter=spec adif-merge.test.js
# ADIF QRZ BURO filter
node --test --test-reporter=spec adif-qrz-filter.test.js
# VHF/UHF Contest Logger
node --test --test-reporter=spec vhf-logger/vhf-logger.test.js
# ADIF Statistics
node --test --test-reporter=spec adif-stats.test.js
# ADIF → Cabrillo converter
node --test --test-reporter=spec adif2cab.test.js
# EDI file validator
node --test --test-reporter=spec edi-validator.test.js
| Test file | Tests | Groups |
|---|---|---|
edi2adif.test.js |
122 | 9 (normBand, parseEDI, adifField, csvEsc, modeBadge, i18n, duplicates, CSV export, inline edit) |
edi-crosscheck.test.js |
56 | 8 (baseCall, levenshtein, parseEDI, runCrosscheck locator mismatch ×6, runCrosscheck callsign ×8, missing locator ×4, thresholds ×3, callsign by locator ×4) |
adif-merge.test.js |
112 | 21 (parseADIF, updateKey, recomputeDupes, adifField, htmlEsc, csvEsc, modeBadge, buildFilename, ADIF export, I18N, re-merge safety, and more) |
adif-qrz-filter.test.js |
48 | 4 (parseAdif, extractField, usesQslBuro ×3, cache) |
vhf-logger/vhf-logger.test.js |
191 | 17 (baseCall, normBand, locToLatLon, haversine, calcBearing, levenshtein, isDupe, recalcDupes, buildEdi, lookupCall, sessionEdit, parseEdiForImport, makeZip, bandColors, manualTime, backup, I18N) |
adif-stats.test.js |
133 | 21 (lookupCall, normBand, normMode, locToLatLon, haversine, parseADIF ×3, computeStats ×6, applyFilters, fmtDate, fmtMonth, htmlEsc, svgHBar, svgVBar, I18N) |
adif2cab.test.js |
191 | 31 (modeToCAB ×5, dfltRST, freqToKHz ×2, parseADIF ×3, extractExchR ×9, formatCabDate, buildQSOLine ×5, htmlEsc, cabModeBadge, modeBadge, CONTESTS structure, I18N) |
edi-validator.test.js |
109 | 22 (locToLatLon, haversine, validate — clean EDI, validate — structure, validate — non-spec keywords, validate — header formats, validate — ZRS mandatory fields, validate — QSO count, validate — QSO field count, validate — QSO date, validate — QSO time, validate — QSO mode, validate — QSO dupe flag, validate — QSO WWL format, validate — QRB deviation, validate — line length, validate — non-ASCII characters, validate — duplicate keywords, validate — QSO date day, validate — QSO date range, validate — QSO RST format, I18N) |
See TESTING.md for full test documentation.
See Improvements.md for the full bug history and feature roadmap.
| Document | Description |
|---|---|
| VHF_Handbook_V10_03_final_EDI.pdf | IARU VHF Handbook — REG1TEST EDI v1 format specification |
MIT
Orodja za obdelavo in pretvorbo formatov radioamaterskih dnevnikov.
| Orodje | Vrsta | Namen |
|---|---|---|
edi2adif.html |
Brskalniška app | Pretvorba REG1TEST EDI v1 tekmovalnih dnevnikov v ADIF in CSV formate |
edi-crosscheck.html |
Brskalniška app | Crosscheck novega EDI dnevnika glede na zgodovinske dnevnike + opcijski OEVSV IARU R1 baseline — zaznava napake lokatorjev in klicnih znakov |
vhf-logger/vhf-logger.html |
Brskalniška app | Beležnik tekmovalnih dnevnikov VHF/UHF/SHF v realnem času z live crosscheckom, prikazom QRB/azimuta in izvozom REG1TEST EDI |
adif-merge.html |
Brskalniška app | Združevanje več ADIF dnevniških datotek — deduplikacija, filtri po pasu/načinu/izvoru, urejanje v živo, izvoz ADIF in CSV |
adif-stats.html |
Brskalniška app | Analiza ADIF dnevnika — statistika po pasu/načinu/kontinentu/državi/času, DXCC per pas, toplotna karta aktivnosti, matrika pas×ura, porazdelitev QRB, HTML izvoz |
adif2cab.html |
Brskalniška app | Pretvorba ADIF dnevnika v format Cabrillo v3; CQ WW SSB/CW/RTTY, IARU HF, IARU VHF, CQ WPX SSB/CW, ARRL DX, Splošno |
edi-validator.html |
Brskalniška app | Samostojni validator EDI datotek: skladnost s specifikacijo, obvezna polja ZRS, preverjanje odmika QRB |
adif-qrz-filter.js |
Node.js CLI | Filtriranje ADIF dnevnika — ohrani samo zveze s postajami, ki sprejemajo biro |
build-baseline.js |
Node.js CLI | Zgradi crosscheck-baseline.json iz OEVSV IARU R1 contest CSV exportov za uporabo z edi-crosscheck.html in vhf-logger/vhf-logger.html |
edi2adif.html)Pretvori REG1TEST EDI v1 tekmovalne dnevnike v format ADIF in druge formate. Datoteko odpri v katerem koli sodobnem brskalniku — namestitev ni potrebna.
.edi datotek hkratiVrednost EDI PBand |
Pas ADIF |
|---|---|
| 50 MHz, 6m | 6m |
| 144 / 145 MHz, 2m | 2m |
| 430 / 432 MHz, 70 cm | 70cm |
| 1,2 / 1,3 GHz, 1296 MHz, 23 cm | 23cm |
| 2,3 GHz, 2320 MHz, 13 cm | 13cm |
| 3,4 GHz, 3400 MHz, 9 cm | 9cm |
| 5,7 GHz, 5760 MHz, 6 cm | 6cm |
| 10 GHz, 10368 MHz, 3 cm | 3cm |
| 24 GHz, 24048 MHz, 1,25 cm | 1.25cm |
| 47 GHz, 6 mm | 6mm |
Podprti načini: SSB · CW · FM · AM · RTTY · SSTV · ATV
edi2adif.html (ena datoteka, ~42 KB).edi datotek na območje za spuščanje ali klikni Izberi datotekePo nalaganju strani internetna povezava ni potrebna (razen za Google Fonts). Vsa obdelava poteka v brskalniku — nobene datoteke ali podatki o zvezah niso nikamor naloženi.
edi-crosscheck.html)Brskalniško orodje, ki primerja nov EDI tekmovalni dnevnik z bazo, zgrajeno iz zgodovinskih EDI dnevnikov. Pomaga odkriti verjetne napake v lokatorjih in klicnih znakih pred oddajo dnevnika. Datoteko odpri v katerem koli sodobnem brskalniku — namestitev ni potrebna.
crosscheck-baseline.json in je stran odprta preko HTTP-ja, se ob zagonu samodejno naloži pred-zgrajen baseline 3 000+ IARU R1 tekmovalnih postaj (klicni znak → lokator, izpeljano iz javnih OEVSV CSV exportov). To omogoča smiseln crosscheck brez lastne EDI zgodovine.Opomba o
file://odpiranju: sodobni brskalniki blokirajofetch()izfile://URL-jev zaradi varnosti. Če dvoklikneš HTML, se baseline tiho ne naloži in orodje deluje natanko kot v1.3 (samo lastna EDI zgodovina). Za uporabo baseline-a postrežaj preko HTTP-ja (python3 -m http.server) — glej Navodila za uporabo spodaj.
| Oznaka | Barva | Pogoj |
|---|---|---|
LOC! |
Rdeča | Lokator se razlikuje od zgodovinskega modusa; zaupanje v modus ≥ prag in nov lokator še nikoli ni bil viden |
LOC? |
Rumena | Lokator se razlikuje od zgodovinskega modusa; nižje zaupanje ali nov lokator je bil že viden (prenosna postaja) |
LOC? |
Rumena | Zveza nima lokatorja, a klicni znak obstaja v zgodovini — predlaga zgodovinski modus lokator |
CALL? |
Rumena | Klicni znak ni v zgodovini; najden je podoben klicni znak globalno (Levenshteinova razdalja 1–2) |
LOC-CALL? |
Modra | Klicni znak ni v zgodovini; najden je podoben klicni znak z istega lokatorja (kompozitna hevristika) |
? |
Siva | Klicni znak ni v zgodovini; ni podobnega klicnega znaka |
✓ |
Zelena | Klicni znak je v zgodovini, lokator ustreza modusu |
Prenosne in mobilne pripone (/P, /M, /MM itd.) se odstranijo pred iskanjem — S59DGO/P se primerja z zgodovino S59DGO. Italijanski regionalni sufiksi (/IV3, /I2 itd.) in številčni sufiksi okrajev (/1, /2) se prav tako odstranijo. Klicni znaki s predponsko poševnico (OE/S59DGO) ostanejo nespremenjeni.
Preverjanje lokatorja zahteva privzeto vsaj 3 zgodovinske pojavitve, a je to nastavljivo prek drsnika Min. pojavitev (1–10). Drsnik Confidence (10–100%) določa mejo med resnostjo high in medium. Oba drsnika lahko spremeniš po nalaganju novega dnevnika — klikni Ponovi, da se pragovi uveljavijo brez ponovnega nalaganja datoteke.
crosscheck-baseline.json prisoten. Vsak baseline vnos šteje 3× toliko kot en EDI QSO (avtoritativna deklaracija lastnega lokatorja iz robotsko-validiranih tekmovalnih dnevnikov). Chip-i v prikazu kažejo raw številke zaradi intuitivnosti.IK3GOY → IW3GOA, ko sta oba iz JN65DM)edi-crosscheck.html (ena datoteka, ~50 KB). Opcijsko prenesi tudi crosscheck-baseline.json (~220 KB) za OEVSV baseline.fetch() iz file://):
cd /pot/do/HamLogTools
python3 -m http.server 8080
# nato odpri: http://localhost:8080/edi-crosscheck.html
Za dvoklik file:// orodje deluje normalno — samo brez baseline-a.
Internetna povezava ni potrebna. Vsa obdelava poteka lokalno v brskalniku.
vhf-logger/vhf-logger.html)Beležnik tekmovalnih dnevnikov v realnem času za VHF/UHF/SHF pasove. Seje shranjuje v localStorage — strežnik ni potreben.
Datoteko odpri v katerem koli sodobnem brskalniku (za baseline podporo postrežaj preko HTTP).
➜ Odpri vhf-logger/vhf-logger.html
crosscheck-baseline.json (enaka baza kot edi-crosscheck.html); baseline se ob zagonu samodejno naloži preko HTTPbaseCall(), tako da se S59DGO/P pravilno ujame z S59DGO; per-pas, izključuje QSO, ki se trenutno urejalocalStoragelocalStorage[REG1TEST;1], polja opreme SPowe/SAnte/STXEq/SRXEq/SAntH, kategorija PSect, blok C* povzetka točkanja (CQSOs, CQSOP, CWWLs, CWWLB, CExcs, CExcB, CDXCs, CDXCB, CToSc, CODXC) in pravilni 15-polni zapisi QSO (zastavica duplikata na stolpcu 14 po specifikaciji)localStorage100dvh se izogiba prekrivanju z orodno vrstico iOS Safari; površine za dotik ≥ 32 × 32 pxvhf-logger/vhf-logger.html (~60 KB). Baseline vhf-logger/crosscheck-baseline.json je vključen v isti podmapi in se naloži samodejno.cd /pot/do/HamLogTools
python3 -m http.server 8080
# nato odpri: http://localhost:8080/vhf-logger/vhf-logger.html
Brez baseline-a beležnik deluje normalno za zaznavanje duplikatov, EDI izvoz in izračun QRB.
Po nalaganju strani internetna povezava ni potrebna. Vsi podatki ostanejo v localStorage brskalnika.
adif-merge.html)Združuje več ADIF dnevniških datotek v en deduplikiran dnevnik. Datoteko odpri v katerem koli sodobnem brskalniku — namestitev ni potrebna.
.adi / .adif datotek hkrati; dodatne datoteke dodaj kadarkoliAPP_ADIFMERGE_SRC zabeleži izvorno datoteko (ob ponovnem mergeu se samodejno odstrani)localStorageadif-merge.html (ena datoteka, ~35 KB).adi ali .adif datotek na območje za spuščanje ali klikni Izberi datotekePo nalaganju strani internetna povezava ni potrebna. Vsa obdelava poteka v brskalniku — nobene datoteke ali podatki o zvezah niso nikamor naloženi.
adif-stats.html)Analizira eno ADIF dnevniško datoteko in prikaže statistiko v interaktivni nadzorni plošči. Datoteko odpri v katerem koli sodobnem brskalniku — namestitev ni potrebna.
.adi / .adif datoteko na območje za spuščanje ali klikni za iskanjeDISTANCE ali izračuna iz GRIDSQUARE + MY_GRIDSQUARE prek haversinalocalStorageadif-stats.html (ena datoteka, ~60 KB).adi ali .adif datoteko na območje za spuščanje ali klikni Izberi datotekoPo nalaganju strani internetna povezava ni potrebna. Vsa obdelava poteka v brskalniku — nobene datoteke ali podatki o zvezah niso nikamor naloženi.
adif2cab.html)Pretvori ADIF dnevniško datoteko v format Cabrillo v3 za oddajo tekmovalnih dnevnikov. Datoteko odpri v katerem koli sodobnem brskalniku — namestitev ni potrebna.
.adi / .adif datoteko na območje za spuščanje ali klikni za iskanjePH (SSB/AM), CW, FM (ločena kategorija), RY (RTTY), DG (vsi ostali digitalni načini)FREQ (MHz → kHz); v primeru odsotnosti pade na center pasuCQZONE), IARU HF → ITU cona / HQ (ITUZ), IARU VHF → Maidenhead lokator (GRIDSQUARE, v velikih črkah), CQ WPX → serijska številka (STX/SRX_STRING), ARRL DX → država/provinca (STATE), Splošno → niz izmenjave (SRX_STRING / SRX)localStorageadif2cab.html (ena datoteka).adi ali .adif datoteko na območje za spuščanje ali klikni Izberi datotekoPo nalaganju strani internetna povezava ni potrebna. Vsa obdelava poteka v brskalniku — nobene datoteke ali podatki o zvezah niso nikamor naloženi.
edi-validator.html)Validira datoteko REG1TEST EDI v1 glede na EDI specifikacijo in zahteve ZRS za obvezna polja. Datoteko odpri v katerem koli sodobnem brskalniku — namestitev ni potrebna.
.edi datoteko na območje za spuščanje ali klikni za iskanje[REG1TEST;1], razdelek [Remarks], deklaracijo [QSORecords;N] in podnožje [END;...]TCall, TLocator, RAZ, RClub itd.)TDate (YYYYMMDD;YYYYMMDD), format in dolžina Maidenhead PWWLo, znana vrednost PBandPSect, PClub, RName, RHBBS ali SPowe prazniYYMMDD, veljavnost dne (prestopna leta), čas HHMM, koda načina 0–9 (0 = “nobeden od spodaj”), format RST glede na način (SSB/AM/FM → 2 znaka; CW/RTTY → 3 znake), zastavica duplikata (D ali prazno)TDate iz glavePWWLo in lokatorjem QSO; opozori, če odmik presega 10 %error (kršitev specifikacije), warn (zahteva ZRS ali odmik) ali info (priporočilo)localStorageedi-validator.html (ena datoteka).edi datoteko na območje za spuščanje ali klikni Izberi datotekoPo nalaganju strani internetna povezava ni potrebna. Vsa obdelava poteka v brskalniku — nobene datoteke niso nikamor naložene.
build-baseline.js)Node.js CLI skripta, ki gradi crosscheck-baseline.json iz mape OEVSV IARU R1 tekmovalnih CSV exportov. Uporablja se za občasno osveževanje pred-zgrajenega baseline-a, ki ga edi-crosscheck.html naloži ob zagonu.
Vir: OEVSV baza rezultatov IARU R1 tekmovanj na https://iaru.oevsv.at/v_upld/prg_list.php. Vsako tekmovanje ima gumb za CSV export z (najmanj) stolpcema Call in WWL. Prenesi CSV-je več tekmovanj v eno mapo, nato zaženi skripto.
# 1. Ustvari mapo za CSV prenose:
mkdir iaru_oevsv_csv
# 2. Prenesi CSV exporte iz OEVSV za tekmovanja, ki jih želiš vključiti.
# Shrani jih v iaru_oevsv_csv/ (poljubna imena datotek).
# 3. Zgradi baseline:
node build-baseline.js
# Izhod: ./crosscheck-baseline.json
node build-baseline.js # privzeto
node build-baseline.js --in ./iaru_oevsv_csv # nastavljiva vhodna mapa
node build-baseline.js --out ./crosscheck-baseline.json
node build-baseline.js --min-appearances 5 # strožji kvalitetni filter
node build-baseline.js --min-appearances 1 # obdrži vse (brez filtra)
node build-baseline.js --pretty # zamiknjen JSON za pregled
node build-baseline.js --verbose # statistika po datotekah
| Možnost | Privzeto | Opis |
|---|---|---|
--in DIR |
./iaru_oevsv_csv |
Mapa s CSV datotekami |
--out FILE |
./crosscheck-baseline.json |
Pot izhodnega JSON |
--min-appearances N |
3 |
Najmanjše skupno število tekmovalnih nastopov za vključitev klicnega znaka |
--pretty |
izkl. | Zamiknjen JSON izhod |
--verbose |
izkl. | Statistika obdelave po datotekah |
*.csv datoteke v vhodni mapi (samodejna detekcija encodinga: UTF-8 → ISO-8859-1 fallback)LL Squares stolpca)/MM ali /AM se zavrže (po definiciji nepredvidljiv)baseCall() (enaka logika kot HTML orodje), pas preko BAND_MAP, lokator v prve 4 velike + zadnji 2 mali--min-appearancesv = datum gradnje, src, n.calls, n.entries, n.files, indeks pasov, slovar klicnih znakov)Baseline se s časom stara, ker se operatorji selijo ali pojavijo novi. Priporočeni interval: rebuild vsake 3–6 mesecev, ali po večjih IARU R1 tekmovanjih (IARU R1 VHF, UHF/SHF, Marconi Memorial). Vsaka osvežitev:
# 1. Prenesi sveže CSV-je v iaru_oevsv_csv/ (dodaj nova tekmovanja, opcijsko odstrani stara)
# 2. Rebuild:
node build-baseline.js
# 3. Skripta zapiše crosscheck-baseline.json in ga preslika v vhf-logger/crosscheck-baseline.json.
# Obe HTML orodji samodejno pobereta novo datoteko ob naslednjem nalaganju strani.
Kompakten JSON, ~220 KB za tipičen IARU R1 dataset (3 000+ klicnih znakov, 16 pasov):
{
"v": "2026-05-13",
"src": "iaru.oevsv.at",
"minAppearances": 3,
"n": { "calls": 3240, "entries": 10564, "files": 35 },
"b": ["6m", "4m", "2m", "70cm", "23cm", ...],
"c": {
"DK0NA": { "2": [["JO50ti", 16]], "3": [["JO50ti", 16]], ... },
"S59P": { "2": [["JN86ao", 15]], ... },
...
}
}
Vsak vnos klicnega znaka je { indeksPasu: [[lokator, count, portableFlag?], ...] }, urejen po count padajoče. Tretji element 1 označuje, da je lokator izključno portable (samo /P ali /M).
adif-qrz-filter.js)Node.js CLI orodje, ki filtrira ADIF dnevnik in ohrani samo tiste zveze, kjer postaja
sprejema QSL kartice preko biroja. Za vsak unikaten klicni znak poizveduje po QRZ.com XML API;
če je v zvezah prisotno polje QSL_VIA, preveri tudi status managerjevega biroja.
Rezultati se predpomnijo lokalno za 7 dni.
QSL_VIA iz ADIF in preveri biro status managerja.qrz-cache.json) preprečuje ponovne poizvedbe--include-unknown)# Prijava z uporabniškim imenom in geslom
node adif-qrz-filter.js contest.adi --username=S59ABC --password=secret
# Uporaba obstoječega ključa seje
node adif-qrz-filter.js contest.adi --key=a1b2c3d4
# Nastavljiva izhodna pot in zamik
node adif-qrz-filter.js contest.adi --key=a1b2c3d4 --output=buro.adi --delay=800
# Ohrani klicne znake, ki jih QRZ ne najde
node adif-qrz-filter.js contest.adi --key=a1b2c3d4 --include-unknown
Možnosti:
| Možnost | Privzeto | Opis |
|---|---|---|
--username=USER |
— | Uporabniško ime QRZ.com (zahteva --password) |
--password=PASS |
— | Geslo QRZ.com |
--key=SESSION |
— | Obstoječ ključ seje QRZ (preskoči prijavo) |
--output=FILE |
input-buro.adi |
Ime izhodne ADIF datoteke |
--delay=MS |
1200 |
Zamik med API klici v milisekundah |
--cache=FILE |
.qrz-cache.json |
Pot do lokalne predpomnilniške datoteke |
--include-unknown |
izkl. | Ohrani QSO-je za klicne znake, ki jih QRZ ne najde |
Opomba: Med zagonom se klicni znaki pošljejo QRZ.com. Glej politiko zasebnosti QRZ.com.
Enotni testi poslovne logike tečejo v Node.js (v18+), brez dodatnih odvisnosti:
# EDI → ADIF pretvornik
node --test --test-reporter=spec edi2adif.test.js
# EDI Crosscheck
node --test --test-reporter=spec edi-crosscheck.test.js
# ADIF Merge
node --test --test-reporter=spec adif-merge.test.js
# ADIF QRZ BURO filter
node --test --test-reporter=spec adif-qrz-filter.test.js
# Beležnik VHF/UHF tekmovanj
node --test --test-reporter=spec vhf-logger/vhf-logger.test.js
# ADIF Statistics
node --test --test-reporter=spec adif-stats.test.js
# ADIF → Cabrillo pretvornik
node --test --test-reporter=spec adif2cab.test.js
# EDI validator
node --test --test-reporter=spec edi-validator.test.js
| Testna datoteka | Testov | Skupin |
|---|---|---|
edi2adif.test.js |
122 | 9 (normBand, parseEDI, adifField, csvEsc, modeBadge, i18n, duplikati, CSV izvoz, urejanje v živo) |
edi-crosscheck.test.js |
56 | 8 (baseCall, levenshtein, parseEDI, runCrosscheck lokator ×6, runCrosscheck klicni znak ×8, manjkajoč lokator ×4, pragovi ×3, klicni znak po lokatorju ×4) |
adif-merge.test.js |
112 | 21 (parseADIF, updateKey, recomputeDupes, adifField, htmlEsc, csvEsc, modeBadge, buildFilename, ADIF izvoz, I18N, varnost ponovnega mergea in več) |
adif-qrz-filter.test.js |
48 | 4 (parseAdif, extractField, usesQslBuro ×3, cache) |
vhf-logger/vhf-logger.test.js |
191 | 17 (baseCall, normBand, locToLatLon, haversine, calcBearing, levenshtein, isDupe, recalcDupes, buildEdi, lookupCall, sessionEdit, parseEdiForImport, makeZip, bandColors, manualTime, backup, I18N) |
adif-stats.test.js |
133 | 21 (lookupCall, normBand, normMode, locToLatLon, haversine, parseADIF ×3, computeStats ×6, applyFilters, fmtDate, fmtMonth, htmlEsc, svgHBar, svgVBar, I18N) |
adif2cab.test.js |
191 | 31 (modeToCAB ×5, dfltRST, freqToKHz ×2, parseADIF ×3, extractExchR ×9, formatCabDate, buildQSOLine ×5, htmlEsc, cabModeBadge, modeBadge, CONTESTS struktura, I18N) |
edi-validator.test.js |
109 | 22 (locToLatLon, haversine, validate — clean EDI, validate — structure, validate — non-spec keywords, validate — header formats, validate — ZRS mandatory fields, validate — QSO count, validate — QSO field count, validate — QSO date, validate — QSO time, validate — QSO mode, validate — QSO dupe flag, validate — QSO WWL format, validate — QRB deviation, validate — line length, validate — non-ASCII characters, validate — duplicate keywords, validate — QSO date day, validate — QSO date range, validate — QSO RST format, I18N) |
Celotna dokumentacija je v TESTING.md.
Polna zgodovina hroščev in načrt prihodnjih funkcionalnosti je v Improvements.md.
| Dokument | Opis |
|---|---|
| VHF_Handbook_V10_03_final_EDI.pdf | IARU VHF Handbook — specifikacija formata REG1TEST EDI v1 |
MIT