Modularize index.html with CSS and HTML partials

- Extract inline CSS to static/css/modes/ (acars, aprs, tscm)
- Create HTML partials for all 9 modes in templates/partials/modes/
- Reduce index.html from 11,862 to 10,281 lines (~15% reduction)
- Use Jinja2 includes for cleaner template organization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-01-14 20:07:38 +00:00
parent 7eba7dbaaa
commit f326be77cd
13 changed files with 11869 additions and 11862 deletions

View File

@@ -0,0 +1,121 @@
<!-- AIRCRAFT MODE (ADS-B) -->
<div id="aircraftMode" class="mode-content">
<div class="section">
<h3>ADS-B Receiver</h3>
<div class="form-group">
<label>Frequency</label>
<input type="text" id="adsbFrequency" value="1090" readonly style="opacity: 0.7;">
<div class="info-text">Fixed at 1090 MHz</div>
</div>
<div class="form-group">
<label>Gain (dB)</label>
<input type="text" id="adsbGain" value="40" placeholder="40">
</div>
<div class="checkbox-group">
<label>
<input type="checkbox" id="adsbEnableMap" checked onchange="toggleAircraftRadar()">
Show Radar Display
</label>
</div>
</div>
<div class="section">
<h3>Display Settings</h3>
<div class="form-group">
<label>Range (nm)</label>
<select id="adsbRange">
<option value="50">50 nm</option>
<option value="100" selected>100 nm</option>
<option value="200">200 nm</option>
<option value="500">500 nm</option>
</select>
</div>
<div class="checkbox-group">
<label>
<input type="checkbox" id="adsbShowLabels" checked>
Show Callsigns
</label>
<label>
<input type="checkbox" id="adsbShowAltitude" checked>
Show Altitude
</label>
<label>
<input type="checkbox" id="adsbShowTrails">
Show Flight Trails
</label>
<label>
<input type="checkbox" id="adsbEnableClustering" onchange="toggleAircraftClustering()">
Cluster Markers
</label>
<label>
<input type="checkbox" id="adsbShowRangeRings" checked onchange="drawRangeRings()">
Show Range Rings
</label>
</div>
<div class="form-group" style="margin-top: 10px;">
<label style="display: flex; align-items: center; gap: 8px;">
Observer Location
<span id="adsbGpsIndicator" class="gps-indicator" style="display: none;" title="GPS connected via gpsd">
<span class="gps-dot"></span> GPS
</span>
</label>
<div style="display: flex; gap: 5px;">
<input type="text" id="adsbObsLat" value="51.5074" placeholder="Latitude" style="flex: 1;" onchange="updateObserverLocation()">
<input type="text" id="adsbObsLon" value="-0.1278" placeholder="Longitude" style="flex: 1;" onchange="updateObserverLocation()">
</div>
<button class="preset-btn" id="adsbGeolocateBtn" onclick="getAdsbGeolocation()" style="width: 100%; margin-top: 5px;">
📍 Use Browser Location
</button>
</div>
<div class="form-group" style="margin-top: 10px;">
<label>Aircraft Filter</label>
<select id="adsbAircraftFilter" onchange="applyAircraftFilter()">
<option value="all">All Aircraft</option>
<option value="military">Military Only</option>
<option value="civil">Civil Only</option>
<option value="emergency">Emergency Only</option>
</select>
</div>
<div class="form-group" style="margin-top: 10px;">
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
<input type="checkbox" id="adsbAlertToggle" checked onchange="adsbAlertsEnabled = this.checked">
🔔 Audio Alerts (Military/Emergency)
</label>
</div>
</div>
<div class="section">
<h3>Reception Statistics</h3>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: 11px;">
<div style="background: rgba(0,212,255,0.1); padding: 8px; border-radius: 4px; text-align: center;">
<div style="color: var(--text-secondary); font-size: 9px; text-transform: uppercase;">Max Range</div>
<div id="adsbMaxRange" style="color: var(--accent-cyan); font-size: 14px; font-weight: bold;">0.0 nm</div>
</div>
<div style="background: rgba(0,212,255,0.1); padding: 8px; border-radius: 4px; text-align: center;">
<div style="color: var(--text-secondary); font-size: 9px; text-transform: uppercase;">Total Seen</div>
<div id="adsbTotalSeen" style="color: var(--accent-cyan); font-size: 14px; font-weight: bold;">0</div>
</div>
<div style="background: rgba(0,212,255,0.1); padding: 8px; border-radius: 4px; text-align: center;">
<div style="color: var(--text-secondary); font-size: 9px; text-transform: uppercase;">Msg Rate</div>
<div id="adsbMsgRate" style="color: var(--accent-cyan); font-size: 14px; font-weight: bold;">0.0/s</div>
</div>
<div style="background: rgba(0,212,255,0.1); padding: 8px; border-radius: 4px; text-align: center;">
<div style="color: var(--text-secondary); font-size: 9px; text-transform: uppercase;">Busiest Hour</div>
<div id="adsbBusiestHour" style="color: var(--accent-cyan); font-size: 14px; font-weight: bold;">--</div>
</div>
</div>
</div>
<div class="info-text" style="margin-top: 8px; display: grid; grid-template-columns: auto auto; gap: 4px 8px; align-items: center;" id="adsbToolStatus">
<span>dump1090:</span><span class="tool-status" id="dump1090Status">Checking...</span>
<span>rtl_adsb:</span><span class="tool-status" id="rtlAdsbStatus">Checking...</span>
</div>
<button class="run-btn" id="startAdsbBtn" onclick="startAdsbScan()">
Start Tracking
</button>
<button class="stop-btn" id="stopAdsbBtn" onclick="stopAdsbScan()" style="display: none;">
Stop Tracking
</button>
</div>

View File

@@ -0,0 +1,57 @@
<!-- APRS MODE -->
<div id="aprsMode" class="mode-content">
<div class="section">
<h3>APRS Tracking</h3>
<p style="color: var(--text-secondary); font-size: 11px; line-height: 1.5; margin-bottom: 15px;">
Decode APRS (Automatic Packet Reporting System) amateur radio position reports on VHF.
</p>
<div style="background: rgba(255,193,7,0.1); border: 1px solid var(--accent-yellow); border-radius: 4px; padding: 8px; margin-bottom: 10px; font-size: 10px;">
<strong style="color: var(--accent-yellow);">Amateur Radio</strong><br>
<span style="color: var(--text-secondary);">APRS operates on 144.390 MHz (N. America) or 144.800 MHz (Europe). Decodes position, weather, and messages from ham radio operators.</span>
</div>
</div>
<div class="section">
<h3>Configuration</h3>
<div class="form-group">
<label>Region</label>
<select id="aprsRegion">
<option value="north_america">North America (144.390)</option>
<option value="europe">Europe (144.800)</option>
<option value="australia">Australia (145.175)</option>
<option value="japan">Japan (144.640)</option>
</select>
</div>
<div class="form-group">
<label>SDR Device</label>
<select id="aprsDevice">
<option value="">Loading devices...</option>
</select>
</div>
<div class="form-group">
<label>Gain (dB)</label>
<input type="text" id="aprsGain" value="40" placeholder="40">
</div>
<div class="info-text" style="margin-top: 8px; display: grid; grid-template-columns: auto auto; gap: 4px 8px; align-items: center;">
<span>direwolf:</span><span class="tool-status" id="direwolfStatus">Checking...</span>
<span>multimon-ng:</span><span class="tool-status" id="aprsMultimonStatus">Checking...</span>
</div>
</div>
<button class="run-btn" id="startAprsBtn" onclick="startAprs()">
Start APRS
</button>
<button class="stop-btn" id="stopAprsBtn" onclick="stopAprs()" style="display: none;">
Stop APRS
</button>
<!-- APRS Status Bar -->
<div id="aprsStatusBar" class="aprs-status-bar" style="display: none;">
<div class="aprs-status-indicator">
<span class="aprs-status-dot" id="aprsStatusDot"></span>
<span class="aprs-status-text" id="aprsStatusText">STANDBY</span>
</div>
<div class="aprs-status-stats">
<span class="aprs-stat"><span class="aprs-stat-label">FREQ:</span> <span id="aprsStatusFreq">--</span></span>
<span class="aprs-stat"><span class="aprs-stat-label">STATIONS:</span> <span id="aprsStatusStations">0</span></span>
<span class="aprs-stat"><span class="aprs-stat-label">PACKETS:</span> <span id="aprsStatusPackets">0</span></span>
</div>
</div>
</div>

View File

@@ -0,0 +1,70 @@
<!-- BLUETOOTH MODE -->
<div id="bluetoothMode" class="mode-content">
<div class="section">
<h3>Bluetooth Interface</h3>
<div class="form-group">
<select id="btInterfaceSelect">
<option value="">Detecting interfaces...</option>
</select>
</div>
<button class="preset-btn" onclick="refreshBtInterfaces()" style="width: 100%;">
Refresh Interfaces
</button>
<div class="info-text" style="margin-top: 8px; display: grid; grid-template-columns: auto auto; gap: 4px 8px; align-items: center;" id="btToolStatus">
<span>hcitool:</span><span class="tool-status missing">Checking...</span>
<span>bluetoothctl:</span><span class="tool-status missing">Checking...</span>
</div>
</div>
<div class="section">
<h3>Scan Mode</h3>
<div class="checkbox-group" style="margin-bottom: 10px;">
<label><input type="radio" name="btScanMode" value="bluetoothctl" checked> bluetoothctl (Recommended)</label>
<label><input type="radio" name="btScanMode" value="hcitool"> hcitool (Legacy)</label>
</div>
<div class="form-group">
<label>Scan Duration (sec)</label>
<input type="text" id="btScanDuration" value="30" placeholder="30">
</div>
<div class="checkbox-group">
<label>
<input type="checkbox" id="btScanBLE" checked>
Scan BLE Devices
</label>
<label>
<input type="checkbox" id="btScanClassic" checked>
Scan Classic BT
</label>
<label>
<input type="checkbox" id="btDetectBeacons" checked>
Detect Trackers (AirTag/Tile)
</label>
</div>
</div>
<div class="section">
<h3>Device Actions</h3>
<div class="form-group">
<label>Target MAC</label>
<input type="text" id="btTargetMac" placeholder="AA:BB:CC:DD:EE:FF">
</div>
<button class="preset-btn" onclick="btEnumServices()" style="width: 100%;">
Enumerate Services
</button>
</div>
<!-- Tracker Following Alert -->
<div id="trackerFollowingAlert" class="tracker-following-alert" style="display: none;">
<!-- Populated by JavaScript -->
</div>
<button class="run-btn" id="startBtBtn" onclick="startBtScan()">
Start Scanning
</button>
<button class="stop-btn" id="stopBtBtn" onclick="stopBtScan()" style="display: none;">
Stop Scanning
</button>
<button class="preset-btn" onclick="resetBtAdapter()" style="margin-top: 5px; width: 100%;">
Reset Adapter
</button>
</div>

View File

@@ -0,0 +1,49 @@
<!-- LISTENING POST MODE -->
<div id="listeningPostMode" class="mode-content">
<div class="section">
<h3>Status</h3>
<!-- Dependency Warning -->
<div id="scannerToolsWarning" style="display: none; background: rgba(255, 100, 100, 0.1); border: 1px solid var(--accent-red); border-radius: 4px; padding: 10px; margin-bottom: 10px;">
<p style="color: var(--accent-red); margin: 0; font-size: 0.85em;">
<strong>Missing:</strong><br>
<span id="scannerToolsWarningText"></span>
</p>
</div>
<!-- Quick Status -->
<div style="background: rgba(0,0,0,0.3); border-radius: 6px; padding: 12px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
<span style="font-size: 10px; color: var(--text-muted); text-transform: uppercase;">Status</span>
<span id="lpQuickStatus" style="font-size: 11px; color: var(--accent-cyan);">IDLE</span>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
<span style="font-size: 10px; color: var(--text-muted); text-transform: uppercase;">Frequency</span>
<span id="lpQuickFreq" style="font-size: 14px; font-family: 'JetBrains Mono', monospace; color: var(--text-primary);">---.--- MHz</span>
</div>
<div style="display: flex; justify-content: space-between; align-items: center;">
<span style="font-size: 10px; color: var(--text-muted); text-transform: uppercase;">Signals</span>
<span id="lpQuickSignals" style="font-size: 14px; font-weight: bold; color: var(--accent-green);">0</span>
</div>
</div>
</div>
<div class="section">
<h3>Bookmarks</h3>
<div style="display: flex; gap: 4px; margin-bottom: 8px;">
<input type="text" id="bookmarkFreqInput" placeholder="Freq (MHz)" style="flex: 1; padding: 6px; background: var(--bg-secondary); border: 1px solid var(--border-color); color: var(--text-primary); border-radius: 4px; font-size: 11px;">
<button class="preset-btn" onclick="addFrequencyBookmark()" style="background: var(--accent-green); color: #000; padding: 6px 10px;">+</button>
</div>
<div id="bookmarksList" style="max-height: 150px; overflow-y: auto; font-size: 11px;">
<div style="color: var(--text-muted); text-align: center; padding: 10px;">No bookmarks saved</div>
</div>
</div>
<div class="section">
<h3>Recent Signals</h3>
<div id="sidebarRecentSignals" style="max-height: 150px; overflow-y: auto; font-size: 11px;">
<div style="color: var(--text-muted); text-align: center; padding: 10px;">No signals yet</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,84 @@
<!-- PAGER MODE -->
<div id="pagerMode" class="mode-content active">
<div class="section">
<h3>Frequency</h3>
<div class="form-group">
<label>Frequency (MHz)</label>
<input type="text" id="frequency" value="153.350" placeholder="e.g., 153.350">
</div>
<div class="preset-buttons" id="presetButtons">
<!-- Populated by JavaScript -->
</div>
<div style="margin-top: 8px; display: flex; gap: 5px;">
<input type="text" id="newPresetFreq" placeholder="New freq (MHz)" style="flex: 1; padding: 6px; background: #0f3460; border: 1px solid #1a1a2e; color: #fff; border-radius: 4px; font-size: 12px;">
<button class="preset-btn" onclick="addPreset()" style="background: #2ecc71;">Add</button>
</div>
<div style="margin-top: 5px;">
<button class="preset-btn" onclick="resetPresets()" style="font-size: 11px;">Reset to Defaults</button>
</div>
</div>
<div class="section">
<h3>Protocols</h3>
<div class="checkbox-group">
<label><input type="checkbox" id="proto_pocsag512" checked> POCSAG-512</label>
<label><input type="checkbox" id="proto_pocsag1200" checked> POCSAG-1200</label>
<label><input type="checkbox" id="proto_pocsag2400" checked> POCSAG-2400</label>
<label><input type="checkbox" id="proto_flex" checked> FLEX</label>
</div>
</div>
<div class="section">
<h3>Settings</h3>
<div class="form-group">
<label>Gain (dB, 0 = auto)</label>
<input type="text" id="gain" value="0" placeholder="0-49 or 0 for auto">
</div>
<div class="form-group">
<label>Squelch Level</label>
<input type="text" id="squelch" value="0" placeholder="0 = off">
</div>
<div class="form-group">
<label>PPM Correction</label>
<input type="text" id="ppm" value="0" placeholder="Frequency correction">
</div>
</div>
<div class="section">
<h3>Logging</h3>
<div class="checkbox-group" style="margin-bottom: 15px;">
<label>
<input type="checkbox" id="loggingEnabled" onchange="toggleLogging()">
Enable Logging
</label>
</div>
<div class="form-group">
<label>Log file path</label>
<input type="text" id="logFilePath" value="pager_messages.log" placeholder="pager_messages.log">
</div>
</div>
<div class="section">
<h3>Message Filters</h3>
<div class="checkbox-group" style="margin-bottom: 10px;">
<label>
<input type="checkbox" id="filterToneOnly" checked onchange="savePagerFilters()">
Hide "Tone Only" messages
</label>
</div>
<div class="form-group">
<label>Hide messages containing (comma-separated)</label>
<input type="text" id="filterKeywords" placeholder="e.g. test, spam, alert" onchange="savePagerFilters()">
</div>
<div class="info-text" style="font-size: 10px; color: #666; margin-top: 5px;">
Messages matching these keywords will be hidden from display but still logged.
</div>
</div>
<button class="run-btn" id="startBtn" onclick="startDecoding()">
Start Decoding
</button>
<button class="stop-btn" id="stopBtn" onclick="stopDecoding()" style="display: none;">
Stop Decoding
</button>
</div>

View File

@@ -0,0 +1,50 @@
<!-- SATELLITE MODE -->
<div id="satelliteMode" class="mode-content">
<div class="section">
<h3>Satellite Command</h3>
<p style="color: var(--text-secondary); font-size: 11px; line-height: 1.5; margin-bottom: 15px;">
Full satellite tracking dashboard with polar plot, ground track map, pass predictions, and live telemetry.
</p>
<a href="/satellite/dashboard" target="_blank" class="preset-btn" style="display: block; text-align: center; text-decoration: none; width: 100%; margin-bottom: 10px;">
Open in New Window
</a>
</div>
<div class="section">
<h3>Satellite Database</h3>
<p style="color: var(--text-secondary); font-size: 11px; margin-bottom: 10px;">
Add satellites via TLE data or fetch from Celestrak.
</p>
<div style="display: flex; flex-direction: column; gap: 8px;">
<button class="preset-btn" onclick="showAddSatelliteModal()" style="width: 100%;">
Add Satellite (TLE)
</button>
<button class="preset-btn" onclick="fetchCelestrak()" style="width: 100%;">
Update from Celestrak
</button>
</div>
<div style="margin-top: 10px; padding: 8px; background: rgba(0,0,0,0.2); border-radius: 4px;">
<div style="font-size: 10px; color: var(--text-muted); margin-bottom: 6px;">TRACKED SATELLITES</div>
<div id="satTrackingList" style="font-size: 11px; color: var(--text-secondary); max-height: 120px; overflow-y: auto;">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 4px;">
<span>ISS (ZARYA)</span>
<span>NOAA 15</span>
<span>NOAA 18</span>
<span>NOAA 19</span>
<span>NOAA 20</span>
<span>METEOR-M2</span>
<span>METEOR-M2-3</span>
</div>
</div>
</div>
</div>
<div class="section">
<h3>Quick Info</h3>
<div style="font-size: 11px; color: var(--text-secondary); line-height: 1.6;">
<p><strong>Polar Plot:</strong> Shows satellite path across the sky. Center = overhead, edge = horizon.</p>
<p style="margin-top: 8px;"><strong>Ground Track:</strong> Real-time satellite position and orbital path on world map.</p>
<p style="margin-top: 8px;"><strong>Pass Quality:</strong> Excellent (60°+), Good (30°+), Fair (below 30°).</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,48 @@
<!-- 433MHz SENSOR MODE -->
<div id="sensorMode" class="mode-content">
<div class="section">
<h3>Frequency</h3>
<div class="form-group">
<label>Frequency (MHz)</label>
<input type="text" id="sensorFrequency" value="433.92" placeholder="e.g., 433.92">
</div>
<div class="preset-buttons">
<button class="preset-btn" onclick="setSensorFreq('433.92')">433.92</button>
<button class="preset-btn" onclick="setSensorFreq('315.00')">315.00</button>
<button class="preset-btn" onclick="setSensorFreq('868.00')">868.00</button>
<button class="preset-btn" onclick="setSensorFreq('915.00')">915.00</button>
</div>
</div>
<div class="section">
<h3>Settings</h3>
<div class="form-group">
<label>Gain (dB, 0 = auto)</label>
<input type="text" id="sensorGain" value="0" placeholder="0-49 or 0 for auto">
</div>
<div class="form-group">
<label>PPM Correction</label>
<input type="text" id="sensorPpm" value="0" placeholder="Frequency correction">
</div>
</div>
<div class="section">
<h3>Protocols</h3>
<div class="info-text" style="margin-bottom: 10px;">
rtl_433 auto-detects 200+ device protocols including weather stations, TPMS, doorbells, and more.
</div>
<div class="checkbox-group">
<label>
<input type="checkbox" id="sensorLogging" onchange="toggleSensorLogging()">
Enable Logging
</label>
</div>
</div>
<button class="run-btn" id="startSensorBtn" onclick="startSensorDecoding()">
Start Listening
</button>
<button class="stop-btn" id="stopSensorBtn" onclick="stopSensorDecoding()" style="display: none;">
Stop Listening
</button>
</div>

View File

@@ -0,0 +1,103 @@
<!-- TSCM MODE (Counter-Surveillance) -->
<div id="tscmMode" class="mode-content">
<div class="section">
<h3 style="display: flex; align-items: center; gap: 8px;">TSCM Sweep <span style="font-size: 9px; font-weight: normal; background: var(--accent-orange); color: #000; padding: 2px 6px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.5px;">Alpha</span></h3>
<div class="form-group">
<label>Sweep Type</label>
<select id="tscmSweepType">
<option value="quick">Quick Scan (2 min)</option>
<option value="standard" selected>Standard (5 min)</option>
<option value="full">Full Sweep (15 min)</option>
<option value="wireless_cameras">Wireless Cameras</option>
<option value="body_worn">Body-Worn Devices</option>
<option value="gps_trackers">GPS Trackers</option>
</select>
</div>
<div class="form-group">
<label>Compare Against</label>
<select id="tscmBaselineSelect">
<option value="">No Baseline</option>
</select>
</div>
</div>
<div class="section">
<h3>Scan Sources</h3>
<div class="form-group" style="margin-bottom: 8px;">
<div style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="tscmWifiEnabled" checked style="margin: 0;">
<label for="tscmWifiEnabled" style="flex: 1; margin: 0;">WiFi Networks</label>
</div>
<select id="tscmWifiInterface" style="width: 100%; margin-top: 4px; font-size: 11px;">
<option value="">Select WiFi interface...</option>
</select>
</div>
<div class="form-group" style="margin-bottom: 8px;">
<div style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="tscmBtEnabled" checked style="margin: 0;">
<label for="tscmBtEnabled" style="flex: 1; margin: 0;">Bluetooth Devices</label>
</div>
<select id="tscmBtInterface" style="width: 100%; margin-top: 4px; font-size: 11px;">
<option value="">Select Bluetooth adapter...</option>
</select>
</div>
<div class="form-group" style="margin-bottom: 8px;">
<div style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="tscmRfEnabled" style="margin: 0;">
<label for="tscmRfEnabled" style="flex: 1; margin: 0;">RF Signals</label>
</div>
<select id="tscmSdrDevice" style="width: 100%; margin-top: 4px; font-size: 11px;">
<option value="">Select SDR device...</option>
</select>
</div>
<button class="preset-btn" onclick="refreshTscmDevices()" style="width: 100%; margin-top: 8px; font-size: 10px;">
🔄 Refresh Devices
</button>
</div>
<div class="section">
<h3>Baseline Management</h3>
<div class="form-group">
<input type="text" id="tscmBaselineName" placeholder="Baseline name...">
</div>
<button class="run-btn" id="tscmRecordBaselineBtn" onclick="tscmRecordBaseline()" style="width: 100%; padding: 8px;">
Record New Baseline
</button>
<button class="stop-btn" id="tscmStopBaselineBtn" onclick="tscmStopBaseline()" style="width: 100%; padding: 8px; display: none;">
Stop Recording
</button>
<div id="tscmBaselineStatus" style="margin-top: 8px; font-size: 11px; color: var(--text-muted);"></div>
</div>
<button class="run-btn" id="startTscmBtn" onclick="startTscmSweep()">
Start Sweep
</button>
<button class="stop-btn" id="stopTscmBtn" onclick="stopTscmSweep()" style="display: none;">
Stop Sweep
</button>
<!-- Futuristic Scanner Progress -->
<div id="tscmProgress" class="tscm-scanner-progress" style="display: none;">
<div class="scanner-ring">
<svg viewBox="0 0 100 100">
<circle class="scanner-track" cx="50" cy="50" r="45" />
<circle class="scanner-progress" id="tscmScannerCircle" cx="50" cy="50" r="45" />
<line class="scanner-sweep" x1="50" y1="50" x2="50" y2="8" />
</svg>
<div class="scanner-center">
<span class="scanner-percent" id="tscmProgressPercent">0%</span>
</div>
</div>
<div class="scanner-info">
<div class="scanner-status" id="tscmProgressLabel">INITIALIZING</div>
<div class="scanner-devices">
<span class="device-indicator" id="tscmWifiIndicator" title="WiFi">📶</span>
<span class="device-indicator" id="tscmBtIndicator" title="Bluetooth">🔵</span>
<span class="device-indicator" id="tscmRfIndicator" title="RF/SDR">📡</span>
</div>
</div>
</div>
<!-- Device Warnings -->
<div id="tscmDeviceWarnings" style="display: none; margin-top: 8px; padding: 8px; background: rgba(255,153,51,0.1); border: 1px solid rgba(255,153,51,0.3); border-radius: 4px;"></div>
</div>

View File

@@ -0,0 +1,142 @@
<!-- WiFi MODE -->
<div id="wifiMode" class="mode-content">
<div class="section">
<h3>WiFi Adapter</h3>
<div class="form-group">
<label>Select Device</label>
<select id="wifiInterfaceSelect" style="font-size: 12px;">
<option value="">Detecting interfaces...</option>
</select>
</div>
<button class="preset-btn" onclick="refreshWifiInterfaces()" style="width: 100%;">
🔄 Refresh Devices
</button>
<div class="info-text" style="margin-top: 8px; display: grid; grid-template-columns: auto auto; gap: 4px 8px; align-items: center;" id="wifiToolStatus">
<span>airmon-ng:</span><span class="tool-status missing">Checking...</span>
<span>airodump-ng:</span><span class="tool-status missing">Checking...</span>
</div>
</div>
<div class="section">
<h3>Monitor Mode</h3>
<div style="display: flex; gap: 8px;">
<button class="preset-btn" id="monitorStartBtn" onclick="enableMonitorMode()" style="flex: 1; background: var(--accent-green); color: #000;">
Enable Monitor
</button>
<button class="preset-btn" id="monitorStopBtn" onclick="disableMonitorMode()" style="flex: 1; display: none;">
Disable Monitor
</button>
</div>
<div class="checkbox-group" style="margin-top: 8px;">
<label style="font-size: 10px;">
<input type="checkbox" id="killProcesses">
Kill interfering processes (may drop other connections)
</label>
</div>
<div id="monitorStatus" class="info-text" style="margin-top: 8px;">
Monitor mode: <span style="color: var(--accent-red);">Inactive</span>
</div>
</div>
<div class="section">
<h3>Scan Settings</h3>
<div class="form-group">
<label>Band</label>
<select id="wifiBand">
<option value="abg">All (2.4 + 5 GHz)</option>
<option value="bg">2.4 GHz only</option>
<option value="a">5 GHz only</option>
</select>
</div>
<div class="form-group">
<label>Channel (empty = hop)</label>
<input type="text" id="wifiChannel" placeholder="e.g., 6 or 36">
</div>
</div>
<div class="section">
<h3>Proximity Alerts</h3>
<div class="info-text" style="margin-bottom: 8px;">
Alert when specific MAC addresses appear
</div>
<div class="form-group">
<input type="text" id="watchMacInput" placeholder="AA:BB:CC:DD:EE:FF">
</div>
<button class="preset-btn" onclick="addWatchMac()" style="width: 100%; margin-bottom: 8px;">
Add to Watch List
</button>
<div id="watchList" style="max-height: 80px; overflow-y: auto; font-size: 10px; color: var(--text-dim);"></div>
</div>
<div class="section">
<h3>Attack Options</h3>
<div class="info-text" style="color: var(--accent-red); margin-bottom: 10px;">
⚠ Only use on authorized networks
</div>
<div class="form-group">
<label>Target BSSID</label>
<input type="text" id="targetBssid" placeholder="AA:BB:CC:DD:EE:FF">
</div>
<div class="form-group">
<label>Target Client (optional)</label>
<input type="text" id="targetClient" placeholder="FF:FF:FF:FF:FF:FF (broadcast)">
</div>
<div class="form-group">
<label>Deauth Count</label>
<input type="text" id="deauthCount" value="5" placeholder="5">
</div>
<button class="preset-btn" onclick="sendDeauth()" style="width: 100%; border-color: var(--accent-red); color: var(--accent-red);">
Send Deauth
</button>
</div>
<!-- Handshake Capture Status Panel -->
<div class="section" id="captureStatusPanel" style="display: none; border: 1px solid var(--accent-orange); border-radius: 4px; padding: 10px; background: rgba(255, 165, 0, 0.1);">
<h3 style="color: var(--accent-orange); margin: 0 0 8px 0;">🎯 Handshake Capture</h3>
<div style="font-size: 11px;">
<div style="margin-bottom: 4px;">
<span style="color: var(--text-dim);">Target:</span>
<span id="captureTargetBssid" style="font-family: monospace;">--</span>
</div>
<div style="margin-bottom: 4px;">
<span style="color: var(--text-dim);">Channel:</span>
<span id="captureTargetChannel">--</span>
</div>
<div style="margin-bottom: 4px;">
<span style="color: var(--text-dim);">File:</span>
<span id="captureFilePath" style="font-size: 9px; word-break: break-all;">--</span>
</div>
<div style="margin-bottom: 8px;">
<span style="color: var(--text-dim);">Status:</span>
<span id="captureStatus" style="font-weight: bold;">--</span>
</div>
<div style="display: flex; gap: 8px;">
<button class="preset-btn" onclick="checkCaptureStatus()" style="flex: 1; font-size: 10px; padding: 4px;">
Check Status
</button>
<button class="preset-btn" onclick="stopHandshakeCapture()" style="flex: 1; font-size: 10px; padding: 4px; background: var(--accent-red); border: none; color: #fff;">
Stop Capture
</button>
</div>
</div>
</div>
<!-- Beacon Flood Alert Panel -->
<div id="beaconFloodAlert" class="beacon-flood-alert" style="display: none;">
<h4 style="color: #ff4444; margin: 0 0 8px 0;">⚠️ BEACON FLOOD DETECTED</h4>
<div style="font-size: 11px;">
<div id="beaconFloodDetails">Multiple beacon frames detected from same channel</div>
<div style="margin-top: 8px;">
<span style="color: var(--text-dim);">Networks/sec:</span>
<span id="beaconFloodRate" style="font-weight: bold; color: #ff4444;">--</span>
</div>
</div>
</div>
<button class="run-btn" id="startWifiBtn" onclick="startWifiScan()">
Start Scanning
</button>
<button class="stop-btn" id="stopWifiBtn" onclick="stopWifiScan()" style="display: none;">
Stop Scanning
</button>
</div>