================================================================================
SitRepMapper v1.12.1 — User Manual

Designed and developed by Stephen Clay McGehee, KN4AM
Coding done using Claude Code AI
See SitRepNet.com for more information
================================================================================


OVERVIEW
--------
SitRepMapper is an offline situation-report and map-pin viewer. It grew
out of amateur radio and emergency communications (EMCOMM) use — reading
F!505 Area Assessment, F!104 Situation Report, F!309 Situation Map Pin,
and CommStat StatRep records either from JS8Spotter's database or
directly from JS8Call's own DIRECTED.TXT log, plotting them on a local
tile map, and generating the same text summary reports as JS8Reporter, no
internet connection required at runtime — but it is just
as useful without any radio involved at all: as a tool for conducting an
Area Study (mapping out what's in your AO, or Area of Operations) and for
information gathering by preparedness groups. The Areas and Flag Pins
features exist for exactly that, letting a group build and share a common
picture of their area by exchanging exported files.

Key capabilities:
  - Displays F!505 / F!104 / F!309 / CommStat report pins, color-coded by
    score, status, or severity
  - Live report auto-refresh — from JS8Spotter's database or directly from
    JS8Call's own Directed Log (Settings > Data Source picks which one) —
    the map updates automatically as new reports arrive, no manual
    export/import required
  - Time Lapse — step through the dates present in the loaded reports
  - Flag Pins — manually-placed point markers, with a sortable list/manage
    window, import/export in a format interoperable with JS8Reporter,
    MHGridMapper, and Flag Pin Tool
  - Areas — manually-drawn polygons, rectangles, and circles for marking
    out regions rather than single points, with their own list/manage
    window and import/export format
  - Report Library — import/export F!505/F!104/F!309/CommStat reports as
    files, for group members without a radio connection or on a
    different schedule; merges with whichever live source is active
  - Offline tile maps (MBTiles); tiles downloaded once and stored locally
  - Grid Converter — translates between Maidenhead, MGRS/USNG, and lat/lon
  - Date Code Tool — converts between a date/time and the #XXXX datecode
    used on F! form prepared-time fields
  - Reports menu — the same 12 text-report generators as JS8Reporter, plus
    an F!104 summary
  - Send — compose and transmit F!104 / F!309 / F!505 / CommStat reports
    over JS8Call, with saved drafts, one-time or daily scheduled sending,
    and a sent-log
  - Export Map Image — save the currently visible map as a PNG or JPEG

More Information:  SitRepNet.com


LAUNCHING THE PROGRAM
----------------------
From the desktop:
  Double-click the SitRepMapper icon.

From the terminal:
  python3 /home/<username>/sitrepmapper/main.py


THE TOOLBAR
-----------
Left to right:

  Grid Locator: [_________] [Go]
    Type a Maidenhead grid locator (4, 6, 8, or 10 characters) and press
    Enter or click Go. The map centers on that square and outlines it with
    a dashed red boundary and label. An invalid locator shows an error
    dialog instead of moving the map. The last grid you went to is
    remembered and the map re-centers on it automatically the next time
    SitRepMapper starts.

  [+] [-]
    Zoom in / zoom out. Disabled at a zoom level with no tile data to show
    (once a tile source is loaded).

  [CONUS View]
    Resets the map to the default continental-US view.

  [Time Lapse] [<] [>]
    Starts or exits Time Lapse (see the Time Lapse section below). The
    < and > buttons step to the previous/next available date and are only
    enabled while Time Lapse is running.

  [Draw Polygon] [Draw Rectangle] [Draw Circle]
    Starts drawing a new Area of that shape (see the AREAS section below).
    The button reads "Cancel Drawing" while a shape is in progress; only
    one drawing mode can be active at a time.

  [View A] [View B]
    Two saved-view slots for jumping back to a zoom level and center point
    of current interest. Click to recall a slot's saved view; right-click
    to save the map's current zoom/center into that slot (the button
    briefly reads "Saved!" for confirmation). Each slot is empty (no
    effect when clicked) until you've right-clicked it at least once.
    Saved views persist between sessions.

  (far right) — the current tile source description.


NAVIGATING THE MAP
-------------------
  Pan:   click-drag the map, or use the arrow keys
  Zoom:  mouse scroll wheel, the toolbar +/- buttons, or the +/-/= keys
  Click a report pin, flag pin, or area to see its details in a popup
  Right-click an empty spot on the map to add a flag pin there
  Right-click an existing flag pin or area to edit or delete it

The status bar (bottom of the window) shows the current zoom level, the
center point's latitude/longitude, its Maidenhead grid, and the number of
F!505 / F!104 / F!309 / CommStat reports currently loaded.


REPORT SOURCES
-----------------
SitRepMapper reads F!505, F!104, F!309, and CommStat StatRep records from
exactly one of two sources at a time — pick which one with Settings >
Data Source, or by using either File > Open command below (opening a
source switches to it automatically).

File > Open JS8Spotter DB…
  Select JS8Spotter's .db file. It is opened read-only, so this is safe to
  do while JS8Spotter is running. SitRepMapper parses all F!505, F!104,
  F!309, and CommStat StatRep records it finds and plots them on the map.
  Re-read automatically every 60 seconds while active.
    Default location: js8spotter.db, directly inside JS8Spotter's own
    program folder (wherever it was installed) — JS8Spotter keeps its
    database alongside itself rather than in a separate app-data folder.

File > Open JS8Call Directed Log…
  Select JS8Call's own DIRECTED.TXT log file directly — no JS8Spotter
  involved at all. JS8Call writes this file continuously to its own Log
  directory (JS8Call menu: Log > Open Log Directory) whether or not any
  companion program is running, so it also captures traffic received
  while SitRepMapper (or JS8Spotter) wasn't open. On first opening (and
  any time you switch to this source) the whole file is scanned; after
  that, only newly-appended lines are read, every 5 seconds. Because
  nothing filters by group at capture time the way JS8Spotter's own
  settings can, this source sees every CommStat StatRep and MC Form
  JS8Call itself decodes.
    Default location:
      Linux / Raspberry Pi:  ~/.local/share/JS8Call/DIRECTED.TXT
      Windows:  C:\Users\<username>\AppData\Local\JS8Call\DIRECTED.TXT
    JS8Call's own Log > Open Log Directory always reflects the actual
    current location on your system, so use that if these don't match.

Either way, View > Pause Auto-Refresh (uncheck to resume) temporarily
stops the poll for whichever source is active. Pause is not remembered
between sessions — a paused session starts fresh (unpaused) the next time
SitRepMapper is launched.

All four report types can also be loaded without either live source, via
File > Import/Export Reports — see REPORT LIBRARY below. These loaded
records work alongside whichever live source is active, and persist
between sessions independent of it.

An IGNORE.TXT file (one callsign per line, '#' for comments) placed in the
SitRepMapper program folder excludes those callsigns from all four report
types, regardless of source.


REPORT LIBRARY
-----------------
Beyond the two live sources above, SitRepMapper keeps its own internal
library of F!505/F!104/F!309/CommStat reports — records loaded by hand
rather than read live from JS8Spotter or JS8Call. This is how group
members without a radio connection, or on a different band/schedule, can
share what they've collected: one member exports a file, another imports
it. Library reports merge with whichever live source is active and
appear alongside it on the map, in Time Lapse, and in the Reports menu
summaries — and unlike the live sources, they're unaffected by a live
source's own re-scan (opening a new DB/log file, or switching sources,
never removes library reports).

File > Import/Export Reports:
  Import F!104 SitReps… / Import F!309 Map Pins… / Import F!505
    Reports… / Import CommStat StatReps…   Import one report type
    directly from a raw JS8Spotter-style log export (plain text)
  Import Report Library…    Load a SitRepMapper report-library file
                             (.reports.json) — adds or updates all
                             four types at once
  Export Report Library…    Save every currently-known report of the
                             chosen type/date span — the saved library
                             plus anything currently on the map from a
                             live source — to a .reports.json file. The
                             suggested filename encodes the type, date
                             span, and UTC export time, e.g.
                             reports_all_20260701-20260731_174029.
                             reports.json ("all" in place of either
                             date if left blank). From/To accept
                             YYYY/MM/DD, YYYY-MM-DD, or YYYYMMDD.

Deleting a report from the library is remembered — if you later
re-import a file containing that same report, SitRepMapper offers to
restore it instead of silently skipping it, so an accidental delete is
recoverable while a deliberate one doesn't come back on its own.

Note: View > Report Library… (below) and the Delete actions on it only
ever see the saved library, not live traffic. A report you can see on
the map because it came from a live source (JS8Spotter DB or Directed
Log) will not be listed there and cannot be deleted from there — only
Export Report Library… includes live traffic (as a one-time snapshot
into the exported file; it does not add that traffic to your saved
library). To stop a live-sourced report from showing at all, use
IGNORE.TXT (see REPORT SOURCES above) or that live source's own re-scan.

View > Report Library… opens a non-modal, sortable list of every report
in the library (Type, Callsign, Grid, Date/Time (UTC), Source), with:
  Delete                  Remove the selected report(s)
  Delete by Date Range…   Remove every report of a chosen type (or all
                           types) within a date span, after a count
                           preview and confirmation. If either date is
                           left blank the confirmation warns that this
                           deletes every matching report with no limit
                           on that end, not just a narrow range.
  Deduplicate              Collapse any exact-duplicate entries (should
                           normally find nothing — import already
                           prevents duplicates; this is integrity
                           tooling for a manually-edited file)


REPORT PINS
-----------
F!505 Area Assessment — round pin, colored by average score across all
  reported fields (Water, Sewage/Waste, Power, Communications, Economy,
  Transportation, Health/Safety, Social/Political):
    Green = Fully Operational   Yellow = Degraded
    Orange = Severely Impaired  Red = Destroyed
    Gray = Unknown/N/A
  Click popup: Callsign, Grid, State, City/County, Time, overall score.

F!104 Situation Report — round pin, colored by operational status:
    Green = Normal   Yellow = Degraded   Red = Significant Problems
  Click popup: Callsign, Grid, State, message, Time, and any active
  F!304 Sitrep / F!306 Power Stability / F!305 Alert flags.

F!309 Situation Map Pin — upward triangle, colored by severity:
    Green = Minor      Yellow = Moderate
    Orange = Severe    Red = Major/Catastrophic
    Gray = Unknown or N/A
  Click popup: Grid, Description, Affected Area, Category, Severity, Time
  Frame, Status, Expiration, Time.

CommStat StatRep — round pin, colored to match the reported overall
  status directly: Green / Yellow / Red / Gray (Unknown).
  Click popup: Callsign, Group, Scope, Message ID, overall status, a
  per-category breakdown (Power, Water, Medical, Comms, Travel, Internet,
  Fuel, Food, Crime, Civil, Political), Notes, Time. Both of CommStat's
  status-string formats — the legacy full 12-digit form and the current
  "+" all-Green shorthand — are fully valid input; a status string that
  doesn't match either is still shown, labeled "Unparsed," rather than
  being dropped.

Duplicate grid squares (Settings > Filters) — matching is always per
callsign, so different stations reporting from the same grid square each
still get their own pin; only repeat submissions from the same station
at that grid are deduplicated:
  - "Use only the most recent assessment" (default) — F!505, F!104, and
    CommStat all keep that station's latest report per grid square.
  - "Average all assessments for the same grid square" — F!505 only;
    averages field scores (@X/Unknown fields excluded) and applies the
    rounding rule from Settings > Pin Colors. F!104 and CommStat always
    use latest (there is nothing meaningful to average). F!309 pins are
    never deduplicated.

New pin highlight (Settings > Pin Colors): draws a magenta ring around any
F!505/F!104/F!309/CommStat pin received within a configurable number of
hours (0 = off; fractional values like 0.5 are accepted, for finer-grained
triage when reports are arriving quickly), so newly-arrived reports stand
out at a glance.

Stacked pins: since duplicate-grid handling above is per report type, a
single grid square can still end up with more than one pin — e.g. an
F!104 and an F!505 filed by the same station, or a CommStat StatRep
alongside either. When two or more reports share a grid square, the
topmost pin (always the most recent of the group) shows a small numbered
badge; click it to see every report there, most recent first, and choose
which one's details to open.


TIME LAPSE
----------
Time Lapse steps through the distinct dates present in the currently
loaded reports, oldest to newest, showing only the reports selected by the
active mode for each date. Start it from the toolbar Time Lapse button or
View > Time Lapse; step with the toolbar < / > buttons. The active date is
shown as a badge in the bottom-left corner of the map. Exit with the same
toolbar button (now labeled "Exit Time Lapse") or by unchecking View >
Time Lapse.

Playback mode (Settings > Time Lapse):
  Rolling Window   — the last N days up through the active date (N is
                     configurable; 14 by default)
  Cumulative       — every report up through the active date
  Snapshot         — only the active date

Time Lapse respects the Date Filter (Settings > Date Filter) — it lets you
step through whatever subset of dates that filter has already narrowed the
data to. If new reports arrive from the live report poll (whichever
source — see REPORT SOURCES) while Time Lapse is running, the available
date range is refreshed automatically, jumping to the newest date if the
one you were on is no longer present.


FLAG PINS
---------
Flag pins are markers you place yourself — for anything not captured by an
incoming report: a shelter location, a hazard, a rally point, a note to
self. Along with Areas (below), this is one of the two tools for
conducting an Area Study or gathering information as a preparedness
group, independent of any radio or JS8Spotter database.

  Add:     right-click an empty spot on the map (or an existing flag
           pin) > "Add Flag Pin Here…"
  Fields:  Description, Maidenhead Grid, Date/Time (UTC), Source, Color,
           Group
  Move:    drag any flag pin to a new location
  Details: click a flag pin to open its popup (Edit… / Delete / Close)
  Edit/Delete directly: right-click a flag pin (also offers "Add Flag
    Pin Here…", for dropping another pin at that same spot)

Two or more flag pins sharing an exact spot show a small numbered badge,
the same as report pins do; click it to see every flag pin there, most
recent first, and choose which one to open. Dragging a flag pin onto
another one snaps it into an exact stack — no need to release on the
exact pixel by hand.

Group is free text — a combobox suggests groups already in use, but you
can type a new one. It's optional; leave it blank if you don't need to
separate pins into groups. Group is used two ways: filtering what an
export includes (see Import/Export below), and View > Flag Pin Groups,
which shows/hides pins on the map by group (see VIEW MENU REFERENCE).

Flag pins persist automatically between sessions
(~/.config/sitrepmapper/flags.flags.json).

View > Flag Pins… opens a non-modal list of every flag pin, with columns
for Description, Grid, Source, Severity, Status, Group, and Date/Time.
Click a column heading to sort by it (click again to reverse); from this
window you can Add, Edit, Delete, Jump to the pin's location on the map,
and Import/Export — the same operations available on the map itself, in
one list view. If you leave this window open, it stays in sync with
changes made elsewhere too — editing a pin on the map, importing a file,
or running Remove Duplicate Flag Pins (below) all update the list
immediately rather than requiring you to close and reopen it.

Import/Export (File menu, or from the Flag Pins… list window):
  File > Export Flag Pins…  — saves all current flags to a .flags.json file
  File > Import Flag Pins…  — adds or updates flags from a .flags.json
    file; existing pins are only overwritten if the incoming copy is
    newer, and anything you'd deliberately deleted stays deleted, with an
    offer to restore it if the file contains it (see APPENDIX: HOW-TO
    GUIDES below)

If your flag pins use two or more different Group values, Export first
shows a "Select Groups to Export" checklist (all groups checked by
default) so you can send only a subset — e.g. just one team's markers.
If everything shares one group, or no Group is in use at all, Export
skips that step and behaves exactly as before: nothing extra to click.

Tools > Remove Duplicate Flag Pins… scans for flag pins that match on
everything except id and Date/Time (Description, Grid, Latitude,
Longitude, Source, Color, Severity, Status, and Group) and removes all
but the most recently updated copy of each. Group is part of that match,
so two pins that differ only by Group are never treated as duplicates —
the same location is often tracked separately per group on purpose, so
it can be shown/hidden independently via View > Flag Pin Groups. You're
shown how many duplicates were found and asked to confirm before
anything is removed.

The file format (sitrep_flags) is shared with JS8Reporter, MHGridMapper,
and Flag Pin Tool, so flag files move freely between all of them — this
is how a group shares a common set of markers: each member exports their
flags and imports everyone else's.


AREAS
-----
Areas are polygons, rectangles, and circles you draw directly on the map
— the region equivalent of a flag pin, for marking out a neighborhood, a
patrol route, a supply radius, or any other bounded area rather than a
single point. Together with Flag Pins, this is the other core Area Study
/ preparedness-group tool.

Drawing a new area:
  1. Click the toolbar Draw Polygon, Draw Rectangle, or Draw Circle button.
     The button's label changes to "Cancel Drawing" while armed; press it
     again (or Escape) to back out without creating anything.
  2. Draw the shape. A live readout follows the cursor while drawing, so
     you can size the shape precisely instead of only after the fact:
       Polygon:    click each vertex in turn; each new edge shows its
                   length and bearing. Once you have at least 3 vertices,
                   click back near the starting point to close the shape.
       Rectangle:  click-drag from one corner to the opposite corner; the
                   readout shows width and height.
       Circle:     click-drag from the center outward to set the radius;
                   the readout shows the radius.
     All measurements are shown in decimal miles.
  3. On completing the shape, the Add Area dialog opens for its
     description (required), color, line thickness, Group (optional, same
     free-text combobox as Flag Pins — see FLAG PINS above), whether its
     title is always shown on the map, and its title text size (Small /
     Medium / Large / Extra Large). For a circle, this dialog also shows
     its center (editable, as Lat/Lon) and real-world radius (editable, as
     linked miles/km fields that stay in sync as you type), and offers an
     optional center crosshair. Concentric circles anchor their titles at
     each ring's own 12-o'clock point rather than the shared center, so
     overlapping titles stay legible.

Working with existing areas:
  Details: click an area to open its popup (Edit… / Delete / Close)
  Move/Reshape: drag a circle's center to move it, a rectangle's corner
    or side to resize it, or a polygon's vertex to reshape it — see
    APPENDIX: HOW-TO GUIDES below for the full set of dragging gestures,
    including snapping, duplicating, and moving concentric circles as a
    group
  Edit/Delete directly: right-click an area (also offers "Add Flag Pin
    Here…", anchored at the actual click point)

View > Areas… opens the same kind of non-modal, sortable list/manage
window as Flag Pins, with Edit, Delete, Jump to Map, and Import/Export.
Like the Flag Pins window, it stays in sync with changes made elsewhere
(map edits, imports, Remove Duplicate Areas) while it's left open.

Areas persist automatically between sessions
(~/.config/sitrepmapper/areas.areas.json).

Import/Export (File menu, or from the Areas… list window):
  File > Export Areas…  — saves all current areas to a .areas.json file
  File > Import Areas…  — adds or updates areas from a .areas.json file

Export filters by Group the same way Flag Pins does: a "Select Groups to
Export" checklist appears only if your areas actually use two or more
different Group values, otherwise every area is exported with no extra step.

Tools > Remove Duplicate Areas… scans for areas that match on everything
except id and Date/Time (shape, geometry, description, color, line
thickness, title/crosshair settings, and Group) and removes all but the
most recently updated copy of each. Group is part of that match, so two
areas that differ only by Group are never treated as duplicates — the
same location is often tracked separately per group on purpose, so it can
be shown/hidden independently via View > Area Groups. You're shown how
many duplicates were found and asked to confirm before anything is
removed.

The file format (sitrep_areas) is specific to Areas — exchange both an
.areas.json and a .flags.json file with other group members to build up a
shared picture of your AO from both tools together.


EXPORTING A MAP IMAGE
------------------------
File > Export Map Image… saves exactly what's currently visible on the
map — tiles, report pins, flag pins, and areas — as a PNG or JPEG file,
rendered at 4x the on-screen resolution for a sharper result. This is
useful for sharing a snapshot of the current picture with someone who
doesn't have SitRepMapper installed, or for keeping a dated record.

This feature requires Ghostscript to be installed on the system (a
one-time install, separate from the Python package dependencies — see
SitRepMapper_Installation_Guide.txt if you're prompted that it's missing).


GRID CONVERTER
---------------
Tools > Grid Converter…
  Enter a Maidenhead grid, an MGRS/USNG coordinate, or "lat, lon" — the
  format is auto-detected. Click Convert to see all three representations.
  Copy Maidenhead / Copy MGRS copy the result to the clipboard. Go to Grid
  on Map recenters the main map on the result and outlines the grid
  square, the same as using the toolbar Grid Locator.


DATE CODE TOOL
-----------------
Tools > Date Code Tool…
  Converts between a Month/Day/Hour/Minute (UTC) date/time and the
  #XXXX datecode used on F!104/F!309/F!505 prepared-time fields, in
  either direction. Uses the exact same encoding the report forms
  themselves accept, so a code produced here always decodes correctly
  on the map.


REPORTS MENU
-------------
Each report opens in its own window with Save to Export Folder, Save As…,
and Close buttons. Saved reports go to an exports/ subfolder directly under
the program folder by default; Settings > General > Export folder lets you
point this at a different folder instead. All reports respect the current
Date Filter and (for F!505) the report visibility toggle; a note at the top
of each report states the active filter. As of this release, the menu
groups reports into a submenu per report type, so it's clear at a glance
which kind of traffic each report is drawn from:

Reports > F!505 Area Reports:
  Area Assessment Summary   — Min/Max/Avg overview plus per-station blocks
  Full Detail Report        — every field for every station
  Score Rankings            — all stations sorted worst (lowest score) first
  Category Focus > <cat>    — one category's detail across all stations
  Alert Records             — stations with active/critical conditions
  Geographic Summary        — stations grouped by state, with state averages
  Critical Infrastructure   — fields scored Destroyed or Severely Impaired
  Trend Analysis            — stations that reported on multiple dates
  Infrastructure Heat Map   — count of stations at each score level, by category
  Data Quality / Coverage   — field completeness and recency per station
  Worst Conditions          — stations ranked by their single worst category
  Network Coverage          — every reporting grid square with coordinates
                               and last report date

Reports > F!104 Reports:
  Summary                    — one line per report: callsign, grid, status,
                                date, and active-form flags

Reports > CommStat Reports:
  Status Roster > Sorted by Callsign / Sorted by Grid /
  Sorted by Status  — one line per StatRep check-in (callsign, grid,
                       group, scope, overall status, time, notes), in
                       your choice of sort order; Sorted by Status lists
                       Red first, then Yellow, then Green, with
                       unparsed/unknown check-ins last

Reports > Raw Reports (As Received)…:
  Every currently-visible report's literal raw as-received text (all
  four types together), grouped by report type and sorted oldest-first
  within each group — useful as a plain-text audit trail of exactly what
  came in, as opposed to the decoded/summarized reports above.


SENDING REPORTS
------------------
The Send menu composes and transmits F!104, F!309, F!505, and CommStat
StatRep forms, plus plain Unformatted Text, over JS8Call — the reverse
direction from the rest of SitRepMapper, which only reads reports. This
requires JS8Call itself to be running with Settings > Reporting > "Enable
TCP Server API" turned on (SitRepMapper connects to 127.0.0.1:2442 by
default, JS8Call's own default). See SitRepMapper_Installation_Guide.txt
for the one-time JS8Call setting this feature also depends on (TCP Max
Connections).

Composing and sending:
  Send > F!104 Situation Report… / F!309 Map Pin Report… / F!505 Area
  Assessment… / CommStat StatRep… / Unformatted Text… opens that form's
  compose dialog. Every free-text field forces uppercase as you type,
  matching JS8's transmit-alphabet limitation — what you see is exactly
  what will go out. Each form's Grid field starts out filled in from
  Settings > General > Station grid on a fresh (non-draft, non-loaded-
  report) form — leave that setting blank if you'd rather start with an
  empty Grid field each time. Unformatted Text has no Grid field.

  Every dialog shares:
    Send To         — a callsign or group, or leave blank to broadcast
    Form Comment    — optional (not shown on F!309 or Unformatted Text)
    Send as MSG     — checkbox; tells JS8Call to store-and-forward the
                      message (JS8Call's "MSG" store-and-forward feature)
                      rather than send a plain directed transmission
    Save Draft / Send Now / Close

  F!505's compose dialog has one dropdown per field (32 total, using the
  same descriptions as the F!505 report) plus a "Set All Items to Option 3"
  button to quickly mark everything Unknown before adjusting individual
  fields. CommStat's compose dialog offers a "+" checkbox to send an
  all-Green status in one step, or per-category dropdowns to set each of
  the 11 categories individually — both are fully valid outgoing formats,
  matching the two formats SitRepMapper also accepts on receive (see
  REPORT PINS above).

  Unformatted Text has no encoded format at all — it sends exactly the
  text entered, upper-cased and with any line breaks collapsed to spaces
  (JS8 transmissions are a single continuous line). Use it for a quick
  message, or to forward text from a non-SitRepMapper form as-is. A
  running character count is shown below the text box; past a
  configurable length (Settings > General, default 80 characters, 0
  disables the warning) it turns amber as a heads-up that a long message
  takes JS8Call a while to transmit — this is a warning only, not a limit.

  Before Send Now transmits anything on F!104, F!309, F!505, or CommStat
  StatRep, the composed message is re-parsed and checked that it decodes
  back to exactly what was entered (Unformatted Text has no such check —
  there's nothing to re-parse). If it doesn't, an "Encoding Check Failed"
  error blocks the send so nothing goes out garbled. Send Now then shows
  the exact over-the-air text and asks for confirmation before
  transmitting.

JS8Call busy detection:
  While connected, SitRepMapper watches JS8Call for signs it's currently
  transmitting or already has a message staged — possibly from JS8Spotter
  or another program. If Send Now is used while that looks true, a "JS8Call
  Appears Busy" warning appears first; declining cancels the send, sending
  anyway proceeds but shows "Sent — Unconfirmed" afterward instead of the
  normal "Sent" message, since there's no way to confirm a colliding send
  actually went out (JS8Call silently drops the loser of a collision, with
  no error). This is a best-effort check, not a guarantee.

Drafts:
  Save Draft stores the form without sending it. Send > Manage Drafts…
  lists every saved draft across all five form types (Form, Summary, Send
  To, Schedule, Last Updated) — Open… recalls one into its compose dialog,
  fully editable; Delete removes it; Close exits. This window stays
  current on its own (checks every few seconds) even if a background
  scheduled send changes something while it's open.

Scheduled sending:
  Only a saved draft can be scheduled — select it in Manage Drafts and
  click Schedule…, then choose:
    Once  — a specific date and time
    Daily — one or more HH:MM times (comma-separated), recurring every day
  Scheduled sends only fire while SitRepMapper is actually running, the
  same as JS8Spotter's own Auto TX Schedule — a schedule due while the
  app is closed is not caught up retroactively later. A "Once" schedule
  fires within about two minutes of its target time; a "Daily" schedule
  fires once per matching time each day. If a scheduled send's window
  closes without ever going out (JS8Call unreachable or busy the whole
  time), it is not silently dropped — see MISSED SENDS below.

  Send > Pause Auto-Send checks off scheduled sends entirely without
  touching the schedules themselves — nothing fires, and nothing is
  logged as missed, until it's unchecked again. Like View > Pause
  Auto-Refresh, it always starts unchecked when the program launches.

Sent log:
  Send > View Sent Log… lists every message that was actually sent,
  whether typed manually or fired from a schedule, with its timestamp and
  exact over-the-air text. It stays current automatically while open.
  Save As… exports it to a file of your choice. The log itself is a single
  flat file — see CONFIGURATION below for how to clear or archive it.

Missed sends:
  If a scheduled send's window closes without a confirmed send, it's
  logged as missed rather than silently disappearing. A "Once" schedule is
  cleared after being logged (its draft is kept, just no longer scheduled);
  a "Daily" schedule keeps recurring — a miss on one day doesn't cancel
  future days. Shortly after SitRepMapper's next launch, a "Missed
  Scheduled Sends" dialog reports how many were missed since you last saw
  this notice, then clears until the next miss occurs.

Loading a received report into the Send form:
  Clicking a report pin on the map opens its details popup; if that report
  is an F!104, F!309, F!505, or CommStat pin, the popup also offers "Load
  into Send Form…", which opens the matching compose dialog pre-filled
  with that report's fields — a fast way to inspect a received report in
  full, or use it as a starting point for a reply, without retyping
  anything. The date/time is always stamped fresh at the moment you
  actually send, never carried over from the original report.


SETTINGS
--------
Settings > Settings… opens a tabbed dialog:

  Data Source   — JS8Spotter Database vs. JS8Call Directed Log (see
                  REPORT SOURCES above) — only one is active at a time
  General       — Station callsign (used as the default "Source" when
                  creating a flag pin); Station grid (used as the default
                  Grid on an empty Send compose form — see SENDING
                  REPORTS); Unformatted Text length warning (characters
                  before the character count turns amber, 0 disables it
                  — see SENDING REPORTS); Export folder (where Reports
                  menu's Save to Export Folder saves files — blank uses
                  the default exports/ subfolder under the program folder)
  Pin Colors    — Rounding rule for averaged F!505 scores (standard /
                  always up / always down); new-pin highlight window
                  (fractional hours accepted, e.g. 0.5)
  Filters       — Duplicate grid-square handling (latest vs. average)
  Date Filter   — No filter / previous N days / a specified date range;
                  which timestamp to filter on (record received time vs.
                  the form's own date code)
  Time Lapse    — Playback mode (Rolling Window / Cumulative / Snapshot)
                  and the rolling-window size in days
  Auto-Update   — Enable/disable the startup update check (checks a
                  small sitrepmapper_version.json file on sitrepnet.com;
                  not user-configurable)

Settings are saved immediately on OK and persist between sessions.


AUTO-UPDATE
-------------
On startup (if enabled in Settings > Auto-Update), SitRepMapper fetches
the configured URL in the background and compares the version it reports
against the running version. If a newer version is available, a dialog
offers to open the download page; if not, or if the check fails (no
internet, unreachable server), nothing is shown — offline operation is
never affected by this setting.

Settings > Check for Updates Now runs the same check on demand and always
reports a result: "up to date," an update-available prompt, or a "check
failed" warning if the server could not be reached. No update is ever
downloaded or applied automatically — you always land on the download
page and install manually, the same as any other update.


FILE MENU REFERENCE
---------------------
  Open MBTiles…          Load a single .mbtiles tile file
  Select Tile Folder…    Load a directory tile cache
  Download Tiles…        Launch TileDownloader (bundled, its own window)
                          to fetch new tile data
  Open JS8Spotter DB…    Open a JS8Spotter database (see REPORT SOURCES)
  Open JS8Call Directed Log…  Open JS8Call's own DIRECTED.TXT log
                               directly (see REPORT SOURCES)
  Import/Export Reports  Cascade — see REPORT LIBRARY: raw per-type
                          import (F!104/F!309/F!505/CommStat) plus
                          Import/Export Report Library…
  Import Flag Pins…      Add/update flags from a .flags.json file
  Export Flag Pins…      Save all current flags to a .flags.json file
  Import Areas…          Add/update areas from a .areas.json file
  Export Areas…          Save all current areas to a .areas.json file
  Export Map Image…      Save the visible map as a PNG or JPEG file
  Quit                   Save the window position/size and settings, then exit


VIEW MENU REFERENCE
----------------------
  Zoom In / Zoom Out          Same as the toolbar +/- buttons
  Reset to CONUS View         Same as the toolbar CONUS View button
  Icon Size                   Small / Medium / Large / Extra Large — report pins
  Flag Size                   Small / Medium / Large / Extra Large — flag pins
  F!505 Reports                Show/hide F!505 pins
  F!104 Reports                Show/hide F!104 pins
  F!309 Map Pins                Show/hide F!309 pins
  CommStat StatReps            Show/hide CommStat pins
  Flag Pins                    Show/hide flag pins
  Areas                        Show/hide drawn areas
  Flag Pin Groups              Per-Group show/hide for flag pins, plus its
                               own Show All Groups / Hide All Groups
                               (see FLAG PINS) — distinct from Show All /
                               Hide All below, which affects every layer
  Area Groups                  Per-Group show/hide for areas, plus its own
                               Show All Groups / Hide All Groups (see AREAS)
  Flag Pins…                   Open the sortable Flag Pins list/manage window
  Areas…                       Open the sortable Areas list/manage window
  Report Library…              Open the sortable Report Library list/manage
                               window (see REPORT LIBRARY)
  Show All / Hide All         Toggle every report/pin/area layer at once
  Legend                      Show/hide the on-map color-key legend
  Pause Auto-Refresh          Suspend the live report poll (JS8Spotter DB:
                               every 60s; JS8Call Directed Log: every 5s)
  Time Lapse                  Start/stop Time Lapse
  Time Lapse Settings…        Opens Settings on the Time Lapse tab


TOOLS MENU REFERENCE
-----------------------
  Grid Converter…             Maidenhead <-> MGRS/USNG <-> Lat/Lon (see above)
  Date Code Tool…             Date/time <-> #XXXX datecode (see above)
  Remove Duplicate Flag Pins… Collapse flag pins identical apart from id/
                               Date/Time (see FLAG PINS above)
  Remove Duplicate Areas…     Collapse areas identical apart from id/
                               Date/Time (see AREAS above)


REPORTS MENU REFERENCE
-------------------------
  See REPORTS MENU above for the full list.


SEND MENU REFERENCE
----------------------
  F!104 Situation Report…     Compose and send an F!104 report
  F!309 Map Pin Report…       Compose and send an F!309 report
  F!505 Area Assessment…      Compose and send an F!505 report
  CommStat StatRep…           Compose and send a CommStat StatRep
  Unformatted Text…           Compose and send plain, unformatted text
  Pause Auto-Send             Stop scheduled drafts from firing until
                               unchecked (see SENDING REPORTS above)
  Manage Drafts…              Open, schedule, or delete saved drafts
  View Sent Log…              View every message actually sent
  (see SENDING REPORTS above for details on each)


SETTINGS MENU REFERENCE
--------------------------
  Settings…                   Opens the tabbed Settings dialog (see above)
  Check for Updates Now       Runs an explicit update check (see AUTO-UPDATE)


HELP MENU REFERENCE
----------------------
  About                        Version, credits, and SitRepNet.com pointer


KEYBOARD SHORTCUTS
---------------------
  +  or  =                    Zoom in
  -                            Zoom out
  Arrow keys                  Pan the map
  Enter (in Grid Locator)     Go to the typed grid
  Escape                      Close the focused dialog or menu, or cancel
                               an area drawing in progress


CONFIGURATION
--------------
Settings are saved to:
  Linux / Raspberry Pi:  ~/.config/sitrepmapper/config.json
  Windows:                C:\Users\<username>\.config\sitrepmapper\config.json

Deleting this file resets all settings to defaults. Flag pins live
alongside it in flags.flags.json, areas in areas.areas.json, and the
Report Library in reports.reports.json (see REPORT LIBRARY above) —
deleting config.json does not affect any of them. Saved reports go to a
separate export folder (see REPORTS MENU above and Settings > General),
not this folder.

The Send feature (see SENDING REPORTS above) keeps three more files in the
same folder:
  send_drafts.json    Saved drafts (Send > Manage Drafts…)
  send_log.json        Sent-log (Send > View Sent Log…)
  missed_sends.json    Missed scheduled sends not yet acknowledged
Each is a single flat file, always read fresh — there is no in-app delete
for the sent-log or drafts list as a whole. You can freely delete or
rename/archive send_log.json yourself at any time (safest done while
SitRepMapper is closed, though it's never held open); a missing file is
treated as empty and recreated automatically on the next send.


TILE DATA SETUP
------------------
SitRepMapper does not bundle map tiles or a tile downloader. Tiles are
obtained separately (see SitRepMapper_Installation_Guide.txt) and loaded from:

  1. A drive labelled SRMAP_NA (plug in before launching)
  2. Any other mounted drive under /media, /mnt, or /run/media
  3. The local tiles/ directory inside the program folder

All .mbtiles files found are loaded simultaneously, so an overview file
and regional detail files work together without manual selection. If
nothing is auto-detected, use File > Open MBTiles… or File > Select Tile
Folder… to load a source manually — the rest of the program is fully
usable (Grid Locator, Grid Converter, either report source, Reports, Flag
Pins, Areas) even with a blank/gray map.


TROUBLESHOOTING
------------------
"ModuleNotFoundError: No module named 'PIL'" on launch
  Pillow is not installed:
      pip3 install Pillow            (Linux / Raspberry Pi)
      pip install Pillow             (Windows)
  If you see "externally managed environment," add --user.

"ModuleNotFoundError: No module named 'mgrs'" / Grid Converter does nothing
  This error fires when you open Tools > Grid Converter, not on launch:
      pip3 install mgrs              (Linux / Raspberry Pi)
      pip install mgrs               (Windows)

"ModuleNotFoundError: No module named 'tkinter'"
  On Raspberry Pi OS, Ubuntu, or Debian:
      sudo apt install python3-tk

Gray canvas on launch / no map visible
  No tile data has been found. See TILE DATA SETUP above, or use File >
  Open MBTiles… / File > Select Tile Folder… to load a source manually.

"TileDownloader Not Found" when using File > Download Tiles…
  TileDownloader is bundled with SitRepMapper — this means the bundled
  tiledownloader/ subfolder is missing from your install (reinstall to
  fix). See SitRepMapper_Installation_Guide.txt.

Database will not open / "Could not read database"
  Confirm the file is a genuine JS8Spotter .db (SQLite) file and that it
  is not on a network location that blocks read-only SQLite access.

Where is JS8Spotter's database file?
  Default: js8spotter.db, directly inside JS8Spotter's own program folder
  — it keeps its database alongside itself, not in a separate app-data
  location. If you've moved or renamed it, locate it from within
  JS8Spotter itself, or search your system for js8spotter.db.

Where is JS8Call's Directed Log?
  Default: ~/.local/share/JS8Call/DIRECTED.TXT on Linux/Raspberry Pi,
  C:\Users\<username>\AppData\Local\JS8Call\DIRECTED.TXT on Windows. To
  confirm the actual current location on your system, use JS8Call itself:
  Log > Open Log Directory opens the folder containing DIRECTED.TXT.
  JS8Call writes it continuously on its own, regardless of whether
  SitRepMapper or JS8Spotter are running.

JS8Call Directed Log source shows nothing / stops updating
  Confirm JS8Call itself is still running and actively decoding — unlike
  the JS8Spotter database, DIRECTED.TXT only grows while JS8Call is open.
  If the file was moved or JS8Call's log rotated, use File > Open JS8Call
  Directed Log… again to point at the current file.

"Export Error" / Ghostscript message using File > Export Map Image…
  Ghostscript is not installed — see SitRepMapper_Installation_Guide.txt. This is a
  system tool, not a Python package, and only affects this one feature.

Program feels sluggish on a Raspberry Pi or other minimal system
  Check what else is running at the same time first — a web browser,
  text editor, or other programs open alongside SitRepMapper, JS8Call,
  and JS8Spotter can be enough to make a low-power system feel slow or
  unresponsive even though SitRepMapper itself is fine. Close anything
  not actually needed and see if it clears up before assuming it's a
  SitRepMapper problem.

Config file location
  See CONFIGURATION above. Deleting config.json resets all settings to
  defaults without touching flag pins, areas, or saved reports.

"Not Connected" using Send
  JS8Call isn't running, or its Settings > Reporting > "Enable TCP Server
  API" option is off. Turn it on and try again.

"JS8Call Rejected the Connection" / "Connections Full" using Send
  Another program (commonly JS8Spotter) is already using JS8Call's API
  connection slot. Close it, or raise JS8Call's Settings > Reporting > TCP
  Max Connections above its default of 1 — SitRepMapper's Send feature
  holds one connection open for its entire runtime, so the cap needs to be
  at least 2 just for SitRepMapper and JS8Spotter to both be open at the
  same time, not only during an actual simultaneous send. See
  SitRepMapper_Installation_Guide.txt.

"JS8Call Appears Busy" prompt using Send
  SitRepMapper detected JS8Call currently transmitting or already holding
  a staged message — sending now risks a silent collision. Send anyway
  proceeds but reports "Sent — Unconfirmed" afterward, since there's no
  way to confirm a colliding send actually transmitted; check JS8Call's
  own log or Tx pane if in doubt.

"Encoding Check Failed" using Send
  The composed message didn't re-parse back to exactly what was entered.
  Sending is blocked automatically so nothing goes out garbled — review
  the field(s) named in the error and correct them.

A scheduled send never went out
  SitRepMapper only fires schedules while it's actually running, the same
  as JS8Spotter's own Auto TX Schedule — a schedule due while the app was
  closed, or that stayed blocked by a busy/unreachable JS8Call for its
  whole window, is not caught up retroactively. Check for a "Missed
  Scheduled Sends" notice on the next launch, or Send > View Sent Log… to
  confirm what did or didn't go out.

Window reopens on the wrong monitor (multi-monitor Raspberry Pi, maximized)
  SitRepMapper remembers window position/size and restores it on the next
  launch. On Raspberry Pi OS Bookworm's default desktop (Wayfire, a
  Wayland compositor), this restore is unreliable specifically when the
  window was maximized on a monitor other than the primary one — the
  window reopens maximized on the primary monitor instead. This is a
  Wayland limitation, not something SitRepMapper can control: Wayland
  intentionally gives applications no way to request an absolute window
  position, unlike X11. Non-maximized window positions are not affected.
  Workarounds:
    - Avoid maximizing the window on a secondary monitor; leave it
      slightly smaller than full-screen instead.
    - Or switch the Pi to the X11 session: sudo raspi-config > Advanced
      Options > Wayland > X11, then reboot.


APPENDIX: HOW-TO GUIDES
--------------------------
Step-by-step walkthroughs for common multi-step tasks, supplementing the
section-by-section reference above.

Sharing a Filtered Set of Reports with Other Group Members
  You're looking at a specific slice of the map — say, all report types
  over the past 14 days — and want someone else to see exactly the same
  picture. Report Library Export/Import (see REPORT LIBRARY above) moves
  report data between installs, but it doesn't carry your map's current
  view state with it, so matching what you see takes two parts: filter
  the export to match your view, then make sure the recipient's own view
  settings match too.
    1. Note what you're currently filtering on: which report types are
       checked under the View menu, and what Settings > General > Date
       Filter is set to (No Filter, Previous N Days, or a specific
       From/To span). "Previous N Days" always runs from today back
       (N-1) days — work out the actual calendar dates if you'll need
       them in step 3.
    2. File > Import/Export Reports > Export Report Library…
    3. In the filter dialog: choose All Types if every report type is
       currently showing (or pick one type to match a narrower view),
       and enter the same date span you noted in step 1.
    4. Click Next →, confirm the match count, then choose where to save
       the .reports.json file.
    5. Send the file to the other group members by whatever means you
       normally use (email, thumb drive, packet, etc.) — SitRepMapper
       has no built-in transfer.
    6. Each recipient: File > Import/Export Reports > Import Report
       Library…, and pick the file. This merges the reports into their
       own library — existing records are only overwritten if the
       incoming copy is newer, and anything they'd deliberately deleted
       stays deleted, with an offer to restore if the file contains it.
    7. Importing only adds to the library — it doesn't change what's
       displayed. For the recipient's map to actually look like yours,
       their own View menu report-type checkboxes and Settings >
       General > Date Filter need to match what you used in step 1.

Restoring a Deleted Flag Pin on Re-Import
  Deleting a flag pin, then later importing a file that still contains it
  (a stale export, a group member's file assembled before your delete, or
  anything similar) no longer silently drops it. If the import finds any
  matches, a "Previously Deleted Flag Pins Found" dialog lists them —
  Description, Grid, Group, and Updated — with every row pre-selected:
    Restore Selected — restores only the checked rows
    Restore All      — restores everything listed
    Skip             — leaves all of them deleted; the rest of the file
                        still imports normally
  A flag pin whose incoming copy is genuinely newer than your deletion
  (for example, someone else re-added it after you deleted your copy) is
  restored automatically without this prompt — the dialog only appears
  for the case that used to fail silently: an incoming copy the same age
  or older than your deletion.

Moving a Circle by Its Center
  Click-drag directly on a circle's center point (the crosshair, if
  shown, marks it) to move the whole circle to a new location — its
  radius stays fixed. If you release near another circle's center, the
  dragged circle snaps onto that circle's exact center instead of just
  landing close to it, so the two become perfectly concentric — a
  "bullseye." A brief click on the center (no real drag) opens the same
  Edit… / Delete popup as clicking anywhere else on the circle.

Moving a Whole Bullseye Together
  Hold Shift while dragging a circle's center to move every circle that
  shares that exact center as one group, each keeping its own radius.
  This also snaps: Shift-dragging one bullseye near another circle (or
  another bullseye) merges the whole group onto that circle's exact
  center.

Duplicating a Circle
  Right-click a circle and choose "Duplicate Circle" (or, from the stack
  picker described below, open a specific circle's popup and click
  Copy) to make an identical copy — same center, radius, color, and
  settings — stacked directly on top of the original. The new copy is
  the one the very next center-drag grabs, so you can drag it straight
  to where it should actually go. To duplicate a whole bullseye,
  duplicate each ring individually (each one restacks automatically) and
  then Shift-drag the new set into place in one move.

Working with Multiple Circles at One Center
  When two or more circles share the exact same center, a small numbered
  badge appears there showing how many. Clicking that spot opens a
  picker listing every circle at that location (most recently updated
  first) so you can choose exactly which one's Edit… / Delete / Copy
  popup to open, instead of always getting whichever is drawn on top.

  Note: a brand-new circle has "Show center crosshair on map" checked by
  default in the Add Area dialog, since the crosshair is the easiest way
  to see exactly where to grab it for the dragging described above.
  Editing an existing circle always keeps its own saved setting.

Reshaping a Rectangle or Polygon by Dragging
  An existing rectangle or polygon draws small square handle markers at
  each corner/vertex — drag one to reshape the area directly on the map
  instead of redrawing it from scratch:
    Rectangle corner:  drag to resize both adjacent sides at once; the
                       opposite corner stays fixed.
    Rectangle side:    drag to resize just that one dimension.
    Polygon vertex:    drag to reshape the polygon at that point (this
                       moves an existing vertex only — there's no
                       insert-a-new-vertex-on-an-edge gesture).


================================================================================
  End of SitRepMapper User Manual
  Designed and developed by Stephen Clay McGehee, KN4AM
  Coding done using Claude Code AI
  See SitRepNet.com for more information
================================================================================
