main cd20f871ce51 cached
1261 files
53.5 MB
14.1M tokens
8037 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (56,340K chars total). Download the full file to get everything.
Repository: alireza787b/mavsdk_drone_show
Branch: main
Commit: cd20f871ce51
Files: 1261
Total size: 53.5 MB

Directory structure:
gitextract_nw1rprxl/

├── .github/
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── RELEASE_TEMPLATE.md
│   └── workflows/
│       ├── pr-validation.yml
│       └── release.yml
├── .gitignore
├── AGENTS.md
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── DISCLAIMER.md
├── ETHICAL-USE.md
├── GEMINI.md
├── LICENSE
├── LICENSE-COMMERCIAL.md
├── LICENSE-NONCOMMERCIAL.md
├── LICENSE-SMALL-BUSINESS.md
├── Makefile
├── NOTICE
├── README.md
├── VERSION
├── actions.py
├── app/
│   ├── dashboard/
│   │   └── drone-dashboard/
│   │       ├── .build_hash
│   │       ├── .gitignore
│   │       ├── FIELD_NAMING_STANDARD.md
│   │       ├── README.md
│   │       ├── download-raw-show
│   │       ├── package.json
│   │       ├── public/
│   │       │   ├── index.html
│   │       │   ├── manifest.json
│   │       │   └── robots.txt
│   │       └── src/
│   │           ├── App.css
│   │           ├── App.js
│   │           ├── App.test.js
│   │           ├── __mocks__/
│   │           │   └── styleMock.js
│   │           ├── assets/
│   │           │   └── compass-rose.psd
│   │           ├── components/
│   │           │   ├── BriefingExport.js
│   │           │   ├── ClusterScopeBar.js
│   │           │   ├── CommandPreflightSummary.js
│   │           │   ├── CommandSender.js
│   │           │   ├── CommandSender.test.js
│   │           │   ├── ControlButtons.js
│   │           │   ├── ControlButtons.test.js
│   │           │   ├── CurrentTime.js
│   │           │   ├── DeviationView.js
│   │           │   ├── DroneActions.js
│   │           │   ├── DroneActions.test.js
│   │           │   ├── DroneCard.js
│   │           │   ├── DroneConfigCard.js
│   │           │   ├── DroneConfigCard.test.js
│   │           │   ├── DroneCriticalCommands.js
│   │           │   ├── DroneCriticalCommands.test.js
│   │           │   ├── DroneDetail.js
│   │           │   ├── DroneGitStatus.js
│   │           │   ├── DroneGitStatus.test.js
│   │           │   ├── DroneGraph.js
│   │           │   ├── DronePositionMap.js
│   │           │   ├── DronePositionMap.test.js
│   │           │   ├── DroneReadinessReport.js
│   │           │   ├── DroneReadinessReport.test.js
│   │           │   ├── DroneWidget.js
│   │           │   ├── DroneWidget.test.js
│   │           │   ├── Environment.js
│   │           │   ├── ErrorBoundary.js
│   │           │   ├── ErrorBoundary.test.js
│   │           │   ├── ExpandedDronePortal.js
│   │           │   ├── ExportSection.js
│   │           │   ├── GitInfo.js
│   │           │   ├── Globe.js
│   │           │   ├── GlobeControlBox.js
│   │           │   ├── GlobeMapView.js
│   │           │   ├── Header.js
│   │           │   ├── IdentityDoctrineStrip.js
│   │           │   ├── ImportSection.js
│   │           │   ├── InfoHint.js
│   │           │   ├── InitialLaunchPlot.js
│   │           │   ├── MapSelector.js
│   │           │   ├── MissionCard.js
│   │           │   ├── MissionDetails.js
│   │           │   ├── MissionDetails.test.js
│   │           │   ├── MissionLayout.js
│   │           │   ├── MissionLayout.test.js
│   │           │   ├── MissionReadinessCard.js
│   │           │   ├── MissionReadinessCard.test.js
│   │           │   ├── MissionTrigger.js
│   │           │   ├── MissionTrigger.test.js
│   │           │   ├── OriginModal.js
│   │           │   ├── PositionTabs.js
│   │           │   ├── PrecisionMoveDialog.js
│   │           │   ├── PrecisionMoveDialog.test.js
│   │           │   ├── RouteDocsShortcut.js
│   │           │   ├── RuntimeModeBadge.js
│   │           │   ├── SaveReviewDialog.js
│   │           │   ├── SaveReviewDialog.test.js
│   │           │   ├── SidebarMenu.js
│   │           │   ├── SidebarMenu.test.js
│   │           │   ├── SwarmPlots.js
│   │           │   ├── SwarmRuntimeControls.js
│   │           │   ├── SwarmRuntimeControls.test.js
│   │           │   ├── SyncWarningBanner.js
│   │           │   ├── TacticalDroneCard.js
│   │           │   ├── TacticalDroneCard.test.js
│   │           │   ├── ThemeToggle.js
│   │           │   ├── TimePicker.js
│   │           │   ├── VisualizationSection.js
│   │           │   ├── logs/
│   │           │   │   ├── LogActiveFilters.js
│   │           │   │   ├── LogExportDialog.js
│   │           │   │   ├── LogHealthBar.js
│   │           │   │   ├── LogLiveIndicator.js
│   │           │   │   ├── LogRowDetail.js
│   │           │   │   ├── LogRowDetail.test.js
│   │           │   │   ├── LogSessionSelector.js
│   │           │   │   ├── LogSourceTree.js
│   │           │   │   ├── LogTable.js
│   │           │   │   ├── LogViewerToolbar.js
│   │           │   │   ├── LogViewerToolbar.test.js
│   │           │   │   ├── OnboardUlogDialog.js
│   │           │   │   └── OnboardUlogDialog.test.js
│   │           │   ├── map/
│   │           │   │   ├── LeafletCoveragePreview.js
│   │           │   │   ├── LeafletDrawControl.js
│   │           │   │   ├── LeafletFindingMarkers.js
│   │           │   │   ├── LeafletMapBase.js
│   │           │   │   ├── MapFallbackBanner.js
│   │           │   │   ├── MapProviderToggle.js
│   │           │   │   └── ViewModeToggle.js
│   │           │   ├── missionConfig/
│   │           │   │   ├── MissionConfigAlertStack.js
│   │           │   │   ├── MissionConfigToolbar.js
│   │           │   │   └── PendingEnrollmentPanel.js
│   │           │   ├── px4/
│   │           │   │   ├── Px4ParamInspector.js
│   │           │   │   ├── Px4ParamInspector.test.js
│   │           │   │   └── Px4ParamProfilePanel.js
│   │           │   ├── sar/
│   │           │   │   ├── CoveragePreview.js
│   │           │   │   ├── DroneStatusCard.js
│   │           │   │   ├── DroneStatusCard.test.js
│   │           │   │   ├── FindingMarkerSystem.js
│   │           │   │   ├── FindingReviewPanel.js
│   │           │   │   ├── FindingReviewPanel.test.js
│   │           │   │   ├── MissionActionBar.js
│   │           │   │   ├── MissionActionBar.test.js
│   │           │   │   ├── MissionHandoffPanel.js
│   │           │   │   ├── MissionHandoffPanel.test.js
│   │           │   │   ├── MissionMonitorSidebar.js
│   │           │   │   ├── MissionMonitorSidebar.test.js
│   │           │   │   ├── MissionPlanSidebar.js
│   │           │   │   ├── MissionRecoveryPanel.js
│   │           │   │   ├── MissionStatsBar.js
│   │           │   │   ├── MissionStatsBar.test.js
│   │           │   │   ├── PlanMonitorToggle.js
│   │           │   │   ├── QuickScoutLaunchReview.js
│   │           │   │   ├── QuickScoutLaunchReview.test.js
│   │           │   │   └── SearchAreaDrawer.js
│   │           │   ├── trajectory/
│   │           │   │   ├── SearchBar.js
│   │           │   │   ├── SwarmTrajectoryTransferDialog.js
│   │           │   │   ├── SwarmTrajectoryTransferDialog.test.js
│   │           │   │   ├── SwarmTrajectoryWorkspaceSummary.js
│   │           │   │   ├── SwarmTrajectoryWorkspaceSummary.test.js
│   │           │   │   ├── TrajectoryExportDialog.js
│   │           │   │   ├── TrajectoryExportDialog.test.js
│   │           │   │   ├── TrajectoryLibraryDialog.js
│   │           │   │   ├── TrajectoryLibraryDialog.test.js
│   │           │   │   ├── TrajectoryPolicyNotes.js
│   │           │   │   ├── TrajectorySegmentReview.js
│   │           │   │   ├── TrajectorySegmentReview.test.js
│   │           │   │   ├── TrajectoryStats.js
│   │           │   │   ├── TrajectoryStats.test.js
│   │           │   │   ├── TrajectoryToolbar.js
│   │           │   │   ├── TrajectoryToolbar.test.js
│   │           │   │   ├── WaypointModal.js
│   │           │   │   ├── WaypointModal.test.js
│   │           │   │   ├── WaypointPanel.js
│   │           │   │   └── WaypointPanel.test.js
│   │           │   └── ui/
│   │           │       ├── OperatorPrimitives.js
│   │           │       ├── OperatorPrimitives.test.js
│   │           │       └── index.js
│   │           ├── config/
│   │           │   ├── apiConfig.js
│   │           │   ├── mapConfig.js
│   │           │   ├── mapConfig.test.js
│   │           │   ├── routeDocs.js
│   │           │   └── routeDocs.test.js
│   │           ├── constants/
│   │           │   ├── droneConstants.js
│   │           │   ├── droneStates.js
│   │           │   ├── fieldMappings.js
│   │           │   ├── flightModes.js.deprecated
│   │           │   ├── logConstants.js
│   │           │   ├── mavModeEnum.js.deprecated
│   │           │   ├── px4FlightModes.js
│   │           │   ├── trajectoryMissionPolicy.js
│   │           │   └── trajectoryMissionPolicy.test.js
│   │           ├── contexts/
│   │           │   ├── AuthContext.js
│   │           │   ├── CommandActivityContext.js
│   │           │   ├── CommandActivityContext.test.js
│   │           │   ├── MapContext.js
│   │           │   ├── ThemeContext.js
│   │           │   └── ThemeContext.test.js
│   │           ├── hooks/
│   │           │   ├── useComputeOrigin.js
│   │           │   ├── useFetch.js
│   │           │   ├── useGcsGitInfo.js
│   │           │   ├── useGcsRuntimeStatus.js
│   │           │   ├── useLogStream.js
│   │           │   ├── useLogStream.test.js
│   │           │   ├── useNormalizedTelemetry.js
│   │           │   ├── useSwarmClusterStatus.js
│   │           │   ├── useSyncDrones.js
│   │           │   └── useTheme.js
│   │           ├── index.css
│   │           ├── index.js
│   │           ├── pages/
│   │           │   ├── CustomShowPage.js
│   │           │   ├── DroneShowDesign.js
│   │           │   ├── EnvironmentsPage.js
│   │           │   ├── EnvironmentsPage.test.js
│   │           │   ├── FleetEnrollmentPage.js
│   │           │   ├── FleetEnrollmentPage.test.js
│   │           │   ├── FleetOpsPage.js
│   │           │   ├── FleetOpsPage.test.js
│   │           │   ├── GlobeView.js
│   │           │   ├── GlobeView.test.js
│   │           │   ├── LogViewer.js
│   │           │   ├── LoginPage.js
│   │           │   ├── ManageDroneShow.js
│   │           │   ├── MissionConfig.js
│   │           │   ├── MissionConfig.test.js
│   │           │   ├── Overview.js
│   │           │   ├── Overview.test.js
│   │           │   ├── Px4ParametersPage.js
│   │           │   ├── Px4ParametersPage.test.js
│   │           │   ├── QuickScoutPage.js
│   │           │   ├── QuickScoutPage.test.js
│   │           │   ├── RuntimeAdminPage.js
│   │           │   ├── RuntimeAdminPage.test.js
│   │           │   ├── SitlControlPage.js
│   │           │   ├── SitlControlPage.test.js
│   │           │   ├── SwarmDesign.js
│   │           │   ├── SwarmDesign.test.js
│   │           │   ├── SwarmTrajectory.js
│   │           │   ├── SwarmTrajectory.test.js
│   │           │   ├── TrajectoryPlanning.js
│   │           │   └── TrajectoryPlanning.test.js
│   │           ├── services/
│   │           │   ├── ElevationService.js
│   │           │   ├── TerrainService.js
│   │           │   ├── apiError.js
│   │           │   ├── droneApiService.js
│   │           │   ├── droneApiService.test.js
│   │           │   ├── fleetEnrollmentApiService.js
│   │           │   ├── fleetEnrollmentApiService.test.js
│   │           │   ├── gcsApiService.js
│   │           │   ├── gcsApiService.test.js
│   │           │   ├── logService.js
│   │           │   ├── logService.test.js
│   │           │   ├── px4ParamsApiService.js
│   │           │   ├── px4ParamsApiService.test.js
│   │           │   ├── sarApiService.js
│   │           │   ├── sarApiService.test.js
│   │           │   ├── sitlControlService.js
│   │           │   └── sitlControlService.test.js
│   │           ├── setupTests.js
│   │           ├── styles/
│   │           │   ├── BriefingExport.css
│   │           │   ├── ClusterScopeBar.css
│   │           │   ├── CommandSender.css
│   │           │   ├── ControlButtons.css
│   │           │   ├── CurrentTime.css
│   │           │   ├── CustomShowPage.css
│   │           │   ├── DesignTokens.css
│   │           │   ├── DeviationView.css
│   │           │   ├── DroneActions.css
│   │           │   ├── DroneCard.css
│   │           │   ├── DroneConfigCard.css
│   │           │   ├── DroneCriticalCommands.css
│   │           │   ├── DroneDetail.css
│   │           │   ├── DroneGitStatus.css
│   │           │   ├── DroneGraph.css
│   │           │   ├── DronePositionMap.css
│   │           │   ├── DroneReadinessReport.css
│   │           │   ├── DroneShowDesign.css
│   │           │   ├── DroneWidget.css
│   │           │   ├── EnvironmentsPage.css
│   │           │   ├── ExpandedDronePortal.css
│   │           │   ├── FleetEnrollmentPage.css
│   │           │   ├── FleetOpsPage.css
│   │           │   ├── GitInfo.css
│   │           │   ├── Globe.css
│   │           │   ├── GlobeControlBox.css
│   │           │   ├── GlobeView.css
│   │           │   ├── Header.css
│   │           │   ├── IdentityDoctrineStrip.css
│   │           │   ├── ImportSection.css
│   │           │   ├── InfoHint.css
│   │           │   ├── LogViewer.css
│   │           │   ├── LoginPage.css
│   │           │   ├── ManageDroneShow.css
│   │           │   ├── MapCommon.css
│   │           │   ├── MapSelector.css
│   │           │   ├── MissionConfig.css
│   │           │   ├── MissionDetails.css
│   │           │   ├── MissionLayout.css
│   │           │   ├── MissionReadinessCard.css
│   │           │   ├── MissionTrigger.css
│   │           │   ├── OperatorPrimitives.css
│   │           │   ├── OriginModal.css
│   │           │   ├── Overview.css
│   │           │   ├── PositionTabs.css
│   │           │   ├── PrecisionMoveDialog.css
│   │           │   ├── Px4ParametersPage.css
│   │           │   ├── QuickScout.css
│   │           │   ├── RuntimeAdminPage.css
│   │           │   ├── RuntimeModeBadge.css
│   │           │   ├── SaveReviewDialog.css
│   │           │   ├── SearchBar.css
│   │           │   ├── SidebarMenu.css
│   │           │   ├── SitlControlPage.css
│   │           │   ├── SwarmDesign.css
│   │           │   ├── SwarmPlots.css
│   │           │   ├── SwarmTrajectory.css
│   │           │   ├── SwarmTrajectoryTransferDialog.css
│   │           │   ├── SyncWarningBanner.css
│   │           │   ├── TacticalDroneCard.css
│   │           │   ├── ThemeToggle.css
│   │           │   ├── TrajectoryLibraryDialog.css
│   │           │   ├── TrajectoryPlanning.css
│   │           │   ├── TrajectoryPolicyNotes.css
│   │           │   ├── TrajectorySegmentReview.css
│   │           │   ├── TrajectoryStats.css
│   │           │   ├── TrajectoryToolbar.css
│   │           │   ├── WaypointModal.css
│   │           │   └── WaypointPanel.css
│   │           ├── useElevation.js
│   │           ├── utilities/
│   │           │   ├── SpeedCalculator.js
│   │           │   ├── SpeedCalculator.test.js
│   │           │   ├── TrajectoryStateManager.js
│   │           │   ├── TrajectoryStateManager.test.js
│   │           │   ├── TrajectoryStorage.js
│   │           │   ├── TrajectoryStorage.test.js
│   │           │   ├── commandExecutionPolicy.js
│   │           │   ├── commandExecutionPolicy.test.js
│   │           │   ├── commandLifecycleFeedback.js
│   │           │   ├── commandLifecycleFeedback.test.js
│   │           │   ├── commandScheduling.js
│   │           │   ├── commandScheduling.test.js
│   │           │   ├── dronePresentation.js
│   │           │   ├── dronePresentation.test.js
│   │           │   ├── droneReadiness.js
│   │           │   ├── droneReadiness.test.js
│   │           │   ├── droneRuntimeStatus.js
│   │           │   ├── droneRuntimeStatus.test.js
│   │           │   ├── fleetOpsViewModel.js
│   │           │   ├── fleetOpsViewModel.test.js
│   │           │   ├── flightModeUtils.js
│   │           │   ├── geoutilities.js
│   │           │   ├── globeScreenInteractions.js
│   │           │   ├── globeScreenInteractions.test.js
│   │           │   ├── globeTelemetryViewModel.js
│   │           │   ├── globeTelemetryViewModel.test.js
│   │           │   ├── logViewerUtils.js
│   │           │   ├── logViewerUtils.test.js
│   │           │   ├── missionConfigFields.js
│   │           │   ├── missionConfigFields.test.js
│   │           │   ├── missionConfigUtilities.js
│   │           │   ├── missionIdentityUtils.js
│   │           │   ├── missionIdentityUtils.test.js
│   │           │   ├── missionSlotStatus.js
│   │           │   ├── missionSlotStatus.test.js
│   │           │   ├── missionUtils.js
│   │           │   ├── missionUtils.test.js
│   │           │   ├── plotThemeColors.js
│   │           │   ├── px4ParameterFiles.js
│   │           │   ├── px4ParameterFiles.test.js
│   │           │   ├── px4ParameterProfiles.js
│   │           │   ├── px4ParameterProfiles.test.js
│   │           │   ├── quickScoutLaunchReadiness.js
│   │           │   ├── quickScoutLaunchReadiness.test.js
│   │           │   ├── quickScoutMissionPresentation.js
│   │           │   ├── quickScoutPlanningSignature.js
│   │           │   ├── quickScoutPlanningSignature.test.js
│   │           │   ├── quickScoutProfiles.js
│   │           │   ├── quickScoutProfiles.test.js
│   │           │   ├── quickScoutSearchGeometry.js
│   │           │   ├── quickScoutSearchGeometry.test.js
│   │           │   ├── smartSwarmLaunchReadiness.js
│   │           │   ├── smartSwarmLaunchReadiness.test.js
│   │           │   ├── swarmDesignUtils.js
│   │           │   ├── swarmDesignUtils.test.js
│   │           │   ├── swarmRuntimeUtils.js
│   │           │   ├── swarmRuntimeUtils.test.js
│   │           │   ├── swarmScopeUtils.js
│   │           │   ├── swarmScopeUtils.test.js
│   │           │   ├── swarmTrajectoryLaunchReadiness.js
│   │           │   ├── swarmTrajectoryLaunchReadiness.test.js
│   │           │   ├── swarmTrajectoryPackageStats.js
│   │           │   ├── swarmTrajectoryPackageStats.test.js
│   │           │   ├── swarmTrajectoryViewModel.js
│   │           │   ├── swarmTrajectoryViewModel.test.js
│   │           │   ├── swarmTrajectoryWorkspaceModel.js
│   │           │   ├── swarmTrajectoryWorkspaceModel.test.js
│   │           │   ├── toastFeedback.js
│   │           │   ├── trajectoryAuthoringGuidance.js
│   │           │   ├── trajectoryAuthoringGuidance.test.js
│   │           │   ├── trajectoryMissionReadiness.js
│   │           │   ├── trajectoryMissionReadiness.test.js
│   │           │   ├── trajectoryTerrainContext.js
│   │           │   ├── trajectoryTerrainContext.test.js
│   │           │   ├── trajectoryTimingPresentation.js
│   │           │   ├── trajectoryTimingPresentation.test.js
│   │           │   └── utilities.js
│   │           └── version.js
│   └── linux_dashboard_start.sh
├── config.json
├── config_sitl.json
├── coordinator.py
├── data/
│   └── origin.sitl.default.json
├── deployment/
│   ├── connectivity/
│   │   └── smart-wifi-manager/
│   │       └── profile.example.json
│   └── defaults.env
├── docs/
│   ├── QUICK_REFERENCE.md
│   ├── README.md
│   ├── TODO_deferred.md
│   ├── VERSIONING.md
│   ├── apis/
│   │   ├── api-modernization-blueprint.md
│   │   ├── drone-api-server.md
│   │   └── gcs-api-server.md
│   ├── archives/
│   │   ├── deprecated/
│   │   │   └── DEPRECATED_v2.0_doc_sitl_demo.md
│   │   ├── hw_id_pos_id_research_2026-03-05.md
│   │   ├── implementation-summaries/
│   │   │   ├── 2025-09-04_flight-mode-fix.md
│   │   │   ├── 2025-09-06_mission-state-rename.md
│   │   │   ├── 2025-09-20_container-fixes.md
│   │   │   ├── 2025-09-20_robustness-summary.md
│   │   │   ├── 2025-11-04_processing-validation.md
│   │   │   ├── 2025-11-05_bug-fix-report.md
│   │   │   ├── 2025-11-05_implementation-summary.md
│   │   │   ├── 2025-11-06_cleanup-summary.md
│   │   │   ├── BACKEND_ANALYSIS_REPORT.md
│   │   │   ├── BACKEND_FASTAPI_MIGRATION_REPORT.md
│   │   │   ├── GCS_SERVER_MIGRATION_PLAN.md
│   │   │   ├── HANDOVER_TO_LOCAL_AGENT.md
│   │   │   ├── PR_MERGE_INSTRUCTIONS.md
│   │   │   └── QUICKSCOUT_REVIEW_REPORT.md
│   │   └── legacy-versions/
│   │       ├── v07_doc.html
│   │       └── v08_doc_server.html
│   ├── configuration_architecture.md
│   ├── control-modes-and-coordinates.md
│   ├── debug/
│   │   └── px4-sitl-preflight-gcs-issue.md
│   ├── features/
│   │   ├── drone-show.md
│   │   ├── git-sync.md
│   │   ├── origin-system.md
│   │   ├── smart-swarm.md
│   │   └── swarm-trajectory.md
│   ├── guides/
│   │   ├── advanced-sitl.md
│   │   ├── config-json-format.md
│   │   ├── connectivity-runtime.md
│   │   ├── csv-migration.md
│   │   ├── custom-repo-workflow.md
│   │   ├── custom-sitl-auth.md
│   │   ├── dashboard-operator.md
│   │   ├── deployment-quick-reference.md
│   │   ├── fleet-ops.md
│   │   ├── fleet-sync-and-secrets.md
│   │   ├── frontend-design-system.md
│   │   ├── frontend-ui-audit.md
│   │   ├── gcs-auth.md
│   │   ├── gcs-setup.md
│   │   ├── headless-automation.md
│   │   ├── led-status-guide.md
│   │   ├── logging-system.md
│   │   ├── mapbox-setup.md
│   │   ├── mavlink-routing-setup.md
│   │   ├── mds-init-cli-reference.md
│   │   ├── mds-init-setup.md
│   │   ├── mds-init-troubleshooting.md
│   │   ├── netbird-setup.md
│   │   ├── operator-makefile.md
│   │   ├── python-compatibility.md
│   │   ├── raspberry-pi-services.md
│   │   ├── repo-asset-layout.md
│   │   ├── runtime-config-sources.md
│   │   ├── runtime-evidence-reporting.md
│   │   ├── sitl-comprehensive.md
│   │   ├── sitl-control.md
│   │   ├── sitl-custom-release-workflow.md
│   │   ├── sitl-validation-platform.md
│   │   ├── smart-swarm-tracking-analysis.md
│   │   └── smart-wifi-manager-dashboard.md
│   ├── plans/
│   │   ├── 2026-03-06-config-json-migration-design.md
│   │   ├── 2026-03-06-config-json-migration.md
│   │   ├── 2026-03-07-swarm-offset-rename.md
│   │   ├── 2026-04-01-dashboard-operator-ux-checkpoint.md
│   │   ├── 2026-04-01-dashboard-ui-hardening-checkpoint.md
│   │   ├── 2026-04-01-frontend-audit-checkpoint.md
│   │   ├── 2026-04-01-hetzner-sitl-checkpoint.md
│   │   ├── 2026-04-01-operator-ui-checkpoint.md
│   │   ├── 2026-04-02-sitl-release-refresh.md
│   │   ├── 2026-04-02-ui-compact-checkpoint.md
│   │   ├── 2026-04-03-api-contract-audit-phase-1.md
│   │   ├── 2026-04-03-api-modernization-phase1.md
│   │   ├── 2026-04-03-api-modernization-phase2-completion.md
│   │   ├── 2026-04-03-api-modernization-phase2.md
│   │   ├── 2026-04-03-api-modernization-review-audit.md
│   │   ├── 2026-04-03-command-legacy-route-retirement.md
│   │   ├── 2026-04-03-command-router-extraction.md
│   │   ├── 2026-04-03-command-v1-canonical-aliases.md
│   │   ├── 2026-04-03-config-swarm-legacy-route-retirement.md
│   │   ├── 2026-04-03-configuration-swarm-router-extraction.md
│   │   ├── 2026-04-03-fleet-config-v1-canonical-aliases.md
│   │   ├── 2026-04-03-gcs-core-router-extraction.md
│   │   ├── 2026-04-03-gcs-telemetry-contract-cleanup.md
│   │   ├── 2026-04-03-git-legacy-route-retirement.md
│   │   ├── 2026-04-03-git-router-extraction.md
│   │   ├── 2026-04-03-git-v1-canonical-aliases.md
│   │   ├── 2026-04-03-internal-canonical-caller-cleanup.md
│   │   ├── 2026-04-03-legacy-route-retirement-audit.md
│   │   ├── 2026-04-03-log-domain-hardening.md
│   │   ├── 2026-04-03-management-static-legacy-route-retirement.md
│   │   ├── 2026-04-03-management-static-router-extraction.md
│   │   ├── 2026-04-03-management-static-v1-canonical-aliases.md
│   │   ├── 2026-04-03-operational-http-alias-retirement.md
│   │   ├── 2026-04-03-origin-legacy-route-retirement.md
│   │   ├── 2026-04-03-origin-router-extraction.md
│   │   ├── 2026-04-03-origin-v1-canonical-aliases.md
│   │   ├── 2026-04-03-sar-router-normalization.md
│   │   ├── 2026-04-03-show-legacy-route-retirement.md
│   │   ├── 2026-04-03-show-management-router-extraction.md
│   │   ├── 2026-04-03-show-v1-canonical-aliases.md
│   │   ├── 2026-04-03-sitl-suite-runtime-root-fix.md
│   │   ├── 2026-04-03-stream-surface-codification.md
│   │   ├── 2026-04-03-swarm-config-v1-canonical-aliases.md
│   │   ├── 2026-04-03-swarm-trajectory-router-extraction.md
│   │   ├── 2026-04-03-swarm-trajectory-v1-retirement.md
│   │   ├── 2026-04-04-api-closeout-websocket-debt-tracking.md
│   │   ├── 2026-04-04-command-contract-canonicalization.md
│   │   ├── 2026-04-04-command-submit-idempotency.md
│   │   ├── 2026-04-04-drone-v1-canonicalization.md
│   │   ├── 2026-04-04-gcs-error-envelope-and-typed-mutations.md
│   │   ├── 2026-04-04-sitl-clean-image-regression-and-hetzner-cleanup.md
│   │   ├── 2026-04-04-sitl-plan-library.md
│   │   ├── 2026-04-04-sitl-release-refresh.md
│   │   ├── 2026-04-04-sitl-validation-platform-phase1.md
│   │   ├── 2026-04-04-sitl-validation-platform-phase2.md
│   │   ├── 2026-04-04-subsystem-error-envelope-normalization.md
│   │   ├── 2026-04-04-swarm-trajectory-typed-contracts.md
│   │   ├── 2026-04-05-precision-move-design-brief.md
│   │   ├── 2026-04-05-precision-move-final-recap.md
│   │   ├── 2026-04-06-mission-config-and-command-copy-cleanup.md
│   │   ├── 2026-04-06-mission-config-architecture-reset-phase1.md
│   │   ├── 2026-04-06-precision-move-phase1-implementation.md
│   │   ├── 2026-04-06-precision-move-phase2-operator-control-surface.md
│   │   ├── 2026-04-06-precision-move-sitl-validation.md
│   │   ├── 2026-04-06-review-intake-and-ui-phase-plan.md
│   │   ├── 2026-04-06-shared-operator-scope-phase2.md
│   │   ├── 2026-04-06-trajectory-authoring-phase3.md
│   │   ├── 2026-04-07-advanced-sitl-regression-and-override-state-fix.md
│   │   ├── 2026-04-07-mission-config-actionable-alerts.md
│   │   ├── 2026-04-07-mission-config-card-compact-indicators.md
│   │   ├── 2026-04-07-mission-config-launch-map-and-sync-finalization.md
│   │   ├── 2026-04-07-mission-config-launch-map-polish.md
│   │   ├── 2026-04-07-quickscout-audit-and-redesign-brief.md
│   │   ├── 2026-04-07-quickscout-foundation-phase1.md
│   │   ├── 2026-04-07-smart-swarm-airborne-gate-and-quick-takeoff.md
│   │   ├── 2026-04-08-quickscout-command-lifecycle-phase2.md
│   │   ├── 2026-04-08-quickscout-corridor-template-foundation-phase10.md
│   │   ├── 2026-04-08-quickscout-execution-semantics-phase13.md
│   │   ├── 2026-04-08-quickscout-findings-cleanup-followup-phase15.md
│   │   ├── 2026-04-08-quickscout-findings-foundation-phase14.md
│   │   ├── 2026-04-08-quickscout-findings-handoff-runtime-validation-phase17.md
│   │   ├── 2026-04-08-quickscout-handoff-evidence-phase16.md
│   │   ├── 2026-04-08-quickscout-launch-review-phase7.md
│   │   ├── 2026-04-08-quickscout-mission-briefing-phase6.md
│   │   ├── 2026-04-08-quickscout-monitor-package-context-phase12.md
│   │   ├── 2026-04-08-quickscout-operator-setup-phase5.md
│   │   ├── 2026-04-08-quickscout-point-geometry-phase9.md
│   │   ├── 2026-04-08-quickscout-recovery-phase3.md
│   │   ├── 2026-04-08-quickscout-runtime-multi-validation-followup.md
│   │   ├── 2026-04-08-quickscout-runtime-validation.md
│   │   ├── 2026-04-08-quickscout-template-aware-launch-review-phase11.md
│   │   ├── 2026-04-08-quickscout-template-complete-runtime-validation-phase18.md
│   │   ├── 2026-04-08-quickscout-template-foundation-phase8.md
│   │   ├── 2026-04-08-quickscout-tester-handoff.md
│   │   ├── 2026-04-08-quickscout-workspace-recovery-ui-phase4.md
│   │   ├── 2026-04-09-px4-parameter-management-design-brief.md
│   │   ├── 2026-04-09-px4-parameter-runtime-validation-phase3.md
│   │   ├── 2026-04-09-px4-parameter-workspace-phase2.md
│   │   ├── 2026-04-09-px4-parameters-profiles-tester-handoff.md
│   │   ├── 2026-04-09-px4-parameters-responsive-handoff-refinement.md
│   │   ├── 2026-04-09-px4-parameters-scan-first-ui-refinement.md
│   │   ├── 2026-04-09-px4-params-foundation-phase1.md
│   │   ├── 2026-04-10-enrollment-identity-phase-closeout.md
│   │   ├── 2026-04-10-fleet-candidate-registry-foundation.md
│   │   ├── 2026-04-10-fleet-enrollment-operator-workflow.md
│   │   ├── 2026-04-10-mission-config-pending-enrollment-cutover.md
│   │   ├── 2026-04-10-node-bootstrap-and-fleet-enrollment-design-brief.md
│   │   ├── 2026-04-10-node-bootstrap-candidate-announce-integration.md
│   │   ├── 2026-04-10-node-bootstrap-fleet-enrollment-v1-recap.md
│   │   ├── 2026-04-10-node-bootstrap-phase1-foundation.md
│   │   ├── 2026-04-10-node-enrollment-and-mavlink-anywhere-review.md
│   │   ├── 2026-04-10-node-enrollment-identity-alignment-brief.md
│   │   ├── 2026-04-10-px4-parameters-alignment-followup.md
│   │   ├── 2026-04-10-px4-parameters-grouped-compact-refinement.md
│   │   ├── 2026-04-11-hardware-demo-confirmation-brief.md
│   │   ├── 2026-04-11-hardware-demo-final-review.md
│   │   ├── 2026-04-11-hardware-demo-preflight-audit.md
│   │   ├── 2026-04-11-hardware-demo-workflow-clarifications.md
│   │   ├── 2026-04-11-official-bootstrap-hardware-closeout.md
│   │   ├── 2026-04-11-onboard-ulog-management-design-brief.md
│   │   ├── 2026-04-11-onboard-ulog-runtime-closeout.md
│   │   ├── 2026-04-11-quickscout-runtime-acceptance-closeout.md
│   │   ├── 2026-04-12-private-customer-bootstrap-runtime-validation.md
│   │   ├── 2026-04-13-sitl-control-automation-adoption.md
│   │   ├── 2026-04-13-sitl-control-interaction-hardening.md
│   │   ├── 2026-04-13-sitl-control-operator-refinement.md
│   │   ├── 2026-04-13-sitl-control-phase1-implementation.md
│   │   ├── 2026-04-13-sitl-control-ux-hardening.md
│   │   ├── 2026-04-14-sitl-control-final-operator-refinement.md
│   │   ├── 2026-04-15-smart-swarm-runtime-phase1-implementation.md
│   │   ├── 2026-04-16-smart-swarm-runtime-closeout.md
│   │   ├── 2026-04-17-frontend-delivery-and-smart-swarm-tracking-checkpoint.md
│   │   ├── 2026-04-18-phase1-tester-feedback-response.md
│   │   ├── 2026-04-21-runtime-architecture-migration-log.md
│   │   ├── 2026-04-25-predeploy-ui-audit-baseline.json
│   │   ├── 2026-04-25-predeploy-ui-ux-refactor-audit-plan.md
│   │   ├── 2026-04-25-tactical-map-globe.md
│   │   ├── 2026-04-29-auth-implementation-journey.md
│   │   ├── 2026-04-29-mds-environment-registry-and-control-plane.md
│   │   └── 2026-04-30-env-registry-implementation-journey.md
│   ├── px4-parameters.md
│   ├── quickscout.md
│   ├── reference/
│   │   ├── mds-environment-registry.generated.md
│   │   └── mds-environment-registry.md
│   ├── research/
│   │   └── git-sync-hardening-research.md
│   └── superpowers/
│       ├── README.md
│       ├── plans/
│       │   └── 2026-03-19-unified-logging-phase1-foundation.md
│       └── specs/
│           ├── 2026-03-19-unified-logging-system-design.md
│           └── 2026-03-26-ai-agent-sitl-audit-loop.md
├── drone_show.py
├── drone_show_src/
│   └── utils.py
├── functions/
│   ├── __init__.py
│   ├── circle.py
│   ├── create_active_csv.py
│   ├── data_utils.py
│   ├── drone_show_metrics.py
│   ├── export_and_plot_shape.py
│   ├── file_management.py
│   ├── file_utils.py
│   ├── git_manager.py
│   ├── global_to_local.py
│   ├── plot_drone_paths.py
│   ├── process_drone_files.py
│   ├── seven_segment.py
│   ├── shapeParameters.py
│   ├── shape_functions.py
│   ├── shape_plots.py
│   ├── show_static_shape_results.py
│   ├── swarm_analyzer.py
│   ├── swarm_global_calculator.py
│   ├── swarm_kml_generator.py
│   ├── swarm_plotter.py
│   ├── swarm_session_manager.py
│   ├── swarm_trajectory_processor.py
│   ├── swarm_trajectory_service.py
│   ├── swarm_trajectory_smoother.py
│   ├── swarm_trajectory_utils.py
│   └── trajectories.py
├── gcs-server/
│   ├── __init__.py
│   ├── api_errors.py
│   ├── api_routes/
│   │   ├── __init__.py
│   │   ├── auth.py
│   │   ├── commands.py
│   │   ├── configuration.py
│   │   ├── core.py
│   │   ├── fleet_candidates.py
│   │   ├── git_status.py
│   │   ├── management.py
│   │   ├── origin.py
│   │   ├── px4_params.py
│   │   ├── show_management.py
│   │   ├── sitl_control.py
│   │   ├── static_assets.py
│   │   ├── swarm.py
│   │   └── swarm_trajectory.py
│   ├── app_fastapi.py
│   ├── auth_runtime.py
│   ├── command.py
│   ├── command_submission.py
│   ├── command_timeout_policy.py
│   ├── command_tracker.py
│   ├── config.py
│   ├── fleet_candidates.py
│   ├── gcs_config_updater.py
│   ├── get_elevation.py
│   ├── git_status.py
│   ├── heartbeat.py
│   ├── link_presence.py
│   ├── log_background.py
│   ├── log_proxy.py
│   ├── log_routes.py
│   ├── origin.py
│   ├── presence.py
│   ├── px4_param_store.py
│   ├── request_logging.py
│   ├── sar/
│   │   ├── __init__.py
│   │   ├── coverage_planner.py
│   │   ├── mission_manager.py
│   │   ├── routes.py
│   │   ├── schemas.py
│   │   ├── service.py
│   │   ├── store.py
│   │   └── terrain.py
│   ├── schemas.py
│   ├── show_management.py
│   ├── start_gcs_server.sh
│   ├── telemetry.py
│   └── utils.py
├── led_indicator.py
├── mavsdk/
│   ├── Makefile
│   ├── __init__.py
│   ├── _base.py
│   ├── action.py
│   ├── action_pb2.py
│   ├── action_pb2_grpc.py
│   ├── action_server.py
│   ├── action_server_pb2.py
│   ├── action_server_pb2_grpc.py
│   ├── async_plugin_manager.py
│   ├── calibration.py
│   ├── calibration_pb2.py
│   ├── calibration_pb2_grpc.py
│   ├── camera.py
│   ├── camera_pb2.py
│   ├── camera_pb2_grpc.py
│   ├── camera_server.py
│   ├── camera_server_pb2.py
│   ├── camera_server_pb2_grpc.py
│   ├── component_information.py
│   ├── component_information_pb2.py
│   ├── component_information_pb2_grpc.py
│   ├── component_information_server.py
│   ├── component_information_server_pb2.py
│   ├── component_information_server_pb2_grpc.py
│   ├── core.py
│   ├── core_pb2.py
│   ├── core_pb2_grpc.py
│   ├── failure.py
│   ├── failure_pb2.py
│   ├── failure_pb2_grpc.py
│   ├── follow_me.py
│   ├── follow_me_pb2.py
│   ├── follow_me_pb2_grpc.py
│   ├── ftp.py
│   ├── ftp_pb2.py
│   ├── ftp_pb2_grpc.py
│   ├── geofence.py
│   ├── geofence_pb2.py
│   ├── geofence_pb2_grpc.py
│   ├── gimbal.py
│   ├── gimbal_pb2.py
│   ├── gimbal_pb2_grpc.py
│   ├── gripper.py
│   ├── gripper_pb2.py
│   ├── gripper_pb2_grpc.py
│   ├── info.py
│   ├── info_pb2.py
│   ├── info_pb2_grpc.py
│   ├── log_files.py
│   ├── log_files_pb2.py
│   ├── log_files_pb2_grpc.py
│   ├── make.bat
│   ├── manual_control.py
│   ├── manual_control_pb2.py
│   ├── manual_control_pb2_grpc.py
│   ├── mavsdk_options_pb2.py
│   ├── mavsdk_options_pb2_grpc.py
│   ├── mission.py
│   ├── mission_pb2.py
│   ├── mission_pb2_grpc.py
│   ├── mission_raw.py
│   ├── mission_raw_pb2.py
│   ├── mission_raw_pb2_grpc.py
│   ├── mission_raw_server.py
│   ├── mission_raw_server_pb2.py
│   ├── mission_raw_server_pb2_grpc.py
│   ├── mocap.py
│   ├── mocap_pb2.py
│   ├── mocap_pb2_grpc.py
│   ├── offboard.py
│   ├── offboard_pb2.py
│   ├── offboard_pb2_grpc.py
│   ├── param.py
│   ├── param_pb2.py
│   ├── param_pb2_grpc.py
│   ├── param_server.py
│   ├── param_server_pb2.py
│   ├── param_server_pb2_grpc.py
│   ├── rtk.py
│   ├── rtk_pb2.py
│   ├── rtk_pb2_grpc.py
│   ├── server_utility.py
│   ├── server_utility_pb2.py
│   ├── server_utility_pb2_grpc.py
│   ├── shell.py
│   ├── shell_pb2.py
│   ├── shell_pb2_grpc.py
│   ├── source/
│   │   ├── conf.py
│   │   ├── index.rst
│   │   ├── nature_adapted/
│   │   │   ├── static/
│   │   │   │   └── style.css
│   │   │   └── theme.conf
│   │   ├── plugins/
│   │   │   ├── action.rst
│   │   │   ├── action_server.rst
│   │   │   ├── calibration.rst
│   │   │   ├── camera.rst
│   │   │   ├── camera_server.rst
│   │   │   ├── component_information.rst
│   │   │   ├── component_information_server.rst
│   │   │   ├── core.rst
│   │   │   ├── failure.rst
│   │   │   ├── follow_me.rst
│   │   │   ├── ftp.rst
│   │   │   ├── geofence.rst
│   │   │   ├── gimbal.rst
│   │   │   ├── gripper.rst
│   │   │   ├── index.rst
│   │   │   ├── info.rst
│   │   │   ├── log_files.rst
│   │   │   ├── manual_control.rst
│   │   │   ├── mission.rst
│   │   │   ├── mission_raw.rst
│   │   │   ├── mission_raw_server.rst
│   │   │   ├── mocap.rst
│   │   │   ├── offboard.rst
│   │   │   ├── param.rst
│   │   │   ├── param_server.rst
│   │   │   ├── rtk.rst
│   │   │   ├── server_utility.rst
│   │   │   ├── shell.rst
│   │   │   ├── telemetry.rst
│   │   │   ├── telemetry_server.rst
│   │   │   ├── tracking_server.rst
│   │   │   ├── transponder.rst
│   │   │   ├── tune.rst
│   │   │   └── winch.rst
│   │   └── system.rst
│   ├── system.py
│   ├── telemetry.py
│   ├── telemetry_pb2.py
│   ├── telemetry_pb2_grpc.py
│   ├── telemetry_server.py
│   ├── telemetry_server_pb2.py
│   ├── telemetry_server_pb2_grpc.py
│   ├── tracking_server.py
│   ├── tracking_server_pb2.py
│   ├── tracking_server_pb2_grpc.py
│   ├── transponder.py
│   ├── transponder_pb2.py
│   ├── transponder_pb2_grpc.py
│   ├── tune.py
│   ├── tune_pb2.py
│   ├── tune_pb2_grpc.py
│   ├── winch.py
│   ├── winch_pb2.py
│   └── winch_pb2_grpc.py
├── mds_logging/
│   ├── __init__.py
│   ├── api_schemas.py
│   ├── cli.py
│   ├── constants.py
│   ├── drone.py
│   ├── formatter.py
│   ├── handlers.py
│   ├── registry.py
│   ├── schema.py
│   ├── server.py
│   ├── session.py
│   └── watcher.py
├── multiple_sitl/
│   ├── calculate_spawn_coordinates.py
│   ├── create_dockers.sh
│   ├── detect_px4_mavlink_port.py
│   ├── multiple_sitl.sh
│   └── startup_sitl.sh
├── process_formation.py
├── pyproject.toml
├── pytest.ini
├── quickscout_mission.py
├── requirements-node.txt
├── requirements.txt
├── resources/
│   ├── README.md
│   ├── common_params.csv
│   ├── config/
│   │   ├── mds_env_internal_allowlist.json
│   │   ├── mds_env_registry.json
│   │   └── mds_env_registry.schema.json
│   ├── config_100_single_vps_docker.json
│   ├── config_100_two_vps_docker.json
│   ├── config_12docker.json
│   ├── config_16docker.json
│   ├── config_40docker.json
│   ├── config_vmware_4.json
│   ├── px4_param_profiles/
│   │   ├── README.md
│   │   ├── fleet_geofence_guardrail.json
│   │   └── sitl_link_loss_relaxed.json
│   ├── swarm_12docker.json
│   ├── swarm_16docker.json
│   ├── swarm_40docker.json
│   └── swarm_sitl_100.json
├── shapes/
│   ├── active.csv
│   ├── hover_test.csv
│   ├── static_shapes/
│   │   └── active/
│   │       └── drone_positions.csv
│   ├── swarm/
│   │   ├── comprehensive_metrics.json
│   │   ├── processed/
│   │   │   ├── Drone 1.csv
│   │   │   ├── Drone 10.csv
│   │   │   ├── Drone 2.csv
│   │   │   ├── Drone 3.csv
│   │   │   ├── Drone 4.csv
│   │   │   ├── Drone 5.csv
│   │   │   ├── Drone 6.csv
│   │   │   ├── Drone 7.csv
│   │   │   ├── Drone 8.csv
│   │   │   └── Drone 9.csv
│   │   └── skybrush/
│   │       ├── Drone 1.csv
│   │       ├── Drone 10.csv
│   │       ├── Drone 2.csv
│   │       ├── Drone 3.csv
│   │       ├── Drone 4.csv
│   │       ├── Drone 5.csv
│   │       ├── Drone 6.csv
│   │       ├── Drone 7.csv
│   │       ├── Drone 8.csv
│   │       └── Drone 9.csv
│   └── swarm_trajectory/
│       ├── processed/
│       │   ├── Drone 1.csv
│       │   ├── Drone 10.csv
│       │   ├── Drone 2.csv
│       │   ├── Drone 3.csv
│       │   ├── Drone 4.csv
│       │   ├── Drone 5.csv
│       │   ├── Drone 6.csv
│       │   ├── Drone 7.csv
│       │   ├── Drone 8.csv
│       │   └── Drone 9.csv
│       └── raw/
│           ├── Drone 1.csv
│           └── Drone 2.csv
├── shapes_sitl/
│   ├── active.csv
│   ├── hover_test.csv
│   ├── static_shapes/
│   │   └── active/
│   │       └── drone_positions.csv
│   ├── swarm/
│   │   ├── comprehensive_metrics.json
│   │   ├── processed/
│   │   │   ├── Drone 1.csv
│   │   │   ├── Drone 2.csv
│   │   │   ├── Drone 3.csv
│   │   │   ├── Drone 4.csv
│   │   │   └── Drone 5.csv
│   │   └── skybrush/
│   │       ├── Drone 1.csv
│   │       ├── Drone 2.csv
│   │       ├── Drone 3.csv
│   │       ├── Drone 4.csv
│   │       └── Drone 5.csv
│   └── swarm_trajectory/
│       ├── processed/
│       │   ├── Drone 1.csv
│       │   ├── Drone 2.csv
│       │   ├── Drone 3.csv
│       │   ├── Drone 4.csv
│       │   └── Drone 5.csv
│       └── raw/
│           ├── Drone 1.csv
│           └── Drone 4.csv
├── smart_swarm.py
├── smart_swarm_src/
│   ├── __init__.py
│   ├── failover.py
│   ├── kalman_filter.py
│   ├── low_pass_filter.py
│   ├── pd_controller.py
│   └── utils.py
├── src/
│   ├── __init__.py
│   ├── action_runners/
│   │   ├── __init__.py
│   │   ├── base.py
│   │   └── precision_move.py
│   ├── command_contract.py
│   ├── connectivity_checker.py
│   ├── constants.py
│   ├── coordinate_utils.py
│   ├── drone.py
│   ├── drone_api_routes.py
│   ├── drone_api_server.py
│   ├── drone_communicator.py
│   ├── drone_config/
│   │   ├── __init__.py
│   │   ├── config_loader.py
│   │   ├── drone_config_data.py
│   │   └── drone_state.py
│   ├── drone_setup.py
│   ├── enums.py
│   ├── filter.py
│   ├── flight_timeout_utils.py
│   ├── gcs_api_routes.py
│   ├── gcs_auth_client.py
│   ├── heartbeat_sender.py
│   ├── led_colors.py
│   ├── led_controller.py
│   ├── live_armability_utils.py
│   ├── local_mavlink_controller.py
│   ├── managed_runtime_status.py
│   ├── mission_startup.py
│   ├── network_status.py
│   ├── origin_cache.py
│   ├── params.py
│   ├── pos_id_auto_detector.py
│   ├── px4_param_models.py
│   ├── px4_params/
│   │   ├── __init__.py
│   │   ├── catalog.py
│   │   └── service.py
│   ├── security/
│   │   ├── __init__.py
│   │   └── auth.py
│   ├── settings/
│   │   ├── __init__.py
│   │   ├── deployment_profile.py
│   │   ├── env_files.py
│   │   ├── env_registry.py
│   │   ├── env_status.py
│   │   ├── identity.py
│   │   └── runtime.py
│   ├── sitl_control_models.py
│   ├── sitl_control_service.py
│   ├── swarm_runtime_state.py
│   ├── synchronized_start.py
│   ├── telemetry_subscription_manager.py
│   └── ulog_service.py
├── swarm.json
├── swarm_sitl.json
├── swarm_trajectory_mission.py
├── tests/
│   ├── README.md
│   ├── __init__.py
│   ├── conftest.py
│   ├── fixtures/
│   │   ├── __init__.py
│   │   ├── command_samples.py
│   │   ├── drone_configs.py
│   │   ├── mission_samples.py
│   │   └── telemetry_samples.py
│   ├── helpers/
│   │   └── __init__.py
│   ├── integration/
│   │   └── __init__.py
│   ├── mocks/
│   │   ├── __init__.py
│   │   └── mavlink_simulator.py
│   ├── requirements-test.txt
│   ├── test_action_runner_runtime.py
│   ├── test_actions_common_params.py
│   ├── test_actions_preflight.py
│   ├── test_analyze_smart_swarm_tracking.py
│   ├── test_api_route_inventory.py
│   ├── test_bootstrap_installers.py
│   ├── test_calculate_spawn_coordinates.py
│   ├── test_check_runtime_venv.py
│   ├── test_command_processing.py
│   ├── test_command_system.py
│   ├── test_command_timeout_policy.py
│   ├── test_config_validation.py
│   ├── test_connectivity_checker.py
│   ├── test_constants.py
│   ├── test_coordinate_utils.py
│   ├── test_coordinator.py
│   ├── test_data_utils.py
│   ├── test_detect_px4_mavlink_port.py
│   ├── test_drone_api_http.py
│   ├── test_drone_api_websocket.py
│   ├── test_drone_communicator.py
│   ├── test_drone_communicator_runtime_swarm.py
│   ├── test_drone_config_components.py
│   ├── test_drone_setup.py
│   ├── test_drone_show_controlled_landing.py
│   ├── test_env_files.py
│   ├── test_env_registry.py
│   ├── test_env_status.py
│   ├── test_file_management.py
│   ├── test_file_utils.py
│   ├── test_filter.py
│   ├── test_fleet_candidate_registry.py
│   ├── test_flight_timeout_utils.py
│   ├── test_gcs_api_http.py
│   ├── test_gcs_api_websocket.py
│   ├── test_gcs_auth_client.py
│   ├── test_gcs_command_routes.py
│   ├── test_gcs_configuration_routes.py
│   ├── test_gcs_core_routes.py
│   ├── test_gcs_fleet_candidates_routes.py
│   ├── test_gcs_git_routes.py
│   ├── test_gcs_management_routes.py
│   ├── test_gcs_origin_routes.py
│   ├── test_gcs_px4_params_routes.py
│   ├── test_gcs_sar_routes.py
│   ├── test_gcs_show_management_routes.py
│   ├── test_gcs_sitl_control_routes.py
│   ├── test_gcs_static_assets_routes.py
│   ├── test_gcs_swarm_routes.py
│   ├── test_gcs_swarm_trajectory_routes.py
│   ├── test_gcs_telemetry.py
│   ├── test_git_manager.py
│   ├── test_git_sync.py
│   ├── test_heartbeat_runtime_mode.py
│   ├── test_heartbeat_sender.py
│   ├── test_led_controller.py
│   ├── test_link_presence.py
│   ├── test_local_mavlink_controller.py
│   ├── test_managed_runtime_status.py
│   ├── test_mds_auth.py
│   ├── test_mds_git_access_check.py
│   ├── test_mds_logging/
│   │   ├── __init__.py
│   │   ├── test_cli.py
│   │   ├── test_constants.py
│   │   ├── test_formatter.py
│   │   ├── test_handlers.py
│   │   ├── test_integration.py
│   │   ├── test_log_background.py
│   │   ├── test_log_proxy.py
│   │   ├── test_log_routes_drone.py
│   │   ├── test_log_routes_gcs.py
│   │   ├── test_noise_control.py
│   │   ├── test_registry.py
│   │   ├── test_schema.py
│   │   ├── test_session.py
│   │   ├── test_sse_stream.py
│   │   └── test_watcher.py
│   ├── test_mds_node_announce_script.py
│   ├── test_mission_startup.py
│   ├── test_network_status.py
│   ├── test_origin_compute.py
│   ├── test_origin_defaults.py
│   ├── test_pos_id_auto_detector.py
│   ├── test_precision_move_runner.py
│   ├── test_presence.py
│   ├── test_process_drone_files.py
│   ├── test_px4_param_catalog.py
│   ├── test_px4_param_service.py
│   ├── test_px4_param_store_profiles.py
│   ├── test_quickscout_mission.py
│   ├── test_request_logging.py
│   ├── test_run_sitl_validation_suite.py
│   ├── test_run_with_log_policy.py
│   ├── test_runtime_settings.py
│   ├── test_sar_api.py
│   ├── test_sar_coverage_planner.py
│   ├── test_sar_schemas.py
│   ├── test_sar_store.py
│   ├── test_schema_validation.py
│   ├── test_show_package_integrity.py
│   ├── test_sitl_control_client.py
│   ├── test_sitl_control_service.py
│   ├── test_smart_swarm_active_routes.py
│   ├── test_smart_swarm_failover.py
│   ├── test_smart_swarm_kalman.py
│   ├── test_smart_swarm_pd_controller.py
│   ├── test_smart_swarm_runtime_math.py
│   ├── test_smart_swarm_target_switch.py
│   ├── test_spa_static_server.py
│   ├── test_swarm_global_calculator.py
│   ├── test_swarm_runtime_state.py
│   ├── test_swarm_trajectory_mission.py
│   ├── test_swarm_trajectory_processor.py
│   ├── test_swarm_trajectory_service.py
│   ├── test_swarm_trajectory_smoother.py
│   ├── test_synchronized_start.py
│   ├── test_telemetry_logging.py
│   ├── test_ulog_service.py
│   ├── test_validate_actions_runtime.py
│   ├── test_validate_configuration_runtime.py
│   ├── test_validate_drone_show_runtime.py
│   ├── test_validate_integrated_runtime.py
│   ├── test_validate_px4_params_runtime.py
│   ├── test_validate_quickscout_runtime.py
│   ├── test_validate_smart_swarm_runtime.py
│   └── test_validate_swarm_trajectory_runtime.py
├── tools/
│   ├── analyze_smart_swarm_tracking.py
│   ├── audit_frontend_ui.py
│   ├── audit_mds_env_registry.py
│   ├── auto_recover/
│   │   └── create_backup_restore_scripts.sh
│   ├── build_custom_image.sh
│   ├── bump_version.py
│   ├── check_and_update_service.sh
│   ├── check_runtime_venv.py
│   ├── coordinator.service
│   ├── deprecated/
│   │   └── update_repo_https.sh
│   ├── docker_sitl_image_lib.sh
│   ├── download_mavsdk_server.sh
│   ├── gcs_fast_forward_update.sh
│   ├── generate_hover_test.py
│   ├── generate_mds_env_reference.py
│   ├── generate_release_notes.py
│   ├── git_sync_mds/
│   │   ├── git_sync_mds.service
│   │   └── install_git_sync_mds.sh
│   ├── install_companion.sh
│   ├── install_gcs.sh
│   ├── install_mds_node.sh
│   ├── led_indicator/
│   │   ├── install_led_indicator.sh
│   │   └── led_indicator.service
│   ├── load_deployment_profile.sh
│   ├── local.env.template
│   ├── mavlink_forward.py
│   ├── mds_auth_admin.py
│   ├── mds_banner.sh
│   ├── mds_gcs_init.sh
│   ├── mds_gcs_init_lib/
│   │   ├── gcs_common.sh
│   │   ├── gcs_env_config.sh
│   │   ├── gcs_firewall.sh
│   │   ├── gcs_nodejs.sh
│   │   ├── gcs_nodejs_env.sh
│   │   ├── gcs_prereqs.sh
│   │   ├── gcs_python.sh
│   │   ├── gcs_python_env.sh
│   │   ├── gcs_repo.sh
│   │   ├── gcs_services.sh
│   │   └── gcs_verify.sh
│   ├── mds_git_access_check.sh
│   ├── mds_init_lib/
│   │   ├── announce.sh
│   │   ├── common.sh
│   │   ├── connectivity.sh
│   │   ├── firewall.sh
│   │   ├── identity.sh
│   │   ├── mavlink_setup.sh
│   │   ├── mavsdk.sh
│   │   ├── network.sh
│   │   ├── prereqs.sh
│   │   ├── python_env.sh
│   │   ├── repo.sh
│   │   ├── services.sh
│   │   └── verify.sh
│   ├── mds_node_announce.sh
│   ├── mds_node_init.sh
│   ├── migrate_csv_to_json.py
│   ├── package_runtime_evidence_report.py
│   ├── package_sitl_image.sh
│   ├── polkit_reboot_add.sh
│   ├── publish_sitl_release_to_mega.sh
│   ├── reconcile_connectivity.sh
│   ├── reconcile_mavlink_runtime.sh
│   ├── recovery.sh
│   ├── release_sitl_image.sh
│   ├── rtk_streamer_gui/
│   │   └── main.py
│   ├── run_mavlink2rest.sh
│   ├── run_mavlink_router.sh
│   ├── run_sitl_validation_suite.py
│   ├── run_with_log_policy.py
│   ├── runtime_validation_support.py
│   ├── sitl_control_client.py
│   ├── sitl_image_prepare.sh
│   ├── sitl_plans/
│   │   ├── README.md
│   │   ├── actions_core.json
│   │   ├── advanced_operator_regression.json
│   │   ├── config_roundtrip.json
│   │   ├── config_then_drone_show.json
│   │   ├── drone_show_matrix.json
│   │   ├── integrated_mixed_mode.json
│   │   ├── mission_regression.json
│   │   ├── operator_regression.json
│   │   ├── px4_params_runtime.json
│   │   ├── quickscout_area_runtime.json
│   │   ├── quickscout_corridor_runtime.json
│   │   ├── quickscout_multi_runtime.json
│   │   ├── quickscout_runtime.json
│   │   ├── quickscout_template_regression.json
│   │   ├── smart_swarm_runtime.json
│   │   ├── swarm_trajectory_short_profile.json
│   │   └── ulog_runtime.json
│   ├── sitl_stop_all.py
│   ├── spa_static_server.py
│   ├── sync_time_linux.sh
│   ├── sync_time_win.bat
│   ├── test_import_show.html
│   ├── update_repo_ssh.sh
│   ├── update_service.sh
│   ├── validate_actions_runtime.py
│   ├── validate_commits.py
│   ├── validate_configuration_runtime.py
│   ├── validate_drone_show_runtime.py
│   ├── validate_integrated_runtime.py
│   ├── validate_onboard_ulog_runtime.py
│   ├── validate_px4_params_runtime.py
│   ├── validate_quickscout_runtime.py
│   ├── validate_smart_swarm_runtime.py
│   ├── validate_swarm_trajectory_runtime.py
│   └── version_sync.py
└── visual/
    └── templates/
        └── visualization.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
# Pull Request

## Description

<!-- Provide a brief description of the changes in this PR -->

## Type of Change

<!-- Mark the relevant option with an "x" -->

- [ ] Bug fix (non-breaking change fixing an issue)
- [ ] New feature (non-breaking change adding functionality)
- [ ] Breaking change (fix or feature causing existing functionality to not work as expected)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring
- [ ] Configuration change

## Related Issues

<!-- Link any related issues using #issue_number -->

Fixes #
Related to #

## Changes Made

<!-- List the main changes made in this PR -->

-
-
-

## Testing

<!-- Describe the testing you've done -->

### SITL Testing
- [ ] Tested in SITL environment
- [ ] Number of drones tested:
- [ ] Test scenarios:

### Code Quality
- [ ] Python syntax validated
- [ ] Frontend builds without errors
- [ ] No new ESLint warnings (or documented)

### Documentation
- [ ] Documentation updated (if needed)
- [ ] CHANGELOG.md updated (if applicable)

## Screenshots/Videos

<!-- If applicable, add screenshots or video links -->

## Checklist

<!-- Mark completed items with an "x" -->

- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have tested my changes in SITL environment
- [ ] Any dependent changes have been merged and published

## Additional Notes

<!-- Any additional information or context -->

---

**Note for Maintainers:**
- Target branch should be `main` for normal PRs
- Keep `main` deployable; use feature/client branches for unvalidated work


================================================
FILE: .github/RELEASE_TEMPLATE.md
================================================
# Release Checklist & Template

**Version:** X.Y

**Release Date:** YYYY-MM-DD

---

## Pre-Release Checklist

Before creating the release, ensure all items are completed:

### Code & Testing
- [ ] All features tested in SITL environment
- [ ] All known bugs fixed or documented
- [ ] Code reviewed and approved
- [ ] No critical security vulnerabilities

### Documentation
- [ ] CHANGELOG.md updated with all changes
- [ ] README.md updated if needed
- [ ] All new features documented
- [ ] API changes documented

### Version Management
- [ ] VERSION file updated to X.Y
- [ ] `python tools/version_sync.py` executed successfully
- [ ] Frontend rebuilt with `npm run build`
- [ ] Version displayed correctly in dashboard sidebar

### Quality Checks
- [ ] Python syntax validation passed
- [ ] Frontend builds without errors
- [ ] No ESLint warnings (or documented)
- [ ] All links in documentation verified

### Repository
- [ ] All changes committed to main
- [ ] `main` contains the validated release commit
- [ ] No uncommitted changes

---

## Release Process

### 1. Create Git Tag

```bash
git checkout main
git tag -a v3.6 -m "Release version 3.6"
git push origin v3.6
```

### 2. Create GitHub Release

1. Go to: https://github.com/alireza787b/mavsdk_drone_show/releases/new
2. Tag version: `v3.6`
3. Target: `main`
4. Release title: `Version 3.6`
5. Description: Copy from CHANGELOG.md (see template below)

---

## Release Notes Template

Copy this template and fill in details from CHANGELOG.md:

```markdown
# MAVSDK Drone Show v3.6

**Release Date:** November 6, 2025

## Highlights

[Brief 2-3 sentence summary of major changes]

## What's New

### Added
- Feature 1 description
- Feature 2 description

### Changed
- Change 1 description
- Change 2 description

### Fixed
- Bug fix 1
- Bug fix 2

## Documentation

📖 [Full Changelog](CHANGELOG.md)
📖 [Documentation Index](docs/README.md)
📖 [Versioning Guide](docs/VERSIONING.md)

## Installation

### SITL Demo (Recommended for Testing)

```bash
# Clone repository
git clone https://github.com/alireza787b/mavsdk_drone_show.git
cd mavsdk_drone_show

# Checkout this version
git checkout v3.6

# Follow SITL guide
```

📖 [Complete SITL Setup Guide](docs/guides/sitl-comprehensive.md)

### Python Requirements

**Requires Python 3.11, 3.12, or 3.13**

See [Python Compatibility Guide](docs/guides/python-compatibility.md)

## Upgrade Notes

[Any breaking changes or migration steps users need to know]

## Known Issues

[List any known issues or limitations in this release]

## Contributors

Thanks to all contributors who helped make this release possible!

---

## 🏢 Commercial Support

For production deployments, custom features, or hardware implementation assistance:
- Email: p30planets@gmail.com
- LinkedIn: [Alireza Ghaderi](https://www.linkedin.com/in/alireza787b/)

---

**Full Changelog**: https://github.com/alireza787b/mavsdk_drone_show/blob/main/CHANGELOG.md
```

---

## Post-Release

After creating the release:

- [ ] Verify release appears on GitHub
- [ ] Test download link works
- [ ] Announce on social media (LinkedIn, etc.)
- [ ] Update any external documentation
- [ ] Create announcement (if major release)

---

## Notes

- Releases should only be created from the `main` branch
- Use semantic version tags: `v3.6`, `v4.0`, etc.
- Include release notes copied from CHANGELOG.md
- Link to documentation and installation guides
- Tag releases for discoverability

---

**Last Updated:** November 2025 (v3.6)


================================================
FILE: .github/workflows/pr-validation.yml
================================================
name: PR Validation

on:
  pull_request:
    branches: [main, main-candidate]
    types: [opened, synchronize, reopened]

jobs:
  validate:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'

      - name: Install dependencies
        run: |
          pip install gitpython

      - name: Validate commit messages
        id: validate_commits
        run: |
          python3 tools/validate_commits.py
        continue-on-error: true

      - name: Predict next version
        id: predict_version
        run: |
          CURRENT_VERSION=$(cat VERSION)
          PREDICTED_VERSION=$(python3 tools/bump_version.py --dry-run --type auto)
          echo "current=$CURRENT_VERSION" >> $GITHUB_OUTPUT
          echo "predicted=$PREDICTED_VERSION" >> $GITHUB_OUTPUT

      - name: Comment on PR
        uses: actions/github-script@v7
        with:
          script: |
            const currentVersion = '${{ steps.predict_version.outputs.current }}';
            const predictedVersion = '${{ steps.predict_version.outputs.predicted }}';
            const validateStatus = '${{ steps.validate_commits.outcome }}';

            const statusIcon = validateStatus === 'success' ? '✅' : '⚠️';
            const versionChange = currentVersion !== predictedVersion ?
              '**' + currentVersion + '** → **' + predictedVersion + '**' :
              '**' + currentVersion + '** (no change)';

            const body = '## ' + statusIcon + ' PR Validation\n\n' +
              '### 📦 Version Impact\n' +
              '- Current: **' + currentVersion + '**\n' +
              '- After merge: ' + versionChange + '\n\n' +
              '### 📋 Commit Message Guidelines\n' +
              'Use [Conventional Commits](https://www.conventionalcommits.org/):\n' +
              '- `feat:` - New feature (bumps minor version)\n' +
              '- `fix:` - Bug fix (bumps minor version)\n' +
              '- `docs:` - Documentation only (no version bump)\n' +
              '- `chore:` - Maintenance (no version bump)\n' +
              '- `BREAKING CHANGE:` - Breaking change (bumps major version)\n\n' +
              '**Examples:**\n' +
              '```\n' +
              'feat: add new trajectory smoother\n' +
              'fix: resolve modal centering issue\n' +
              'docs: update installation guide\n' +
              'chore: cleanup deprecated files\n' +
              '```\n\n' +
              '### 🤖 Automation\n' +
              'Once merged to `main`, the version will be automatically bumped and a release will be created.\n\n' +
              '---\n' +
              '*Generated by [Automated Release](https://github.com/${{ github.repository }}/actions/workflows/release.yml)*';

            // Find existing comment
            const { data: comments } = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
            });

            const botComment = comments.find(comment =>
              comment.user.type === 'Bot' &&
              comment.body.includes('PR Validation')
            );

            if (botComment) {
              // Update existing comment
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: botComment.id,
                body: body
              });
            } else {
              // Create new comment
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                body: body
              });
            }


================================================
FILE: .github/workflows/release.yml
================================================
name: Automated Release

on:
  push:
    branches: [main]
    paths-ignore:
      - '**.md'
      - 'docs/**'
      - '.github/**'
  workflow_dispatch:
    inputs:
      version:
        description: 'Manual version (e.g., 3.8) or leave empty for auto'
        required: false
        default: ''
      bump_type:
        description: 'Auto bump type if version empty'
        required: false
        default: 'auto'
        type: choice
        options:
          - auto
          - minor
          - major

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Fetch all history for commit analysis
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'

      - name: Install dependencies
        run: |
          pip install gitpython

      - name: Get current version
        id: current_version
        run: |
          CURRENT_VERSION=$(cat VERSION)
          echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
          echo "📌 Current version: $CURRENT_VERSION"

      - name: Bump version
        id: bump_version
        run: |
          if [ -n "${{ github.event.inputs.version }}" ]; then
            echo "🎯 Using manual version: ${{ github.event.inputs.version }}"
            python3 tools/bump_version.py --manual "${{ github.event.inputs.version }}"
          else
            echo "🤖 Auto-detecting version bump from commits"
            python3 tools/bump_version.py --type "${{ github.event.inputs.bump_type || 'auto' }}"
          fi

          NEW_VERSION=$(cat VERSION)
          echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
          echo "✅ New version: $NEW_VERSION"

      - name: Check if version changed
        id: version_check
        run: |
          OLD_VERSION="${{ steps.current_version.outputs.version }}"
          NEW_VERSION="${{ steps.bump_version.outputs.version }}"

          if [ "$OLD_VERSION" == "$NEW_VERSION" ]; then
            echo "changed=false" >> $GITHUB_OUTPUT
            echo "⏭️  No version change needed"
          else
            echo "changed=true" >> $GITHUB_OUTPUT
            echo "🎉 Version changed: $OLD_VERSION → $NEW_VERSION"
          fi

      - name: Generate release notes
        if: steps.version_check.outputs.changed == 'true'
        id: release_notes
        run: |
          python3 tools/generate_release_notes.py > release_notes.md
          echo "✅ Release notes generated"

      - name: Commit version bump
        if: steps.version_check.outputs.changed == 'true'
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add VERSION CHANGELOG.md src/__init__.py app/dashboard/drone-dashboard/package.json app/dashboard/drone-dashboard/src/version.js
          git commit -m "chore: bump version to ${{ steps.bump_version.outputs.version }}" -m "Automated version bump" -m "Co-Authored-By: github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
          git push

      - name: Create Git tag
        if: steps.version_check.outputs.changed == 'true'
        run: |
          git tag -a "v${{ steps.bump_version.outputs.version }}" -m "Release v${{ steps.bump_version.outputs.version }}"
          git push origin "v${{ steps.bump_version.outputs.version }}"
          echo "🏷️  Created tag: v${{ steps.bump_version.outputs.version }}"

      - name: Create GitHub Release
        if: steps.version_check.outputs.changed == 'true'
        uses: softprops/action-gh-release@v1
        with:
          tag_name: v${{ steps.bump_version.outputs.version }}
          name: v${{ steps.bump_version.outputs.version }}
          body_path: release_notes.md
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Summary
        if: steps.version_check.outputs.changed == 'true'
        run: |
          echo "## ✅ Release Complete!" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Version:** v${{ steps.bump_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
          echo "**Tag:** \`v${{ steps.bump_version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "🔗 [View Release](https://github.com/${{ github.repository }}/releases/tag/v${{ steps.bump_version.outputs.version }})" >> $GITHUB_STEP_SUMMARY


================================================
FILE: .gitignore
================================================
# Compiled Python files
**/__pycache__/
*.py[cod]
*.pyc
*.pyo
*.pyd
__pycache__/
.Python
.pyc
*$py.class

# Specific cache directories that were previously tracked
mavsdk/__pycache__/
src/__pycache__/
functions/__pycache__/
gcs-server/__pycache__/
mavsdk/bin/__pycache__/
# Packages
*.egg
*.egg-info/
dist/
build/
eggs/
parts/
bin/
var/
sdist/
develop-eggs/
.wheelhouse/
.installed.cfg
MANIFEST

# Path images and generated trajectory files to reduce pull time
shapes/plots/*.jpg
shapes/trajectory/
shapes_sitl/trajectory/
artifacts/
shapes/**/.trajectory_session.json
shapes_sitl/**/.trajectory_session.json
# CRITICAL: DO NOT ignore processed directories - these contain mission-critical drone trajectory files
# that must be version controlled for safety, traceability, and team collaboration
# shapes/swarm/processed/
# shapes_sitl/swarm/processed/



# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
coverage_html/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
junit.xml

# Translations
*.mo
*.pot

# Django stuff
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff
instance/
.webassets-cache

# Scrapy stuff
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints/

# PyCharm
.idea/

# VSCode
.vscode/

# Environment files
.venv/
env/
venv/
ENV/
env.bak/
venv.bak/

# Ignore environment variables
.env

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/

# Temporary files
*.temp
*.tmp
*.swp
*~

# Backup files
*.backup
*.bak
*_bak.py
*_old.py

# Logs — session files and symlinks (never committed)
logs/
logs/sessions/
logs/current
*.log
*.jsonl
gcs-server/logs/
# Re-include source component directories named logs
!app/dashboard/drone-dashboard/src/components/logs/

# Test and optimization files
test_logging_optimizations.py
cached_files.txt
/test_config*.py
/offboard_multiple*.py

# Local configuration files
/local_config.yml
/local_config.xml
/online_config.json
/data/origin.json
/.mds_sitl_image_build.env
/.mds_px4_source_provenance.env
/.mds_px4_submodules.txt

# Specific binary and hardware ID files that should not be committed
/mavsdk_server
/mavsdk_server*
/*.hwID
/real.mode

*Zone.Identifier

# Node modules
node_modules/

# Empty npm artifact files
react-scripts
drone-dashboard@*

# Production files
dist/

# Credentials
*.pem
*.key

# Database
*.db
*.sql

# OS generated files
.DS_Store
Thumbs.db

# Dependencies
.pnp/
.pnp.js

# Testing
/coverage/

# Production
/build/

# Miscellaneous
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

app/dashboard/drone-dashboard/.env
app/dashboard/drone-dashboard/.env.bak
*.ZoneIdentifier
.claude/settings.local.json
QUICKSCOUT_IMPLEMENTATION_PROMPT.md

# Build artifacts & temp
multiple_sitl/**/build/
.benchmarks/
temp/
runtime_data/


================================================
FILE: AGENTS.md
================================================
# MDS Agent Operating Spec

This file is the canonical machine-oriented operating spec for terminal AI agents working in this repository.

## Scope

- Applies to the full repository unless a deeper-scoped agent instruction file overrides it.
- Intended for Codex, Claude Code, Gemini CLI, and similar future terminal agents.
- Optimize for correctness, auditability, low-noise operation, and clean handoff state.

## Core Mission

Use a disciplined loop to audit, reproduce, fix, validate, document, package, and hand off MDS changes across:

- local Ubuntu/Linux workstations
- same-box VPS workflows
- remote SSH validation hosts
- official repo/branch or customer-specific repo/branch
- official stock SITL image or custom validated image

Do not assume the environment. Detect it first.

## Non-Negotiables

- Prefer the existing repo workflows and docs over inventing new ones mid-task.
- Treat git as the source of truth. Do not normalize `docker commit` as a release workflow.
- Keep a single source of truth for configuration and operator behavior.
- Use unified logs as the first debugging surface before speculative fixes.
- Keep code changes minimal, explainable, and test-backed.
- If behavior changes, update the relevant docs and any validation tooling in the same phase.
- If repeated findings show the agent docs are incomplete, propose or apply a focused update when the user approves.
- If the current branch/worktree is dirty, do not overwrite unrelated user changes.
- Do not perform destructive cleanup or reset actions unless explicitly required and safe.

## Read First

Before substantial work, inspect the current repo state and then read only the docs relevant to the task:

1. `README.md`
2. `docs/README.md`
3. `CHANGELOG.md`
4. Task-specific docs:
   - SITL bootstrap/runtime: `docs/guides/sitl-comprehensive.md`
   - custom image/release flow: `docs/guides/advanced-sitl.md`, `docs/guides/sitl-custom-release-workflow.md`
   - full SITL agent loop: `docs/superpowers/specs/2026-03-26-ai-agent-sitl-audit-loop.md`
   - Drone Show: `docs/features/drone-show.md`
   - Smart Swarm: `docs/features/smart-swarm.md`
   - origin/coordinates: `docs/features/origin-system.md`, `docs/control-modes-and-coordinates.md`
   - logs/debugging: `docs/guides/logging-system.md`
   - GCS/API behavior: `docs/apis/gcs-api-server.md`, `docs/apis/drone-api-server.md`

If docs and code disagree, verify the code path and then fix the docs.

## Environment Detection

Determine these before changing anything important:

- active repo path
- active branch and HEAD commit
- worktree cleanliness
- whether the task is local-only or uses a remote validation host
- whether SITL runs on the same machine or a remote machine
- whether the deployment uses:
  - official repo + `main-candidate`
  - custom repo URL
  - custom branch
  - official stock SITL image
  - custom/pinned SITL image
- whether runtime startup sync is enabled (`MDS_SITL_GIT_SYNC`)

Never hardcode `/opt`, `/root`, hostnames, repo URLs, or branch names without verifying them.

## Standard Agent Loop

1. Build context
   - inspect repo status, recent commits, relevant docs, and relevant code paths
   - identify whether the issue is code, environment, docs, data, image, or operator misunderstanding
2. Reproduce
   - use the smallest reproducible path
   - prefer existing validation tools and unified logs before manual probing
3. Isolate
   - identify the failing layer: dashboard, GCS, API, git sync, Docker image, PX4/SITL, mission logic, network, or docs
4. Fix cleanly
   - preserve architecture and naming consistency
   - prefer shared helpers and parameterization over one-off patches
5. Validate locally
   - run the narrowest checks that prove the fix
   - expand only as needed
6. Validate end to end
   - rerun the real operator workflow when behavior affects runtime missions or release paths
7. Update docs
   - update only the relevant docs, guides, or changelog entries
8. Decide release impact
   - if runtime or image contents changed, determine whether image rebuild/package/upload is required
   - if docs-only changed, do not rebuild a release image unless strict provenance alignment is explicitly desired
9. Leave a clean handoff
   - summarize what changed, what was verified, what remains optional, and exact commit/tag state

## SITL Audit / Debug / Release Loop

When working on SITL-backed features or regressions:

1. verify prerequisites from the current guide rather than memory
2. load the correct image or build the correct validated image
3. launch GCS/dashboard using the documented mode
4. create SITL containers using the documented workflow
5. confirm health/readiness via API, dashboard, and logs
6. run scenario-specific validation:
   - Drone Show
   - Smart Swarm
   - QuickScout
   - logging / export / UI flow
7. inspect unified logs first:
   - GCS logs
   - drone logs
   - frontend/log viewer if relevant
8. if fixes are needed:
   - patch code
   - rerun targeted tests
   - rerun the live SITL scenario
9. if the validated runtime changed:
   - rebuild clean image using the documented release workflow
   - export/package/checksum
   - upload/replace distribution artifact
   - update public docs links only after the new artifact is live

## Release Decision Boundary

Rebuild and redistribute the SITL image when one of these is true:

- the runtime filesystem changed
- startup scripts changed
- baked dependencies changed
- packaged mission assets changed
- documented public behavior depends on new runtime/image contents

Do not rebuild the public image for docs-only clarifications unless exact image-to-commit provenance is a deliberate release goal.

## Logging and Evidence

- Prefer unified logs over ad hoc terminal output.
- Distinguish signal from polling noise.
- Preserve operator clarity: high-signal `INFO`, actionable `WARNING`, true failures at `ERROR`, detailed loops at `DEBUG`.
- When evaluating behavior, cite the exact log/event/API evidence that supports the conclusion.

## Decision Boundaries for Asking the User

Ask only when a decision is genuinely external or risky, for example:

- destructive cleanup of user data or unrelated changes
- credentials, policy, licensing, or customer-specific release choices
- ambiguous operator behavior where multiple valid semantics exist
- real-aircraft safety, regulatory, or field-procedure decisions

Otherwise, make the best technical decision, document it, and continue.

## Future-Proof Agent Guidance

- Use newer agent capabilities when available if they improve safety, verification, or throughput:
  - planning/todos
  - subagents
  - worktrees
  - MCP/tools integrations
  - web research
  - structured memory/context files
- Do not assume older limitations or older product behavior still apply.
- When tool/platform behavior may have changed, verify current official docs before relying on memory.
- Prefer vendor-neutral repo structure with thin vendor-specific shims over duplicating the full operating spec in multiple files.

## Repo Conventions for Agent Context

- Canonical repo-wide agent instructions live in this file: `AGENTS.md`
- Detailed SITL audit/debug/release companion spec lives at:
  - `docs/superpowers/specs/2026-03-26-ai-agent-sitl-audit-loop.md`
- Vendor shims may exist at repo root:
  - `CLAUDE.md`
  - `GEMINI.md`
- Human-facing docs should link to agent instructions minimally, not duplicate them

## Expected Output at Phase End

At the end of a substantial phase, provide:

- branch and commit/tag state
- what changed
- what was validated
- what remains optional vs required
- whether release artifacts/docs were refreshed
- whether the phase is ready for testers, operators, or deployment


================================================
FILE: CHANGELOG.md
================================================
# Changelog

All notable changes to MAVSDK Drone Show (MDS) project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project uses simple two-part versioning: `X.Y` (Major.Minor).

---

## [5.2] - 2026-04-19

### Added
- Custom SITL/private repository authentication handoff:
  documented public, public-fork, and private-repo auth paths; added
  non-interactive Git access preflight for SITL runtime sync and image
  preparation; and verified private SSH read/write operation on Hetzner.
- Operator-friendly Mission Config optional-field templates for `callsign`,
  `marker_color`, `notes`, and `role_hint`.

### Changed
- Dashboard startup, SITL launcher, and image-release scripts now propagate
  read-only SSH/token auth settings consistently into child preflight checks.
- Private SITL image workflow now closes on a flattened `latest` image at the
  validated client branch, while public official usage remains unauthenticated.

---


## [Unreleased]

### Added
- Root `Makefile` command index for common GCS startup, bootstrap, fleet sync,
  SITL reconcile, and validation commands, plus an operator guide documenting
  that `make` targets are thin wrappers around canonical scripts/APIs.
- `tools/sitl_stop_all.py`, a small stdlib-only helper used by `make sitl-stop`
  to remove local SITL containers through the supported SITL Control API.

### Changed
- Fleet Ops node cards now expose compact per-node sidecar dashboard shortcuts
  and use a more stable mobile card layout for node identity, status pills, and
  quick actions.
- Active installer, dashboard, docs-link, SITL image, and git-sync defaults now
  use `main` as the canonical deployment branch; feature/client branches remain
  explicit overrides through `MDS_BRANCH`.
- SITL image selection now has a git-tracked deployment default, so official
  and private deployments can publish/use different validated images without
  manual `MDS_DOCKER_IMAGE` overrides.
- Dashboard drone cards were compacted for mobile/operator use by reducing
  repeated visual weight and keeping telemetry indicators in a denser grid.

### Fixed
- 3D Globe filter controls now open as a scene-local modal layer above drone
  labels/cards, with click-away dismissal and disabled drone touch targets
  while filters are open.

---

## [5.3] - 2026-04-25

### Added
- Node git auth visibility on fleet surfaces:
  drone git-status payloads now expose repo access posture plus node-local git
  auth health summary/issues without leaking secret file paths, and the GCS git
  aggregation/dashboard surfaces now carry those warnings through to operators.
- Node managed-runtime visibility on fleet surfaces:
  drone git-status payloads now carry compact node-local `mavlink-anywhere`
  and Smart Wi-Fi runtime posture, and the GCS git aggregation/dashboard now
  resolves whether each node dashboard is directly reachable, local-only, or
  disabled before exposing operator links.
- Node post-sync runtime visibility:
  node git sync now records a durable local post-sync runtime summary
  (updated units, coordinator restart scheduling, connectivity reconcile
  result, MAVLink runtime reconcile result, requirements update posture), and
  that summary is exposed through node/GCS git-status surfaces.
- GCS Runtime mixed-mode preflight visibility:
  runtime status/config now report local SITL inventory count, and Runtime
  Admin warns before REAL-mode restart when local SITL containers would remain
  running and only be heartbeat-fenced rather than stopped automatically.
- GCS Runtime local sidecar entry points:
  the GCS-local GCS Runtime view now links directly to the local
  `mavlink-anywhere` and Smart Wi-Fi dashboards when present.
- GCS Runtime constrained GCS self-update:
  GCS Runtime now exposes a fast-forward-only `Update GCS` action that
  fetches the tracked upstream, blocks dirty/diverged/no-upstream states, and
  refuses updates touching launcher, frontend, tooling, or dependency paths.
- Fleet Ops Smart Wi-Fi profile import:
  added secret-safe GCS APIs and a dashboard action for importing the
  repo-owned Smart Wi-Fi fleet profile, returning only hashes/status/counts and
  using the existing Sync + reconcile path for node rollout.

### Changed
- Mobile sidebar layering and scrolling were hardened: the drawer now sits above
  the backdrop at modal z-index, owns mobile touch scrolling, and uses an opaque
  mobile light background so it does not appear disabled or faded.
- GCS Runtime is now explicitly GCS-host scoped: git access hides raw secret
  paths, GCS-local sidecar dashboard links were removed from the primary
  layout, and sidecar/tool state is summarized as host capability context while
  per-drone compliance is reserved for Fleet Ops.
- Mobile runtime chrome is now sidebar-owned: the standalone mobile runtime
  pill was removed from the page shell, the hamburger overlay no longer blurs
  the dashboard, and the sidebar keeps a compact clickable `REAL`/`SITL`
  runtime badge that opens GCS Runtime.
- SITL mutable latest-on-boot launches now default to the host-mounted current
  `startup_sitl.sh`, while pinned-image launches stay on the image-baked
  bootstrap path.
- GCS launcher restarts now push the current runtime env allowlist into each
  fresh tmux session and inline-export the same values in the first pane
  command before starting backend/frontend processes, preventing stale tmux
  server or pane-shell state from pinning the runtime mode back to old
  `MDS_MODE` values after an operator-triggered restart.
  script, and SITL policy/inventory now surface that startup-script source so
  operators can see which bootstrap path is active.
- SITL startup no longer carries the retired `HWID_DIR` shell reference, so
  host-mounted bootstrap scripts no longer crash under `set -u` during early
  container startup.
- SITL Control now stays available in `REAL` mode as a cleanup-only surface:
  local SITL inventory, logs, operations, and remove remain available for
  leftover containers, while create/reconcile/restart/image-save actions stay
  blocked until the GCS returns to `SITL` mode.
- GCS tmux startup now waits briefly for fresh panes/windows before sending the
  backend/frontend launch commands, reducing intermittent empty-session
  launches under live host load.
- GCS Runtime update-readiness is now actionable rather than advisory only:
  safe runtime/config/docs-only updates can be scheduled directly from the GCS
  host, while higher-risk repo mutations are explicitly redirected to the
  manual update path.
- GCS launcher build detection no longer relies on the coarse `build/`
  directory mtime; it now compares real React build markers plus `src/`,
  `public/`, `.env`, `VERSION`, and dependency manifests so routine runtime
  restarts do not trigger unnecessary production frontend rebuilds.
- GCS Runtime repo update-readiness visibility:
  runtime status now carries a typed GCS repo sync/update posture, and Runtime
  Admin shows whether the host is up to date, behind and fast-forwardable,
  dirty, ahead, divergent, or missing an upstream before any self-update path
  is exposed.
- dashboard/operator refinement for final tester handoff:
  drone cards now support direct command-scope toggles, per-drone jog access,
  per-drone mission cancel affordances, quieter command-history monitoring,
  cleaned lifecycle toast wording for Smart Swarm/runtime actions, stable
  non-jitter card state styling, and compact `Pn|Hm` labels in the 3D globe
  visibility controls
- Smart Swarm tracking-analysis workflow:
  added `tools/analyze_smart_swarm_tracking.py`, focused tests, and operator
  docs so maintainers can capture expected vs actual follower tracking during
  repeated leader jogs and mixed body/NED frame changes using the dedicated
  Smart Swarm websocket stream instead of the lower-rate operator telemetry
  aggregate
- Smart Swarm runtime transport/control hardening:
  follower-to-leader state now uses a dedicated realtime swarm-state stream
  (`WS /ws/swarm-state`) with `GET /api/v1/swarm/state` HTTP fallback, telemetry
  freshness now uses millisecond timestamps plus sequence tracking instead of
  second-resolution `update_time` only, follower control now includes
  leader-velocity feedforward and yaw-rate body-frame compensation, live
  topology/offset changes reset and blend controller state cleanly, and the
  drone runtime now persists canonical per-command fields such as
  `update_branch`, `reboot_after_params`, and `precision_move_request_file`
  while exposing `home_position_set` / telemetry-staleness truth correctly in
  drone-state responses
- SITL Control final operator refinement:
  all instance rows now default to collapsed click-open behavior across
  mobile/tablet/desktop, `Ops` stays closed unless explicitly toggled,
  reconcile/add/restart/remove/batch/image-save now use a shared confirmation
  dialog pattern, filtered visible-scope batch restart/remove is available for
  larger fleets, minimal host resource warnings are shown inline, and the
  dashboard now exposes a typed image-save workflow backed by the canonical
  SITL release script instead of ad hoc container snapshots
- official `System -> SITL Control` V1 for temporary local SITL hosts:
  typed GCS supervisor APIs now expose host/image/instance inventory,
  tracked reconcile/restart/remove operations, and tailed instance logs, while
  the dashboard adds a dedicated responsive SITL Control page with beginner
  defaults, folded advanced overrides, and live-validated Docker lifecycle
  control against real Hetzner SITL containers
- SITL Control UX/log hardening:
  restart/remove now keep the inventory visible with instance-local pending
  state instead of dropping the page into a full-screen reload shell, the
  instance list now supports scan-first search/filtering for larger fleets, the
  reconcile form now uses auto-populated image repo/tag selectors with folded
  manual override, and instance logs now fall back to file-backed SITL runtime
  logs when Docker log output is empty
- SITL Control operator refinement:
  image inventory and operation history are now collapsed secondary panels,
  the instance list is the primary scalable work surface, image selectors are
  split cleanly into repo/tag with auto-discovered choices, instance cards now
  show compact repo/image identity, and operators can add one new `drone-N`
  without pruning the existing fleet, including optional custom ID/IP for
  advanced sparse-layout test cases
- SITL Control interaction hardening:
  background refresh now stays visually quiet instead of flashing a visible
  page-level refresh state, compact/mobile layouts expand the selected
  instance detail inline near the chosen row while wide desktop keeps the
  docked detail panel, `Add next` and exact-slot add are grouped into one
  clearer control cluster, and poll-driven SITL errors now use a reusable
  throttled-toast helper instead of repeating the same failure toast on every
  refresh cycle
- `tools/sitl_control_client.py` as the reusable headless SITL Control client
  for validators, AI agents, and future MCP tooling; the declarative SITL
  validation suite now defaults to API-first fleet resets with shell fallback,
  and the SITL validation / automation docs now explicitly treat raw
  `create_dockers.sh` usage as the cold-start path rather than the primary
  steady-state lifecycle interface
- refreshed the public official SITL archive publication and download
  instruction link, and published the matching private customer SITL archive
  to a dedicated MEGA target after validating the customer 3-drone Hetzner
  SITL gate on the private image
- documented private Git token expiry recovery in the custom-repo and custom
  SITL release guides after validating the private customer image-build
  path on Hetzner
- private GitHub bootstrap/runtime auth is now first-class for customer-style
  GCS and node workflows when deploy keys are unavailable:
  `install_gcs.sh`, `install_mds_node.sh`, `mds_gcs_init.sh`,
  `mds_node_init.sh`, the repo helpers, the runtime launcher, and the runtime
  git-sync path now all understand `MDS_GIT_AUTH_TOKEN_FILE` /
  `--git-auth-token-file` and keep that token-file source of truth aligned
  from bootstrap through later repo sync
- the GCS repository phase now respects explicit private HTTPS repo selection

### Fixed
- git-sync post-sync service policy is now explicit and regression-tested:
  coordinator restarts are scheduled only when appropriate, inactive
  coordinator runtimes stay intentionally stopped after sync, `git_sync_mds`
  unit updates reapply safely without trying to restart the running sync job,
  and the node-local env template now points at the canonical
  `coordinator.service` unit name
- shell-level runtime posture is now visible even when navigation is collapsed:
  the sidebar uses one shared runtime badge in expanded and collapsed states,
  mobile now keeps the same REAL/SITL badge visible beside the navigation
  toggle, and restart-required drift is surfaced directly in that shell badge
  instead of only inside GCS Runtime
- drone-card runtime labels now follow the same canonical `runtime_mode`
  signal that the backend heartbeat fence uses:
  Mission Config cards prefer the node-declared mode over local serial/network
  heuristics, badge REAL/SITL explicitly instead of the ambiguous old
  `Hardware` label, and mark whether the displayed posture was declared by the
  node heartbeat or inferred as a fallback when legacy nodes have not yet
  upgraded
- heartbeat intake is now runtime-mode aware:
  nodes can declare `runtime_mode`, GCS fences mismatched SITL/REAL heartbeats
  before they contaminate live state, heartbeat/network snapshots now retain the
  accepted mode, and GCS Runtime can safely rely on a backend-side
  mixed-mode guard instead of only frontend filtering
- `PUT /api/v1/system/gcs-config` no longer pretends to persist everything:
  the route now safely writes only host-local `MDS_MODE` /
  `MDS_GIT_AUTO_PUSH` into `/etc/mds/gcs.env`, reports
  running-vs-configured drift explicitly, and warns instead of silently
  accepting unsupported fields such as `gcs_port` or
  `acceptable_deviation`
- GCS Runtime host-local apply semantics are now explicit:
  `POST /api/v1/system/gcs-config/apply` compares the running process against
  `/etc/mds/gcs.env`, schedules a controlled relaunch through the canonical GCS
  launcher only when drift exists, debounces repeated requests, and warns when
  SITL instances are still running during a switch back to real mode
- dashboard first-load delivery on weak/mobile links:
  the lightweight SPA server now serves gzip-compressed large text assets,
  marks fingerprinted `/static/...` files immutable, disables caching for the
  HTML shell, and the dashboard now route-splits heavy primary views so the
  initial bootstrap bundle no longer blocks first paint behind a multi-megabyte
  uncompressed `main.*.js`
- Smart Swarm official runtime closeout:
  leader-only commands and repo sync target selection now treat a drone as
  recently online when either heartbeat or telemetry freshness proves the link
  is alive, Smart Swarm followers now force a leader-stream reconnect when the
  assigned leader changes live instead of continuing to consume the old
  leader's stream, drone git-status now routes through the shared git manager
  so custom branches without an upstream return a clean report instead of
  logging fatal `@{u}` noise, and SSH repo sync no longer performs a redundant
  final `git pull` that could fail on custom branches after fetch+reset had
  already pinned the runtime to `origin/<branch>`; the Smart Swarm validator
  now also includes an optional SITL leader-dropout/failover drill, and the
  production GCS launcher disables Gunicorn worker recycling by default for the
  stateful single-worker runtime so command tracking does not disappear mid-run
  during long acceptance drills
- `linux_dashboard_start.sh` now exports the runtime git auth variables from
  `/etc/mds/gcs.env`, keeps the real-mode marker at the repo root `real.mode`
  where the rest of MDS expects it, and prints canonical
  `/api/v1/system/health` examples instead of stale `/health` guidance
- a 2026-04-12 private customer bootstrap/runtime validation note documenting
  the deploy-key-disabled private-customer validation path, the live Hetzner
  private-repo bootstrap and runtime verification, the discovered GitHub
  temporary-clone-token expiration behavior, and the remaining external
  blocker that the field hardware node is currently idle/unreachable on the
  overlay network
- a 2026-04-11 official bootstrap hardware closeout note documenting the final
  official wrapper and existing-node bootstrap behavior on real ARM companion
  hardware, the validated overlay -> Hetzner GCS candidate announce flow, the
  cleaned node identity/local-env generation, the shell-hardening fixes across
  verification/NTP/MAVSDK bootstrap paths, and the remaining non-blocking
  follow-up work before moving entirely into the private client fork rollout
- a 2026-04-11 hardware-demo confirmation brief locking the final decisions
  that bootstrap should not auto-edit `src/params.py`, that node runtime still
  standardizes on the `droneshow` user while GCS remains user-flexible, that
  the Hetzner GCS and reachable hardware companion are both now verified on
  the overlay network, and that the remaining implementation work should focus
  on wrapper auth ordering, overlay-peer reuse, post-enrollment sync, and
  stale config/docs cleanup before any private customer demo fork
- a 2026-04-11 hardware-demo final review note consolidating the final
  operator-facing bootstrap philosophy, the answer that customer operators
  should not edit `src/params.py` for repo selection, the provider-neutral
  network doctrine, the post-enrollment node-sync requirement, and the
  remaining official must-fix items before starting a private customer demo
  deployment
- a 2026-04-11 hardware-demo workflow clarification note answering the wrapper
  versus repo-local init philosophy directly, documenting the recommended
  official-wrapper-plus-target-repo model, clarifying real-hardware
  permissions, NetBird reuse/rebind expectations, the post-enrollment node
  sync requirement, and the remaining must-fix items before a private
  customer hardware demo rollout
- a 2026-04-11 hardware demo preflight audit brief documenting the current
  canonical node/GCS bootstrap and Fleet Enrollment workflow, the still-open
  first-time private-repo bootstrap blocker in both wrapper installers, the
  recommended private customer repo/auth model, the `mavlink-anywhere` audit,
  and the exact must-close checklist before starting a customer-specific demo
  fork or first real-hardware deployment
- a 2026-04-11 onboard ULog runtime closeout note documenting the new
  Log Viewer `Onboard ULog` workflow, the drone/GCS API surfaces, the
  filesystem fallback used when SITL-side MAVSDK log enumeration is not
  available, the passing live Hetzner `ulog_runtime` validator, and the
  browser-test handoff expectations for list/download/erase behavior
- onboard PX4 ULog management v1 across the drone API, GCS log proxy, and
  dashboard Log Viewer: operators can now list file-backed onboard ULogs for a
  selected drone, stage a browser download with progress polling, and erase
  all onboard ULogs while keeping compact `Pn|Hm` identity visible in the UI
- a reusable `ulog` SITL validator mode plus the checked-in `ulog_runtime`
  bundled plan and `ulog_only` template, so list/download/erase behavior can
  be revalidated on fresh containers instead of relying on manual log checks
- a 2026-04-11 onboard ULog management design brief documenting the current
  MDS log-viewer integration points, the MAVSDK/PX4/MAVLink feasibility audit
  for list/download/erase operations, the file-backed-versus-streaming split
  for SITL and real hardware, and the recommended phased implementation plan
- QuickScout runtime monitoring now treats MAVSDK mission-progress callbacks as
  optional hints instead of the sole completion signal, adds bounded upload /
  start / airborne / post-action timeouts plus a bounded arm-RPC timeout in the
  shared startup seam, and keeps slot-plus-hardware identity visible in the
  QuickScout monitor cards so live operator context stays consistent with the
  wider enrollment / identity doctrine
- a 2026-04-11 QuickScout runtime acceptance closeout note documenting the
  hardened runtime-monitoring path, the refreshed clean-sync Hetzner validator
  flow, the passing focused backend/frontend validation batches, and the green
  all-mode `operator_regression` SITL acceptance suite on `ff519535`
- a 2026-04-10 enrollment/identity release-closeout note documenting the
  explicit slot-vs-hardware operator doctrine across Mission Config, Smart
  Swarm, Swarm Trajectory, QuickScout, and Fleet Enrollment, the shared UI
  identity guidance strips, the detached-worktree git/runtime fixes, the full
  green Hetzner `operator_regression` acceptance pass, and the refreshed public
  SITL archive publication
- a 2026-04-10 node-enrollment phase closeout note documenting the final
  `hw_id` / `pos_id` / `mav_sys_id` doctrine, the operator decision tree for
  new-node acceptance versus same-airframe recovery versus spare replacement
  versus ordinary slot swaps, the Smart Swarm `hw_id` rationale, and the
  remaining explicit post-v1 debt
- a 2026-04-10 combined node-enrollment and `mavlink-anywhere` review note
  documenting the final bootstrap/enrollment scenario guidance, the clarified
  `hw_id` / `pos_id` targeting doctrine, the current on-device identity files,
  the QuickScout slot-selection consistency fix, and the non-breaking
  improvement plan for `mavlink-anywhere`
- explicit 2026-04-10 identity-targeting doctrine guidance documenting when
  MDS should stay `hw_id`-anchored versus when high-level mission planners may
  remain `pos_id`-anchored and resolve to current hardware at launch, plus
  clarified bootstrap-wrapper versus init-engine usage and on-device identity
  file locations
- a 2026-04-10 consolidated node-enrollment and identity-alignment brief
  documenting the current bootstrap/candidate/enrollment workflows, the
  scenario-by-scenario operator guidance, the `hw_id` / `pos_id` / `mav_sys_id`
  doctrine for cross-mode consistency, the public standards references checked,
  and the explicit post-v1 `mavlink-anywhere` / identity-model follow-up debt
- a 2026-04-10 node-bootstrap and fleet-enrollment v1 recap note documenting
  the implemented workflow boundaries, the operator scenarios for accept /
  replace / recover, the current post-v1 deferred items, and the tester-facing
  caveats for hardware rollout and future automation
- a 2026-04-10 node-bootstrap candidate-announce checkpoint note documenting
  the new canonical `mds_node_announce.sh` helper, the `mds_node_init.sh`
  announce integration, the expanded node manifest/bootstrap report fields, the
  active docs/headless-automation cleanup, and the paired local / Hetzner
  validation results
- a 2026-04-10 fleet-enrollment operator-workflow checkpoint note
  documenting the dedicated `Fleet Enrollment` page, the new same-hardware
  recovery route, the retirement of the old `ReplaceDroneWizard`, the Mission
  Config cutover onto the canonical enrollment workflow, and the paired local /
  Hetzner validation results
- a 2026-04-10 Mission Config pending-enrollment cutover checkpoint note
  documenting the removal of heartbeat-driven auto-add, the new derived
  pending-candidate review panel, the replacement-wizard standby-node reuse,
  and the focused Hetzner validation/build results for the safer fleet
  enrollment transition
- a 2026-04-10 node-bootstrap phase 1 foundation checkpoint note documenting
  the generic companion-node bootstrap cleanup, the new
  `/etc/mds/node_identity.json` manifest, the optional `--report-json` machine
  output seam, the active-doc alignment for cloning/automation workflows, and
  the validation boundary before candidate-enrollment work begins
- a 2026-04-10 node-bootstrap and fleet-enrollment design brief documenting
  the current `install_mds_node.sh` / `mds_node_init.sh` provisioning stack audit, the
  recommendation to retire heartbeat-driven auto-add and the deprecated
  `raspberry_setup.sh` path, the proposed candidate-registration workflow,
  the real-hardware replacement/recovery scenarios, and the phased automation /
  MCP-friendly implementation plan
- deferred guidance for converging `INIT_SYSID` onto the shared PX4 parameter
  service later, while keeping it out of the main runtime PX4 Parameters page
  until the broader action-pipeline audit is active, plus explicit deferral of
  firmware/build identity display until a clean vehicle-served source is added
- a 2026-04-09 PX4 Parameters scan-first UI refinement note documenting the
  dialog-first desktop/mobile inspection flow, the reduced compact-card and
  desktop-table density, the cleaner metadata grouping, the refreshed Hetzner
  browser stack, and the focused frontend validation/build results
- explicit PX4 parameter metadata-source-order guidance documenting the
  production doctrine for vehicle-served metadata, local PX4 catalog fallback,
  optional read-only docs caching, and the deferred hardware-grade metadata
  cache follow-up
- a 2026-04-09 PX4 Parameters responsive handoff refinement note documenting
  the compact/mobile inspector flow, the explicit skip-offline batch behavior,
  the tracked single-drone PX4 reboot control, and the refreshed Hetzner
  frontend validation/build results
- a 2026-04-09 PX4 parameter workspace phase 2 checkpoint note documenting the GCS diff/import/patch-job routes, the new dashboard `PX4 Parameters` page, the reusable runtime validator scaffold, the batch scope reuse, and the paired backend/Hetzner frontend validation results
- `docs/px4-parameters.md`, a dedicated operator/developer guide for the new GCS-managed PX4 parameter workflow, metadata source rules, QGC interoperability, and current deferred follow-up items
- a 2026-04-09 PX4 parameter-management foundation checkpoint note documenting the new shared `px4-params` models, the drone-local MAVSDK param facade, the canonical drone/GCS snapshot routes, the runtime docs-link policy envelope, and the focused `50 passed` backend validation batch
- a 2026-04-09 PX4 parameter-management design brief documenting the current raw-MAVSDK-only state, the recommended dedicated `px4-params` subsystem, the planned single-drone and batch workflows, the QGC/PX4/MAVLink research findings, and the phased implementation plan
- a 2026-04-08 QuickScout tester-handoff checkpoint note documenting the implemented v1 feature set, the shared map/workspace consistency review versus Swarm Trajectory, the current post-v1 debt, and the recommended browser test flows and expected outcomes
- a 2026-04-08 QuickScout template-complete runtime-validation phase 18 checkpoint note documenting the new area/corridor runtime builders, the reusable template-regression SITL plans, the live Hetzner area/corridor drills, and the passing reset-backed QuickScout template regression suite
- a 2026-04-08 QuickScout findings-aware runtime-validation phase 17 checkpoint note documenting the live single-drone and multi-drone handoff/evidence validator passes, the updated reusable QuickScout plan semantics, and the narrowed remaining post-v1 QuickScout debt
- a 2026-04-08 QuickScout findings cleanup and follow-up checkpoint note documenting the findings-only contract cleanup, the removal of public `/api/sar/poi` aliases, the finding-led follow-up search seed flow, the map focus fix, and the paired local/Hetzner validation results
- a 2026-04-08 QuickScout multi-drone SITL-platform checkpoint note documenting the new reusable `quickscout` validator mode, the stable bundled `quickscout_runtime` plan, the multi-drone last-known-point runtime drill, and the paired local/Hetzner validation results
- a 2026-04-08 QuickScout runtime-validation checkpoint note documenting the live launch-path debugging chain, the fresh-container Hetzner validator pass, the local regression additions for the mission executor, and the remaining next-slice QuickScout execution work
- a 2026-04-08 QuickScout execution-semantics phase 13 checkpoint note documenting the new operator-facing mission phases, honest control-availability contract, follow-up-planning guidance, and the paired local/Hetzner validation results
- a 2026-04-08 QuickScout point-geometry phase 9 checkpoint note documenting the point-search geometry utility, the point-centered map radius preview, the derived footprint guidance, and the focused Hetzner frontend validation/build results
- a 2026-04-08 QuickScout template-foundation phase 8 checkpoint note documenting the new mission-template contract, the first `last_known_point` search flow, the template-aware workspace recovery/signature logic, and the paired local/Hetzner validation results
- a 2026-04-08 QuickScout launch-review phase 7 checkpoint note documenting the new stale-package recompute gate, the shared preflight-backed launch-review card, the planning-signature and launch-readiness utilities, and the focused Hetzner frontend validation/build results
- a 2026-04-08 QuickScout mission-briefing phase 6 checkpoint note documenting the new durable mission label/profile/brief metadata, the recovered workspace hydration updates, the mission-catalog display improvements, and the paired local/Hetzner validation results
- a 2026-04-08 QuickScout operator setup phase 5 checkpoint note documenting the new planning profile presets, explicit QuickScout end-behavior controls, the operator-setup sidebar refactor, and the focused Hetzner validation/build results
- a 2026-04-08 QuickScout workspace recovery UI phase 4 checkpoint note documenting the reusable saved-mission workspace panel, the QuickScout page recovery/hydration flow, the new page-level recovery tests, and the focused Hetzner validation/build results
- a 2026-04-08 QuickScout recovery phase 3 checkpoint note documenting the new mission catalog/workspace recovery endpoints, the matching SAR frontend service hooks, the route-inventory update, and the paired local/Hetzner validation results
- a 2026-04-08 QuickScout command-lifecycle phase 2 checkpoint note documenting the shared tracked-submit extraction, the new QuickScout tracked launch/control responses, the mission-scope targeting fix, the abort-behavior mapping fix, and the paired local/Hetzner validation results
- a 2026-04-07 QuickScout foundation phase 1 checkpoint note documenting the new durable SQLite-backed QuickScout store, the backend service boundary that replaces the old in-memory mission/POI managers, the stricter live-GPS planning gate, the camera-interval waypoint persistence, and the focused backend validation results
- a 2026-04-07 Mission Config launch-map polish checkpoint note documenting the Google-satellite default, tighter launch-layout fit behavior, zoom-adaptive marker styling, always-reviewable Origin status affordance, and the focused Hetzner React validation/build results
- a 2026-04-07 Mission Config actionable-alert checkpoint note documenting the new clickable Mission Config review alerts, the origin-loading versus origin-missing distinction, the origin-workflow jump action, the zero-origin Mission Layout export fix, and the focused Hetzner React validation/build results
- a 2026-04-07 Mission Config launch-map and git-sync finalization checkpoint note documenting the new expected/live Leaflet launch map, zero-origin handling fix, click-through card parity, explicit sync target branch/commit reporting, and the final live Hetzner runtime cleanup
- a 2026-04-07 advanced SITL regression checkpoint note documenting the new integrated mixed-mode leader-override validator, the runtime mission-state root-cause fix, the green Hetzner `integrated_mixed_mode` and `advanced_operator_regression` runs, and the updated advanced-plan documentation
- a 2026-04-06 Phase 4 UI closeout note documenting the shortened Overview scope guidance, the compacted preflight strip, the reduced Mission Details readiness/timing copy, and the paired Hetzner Jest/build validation results
- a 2026-04-06 Mission Config / command-surface cleanup phase 4 checkpoint note documenting the compressed Mission Config ops shell, the plot/map launch-layout toggle, the shorter command/mission copy, the Custom Show token overrides, the tablet-width trajectory compact behavior, and the paired Hetzner Jest/build validation results
- a 2026-04-06 trajectory-authoring phase 3 checkpoint note documenting the map-first Trajectory Planning layout, the docked compact route-review surface, the collapsed Swarm Trajectory workspace-review flow with related-tool links, the map resize/fly-to fixes, the focused trajectory Jest coverage, and the paired Hetzner build result
- a 2026-04-06 shared operator-scope phase 2 checkpoint note documenting the explicit visible-cards-to-command-scope bridge, the new card-level command-scope markers, the shared Overview-owned target state, the build-found PropTypes/hook fixes, and the paired Hetzner Jest/build validation results
- a 2026-04-06 Mission Config architecture-reset phase 1 checkpoint note documenting the issue-first Mission Config workspace shell, the compacted assignment-card default view, the corrected secondary tool-panel layout, the Precision Move lint-warning cleanup, and the paired Hetzner Jest/build validation results
- a 2026-04-06 Precision Move phase 2 checkpoint note documenting the operator-control-surface cleanup, the new Planned Move vs Live Jog behavior, the reduced dialog verbosity, the improved frame wording, the terminal-status tone cleanup, the low-bandwidth command-submit timeout safeguard, and the paired Hetzner React validation results
- a 2026-04-06 Precision Move operator-UX refinement checkpoint note documenting the compact controller-style dialog layout, folded manual/tuning sections, shared scope-edit return path, live command-status strip, runtime policy endpoint, and the paired backend/frontend validation results
- a 2026-04-06 Precision Move SITL validation checkpoint note documenting the fixed fresh-container branch-sync boot path, the green live Hetzner 3-drone Precision Move action run, the validator false-negative fixes, and the confirmed immediate-action override semantics
- a 2026-04-06 Precision Move phase 1 checkpoint note documenting the new `PRECISION_MOVE (112)` action, the typed command/executor path, the dedicated dashboard dialog, the quick-control and direct-HOLD refinements, the reusable SITL validator extension, the fresh-container git-sync bootstrap fix, and the remaining deferred follow-up items
- a 2026-04-04 SITL release refresh checkpoint note documenting the final deferred-debt audit result, the low-space release packaging fix, the stale Hetzner validation-tree cleanup, and the refreshed packaged image publication flow
- a 2026-04-04 SITL plan-library checkpoint note documenting the checked-in `tools/sitl_plans/` scenario library, the named-plan CLI entrypoint, the currently validated scenario coverage, and the deferred advanced combined-mode boundary
- a 2026-04-04 SITL validation-platform phase 2 checkpoint note documenting the new Mission Config/origin runtime validator, the `config_only` template, the host-agnostic validator/runtime-root guidance, the full live Hetzner operator-regression pass, and the updated AI-agent/runtime docs
- a 2026-04-04 SITL clean-image regression checkpoint note documenting the stale mixed-runtime finding, the fully green Hetzner operator-regression run on a rebuilt pinned image, and the post-validation host cleanup
- a 2026-04-04 SITL validation-platform checkpoint note documenting the new standalone action validator, the declarative suite templates/plan-file flow, deterministic dry-run/provenance output, explicit QuickScout deferral, and the focused local/Hetzner validation results
- a 2026-04-04 API closeout checkpoint note documenting the websocket-contract cleanup, the explicit deferred API follow-ups, the standing rules for future API additions, and the focused validation results
- a 2026-04-04 Swarm Trajectory typed-contract checkpoint note documenting the typed success models, OpenAPI request/response cleanup, operational failure normalization, and the paired local/Hetzner validation results
- a 2026-04-04 subsystem error-envelope checkpoint note documenting the Swarm Trajectory error-contract cleanup, the QuickScout/Swarm Trajectory OpenAPI response-metadata alignment, and the focused subsystem validation results
- a 2026-04-04 GCS error-envelope and typed-mutation checkpoint note documenting the shared FastAPI error contract, the typed request-model cleanup for fleet/origin/swarm/show-management/GCS-config routes, and the paired local/Hetzner validation results
- a 2026-04-04 command-submit idempotency checkpoint note documenting the canonical `idempotency_key` contract, the replay-safe command tracker path, the replay/conflict response semantics, and the paired local/Hetzner validation results
- a 2026-04-04 command-contract canonicalization checkpoint note documenting the canonical snake_case command envelope, the backend/frontend/runtime caller migration, the refreshed command API docs, the paired local/Hetzner validation results, and the remaining merge-readiness review debt
- a 2026-04-04 drone canonicalization checkpoint note documenting the shared drone route constants, the canonical `/api/v1/git/status` and `/api/v1/navigation/position-deviation` routes, the retirement of the legacy drone business aliases, the HTTP/WebSocket state serializer alignment, and the paired local/Hetzner validation results
- a 2026-04-03 API-modernization review audit note documenting why the stream is not yet merge-ready, with the remaining drone-side contract, caller-migration, schema, and documentation slices required before any merge to `main`
- a 2026-04-03 GCS telemetry contract-cleanup checkpoint note documenting the retirement of the duplicate GCS telemetry aliases, the removal of the fake command-cancel endpoint, the validator migration onto canonical health/telemetry routes, and the LAND/RTL timeout fallback fix
- a 2026-04-03 SITL suite runtime-root fix checkpoint note documenting the reusable multi-mode validator, the stale live gunicorn restart on Hetzner, the validator-root/runtime-root split, and the corrected end-to-end live 3-drone suite pass across Drone Show, Smart Swarm, and Swarm Trajectory
- a 2026-04-03 stream-surface codification checkpoint note documenting the third Phase 5 API-modernization slice, the explicit WebSocket transport-root policy, the shared GCS WebSocket route builders/constants, and the Hetzner Jest/build validation results
- a 2026-04-03 logging-domain hardening checkpoint note documenting the second Phase 5 API-modernization slice, the shared session-path validation, typed log-route models, the stable-root policy for `/api/logs/*` and `/api/sar/*`, and the paired local/Hetzner validation results
- a 2026-04-03 SAR router normalization checkpoint note documenting the first Phase 5 API-modernization slice, the QuickScout router-factory cleanup, the removal of the old `sys.path` import hack, and the paired local/Hetzner validation results
- a 2026-04-03 operational HTTP alias retirement checkpoint note documenting the sixteenth Phase 4 API-modernization slice, the removal of the last versionless heartbeat/network/git HTTP aliases, the runtime default-route cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 Swarm Trajectory v1-retirement checkpoint note documenting the fifteenth Phase 4 API-modernization slice, the retirement of the versionless Swarm Trajectory routes, the runtime-tool/frontend/doc cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 origin legacy-retirement checkpoint note documenting the fourteenth Phase 4 API-modernization slice, the removal of the old origin verb-style aliases, the route-resolver/request-log cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 command-control legacy-retirement checkpoint note documenting the thirteenth Phase 4 API-modernization slice, the removal of the old command verb-style aliases, the request-log and shared-route cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 show-management legacy-retirement checkpoint note documenting the twelfth Phase 4 API-modernization slice, the removal of the old show import/metrics/plot/deploy aliases, the shared frontend resolver cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 config/swarm legacy-retirement checkpoint note documenting the eleventh Phase 4 API-modernization slice, the removal of the GCS configuration/swarm verb-style aliases, the shared frontend resolver cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 legacy-route retirement audit note documenting the remaining GCS compatibility buckets as remove-now, keep-temporarily, and defer-with-reason so the remaining API cleanup can proceed deliberately
- a 2026-04-03 management/static legacy-retirement checkpoint note documenting the tenth Phase 4 API-modernization slice, the removal of the old GCS config/network/static plot aliases, the shared frontend resolver cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 git legacy-retirement checkpoint note documenting the ninth Phase 4 API-modernization slice, the removal of the deprecated one-off git detail endpoints, the route-inventory cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 canonical management/static v1 checkpoint note documenting the eighth Phase 4 GCS route-migration slice, the new `/api/v1/system/gcs-config`, `/api/v1/fleet/network-details`, and `/api/v1/swarm-trajectories/plots/{filename}` routes, the frontend caller migration, dead frontend helper removal, and the paired local/Hetzner validation results
- a 2026-04-03 canonical internal-caller cleanup checkpoint note documenting the seventh Phase 4 API-modernization slice, the shared drone/tool GCS route constants, the drone-side callback/bootstrap migration, and the paired local/Hetzner validation results
- a 2026-04-03 canonical show-management v1 checkpoint note documenting the sixth Phase 4 GCS route-migration slice, the new `/api/v1/shows/skybrush/*` and `/api/v1/shows/custom/*` routes, the shared frontend caller migration, and the paired local/Hetzner validation results
- a 2026-04-03 canonical git v1 checkpoint note documenting the fifth Phase 4 GCS route-migration slice, the new `/api/v1/git/status` and `/api/v1/git/sync-operations` routes, the request-log classification cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 canonical origin v1 checkpoint note documenting the fourth Phase 4 GCS route-migration slice, the new `/api/v1/origin*` routes, the bootstrap-resource naming cleanup, and the paired local/Hetzner validation results
- a 2026-04-03 canonical swarm-config v1 checkpoint note documenting the third Phase 4 GCS route-migration slice, the new `/api/v1/config/swarm` and `/api/v1/config/swarm/assignments/{hw_id}` routes, the internal caller migration, and the paired local/Hetzner validation results
- a 2026-04-03 canonical fleet-config v1 checkpoint note documenting the second Phase 4 GCS route-migration slice, the new `/api/v1/config/fleet*` aliases, the trajectory-start position contract cleanup, the frontend service migration, and the paired local/Hetzner validation results
- a 2026-04-03 canonical command v1 checkpoint note documenting the first Phase 4 GCS route-migration slice, the new `/api/v1/commands` and `/api/v1/command-reports/*` aliases, the frontend service migration, and the paired local/Hetzner validation results
- a 2026-04-03 Commands router extraction checkpoint note documenting the eighth Phase 3 backend route-domain split, the extracted Commands compatibility surface, the `submit_command` validation hardening, the `app_fastapi.py` monolith-route removal milestone, and the paired local/Hetzner validation results
- a 2026-04-03 Swarm Trajectory router extraction checkpoint note documenting the seventh Phase 3 backend route-domain split, the extracted trajectory-management compatibility surface, the malformed-JSON contract fix, the stale Flask duplicate removal, and the paired local/Hetzner validation results
- a 2026-04-03 Show Management router extraction checkpoint note documenting the sixth Phase 3 backend route-domain split, the extracted Drone Show / Custom Show compatibility surface, the helper move into `gcs-server/show_management.py`, the show-specific contract fixes, and the paired local/Hetzner validation results
- a 2026-04-03 Management and Static Assets router extraction checkpoint note documenting the fifth Phase 3 backend route-domain split, the GCS management/static compatibility surfaces moved out of `app_fastapi.py`, the explicit `save-gcs-config` stub contract, the static plot path-hardening work, the Hetzner validation-venv setup, and the paired backend/frontend validation results
- a 2026-04-03 Origin router extraction checkpoint note documenting the fourth Phase 3 backend route-domain split, the extracted origin/elevation surface, the compute-origin contract cleanup, the launch-position export behavior, and the combined local/Hetzner validation results
- a 2026-04-03 Git router extraction checkpoint note documenting the third Phase 3 backend route-domain split, the extracted Git REST/WebSocket surface, the preserved sync-helper seam in `app_fastapi.py`, and the combined local/Hetzner validation results
- a 2026-04-03 Configuration and Swarm router extraction checkpoint note documenting the second Phase 3 backend route-domain split, the modular config/swarm route move, the shared swarm-cycle validation move, the configuration error-status cleanup, and the combined local/Hetzner validation results across the extracted router suites
- a 2026-04-03 GCS core router extraction checkpoint note documenting the first Phase 3 backend route-domain split, the preserved `app_fastapi` patch seams, and the paired local/Hetzner backend validation results
- a 2026-04-03 API modernization phase 2 completion note documenting the remaining frontend caller migration, dead legacy frontend removal, auth/MCP readiness rules, Hetzner validation results, and the build hardening required for Node 22 on Hetzner
- a 2026-04-03 API modernization phase 2 checkpoint note documenting the core frontend caller migration onto the centralized GCS service layer, the focused Hetzner validation batch, the production build result, and the remaining route domains for the next slice
- a 2026-04-03 API contract audit phase 1 note documenting the live GCS/drone route inventory, the main naming and identity inconsistencies, the `/api/v1` migration target, and the staged MCP-ready API cleanup plan
- a 2026-04-01 dashboard UI hardening checkpoint note covering the live Hetzner mobile/tablet/desktop screenshot pass, the operator-console dashboard shell/theme changes, and the remaining runtime sync caveats before browser handoff
- a 2026-04-01 frontend audit checkpoint note documenting the recovered context, Hetzner-backed screenshot review, the responsive dashboard/trajectory work completed in this slice, and the explicit QuickScout follow-up todo for the next pass
- explicit operator documentation for compact identity shorthand `Pn|Hm` across the frontend field naming standard and config/identity guides, so recovered checkpoints and new operators can read dashboard scope labels without guessing
- a 2026-04-02 UI compact checkpoint note covering the Mission Config slot-state compaction, cluster count badge cleanup, explicit graph direction guidance, Hetzner validation results, and the deferred next-phase backlog
- `tools/publish_sitl_release_to_mega.sh`, a configurable session-first MEGA publish helper for packaged SITL releases that supports existing-session reuse, session-string login, optional stdin credential fallback, remote artifact replacement, public link export, and machine-readable output for operator or agent workflows

### Fixed
- onboard ULog management no longer fails in SITL when MAVSDK log-file
  enumeration is unavailable or when PX4 ULogs live only on the local
  companion filesystem: the drone-side service now falls back to configured
  `.ulg` directories, supports staged downloads from those files, and treats an
  empty fallback directory after erase as a clean empty catalog instead of a
  server error
- the default SITL PX4 parameter override no longer disables the very ULog
  files that the onboard-log workflow needs to manage; fresh SITL containers
  now keep PX4 file logging enabled with `SDLOG_MODE=0`
- the PX4 Parameters workspace no longer depends on MAVSDK’s older float-only
  component-information path for most metadata: drone-side snapshot rows now
  prefer PX4’s generated `parameters.json` catalog when available, which brings
  defaults, range, descriptions, units, reboot flags, and grouped metadata
  across integer and float parameters instead of leaving most rows value-only
- PX4 Parameters no longer falls back to the wrong desktop interaction model on
  touch devices that request browser “desktop mode”: compact card selection and
  the focused detail dialog now remain active on coarse-pointer narrow-physical
  devices, which keeps the page readable on phones/tablets
- the PX4 Parameters page no longer collapses into a desktop-only workflow on
  phone/tablet: compact view now uses searchable target selection, parameter
  cards, and a focused detail dialog instead of an unreadable grid-plus-inline
  inspector layout
- PX4 parameter metadata is no longer effectively hidden on compact screens:
  current/default/range/reboot/docs affordances now stay visible in the compact
  flow, and the single-drone workspace surfaces tracked inline status for
  snapshot refresh, write/import, and reboot operations
- batch PX4 profile/patch apply no longer hard-blocks the whole scope when some
  selected drones are offline; operators now get an explicit skip-offline
  confirmation path plus a clearer per-drone result summary
- PX4 Parameters no longer floods operators with raw floating-point precision:
  parameter values now use PX4 decimal hints when available and otherwise fall
  back to trimmed display precision, while compact/tablet widths keep the
  focused dialog flow instead of collapsing back into a below-table inspector
- PX4 parameter snapshots no longer depend solely on MAVSDK `GetAllParams`: drone-local snapshot refresh now waits for the target drone HTTP API to become healthy in live SITL, and the drone-side service falls back to the MAVLink parameter microservice on the routed local `14569` endpoint when the runtime MAVSDK server does not implement bulk parameter listing
- the PX4 parameter-management runtime no longer depends on a stale gRPC pin: `requirements.txt` now aligns with the installed `mavsdk 3.10.2` generated stubs by pinning `grpcio==1.71.0`, which fixes the live Hetzner backend import failure exposed during the first clean-sync PX4 smoke attempt
- the PX4 Parameters batch workspace test now waits for the fleet scope to finish loading before dispatching a patch, matching the real operator flow and preventing a false zero-target no-op during Jest validation
- QuickScout is no longer falsely tracked as “deferred” in the reusable SITL platform: the live runtime validator now supports stable multi-drone last-known-point drills, the suite exposes a first-class `quickscout` validator mode plus `quickscout_only` template and `quickscout_runtime` bundled plan, and the shared SITL docs now describe QuickScout as a dedicated gate included in the current mission/operator regression bundles
- QuickScout launch validation no longer stalls in a false "executing/searching" state on fresh SITL: the mission executor now boots its own MAVSDK server on the canonical gRPC port, coerces runtime CLI/action payloads safely, aligns mission items with the vendored MAVSDK signature, normalizes optional numeric fields such as `yaw_deg`, gates startup on the same local readiness/home signals the rest of the stack already trusts, marks the first mission item as a takeoff item, and passes the live Hetzner launch-hold-abort-reset validator end to end
- QuickScout monitor status no longer collapses every live mission into coarse generic survey state: the GCS now derives operator-facing phases such as `ready_to_launch`, `launch_partial`, `holding`, and `return_commanded`, and the live status payload carries compact summary/guidance text plus resolved control availability for UI, automation, and future MCP consumers
- QuickScout no longer advertises a fake direct resume path for paused coverage packages: `/api/sar/mission/{mission_id}/resume` now returns explicit `replan_required` guidance without mutating mission state, the monitor action bar prioritizes follow-up planning, and monitor mode surfaces the same doctrine to operators
- QuickScout per-drone monitor cards now carry compact runtime notes from launch/control/progress updates, so operators can tell “launch not accepted”, “holding on operator command”, “executing assigned search track”, and mission-end return behavior apart without decoding raw state transitions
- QuickScout planning and monitoring now expose mission end behavior explicitly instead of relying on an implicit backend default or implying fixed RTL semantics: plan requests now carry `return_behavior`, recovered missions restore it, and the monitor action bar reflects the configured end behavior
- QuickScout no longer depends on one browser-local `missionId` after refresh: the page can now reopen persisted workspaces, auto-recover active missions, restore saved plan geometry/config/drone selections, and surface a shared saved-mission panel in both planning and monitor contexts
- QuickScout now exposes durable mission-recovery surfaces instead of forcing the frontend to rely on one in-memory `missionId`: persisted missions can now be listed, a single workspace payload can reopen the stored mission package plus live-derived status, and the dashboard SAR service layer has matching recovery entrypoints for the later workspace redesign
- QuickScout no longer bypasses the shared tracked command lifecycle for launch, pause, and abort: launch now returns per-drone tracked command submissions, pause/abort now return typed tracked control responses, and durable mission recovery data now includes compact last-command summaries instead of ephemeral route-local success dicts
- QuickScout mission controls no longer default to all configured drones when no subset is provided; pause, resume, and abort now scope to mission participants by default, which removes a real cross-mission control hazard from the old PoC path
- QuickScout abort now respects the selected return behavior instead of always sending RTL, mapping `return_home` to `RETURN_RTL`, `land_current` to `LAND`, and `hold_position` to `HOLD`
- advanced SITL mixed-mode validation no longer fails because override missions clobber their own staged mission metadata: interrupting a running mission now preserves the replacement mission/state while the superseded process is terminated, so leader-only Swarm Trajectory overrides report `mission=4` correctly in fleet telemetry and the integrated operator drill stays observable end to end
- Mission Config now opens on a tighter assignment wall instead of a long top-heavy explainer stack: the header copy is shorter, issue/origin warnings are compact alert rows, filters live in one ops rail, the visible-card summary is terse, and the right-side launch-review panel can switch between the default engineering plot and a real map view without leaving the workspace
- Trajectory Planning and Swarm Trajectory now use their compact authoring-first behavior through tablet width as well as phone width, so route authoring no longer falls back to the verbose desktop layout on mid-sized operator screens
- Trajectory Planning no longer front-loads desktop route review above the working surface: the map/waypoint workspace stays first, review surfaces dock below it, and the route-policy brief is now one compact disclosure instead of a separate expanded desktop block
- Swarm Trajectory no longer repeats operator guidance in a standalone top banner: workspace doctrine/stage review is collapsed into the workspace summary and the related-tool handoff is now a compact reusable link row instead of another full-width explainer
- Command Control, mission-trigger cards, and Custom Show no longer carry as much tester-reported copy/token noise: target-scope guidance is shorter, mission notes are glanceable, and Custom Show now forces dashboard tokens for dark/light readability instead of inheriting weaker default MUI colors
- the Precision Move dialog now prioritizes the fast operator path: compact controller-style nudges, folded manual tuning, direct scope-edit return into the shared Command Control selector, visible live runtime defaults, and cleaner live command-state context without forking the main target-selection workflow
- GCS now exposes `/api/v1/commands/policy/precision-move`, a typed runtime policy envelope for default speed/tolerance/timeout/limit values so UI, automation, and future MCP surfaces can reuse the live backend contract instead of hardcoded frontend guesses
- the action system now supports a typed local-relative `PRECISION_MOVE` command end to end, from GCS submit validation to drone runtime payload staging, timeout budgeting, `DroneSetup` mission routing, and the offboard local-position executor that settles then returns control to PX4 Hold
- the dashboard Actions tab no longer has to force parameterized precision moves through the generic two-step confirm flow; the new dedicated Precision Move dialog is now the single operator confirmation surface and still submits through the standard command lifecycle tracker
- command submission normalization now explicitly preserves nested `precision_move` payloads while still converting the surrounding command envelope onto the canonical snake_case GCS API contract
- Docker SITL release packaging no longer requires a full intermediate `.tar` on disk when compression is enabled and `--keep-tar` is not requested; `tools/package_sitl_image.sh` now streams `docker save` directly into `7z`, which keeps the release workflow viable on smaller VPS hosts
- Hetzner promotion-style SITL validation is now documented against the mode that actually proved stable in practice: fresh rebuilt image, fresh fleet recreation, and boot-time repo/dependency sync disabled during the regression run
- the reusable SITL suite is no longer just a hardcoded mission wrapper: it now supports the standalone action-control drill, plan-hash/provenance capture, side-effect-free dry-run, final reset/failure cleanup behavior, and explicit deferred QuickScout tracking for future expansion
- Swarm Trajectory short-profile preparation no longer leaves shared raw leader CSVs mutated after a validation run; the validator now snapshots the original raw profiles, restores them in a finalization step, and records the restore result in the JSON summary
- Drone Show and Smart Swarm runtime validators no longer rely on success-only cleanup paths; both now emit structured fail results, attempt runtime cleanup, and still write final JSON summaries after failures
- `WS /ws/heartbeats` now emits the normalized heartbeat list contract documented in the GCS API instead of the older raw internal heartbeat map, and the old skipped GCS websocket suite was replaced with deterministic route-level contract coverage for telemetry, heartbeat, and git-status streams
- the GCS and drone websocket API docs now match the live transport contracts more closely: GCS examples reflect the real payload shapes, and drone docs no longer claim bidirectional command transport over `WS /ws/drone-state`
- the active Swarm Trajectory success surfaces now use typed GCS schema models and `response_model` contracts, so `/docs` and `/openapi.json` describe the real leaders/upload/recommendation/status/policy/process/clear/remove/commit payloads instead of leaving that domain as ad hoc dictionaries
- `POST /api/v1/swarm-trajectories/process` and `POST /api/v1/swarm-trajectories/commit` now use typed optional request models, which removes the last manual request parsing in that route family and standardizes schema/body failures onto the shared `422 Validation error` envelope
- Swarm Trajectory processing and clear-processed service failures now raise typed `SwarmTrajectoryError` instead of returning `200` with `success=false`, so transport success and operational success are no longer conflated on that domain boundary
- frontend API error extraction now handles structured validation/detail arrays, and the Swarm Trajectory frontend service now surfaces backend process/clear failures as readable operator errors instead of raw Axios status strings
- the remaining Swarm Trajectory route-family failures now use the shared GCS `ErrorResponse` envelope instead of route-local `success=false` payloads, so malformed JSON, missing processed assets, and operator-facing git/cluster errors now surface stable `error`, `detail`, `timestamp`, and `path` fields like the rest of the cleaned GCS HTTP surface
- Swarm Trajectory git commit/push failures now map to explicit operation statuses (`409` for divergence/conflict cases, `502` for network/auth/timeout upstream failures) instead of collapsing every failure into a generic `500` with a custom body
- QuickScout SAR and Swarm Trajectory router docs/OpenAPI metadata now advertise the shared error-response contract directly at the router boundary, instead of relying on app-level behavior while the subsystem routers looked undocumented in isolation
- canonical GCS FastAPI HTTP routes now use one shared machine-readable error envelope for request validation, `HTTPException`, and uncaught server failures, so clients receive stable `error`, `detail`, `timestamp`, and `path` fields instead of mixed default FastAPI payloads and raw exception strings
- the remaining high-value GCS mutation routes no longer hand-parse JSON bodies ad hoc: fleet config, GCS config stub writes, origin compute, swarm config save/patch, and Drone Show deployment now use typed request models with standard `422` validation behavior
- the canonical swarm-config resource now returns normalized saved assignment objects, including defaulted `offset_x`, `offset_y`, `offset_z`, and `frame` fields, instead of mixed sparse payload shapes between read and write paths
- command submission is now replay-safe at the GCS contract boundary: `POST /api/v1/commands` accepts canonical `idempotency_key`, returns `replayed=true` when the same normalized submission is retried, and rejects conflicting reuse of the same key with `409` instead of creating a second live tracked command
- command submit/status responses now surface `idempotency_key`, so future MCP/tooling layers can correlate transport retries with the long-running tracked command instead of relying on hidden client-side bookkeeping
- the drone API now treats the canonical `/api/v1/...` contract as the only current public business HTTP surface, adding `GET /api/v1/git/status` and `GET /api/v1/navigation/position-deviation` while retiring the legacy drone business aliases that previously stayed mounted beside the v1 routes
- first-party runtime/tooling callers now use the shared canonical drone route surface instead of repeating legacy strings such as `/get_drone_state`, `/get-home-pos`, `/get-git-status`, and `/api/live-armability`, so GCS polling, validators, mission runtimes, and local helpers no longer reinforce the retired contract
- `GET /api/v1/drone/state` and `WS /ws/drone-state` now share one validator-backed serializer, so the live drone state payload stays schema-aligned across HTTP and WebSocket transport instead of drifting by transport path
- duplicate GCS HTTP telemetry aliases `GET /telemetry` and `GET /api/telemetry` are now retired, leaving `GET /api/v1/fleet/telemetry` as the single current fleet-telemetry snapshot route
- the fake `POST /api/v1/commands/{command_id}/cancel` endpoint has been removed because it never dispatched a live cancel to drones; the only current cancellation contract remains `POST /api/v1/commands` with `missionType=0`
- reusable live validators, request-log classification, route inventory, and shared frontend/docs guidance now prove and describe the canonical `GET /api/v1/system/health` and `GET /api/v1/fleet/telemetry` routes instead of preserving removed telemetry aliases as pseudo-compatibility
- LAND / RTL timeout fallback estimation now reads the drone home-position `altitude` field instead of the nonexistent `alt`, preventing under-budgeted tracking windows when relative-altitude telemetry is unavailable
- the third Phase 5 API-modernization slice now treats `/ws/telemetry`, `/ws/heartbeats`, and `/ws/git-status` as intentional canonical transport roots instead of leaving them as undocumented versionless leftovers, closing the last open GCS route-shape policy gap after the Phase 4 HTTP retirement work
- shared GCS frontend route helpers now build WebSocket URLs from the configured backend base URL with correct `http`→`ws` and `https`→`wss` protocol mapping while preserving already-absolute WebSocket URLs, so future stream consumers do not reintroduce hardcoded or incorrectly prefixed socket endpoints
- the second Phase 5 API-modernization slice now hardens the shared logging session layer so session IDs must resolve inside the configured log directory, which closes the path-traversal risk for both GCS and drone-side `/api/logs/*` session access and export flows
- GCS log routes now use typed request/response models for frontend reports, export requests, config toggles, and session payloads instead of relying on untyped dictionaries, bringing the logging domain in line with the broader contract-cleanup standard without renaming the stable `/api/logs/*` namespace
- the API modernization policy now treats `/api/logs/*` and `/api/sar/*` as intentional stable subsystem roots rather than unfinished alias debt, so the remaining open contract question is concentrated on the GCS WebSocket stream surface instead of churn for already-namespaced domains
- the first Phase 5 API-modernization slice now normalizes the QuickScout SAR backend onto the same dependency-injected router-factory pattern as the rest of the cleaned GCS API, replacing the old module-global router and `sys.path` mutation in `gcs-server/sar/routes.py` without changing the live `/api/sar/*` contract
- QuickScout route handlers now read `load_config`, telemetry state, and command-dispatch dependencies from the live `app_fastapi` module object at request time, so tests and future auth/MCP wrapping no longer depend on import-time state capture inside the SAR route module
- the sixteenth Phase 4 API-modernization slice now retires the remaining versionless operational HTTP aliases `POST /heartbeat`, `POST /drone-heartbeat`, `GET /get-heartbeats`, `GET /get-network-status`, `GET /git-status`, and `POST /sync-repos`, leaving the canonical `/api/v1/fleet/heartbeats`, `/api/v1/fleet/network-status`, `/api/v1/git/status`, and `/api/v1/git/sync-operations` routes as the only supported GCS HTTP contract for those operational reads and mutations
- the default drone heartbeat sender path now comes from the shared canonical route constant `GCS_FLEET_HEARTBEATS_ROUTE` instead of the old `/drone-heartbeat` string, so runtime callbacks no longer keep a removed compatibility alias artificially alive
- the shared frontend route resolver, request-log classification, route inventory, and active git/heartbeat docs now treat the operational v1 routes as the single current HTTP surface instead of quietly preserving retired alias knowledge
- the fifteenth Phase 4 API-modernization slice now retires the versionless Swarm Trajectory routes `GET /api/swarm/leaders`, `POST /api/swarm/trajectory/upload/{leader_id}`, `POST /api/swarm/trajectory/process`, `GET /api/swarm/trajectory/recommendation`, `GET /api/swarm/trajectory/status`, `GET /api/swarm/trajectory/policy`, `POST /api/swarm/trajectory/clear-processed`, `POST /api/swarm/trajectory/clear`, `POST /api/swarm/trajectory/clear-leader/{leader_id}`, `DELETE /api/swarm/trajectory/remove/{leader_id}`, `GET /api/swarm/trajectory/download/{drone_id}`, `GET /api/swarm/trajectory/download-kml/{drone_id}`, `GET /api/swarm/trajectory/download-cluster-kml/{leader_id}`, `POST /api/swarm/trajectory/clear-drone/{drone_id}`, and `POST /api/swarm/trajectory/commit` because the dashboard, tooling, and validation clients now use the canonical `/api/v1/swarm-trajectories/*` surface
- the shared frontend GCS route resolver, Swarm Trajectory runtime validator, route inventory, and API docs now treat `/api/v1/swarm-trajectories/*` as the single current contract, so the retired versionless routes cannot linger as pseudo-compatibility
- removed an unused block of stale trajectory schema models that still advertised non-existent legacy endpoints, keeping schema metadata aligned with the live contract instead of preserving dead API shapes
- the fourteenth Phase 4 API-modernization slice now retires the public origin legacy routes `GET /get-origin`, `POST /set-origin`, `GET /get-gps-global-origin`, `GET /elevation`, `GET /get-origin-for-drone`, `GET /get-position-deviations`, `POST /compute-origin`, and `GET /get-desired-launch-positions` because they have no remaining live dashboard, runtime-tooling, or SITL-helper callers
- the shared frontend GCS route resolver and GCS request-log classification now treat the canonical origin surface as the single source of truth, so removed backend origin routes cannot linger in UI helpers or operational logging heuristics
- the active operator/developer docs, origin router coverage, HTTP regressions, and route inventory now reflect the canonical origin surface only instead of continuing to advertise or assert the retired aliases as current behavior
- the thirteenth Phase 4 API-modernization slice now retires the public command-control legacy routes `POST /submit_command`, `GET /command/{command_id}`, `GET /commands/recent`, `GET /commands/active`, `GET /commands/statistics`, `POST /command/{command_id}/cancel`, `POST /command/execution-start`, and `POST /command/execution-result` because they have no remaining live dashboard, runtime-tooling, or SITL-helper callers
- the shared frontend GCS route resolver and GCS request-log classification no longer keep the retired command aliases alive as pseudo-compatibility, so removed backend routes cannot linger in UI helpers or operational logging heuristics
- the public GCS API docs, command router coverage, route inventory, and HTTP regression batches now reflect the canonical command-control surface only, instead of continuing to advertise or assert the retired aliases as current behavior
- the tenth Phase 4 API-modernization slice now retires the public management/static legacy routes `GET /get-gcs-config`, `POST /save-gcs-config`, `GET /get-network-info`, and `GET /static/plots/{filename}` because they have no remaining live dashboard, runtime-tooling, or validation-script callers
- the shared frontend GCS route resolver no longer recognizes the retired management/static legacy paths, so removed backend routes cannot survive as frontend pseudo-compatibility
- the public GCS API docs now describe only the canonical management/static surface for GCS config, detailed fleet network metadata, and Swarm Trajectory plots instead of presenting removed aliases as current endpoints
- the ninth Phase 4 API-modernization slice now retires the deprecated one-off git detail routes `GET /get-gcs-git-status` and `GET /get-drone-git-status/{drone_id}` because they have no remaining live callers and the canonical `GET /api/v1/git/status` surface already carries the same data
- git route inventory, router coverage, HTTP regressions, and the public git documentation now reflect the retired route set instead of preserving those deprecated endpoints as misleading permanent compatibility debt
- the eighth Phase 4 GCS route-migration slice now introduces canonical management/static routes: `GET /api/v1/system/gcs-config`, `PUT /api/v1/system/gcs-config`, `GET /api/v1/fleet/network-details`, and `GET /api/v1/swarm-trajectories/plots/{filename}`
- the shared frontend GCS service layer now uses the canonical management/static routes for GCS configuration reads/writes, detailed fleet network metadata, and Swarm Trajectory plot URLs instead of reinforcing `/get-gcs-config`, `/save-gcs-config`, `/get-network-info`, and `/static/plots/{filename}`
- the canonical GCS-config write path is now modeled truthfully as `PUT /api/v1/system/gcs-config` while the legacy `POST /save-gcs-config` alias remains mounted during rollout, preventing the canonical resource contract from inheriting the older action-style route shape
- route inventory, router coverage, HTTP regressions, and shared dashboard GCS service tests now cover the canonical management/static surface, and the dead frontend git-status helper exports were removed instead of being preserved as misleading compatibility debris
- the sixth Phase 4 GCS route-migration slice now introduces canonical show-management routes for both live show workflows: `POST /api/v1/shows/skybrush/import`, `GET /api/v1/shows/skybrush`, `GET /api/v1/shows/skybrush/archives/raw`, `GET /api/v1/shows/skybrush/archives/processed`, `GET /api/v1/shows/skybrush/metrics`, `GET /api/v1/shows/skybrush/safety-report`, `GET /api/v1/shows/skybrush/validation`, `POST /api/v1/shows/skybrush/deployments`, `GET /api/v1/shows/skybrush/plots`, `GET /api/v1/shows/skybrush/plots/{filename}`, `GET /api/v1/shows/custom`, `POST /api/v1/shows/custom/import`, and `GET /api/v1/shows/custom/preview`
- the shared frontend GCS service layer now uses the canonical show-management routes for show metadata, custom-show metadata, SkyBrush/custom imports, processed/raw downloads, plot discovery, and custom preview assets instead of reinforcing the legacy compatibility paths
- canonical show-management naming now reflects the two real operator workflows explicitly: standard SkyBrush processing lives under `/api/v1/shows/skybrush/*`, the specialist shared-CSV flow lives under `/api/v1/shows/custom/*`, and the read-only validation snapshot is modeled as `GET /api/v1/shows/skybrush/validation` even though the legacy compatibility route remains `POST /validate-trajectory`
- show route inventory, router coverage, HTTP regressions, and shared dashboard GCS service tests now cover the canonical show-management surface so later cleanup cannot silently drift from the mounted routes or active callers
- the public GCS API docs and Drone Show feature guide now present the canonical show-management surface first while keeping the legacy compatibility routes explicit during rollout
- the seventh Phase 4 API-modernization slice now moves the remaining real internal GCS callers in drone runtime/tooling onto canonical routes instead of the compatibility aliases
- drone-side execution callbacks now post to `POST /api/v1/command-reports/execution-start` and `POST /api/v1/command-reports/execution-result`, including the direct fallback path used when a queued command is superseded before runtime launch
- drone-side bootstrap-origin fetches now use `GET /api/v1/origin/bootstrap`, and the Drone Show validation tooling plus the standalone import test page now use the canonical SkyBrush/custom show routes
- `src/gcs_api_routes.py` now provides one shared route constant surface for the drone runtime and validation tooling, preventing the same canonical GCS paths from drifting into new hardcoded copies
- drone-side regression coverage now explicitly checks the canonical superseded-command callback path and canonical bootstrap-origin fetch, and the updated drone-side batch passes locally and on Hetzner with `105` tests
- the fifth Phase 4 GCS route-migration slice now introduces canonical git routes: `GET /api/v1/git/status` and `POST /api/v1/git/sync-operations`
- the shared frontend GCS service layer and the remaining active hardcoded dashboard git-status poll now use the canonical git routes instead of reinforcing `/git-status` directly
- canonical git-sync naming now reflects the real contract: the API performs dispatch plus convergence verification synchronously, so the canonical path is `sync-operations` instead of the earlier provisional `sync-jobs` wording
- successful canonical git-status polls are now classified as routine `DEBUG` request noise the same way legacy `/git-status` polls were, preventing log-volume regressions during caller migration
- route inventory, HTTP regressions, router coverage, and dashboard service tests now cover the canonical git surface so later cleanup cannot silently drift from the mounted routes
- the fourth Phase 4 GCS route-migration slice now introduces canonical origin routes: `GET /api/v1/origin`, `PUT /api/v1/origin`, `GET /api/v1/origin/bootstrap`, `GET /api/v1/navigation/global-origin`, `GET /api/v1/origin/elevation`, `GET /api/v1/origin/deviations`, `POST /api/v1/origin/compute`, and `GET /api/v1/origin/launch-positions`
- the shared frontend GCS service layer and the Drone Show runtime/validation tooling touched in this slice now use the canonical origin paths instead of reinforcing the older compatibility URLs
- the canonical origin write contract no longer falsely requires altitude when the dashboard treats it as optional; `PUT /api/v1/origin` now defaults omitted altitude to `0.0` MSL and preserves the explicit `source` field in the typed origin response
- origin bootstrap consumers now have a distinct canonical route at `GET /api/v1/origin/bootstrap` instead of relying on an implicit mis-mapping to the generic origin-read resource, which keeps the v1 surface semantically explicit for future MCP/automation use
- origin route inventory, HTTP regressions, router coverage, dashboard-service tests, and the Drone Show validation helper all now cover the canonical origin surface, preventing silent drift between the migration blueprint and live callers
- the third Phase 4 GCS route-migration slice now introduces canonical swarm-config routes: `GET /api/v1/config/swarm`, `PUT /api/v1/config/swarm`, and `PATCH /api/v1/config/swarm/assignments/{hw_id}`
- the canonical swarm-config `GET` route now returns the persisted typed resource shape `{version, assignments}` instead of the older raw-list compatibility payload, while the legacy `/get-swarm-data` route remains available during rollout
- the shared frontend GCS service layer now uses the canonical swarm-config resource path, saves swarm assignments through `PUT /api/v1/config/swarm`, and unwraps canonical swarm envelopes centrally so `Overview`, `Mission Config`, and `Swarm Design` stay aligned on one config contract
- the misleading leader-only reassignment contract now has a canonical partial-update route at `PATCH /api/v1/config/swarm/assignments/{hw_id}`, matching the live behavior that can update `follow`, offsets, and frame together instead of pretending the route only changes leaders
- Smart Swarm runtime refresh/failover reporting, swarm analysis fallback, and the reusable validation scripts now call the canonical swarm-config routes; the reusable validation clients touched in this slice also use the canonical command submit/status paths so internal tooling stops reinforcing stale GCS URLs
- swarm route inventory and HTTP regression guardrails now cover the canonical swarm-config surface in addition to the legacy compatibility routes, including the enveloped canonical read contract and the partial assignment patch behavior
- the second Phase 4 GCS route-migration slice now introduces canonical fleet-config aliases: `GET /api/v1/config/fleet`, `PUT /api/v1/config/fleet`, `POST /api/v1/config/fleet/validation`, `GET /api/v1/config/fleet/trajectory-start-positions`, and `GET /api/v1/config/fleet/trajectory-start-positions/{pos_id}`
- the shared frontend GCS service layer now uses the canonical fleet-config resource paths, including `PUT /api/v1/config/fleet` for save and the path-parameter form for per-slot trajectory-start lookups
- the canonical per-position trajectory-start route now returns `x`/`y` to match the existing fleet trajectory-position collection, while the legacy `/get-trajectory-first-row?pos_id=...` path keeps its older `north`/`east` compatibility payload
- Mission Config trajectory-position hydration now accepts canonical `x`/`y` and legacy `north`/`east`, so the frontend can move to the cleaned config contract without breaking compatibility during rollout
- configuration route inventory and alias guardrails now cover the canonical fleet-config surface in addition to the legacy compatibility paths, preventing silent drift between the mounted FastAPI routes and the migration blueprint
- the first Phase 4 GCS route-migration slice now introduces canonical v1 command aliases: `POST /api/v1/commands`, `GET /api/v1/commands/{command_id}`, `GET /api/v1/commands/recent`, `GET /api/v1/commands/active`, `GET /api/v1/commands/statistics`, `POST /api/v1/commands/{command_id}/cancel`, `POST /api/v1/command-reports/execution-start`, and `POST /api/v1/command-reports/execution-result`
- the shared frontend GCS service layer now uses the canonical v1 command endpoints for submit/status/recent/active command flows instead of the legacy compatibility paths, so the operator UI and future MCP-facing consumers move onto one current command contract
- command-route inventory and alias guardrails now cover the canonical v1 command surface in addition to the legacy compatibility paths, preventing later drift between documented aliases and the mounted FastAPI routes
- request-log noise classification now recognizes canonical command poll/callback paths (`/api/v1/commands/...`, `/api/v1/command-reports/...`) so successful v1 command monitoring traffic stays at `DEBUG` while submit/cancel/operator actions remain visible at `INFO`
- the public GCS API documentation now presents the command control surface under canonical v1 routes first while still calling out the legacy compatibility paths explicitly
- `tools/run_sitl_validation_suite.py` now separates `--validator-root` from `--repo-root`, so temporary validation checkouts can execute the newest tooling while all reset steps and repo-backed runtime data operations target the same checkout that the live GCS actually serves from
- the reusable SITL validation workflow is now validated locally and on Hetzner with `371 passed, 8 skipped`, and the corrected live 3-drone suite passed end to end with the runtime-root-aware invocation
- the eighth Phase 3 backend extraction now moves the remaining Commands REST surface into `gcs-server/api_routes/commands.py`, so `app_fastapi.py` no longer owns `/submit_command`, `/command/{command_id}`, `/commands/recent`, `/commands/active`, `/commands/statistics`, `/command/{command_id}/cancel`, `/command/execution-result`, or `/command/execution-start`
- command-route coverage now has focused router-level tests for route registration, live dependency lookup, request-body validation, target-resolution failure handling, and the intentionally fail-closed cancel path, closing the last major gap in the extracted GCS route suite
- `POST /submit_command` now rejects malformed JSON, non-object JSON bodies, invalid `target_drones` shapes, and explicit target selections that match no configured drones with `400` instead of creating ambiguous zero-target command records or surfacing generic server errors
- command-only target-telemetry and altitude-budget helpers now live with the extracted command router instead of remaining as private file-local logic inside `app_fastapi.py`
- `SubmitCommandRequest` / `SubmitCommandResponse` schema metadata and the human-facing GCS API doc now align with the live command contract, including `target_drones`, the normalized hardware-ID response behavior, and the legacy-but-ignored ack fields
- `gcs-server/app_fastapi.py` no longer contains business `@app.get(...)`, `@app.post(...)`, or other business route decorators; it is now reduced to infrastructure, dependency state, router mounting, and shared compatibility seams on the GCS side
- the seventh Phase 3 backend extraction now moves the full Swarm Trajectory route surface into `gcs-server/api_routes/swarm_trajectory.py`, so `app_fastapi.py` no longer owns `/api/swarm/leaders`, `/api/swarm/trajectory/upload/{leader_id}`, `/api/swarm/trajectory/process`, `/api/swarm/trajectory/recommendation`, `/api/swarm/trajectory/status`, `/api/swarm/trajectory/policy`, `/api/swarm/trajectory/clear-processed`, `/api/swarm/trajectory/clear`, `/api/swarm/trajectory/clear-leader/{leader_id}`, `/api/swarm/trajectory/remove/{leader_id}`, `/api/swarm/trajectory/download/{drone_id}`, `/api/swarm/trajectory/download-kml/{drone_id}`, `/api/swarm/trajectory/download-cluster-kml/{leader_id}`, `/api/swarm/trajectory/clear-drone/{drone_id}`, or `/api/swarm/trajectory/commit`
- Swarm Trajectory route coverage now has focused router-level tests for route registration, live dependency lookup, runtime policy reads, and request-body validation, closing the gap where only route existence and the policy endpoint were asserted directly
- `POST /api/swarm/trajectory/process` and `POST /api/swarm/trajectory/commit` now reject malformed JSON and non-object JSON bodies with `400` instead of falling through to a generic `500`
- the stale unused Flask-era duplicate `gcs-server/swarm_trajectory_routes.py` has been removed, leaving the extracted FastAPI router as the single current Swarm Trajectory route definition in the repo
- the sixth Phase 3 backend extraction now moves the remaining Drone Show / Custom Show routes into `gcs-server/api_routes/show_management.py`, so `app_fastapi.py` no longer owns `/import-show`, `/download-raw-show`, `/download-processed-show`, `/get-show-info`, `/get-custom-show-info`, `/import-custom-show`, `/get-comprehensive-metrics`, `/get-safety-report`, `/validate-trajectory`, `/deploy-show`, `/get-show-plots`, `/get-show-plots/{filename}`, or `/get-custom-show-image`
- shared Drone Show / Custom Show helper logic now lives in `gcs-server/show_management.py`, while `app_fastapi.py` keeps compatibility wrappers for the patch-driven test seam instead of duplicating domain logic inline
- `POST /deploy-show` now accepts standard JSON content types with charset parameters instead of only an exact `application/json` header match
- show trajectory validation now preserves `FAIL` when safety blockers exist, instead of accidentally downgrading that result back to `WARNING` when collision or speed warnings are also present
- `GET /get-show-plots/{filename}` now resolves files through a bounded path check, closing the traversal risk in the legacy show-plot download surface
- `GET /get-show-plots` now returns an empty result for a missing plots directory instead of creating directories as a side effect of a read request
- the GCS API server docs now include the active custom-show endpoints and the expanded show-import response payload, removing the show-domain doc drift that had built up around the extracted routes
- the fifth Phase 3 backend extraction now moves `/get-gcs-config`, `/save-gcs-config`, `/get-network-info`, and `/static/plots/{filename}` into `gcs-server/api_routes/management.py` and `gcs-server/api_routes/static_assets.py`, so `app_fastapi.py` no longer owns that compatibility cluster
- `POST /save-gcs-config` now returns an explicit compatibility stub result with `success=true`, `persisted=false`, and warnings instead of the old ambiguous payload that looked like a real save even though no persistence path exists
- static plot serving now resolves paths through a bounded project-root check before returning files, closing the traversal risk that existed when arbitrary filenames were joined directly under the plots directory
- `MissionReadinessCard` now builds static-plot URLs through the shared GCS route helper instead of hardcoding `/static/plots/...`, keeping frontend route composition aligned with the centralized API contract
- the project `dev` extra now includes `pytest-timeout`, which fixes the mismatch where `pytest.ini` required timeout options but a clean validation environment did not install the plugin
- removed the redundant ignored `[tool.pytest.ini_options]` block from `pyproject.toml`, leaving `pytest.ini` as the single source of truth for pytest behavior
- the fourth Phase 3 backend extraction now moves the full Origin domain into `gcs-server/api_routes/origin.py`, so `app_fastapi.py` no longer owns `/get-origin`, `/set-origin`, `/get-gps-global-origin`, `/elevation`, `/get-origin-for-drone`, `/get-position-deviations`, `/compute-origin`, or `/get-desired-launch-positions`
- origin geometry/reporting helpers now live in `gcs-server/origin.py` instead of being duplicated inside route handlers, including the richer deviation report and desired-launch-position export payload used by the extracted router
- `POST /compute-origin` now behaves like the frontend/operator workflow already expects: it computes and returns a candidate origin without silently overwriting shared origin state; `POST /set-origin` remains the only explicit write path for origin persistence
- `compute_origin_from_drone(...)` now imports the `pyproj` primitives it already depends on, fixing a latent runtime failure path that could raise `NameError` when the origin-compute flow was exercised outside mocks
- `GET /get-desired-launch-positions` now actually honors its documented `heading` and `format` parameters: heading rotates formation offsets before GPS projection, `format=csv` returns a CSV attachment, and `format=kml` returns a KML attachment instead of those parameters being silently ignored
- command submission now preserves valid `auto_global_origin` coordinates at latitude/longitude `0.0`, replacing the old truthiness check that incorrectly treated equator/prime-meridian origins as missing
- route inventory coverage now includes a duplicate method/path guard for the GCS API so future route extractions cannot accidentally double-register a public surface without failing tests
- the third Phase 3 backend extraction now moves the Git routes into `gcs-server/api_routes/git_status.py`, so `app_fastapi.py` no longer owns `/git-status`, `/sync-repos`, `/ws/git-status`, `/get-gcs-git-status`, or `/get-drone-git-status/{drone_id}`
- Git route coverage now has focused router-level tests for route registration, live dependency lookup, and sync verification hook usage, closing the gap where Git extraction risk was previously covered only by the broader integration suite
- the extracted Git websocket now builds its payload from the same shared response builder used by the REST endpoint, keeping the live contract aligned between `/git-status` and `/ws/git-status`
- the second Phase 3 backend extraction now moves the configuration routes into `gcs-server/api_routes/configuration.py` and swarm configuration / Smart Swarm reassignment routes into `gcs-server/api_routes/swarm.py`, so `app_fastapi.py` no longer owns `/get-config-data`, `/save-config-data`, `/validate-config`, `/get-drone-positions`, `/get-trajectory-first-row`, `/get-swarm-data`, `/save-swarm-data`, or `/request-new-leader`
- configuration helper routes now have focused router-level coverage for route registration, live dependency lookup, invalid client payload preservation, and helper-path behavior, which closes the previous gap where only the broader API suite covered the domain partially
- invalid configuration payload shape now preserves `400` instead of being flattened into a generic `500`, while leaving the existing malformed raw JSON behavior unchanged for this slice
- both extracted mutable router domains now use `asyncio.get_running_loop()` for async git side-effect paths, aligning them with current async-loop practice
- swarm cycle validation now lives with the swarm router instead of as file-local helpers in `app_fastapi.py`, so the swarm domain keeps one cohesive validation surface instead of reaching back into the monolith for follow-chain rules
- the first Phase 3 backend extraction now moves GCS health, telemetry, heartbeat, and network-status routes into `gcs-server/api_routes/core.py` and mounts them through `create_core_router(...)`, reducing `app_fastapi.py` surface area without changing the live HTTP/WebSocket contract
- the extracted core router reads dependency attributes from the live `app_fastapi` module object at request time instead of capturing handler references at import time, so existing patch-driven backend tests and future auth/MCP layers keep one stable hook surface during modularization
- `GET /get-network-info` now returns the live heartbeat-derived network snapshot directly after the core route extraction, removing its stale dependency on the deleted private helper and keeping the legacy compatibility alias working
- the remaining active Drone Show, Swarm Trajectory, QuickScout, mission-detail, log, and SAR frontend consumers now use the shared GCS route/service layer instead of page-owned backend URLs, so uploads, downloads, static plot URLs, telemetry/config reads, and route-key polling all flow through one contract surface
- added a shared `apiError` helper and moved upload/import flows onto it, so blob-backed and JSON-backed API failures now resolve through one consistent operator-facing error path instead of each page re-parsing responses differently
- `buildGcsUrl()` now preserves absolute URLs instead of prefixing them twice, fixing a real service-layer bug exposed by the Swarm Trajectory migration where helper-built absolute URLs could otherwise become invalid request targets
- removed the dead unrouted `ImportShow` / `FileUpload` frontend path and its stale CSS instead of carrying it forward as misleading compatibility baggage; the live Drone Show workflow is now exclusively `ManageDroneShow` plus its import/visualization/export sections
- Hetzner frontend validation now includes dedicated `logService` and `sarApiService` regression coverage plus the updated `SwarmTrajectory` page/service mocks, closing the remaining route-centralization gaps in the focused API contract suite
- the dashboard build script now disables production sourcemaps and sets an explicit Node heap budget, so `npm run build` completes reliably on the Hetzner Node 22 runtime instead of failing with V8 heap exhaustion and third-party sourcemap noise
- the API modernization phase 2 slice now centralizes the highest-traffic frontend GCS callers behind `src/services/gcsApiService.js`, so Dashboard Overview, Mission Config, Swarm Design, Globe View, Drone Detail, git/sync widgets, origin helpers, mission-config save/validate flows, and command-service reads no longer hardcode backend route strings across pages and hooks
- added focused dashboard service coverage for the new route layer (`gcsApiService.test.js`) and the migrated command/swarm helpers (`droneApiService.test.js`), giving the API cleanup stream an explicit frontend contract gate instead of relying only on end-to-end browser checks
- `getSwarmClusterStatus()` now tolerates both raw axios responses and already-unwrapped status payloads, fixing a mixed response-shape bug that could hide processed-cluster state depending on which helper path supplied the data
- the first API modernization slice now exposes canonical `/api/v1/...` aliases for core GCS health/telemetry/heartbeat/network routes and core drone health/state/command/preflight/navigation/network routes while preserving legacy compatibility paths, giving docs/tests/automation a stable migration target before deeper route extraction and caller migration
- added machine-enforced route inventory coverage for the full current GCS and drone business API surfaces, including the active HTTP/WebSocket sets, heartbeat/health aliases, and deprecated git compatibility endpoints, so the API cleanup program can proceed against a frozen baseline instead of rediscovering the live contract by hand
- cluster-scope rails now render drone counts as discrete badges instead of parenthetical suffixes, keeping Dashboard, Mission Config, Swarm Design, and Command Control scope chips denser and easier to scan on mobile
- Mission Config show-slot status now collapses verbose config/heartbeat/auto prose into one compact verified/pending/review state with short source chips, explicit mismatch accept actions, and simulator-aware wording instead of noisy repeated slot sentences
- Swarm Design follow-chain guidance now states the graph direction explicitly as leader to follower, so operators do not misread the topology while reviewing cluster propagation
- the official SITL download guide now points to the refreshed MEGA release archive built from `main-candidate` commit `4cfbae9`, so docs, published image tags, and the packaged artifact no longer drift
- mobile theme application now updates the document root, body, `theme-color`, and `color-scheme` together, so Auto/Light mode reads more consistently on handheld browsers instead of inheriting a stale dark-biased frame state
- Mission Config and Drone Detail light-theme surfaces now use brighter, token-driven shadows and status chips, remove several dark-only hardcoded accents, and tighten the top identity summary cards for handheld audits
- dashboard theme selection now bootstraps before React mounts, so mobile Auto/Light mode applies on first paint instead of flashing the wrong palette
- dashboard webfont loading now matches the design system (`IBM Plex Sans` / `IBM Plex Mono`) instead of falling back to older mismatched type choices
- compact operator identity now standardizes on `Pn|Hm` for dense control surfaces where slot and hardware truth both matter, and that format now feeds cluster-scope labels, swarm follow-option labels, plot hover text, and dashboard search terms/tooltips instead of mixing longer ad hoc variants
- Drone Actions command buttons now keep icon and label alignment consistent even for shorter labels like `Hold`, so the action grid reads as one clean operator control matrix instead of a set of uneven cards
- Mission Config assignment cards now use tighter token-driven surfaces, less hard-coded accent styling, and denser identity/info/network layouts, reducing contrast drift and card clutter during the mobile operator audit
- Dashboard Overview now reuses the same cluster-scope rail as Mission Config and Swarm Design, so large fleets can be narrowed by detected top-leader cluster without changing command scope
- Command Control, mission cards, and action cards now use shorter operator-facing labels and less repeated copy while keeping the full command meaning in tooltips, confirmations, and detailed mission briefs
- Drone Actions, Drone Detail, Mission Config, and Smart Swarm light-theme surfaces now align more closely with the primary shell, reducing contrast drift between dashboard sections during mobile review
- dashboard theme auto mode now resolves against both dark/light media queries, falls back safely to dark when a mobile browser does not expose a clear preference, and advertises `color-scheme` in the document head so handheld browsers apply the operator palette more consistently
- light mode now uses a materially brighter canvas, sidebar, and body gradient instead of a slightly softened dark shell, so explicit `Light` selection reads like a real daylight operator theme on phones and tablets
- action override and mission selection cards now carry less always-visible copy: action buttons show the command label cleanly without stacked micro-descriptions, mission cards rely on shorter summaries plus native tooltips, and operator detail stays in the mission brief / confirmation flow instead of repeating on every card
- Mission Config now uses the same operator search grammar as Dashboard (`pos 1-5`, `hw 2,4`, free text, callsign) and adds a reusable cluster-scope rail driven by saved swarm topology, so assignment audits can be narrowed to one top-leader cluster or `Needs review` without changing the saved mission data
- Swarm Design now reuses the same cluster-scope rail and structured search grammar as Mission Config / Dashboard, so large topology audits can pivot between `All drones`, one top-leader cluster, and `Needs review` while preserving the existing grouped cluster layout
- the dashboard overview/command shell now switches to the overlay sidebar earlier on tablets, stacks summary/command sections cleanly on phone widths, and keeps drone-card density usable instead of leaving the dashboard in a cropped desktop layout on handheld screens
- dashboard theme control is now explicit instead of a confusing cycle-only control: expanded sidebar state shows a real light/dark/auto selector with the effective mode label, and operator-facing light/dark contrast is stronger across the dashboard shell, git info, command monitor, and mission readiness surfaces
- the dashboard responsive shell now audits cleanly on live Hetzner mobile captures: the sidebar/nav overlay uses the mobile viewport state correctly, the content column no longer keeps the stale desktop gutter, and overview/command-control cards no longer overflow or clip on a 390px phone viewport
- Trajectory Planning mobile authoring now uses a denser 2-column mission brief, a horizontally compact toolbar ribbon, and a mobile-first block order that pulls live authoring controls ahead of the longer review/policy sections while preserving the richer desktop layout in both light and dark themes
- QuickScout mobile layout groundwork now stacks the top bar/search and the map-plus-sidebar flow vertically instead of forcing the desktop split-pane into a phone viewport, but final operator acceptance of QuickScout remains explicitly deferred to the next UI audit slice
- Drone Show runtime validation now rebuilds and retries its safe GET polling after transient transport resets, recreates the selected SITL fleet between internal mode runs, waits on the same live per-drone launch-readiness probe that the backend enforces before dispatch, and only retries the specific transient launch-probe `HTTP 400` path after rechecking readiness, so long multi-mode validation no longer flakes out on stale transport, bad landed geometry, or short re-stage timing races
- Smart Swarm runtime validation now restores the selected saved swarm assignments after the in-flight reassignment drill, so acceptance runs no longer leave the SITL follow chain mutated for later sessions; the Smart Swarm guide now also states explicitly that cross-mode Drone Show / Swarm Trajectory validation still requires a launch-geometry reset because those modes can end with aircraft landed away from the show pads
- Drone Show runtime validation now re-checks selected-drone launch geometry immediately before each show/custom-show dispatch, so mixed-mode SITL drills fail fast when the fleet is idle but displaced off the show staging slots instead of attempting a bad launch
- shared command tracking now sizes standalone `LAND` and `RETURN_RTL` timeouts from live target altitude when that telemetry/home-position truth is available, so high-altitude recoveries no longer flip to terminal timeout while the fleet is still descending normally
- Drone Show runtime validation now treats `/get-position-deviations` as selected-fleet truth instead of full-config truth, so 3-drone acceptance runs no longer abort just because unlaunched config slots are intentionally offline while still failing selected drones that have launch-blocking geometry errors
- command terminal states are now immutable once they reach `phase=terminal`; late ACK/execution callbacks are captured under `late_reports` for diagnostics instead of reviving timed-out/cancelled/failed commands into a newer status
- Command Control now rehydrates its live/recent command monitor from `/commands/active` and `/commands/recent` on mount, so a dashboard refresh or route change does not silently drop in-flight command context that the backend is still tracking
- shared command monitoring now keeps `/commands/active` refreshed after hydration, backfills terminal transitions from `/commands/recent`, uses backend timestamps instead of raw browser wall-clock time for initial scheduled-state snapshots, and treats `HOVER_TEST` as the same strict synchronized offboard doctrine already enforced by the backend, so reloads / second-operator sessions / clock-skewed browsers no longer show stale command progress or the wrong late-start expectations
- frontend command activity now uses one shared store across `Command Control`, per-drone airborne overrides, and `Smart Swarm Runtime`, so those surfaces feed the same backend-backed command monitor instead of each command path behaving like an isolated toast-only flow
- Swarm Trajectory planner now recomputes `Speed-driven ETA` waypoint arrival times from the operator-owned preferred leg speeds whenever upstream geometry or altitude changes, so drag moves, terrain-backed altitude edits, imports, and panel edits no longer leave stale derived ETAs behind
- Swarm Trajectory planner now keeps save/import state honest: external CSV/JSON imports load into the planner as drafts instead of silently overwriting a saved route with the same name, imported terrain-backed waypoints re-resolve their ground context before use, and the toolbar distinguishes `Unsaved draft`, `Draft auto-saved`, and clean saved state instead of collapsing them into one misleading status
- Swarm Trajectory processing now resolves followers through their direct parent chain instead of flattening every nested follower to the top leader, and swarm follow-graph validation now fails fast on circular or missing parent chains instead of quietly producing misleading partial outputs
- Swarm Trajectory command tracking now resolves mission enums robustly across mixed import paths and budgets timeout from the actual selected processed trajectories, so subset launches no longer fall back to the generic 60s tracker timeout or time out just because unrelated drones have longer routes in the same processed package
- Mission Trigger, Mission Details, and Drone Actions now reuse one shared schedule/execution policy layer, so strict synchronized missions and standalone scheduled actions explain the same late-trigger / late-start behavior everywhere instead of drifting between pages and confirmation dialogs
- standalone `TAKEOFF` now reuses the shared bounded PX4 armability gate after its GPS/home preflight checks, aligning operator expectations with Drone Show and Swarm Trajectory startup behavior instead of relying on a one-shot arm attempt
- command/status docs now explicitly distinguish strict synchronized choreography retries from standalone action retry behavior, so delayed or missed trigger semantics stay consistent for operators and integrators
- Swarm Trajectory planner speed validation now uses the same `20.0 m/s` redesign ceiling as the current runtime policy, so preferred-speed input clamping, impossible-speed flags, and operator envelope wording no longer disagree about whether `20-30 m/s` routes are still acceptable
- mission scheduling surfaces now state the strict synchronized-launch doctrine in-page for Drone Show, Custom CSV, and Swarm Trajectory, so operators see the safe queue window / late-start-abort contract before dispatch instead of discovering it only from backend behavior
- Command Control now preserves recent command snapshots instead of replacing the previous live monitor every time a newer command arrives, so operators can cross-check multi-step dispatches without losing the earlier command's lifecycle context
- overview and expanded drone cards now treat `mission` as the live/current mission and keep `last_mission` as secondary history context, so operators no longer see a stale historical mission under a label that implies current execution truth
- Swarm Trajectory waypoint editing now treats derived fields consistently across the modal and side panel: AGL-authored stored MSL altitude, speed-derived arrival time, and auto-arrival heading stay read-only with inline operator guidance, while only the real operator-owned inputs remain directly editable
- synchronized Drone Show / Custom CSV / Swarm Trajectory dispatch now stops retrying once the safe queue window before trigger-minus-warmup has passed, and the offboard runtimes abort if they miss the requested start time beyond a configurable tolerance instead of starting late and pretending the mission stayed synchronized
- command tracking now treats execution-start and execution-result callbacks as authoritative acceptance evidence, so a dropped GCS->drone HTTP ACK no longer leaves a command stuck as offline/unknown after the drone actually executed it
- Command Control now keeps a persistent live command monitor fed by the normalized backend lifecycle stages, so operators can see acknowledgment/acceptance/execution state beyond transient toasts and can dispatch `Cancel Mission` back to the same targets before trigger time or during execution from the same surface
- drone-side execution-start and execution-result callbacks now retry through a bounded in-memory queue with backoff and per-command coalescing when GCS is temporarily unreachable, so brief network loss no longer forces command tracking to time out just because one callback POST was dropped
- same-host Swarm Trajectory SITL processing/review now resolves the configured shared trajectory workspace as the backend source of truth too, so reprocessing, status, plots, and mission execution stay aligned even when GCS code is running from a different repo checkout or validation worktree
- command submission now returns the backend-selected `tracking_timeout_ms`, lifecycle toasts reuse that mission-aware timeout instead of a flat 120s frontend guess, and scheduled commands include the future trigger delay in that same timeout budget, so long Drone Show / Swarm Trajectory / RTL flows no longer degrade into false "final status unknown" warnings while the backend is still tracking them correctly
- shared command submission/tracking now uses mission-aware timeout budgets plus active background timeout promotion, so TAKE_OFF / LAND / RTL / Drone Show / Custom CSV / Swarm Trajectory / QuickScout commands no longer share one flat tracker timeout or stay stuck forever when execution reporting disappears
- scheduled shared commands now include the future trigger delay in their backend/frontend lifecycle timeout budget, so delayed takeoff/show/swarm launches do not age out before the trigger time arrives
- drone-side command handling now treats duplicate delivery of the same active `command_id` as an idempotent ACK, installs overrides transactionally so failed replacements do not falsely supersede the earlier queued mission, and gives `missionType=0` a real cancel/clear path instead of routing it through the normal mission-install flow
- the old tracker-only `POST /command/{id}/cancel` path now fails closed instead of pretending to cancel a live mission without dispatching anything to drones; live cancellation must go through the real shared command path (`missionType=0`)
- standalone `RETURN_RTL` action completion now means the full operator-visible lifecycle completed (return, touchdown, disarm) rather than only "RTL mode was accepted", which keeps action semantics aligned with command tracking, mission end-behavior handling, and long-tail landing cleanup across modes
- Swarm Trajectory planner waypoint authoring now comes from one shared operator-brief builder across the waypoint modal and waypoint panel, so altitude/timing/heading ownership uses the same labels, tones, and derived-vs-operator wording in add/edit/review flows instead of drifting between separate component-specific summaries
- Swarm Trajectory waypoint-panel altitude editing now follows the same single-owner rule as timing and heading: `Target AGL` keeps stored MSL altitude as a derived readout, while direct MSL editing stays available only when `MSL input` owns the waypoint altitude
- Swarm Trajectory planner toolbar now surfaces the live handoff posture (`Draft only`, `Review required`, `Ready to process`) and reuses the readiness model's real transfer label instead of always showing the same generic cluster-assignment action even when the current route still needs review
- command tracking now exposes one normalized operator-facing `progress` snapshot across all missions, and lifecycle toasts use it to distinguish queued/scheduled commands, active execution, and the legitimate long-tail `finishing remaining drones` phase instead of making operators infer everything from the coarse legacy `status=executing` label
- Swarm Trajectory runtime validation logs now print the same normalized command `progress` snapshot that the API exposes, so live Hetzner/SITL audits can see execution-vs-finishing lifecycle state directly in terminal output instead of only raw ACK/execution counters
- Swarm Trajectory launch-preflight now consumes backend session change-detection truth, so stale processed packages are blocked when swarm structure, raw leader CSV contents, or trajectory-processing parameters changed after the last processing pass; the workspace stages and doctrine now surface the same freshness rule instead of treating those cases as merely advisory
- Swarm Trajectory planner timing presentation now comes from one shared utility across the waypoint panel, planner brief, leader-transfer dialog, and library summaries, so `Mission clock` / `Route entry` / `Route motion` wording no longer drifts and the waypoint panel no longer shows mission clock under the older ambiguous `Route time` label
- Swarm Trajectory processed CSVs now preserve `vx/vy/vz` and `ax/ay/az` as real local NED metric quantities instead of raw lat/lon/alt derivatives, which makes runtime diagnostics and `continue_heading` end behavior consistent with the controller contract
- Swarm Trajectory initial drift sampling now uses the same non-blocking local-API pattern as Drone Show, and drift correction is skipped when preflight only has a fallback current-position reference instead of PX4's actual GPS global origin
- Swarm Trajectory runtime now treats its launch-time global reference explicitly instead of carrying it through the mission path as a misleading `home_position` name:
  - pre-flight prefers PX4 GPS global origin, with a bounded fallback to the current global position sample when the origin RPC is unavailable
  - that reference is now documented and tested as readiness / drift / recovery truth only, not as a redefinition of the authored global route geometry
- Swarm Trajectory waypoint authoring now locks confirmation until terrain lookup resolves or the operator explicitly chooses the estimated-terrain fallback, so high-terrain routes cannot be saved against stale `groundElevation=0` assumptions while the planner is still loading terrain
- Swarm Trajectory waypoint authoring now rejects non-increasing manual arrival times at the modal boundary instead of waiting for a later route-readiness pass to discover the chronology error
- Swarm Trajectory coordinate edits and dragged waypoint moves now refresh terrain truth at the new coordinates: `Target AGL` waypoints preserve the authored clearance intent by recomputing stored MSL altitude against the refreshed ground elevation, `MSL input` waypoints keep their stored mission altitude while updating derived terrain review, and stale async terrain replies are ignored so rapid waypoint moves cannot overwrite newer planner edits
- Swarm Trajectory waypoint-panel coordinate saves now show that terrain and clearance are being refreshed instead of pretending the edit is an instant local-only change, keeping operator feedback aligned with the real async terrain update path
- Swarm Trajectory workspace wording now treats partial outputs as attention-state review packages instead of generic launch-ready results, frames git commit as optional mission traceability rather than a safety gate, and labels the handoff back to command control as `Open Mission Trigger` so launch approval is clearly anchored in dashboard preflight
- Swarm Trajectory cluster-state handling now normalizes partial-state aliases in the shared frontend model, so readiness cards, processing workspace views, and tests cannot silently drift if a legacy `partial` state appears in mocked or transitional data
- Swarm Trajectory follower generation now applies NED/body offsets around each leader waypoint's instantaneous global position instead of a fixed formation centroid, and `offset_z` now follows the documented Swarm Design `Up-positive` convention all the way through the global follower projection math
- Swarm Trajectory planner terrain review no longer mistakes `groundElevation=0` for missing terrain, so sea-level routes keep their real terrain-confidence and AGL-clearance context in waypoint review instead of silently dropping those cues
- Swarm Trajectory authoring guidance now treats terrain confidence as a first-class operator cue and uses `leg` terminology consistently in the waypoint modal, keeping altitude/timing/heading/terrain ownership aligned across modal, panel, docs, and tests
- Trajectory library saves now reject blank/whitespace-only route names at both the dialog and storage layers, so planner saves cannot quietly create invalid catalog entries and valid names are normalized consistently before reuse or overwrite
- Swarm Trajectory planner, launch review, docs, and shared execution doctrine now state the mission frame explicitly: authored routes stay global lat/lon with stored MSL altitude, while PX4 launch/home truth remains an execution-time readiness and recovery input instead of a hidden route transform; the mission script also no longer carries the stale `shapes/.../swarm/processed` provenance path
- Swarm Trajectory planner import/export language now calls out the real asset boundary: CSV import/export is the authored leader route for round-trip editing or assignment, not the processed multi-drone mission package that gets launched later from `Swarm Trajectory` + dashboard Mission Type 4
- Swarm Trajectory planner/library/transfer summaries now label authored **Route Time** explicitly instead of a generic duration, because real command completion can be materially longer once initial climb, RTL, landing, and other end-behavior cleanup are included
- launch-from-ground mission dispatch now uses a live per-drone MAVSDK armability probe before GCS sends the command, closing the gap where passive telemetry could still look ready while PX4 would deny arming at mission start
- Drone API now exposes an explicit live armability probe endpoint backed by the same MAVSDK startup-health logic used by Drone Show and Swarm Trajectory mission startup, so launch gating and mission runtime share one armability definition
- live armability callers now use one total HTTP timeout budget derived from MAVSDK connect time + probe time + transport margin, so slow-but-valid SITL probes no longer get mislabeled as unreachable before the drone-side readiness endpoint has actually finished
- telemetry readiness now distinguishes actual PX4 HOME_POSITION truth from the first fallback GPS position cache, so `home_position_set` and launch gating no longer silently treat "we have a position sample" as "PX4 home is established"
- Swarm Trajectory / live readiness validation now treats a lone MAVLink `system_status=UNINIT` report as an advisory when PX4 preflight data and live telemetry are otherwise healthy, preventing false launch blocks after SITL mission recovery while still surfacing the discrepancy to operators
- Swarm Trajectory Mission Type 4 launch readiness is now scope-aware instead of globally all-or-nothing: a selected subset can launch when every selected drone has a processed output and the full required leader chain is included, while unrelated incomplete clusters stay as warnings instead of false blockers
- Swarm Trajectory selected-target safety is now enforced in both layers: the dashboard preflight blocks broken leader chains or missing processed outputs, and the backend `/submit_command` path rejects the same unsafe subset even if the UI is bypassed
- Swarm Trajectory status/preflight now exposes authoritative processed-package timing and altitude truth from the generated `Drone N.csv` files, so Mission Type 4 launch surfaces can show mission clock, route-entry time, route-motion window, and altitude envelope from the active package instead of relying on looser inferred summaries
- Swarm Trajectory package timing/altitude formatting now comes from one shared frontend utility across Mission Type 4 launch surfaces, and the leader-assignment dialog now shows the current selected-cluster package summary plus the exact “current outputs become stale until reprocess” impact of uploading a new leader CSV
- the standard `linux_dashboard_start.sh --sitl` / development launcher path no longer starts FastAPI with `--reload` by default, because backend auto-reload splits in-memory telemetry, heartbeat, and command-tracker state across processes; backend reload is now an explicit opt-in debug override only
- Swarm Trajectory planner, transfer dialog, docs, and validation tooling now share one clearer four-stage operator model (`author leader path -> define route entry/leg intent -> assign leader -> process/review/launch`), and the runtime validator now imports the real repo timeout model instead of silently falling back to stale internal timeout constants when run from the `tools/` path
- Swarm Trajectory authoring terminology is now precise about leg-vs-waypoint ownership: the UI and docs use `Route entry delay`, `Waypoint arrival time`, `Preferred leg speed`, `Required leg speed`, and `Entry heading` / `Arrival heading` consistently, so operators no longer have to infer whether a field belongs to the route anchor, the inbound leg, or the arrival posture
- Swarm Trajectory route-entry timing now comes from one shared timing policy: waypoint 1 defaults to a `10s` route-entry delay after mission start, the planner surfaces that default explicitly, and timing helpers use the same fallback instead of hidden duplicated magic numbers
- Swarm Trajectory mission briefs and transfer summaries now show the real authored route-entry delay (for example `Entry +12s`) instead of only counting that a route-entry anchor exists
- Swarm Trajectory runtime validation can now prepare its own short deterministic top-leader profile before processing, so subset SITL acceptance runs (for example 3-drone cluster tests) no longer depend on a previously loaded long route on the host
- local Docker SITL now shares the host `shapes_sitl/swarm_trajectory/` workspace into each container through a dedicated runtime path, so same-host Swarm Trajectory processing and execution stay consistent without forcing a repo commit or leaving the container repo dirty
- Swarm Trajectory end-behavior recovery is now fail-closed: if `return_home` and every recovery path still fail, the mission exits with failure instead of logging a critical line and then incorrectly reporting mission success
- Swarm Trajectory RTL completion now has a bounded near-ground low-motion fallback for SITL/PX4 edge cases where the aircraft is effectively down but never transitions to `ON_GROUND`, preventing one drone from hanging the entire command for the full RTL timeout
- the Swarm Trajectory runtime validator now tracks per-drone peak altitude gain over time instead of requiring every selected drone to be above the climb threshold on the same polling tick, which removes false failures on short follower routes that clear the climb gate and then descend into a lower processed path
- Swarm Trajectory authoring and transfer now use the real operator wording end to end: the planner action is `Assign to Cluster`, readiness transfer labels match that cluster-assignment model, planner notices now say when a leader path was assigned rather than vaguely "sent", and the transfer dialog title/copy no longer hides that this is a leader-cluster handoff
- Swarm Trajectory authoring guidance is now single-source across the planner, waypoint modal, waypoint panel, and transfer surface: shared descriptions explain what `MSL input`, `Target AGL`, `Speed-driven ETA`, `Time-driven speed`, `Auto heading`, `Manual heading`, and the `Mission start anchor` actually mean, while waypoint intent tags move that extra detail into hover hints instead of duplicating noisy prose inline
- Swarm Trajectory waypoint authoring now labels derived timing/speed values explicitly (`Derived waypoint arrival time`, `Leg speed check`) so the modal and waypoint panel show which values are operator-owned versus planner-derived instead of relying on disabled fields or post-hoc warnings
- the waypoint panel guidance now tells operators that only owned inputs are editable, while derived timing and speed checks remain locked and continuously visible
- legacy frontend hook/dependency warnings in `DroneDetail`, `DroneGraph`, `Globe`, `MapSelector`, and `OriginModal` were cleaned up, and the dashboard production build now passes again under `CI=true`
- Swarm Trajectory planner and transfer now expose one shared operator-policy strip before assignment: the UI states explicitly that missions always execute stored MSL altitude, `Target AGL` is authoring input converted at planning time, terrain confidence changes review posture, and waypoint 1 owns route-entry timing/heading while later legs own ETA-versus-speed intent
- Swarm Trajectory processing workspace now repeats the same execution boundary before launch review: operators see in-page that only top leaders are authored, processed drones fly per-drone generated global paths, Smart Swarm is the live-follow mode instead, and any earlier AGL planning input has already been converted into the stored MSL mission package
- Swarm Trajectory planner CSV interchange now preserves authoring intent as optional metadata columns: exported leader CSVs keep altitude reference, target AGL, terrain confidence, timing mode, preferred speed, and calculated heading for round-trips back into the planner, while older minimal mission CSVs still import correctly and backend processors continue accepting the same required core columns
- Swarm Trajectory `Leg Review` now supports condensed attention-only and full-route audit modes, and each leg exposes compact timing, heading, altitude, and terrain-confidence intent so operators can audit the whole path without leaving the planner
- Swarm Trajectory subset runtime validation now adapts its generated short-profile route-entry delay to the selected follower offsets and reports inactive/post-mission geometry windows explicitly, preventing misleading failures when a short SITL validation route ends before a large-offset cluster can fully form
- command tracking now reopens ACK-only failed commands when later execution evidence proves the drone really ran the mission, so low-bandwidth false-offline classifications do not stay terminal forever
- Swarm Trajectory runtime validation now exposes stable processed-window aliases and requires sustained active geometry before declaring formation success, so a t=0 coincidence or immediate mission drop-out does not look like a valid convergence pass
- Swarm Trajectory subset formation validation now uses the processed per-drone mission package as the authoritative geometry reference over mission time, instead of re-deriving follower expectations from raw assignment offsets that no longer fully represent the executed global paths
- Swarm Trajectory planner timing summaries now separate `Mission Clock` from `Route Motion`, so route-entry delay is no longer silently folded into the same operator-facing “route time” number while also being shown separately elsewhere
- the first Swarm Trajectory waypoint now stays explicit/manual all the way through modal initialization, so the mission-start anchor no longer boots in a contradictory auto-heading state or disables the operator's initial route-entry heading field
- Swarm Trajectory initial climb is now a real safety gate instead of a time-only phase: waypoint progression no longer advances while the climb gate is still unresolved, launch altitude confirmation can fall back to launch-referenced absolute altitude when relative altitude lags, and a failed climb now terminates loudly with safe cleanup instead of silently exhausting the mission in the background
- Swarm Trajectory 5-drone SITL runtime validation now passes end to end on the hardened mission engine, including process -> climb gate -> in-flight follower geometry -> long return-home completion -> command tracker terminal success -> fleet idle reset
- Swarm Trajectory planner utilities and authoring components no longer emit routine browser-console warning noise for handled fallback paths, and the trajectory authoring surface was cleaned of stale phase-specific banner comments that no longer described the maintained behavior
- Swarm Trajectory runtime validation now budgets the terminal wait window from the processed mission peak altitude instead of the early formation snapshot altitude, so high-altitude RTL descents no longer time out while the aircraft is still descending correctly
- Swarm Trajectory mission validation now enforces a real initial-climb altitude sample before leaving the takeoff gate, preventing premature path-follow entry on time-only progress
- Swarm Trajectory `return_home` cleanup is now bounded and mode-aware: the mission verifies that PX4 really enters RTL, retries once if a drone remains stuck in Hold/Offboard, and degrades to explicit LAND fallback with bounded action-RPC waits instead of hanging indefinitely on a lost ACK or non-engaged RTL state
- Swarm Trajectory planner geodesic math is now self-contained and testable: speed, heading, timing, and trajectory statistics no longer depend on the heavier Turf bundle in `SpeedCalculator`
- Swarm Trajectory planner statistics now use the same 3D path-distance model as the speed/timing logic, so climb/descent legs are reflected consistently in operator-facing totals and average speed
- direct frontend utility coverage now exists for Swarm Trajectory planner speed, heading, timing validation, and 3D stats
- Swarm Trajectory waypoint authoring now has an explicit segment-planning model instead of a hidden time-only assumption: later-waypoint modals can run in `Auto from leg speed` or `Manual arrival time`, the waypoint panel exposes `Segment Plan` and `Leg Speed` inline, and derived arrival times are clearly shown as derived rather than free-edit fields
- Swarm Trajectory planner state now preserves operator intent through modal -> panel -> save/load/export -> undo/redo, including timing mode, preferred leg speed, and terrain context metadata instead of dropping those fields after creation
- Swarm Trajectory altitude authoring now supports both direct `MSL input` and terrain-assisted `Target AGL` entry while keeping canonical mission storage in MSL, and the planner review surface now shows derived AGL context plus the stored altitude plan instead of hiding that conversion
- Swarm Trajectory planner now publishes a real mission brief before swarm transfer, summarizing distance, duration, altitude envelope, max-leg-speed posture, timing mode mix, altitude-input mix, heading intent, and terrain-confidence so operators can catch speed or terrain caveats before leader assignment
- Swarm Trajectory planner now repeats its execution model on the authoring surface itself, so `Trajectory Planning` explicitly declares that it authors top-leader paths only, keeps launch-readiness/terrain/speed caveats visible above the map, and avoids forcing operators to infer workflow state from separate pages
- waypoint authoring and review now expose the same operator intent model everywhere: the modal publishes altitude-plan / segment-plan / heading / terrain summary cards, and waypoint cards show compact tags for altitude reference, timing mode, heading mode, and terrain confidence before launch
- Swarm Trajectory planner save/load now uses one shared trajectory-library dialog instead of duplicated page-local modal code, and the library view exposes duration, distance, max speed, modified time, and autosave status so operators can reload the right leader path without guessing
- Swarm Trajectory planner mission-envelope defaults are now centralized in one shared policy module, so altitude/speed defaults, validation bounds, terrain-safety fallback altitude, and operator-facing envelope text no longer drift between modal, panel, search, storage, and planner summary surfaces
- Swarm Trajectory waypoint leg ownership is now consistent across math and UI: the first waypoint is always the explicit manual mission-start anchor, while every later waypoint owns the arrival-leg speed and auto-heading that reaches it instead of mixing inbound timing with outbound heading/speed labels
- Swarm Trajectory waypoint review no longer forces operators to mentally convert terrain-backed altitudes: the panel now makes `Altitude Input` editable, keeps stored MSL explicit, and lets `Target AGL` waypoints edit `Clearance AGL` directly while recomputing canonical stored altitude
- Swarm Trajectory processing/review now uses one clearer staged workspace model: the page surfaces a single workspace-status banner, explicit step cards for upload/process/review readiness, step-local processing recommendations, and commit actions that live inside the review stage instead of being scattered across the screen
- Swarm Trajectory planner/transfer readiness now uses one explicit mission-posture model: timing conflicts, single-waypoint drafts, and impossible-speed legs are surfaced as transfer blockers, review-only caveats stay separate from blockers, and the `Send to Swarm` dialog now shows whether a path is `Draft only`, `Review required`, or `Ready to process` while using real cluster-state truth instead of a simplified ready/uploaded heuristic
- Swarm Trajectory authoring labels are now consistent across the planner, waypoint modal, and waypoint panel: the first point is explicitly treated as the `Mission start anchor`, non-initial legs use `Speed-driven ETA` vs `Time-driven speed`, altitude review emphasizes canonical stored MSL, and duplicate warning noise was removed from the header stats so action-focused caveats stay in the workflow brief instead
- Swarm Trajectory planner handoff/navigation is now wired end-to-end: `Send to Swarm` can open `Swarm Design` or `Swarm Trajectory` directly from the dialog, readiness/docs/runtime copy now explicitly treat `Swarm Design` as the prerequisite step, and launch instructions now point to `Dashboard -> Command Control -> Mission Trigger` instead of the stale `Mission Control` wording
- Mission Type 4 preflight now summarizes the processed Swarm Trajectory package more clearly, including ready clusters, processed drones, missing uploads, the active processing session, and direct remediation links back to the authoring / processing pages
- Swarm Trajectory page now takes processing recommendation and freshness guidance from the status payload itself, so workspace state, review prompts, and launch gating no longer depend on a second recommendation fetch that could drift from the active session snapshot
- Swarm Trajectory follower generation no longer carries a stale `formation_origin` contract through the processor; offsets are now documented and coded directly against each leader waypoint's instantaneous global position, which removes one misleading origin concept from the stack
- Swarm Trajectory planner/operator doctrine now states that follower regeneration is leader-waypoint-relative global geometry, not a separate centroid/origin model, so the planner brief and launch-policy notes match the real processor/runtime contract
- Trajectory planner undo/redo state now uses the real recalculated waypoint arrays for add/update/delete/move operations, preventing stale internal state from drifting away from what the operator actually sees in the planner
- Swarm Trajectory planner now uses inline notices for destructive actions, waypoint edit validation, modal altitude validation, and keyboard-shortcut help instead of blocking browser popup flows, while keeping altitude authoring explicitly MSL with terrain-derived AGL context
- Swarm Trajectory processing/status truth is now richer and less heuristic: recommendations include expected/uploaded/missing leader IDs, processing results now distinguish `success` vs `partial` outcome, cluster status exposes explicit states/issues/advisories, and planner export now uses the current in-memory path instead of stale saved-local-storage state
- drone `UPDATE_CODE` commands now preserve their runtime `update_branch` payload all the way into mission execution, so dashboard-triggered repo sync actually runs instead of reporting accepted while silently failing branch resolution on the drone
- git-sync verification now ignores generated SITL provenance metadata files, so stock containers do not stay permanently `dirty` just because they carry build/provenance markers
- the `Sync Now` flow now verifies real branch/commit convergence before reporting success, and default all-drone sync now prefers recently active drones instead of counting stale offline config slots from the same host
- `tools/update_repo_ssh.sh` now resolves user/home robustly even in non-interactive container execution, avoiding `USER: unbound variable` failures during scripted sync actions
- `tools/update_repo_ssh.sh` no longer treats ICMP `ping` as a hard requirement for connectivity, so Docker/SITL sync uses TCP-aware advisory probing and lets the actual `git fetch` decide whether network access is available
- mission and action scheduling now present GCS-aligned UTC execution times more clearly, so operator confirmations/toasts stay consistent even when the browser wall clock is off
- browser/GCS clock-drift notes now appear only for material offsets instead of small harmless differences, reducing operator noise during normal SITL use
- per-drone overview-card overrides now explain that they are airborne intervention controls, so disarmed or link-unavailable cards no longer look like broken action panels
- overview preflight tiles no longer flicker back to "Checking git state" on each poll, and now use quieter state coloring plus hover diagnostics instead of text churn
- the Actions tab is more compact, action descriptions moved to hover/confirmation context, and flight/test actions can now be scheduled without forcing maintenance or danger actions into delayed execution
- dashboard drone cards now separate warning/unknown link states from true blocked readiness, add clearer link-state hover details, and avoid treating every non-ready state as the same red alarm
- the Custom CSV workflow now has a real dashboard upload/validate/preview path instead of the old placeholder/CORS-broken preview behavior
- the Drone Show dashboard now states more clearly that SkyBrush ZIP import and Custom CSV are separate operator workflows, reducing accidental mode confusion
- **Custom Repo Workflow Validation**:
  - documented the real GitHub behavior that public upstream forks stay public by default, so confidentiality-sensitive customer setups should use a private mirror/custom repo path instead of assuming a private fork
  - GCS and drone SSH repo setup now pin repo-local `core.sshCommand` when SSH is used, so pre-existing host `~/.ssh/config` GitHub identities do not silently override the intended MDS deploy key
  - GCS env configuration now rewrites `/etc/mds/gcs.env` when repo, branch, or access mode changes on a non-interactive rerun, so launcher/runtime state stays aligned with the selected customer repo instead of preserving stale official defaults
  - SITL runtime and SITL image preparation now use file-backed private GitHub auth via `MDS_GIT_AUTH_TOKEN_FILE`, so private mutable SITL and private custom-image builds avoid exposing raw tokens in process arguments
  - fresh headless GCS startup is now robust when Node.js was installed via `nvm`, because the launcher discovers the Node toolchain explicitly and uses absolute `uvicorn` / `gunicorn` / `npm` paths inside tmux panes instead of depending on inherited shell PATH state
  - SITL image preparation and live SITL runtime no longer blank the repo URL when authenticated GitHub HTTPS is unavailable, and official/custom image builds now stop immediately if runtime filesystem preparation fails instead of flattening a partial container
- the official public SITL archive was rebuilt from the corrected release flow, republished on MEGA, and re-linked in the SITL guide after validation on a fresh Hetzner host
- dashboard runtime freshness now uses a server-derived telemetry clock hint instead of blindly trusting the operator browser clock, so fresh remote SITL sessions no longer show false stale-link readiness states just because the client clock is skewed
- Drone Show and Swarm Trajectory offboard startup now share a bounded MAVSDK armability gate before arming, reducing transient PX4 pre-arm denials during SITL and hardware mission launch
- drone readiness cards now preserve a recent PX4 readiness snapshot as a warning-only link issue instead of immediately flipping the whole card to `Unverified`, so low-bandwidth or briefly delayed telemetry is shown more cleanly for operators
- the Custom CSV page now uses the served image endpoint directly instead of a cross-origin `fetch()` blob path, which removes the false preview error caused by browser CORS on `:3030 -> :5000`
- drone card position-ID comparison now normalizes numeric/string values before flagging a mismatch, so matching IDs no longer show a false warning icon
- the Overview dashboard now normalizes live telemetry before rendering drone cards, so browser/server clock skew no longer produces false `Heartbeat only` / `Link lost` card states, and short 3-point SkyBrush imports now process correctly through the linear fallback path
- the telemetry API now exposes a server clock header and the dashboard uses that server-derived time when evaluating freshness, so moderate browser clock drift no longer silently degrades link state; if a meaningful client/server offset exists it is surfaced in the link-status tooltip instead
- Swarm Trajectory readiness now uses truthful per-cluster backend state instead of heuristic leader-count guesses: uploaded raw CSV content changes force a fresh reprocess, leader uploads are validated against the current top-leader set, processing status now exposes real cluster readiness/missing followers/plot availability, and the dashboard distinguishes `ready`, `pending process`, and `missing upload`
- Mission Type 4 dashboard launch gating now follows that same backend cluster truth instead of only generic mission heuristics, so missing uploads, pending processing, partial outputs, cluster issues, and missing active-package state all block launch before dispatch
- Swarm Trajectory review/git actions now respect the actual GCS write-back mode: writable setups keep `Commit & Push Outputs`, while read-only/demo setups use a truthful local-commit-only path and the backend stops before pull/push when `MDS_GIT_AUTO_PUSH=false`
- direct frontend tests now cover the Swarm Trajectory launch-readiness model, Mission Type 4 launch gating, and the page-level local-commit wording for read-only GCS deployments
- Swarm Trajectory planner now includes a dedicated `Leg Review` surface so operators can see per-leg distance, duration, required speed, and nominal / review / unsafe pacing before assigning a leader path to a swarm cluster
- Swarm Trajectory planner/operator guidance now states explicitly that current `Target AGL` assistance is waypoint-based rather than full along-leg terrain following, so sparse routes over changing terrain are not misinterpreted as true terrain-follow missions

### Added
- **Custom Repo Workflow Guide**:
  - new `docs/guides/custom-repo-workflow.md` covering customer/private repo operation across GCS, real drones, SITL, upstream sync, and custom release images
- **Repo-wide AI agent operating spec**:
  - new root `AGENTS.md` as the canonical machine-oriented SITL audit/debug/release loop
  - thin root `CLAUDE.md` and `GEMINI.md` shims that point to the shared spec instead of duplicating instructions
  - new `docs/superpowers/specs/2026-03-26-ai-agent-sitl-audit-loop.md` for the deeper agent-only execution contract
  - new `docs/superpowers/README.md` index so agent-only specs/plans stay organized without cluttering user-facing docs
- **Drone Show Operator Guide**:
  - new `docs/features/drone-show.md` covering SkyBrush import flow, GLOBAL/LOCAL modes, Custom CSV, trigger timing, and read-only demo guidance
- **Unified Logging System (`mds_logging`)**: Shared logging contract for all components
  - JSONL format for machine-parseable log files with ISO 8601 UTC timestamps
  - Session-based retention with configurable limits (count + size)
  - Colored console output with component-tagged messages
  - Component self-registration registry for auto-discovery
  - In-memory pub/sub watcher for SSE streaming
  - Shared CLI flags: `--verbose`, `--debug`, `--quiet`, `--log-json`, `--log-dir`
  - Environment variable config with `MDS_LOG_*` prefix and deprecation shims
- **Frontend Log Viewer (Phase 3)**:
  - Log Viewer page at `/logs` with Operations and Developer modes
  - Operations mode: WARNING+ filter, health bar, live event feed, clean UI
  - Developer mode: all log levels, component tree, search, session selector, export
  - Explicit `GCS` vs `Drone #N` scope switch for live streams and historical sessions
  - Human-readable session labels with explicit UTC note, clickable error/warning drill-down, and time-window focus controls
  - Active filter chips, one-click `Clear All Filters`, and explanatory empty states to reduce operator confusion
  - MUI DataGrid virtual scroll for 100K+ log rows
  - Real-time SSE streaming via `useLogStream` hook with 200ms batching and 5000-line ring buffer
  - Historical session browsing with filtering and client-side pagination
  - Export sessions as JSONL or ZIP, including proxied drone sessions
  - ErrorBoundary catches React render errors and reports to `POST /api/logs/frontend`
  - New "System" sidebar section with Log Viewer entry
  - `@mui/x-data-grid` dependency for virtual scroll
- **Log Aggregation & Streaming (Phase 2)**:
  - Drone-side log API: `GET /api/logs/sessions`, `GET /api/logs/sessions/{id}`, `GET /api/logs/stream` (SSE)
  - GCS log API router with 10 endpoints at `/api/logs/*`
  - Real-time SSE streaming with level/component/source/drone_id filtering
  - GCS-to-drone log proxy (sessions, session content, SSE stream forwarding)
  - Session export as JSONL or ZIP via `POST /api/logs/export`
  - Frontend error reporting via `POST /api/logs/frontend`
  - Component registry endpoint at `GET /api/logs/sources`
  - Optional background pull of WARNING+ logs from drones (`MDS_LOG_BACKGROUND_PULL`)
  - Runtime config toggle at `POST /api/logs/config`
  - `read_session_lines()` helper for filtered session content retrieval
  - `httpx` async HTTP client dependency for drone proxy
- **SITL Image Release Tooling**:
  - `tools/sitl_image_prepare.sh` to rebuild a clean runtime filesystem inside a temporary container
  - `tools/release_sitl_image.sh` to flatten and retag official SITL releases without carrying old `docker commit` history
  - `tools/run_with_log_policy.py` for bounded runtime file logs in SITL containers
- **Smart Swarm Runtime Guide**:
  - Dedicated operator/developer guide at `docs/features/smart-swarm.md`
  - Explicit command-scope model for single-drone vs swarm-level runtime controls
  - Documented leader-loss policy and extension points for future election strategies
- **Smart Swarm Acceptance Tooling**:
  - `tools/validate_smart_swarm_runtime.py` for branch-level 5-drone SITL validation
  - waits for preflight readiness before takeoff so fresh-boot SITL checks do not race container startup
  - validates full command acceptance/execution, cluster settle, live reassignment, leader-only RTL, hold, land, and final disarm

### Changed
- detached-worktree runtimes now resolve a meaningful git branch name for both
  GCS-side and drone-side git status reporting instead of surfacing
  `HEAD`/branch-read failures when the runtime lives in a git worktree
- the SSH git-sync bootstrap/update path now falls back to a detached
  `origin/<branch>` checkout when the named branch is already owned by another
  worktree, which keeps clean-runtime deployments and startup git sync working
  together on Hetzner and future production hosts
- generated SITL validator artifacts and trajectory-session state are now
  treated as runtime data instead of tracked repo content, so successful
  validation runs do not make the runtime repository appear dirty
- the public SITL download instructions in `docs/guides/sitl-comprehensive.md`
  now point at the refreshed `main@1c0ebc6` archive link published on
  2026-04-10
- the SITL validation docs now state the container lifecycle policy explicitly: recreate at suite start, before late Drone Show after other mission families, and after the suite; container reuse remains a narrow debugging convenience rather than the acceptance-grade default
- the SITL validation suite now supports a checked-in scenario library through `--list-bundled-plans` and `--plan-name`, so maintainers, CI, and AI agents can run named git-tracked scenarios from `tools/sitl_plans/` instead of relying on ad hoc temporary JSON plan files
- the checked-in SITL plan library now exposes stable named scenarios for configuration round-trip, Drone Show, actions, Smart Swarm, Swarm Trajectory, mission regression, and full operator regression while leaving the harder mixed-mode/fault-injection drills explicitly deferred until they are deterministic enough for routine acceptance
- the reusable SITL validation platform now treats Mission Config/origin as a first-class deterministic acceptance gate via `tools/validate_configuration_runtime.py`, a safe `config_only` template, and the default `operator_regression` flow `reset -> configuration -> reset_before_drone_show -> Drone Show -> actions -> Smart Swarm -> Swarm Trajectory -> final reset`
- fleet config persistence now accepts `PUT /api/v1/config/fleet?commit=false`, so live validation and other temporary config workflows can bypass git auto-push safely instead of inheriting the global writable-host policy
- suite provenance now tolerates non-git validator roots cleanly, so plain synced validator copies remain supported for split-root or remote-host workflows without noisy git stderr leakage
- the SITL validation docs and AI-agent SITL operating spec now describe the platform as host-agnostic, with explicit same-host, split-root, and remote-`base_url` usage instead of one VPS-specific layout
- retired the public GCS show-management legacy routes `/import-show`, `/download-raw-show`, `/download-processed-show`, `/get-show-info`, `/get-custom-show-info`, `/import-custom-show`, `/get-comprehensive-metrics`, `/get-safety-report`, `/validate-trajectory`, `/deploy-show`, `/get-show-plots`, `/get-show-plots/{filename}`, and `/get-custom-show-image`, leaving the canonical `/api/v1/shows/skybrush*` and `/api/v1/shows/custom*` surfaces as the only supported GCS contract for show workflows
- retired the public GCS configuration/swarm legacy routes `/get-config-data`, `/save-config-data`, `/validate-config`, `/get-drone-positions`, `/get-trajectory-first-row`, `/get-swarm-data`, `/save-swarm-data`, and `/request-new-leader`, leaving the canonical `/api/v1/config/fleet*` and `/api/v1/config/swarm*` surfaces as the only supported GCS contract for those domains
- `Show Design` / `Custom Show` operator guidance, Mission Details, and the Drone Show guide now reflect the current split between the normal SkyBrush import pipeline and the expert-only Custom CSV override
- Bootstrap installers now propagate custom repo/branch selections all the way into `mds_gcs_init.sh` / `mds_node_init.sh`, including explicit `--repo-url` support and correct persistence of custom branch settings in later config/state
- Root `README.md` and `docs/README.md` now use a cleaner "start here" / role-based navigation model so testers, operators, deployers, and maintainers can reach the right guide with less duplication and less scrolling
- Drone git sync now uses the same repo/branch source of truth in both boot-time sync and operator-triggered `UPDATE_CODE` flows by loading `/etc/mds/local.env` before resolving `MDS_REPO_URL` / `MDS_BRANCH`
- Bootstrap and setup flows now accept `--fork OWNER` or `--fork OWNER/REPO`, so customer org/private repo paths no longer require ad hoc URL rewriting
- README, docs index, setup guides, automation guides, and troubleshooting guides now route custom repo users to a single end-to-end workflow instead of assuming only a personal GitHub fork
- fresh-host setup guides now include the missing `curl` prerequisite for the one-line GCS bootstrap and explicitly note the validated headless `/health` readiness check after launch
- SITL archive docs now standardize on the official `MEGAcmd` client installed through MEGA's Ubuntu package and `apt`, so public downloads and authenticated archive replacement use one consistent toolchain
- the official public SITL archive was refreshed again from the exact validated branch state and re-exported on MEGA with baked commit `f55a65b`
- the SITL guide now points directly to the YouTube playlist, trims repeated Mega wording, clarifies that manual browser download of the same archive is acceptable on local systems, and adds a stronger advanced/custom/hardware caution with direct contact info
- Drone Show now separates the tracked stock SITL demo origin (`data/origin.sitl.default.json`) from the mutable runtime origin override (`data/origin.json`), and the stock Azadi Stadium default is shared by both GCS origin fallback and `startup_sitl.sh`
- The shipped SITL Drone Show bundle now matches the stock 5-drone SITL config end-to-end, and packaged Drone Show metrics were refreshed so stock assets no longer drift from config
- Superseded running Drone Show missions now report a terminal execution result back to GCS instead of leaving command tracking stuck in `executing`
- GCS HTTPS/demo installs now write `MDS_GIT_AUTO_PUSH=false` into `/etc/mds/gcs.env`, and dashboard imports/saves fail fast instead of hanging on interactive push prompts
- Drone Show dashboard surfaces now avoid misleading empty export/visualization states before any show is imported, and the custom CSV confirmation path is explicit about its local-only execution model
- All GCS server components migrated from `gcs_logging`/`logging_config` to `mds_logging`
- All drone-side components migrated from `configure_logging()`/inline setup to `mds_logging`
- CLI flags unified: `--debug` replaced with `--verbose`/`--debug`/`--quiet`
- Backend compatibility shims and test helpers now match the current FastAPI/httpx websocket path, telemetry schema, and session ordering behavior so the full regression suite stays green on current dependencies
- `multiple_sitl/startup_sitl.sh` now keeps runtime repo sync via `git fetch/reset`, only reinstalls Python requirements when `requirements.txt` changes, and bounds container-side file logs by default
- Docker SITL image prep now preserves the real PX4 git/submodule metadata, records PX4 provenance in image metadata files, and makes the startup repo auto-sync behavior explicit as mutable latest-on-boot mode
- Docker SITL launcher now persists wrapper-level startup diagnostics, strips repetitive PX4 shell prompt noise from `sitl_simulation.log`, and waits for PX4/router/coordinator readiness before reporting success
- `tools/build_custom_image.sh` now produces flattened custom images instead of layering more state through `docker commit`
- SITL image preparation/build docs now pin PX4 plus baked `mavsdk_server` inside the image, pass `MDS_MAVSDK_VERSION` / `MDS_MAVSDK_URL` through the image-build path, and use updated MAVSDK release asset naming for current releases
- SITL public setup docs now separate pinned validated releases from mutable latest-on-boot development mode, add a dedicated custom release workflow guide, and refresh FastAPI startup/version guidance for current GCS deployment behavior
- Root and docs index READMEs now reflect the current MDS 5 scope more accurately, including QuickScout SAR, trajectory planning, unified logging, and the current SITL/custom-release workflow paths
- Smart Swarm now refreshes GCS-backed assignments before startup role selection, exposes compact swarm-runtime controls in the dashboard, and uses a safer `upstream_or_hold` leader-loss default instead of cross-cluster numeric fallback
- Smart Swarm runtime controls now default to `Selected Drone`, with explicit `Selected Cluster` scope for formation-level actions so mixed missions stay predictable
- Smart Swarm dashboard flow now includes a clearer `Formation Preview`, live readiness snapshot, scoped start blockers, explicit cluster-target semantics, and less redundant ready-state noise on drone cards
- Smart Swarm follower recovery now restarts offboard cleanly on follower re-entry, waits for state lock before sending setpoints, and treats stale leader telemetry as a failover condition
- GCS swarm updates now reject follow-chain cycles both for dashboard saves and live `/request-new-leader` changes
- Smart Swarm predictor/control internals now use corrected grouped-state Kalman process noise, incremental prediction timing, and leader-velocity feedforward to reduce formation lag
- Smart Swarm leader-change notifications now update only `follow` in GCS so failover or runtime reassignment does not overwrite fresher operator-edited offsets/frame values
- GCS launcher logging is now quieter by default: duplicate raw access logs are disabled unless `MDS_GCS_ACCESS_LOGS=true`, and noisy third-party HTTP client debug output is suppressed so Smart Swarm/runtime signal stays readable
- GCS launchers now set console logging deterministically through `MDS_GCS_CONSOLE_LOG_LEVEL` (default `INFO`), so inherited shell/debug state does not silently make the first-run tester flow noisy
- Smart Swarm and GCS polling paths now use named transport timeout parameters instead of scattered literals, including follower leader-state fetches, GCS swarm-config refresh, leader-change notify, and GCS drone telemetry/git pulls
- Routine successful command-status polling (`GET /command/<id>`) and internal execution-result callbacks are now treated as `DEBUG` request noise instead of `INFO`
- Drone config lookups no longer spam routine `INFO` lines during normal runtime polling
- SITL and Smart Swarm docs now reflect Python 3.11+ manual requirements, the optional nature of external NetBird/MAVLink routing, the stock 5-drone SITL config limit, and the validated Smart Swarm acceptance flow
- SITL distribution docs now treat third-party `megatools` as public-download-only and standardize authenticated archive replacement on official `MEGAcmd`, including the refreshed public archive link for the current validated image
- README and Smart Swarm docs now spell out the first dashboard-driven Smart Swarm operator path from `Overview` readiness checks through `Swarm Design` runtime control

### Removed
- `gcs-server/logging_config.py` (857 lines, DroneSwarmLogger)
- `gcs-server/gcs_logging.py` (PYTHONPATH workaround wrapper)
- `src/logging_config.py` (drone-side logging config)
- `configure_logging()` function from `drone_show_src/utils.py`
- `setup_logging()` function from `functions/file_management.py`
- All `logging.basicConfig()` calls across the codebase

---

## [5.0] - 2026-02-24

### Added
- **QuickScout SAR/Reconnaissance Module**: Multi-drone cooperative area survey
  - New mission mode: `QUICKSCOUT = 5` with boustrophedon coverage planning
  - Boustrophedon (lawn-mower) coverage path planner with Shapely polygon operations
  - ENU coordinate conversion via pymap3d for accurate local planning
  - Automatic sector partitioning and GPS-proximity drone assignment
  - PX4 Mission Mode executor (`quickscout_mission.py`) with MAVSDK mission upload
  - Mission lifecycle management: plan, launch, pause, resume, abort
  - Point of Interest (POI) management with CRUD operations
  - Terrain-following altitude adjustment
  - Camera trigger actions at configurable intervals
- **SAR API Endpoints**: FastAPI APIRouter at `/api/sar`
  - Coverage planning, mission control, drone progress, POI, and elevation endpoints
  - Thread-safe singleton managers for mission state and POI storage
- **QuickScout Dashboard Page**: Full Plan/Monitor UI
  - Mapbox GL polygon drawing for search area definition
  - Coverage path preview with per-drone color coding
  - Real-time drone progress monitoring with status cards
  - Interactive POI marker system
  - Survey configuration panel with advanced options
- **SAR Test Suite**: Schema validation, coverage planner algorithm, and API endpoint tests
- **New Dependencies**: `shapely>=2.0.0` and `pymap3d` (GCS server only), `@mapbox/mapbox-gl-draw` (frontend)
- **Documentation**: `docs/quickscout.md` with architecture, API reference, and configuration guide

---

## [4.5] - 2026-02-24

### Added
- **Automated mavlink-router Integration**: Dashboard binary auto-download, systemd service setup via `mavlink_setup.sh`

### Changed
- **Config/Swarm migrated from CSV to JSON** (`v4.5.0-config-json`):
  - `config.csv` → `config.json`, `swarm.csv` → `swarm.json` (same for SITL variants)
  - JSON envelope format: `{"version": 1, "drones": [...]}` / `{"version": 1, "assignments": [...]}`
  - Native types: `mavlink_port`/`baudrate` as int, `follow` as int
  - Pydantic schemas with `extra='allow'` for user-defined custom fields (e.g. `color`, `notes`)
  - Shell scripts use `jq` for config parsing (dependency checked at runtime)
  - Dashboard: JSON import/export (primary), CSV import as fallback
  - Resource templates updated (10 files)
  - One-time migration tool: `tools/migrate_csv_to_json.py`
  - Guide: `docs/guides/config-json-format.md`
- **Swarm offset fields renamed** for clarity and extensibility:
  - `offset_n/offset_e/offset_alt` → `offset_x/offset_y/offset_z`
  - `body_coord` (bool) → `frame` (enum: `"ned"` | `"body"`)
  - Meaning of x/y/z depends on frame (ned: North/East/Up; body: Forward/Right/Up)
  - `offset_z` is always positive-up regardless of frame

---

## [4.4] - 2026-01-30

### Changed
- Version bump for enterprise services and configuration improvements

---

## [4.3] - 2026-01-28

### Added
- **Enhanced Repository Management**: Interactive fork vs default repository selection
  - Clear read-only warning for default repo users
  - SSH access detection for collaborators
  - Fork configuration verification (matches RPi init behavior)
- **NetBird VPN Integration**: VPN networking guidance in installation summary
  - New guide: `docs/guides/netbird-setup.md`
  - Network architecture diagrams
  - Step-by-step setup instructions
- **CLI Improvements**: New `--fork` option for `install_gcs.sh`
  - Quick fork setup: `curl ... | sudo bash -s -- --fork username`
  - Better error messages and guidance

### Changed
- **Repository Selection Flow**: Separated "what repo" from "how to access"
  - Step 1: Choose official repo or your own fork
  - Step 2: Choose HTTPS or SSH access
  - SSH recommended for production (enables git sync)
- **Path Resolution**: Fixed PYTHONPATH for GCS server module imports
  - Works correctly from any execution directory
  - Explicitly sets PROJECT_ROOT in PYTHONPATH
- **Documentation**: Updated gcs-setup.md with repository options and VPN networking

### Fixed
- **Module Import Issues**: GCS server can now find functions module from any path
- **Version Consistency**: All files updated to 4.3.0

---

## [4.2] - 2026-01-28

### Added
- **Unified MDS Branding**: Consistent ASCII art banner across all initialization scripts
  - New shared banner file: `tools/mds_banner.sh`
  - `print_mds_banner()` function for consistent display
  - `get_git_info()` function for git branch/commit retrieval
- **Version/Git Info at Startup**: All scripts now display version, branch, and commit at startup
  - GCS bootstrap shows version and branch during installation
  - GCS init displays version, branch, commit, and timestamp
  - RPi init displays version, branch, commit, and timestamp
  - Dashboard startup shows version and git info

### Changed
- **Banner Unification**: All scripts now use the same MDS ASCII art
  - `tools/install_gcs.sh`: Replaced box-drawing banner with unified banner
  - `tools/mds_gcs_init.sh`: Uses shared banner with git info
  - `tools/mds_gcs_init_lib/gcs_common.sh`: Sources shared banner
  - `tools/mds_node_init.sh`: Uses shared banner with git info
  - `tools/mds_init_lib/common.sh`: Sources shared banner
  - `app/linux_dashboard_start.sh`: Replaced wide ASCII with unified banner
- **Version Synchronization**: All version numbers updated to 4.2.0
  - `GCS_VERSION` in gcs_common.sh
  - `MDS_VERSION` in common.sh
  - `MDS_BANNER_VERSION` in mds_banner.sh
  - Documentation updated (README.md, docs/README.md, gcs-setup.md)

---

## [4.1] - 2026-01-24

### Added
- **GCS Initialization System**: Enterprise-grade VPS/Ubuntu GCS setup
  - One-line installation: `curl ... | sudo bash`
  - Comprehensive `mds_gcs_init.sh` with 9 phases
  - Library modules for prereqs, Python, Node.js, firewall, etc.
- **Documentation Updates**: GCS setup guide and documentation links

---

## [4.0] - 2026-01-20

### Added
- **Enterprise Raspberry Pi Initialization**: Production-ready `mds_node_init.sh`
  - Modular library architecture in `mds_init_lib/`
  - 13 installation phases with state tracking
  - Resume capability for interrupted installations
  - SSH key management for git sync
- **Production Dashboard Startup**: Enhanced `linux_dashboard_start.sh`
  - FastAPI/Flask backend selection
  - Development and production modes
  - tmux session management

---

## [3.8] - 2025-11-07

### Added
- Automated version bump (minor)

### Changed
- See commit history for detailed changes

---


## [3.7] - 2025-11-07

### Added
- **Comprehensive Project Cleanup**: Removed 14 unnecessary files and directories from root
  - Removed backup files: `config.csv.backup`, `config_sitl.csv.backup`
  - Removed old code backups: `drone_show_bak.py`, `smart_swarm_old.py`
  - Removed test/experimental scripts: `offboard_multiple_from_csv.py`, `test_config_*.py`
  - Removed empty npm artifacts: `drone-dashboard@1.0.0`, `react-scripts`
  - Removed misplaced `package-lock.json` from root (React is in `app/dashboard/drone-dashboard/`)
- **.gitignore Enhancements**: Added patterns to prevent future clutter
  - Backup files: `*.backup`, `*.bak`, `*_bak.py`, `*_old.py`
  - Binary executables: `mavsdk_server*`
  - Empty npm artifacts: `react-scripts`, `drone-dashboard@*`
  - Test scripts in root: `/test_config*.py`, `/offboard_multiple*.py`
- **PolyForm Dual Licensing**: Professional open-source licensing framework
  - PolyForm Noncommercial 1.0.0 for education, research, non-profits
  - PolyForm Small Business 1.0.0 for small commercial operations (< 10 drones, < $1M revenue, < 100 employees)
  - Custom commercial licensing for large operations
  - Comprehensive legal protection: LICENSE, DISCLAIMER.md, NOTICE, ETHICAL-USE.md

### Fixed
- **Critical UX Issue - Modal Dialog Centering**: Confirmation dialogs now properly center in viewport
  - Implemented React Portal for modal rendering (CommandSender.js)
  - Modal now renders to `document.body` instead of inline in container
  - Users no longer need to scroll to find confirmation dialogs - major UX improvement
- **React Console Warnings Resolved**:
  - Removed 6 debug `console.log()` statements from `missionConfigUtilities.js`
  - Fixed "assign before export" warning in `version.js` by refactoring export pattern
  - Updated `tools/version_sync.py` to generate ESLint-compliant JavaScript exports
  - Kept appropriate `console.error()` statements for error handling

### Changed
- **JavaScript Export Pattern**: Modernized version.js and auto-generation script
  - Declare constants first, then export (ESLint best practice)
  - Updated `tools/version_sync.py` template to generate compliant code
- **Legal Documentation Structure**: Confirmed LICENSE files correctly placed in root per industry standards
  - LICENSE, NOTICE, DISCLAIMER.md remain in root (GitHub/Apache/Google best practice)
  - Dual licensing structure clearly documented for easy discovery

---

## [3.6] - 2025-11-06

### Added
- **Documentation Restructure**: Comprehensive reorganization of all project documentation
  - Created organized folder structure: `docs/quickstart/`, `docs/guides/`, `docs/features/`, `docs/hardware/`, `docs/api/`
  - Created `docs/archives/` for historical documentation and implementation summaries
  - New documentation index at `docs/README.md` for easy navigation
- **Versioning System**: Unified version management across entire project
  - Single source of truth: `VERSION` file in project root
  - Automated version synchronization script: `tools/version_sync.py`
  - Dynamic version display in dashboard with git commit hash
  - Versioning workflow guide at `docs/VERSIONING.md`
- **CHANGELOG.md**: Separate, structured changelog following Keep a Changelog format
- **GCS Configuration Enhancements**:
  - Dashboard .env file auto-update feature for GCS IP changes
  - Checkbox option to update `REACT_APP_SERVER_URL` when changing GCS IP
  - User warnings about rebuild requirements and server location
- **UI/UX Production Improvements**:
  - Origin coordinate display with responsive multi-line layout
  - GPS coordinates truncated to 6 decimal places (0.11m accuracy)
  - Modal dialogs now center on viewport instead of container
  - Comprehensive toast notifications for save operations with git status
  - Save button renamed to "Save & Commit to Git" for clarity

### Changed
- **README.md**: Cleaned and streamlined for professional presentation
  - Added table of contents
  - Removed embedded version history (moved to CHANGELOG.md)
  - Better separation of quick start vs comprehensive guides
  - Improved navigation and structure
- **Documentation Organization**:
  - Moved implementation summaries to `docs/archives/implementation-summaries/`
  - Moved legacy docs (v2.0, HTML, PDF) to `docs/archives/`
  - Renamed and relocated current docs to new folder structure
  - Dashboard README customized for MDS (was generic Create React App template)
- **Dark Mode Fixes**:
  - Fixed unreadable metric boxes in ManageDroneShow page
  - Replaced MUI inline styles with CSS variables for theme compatibility
  - Added 80+ lines of dark mode compatible CSS
- **Version Display**: Dashboard sidebar now shows `v3.6 (git-hash)` dynamically

### Fixed
- GCS configuration dialog showing empty "Current IP" field (nested data structure issue)
- GCS IP not differentiating between SITL mode (172.18.0.1) and Real mode (100.96.32.75)
- Confirmation dialogs requiring scroll to see (viewport centering issue)
- No visual feedback during configuration save/commit operations
- Origin GPS coordinates overflowing container
- Dark mode color accessibility in VisualizationSection components

---

## [3.5] - 2025-09

### Added
- **Professional React Dashboard** with expert portal-based UI/UX using React Portal architecture
- **3D Trajectory Planning** with interactive waypoint creation, terrain elevation, and speed optimization
- **Enhanced Mobile Responsiveness** with touch-friendly interface and responsive design
- **Smart Swarm Trajectory Processing** with cluster leader management and dynamic formation reshaping
- **Expert Tab Navigation** with professional mission operations interface
- **Advanced UI/UX Improvements** with modal overlays, responsive design, and touch-friendly controls

### Changed
- Complete dashboard redesign with modern React patterns

### Fixed
- Multiple bug fixes and performance improvements for production deployment

---

## [3.0] - 2025-06

### Added
- **Smart Swarm Leader–Follower System**: Fully operational with leader failover, auto re-election, and seamless follower sync
- **Global Mode Setpoints**: Unified approach for both offline and live missions
- **Enhanced Failsafe Checks**: Comprehensive preflight health checks and in-flight monitoring
- **Stable Startup Sequence**: Three-way handshake mechanism ("OK-to-Start" broadcast)
- **Unified All-in-One System**: Single platform for both drone shows and live swarm operations

### Fixed
- Race condition issues under high CPU load (GUIDED → AUTO transitions)
- Emergency-land command reliability during mode transitions
- Network buffer tuning for large-scale simulations (100+ drones)

---

## [2.0] - 2024-11

### Added
- Enhanced React GUI with improved user experience
- Robust Flask backend architecture
- Comprehensive drone-show scripts
- Docker SITL environment for testing
- [100-Drone SITL Test Video](https://www.youtube.com/watch?v=VsNs3kFKEvU)

### Changed
- Major GUI overhaul
- Backend infrastructure im
Download .txt
gitextract_nw1rprxl/

├── .github/
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── RELEASE_TEMPLATE.md
│   └── workflows/
│       ├── pr-validation.yml
│       └── release.yml
├── .gitignore
├── AGENTS.md
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── DISCLAIMER.md
├── ETHICAL-USE.md
├── GEMINI.md
├── LICENSE
├── LICENSE-COMMERCIAL.md
├── LICENSE-NONCOMMERCIAL.md
├── LICENSE-SMALL-BUSINESS.md
├── Makefile
├── NOTICE
├── README.md
├── VERSION
├── actions.py
├── app/
│   ├── dashboard/
│   │   └── drone-dashboard/
│   │       ├── .build_hash
│   │       ├── .gitignore
│   │       ├── FIELD_NAMING_STANDARD.md
│   │       ├── README.md
│   │       ├── download-raw-show
│   │       ├── package.json
│   │       ├── public/
│   │       │   ├── index.html
│   │       │   ├── manifest.json
│   │       │   └── robots.txt
│   │       └── src/
│   │           ├── App.css
│   │           ├── App.js
│   │           ├── App.test.js
│   │           ├── __mocks__/
│   │           │   └── styleMock.js
│   │           ├── assets/
│   │           │   └── compass-rose.psd
│   │           ├── components/
│   │           │   ├── BriefingExport.js
│   │           │   ├── ClusterScopeBar.js
│   │           │   ├── CommandPreflightSummary.js
│   │           │   ├── CommandSender.js
│   │           │   ├── CommandSender.test.js
│   │           │   ├── ControlButtons.js
│   │           │   ├── ControlButtons.test.js
│   │           │   ├── CurrentTime.js
│   │           │   ├── DeviationView.js
│   │           │   ├── DroneActions.js
│   │           │   ├── DroneActions.test.js
│   │           │   ├── DroneCard.js
│   │           │   ├── DroneConfigCard.js
│   │           │   ├── DroneConfigCard.test.js
│   │           │   ├── DroneCriticalCommands.js
│   │           │   ├── DroneCriticalCommands.test.js
│   │           │   ├── DroneDetail.js
│   │           │   ├── DroneGitStatus.js
│   │           │   ├── DroneGitStatus.test.js
│   │           │   ├── DroneGraph.js
│   │           │   ├── DronePositionMap.js
│   │           │   ├── DronePositionMap.test.js
│   │           │   ├── DroneReadinessReport.js
│   │           │   ├── DroneReadinessReport.test.js
│   │           │   ├── DroneWidget.js
│   │           │   ├── DroneWidget.test.js
│   │           │   ├── Environment.js
│   │           │   ├── ErrorBoundary.js
│   │           │   ├── ErrorBoundary.test.js
│   │           │   ├── ExpandedDronePortal.js
│   │           │   ├── ExportSection.js
│   │           │   ├── GitInfo.js
│   │           │   ├── Globe.js
│   │           │   ├── GlobeControlBox.js
│   │           │   ├── GlobeMapView.js
│   │           │   ├── Header.js
│   │           │   ├── IdentityDoctrineStrip.js
│   │           │   ├── ImportSection.js
│   │           │   ├── InfoHint.js
│   │           │   ├── InitialLaunchPlot.js
│   │           │   ├── MapSelector.js
│   │           │   ├── MissionCard.js
│   │           │   ├── MissionDetails.js
│   │           │   ├── MissionDetails.test.js
│   │           │   ├── MissionLayout.js
│   │           │   ├── MissionLayout.test.js
│   │           │   ├── MissionReadinessCard.js
│   │           │   ├── MissionReadinessCard.test.js
│   │           │   ├── MissionTrigger.js
│   │           │   ├── MissionTrigger.test.js
│   │           │   ├── OriginModal.js
│   │           │   ├── PositionTabs.js
│   │           │   ├── PrecisionMoveDialog.js
│   │           │   ├── PrecisionMoveDialog.test.js
│   │           │   ├── RouteDocsShortcut.js
│   │           │   ├── RuntimeModeBadge.js
│   │           │   ├── SaveReviewDialog.js
│   │           │   ├── SaveReviewDialog.test.js
│   │           │   ├── SidebarMenu.js
│   │           │   ├── SidebarMenu.test.js
│   │           │   ├── SwarmPlots.js
│   │           │   ├── SwarmRuntimeControls.js
│   │           │   ├── SwarmRuntimeControls.test.js
│   │           │   ├── SyncWarningBanner.js
│   │           │   ├── TacticalDroneCard.js
│   │           │   ├── TacticalDroneCard.test.js
│   │           │   ├── ThemeToggle.js
│   │           │   ├── TimePicker.js
│   │           │   ├── VisualizationSection.js
│   │           │   ├── logs/
│   │           │   │   ├── LogActiveFilters.js
│   │           │   │   ├── LogExportDialog.js
│   │           │   │   ├── LogHealthBar.js
│   │           │   │   ├── LogLiveIndicator.js
│   │           │   │   ├── LogRowDetail.js
│   │           │   │   ├── LogRowDetail.test.js
│   │           │   │   ├── LogSessionSelector.js
│   │           │   │   ├── LogSourceTree.js
│   │           │   │   ├── LogTable.js
│   │           │   │   ├── LogViewerToolbar.js
│   │           │   │   ├── LogViewerToolbar.test.js
│   │           │   │   ├── OnboardUlogDialog.js
│   │           │   │   └── OnboardUlogDialog.test.js
│   │           │   ├── map/
│   │           │   │   ├── LeafletCoveragePreview.js
│   │           │   │   ├── LeafletDrawControl.js
│   │           │   │   ├── LeafletFindingMarkers.js
│   │           │   │   ├── LeafletMapBase.js
│   │           │   │   ├── MapFallbackBanner.js
│   │           │   │   ├── MapProviderToggle.js
│   │           │   │   └── ViewModeToggle.js
│   │           │   ├── missionConfig/
│   │           │   │   ├── MissionConfigAlertStack.js
│   │           │   │   ├── MissionConfigToolbar.js
│   │           │   │   └── PendingEnrollmentPanel.js
│   │           │   ├── px4/
│   │           │   │   ├── Px4ParamInspector.js
│   │           │   │   ├── Px4ParamInspector.test.js
│   │           │   │   └── Px4ParamProfilePanel.js
│   │           │   ├── sar/
│   │           │   │   ├── CoveragePreview.js
│   │           │   │   ├── DroneStatusCard.js
│   │           │   │   ├── DroneStatusCard.test.js
│   │           │   │   ├── FindingMarkerSystem.js
│   │           │   │   ├── FindingReviewPanel.js
│   │           │   │   ├── FindingReviewPanel.test.js
│   │           │   │   ├── MissionActionBar.js
│   │           │   │   ├── MissionActionBar.test.js
│   │           │   │   ├── MissionHandoffPanel.js
│   │           │   │   ├── MissionHandoffPanel.test.js
│   │           │   │   ├── MissionMonitorSidebar.js
│   │           │   │   ├── MissionMonitorSidebar.test.js
│   │           │   │   ├── MissionPlanSidebar.js
│   │           │   │   ├── MissionRecoveryPanel.js
│   │           │   │   ├── MissionStatsBar.js
│   │           │   │   ├── MissionStatsBar.test.js
│   │           │   │   ├── PlanMonitorToggle.js
│   │           │   │   ├── QuickScoutLaunchReview.js
│   │           │   │   ├── QuickScoutLaunchReview.test.js
│   │           │   │   └── SearchAreaDrawer.js
│   │           │   ├── trajectory/
│   │           │   │   ├── SearchBar.js
│   │           │   │   ├── SwarmTrajectoryTransferDialog.js
│   │           │   │   ├── SwarmTrajectoryTransferDialog.test.js
│   │           │   │   ├── SwarmTrajectoryWorkspaceSummary.js
│   │           │   │   ├── SwarmTrajectoryWorkspaceSummary.test.js
│   │           │   │   ├── TrajectoryExportDialog.js
│   │           │   │   ├── TrajectoryExportDialog.test.js
│   │           │   │   ├── TrajectoryLibraryDialog.js
│   │           │   │   ├── TrajectoryLibraryDialog.test.js
│   │           │   │   ├── TrajectoryPolicyNotes.js
│   │           │   │   ├── TrajectorySegmentReview.js
│   │           │   │   ├── TrajectorySegmentReview.test.js
│   │           │   │   ├── TrajectoryStats.js
│   │           │   │   ├── TrajectoryStats.test.js
│   │           │   │   ├── TrajectoryToolbar.js
│   │           │   │   ├── TrajectoryToolbar.test.js
│   │           │   │   ├── WaypointModal.js
│   │           │   │   ├── WaypointModal.test.js
│   │           │   │   ├── WaypointPanel.js
│   │           │   │   └── WaypointPanel.test.js
│   │           │   └── ui/
│   │           │       ├── OperatorPrimitives.js
│   │           │       ├── OperatorPrimitives.test.js
│   │           │       └── index.js
│   │           ├── config/
│   │           │   ├── apiConfig.js
│   │           │   ├── mapConfig.js
│   │           │   ├── mapConfig.test.js
│   │           │   ├── routeDocs.js
│   │           │   └── routeDocs.test.js
│   │           ├── constants/
│   │           │   ├── droneConstants.js
│   │           │   ├── droneStates.js
│   │           │   ├── fieldMappings.js
│   │           │   ├── flightModes.js.deprecated
│   │           │   ├── logConstants.js
│   │           │   ├── mavModeEnum.js.deprecated
│   │           │   ├── px4FlightModes.js
│   │           │   ├── trajectoryMissionPolicy.js
│   │           │   └── trajectoryMissionPolicy.test.js
│   │           ├── contexts/
│   │           │   ├── AuthContext.js
│   │           │   ├── CommandActivityContext.js
│   │           │   ├── CommandActivityContext.test.js
│   │           │   ├── MapContext.js
│   │           │   ├── ThemeContext.js
│   │           │   └── ThemeContext.test.js
│   │           ├── hooks/
│   │           │   ├── useComputeOrigin.js
│   │           │   ├── useFetch.js
│   │           │   ├── useGcsGitInfo.js
│   │           │   ├── useGcsRuntimeStatus.js
│   │           │   ├── useLogStream.js
│   │           │   ├── useLogStream.test.js
│   │           │   ├── useNormalizedTelemetry.js
│   │           │   ├── useSwarmClusterStatus.js
│   │           │   ├── useSyncDrones.js
│   │           │   └── useTheme.js
│   │           ├── index.css
│   │           ├── index.js
│   │           ├── pages/
│   │           │   ├── CustomShowPage.js
│   │           │   ├── DroneShowDesign.js
│   │           │   ├── EnvironmentsPage.js
│   │           │   ├── EnvironmentsPage.test.js
│   │           │   ├── FleetEnrollmentPage.js
│   │           │   ├── FleetEnrollmentPage.test.js
│   │           │   ├── FleetOpsPage.js
│   │           │   ├── FleetOpsPage.test.js
│   │           │   ├── GlobeView.js
│   │           │   ├── GlobeView.test.js
│   │           │   ├── LogViewer.js
│   │           │   ├── LoginPage.js
│   │           │   ├── ManageDroneShow.js
│   │           │   ├── MissionConfig.js
│   │           │   ├── MissionConfig.test.js
│   │           │   ├── Overview.js
│   │           │   ├── Overview.test.js
│   │           │   ├── Px4ParametersPage.js
│   │           │   ├── Px4ParametersPage.test.js
│   │           │   ├── QuickScoutPage.js
│   │           │   ├── QuickScoutPage.test.js
│   │           │   ├── RuntimeAdminPage.js
│   │           │   ├── RuntimeAdminPage.test.js
│   │           │   ├── SitlControlPage.js
│   │           │   ├── SitlControlPage.test.js
│   │           │   ├── SwarmDesign.js
│   │           │   ├── SwarmDesign.test.js
│   │           │   ├── SwarmTrajectory.js
│   │           │   ├── SwarmTrajectory.test.js
│   │           │   ├── TrajectoryPlanning.js
│   │           │   └── TrajectoryPlanning.test.js
│   │           ├── services/
│   │           │   ├── ElevationService.js
│   │           │   ├── TerrainService.js
│   │           │   ├── apiError.js
│   │           │   ├── droneApiService.js
│   │           │   ├── droneApiService.test.js
│   │           │   ├── fleetEnrollmentApiService.js
│   │           │   ├── fleetEnrollmentApiService.test.js
│   │           │   ├── gcsApiService.js
│   │           │   ├── gcsApiService.test.js
│   │           │   ├── logService.js
│   │           │   ├── logService.test.js
│   │           │   ├── px4ParamsApiService.js
│   │           │   ├── px4ParamsApiService.test.js
│   │           │   ├── sarApiService.js
│   │           │   ├── sarApiService.test.js
│   │           │   ├── sitlControlService.js
│   │           │   └── sitlControlService.test.js
│   │           ├── setupTests.js
│   │           ├── styles/
│   │           │   ├── BriefingExport.css
│   │           │   ├── ClusterScopeBar.css
│   │           │   ├── CommandSender.css
│   │           │   ├── ControlButtons.css
│   │           │   ├── CurrentTime.css
│   │           │   ├── CustomShowPage.css
│   │           │   ├── DesignTokens.css
│   │           │   ├── DeviationView.css
│   │           │   ├── DroneActions.css
│   │           │   ├── DroneCard.css
│   │           │   ├── DroneConfigCard.css
│   │           │   ├── DroneCriticalCommands.css
│   │           │   ├── DroneDetail.css
│   │           │   ├── DroneGitStatus.css
│   │           │   ├── DroneGraph.css
│   │           │   ├── DronePositionMap.css
│   │           │   ├── DroneReadinessReport.css
│   │           │   ├── DroneShowDesign.css
│   │           │   ├── DroneWidget.css
│   │           │   ├── EnvironmentsPage.css
│   │           │   ├── ExpandedDronePortal.css
│   │           │   ├── FleetEnrollmentPage.css
│   │           │   ├── FleetOpsPage.css
│   │           │   ├── GitInfo.css
│   │           │   ├── Globe.css
│   │           │   ├── GlobeControlBox.css
│   │           │   ├── GlobeView.css
│   │           │   ├── Header.css
│   │           │   ├── IdentityDoctrineStrip.css
│   │           │   ├── ImportSection.css
│   │           │   ├── InfoHint.css
│   │           │   ├── LogViewer.css
│   │           │   ├── LoginPage.css
│   │           │   ├── ManageDroneShow.css
│   │           │   ├── MapCommon.css
│   │           │   ├── MapSelector.css
│   │           │   ├── MissionConfig.css
│   │           │   ├── MissionDetails.css
│   │           │   ├── MissionLayout.css
│   │           │   ├── MissionReadinessCard.css
│   │           │   ├── MissionTrigger.css
│   │           │   ├── OperatorPrimitives.css
│   │           │   ├── OriginModal.css
│   │           │   ├── Overview.css
│   │           │   ├── PositionTabs.css
│   │           │   ├── PrecisionMoveDialog.css
│   │           │   ├── Px4ParametersPage.css
│   │           │   ├── QuickScout.css
│   │           │   ├── RuntimeAdminPage.css
│   │           │   ├── RuntimeModeBadge.css
│   │           │   ├── SaveReviewDialog.css
│   │           │   ├── SearchBar.css
│   │           │   ├── SidebarMenu.css
│   │           │   ├── SitlControlPage.css
│   │           │   ├── SwarmDesign.css
│   │           │   ├── SwarmPlots.css
│   │           │   ├── SwarmTrajectory.css
│   │           │   ├── SwarmTrajectoryTransferDialog.css
│   │           │   ├── SyncWarningBanner.css
│   │           │   ├── TacticalDroneCard.css
│   │           │   ├── ThemeToggle.css
│   │           │   ├── TrajectoryLibraryDialog.css
│   │           │   ├── TrajectoryPlanning.css
│   │           │   ├── TrajectoryPolicyNotes.css
│   │           │   ├── TrajectorySegmentReview.css
│   │           │   ├── TrajectoryStats.css
│   │           │   ├── TrajectoryToolbar.css
│   │           │   ├── WaypointModal.css
│   │           │   └── WaypointPanel.css
│   │           ├── useElevation.js
│   │           ├── utilities/
│   │           │   ├── SpeedCalculator.js
│   │           │   ├── SpeedCalculator.test.js
│   │           │   ├── TrajectoryStateManager.js
│   │           │   ├── TrajectoryStateManager.test.js
│   │           │   ├── TrajectoryStorage.js
│   │           │   ├── TrajectoryStorage.test.js
│   │           │   ├── commandExecutionPolicy.js
│   │           │   ├── commandExecutionPolicy.test.js
│   │           │   ├── commandLifecycleFeedback.js
│   │           │   ├── commandLifecycleFeedback.test.js
│   │           │   ├── commandScheduling.js
│   │           │   ├── commandScheduling.test.js
│   │           │   ├── dronePresentation.js
│   │           │   ├── dronePresentation.test.js
│   │           │   ├── droneReadiness.js
│   │           │   ├── droneReadiness.test.js
│   │           │   ├── droneRuntimeStatus.js
│   │           │   ├── droneRuntimeStatus.test.js
│   │           │   ├── fleetOpsViewModel.js
│   │           │   ├── fleetOpsViewModel.test.js
│   │           │   ├── flightModeUtils.js
│   │           │   ├── geoutilities.js
│   │           │   ├── globeScreenInteractions.js
│   │           │   ├── globeScreenInteractions.test.js
│   │           │   ├── globeTelemetryViewModel.js
│   │           │   ├── globeTelemetryViewModel.test.js
│   │           │   ├── logViewerUtils.js
│   │           │   ├── logViewerUtils.test.js
│   │           │   ├── missionConfigFields.js
│   │           │   ├── missionConfigFields.test.js
│   │           │   ├── missionConfigUtilities.js
│   │           │   ├── missionIdentityUtils.js
│   │           │   ├── missionIdentityUtils.test.js
│   │           │   ├── missionSlotStatus.js
│   │           │   ├── missionSlotStatus.test.js
│   │           │   ├── missionUtils.js
│   │           │   ├── missionUtils.test.js
│   │           │   ├── plotThemeColors.js
│   │           │   ├── px4ParameterFiles.js
│   │           │   ├── px4ParameterFiles.test.js
│   │           │   ├── px4ParameterProfiles.js
│   │           │   ├── px4ParameterProfiles.test.js
│   │           │   ├── quickScoutLaunchReadiness.js
│   │           │   ├── quickScoutLaunchReadiness.test.js
│   │           │   ├── quickScoutMissionPresentation.js
│   │           │   ├── quickScoutPlanningSignature.js
│   │           │   ├── quickScoutPlanningSignature.test.js
│   │           │   ├── quickScoutProfiles.js
│   │           │   ├── quickScoutProfiles.test.js
│   │           │   ├── quickScoutSearchGeometry.js
│   │           │   ├── quickScoutSearchGeometry.test.js
│   │           │   ├── smartSwarmLaunchReadiness.js
│   │           │   ├── smartSwarmLaunchReadiness.test.js
│   │           │   ├── swarmDesignUtils.js
│   │           │   ├── swarmDesignUtils.test.js
│   │           │   ├── swarmRuntimeUtils.js
│   │           │   ├── swarmRuntimeUtils.test.js
│   │           │   ├── swarmScopeUtils.js
│   │           │   ├── swarmScopeUtils.test.js
│   │           │   ├── swarmTrajectoryLaunchReadiness.js
│   │           │   ├── swarmTrajectoryLaunchReadiness.test.js
│   │           │   ├── swarmTrajectoryPackageStats.js
│   │           │   ├── swarmTrajectoryPackageStats.test.js
│   │           │   ├── swarmTrajectoryViewModel.js
│   │           │   ├── swarmTrajectoryViewModel.test.js
│   │           │   ├── swarmTrajectoryWorkspaceModel.js
│   │           │   ├── swarmTrajectoryWorkspaceModel.test.js
│   │           │   ├── toastFeedback.js
│   │           │   ├── trajectoryAuthoringGuidance.js
│   │           │   ├── trajectoryAuthoringGuidance.test.js
│   │           │   ├── trajectoryMissionReadiness.js
│   │           │   ├── trajectoryMissionReadiness.test.js
│   │           │   ├── trajectoryTerrainContext.js
│   │           │   ├── trajectoryTerrainContext.test.js
│   │           │   ├── trajectoryTimingPresentation.js
│   │           │   ├── trajectoryTimingPresentation.test.js
│   │           │   └── utilities.js
│   │           └── version.js
│   └── linux_dashboard_start.sh
├── config.json
├── config_sitl.json
├── coordinator.py
├── data/
│   └── origin.sitl.default.json
├── deployment/
│   ├── connectivity/
│   │   └── smart-wifi-manager/
│   │       └── profile.example.json
│   └── defaults.env
├── docs/
│   ├── QUICK_REFERENCE.md
│   ├── README.md
│   ├── TODO_deferred.md
│   ├── VERSIONING.md
│   ├── apis/
│   │   ├── api-modernization-blueprint.md
│   │   ├── drone-api-server.md
│   │   └── gcs-api-server.md
│   ├── archives/
│   │   ├── deprecated/
│   │   │   └── DEPRECATED_v2.0_doc_sitl_demo.md
│   │   ├── hw_id_pos_id_research_2026-03-05.md
│   │   ├── implementation-summaries/
│   │   │   ├── 2025-09-04_flight-mode-fix.md
│   │   │   ├── 2025-09-06_mission-state-rename.md
│   │   │   ├── 2025-09-20_container-fixes.md
│   │   │   ├── 2025-09-20_robustness-summary.md
│   │   │   ├── 2025-11-04_processing-validation.md
│   │   │   ├── 2025-11-05_bug-fix-report.md
│   │   │   ├── 2025-11-05_implementation-summary.md
│   │   │   ├── 2025-11-06_cleanup-summary.md
│   │   │   ├── BACKEND_ANALYSIS_REPORT.md
│   │   │   ├── BACKEND_FASTAPI_MIGRATION_REPORT.md
│   │   │   ├── GCS_SERVER_MIGRATION_PLAN.md
│   │   │   ├── HANDOVER_TO_LOCAL_AGENT.md
│   │   │   ├── PR_MERGE_INSTRUCTIONS.md
│   │   │   └── QUICKSCOUT_REVIEW_REPORT.md
│   │   └── legacy-versions/
│   │       ├── v07_doc.html
│   │       └── v08_doc_server.html
│   ├── configuration_architecture.md
│   ├── control-modes-and-coordinates.md
│   ├── debug/
│   │   └── px4-sitl-preflight-gcs-issue.md
│   ├── features/
│   │   ├── drone-show.md
│   │   ├── git-sync.md
│   │   ├── origin-system.md
│   │   ├── smart-swarm.md
│   │   └── swarm-trajectory.md
│   ├── guides/
│   │   ├── advanced-sitl.md
│   │   ├── config-json-format.md
│   │   ├── connectivity-runtime.md
│   │   ├── csv-migration.md
│   │   ├── custom-repo-workflow.md
│   │   ├── custom-sitl-auth.md
│   │   ├── dashboard-operator.md
│   │   ├── deployment-quick-reference.md
│   │   ├── fleet-ops.md
│   │   ├── fleet-sync-and-secrets.md
│   │   ├── frontend-design-system.md
│   │   ├── frontend-ui-audit.md
│   │   ├── gcs-auth.md
│   │   ├── gcs-setup.md
│   │   ├── headless-automation.md
│   │   ├── led-status-guide.md
│   │   ├── logging-system.md
│   │   ├── mapbox-setup.md
│   │   ├── mavlink-routing-setup.md
│   │   ├── mds-init-cli-reference.md
│   │   ├── mds-init-setup.md
│   │   ├── mds-init-troubleshooting.md
│   │   ├── netbird-setup.md
│   │   ├── operator-makefile.md
│   │   ├── python-compatibility.md
│   │   ├── raspberry-pi-services.md
│   │   ├── repo-asset-layout.md
│   │   ├── runtime-config-sources.md
│   │   ├── runtime-evidence-reporting.md
│   │   ├── sitl-comprehensive.md
│   │   ├── sitl-control.md
│   │   ├── sitl-custom-release-workflow.md
│   │   ├── sitl-validation-platform.md
│   │   ├── smart-swarm-tracking-analysis.md
│   │   └── smart-wifi-manager-dashboard.md
│   ├── plans/
│   │   ├── 2026-03-06-config-json-migration-design.md
│   │   ├── 2026-03-06-config-json-migration.md
│   │   ├── 2026-03-07-swarm-offset-rename.md
│   │   ├── 2026-04-01-dashboard-operator-ux-checkpoint.md
│   │   ├── 2026-04-01-dashboard-ui-hardening-checkpoint.md
│   │   ├── 2026-04-01-frontend-audit-checkpoint.md
│   │   ├── 2026-04-01-hetzner-sitl-checkpoint.md
│   │   ├── 2026-04-01-operator-ui-checkpoint.md
│   │   ├── 2026-04-02-sitl-release-refresh.md
│   │   ├── 2026-04-02-ui-compact-checkpoint.md
│   │   ├── 2026-04-03-api-contract-audit-phase-1.md
│   │   ├── 2026-04-03-api-modernization-phase1.md
│   │   ├── 2026-04-03-api-modernization-phase2-completion.md
│   │   ├── 2026-04-03-api-modernization-phase2.md
│   │   ├── 2026-04-03-api-modernization-review-audit.md
│   │   ├── 2026-04-03-command-legacy-route-retirement.md
│   │   ├── 2026-04-03-command-router-extraction.md
│   │   ├── 2026-04-03-command-v1-canonical-aliases.md
│   │   ├── 2026-04-03-config-swarm-legacy-route-retirement.md
│   │   ├── 2026-04-03-configuration-swarm-router-extraction.md
│   │   ├── 2026-04-03-fleet-config-v1-canonical-aliases.md
│   │   ├── 2026-04-03-gcs-core-router-extraction.md
│   │   ├── 2026-04-03-gcs-telemetry-contract-cleanup.md
│   │   ├── 2026-04-03-git-legacy-route-retirement.md
│   │   ├── 2026-04-03-git-router-extraction.md
│   │   ├── 2026-04-03-git-v1-canonical-aliases.md
│   │   ├── 2026-04-03-internal-canonical-caller-cleanup.md
│   │   ├── 2026-04-03-legacy-route-retirement-audit.md
│   │   ├── 2026-04-03-log-domain-hardening.md
│   │   ├── 2026-04-03-management-static-legacy-route-retirement.md
│   │   ├── 2026-04-03-management-static-router-extraction.md
│   │   ├── 2026-04-03-management-static-v1-canonical-aliases.md
│   │   ├── 2026-04-03-operational-http-alias-retirement.md
│   │   ├── 2026-04-03-origin-legacy-route-retirement.md
│   │   ├── 2026-04-03-origin-router-extraction.md
│   │   ├── 2026-04-03-origin-v1-canonical-aliases.md
│   │   ├── 2026-04-03-sar-router-normalization.md
│   │   ├── 2026-04-03-show-legacy-route-retirement.md
│   │   ├── 2026-04-03-show-management-router-extraction.md
│   │   ├── 2026-04-03-show-v1-canonical-aliases.md
│   │   ├── 2026-04-03-sitl-suite-runtime-root-fix.md
│   │   ├── 2026-04-03-stream-surface-codification.md
│   │   ├── 2026-04-03-swarm-config-v1-canonical-aliases.md
│   │   ├── 2026-04-03-swarm-trajectory-router-extraction.md
│   │   ├── 2026-04-03-swarm-trajectory-v1-retirement.md
│   │   ├── 2026-04-04-api-closeout-websocket-debt-tracking.md
│   │   ├── 2026-04-04-command-contract-canonicalization.md
│   │   ├── 2026-04-04-command-submit-idempotency.md
│   │   ├── 2026-04-04-drone-v1-canonicalization.md
│   │   ├── 2026-04-04-gcs-error-envelope-and-typed-mutations.md
│   │   ├── 2026-04-04-sitl-clean-image-regression-and-hetzner-cleanup.md
│   │   ├── 2026-04-04-sitl-plan-library.md
│   │   ├── 2026-04-04-sitl-release-refresh.md
│   │   ├── 2026-04-04-sitl-validation-platform-phase1.md
│   │   ├── 2026-04-04-sitl-validation-platform-phase2.md
│   │   ├── 2026-04-04-subsystem-error-envelope-normalization.md
│   │   ├── 2026-04-04-swarm-trajectory-typed-contracts.md
│   │   ├── 2026-04-05-precision-move-design-brief.md
│   │   ├── 2026-04-05-precision-move-final-recap.md
│   │   ├── 2026-04-06-mission-config-and-command-copy-cleanup.md
│   │   ├── 2026-04-06-mission-config-architecture-reset-phase1.md
│   │   ├── 2026-04-06-precision-move-phase1-implementation.md
│   │   ├── 2026-04-06-precision-move-phase2-operator-control-surface.md
│   │   ├── 2026-04-06-precision-move-sitl-validation.md
│   │   ├── 2026-04-06-review-intake-and-ui-phase-plan.md
│   │   ├── 2026-04-06-shared-operator-scope-phase2.md
│   │   ├── 2026-04-06-trajectory-authoring-phase3.md
│   │   ├── 2026-04-07-advanced-sitl-regression-and-override-state-fix.md
│   │   ├── 2026-04-07-mission-config-actionable-alerts.md
│   │   ├── 2026-04-07-mission-config-card-compact-indicators.md
│   │   ├── 2026-04-07-mission-config-launch-map-and-sync-finalization.md
│   │   ├── 2026-04-07-mission-config-launch-map-polish.md
│   │   ├── 2026-04-07-quickscout-audit-and-redesign-brief.md
│   │   ├── 2026-04-07-quickscout-foundation-phase1.md
│   │   ├── 2026-04-07-smart-swarm-airborne-gate-and-quick-takeoff.md
│   │   ├── 2026-04-08-quickscout-command-lifecycle-phase2.md
│   │   ├── 2026-04-08-quickscout-corridor-template-foundation-phase10.md
│   │   ├── 2026-04-08-quickscout-execution-semantics-phase13.md
│   │   ├── 2026-04-08-quickscout-findings-cleanup-followup-phase15.md
│   │   ├── 2026-04-08-quickscout-findings-foundation-phase14.md
│   │   ├── 2026-04-08-quickscout-findings-handoff-runtime-validation-phase17.md
│   │   ├── 2026-04-08-quickscout-handoff-evidence-phase16.md
│   │   ├── 2026-04-08-quickscout-launch-review-phase7.md
│   │   ├── 2026-04-08-quickscout-mission-briefing-phase6.md
│   │   ├── 2026-04-08-quickscout-monitor-package-context-phase12.md
│   │   ├── 2026-04-08-quickscout-operator-setup-phase5.md
│   │   ├── 2026-04-08-quickscout-point-geometry-phase9.md
│   │   ├── 2026-04-08-quickscout-recovery-phase3.md
│   │   ├── 2026-04-08-quickscout-runtime-multi-validation-followup.md
│   │   ├── 2026-04-08-quickscout-runtime-validation.md
│   │   ├── 2026-04-08-quickscout-template-aware-launch-review-phase11.md
│   │   ├── 2026-04-08-quickscout-template-complete-runtime-validation-phase18.md
│   │   ├── 2026-04-08-quickscout-template-foundation-phase8.md
│   │   ├── 2026-04-08-quickscout-tester-handoff.md
│   │   ├── 2026-04-08-quickscout-workspace-recovery-ui-phase4.md
│   │   ├── 2026-04-09-px4-parameter-management-design-brief.md
│   │   ├── 2026-04-09-px4-parameter-runtime-validation-phase3.md
│   │   ├── 2026-04-09-px4-parameter-workspace-phase2.md
│   │   ├── 2026-04-09-px4-parameters-profiles-tester-handoff.md
│   │   ├── 2026-04-09-px4-parameters-responsive-handoff-refinement.md
│   │   ├── 2026-04-09-px4-parameters-scan-first-ui-refinement.md
│   │   ├── 2026-04-09-px4-params-foundation-phase1.md
│   │   ├── 2026-04-10-enrollment-identity-phase-closeout.md
│   │   ├── 2026-04-10-fleet-candidate-registry-foundation.md
│   │   ├── 2026-04-10-fleet-enrollment-operator-workflow.md
│   │   ├── 2026-04-10-mission-config-pending-enrollment-cutover.md
│   │   ├── 2026-04-10-node-bootstrap-and-fleet-enrollment-design-brief.md
│   │   ├── 2026-04-10-node-bootstrap-candidate-announce-integration.md
│   │   ├── 2026-04-10-node-bootstrap-fleet-enrollment-v1-recap.md
│   │   ├── 2026-04-10-node-bootstrap-phase1-foundation.md
│   │   ├── 2026-04-10-node-enrollment-and-mavlink-anywhere-review.md
│   │   ├── 2026-04-10-node-enrollment-identity-alignment-brief.md
│   │   ├── 2026-04-10-px4-parameters-alignment-followup.md
│   │   ├── 2026-04-10-px4-parameters-grouped-compact-refinement.md
│   │   ├── 2026-04-11-hardware-demo-confirmation-brief.md
│   │   ├── 2026-04-11-hardware-demo-final-review.md
│   │   ├── 2026-04-11-hardware-demo-preflight-audit.md
│   │   ├── 2026-04-11-hardware-demo-workflow-clarifications.md
│   │   ├── 2026-04-11-official-bootstrap-hardware-closeout.md
│   │   ├── 2026-04-11-onboard-ulog-management-design-brief.md
│   │   ├── 2026-04-11-onboard-ulog-runtime-closeout.md
│   │   ├── 2026-04-11-quickscout-runtime-acceptance-closeout.md
│   │   ├── 2026-04-12-private-customer-bootstrap-runtime-validation.md
│   │   ├── 2026-04-13-sitl-control-automation-adoption.md
│   │   ├── 2026-04-13-sitl-control-interaction-hardening.md
│   │   ├── 2026-04-13-sitl-control-operator-refinement.md
│   │   ├── 2026-04-13-sitl-control-phase1-implementation.md
│   │   ├── 2026-04-13-sitl-control-ux-hardening.md
│   │   ├── 2026-04-14-sitl-control-final-operator-refinement.md
│   │   ├── 2026-04-15-smart-swarm-runtime-phase1-implementation.md
│   │   ├── 2026-04-16-smart-swarm-runtime-closeout.md
│   │   ├── 2026-04-17-frontend-delivery-and-smart-swarm-tracking-checkpoint.md
│   │   ├── 2026-04-18-phase1-tester-feedback-response.md
│   │   ├── 2026-04-21-runtime-architecture-migration-log.md
│   │   ├── 2026-04-25-predeploy-ui-audit-baseline.json
│   │   ├── 2026-04-25-predeploy-ui-ux-refactor-audit-plan.md
│   │   ├── 2026-04-25-tactical-map-globe.md
│   │   ├── 2026-04-29-auth-implementation-journey.md
│   │   ├── 2026-04-29-mds-environment-registry-and-control-plane.md
│   │   └── 2026-04-30-env-registry-implementation-journey.md
│   ├── px4-parameters.md
│   ├── quickscout.md
│   ├── reference/
│   │   ├── mds-environment-registry.generated.md
│   │   └── mds-environment-registry.md
│   ├── research/
│   │   └── git-sync-hardening-research.md
│   └── superpowers/
│       ├── README.md
│       ├── plans/
│       │   └── 2026-03-19-unified-logging-phase1-foundation.md
│       └── specs/
│           ├── 2026-03-19-unified-logging-system-design.md
│           └── 2026-03-26-ai-agent-sitl-audit-loop.md
├── drone_show.py
├── drone_show_src/
│   └── utils.py
├── functions/
│   ├── __init__.py
│   ├── circle.py
│   ├── create_active_csv.py
│   ├── data_utils.py
│   ├── drone_show_metrics.py
│   ├── export_and_plot_shape.py
│   ├── file_management.py
│   ├── file_utils.py
│   ├── git_manager.py
│   ├── global_to_local.py
│   ├── plot_drone_paths.py
│   ├── process_drone_files.py
│   ├── seven_segment.py
│   ├── shapeParameters.py
│   ├── shape_functions.py
│   ├── shape_plots.py
│   ├── show_static_shape_results.py
│   ├── swarm_analyzer.py
│   ├── swarm_global_calculator.py
│   ├── swarm_kml_generator.py
│   ├── swarm_plotter.py
│   ├── swarm_session_manager.py
│   ├── swarm_trajectory_processor.py
│   ├── swarm_trajectory_service.py
│   ├── swarm_trajectory_smoother.py
│   ├── swarm_trajectory_utils.py
│   └── trajectories.py
├── gcs-server/
│   ├── __init__.py
│   ├── api_errors.py
│   ├── api_routes/
│   │   ├── __init__.py
│   │   ├── auth.py
│   │   ├── commands.py
│   │   ├── configuration.py
│   │   ├── core.py
│   │   ├── fleet_candidates.py
│   │   ├── git_status.py
│   │   ├── management.py
│   │   ├── origin.py
│   │   ├── px4_params.py
│   │   ├── show_management.py
│   │   ├── sitl_control.py
│   │   ├── static_assets.py
│   │   ├── swarm.py
│   │   └── swarm_trajectory.py
│   ├── app_fastapi.py
│   ├── auth_runtime.py
│   ├── command.py
│   ├── command_submission.py
│   ├── command_timeout_policy.py
│   ├── command_tracker.py
│   ├── config.py
│   ├── fleet_candidates.py
│   ├── gcs_config_updater.py
│   ├── get_elevation.py
│   ├── git_status.py
│   ├── heartbeat.py
│   ├── link_presence.py
│   ├── log_background.py
│   ├── log_proxy.py
│   ├── log_routes.py
│   ├── origin.py
│   ├── presence.py
│   ├── px4_param_store.py
│   ├── request_logging.py
│   ├── sar/
│   │   ├── __init__.py
│   │   ├── coverage_planner.py
│   │   ├── mission_manager.py
│   │   ├── routes.py
│   │   ├── schemas.py
│   │   ├── service.py
│   │   ├── store.py
│   │   └── terrain.py
│   ├── schemas.py
│   ├── show_management.py
│   ├── start_gcs_server.sh
│   ├── telemetry.py
│   └── utils.py
├── led_indicator.py
├── mavsdk/
│   ├── Makefile
│   ├── __init__.py
│   ├── _base.py
│   ├── action.py
│   ├── action_pb2.py
│   ├── action_pb2_grpc.py
│   ├── action_server.py
│   ├── action_server_pb2.py
│   ├── action_server_pb2_grpc.py
│   ├── async_plugin_manager.py
│   ├── calibration.py
│   ├── calibration_pb2.py
│   ├── calibration_pb2_grpc.py
│   ├── camera.py
│   ├── camera_pb2.py
│   ├── camera_pb2_grpc.py
│   ├── camera_server.py
│   ├── camera_server_pb2.py
│   ├── camera_server_pb2_grpc.py
│   ├── component_information.py
│   ├── component_information_pb2.py
│   ├── component_information_pb2_grpc.py
│   ├── component_information_server.py
│   ├── component_information_server_pb2.py
│   ├── component_information_server_pb2_grpc.py
│   ├── core.py
│   ├── core_pb2.py
│   ├── core_pb2_grpc.py
│   ├── failure.py
│   ├── failure_pb2.py
│   ├── failure_pb2_grpc.py
│   ├── follow_me.py
│   ├── follow_me_pb2.py
│   ├── follow_me_pb2_grpc.py
│   ├── ftp.py
│   ├── ftp_pb2.py
│   ├── ftp_pb2_grpc.py
│   ├── geofence.py
│   ├── geofence_pb2.py
│   ├── geofence_pb2_grpc.py
│   ├── gimbal.py
│   ├── gimbal_pb2.py
│   ├── gimbal_pb2_grpc.py
│   ├── gripper.py
│   ├── gripper_pb2.py
│   ├── gripper_pb2_grpc.py
│   ├── info.py
│   ├── info_pb2.py
│   ├── info_pb2_grpc.py
│   ├── log_files.py
│   ├── log_files_pb2.py
│   ├── log_files_pb2_grpc.py
│   ├── make.bat
│   ├── manual_control.py
│   ├── manual_control_pb2.py
│   ├── manual_control_pb2_grpc.py
│   ├── mavsdk_options_pb2.py
│   ├── mavsdk_options_pb2_grpc.py
│   ├── mission.py
│   ├── mission_pb2.py
│   ├── mission_pb2_grpc.py
│   ├── mission_raw.py
│   ├── mission_raw_pb2.py
│   ├── mission_raw_pb2_grpc.py
│   ├── mission_raw_server.py
│   ├── mission_raw_server_pb2.py
│   ├── mission_raw_server_pb2_grpc.py
│   ├── mocap.py
│   ├── mocap_pb2.py
│   ├── mocap_pb2_grpc.py
│   ├── offboard.py
│   ├── offboard_pb2.py
│   ├── offboard_pb2_grpc.py
│   ├── param.py
│   ├── param_pb2.py
│   ├── param_pb2_grpc.py
│   ├── param_server.py
│   ├── param_server_pb2.py
│   ├── param_server_pb2_grpc.py
│   ├── rtk.py
│   ├── rtk_pb2.py
│   ├── rtk_pb2_grpc.py
│   ├── server_utility.py
│   ├── server_utility_pb2.py
│   ├── server_utility_pb2_grpc.py
│   ├── shell.py
│   ├── shell_pb2.py
│   ├── shell_pb2_grpc.py
│   ├── source/
│   │   ├── conf.py
│   │   ├── index.rst
│   │   ├── nature_adapted/
│   │   │   ├── static/
│   │   │   │   └── style.css
│   │   │   └── theme.conf
│   │   ├── plugins/
│   │   │   ├── action.rst
│   │   │   ├── action_server.rst
│   │   │   ├── calibration.rst
│   │   │   ├── camera.rst
│   │   │   ├── camera_server.rst
│   │   │   ├── component_information.rst
│   │   │   ├── component_information_server.rst
│   │   │   ├── core.rst
│   │   │   ├── failure.rst
│   │   │   ├── follow_me.rst
│   │   │   ├── ftp.rst
│   │   │   ├── geofence.rst
│   │   │   ├── gimbal.rst
│   │   │   ├── gripper.rst
│   │   │   ├── index.rst
│   │   │   ├── info.rst
│   │   │   ├── log_files.rst
│   │   │   ├── manual_control.rst
│   │   │   ├── mission.rst
│   │   │   ├── mission_raw.rst
│   │   │   ├── mission_raw_server.rst
│   │   │   ├── mocap.rst
│   │   │   ├── offboard.rst
│   │   │   ├── param.rst
│   │   │   ├── param_server.rst
│   │   │   ├── rtk.rst
│   │   │   ├── server_utility.rst
│   │   │   ├── shell.rst
│   │   │   ├── telemetry.rst
│   │   │   ├── telemetry_server.rst
│   │   │   ├── tracking_server.rst
│   │   │   ├── transponder.rst
│   │   │   ├── tune.rst
│   │   │   └── winch.rst
│   │   └── system.rst
│   ├── system.py
│   ├── telemetry.py
│   ├── telemetry_pb2.py
│   ├── telemetry_pb2_grpc.py
│   ├── telemetry_server.py
│   ├── telemetry_server_pb2.py
│   ├── telemetry_server_pb2_grpc.py
│   ├── tracking_server.py
│   ├── tracking_server_pb2.py
│   ├── tracking_server_pb2_grpc.py
│   ├── transponder.py
│   ├── transponder_pb2.py
│   ├── transponder_pb2_grpc.py
│   ├── tune.py
│   ├── tune_pb2.py
│   ├── tune_pb2_grpc.py
│   ├── winch.py
│   ├── winch_pb2.py
│   └── winch_pb2_grpc.py
├── mds_logging/
│   ├── __init__.py
│   ├── api_schemas.py
│   ├── cli.py
│   ├── constants.py
│   ├── drone.py
│   ├── formatter.py
│   ├── handlers.py
│   ├── registry.py
│   ├── schema.py
│   ├── server.py
│   ├── session.py
│   └── watcher.py
├── multiple_sitl/
│   ├── calculate_spawn_coordinates.py
│   ├── create_dockers.sh
│   ├── detect_px4_mavlink_port.py
│   ├── multiple_sitl.sh
│   └── startup_sitl.sh
├── process_formation.py
├── pyproject.toml
├── pytest.ini
├── quickscout_mission.py
├── requirements-node.txt
├── requirements.txt
├── resources/
│   ├── README.md
│   ├── common_params.csv
│   ├── config/
│   │   ├── mds_env_internal_allowlist.json
│   │   ├── mds_env_registry.json
│   │   └── mds_env_registry.schema.json
│   ├── config_100_single_vps_docker.json
│   ├── config_100_two_vps_docker.json
│   ├── config_12docker.json
│   ├── config_16docker.json
│   ├── config_40docker.json
│   ├── config_vmware_4.json
│   ├── px4_param_profiles/
│   │   ├── README.md
│   │   ├── fleet_geofence_guardrail.json
│   │   └── sitl_link_loss_relaxed.json
│   ├── swarm_12docker.json
│   ├── swarm_16docker.json
│   ├── swarm_40docker.json
│   └── swarm_sitl_100.json
├── shapes/
│   ├── active.csv
│   ├── hover_test.csv
│   ├── static_shapes/
│   │   └── active/
│   │       └── drone_positions.csv
│   ├── swarm/
│   │   ├── comprehensive_metrics.json
│   │   ├── processed/
│   │   │   ├── Drone 1.csv
│   │   │   ├── Drone 10.csv
│   │   │   ├── Drone 2.csv
│   │   │   ├── Drone 3.csv
│   │   │   ├── Drone 4.csv
│   │   │   ├── Drone 5.csv
│   │   │   ├── Drone 6.csv
│   │   │   ├── Drone 7.csv
│   │   │   ├── Drone 8.csv
│   │   │   └── Drone 9.csv
│   │   └── skybrush/
│   │       ├── Drone 1.csv
│   │       ├── Drone 10.csv
│   │       ├── Drone 2.csv
│   │       ├── Drone 3.csv
│   │       ├── Drone 4.csv
│   │       ├── Drone 5.csv
│   │       ├── Drone 6.csv
│   │       ├── Drone 7.csv
│   │       ├── Drone 8.csv
│   │       └── Drone 9.csv
│   └── swarm_trajectory/
│       ├── processed/
│       │   ├── Drone 1.csv
│       │   ├── Drone 10.csv
│       │   ├── Drone 2.csv
│       │   ├── Drone 3.csv
│       │   ├── Drone 4.csv
│       │   ├── Drone 5.csv
│       │   ├── Drone 6.csv
│       │   ├── Drone 7.csv
│       │   ├── Drone 8.csv
│       │   └── Drone 9.csv
│       └── raw/
│           ├── Drone 1.csv
│           └── Drone 2.csv
├── shapes_sitl/
│   ├── active.csv
│   ├── hover_test.csv
│   ├── static_shapes/
│   │   └── active/
│   │       └── drone_positions.csv
│   ├── swarm/
│   │   ├── comprehensive_metrics.json
│   │   ├── processed/
│   │   │   ├── Drone 1.csv
│   │   │   ├── Drone 2.csv
│   │   │   ├── Drone 3.csv
│   │   │   ├── Drone 4.csv
│   │   │   └── Drone 5.csv
│   │   └── skybrush/
│   │       ├── Drone 1.csv
│   │       ├── Drone 2.csv
│   │       ├── Drone 3.csv
│   │       ├── Drone 4.csv
│   │       └── Drone 5.csv
│   └── swarm_trajectory/
│       ├── processed/
│       │   ├── Drone 1.csv
│       │   ├── Drone 2.csv
│       │   ├── Drone 3.csv
│       │   ├── Drone 4.csv
│       │   └── Drone 5.csv
│       └── raw/
│           ├── Drone 1.csv
│           └── Drone 4.csv
├── smart_swarm.py
├── smart_swarm_src/
│   ├── __init__.py
│   ├── failover.py
│   ├── kalman_filter.py
│   ├── low_pass_filter.py
│   ├── pd_controller.py
│   └── utils.py
├── src/
│   ├── __init__.py
│   ├── action_runners/
│   │   ├── __init__.py
│   │   ├── base.py
│   │   └── precision_move.py
│   ├── command_contract.py
│   ├── connectivity_checker.py
│   ├── constants.py
│   ├── coordinate_utils.py
│   ├── drone.py
│   ├── drone_api_routes.py
│   ├── drone_api_server.py
│   ├── drone_communicator.py
│   ├── drone_config/
│   │   ├── __init__.py
│   │   ├── config_loader.py
│   │   ├── drone_config_data.py
│   │   └── drone_state.py
│   ├── drone_setup.py
│   ├── enums.py
│   ├── filter.py
│   ├── flight_timeout_utils.py
│   ├── gcs_api_routes.py
│   ├── gcs_auth_client.py
│   ├── heartbeat_sender.py
│   ├── led_colors.py
│   ├── led_controller.py
│   ├── live_armability_utils.py
│   ├── local_mavlink_controller.py
│   ├── managed_runtime_status.py
│   ├── mission_startup.py
│   ├── network_status.py
│   ├── origin_cache.py
│   ├── params.py
│   ├── pos_id_auto_detector.py
│   ├── px4_param_models.py
│   ├── px4_params/
│   │   ├── __init__.py
│   │   ├── catalog.py
│   │   └── service.py
│   ├── security/
│   │   ├── __init__.py
│   │   └── auth.py
│   ├── settings/
│   │   ├── __init__.py
│   │   ├── deployment_profile.py
│   │   ├── env_files.py
│   │   ├── env_registry.py
│   │   ├── env_status.py
│   │   ├── identity.py
│   │   └── runtime.py
│   ├── sitl_control_models.py
│   ├── sitl_control_service.py
│   ├── swarm_runtime_state.py
│   ├── synchronized_start.py
│   ├── telemetry_subscription_manager.py
│   └── ulog_service.py
├── swarm.json
├── swarm_sitl.json
├── swarm_trajectory_mission.py
├── tests/
│   ├── README.md
│   ├── __init__.py
│   ├── conftest.py
│   ├── fixtures/
│   │   ├── __init__.py
│   │   ├── command_samples.py
│   │   ├── drone_configs.py
│   │   ├── mission_samples.py
│   │   └── telemetry_samples.py
│   ├── helpers/
│   │   └── __init__.py
│   ├── integration/
│   │   └── __init__.py
│   ├── mocks/
│   │   ├── __init__.py
│   │   └── mavlink_simulator.py
│   ├── requirements-test.txt
│   ├── test_action_runner_runtime.py
│   ├── test_actions_common_params.py
│   ├── test_actions_preflight.py
│   ├── test_analyze_smart_swarm_tracking.py
│   ├── test_api_route_inventory.py
│   ├── test_bootstrap_installers.py
│   ├── test_calculate_spawn_coordinates.py
│   ├── test_check_runtime_venv.py
│   ├── test_command_processing.py
│   ├── test_command_system.py
│   ├── test_command_timeout_policy.py
│   ├── test_config_validation.py
│   ├── test_connectivity_checker.py
│   ├── test_constants.py
│   ├── test_coordinate_utils.py
│   ├── test_coordinator.py
│   ├── test_data_utils.py
│   ├── test_detect_px4_mavlink_port.py
│   ├── test_drone_api_http.py
│   ├── test_drone_api_websocket.py
│   ├── test_drone_communicator.py
│   ├── test_drone_communicator_runtime_swarm.py
│   ├── test_drone_config_components.py
│   ├── test_drone_setup.py
│   ├── test_drone_show_controlled_landing.py
│   ├── test_env_files.py
│   ├── test_env_registry.py
│   ├── test_env_status.py
│   ├── test_file_management.py
│   ├── test_file_utils.py
│   ├── test_filter.py
│   ├── test_fleet_candidate_registry.py
│   ├── test_flight_timeout_utils.py
│   ├── test_gcs_api_http.py
│   ├── test_gcs_api_websocket.py
│   ├── test_gcs_auth_client.py
│   ├── test_gcs_command_routes.py
│   ├── test_gcs_configuration_routes.py
│   ├── test_gcs_core_routes.py
│   ├── test_gcs_fleet_candidates_routes.py
│   ├── test_gcs_git_routes.py
│   ├── test_gcs_management_routes.py
│   ├── test_gcs_origin_routes.py
│   ├── test_gcs_px4_params_routes.py
│   ├── test_gcs_sar_routes.py
│   ├── test_gcs_show_management_routes.py
│   ├── test_gcs_sitl_control_routes.py
│   ├── test_gcs_static_assets_routes.py
│   ├── test_gcs_swarm_routes.py
│   ├── test_gcs_swarm_trajectory_routes.py
│   ├── test_gcs_telemetry.py
│   ├── test_git_manager.py
│   ├── test_git_sync.py
│   ├── test_heartbeat_runtime_mode.py
│   ├── test_heartbeat_sender.py
│   ├── test_led_controller.py
│   ├── test_link_presence.py
│   ├── test_local_mavlink_controller.py
│   ├── test_managed_runtime_status.py
│   ├── test_mds_auth.py
│   ├── test_mds_git_access_check.py
│   ├── test_mds_logging/
│   │   ├── __init__.py
│   │   ├── test_cli.py
│   │   ├── test_constants.py
│   │   ├── test_formatter.py
│   │   ├── test_handlers.py
│   │   ├── test_integration.py
│   │   ├── test_log_background.py
│   │   ├── test_log_proxy.py
│   │   ├── test_log_routes_drone.py
│   │   ├── test_log_routes_gcs.py
│   │   ├── test_noise_control.py
│   │   ├── test_registry.py
│   │   ├── test_schema.py
│   │   ├── test_session.py
│   │   ├── test_sse_stream.py
│   │   └── test_watcher.py
│   ├── test_mds_node_announce_script.py
│   ├── test_mission_startup.py
│   ├── test_network_status.py
│   ├── test_origin_compute.py
│   ├── test_origin_defaults.py
│   ├── test_pos_id_auto_detector.py
│   ├── test_precision_move_runner.py
│   ├── test_presence.py
│   ├── test_process_drone_files.py
│   ├── test_px4_param_catalog.py
│   ├── test_px4_param_service.py
│   ├── test_px4_param_store_profiles.py
│   ├── test_quickscout_mission.py
│   ├── test_request_logging.py
│   ├── test_run_sitl_validation_suite.py
│   ├── test_run_with_log_policy.py
│   ├── test_runtime_settings.py
│   ├── test_sar_api.py
│   ├── test_sar_coverage_planner.py
│   ├── test_sar_schemas.py
│   ├── test_sar_store.py
│   ├── test_schema_validation.py
│   ├── test_show_package_integrity.py
│   ├── test_sitl_control_client.py
│   ├── test_sitl_control_service.py
│   ├── test_smart_swarm_active_routes.py
│   ├── test_smart_swarm_failover.py
│   ├── test_smart_swarm_kalman.py
│   ├── test_smart_swarm_pd_controller.py
│   ├── test_smart_swarm_runtime_math.py
│   ├── test_smart_swarm_target_switch.py
│   ├── test_spa_static_server.py
│   ├── test_swarm_global_calculator.py
│   ├── test_swarm_runtime_state.py
│   ├── test_swarm_trajectory_mission.py
│   ├── test_swarm_trajectory_processor.py
│   ├── test_swarm_trajectory_service.py
│   ├── test_swarm_trajectory_smoother.py
│   ├── test_synchronized_start.py
│   ├── test_telemetry_logging.py
│   ├── test_ulog_service.py
│   ├── test_validate_actions_runtime.py
│   ├── test_validate_configuration_runtime.py
│   ├── test_validate_drone_show_runtime.py
│   ├── test_validate_integrated_runtime.py
│   ├── test_validate_px4_params_runtime.py
│   ├── test_validate_quickscout_runtime.py
│   ├── test_validate_smart_swarm_runtime.py
│   └── test_validate_swarm_trajectory_runtime.py
├── tools/
│   ├── analyze_smart_swarm_tracking.py
│   ├── audit_frontend_ui.py
│   ├── audit_mds_env_registry.py
│   ├── auto_recover/
│   │   └── create_backup_restore_scripts.sh
│   ├── build_custom_image.sh
│   ├── bump_version.py
│   ├── check_and_update_service.sh
│   ├── check_runtime_venv.py
│   ├── coordinator.service
│   ├── deprecated/
│   │   └── update_repo_https.sh
│   ├── docker_sitl_image_lib.sh
│   ├── download_mavsdk_server.sh
│   ├── gcs_fast_forward_update.sh
│   ├── generate_hover_test.py
│   ├── generate_mds_env_reference.py
│   ├── generate_release_notes.py
│   ├── git_sync_mds/
│   │   ├── git_sync_mds.service
│   │   └── install_git_sync_mds.sh
│   ├── install_companion.sh
│   ├── install_gcs.sh
│   ├── install_mds_node.sh
│   ├── led_indicator/
│   │   ├── install_led_indicator.sh
│   │   └── led_indicator.service
│   ├── load_deployment_profile.sh
│   ├── local.env.template
│   ├── mavlink_forward.py
│   ├── mds_auth_admin.py
│   ├── mds_banner.sh
│   ├── mds_gcs_init.sh
│   ├── mds_gcs_init_lib/
│   │   ├── gcs_common.sh
│   │   ├── gcs_env_config.sh
│   │   ├── gcs_firewall.sh
│   │   ├── gcs_nodejs.sh
│   │   ├── gcs_nodejs_env.sh
│   │   ├── gcs_prereqs.sh
│   │   ├── gcs_python.sh
│   │   ├── gcs_python_env.sh
│   │   ├── gcs_repo.sh
│   │   ├── gcs_services.sh
│   │   └── gcs_verify.sh
│   ├── mds_git_access_check.sh
│   ├── mds_init_lib/
│   │   ├── announce.sh
│   │   ├── common.sh
│   │   ├── connectivity.sh
│   │   ├── firewall.sh
│   │   ├── identity.sh
│   │   ├── mavlink_setup.sh
│   │   ├── mavsdk.sh
│   │   ├── network.sh
│   │   ├── prereqs.sh
│   │   ├── python_env.sh
│   │   ├── repo.sh
│   │   ├── services.sh
│   │   └── verify.sh
│   ├── mds_node_announce.sh
│   ├── mds_node_init.sh
│   ├── migrate_csv_to_json.py
│   ├── package_runtime_evidence_report.py
│   ├── package_sitl_image.sh
│   ├── polkit_reboot_add.sh
│   ├── publish_sitl_release_to_mega.sh
│   ├── reconcile_connectivity.sh
│   ├── reconcile_mavlink_runtime.sh
│   ├── recovery.sh
│   ├── release_sitl_image.sh
│   ├── rtk_streamer_gui/
│   │   └── main.py
│   ├── run_mavlink2rest.sh
│   ├── run_mavlink_router.sh
│   ├── run_sitl_validation_suite.py
│   ├── run_with_log_policy.py
│   ├── runtime_validation_support.py
│   ├── sitl_control_client.py
│   ├── sitl_image_prepare.sh
│   ├── sitl_plans/
│   │   ├── README.md
│   │   ├── actions_core.json
│   │   ├── advanced_operator_regression.json
│   │   ├── config_roundtrip.json
│   │   ├── config_then_drone_show.json
│   │   ├── drone_show_matrix.json
│   │   ├── integrated_mixed_mode.json
│   │   ├── mission_regression.json
│   │   ├── operator_regression.json
│   │   ├── px4_params_runtime.json
│   │   ├── quickscout_area_runtime.json
│   │   ├── quickscout_corridor_runtime.json
│   │   ├── quickscout_multi_runtime.json
│   │   ├── quickscout_runtime.json
│   │   ├── quickscout_template_regression.json
│   │   ├── smart_swarm_runtime.json
│   │   ├── swarm_trajectory_short_profile.json
│   │   └── ulog_runtime.json
│   ├── sitl_stop_all.py
│   ├── spa_static_server.py
│   ├── sync_time_linux.sh
│   ├── sync_time_win.bat
│   ├── test_import_show.html
│   ├── update_repo_ssh.sh
│   ├── update_service.sh
│   ├── validate_actions_runtime.py
│   ├── validate_commits.py
│   ├── validate_configuration_runtime.py
│   ├── validate_drone_show_runtime.py
│   ├── validate_integrated_runtime.py
│   ├── validate_onboard_ulog_runtime.py
│   ├── validate_px4_params_runtime.py
│   ├── validate_quickscout_runtime.py
│   ├── validate_smart_swarm_runtime.py
│   ├── validate_swarm_trajectory_runtime.py
│   └── version_sync.py
└── visual/
    └── templates/
        └── visualization.html
Download .txt
Showing preview only (751K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (8037 symbols across 499 files)

FILE: actions.py
  function fail (line 96) | def fail():
  function check_mavsdk_server_running (line 103) | def check_mavsdk_server_running(port):
  function wait_for_port (line 117) | def wait_for_port(port, host='localhost', timeout=10.0):
  function log_mavsdk_output (line 131) | async def log_mavsdk_output(mavsdk_server):
  function stop_mavsdk_server (line 169) | def stop_mavsdk_server(mavsdk_server):
  function find_mavsdk_server (line 187) | def find_mavsdk_server():
  function start_mavsdk_server (line 213) | def start_mavsdk_server(grpc_port, udp_port):
  function _normalize_action_name (line 267) | def _normalize_action_name(action_name: str | None) -> str | None:
  function perform_action (line 274) | async def perform_action(action, altitude=None, parameters=None, branch=...
  function wait_for_drone_connection (line 375) | async def wait_for_drone_connection(drone, timeout=10):
  function wait_for_telemetry_condition (line 391) | async def wait_for_telemetry_condition(stream_factory, predicate, descri...
  function _get_local_drone_state_snapshot (line 407) | def _get_local_drone_state_snapshot(timeout: float = 1.0):
  function _get_local_home_position_snapshot (line 421) | def _get_local_home_position_snapshot(timeout: float = 1.0):
  function _get_local_relative_altitude_snapshot (line 435) | def _get_local_relative_altitude_snapshot(timeout: float = 1.0):
  function _get_current_relative_altitude (line 451) | async def _get_current_relative_altitude(drone, timeout: float = 3.0):
  function _get_current_landed_state (line 468) | async def _get_current_landed_state(drone, timeout: float = 3.0):
  function wait_until_armed_state (line 480) | async def wait_until_armed_state(drone, expected: bool, timeout=15):
  function wait_until_landed_state (line 490) | async def wait_until_landed_state(drone, expected_states, description, t...
  function wait_until_flight_mode (line 500) | async def wait_until_flight_mode(drone, expected_mode, timeout=15):
  function wait_until_relative_altitude (line 509) | async def wait_until_relative_altitude(drone, minimum_relative_altitude_...
  function safe_action (line 531) | async def safe_action(func, *args, **kwargs):
  function _run_takeoff (line 550) | async def _run_takeoff(context: ActionExecutionContext, invocation: Acti...
  function _run_land (line 554) | async def _run_land(context: ActionExecutionContext, invocation: ActionI...
  function _run_return_rtl (line 558) | async def _run_return_rtl(context: ActionExecutionContext, invocation: A...
  function _run_hold (line 562) | async def _run_hold(context: ActionExecutionContext, invocation: ActionI...
  function _run_kill_terminate (line 566) | async def _run_kill_terminate(context: ActionExecutionContext, invocatio...
  function _run_test (line 570) | async def _run_test(context: ActionExecutionContext, invocation: ActionI...
  function _run_reboot_fc (line 574) | async def _run_reboot_fc(context: ActionExecutionContext, invocation: Ac...
  function _run_reboot_sys (line 578) | async def _run_reboot_sys(context: ActionExecutionContext, invocation: A...
  function _run_init_sysid (line 582) | async def _run_init_sysid(context: ActionExecutionContext, invocation: A...
  function _run_apply_common_params (line 586) | async def _run_apply_common_params(context: ActionExecutionContext, invo...
  function _run_update_code (line 590) | async def _run_update_code(context: ActionExecutionContext, invocation: ...
  function _run_precision_move (line 594) | async def _run_precision_move(context: ActionExecutionContext, invocatio...
  function get_action_spec (line 598) | def get_action_spec(action_name: str | None) -> ActionSpec | None:
  function parse_param_value (line 687) | def parse_param_value(raw_value, param_name):
  function set_parameters (line 708) | async def set_parameters(drone, parameters):
  function apply_common_params (line 728) | async def apply_common_params(drone, reboot_after=False):
  function ensure_ready_for_flight (line 790) | async def ensure_ready_for_flight(drone, timeout: float | None = None):
  function takeoff (line 837) | async def takeoff(drone, altitude):
  function land (line 891) | async def land(drone):
  function return_rtl (line 962) | async def return_rtl(drone):
  function kill_terminate (line 1027) | async def kill_terminate(drone):
  function hold (line 1057) | async def hold(drone):
  function test (line 1078) | async def test(drone):
  function reboot (line 1103) | async def reboot(drone, fc_flag, sys_flag, force_reboot=True):
  function reboot_system (line 1134) | async def reboot_system():
  function update_code (line 1149) | async def update_code(branch=None):
  function init_sysid (line 1226) | async def init_sysid(drone):

FILE: app/dashboard/drone-dashboard/src/App.js
  constant MOBILE_BREAKPOINT (line 63) | const MOBILE_BREAKPOINT = 960;

FILE: app/dashboard/drone-dashboard/src/components/CommandPreflightSummary.js
  function normalizeId (line 13) | function normalizeId(value) {

FILE: app/dashboard/drone-dashboard/src/components/DroneActions.js
  constant ACTION_SECTIONS (line 37) | const ACTION_SECTIONS = [
  constant ACTION_SHORT_LABELS (line 64) | const ACTION_SHORT_LABELS = {
  constant ACTION_ICONS (line 82) | const ACTION_ICONS = {
  constant ACTION_DESCRIPTIONS (line 100) | const ACTION_DESCRIPTIONS = {

FILE: app/dashboard/drone-dashboard/src/components/DroneConfigCard.js
  constant SERIAL_PORT_OPTIONS (line 54) | const SERIAL_PORT_OPTIONS = [
  constant BAUDRATE_OPTIONS (line 61) | const BAUDRATE_OPTIONS = [
  constant HEX_COLOR_PATTERN (line 69) | const HEX_COLOR_PATTERN = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
  constant RGB_COLOR_PATTERN (line 70) | const RGB_COLOR_PATTERN = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{...
  constant DEFAULT_MARKER_COLOR_FALLBACK (line 71) | const DEFAULT_MARKER_COLOR_FALLBACK = [95, 185, 255];
  function normalizeRuntimeModeValue (line 105) | function normalizeRuntimeModeValue(value) {
  function getCustomFieldValuePreview (line 116) | function getCustomFieldValuePreview(field) {
  function buildHeartbeatPresencePresentation (line 774) | function buildHeartbeatPresencePresentation(heartbeatData, heartbeatAgeS...
  function DroneConfigCard (line 1502) | function DroneConfigCard({

FILE: app/dashboard/drone-dashboard/src/components/DroneCriticalCommands.js
  constant PRIMARY_COMMAND_SLOT (line 23) | const PRIMARY_COMMAND_SLOT = {
  constant SECONDARY_COMMANDS (line 42) | const SECONDARY_COMMANDS = [
  function getDisabledReason (line 69) | function getDisabledReason(command, isArmed, runtimeStatus) {
  function getPanelNote (line 81) | function getPanelNote(isArmed, runtimeStatus) {

FILE: app/dashboard/drone-dashboard/src/components/DroneCriticalCommands.test.js
  function MonitorProbe (line 35) | function MonitorProbe() {

FILE: app/dashboard/drone-dashboard/src/components/DroneDetail.js
  constant POLLING_RATE_HZ (line 23) | const POLLING_RATE_HZ = 2;

FILE: app/dashboard/drone-dashboard/src/components/DroneGraph.js
  function buildGraphElements (line 7) | function buildGraphElements(drones) {
  function applySelectionClasses (line 40) | function applySelectionClasses(cy, selectedDroneId) {
  function DroneGraph (line 58) | function DroneGraph({ swarmData, selectedDroneId, onSelectDrone }) {

FILE: app/dashboard/drone-dashboard/src/components/DroneReadinessReport.js
  function getStatusIcon (line 8) | function getStatusIcon(status) {
  function renderMessageList (line 21) | function renderMessageList(messages, emptyLabel) {
  function getCompactDetailsLabel (line 43) | function getCompactDetailsLabel(readiness) {

FILE: app/dashboard/drone-dashboard/src/components/ErrorBoundary.js
  class ErrorBoundary (line 5) | class ErrorBoundary extends React.Component {
    method constructor (line 6) | constructor(props) {
    method getDerivedStateFromError (line 11) | static getDerivedStateFromError(error) {
    method componentDidCatch (line 15) | componentDidCatch(error, errorInfo) {
    method render (line 37) | render() {

FILE: app/dashboard/drone-dashboard/src/components/Globe.js
  constant DEFAULT_DRONE_MARKER_COLOR (line 19) | const DEFAULT_DRONE_MARKER_COLOR = 'dodgerblue';
  constant HEX_COLOR_PATTERN (line 20) | const HEX_COLOR_PATTERN = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
  constant SELECTED_CARD_WIDTH_PX (line 21) | const SELECTED_CARD_WIDTH_PX = 320;
  constant SELECTED_CARD_HEIGHT_PX (line 22) | const SELECTED_CARD_HEIGHT_PX = 260;
  constant SELECTED_CARD_GAP_PX (line 23) | const SELECTED_CARD_GAP_PX = 18;
  constant DEFAULT_CAMERA_POSITION (line 24) | const DEFAULT_CAMERA_POSITION = [12, 10, 12];
  constant CAMERA_FIT_PADDING (line 25) | const CAMERA_FIT_PADDING = 6;
  constant CAMERA_FIT_SCALE (line 26) | const CAMERA_FIT_SCALE = 1.32;
  constant MIN_CAMERA_FIT_DISTANCE (line 27) | const MIN_CAMERA_FIT_DISTANCE = 9;
  function Globe (line 303) | function Globe({ drones, selectedDroneId, onSelectDrone }) {

FILE: app/dashboard/drone-dashboard/src/components/GlobeControlBox.js
  function buildDroneClusterGroups (line 8) | function buildDroneClusterGroups(drones = []) {
  function GlobeControlBox (line 76) | function GlobeControlBox({

FILE: app/dashboard/drone-dashboard/src/components/GlobeMapView.js
  constant DEFAULT_DRONE_MARKER_COLOR (line 40) | const DEFAULT_DRONE_MARKER_COLOR = 'dodgerblue';
  constant HEX_COLOR_PATTERN (line 41) | const HEX_COLOR_PATTERN = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
  function fitLeafletMapToFleet (line 80) | function fitLeafletMapToFleet(map, validDrones = []) {

FILE: app/dashboard/drone-dashboard/src/components/ImportSection.js
  constant PROGRESS_STEPS (line 32) | const PROGRESS_STEPS = [
  constant INITIAL_PROGRESS (line 41) | const INITIAL_PROGRESS = {

FILE: app/dashboard/drone-dashboard/src/components/InfoHint.js
  function InfoHint (line 7) | function InfoHint({ content, label = 'More information', className = '',...

FILE: app/dashboard/drone-dashboard/src/components/InitialLaunchPlot.js
  function InitialLaunchPlot (line 7) | function InitialLaunchPlot({

FILE: app/dashboard/drone-dashboard/src/components/MapSelector.js
  function MapEvents (line 24) | function MapEvents({ onSelect, initialPosition, hasInteracted, onFirstIn...

FILE: app/dashboard/drone-dashboard/src/components/MissionLayout.test.js
  function MockOriginModal (line 11) | function MockOriginModal({ isOpen }) {

FILE: app/dashboard/drone-dashboard/src/components/MissionTrigger.js
  constant MISSION_PRESENTATIONS (line 30) | const MISSION_PRESENTATIONS = {
  constant DEFAULT_MISSION_PRESENTATION (line 68) | const DEFAULT_MISSION_PRESENTATION = {
  function getMissionPresentation (line 75) | function getMissionPresentation(missionType) {

FILE: app/dashboard/drone-dashboard/src/components/OriginModal.js
  function extractDroneParameters (line 12) | function extractDroneParameters(drone, telemetryData) {

FILE: app/dashboard/drone-dashboard/src/components/PrecisionMoveDialog.js
  constant MOVE_STEP_OPTIONS (line 18) | const MOVE_STEP_OPTIONS = [0.25, 0.5, 1, 2, 5];
  constant YAW_STEP_OPTIONS (line 19) | const YAW_STEP_OPTIONS = [15, 30, 45, 90];
  constant DEFAULT_FORM_STATE (line 21) | const DEFAULT_FORM_STATE = Object.freeze({
  constant FRAME_LABELS (line 35) | const FRAME_LABELS = {
  constant YAW_MODE_OPTIONS (line 56) | const YAW_MODE_OPTIONS = [
  constant CONTROL_MODE_OPTIONS (line 62) | const CONTROL_MODE_OPTIONS = [
  function buildInitialState (line 75) | function buildInitialState() {
  function parseSignedNumber (line 79) | function parseSignedNumber(value) {
  function parseOptionalPositiveNumber (line 88) | function parseOptionalPositiveNumber(value) {
  function formatSignedDistance (line 101) | function formatSignedDistance(value, positiveLabel, negativeLabel) {
  function formatAxisValue (line 110) | function formatAxisValue(value) {
  function formatRuntimeValue (line 117) | function formatRuntimeValue(value, unit, fallback = 'Runtime policy unav...
  function buildPrecisionMoveResult (line 125) | function buildPrecisionMoveResult(formState, frameConfig) {

FILE: app/dashboard/drone-dashboard/src/components/PrecisionMoveDialog.test.js
  function renderDialog (line 45) | function renderDialog(overrides = {}) {

FILE: app/dashboard/drone-dashboard/src/components/RouteDocsShortcut.js
  function buildRepoWebUrl (line 7) | function buildRepoWebUrl(repo = '') {
  function RouteDocsShortcut (line 12) | function RouteDocsShortcut() {

FILE: app/dashboard/drone-dashboard/src/components/RuntimeModeBadge.js
  function normalizeMode (line 7) | function normalizeMode(mode) {
  function RuntimeModeBadge (line 18) | function RuntimeModeBadge({

FILE: app/dashboard/drone-dashboard/src/components/SwarmPlots.js
  function getThemeColors (line 14) | function getThemeColors() {
  function getRoleColor (line 28) | function getRoleColor(role, colors) {
  function getBaseLayout (line 40) | function getBaseLayout(colors, isThreeDimensional = false) {
  function buildHoverText (line 71) | function buildHoverText(points) {
  function buildMarker (line 84) | function buildMarker(points, colors) {
  function PlotFrame (line 96) | function PlotFrame({ title, data, layout, config = plotConfig, className...
  function ThreeDPlot (line 122) | function ThreeDPlot({ points }) {
  function NorthEastPlot (line 167) | function NorthEastPlot({ points }) {
  function EastAltitudePlot (line 196) | function EastAltitudePlot({ points }) {
  function NorthAltitudePlot (line 225) | function NorthAltitudePlot({ points }) {
  function SwarmPlots (line 254) | function SwarmPlots({ swarmData, configData, selectedClusterId, onSelect...

FILE: app/dashboard/drone-dashboard/src/components/SwarmRuntimeControls.js
  constant ACTION_ICONS (line 30) | const ACTION_ICONS = {
  function buildRuntimeBrief (line 37) | function buildRuntimeBrief(targetDrones = []) {

FILE: app/dashboard/drone-dashboard/src/components/SwarmRuntimeControls.test.js
  function MonitorProbe (line 28) | function MonitorProbe() {

FILE: app/dashboard/drone-dashboard/src/components/TacticalDroneCard.js
  constant GPS_FIX_LABELS (line 26) | const GPS_FIX_LABELS = {
  constant HEX_COLOR_PATTERN (line 64) | const HEX_COLOR_PATTERN = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;

FILE: app/dashboard/drone-dashboard/src/components/VisualizationSection.js
  constant VIS_TOKENS (line 47) | const VIS_TOKENS = {

FILE: app/dashboard/drone-dashboard/src/components/logs/LogTable.js
  constant LEVEL_ICONS (line 7) | const LEVEL_ICONS = {

FILE: app/dashboard/drone-dashboard/src/components/logs/OnboardUlogDialog.js
  constant POLL_INTERVAL_MS (line 22) | const POLL_INTERVAL_MS = 1200;

FILE: app/dashboard/drone-dashboard/src/components/map/LeafletDrawControl.js
  constant CLICK_DELAY (line 28) | const CLICK_DELAY = 300;
  function normalizeInitialPoints (line 41) | function normalizeInitialPoints(points = []) {
  method click (line 131) | click(e) {
  method dblclick (line 162) | dblclick(e) {
  method mousemove (line 176) | mousemove(e) {

FILE: app/dashboard/drone-dashboard/src/components/map/LeafletFindingMarkers.js
  method click (line 22) | click(event) {

FILE: app/dashboard/drone-dashboard/src/components/map/MapFallbackBanner.js
  constant SESSION_KEY (line 10) | const SESSION_KEY = 'mds_fallback_banner_dismissed';
  constant MAPBOX_GUIDE_URL (line 11) | const MAPBOX_GUIDE_URL = buildDocsUrl(getRouteDoc('/globe-view'), {

FILE: app/dashboard/drone-dashboard/src/components/map/ViewModeToggle.js
  constant VIEW_MODES (line 8) | const VIEW_MODES = {

FILE: app/dashboard/drone-dashboard/src/components/missionConfig/MissionConfigAlertStack.js
  function MissionConfigAlertStack (line 7) | function MissionConfigAlertStack({

FILE: app/dashboard/drone-dashboard/src/components/missionConfig/MissionConfigToolbar.js
  function MissionConfigToolbar (line 9) | function MissionConfigToolbar({

FILE: app/dashboard/drone-dashboard/src/components/missionConfig/PendingEnrollmentPanel.js
  function PendingEnrollmentPanel (line 6) | function PendingEnrollmentPanel({

FILE: app/dashboard/drone-dashboard/src/components/sar/FindingReviewPanel.js
  constant FINDING_TYPE_OPTIONS (line 3) | const FINDING_TYPE_OPTIONS = [
  constant PRIORITY_OPTIONS (line 14) | const PRIORITY_OPTIONS = [
  constant CONFIDENCE_OPTIONS (line 21) | const CONFIDENCE_OPTIONS = [
  constant SOURCE_OPTIONS (line 27) | const SOURCE_OPTIONS = [
  constant STATUS_OPTIONS (line 34) | const STATUS_OPTIONS = [

FILE: app/dashboard/drone-dashboard/src/components/sar/MissionRecoveryPanel.js
  constant ACTIVE_STATES (line 3) | const ACTIVE_STATES = new Set(['executing', 'paused']);

FILE: app/dashboard/drone-dashboard/src/components/sar/QuickScoutLaunchReview.js
  function getReturnBehaviorLabel (line 13) | function getReturnBehaviorLabel(returnBehavior) {
  function getLaunchStatus (line 23) | function getLaunchStatus(planNeedsRecompute, launchReadiness) {

FILE: app/dashboard/drone-dashboard/src/components/trajectory/SearchBar.js
  constant CACHE_MAX (line 23) | const CACHE_MAX = 50;

FILE: app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryExportDialog.js
  constant EXPORT_FORMATS (line 4) | const EXPORT_FORMATS = [

FILE: app/dashboard/drone-dashboard/src/components/ui/OperatorPrimitives.js
  constant TONES (line 10) | const TONES = ['neutral', 'info', 'success', 'warning', 'danger', 'muted'];
  constant SIZES (line 11) | const SIZES = ['sm', 'md', 'lg'];
  function StatusBadge (line 13) | function StatusBadge({ tone = 'neutral', icon = null, children, classNam...
  function ActionIconButton (line 32) | function ActionIconButton({
  function OperatorCard (line 74) | function OperatorCard({
  function MetricPill (line 108) | function MetricPill({ label, value, detail = '', icon = null, tone = 'ne...
  function MetricStrip (line 129) | function MetricStrip({ items = [], label = 'Status summary', className =...
  function DocsLink (line 159) | function DocsLink({
  function PageActionBar (line 209) | function PageActionBar({
  function PageShell (line 262) | function PageShell({
  function OperatorNotice (line 309) | function OperatorNotice({
  function EmptyState (line 344) | function EmptyState({ icon = null, title, detail = '', action = null, cl...
  function ConfirmDialog (line 365) | function ConfirmDialog({

FILE: app/dashboard/drone-dashboard/src/config/apiConfig.js
  constant DEFAULT_GCS_PORT (line 21) | const DEFAULT_GCS_PORT = process.env.REACT_APP_GCS_PORT || '5030';
  constant DEFAULT_DRONE_PORT (line 22) | const DEFAULT_DRONE_PORT = process.env.REACT_APP_DRONE_PORT || '7070';
  function getBaseServerURL (line 30) | function getBaseServerURL() {
  function getGCSPort (line 51) | function getGCSPort() {
  function getDronePort (line 59) | function getDronePort() {
  function getBackendURL (line 68) | function getBackendURL(port = null) {
  function getDroneServiceURL (line 78) | function getDroneServiceURL() {
  method baseURL (line 85) | get baseURL() { return getBaseServerURL(); }
  method gcsPort (line 86) | get gcsPort() { return getGCSPort(); }
  method dronePort (line 87) | get dronePort() { return getDronePort(); }
  method gcsURL (line 88) | get gcsURL() { return getBackendURL(); }
  method droneURL (line 89) | get droneURL() { return getDroneServiceURL(); }

FILE: app/dashboard/drone-dashboard/src/config/mapConfig.js
  constant MAP_PROVIDERS (line 4) | const MAP_PROVIDERS = {
  constant DEFAULT_PROVIDER (line 9) | const DEFAULT_PROVIDER = MAP_PROVIDERS.MAPBOX;
  constant MAPBOX_TOKEN (line 11) | const MAPBOX_TOKEN =
  constant TILE_LAYERS (line 17) | const TILE_LAYERS = {
  constant DEFAULT_CENTER (line 47) | const DEFAULT_CENTER = { lat: 35.6895, lng: 139.6917 };
  constant DEFAULT_LEAFLET_SUBDOMAINS (line 48) | const DEFAULT_LEAFLET_SUBDOMAINS = 'abc';
  constant LEAFLET_DEFAULTS (line 50) | const LEAFLET_DEFAULTS = {
  constant PROVIDER_STORAGE_KEY (line 58) | const PROVIDER_STORAGE_KEY = 'mds_map_provider';
  constant TILE_STORAGE_KEY (line 59) | const TILE_STORAGE_KEY = 'mds_tile_layer';
  constant DEFAULT_TILE_KEY (line 63) | const DEFAULT_TILE_KEY = 'esriSatellite';

FILE: app/dashboard/drone-dashboard/src/config/routeDocs.js
  constant DEFAULT_DOC_BRANCH (line 4) | const DEFAULT_DOC_BRANCH = 'main';
  constant ROUTE_DOCS (line 6) | const ROUTE_DOCS = Object.freeze([
  constant ROUTE_DOCS_BY_PATH (line 133) | const ROUTE_DOCS_BY_PATH = Object.freeze(
  function getRouteDoc (line 140) | function getRouteDoc(pathname = '/') {
  function normalizeGithubRepoUrl (line 144) | function normalizeGithubRepoUrl(repoUrl = '') {
  function buildDocsUrl (line 168) | function buildDocsUrl(doc, { repoUrl = '', repoWebUrl = '', branch = DEF...
  function getRouteDocUrl (line 186) | function getRouteDocUrl(pathname = '/', options = {}) {

FILE: app/dashboard/drone-dashboard/src/constants/droneConstants.js
  constant DRONE_MISSION_TYPES (line 8) | const DRONE_MISSION_TYPES = {
  constant DRONE_MISSION_DISPLAY_ORDER (line 17) | const DRONE_MISSION_DISPLAY_ORDER = [
  constant DRONE_ACTION_TYPES (line 25) | const DRONE_ACTION_TYPES = {
  constant DRONE_MISSION_IMAGES (line 43) | const DRONE_MISSION_IMAGES = {
  constant DRONE_MISSION_NAMES (line 48) | const DRONE_MISSION_NAMES = {
  constant DRONE_ACTION_NAMES (line 56) | const DRONE_ACTION_NAMES = {

FILE: app/dashboard/drone-dashboard/src/constants/droneStates.js
  constant DRONE_SHOW_STATES (line 11) | const DRONE_SHOW_STATES = {

FILE: app/dashboard/drone-dashboard/src/constants/fieldMappings.js
  constant FIELD_NAMES (line 21) | const FIELD_NAMES = {
  constant DRONE_RUNTIME_CLOCK_PROP (line 86) | const DRONE_RUNTIME_CLOCK_PROP = '__runtimeClock';
  constant UNIX_MS_THRESHOLD (line 88) | const UNIX_MS_THRESHOLD = 1_000_000_000_000;
  function normalizeRuntimeTimestampMs (line 90) | function normalizeRuntimeTimestampMs(value) {
  function extractServerNowMs (line 109) | function extractServerNowMs(headers = {}) {
  function getRuntimeClockReferenceMs (line 122) | function getRuntimeClockReferenceMs(droneData) {
  function normalizeClockMeta (line 133) | function normalizeClockMeta(clockMeta = {}) {
  function attachDroneRuntimeClock (line 156) | function attachDroneRuntimeClock(droneData, clockMeta = {}) {
  function normalizeDroneData (line 192) | function normalizeDroneData(droneData) {
  function normalizeTelemetryResponse (line 286) | function normalizeTelemetryResponse(telemetryResponse, clockMeta = {}) {
  function getField (line 313) | function getField(drone, fieldKey, defaultValue = undefined) {

FILE: app/dashboard/drone-dashboard/src/constants/logConstants.js
  constant LOG_LEVELS (line 4) | const LOG_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'];
  constant LOG_LEVEL_COLORS (line 6) | const LOG_LEVEL_COLORS = {
  constant OPS_DEFAULT_LEVEL (line 15) | const OPS_DEFAULT_LEVEL = 'WARNING';
  constant DEV_DEFAULT_LEVEL (line 17) | const DEV_DEFAULT_LEVEL = 'DEBUG';
  constant MAX_LOG_LINES (line 20) | const MAX_LOG_LINES = 5000;
  constant SSE_BATCH_INTERVAL_MS (line 23) | const SSE_BATCH_INTERVAL_MS = 200;
  constant HEALTH_POLL_INTERVAL_MS (line 26) | const HEALTH_POLL_INTERVAL_MS = 5000;
  constant MODES (line 29) | const MODES = { OPS: 'operations', DEV: 'developer' };
  constant LIVE_TIME_WINDOWS (line 32) | const LIVE_TIME_WINDOWS = [
  constant SEVERITY_FOCUS (line 40) | const SEVERITY_FOCUS = {

FILE: app/dashboard/drone-dashboard/src/constants/px4FlightModes.js
  constant PX4_MAIN_MODES (line 18) | const PX4_MAIN_MODES = {
  constant PX4_AUTO_SUB_MODES (line 33) | const PX4_AUTO_SUB_MODES = {
  constant PX4_FLIGHT_MODES (line 50) | const PX4_FLIGHT_MODES = {
  constant MAV_STATE (line 86) | const MAV_STATE = {

FILE: app/dashboard/drone-dashboard/src/constants/trajectoryMissionPolicy.js
  constant DEFAULT_TRAJECTORY_ALTITUDE_POLICY (line 1) | const DEFAULT_TRAJECTORY_ALTITUDE_POLICY = Object.freeze({
  constant DEFAULT_TRAJECTORY_SPEED_POLICY (line 8) | const DEFAULT_TRAJECTORY_SPEED_POLICY = Object.freeze({
  constant DEFAULT_TRAJECTORY_TIMING_POLICY (line 16) | const DEFAULT_TRAJECTORY_TIMING_POLICY = Object.freeze({
  constant DEFAULT_TRAJECTORY_TERRAIN_POLICY (line 22) | const DEFAULT_TRAJECTORY_TERRAIN_POLICY = Object.freeze({
  constant TRAJECTORY_ALTITUDE_POLICY (line 27) | const TRAJECTORY_ALTITUDE_POLICY = { ...DEFAULT_TRAJECTORY_ALTITUDE_POLI...
  constant TRAJECTORY_SPEED_POLICY (line 28) | const TRAJECTORY_SPEED_POLICY = { ...DEFAULT_TRAJECTORY_SPEED_POLICY };
  constant TRAJECTORY_TIMING_POLICY (line 29) | const TRAJECTORY_TIMING_POLICY = { ...DEFAULT_TRAJECTORY_TIMING_POLICY };
  constant TRAJECTORY_TERRAIN_POLICY (line 30) | const TRAJECTORY_TERRAIN_POLICY = { ...DEFAULT_TRAJECTORY_TERRAIN_POLICY };

FILE: app/dashboard/drone-dashboard/src/contexts/AuthContext.js
  function AuthProvider (line 13) | function AuthProvider({ children }) {
  function useAuth (line 88) | function useAuth() {

FILE: app/dashboard/drone-dashboard/src/contexts/CommandActivityContext.js
  constant MAX_COMMAND_MONITORS (line 16) | const MAX_COMMAND_MONITORS = 8;
  constant ACTIVE_COMMAND_REFRESH_MS (line 17) | const ACTIVE_COMMAND_REFRESH_MS = 2000;
  constant RECENT_COMMAND_REFRESH_MS (line 18) | const RECENT_COMMAND_REFRESH_MS = 15000;
  function sortCommandMonitors (line 20) | function sortCommandMonitors(monitors = []) {
  function mergeSnapshots (line 33) | function mergeSnapshots(previousMonitors, incomingSnapshots) {

FILE: app/dashboard/drone-dashboard/src/contexts/CommandActivityContext.test.js
  function MonitorProbe (line 17) | function MonitorProbe() {

FILE: app/dashboard/drone-dashboard/src/contexts/ThemeContext.js
  constant META_THEME_COLOR_TOKEN (line 3) | const META_THEME_COLOR_TOKEN = '--app-meta-theme-color';
  constant THEMES (line 6) | const THEMES = {

FILE: app/dashboard/drone-dashboard/src/contexts/ThemeContext.test.js
  function ThemeProbe (line 6) | function ThemeProbe() {

FILE: app/dashboard/drone-dashboard/src/hooks/useGcsGitInfo.js
  constant DEFAULT_POLL_INTERVAL_MS (line 6) | const DEFAULT_POLL_INTERVAL_MS = 15000;
  function formatRepoLabel (line 8) | function formatRepoLabel(remoteUrl, fallback = STATIC_REPO) {
  function useGcsGitInfo (line 22) | function useGcsGitInfo(pollIntervalMs = DEFAULT_POLL_INTERVAL_MS) {

FILE: app/dashboard/drone-dashboard/src/hooks/useGcsRuntimeStatus.js
  constant DEFAULT_POLL_INTERVAL_MS (line 5) | const DEFAULT_POLL_INTERVAL_MS = 15000;
  constant RUNTIME_MODE_CACHE_KEY (line 6) | const RUNTIME_MODE_CACHE_KEY = 'mds:gcs-runtime-mode';
  function normalizeModeLabel (line 8) | function normalizeModeLabel(mode) {
  function useGcsRuntimeStatus (line 19) | function useGcsRuntimeStatus(pollIntervalMs = DEFAULT_POLL_INTERVAL_MS) {

FILE: app/dashboard/drone-dashboard/src/hooks/useLogStream.test.js
  class MockEventSource (line 6) | class MockEventSource {
    method constructor (line 7) | constructor(url, options = undefined) {
    method close (line 15) | close() { this.closed = true; }

FILE: app/dashboard/drone-dashboard/src/hooks/useNormalizedTelemetry.js
  function useNormalizedTelemetry (line 37) | function useNormalizedTelemetry(endpoint, interval = null, normalize = t...
  function useDroneTelemetry (line 107) | function useDroneTelemetry(droneId, interval = 1000) {

FILE: app/dashboard/drone-dashboard/src/hooks/useSyncDrones.js
  function useSyncDrones (line 9) | function useSyncDrones() {

FILE: app/dashboard/drone-dashboard/src/pages/CustomShowPage.js
  constant FALLBACK_REQUIRED_COLUMNS (line 34) | const FALLBACK_REQUIRED_COLUMNS = ['t', 'px', 'py', 'pz', 'vx', 'vy', 'v...
  function formatDuration (line 36) | function formatDuration(durationSec) {

FILE: app/dashboard/drone-dashboard/src/pages/EnvironmentsPage.js
  constant DOMAIN_LABELS (line 40) | const DOMAIN_LABELS = {
  function compactHash (line 53) | function compactHash(value) {
  function boolLabel (line 58) | function boolLabel(value) {
  function displayValue (line 69) | function displayValue(entry) {
  function valueTone (line 79) | function valueTone(entry) {
  function restartTone (line 92) | function restartTone(restartRequired) {
  function restartLabel (line 105) | function restartLabel(restartRequired) {
  function normalizeError (line 118) | function normalizeError(error, fallback) {
  function resolveNodeHost (line 122) | function resolveNodeHost(row) {
  function downloadJson (line 142) | function downloadJson(filename, payload) {
  function buildGcsEnvProfile (line 154) | function buildGcsEnvProfile(values) {
  function buildNodeEnvProfile (line 158) | function buildNodeEnvProfile(values, hwId) {
  function buildEnvProfile (line 162) | function buildEnvProfile(values, extra) {
  function parseEnvProfile (line 180) | function parseEnvProfile(rawText, expectedScope) {
  function parseGcsEnvProfile (line 198) | function parseGcsEnvProfile(rawText) {
  function parseNodeEnvProfile (line 202) | function parseNodeEnvProfile(rawText) {
  function buildInitialDraft (line 206) | function buildInitialDraft(entry) {
  function buildEnvEntryDocPath (line 216) | function buildEnvEntryDocPath(entry) {
  function EnvEntryCard (line 221) | function EnvEntryCard({
  function EnvEntryDialog (line 280) | function EnvEntryDialog({ entry, busy, onSave, onClose }) {
  function buildNodePlanDraft (line 396) | function buildNodePlanDraft(entry) {
  function NodeEnvPlanner (line 409) | function NodeEnvPlanner({
  function EnvImportDialog (line 537) | function EnvImportDialog({ plan, busy, onConfirm, onClose }) {
  function EnvironmentsPage (line 597) | function EnvironmentsPage() {

FILE: app/dashboard/drone-dashboard/src/pages/EnvironmentsPage.test.js
  function renderPage (line 177) | function renderPage() {

FILE: app/dashboard/drone-dashboard/src/pages/FleetEnrollmentPage.js
  constant ACTIVE_STATE_SET (line 45) | const ACTIVE_STATE_SET = new Set(['pending_operator_review', 'conflict']);
  function formatCandidateStateLabel (line 47) | function formatCandidateStateLabel(state) {
  function formatCandidateStateTone (line 66) | function formatCandidateStateTone(state) {
  function formatRuntimeModeLabel (line 83) | function formatRuntimeModeLabel(value) {
  function formatConflictReason (line 94) | function formatConflictReason(reason) {
  function formatHeartbeatSummary (line 109) | function formatHeartbeatSummary(candidate) {
  function buildCandidateSearchBlob (line 122) | function buildCandidateSearchBlob(candidate) {
  function filterCandidateByState (line 141) | function filterCandidateByState(candidate, stateFilter) {
  function buildMutationNotice (line 151) | function buildMutationNotice(responseData) {
  function EnrollmentNotice (line 173) | function EnrollmentNotice({ notice }) {
  function CandidateStatePill (line 193) | function CandidateStatePill({ state }) {
  function ActionDialog (line 201) | function ActionDialog({
  function FleetEnrollmentPage (line 235) | function FleetEnrollmentPage() {

FILE: app/dashboard/drone-dashboard/src/pages/FleetEnrollmentPage.test.js
  function mockFetch (line 42) | function mockFetch({ candidates, config }) {

FILE: app/dashboard/drone-dashboard/src/pages/FleetOpsPage.js
  constant TABS (line 35) | const TABS = [
  constant FILTERS (line 42) | const FILTERS = [
  function toPrimitiveTone (line 50) | function toPrimitiveTone(tone) {
  function StatusMetric (line 57) | function StatusMetric({ icon: Icon, label, status, detail }) {
  function dashboardPortFromRuntime (line 70) | function dashboardPortFromRuntime(runtime) {
  function formatDashboardHost (line 82) | function formatDashboardHost(ip) {
  function resolveDashboardHref (line 90) | function resolveDashboardHref(runtime, nodeIp) {
  function DashboardQuickLinks (line 108) | function DashboardQuickLinks({ row }) {
  function DashboardLinks (line 163) | function DashboardLinks({ runtime, nodeIp, label }) {
  function SidecarHashFacts (line 195) | function SidecarHashFacts({ runtime, profile = false }) {
  function NodeDetails (line 224) | function NodeDetails({ row, activeTab }) {
  function NodeCard (line 304) | function NodeCard({ row, activeTab, selected, onToggleSelected }) {
  function filterRows (line 340) | function filterRows(rows, query, filter) {
  function FleetOpsPage (line 377) | function FleetOpsPage({ gitStatusOverride = null, heartbeatOverride = nu...

FILE: app/dashboard/drone-dashboard/src/pages/FleetOpsPage.test.js
  function mockFleetFeeds (line 109) | function mockFleetFeeds() {
  function clonePayload (line 121) | function clonePayload(payload) {
  function renderFleetOps (line 125) | function renderFleetOps(props = {}) {

FILE: app/dashboard/drone-dashboard/src/pages/LoginPage.js
  constant AUTH_GUIDE_URL (line 9) | const AUTH_GUIDE_URL = buildDocsUrl(
  function LoginPage (line 14) | function LoginPage() {

FILE: app/dashboard/drone-dashboard/src/pages/ManageDroneShow.js
  constant WORKFLOW_STEPS (line 20) | const WORKFLOW_STEPS = [

FILE: app/dashboard/drone-dashboard/src/pages/MissionConfig.test.js
  function MockOriginModal (line 42) | function MockOriginModal({ isOpen }) {

FILE: app/dashboard/drone-dashboard/src/pages/Px4ParametersPage.js
  constant SNAPSHOT_REFRESH_INTERVAL_MS (line 50) | const SNAPSHOT_REFRESH_INTERVAL_MS = 15000;
  constant COMPACT_BREAKPOINT (line 51) | const COMPACT_BREAKPOINT = 1120;
  constant TOUCH_COMPACT_BREAKPOINT (line 52) | const TOUCH_COMPACT_BREAKPOINT = 1400;
  constant PARAMETER_LINK_ACTIVE_LEVELS (line 53) | const PARAMETER_LINK_ACTIVE_LEVELS = new Set(['online', 'degraded']);
  function isTouchViewport (line 55) | function isTouchViewport() {
  function isCompactParameterViewport (line 65) | function isCompactParameterViewport() {
  function trimTrailingZeros (line 73) | function trimTrailingZeros(value) {
  function formatParameterValue (line 80) | function formatParameterValue(value, row = null) {
  function formatParameterRange (line 106) | function formatParameterRange(row = null) {
  function formatRelativeSnapshotAge (line 125) | function formatRelativeSnapshotAge(snapshot) {
  function isSnapshotStale (line 139) | function isSnapshotStale(snapshot) {
  function deriveWriteBlockedReason (line 146) | function deriveWriteBlockedReason(policy, selectedDrone, snapshotSummary...
  function getSnapshotStatusLabel (line 166) | function getSnapshotStatusLabel({ selectedDrone, writeBlockedReason, sna...
  function buildNotice (line 182) | function buildNotice(tone, title, detail = '', busy = false) {
  function buildTrackingNotice (line 186) | function buildTrackingNotice(snapshot, fallbackTitle = 'Command update') {
  function summarizeBatchResults (line 208) | function summarizeBatchResults(results = []) {
  function parseDraftValue (line 375) | function parseDraftValue(row, draftValue) {
  function downloadTextFile (line 385) | function downloadTextFile(filename, text) {
  function loadPolicy (line 460) | async function loadPolicy() {
  function loadProfiles (line 480) | async function loadProfiles() {
  function loadSwarmAssignments (line 507) | async function loadSwarmAssignments() {
  function loadFleetConfig (line 527) | async function loadFleetConfig() {
  function loadTelemetry (line 547) | async function loadTelemetry() {
  function loadProfile (line 678) | async function loadProfile() {

FILE: app/dashboard/drone-dashboard/src/pages/QuickScoutPage.js
  constant DEFAULT_SURVEY_CONFIG (line 85) | const DEFAULT_SURVEY_CONFIG = {
  constant DEFAULT_LAST_KNOWN_POINT_RADIUS_M (line 96) | const DEFAULT_LAST_KNOWN_POINT_RADIUS_M = 120;
  constant DEFAULT_CORRIDOR_WIDTH_M (line 97) | const DEFAULT_CORRIDOR_WIDTH_M = 90;
  constant ACTIVE_MISSION_STATES (line 99) | const ACTIVE_MISSION_STATES = new Set(['executing', 'paused']);
  constant MONITOR_MISSION_STATES (line 100) | const MONITOR_MISSION_STATES = new Set(['executing', 'paused', 'complete...

FILE: app/dashboard/drone-dashboard/src/pages/RuntimeAdminPage.js
  function formatRepoAccessModeLabel (line 43) | function formatRepoAccessModeLabel(mode) {
  function StatusPill (line 56) | function StatusPill({ tone = 'neutral', children }) {
  function formatAuthHealthTone (line 65) | function formatAuthHealthTone(status) {
  function formatRepoSyncTone (line 78) | function formatRepoSyncTone(status) {
  function formatRepoSyncLabel (line 94) | function formatRepoSyncLabel(status) {
  function formatNoticeTone (line 113) | function formatNoticeTone(status, fallback = 'neutral') {
  function buildNotice (line 129) | function buildNotice(payload, fallbackTone = 'neutral') {
  function RuntimeAdminPage (line 141) | function RuntimeAdminPage({ runtimeOverride = null, gitInfoOverride = nu...

FILE: app/dashboard/drone-dashboard/src/pages/SitlControlPage.js
  constant INVENTORY_POLL_INTERVAL_MS (line 42) | const INVENTORY_POLL_INTERVAL_MS = 10000;
  constant OPERATION_POLL_INTERVAL_MS (line 43) | const OPERATION_POLL_INTERVAL_MS = 2000;
  constant LOG_TAIL_OPTIONS (line 44) | const LOG_TAIL_OPTIONS = [80, 200, 500];
  constant TERMINAL_OPERATION_STATES (line 45) | const TERMINAL_OPERATION_STATES = new Set(['failed', 'succeeded']);
  constant ENABLE_BACKGROUND_POLLING (line 46) | const ENABLE_BACKGROUND_POLLING = process.env.NODE_ENV !== 'test';
  function splitImageRef (line 48) | function splitImageRef(imageRef) {
  function buildImageCatalog (line 64) | function buildImageCatalog(images) {
  function getImageShortLabel (line 99) | function getImageShortLabel(imageRef) {
  function getRepoLabel (line 105) | function getRepoLabel(repoUrl) {
  function formatBytes (line 118) | function formatBytes(value) {
  function formatTimestamp (line 133) | function formatTimestamp(value) {
  function formatDockerTone (line 151) | function formatDockerTone(dockerState) {
  function formatInstanceTone (line 158) | function formatInstanceTone(instance) {
  function formatOperationTone (line 168) | function formatOperationTone(operation) {
  function getPrimaryInstanceIp (line 181) | function getPrimaryInstanceIp(instance, preferredNetworkName) {
  function SummaryCard (line 192) | function SummaryCard({ icon: Icon, label, value, tone = 'default', detai...
  function SectionHeader (line 207) | function SectionHeader({ title, detail = '', action = null }) {
  function SitlEmptyState (line 219) | function SitlEmptyState({ title, detail }) {
  function FieldLabel (line 225) | function FieldLabel({ label, hint = '' }) {
  function buildConfirmDialogMessage (line 234) | function buildConfirmDialogMessage(dialog) {
  function sanitizeTagValue (line 258) | function sanitizeTagValue(value, { fallback = '' } = {}) {
  function buildDefaultReleaseVersionTag (line 267) | function buildDefaultReleaseVersionTag(image, policy) {
  function buildDefaultArchiveBasename (line 278) | function buildDefaultArchiveBasename(imageRepo) {
  function formatPercent (line 287) | function formatPercent(value) {
  function buildPortainerUrl (line 295) | function buildPortainerUrl(host) {
  function evaluateHostResources (line 303) | function evaluateHostResources(host) {
  function SitlControlPage (line 375) | function SitlControlPage() {

FILE: app/dashboard/drone-dashboard/src/pages/SwarmDesign.js
  constant CSV_HEADERS (line 59) | const CSV_HEADERS = ['hw_id', 'follow', 'offset_x', 'offset_y', 'offset_...
  function hasIncompleteNumericValue (line 61) | function hasIncompleteNumericValue(value) {
  function SwarmDesign (line 69) | function SwarmDesign() {

FILE: app/dashboard/drone-dashboard/src/pages/TrajectoryPlanning.js
  method click (line 85) | click(e) {

FILE: app/dashboard/drone-dashboard/src/services/ElevationService.js
  constant CACHE_MAX (line 8) | const CACHE_MAX = 500;
  constant GRID_SNAP (line 9) | const GRID_SNAP = 0.0002;
  function snapCoord (line 12) | function snapCoord(val) {
  function getCacheKey (line 16) | function getCacheKey(lat, lng) {
  function cacheSet (line 20) | function cacheSet(key, value) {
  function estimateStaticElevation (line 32) | function estimateStaticElevation(lat, lng) {
  function queryMapboxTilequery (line 58) | async function queryMapboxTilequery(lat, lng, timeout = 5000) {
  function getTerrainElevation (line 99) | async function getTerrainElevation(lat, lng, options = {}) {
  function clearElevationCache (line 163) | function clearElevationCache() {

FILE: app/dashboard/drone-dashboard/src/services/TerrainService.js
  class TerrainService (line 17) | class TerrainService {
    method constructor (line 18) | constructor() {
    method initialize (line 33) | async initialize(mapboxToken = null, mapInstance = null) {
    method setAltitudePreference (line 72) | setAltitudePreference(preference) {
    method getAltitudePreference (line 84) | getAltitudePreference() {
    method getGroundElevation (line 95) | async getGroundElevation(latitude, longitude) {
    method getBatchGroundElevation (line 146) | async getBatchGroundElevation(coordinates) {
    method convertMSLtoAGL (line 201) | async convertMSLtoAGL(latitude, longitude, mslAltitude) {
    method convertAGLtoMSL (line 226) | async convertAGLtoMSL(latitude, longitude, aglAltitude) {
    method getWaypointAltitudeInfo (line 251) | async getWaypointAltitudeInfo(waypoint) {
    method processTrajectoryTerrain (line 297) | async processTrajectoryTerrain(waypoints) {
    method validateAltitudeWithTerrain (line 360) | validateAltitudeWithTerrain(mslAltitude, aglAltitude, groundElevation) {
    method verifyTerrainSource (line 419) | async verifyTerrainSource() {
    method queryMapboxTerrain (line 455) | async queryMapboxTerrain(latitude, longitude) {
    method batchQueryTerrain (line 479) | async batchQueryTerrain(coordinates) {
    method estimateElevation (line 498) | estimateElevation(latitude, longitude) {
    method formatAltitudeDisplay (line 540) | formatAltitudeDisplay(mslAltitude, aglAltitude) {
    method cacheElevation (line 551) | cacheElevation(key, elevation) {
    method clearCache (line 564) | clearCache(bounds = null) {
    method getServiceStats (line 583) | getServiceStats() {

FILE: app/dashboard/drone-dashboard/src/services/apiError.js
  function extractApiErrorMessage (line 1) | async function extractApiErrorMessage(error, fallbackMessage = 'Request ...

FILE: app/dashboard/drone-dashboard/src/services/fleetEnrollmentApiService.js
  function buildFleetCandidateUrl (line 9) | function buildFleetCandidateUrl(candidateId = '', suffix = '') {
  function listFleetCandidates (line 19) | async function listFleetCandidates({ includeInactive = false, runtimeMod...
  function getFleetCandidate (line 28) | async function getFleetCandidate(candidateId) {
  function announceFleetCandidate (line 32) | async function announceFleetCandidate(payload) {
  function acceptFleetCandidate (line 36) | async function acceptFleetCandidate(candidateId, payload, { commit = tru...
  function replaceFleetCandidate (line 42) | async function replaceFleetCandidate(candidateId, payload, { commit = tr...
  function recoverFleetCandidate (line 48) | async function recoverFleetCandidate(candidateId, payload, { commit = tr...
  function rejectFleetCandidate (line 54) | async function rejectFleetCandidate(candidateId, payload = {}) {
  function ignoreFleetCandidate (line 58) | async function ignoreFleetCandidate(candidateId, payload = {}) {

FILE: app/dashboard/drone-dashboard/src/services/gcsApiService.js
  constant ABSOLUTE_URL_PATTERN (line 4) | const ABSOLUTE_URL_PATTERN = /^[a-z][a-z\d+\-.]*:\/\//i;
  constant ABSOLUTE_WS_URL_PATTERN (line 5) | const ABSOLUTE_WS_URL_PATTERN = /^wss?:\/\//i;
  constant COMMAND_SUBMIT_TIMEOUT_MS (line 6) | const COMMAND_SUBMIT_TIMEOUT_MS = 12000;
  constant GCS_ROUTE_KEYS (line 8) | const GCS_ROUTE_KEYS = Object.freeze({
  constant GCS_ROUTES (line 88) | const GCS_ROUTES = Object.freeze({
  constant GCS_WS_ROUTES (line 168) | const GCS_WS_ROUTES = Object.freeze({
  constant ROUTE_KEY_BY_PATH (line 174) | const ROUTE_KEY_BY_PATH = Object.freeze({
  function resolveGcsRoute (line 249) | function resolveGcsRoute(routeOrPath) {
  function resolveGcsRouteKey (line 268) | function resolveGcsRouteKey(routeOrPath) {
  function buildGcsUrl (line 284) | function buildGcsUrl(routeOrPath) {
  function buildGcsWebSocketUrl (line 292) | function buildGcsWebSocketUrl(path) {
  function setGcsCsrfToken (line 307) | function setGcsCsrfToken(token) {
  function withGcsAuthConfig (line 311) | function withGcsAuthConfig(config = {}, method = 'GET') {
  function buildTelemetryWebSocketUrl (line 331) | function buildTelemetryWebSocketUrl() {
  function buildHeartbeatWebSocketUrl (line 335) | function buildHeartbeatWebSocketUrl() {
  function buildGitStatusWebSocketUrl (line 339) | function buildGitStatusWebSocketUrl() {
  function buildLogsUrl (line 343) | function buildLogsUrl(suffix = '') {
  function buildSarUrl (line 347) | function buildSarUrl(suffix = '') {
  function buildShowPlotUrl (line 351) | function buildShowPlotUrl(filename = '') {
  function buildShowDownloadUrl (line 359) | function buildShowDownloadUrl(type = 'raw') {
  function buildStaticPlotUrl (line 367) | function buildStaticPlotUrl(filename) {
  function buildSwarmTrajectoryUrl (line 371) | function buildSwarmTrajectoryUrl(suffix = '') {
  function unwrapFleetTelemetryPayload (line 375) | function unwrapFleetTelemetryPayload(payload) {
  function unwrapSwarmConfigPayload (line 382) | function unwrapSwarmConfigPayload(payload) {
  function fetchGcsResource (line 392) | async function fetchGcsResource(routeOrPath, config = {}) {
  function fetchBlobGcsResource (line 396) | async function fetchBlobGcsResource(routeOrPath, config = {}) {
  function postGcsResource (line 403) | async function postGcsResource(routeOrPath, payload = {}, config = {}) {
  function putGcsResource (line 407) | async function putGcsResource(routeOrPath, payload = {}, config = {}) {
  function patchGcsResource (line 411) | async function patchGcsResource(routeOrPath, payload = {}, config = {}) {
  function deleteGcsResource (line 415) | async function deleteGcsResource(routeOrPath, config = {}) {
  function getAuthStatusResponse (line 419) | async function getAuthStatusResponse(config = {}) {
  function loginResponse (line 427) | async function loginResponse(payload, config = {}) {
  function logoutResponse (line 435) | async function logoutResponse(config = {}) {
  function changeOwnPasswordResponse (line 441) | async function changeOwnPasswordResponse(payload, config = {}) {
  function listAuthUsersResponse (line 445) | async function listAuthUsersResponse(config = {}) {
  function createAuthUserResponse (line 449) | async function createAuthUserResponse(payload, config = {}) {
  function updateAuthUserResponse (line 453) | async function updateAuthUserResponse(username, payload, config = {}) {
  function listAuthTokensResponse (line 457) | async function listAuthTokensResponse(config = {}) {
  function createAuthTokenResponse (line 461) | async function createAuthTokenResponse(payload, config = {}) {
  function revokeAuthTokenResponse (line 465) | async function revokeAuthTokenResponse(tokenId, config = {}) {
  function getFleetTelemetryResponse (line 469) | async function getFleetTelemetryResponse(config = {}) {
  function getFleetConfigResponse (line 473) | async function getFleetConfigResponse(config = {}) {
  function getFleetHeartbeatsResponse (line 477) | async function getFleetHeartbeatsResponse(config = {}) {
  function saveFleetConfigResponse (line 481) | async function saveFleetConfigResponse(payload, config = {}) {
  function validateFleetConfigResponse (line 485) | async function validateFleetConfigResponse(payload, config = {}) {
  function getSwarmConfigResponse (line 489) | async function getSwarmConfigResponse(config = {}) {
  function saveSwarmConfigResponse (line 493) | async function saveSwarmConfigResponse(payload, { commit = false, ...con...
  function getUnifiedGitStatusResponse (line 506) | async function getUnifiedGitStatusResponse(config = {}) {
  function normalizeCommandSubmitPayload (line 510) | function normalizeCommandSubmitPayload(payload = {}) {
  function submitCommandResponse (line 538) | async function submitCommandResponse(payload, config = {}) {
  function getCommandStatusResponse (line 542) | async function getCommandStatusResponse(commandId, config = {}) {
  function getRecentCommandsResponse (line 546) | async function getRecentCommandsResponse(
  function getActiveCommandsResponse (line 561) | async function getActiveCommandsResponse(config = {}) {
  function getPrecisionMovePolicyResponse (line 565) | async function getPrecisionMovePolicyResponse(config = {}) {
  function syncReposResponse (line 569) | async function syncReposResponse(payload = {}, config = {}) {
  function getConnectivityProfileResponse (line 573) | async function getConnectivityProfileResponse(config = {}) {
  function updateConnectivityProfileResponse (line 577) | async function updateConnectivityProfileResponse(payload = {}, config = ...
  function getOriginResponse (line 581) | async function getOriginResponse(config = {}) {
  function setOriginResponse (line 585) | async function setOriginResponse(payload, config = {}) {
  function getPositionDeviationsResponse (line 589) | async function getPositionDeviationsResponse(config = {}) {
  function getDronePositionsResponse (line 593) | async function getDronePositionsResponse(config = {}) {
  function getNetworkInfoResponse (line 597) | async function getNetworkInfoResponse(config = {}) {
  function getGcsConfigResponse (line 601) | async function getGcsConfigResponse(config = {}) {
  function saveGcsConfigResponse (line 605) | async function saveGcsConfigResponse(payload, config = {}) {
  function applyGcsConfigResponse (line 609) | async function applyGcsConfigResponse(config = {}) {
  function getEnvRegistryResponse (line 613) | async function getEnvRegistryResponse(config = {}) {
  function getGcsEnvResponse (line 617) | async function getGcsEnvResponse(config = {}) {
  function updateGcsEnvResponse (line 621) | async function updateGcsEnvResponse(payload = {}, config = {}) {
  function applyGcsEnvResponse (line 625) | async function applyGcsEnvResponse(config = {}) {
  function planFleetEnvResponse (line 629) | async function planFleetEnvResponse(payload = {}, config = {}) {
  function getFleetNodeEnvResponse (line 633) | async function getFleetNodeEnvResponse(hwId, config = {}) {
  function updateFleetNodeEnvResponse (line 637) | async function updateFleetNodeEnvResponse(hwId, payload = {}, config = {...
  function applyRuntimeUpdateResponse (line 641) | async function applyRuntimeUpdateResponse(config = {}) {
  function getRuntimeStatusResponse (line 645) | async function getRuntimeStatusResponse(config = {}) {
  function computeOriginResponse (line 649) | async function computeOriginResponse(payload, config = {}) {
  function getSwarmLeadersResponse (line 653) | async function getSwarmLeadersResponse(config = {}) {
  function getShowInfoResponse (line 657) | async function getShowInfoResponse(config = {}) {
  function getShowPlotsResponse (line 661) | async function getShowPlotsResponse(config = {}) {
  function getComprehensiveMetricsResponse (line 665) | async function getComprehensiveMetricsResponse(config = {}) {
  function getCustomShowInfoResponse (line 669) | async function getCustomShowInfoResponse(config = {}) {
  function importShowResponse (line 673) | async function importShowResponse(payload, config = {}) {
  function importCustomShowResponse (line 677) | async function importCustomShowResponse(payload, config = {}) {
  function getTrajectoryFirstRowResponse (line 681) | async function getTrajectoryFirstRowResponse(posId, config = {}) {
  function getSwarmTrajectoryStatusResponse (line 688) | async function getSwarmTrajectoryStatusResponse(config = {}) {
  function getSwarmTrajectoryPolicyResponse (line 692) | async function getSwarmTrajectoryPolicyResponse(config = {}) {
  function processSwarmTrajectoriesResponse (line 696) | async function processSwarmTrajectoriesResponse(payload = {}, config = {...
  function clearProcessedSwarmTrajectoriesResponse (line 700) | async function clearProcessedSwarmTrajectoriesResponse(config = {}) {

FILE: app/dashboard/drone-dashboard/src/services/px4ParamsApiService.js
  function buildPx4ParamsUrl (line 9) | function buildPx4ParamsUrl(suffix = '') {
  function getPx4ParamPolicy (line 13) | async function getPx4ParamPolicy() {
  function listPx4ParamProfiles (line 17) | async function listPx4ParamProfiles() {
  function getPx4ParamProfile (line 21) | async function getPx4ParamProfile(profileId) {
  function refreshPx4ParamSnapshots (line 25) | async function refreshPx4ParamSnapshots({ hwIds, componentId = 1 }) {
  function getPx4ParamSnapshot (line 32) | async function getPx4ParamSnapshot(snapshotId) {
  function getPx4ParamSnapshotRows (line 36) | async function getPx4ParamSnapshotRows(snapshotId) {
  function createPx4ParamPatchJob (line 40) | async function createPx4ParamPatchJob({
  function getPx4ParamPatchJob (line 54) | async function getPx4ParamPatchJob(jobId) {
  function importQgcParameterFile (line 58) | async function importQgcParameterFile(content) {
  function importMdsPatch (line 62) | async function importMdsPatch(content) {
  function diffPx4ParamSnapshot (line 66) | async function diffPx4ParamSnapshot({

FILE: app/dashboard/drone-dashboard/src/services/sarApiService.js
  function buildQueryString (line 15) | function buildQueryString(params = {}) {

FILE: app/dashboard/drone-dashboard/src/services/sitlControlService.js
  constant SITL_CONTROL_READ_TIMEOUT_MS (line 10) | const SITL_CONTROL_READ_TIMEOUT_MS = 10000;
  constant SITL_CONTROL_MUTATION_TIMEOUT_MS (line 11) | const SITL_CONTROL_MUTATION_TIMEOUT_MS = 30000;
  function withTimeout (line 13) | function withTimeout(config = {}, timeout) {
  function getSitlControlPolicy (line 20) | async function getSitlControlPolicy(config = {}) {
  function getSitlControlHost (line 25) | async function getSitlControlHost(config = {}) {
  function getSitlControlImages (line 30) | async function getSitlControlImages(config = {}) {
  function releaseSitlImage (line 35) | async function releaseSitlImage(payload, config = {}) {
  function getSitlControlInstances (line 40) | async function getSitlControlInstances(config = {}) {
  function runSitlInstanceAction (line 45) | async function runSitlInstanceAction(payload, config = {}) {
  function createSitlInstance (line 50) | async function createSitlInstance(payload, config = {}) {
  function reconcileSitlFleet (line 55) | async function reconcileSitlFleet(payload, config = {}) {
  function getSitlControlOperations (line 60) | async function getSitlControlOperations({ limit = 20, ...config } = {}) {
  function getSitlControlOperation (line 71) | async function getSitlControlOperation(operationId, config = {}) {
  function restartSitlInstance (line 77) | async function restartSitlInstance(instanceName, config = {}) {
  function removeSitlInstance (line 83) | async function removeSitlInstance(instanceName, config = {}) {
  function getSitlControlInstanceLogs (line 89) | async function getSitlControlInstanceLogs(instanceName, { tail = 200, .....

FILE: app/dashboard/drone-dashboard/src/setupTests.js
  method addListener (line 14) | addListener() {}
  method removeListener (line 15) | removeListener() {}
  method addEventListener (line 16) | addEventListener() {}
  method removeEventListener (line 17) | removeEventListener() {}
  method dispatchEvent (line 18) | dispatchEvent() { return false; }

FILE: app/dashboard/drone-dashboard/src/utilities/SpeedCalculator.js
  constant SPEED_THRESHOLDS (line 17) | const SPEED_THRESHOLDS = {
  constant YAW_CONSTANTS (line 32) | const YAW_CONSTANTS = {
  constant TIMING_MODES (line 38) | const TIMING_MODES = {
  constant ALTITUDE_REFERENCE (line 43) | const ALTITUDE_REFERENCE = {
  constant EARTH_RADIUS_M (line 48) | const EARTH_RADIUS_M = 6_371_000;
  constant TRAJECTORY_SEGMENT_COLORS (line 218) | const TRAJECTORY_SEGMENT_COLORS = Object.freeze({

FILE: app/dashboard/drone-dashboard/src/utilities/TrajectoryStateManager.js
  constant ACTION_TYPES (line 6) | const ACTION_TYPES = {
  class TrajectoryStateManager (line 25) | class TrajectoryStateManager {
    method constructor (line 26) | constructor(maxHistorySize = 50) {
    method getCurrentState (line 40) | getCurrentState() {
    method executeAction (line 47) | executeAction(actionType, payload, description = '') {
    method applyAction (line 66) | applyAction(actionType, payload) {
    method saveToUndoStack (line 125) | saveToUndoStack(actionType, description) {
    method undo (line 139) | undo() {
    method redo (line 166) | redo() {
    method canUndo (line 187) | canUndo() {
    method canRedo (line 194) | canRedo() {
    method getHistoryStatus (line 201) | getHistoryStatus() {
    method getActionHistory (line 219) | getActionHistory() {
    method clearHistory (line 237) | clearHistory() {
    method setInitialState (line 245) | setInitialState(state) {
    method createCheckpoint (line 253) | createCheckpoint(description = 'Checkpoint') {
    method optimizeStacks (line 261) | optimizeStacks() {
    method getDefaultDescription (line 274) | getDefaultDescription(actionType) {
    method deepClone (line 298) | deepClone(obj) {
    method validateState (line 324) | validateState(state = this.currentState) {
    method export (line 364) | export() {
    method import (line 377) | import(data) {

FILE: app/dashboard/drone-dashboard/src/utilities/TrajectoryStorage.js
  class TrajectoryStorage (line 20) | class TrajectoryStorage {
    method constructor (line 21) | constructor() {
    method saveTrajectory (line 31) | async saveTrajectory(name, waypoints, metadata = {}) {
    method loadTrajectory (line 101) | async loadTrajectory(identifier) {
    method getAllTrajectories (line 142) | getAllTrajectories() {
    method deleteTrajectory (line 154) | async deleteTrajectory(identifier) {
    method exportTrajectory (line 188) | async exportTrajectory(identifier, format = 'json') {
    method exportCurrentTrajectory (line 216) | async exportCurrentTrajectory(name, waypoints, format = 'json', metada...
    method buildPersistenceSignature (line 245) | buildPersistenceSignature(name, waypoints = []) {
    method importTrajectory (line 257) | async importTrajectory(file) {
    method autoSave (line 314) | async autoSave(waypoints, metadata = {}) {
    method createBackup (line 335) | async createBackup() {
    method getStorageStats (line 357) | getStorageStats() {
    method validateTrajectoryData (line 383) | validateTrajectoryData(trajectory) {
    method sanitizeWaypoints (line 419) | sanitizeWaypoints(waypoints) {
    method convertToCSV (line 448) | convertToCSV(waypoints) {
    method convertToKML (line 491) | convertToKML(trajectory) {
    method buildExportFile (line 519) | buildExportFile(trajectory, format = 'json') {
    method parseCSV (line 549) | parseCSV(content, filename) {
    method getStorageData (line 615) | getStorageData(key) {
    method setStorageData (line 624) | async setStorageData(key, data) {
    method handleStorageQuotaExceeded (line 639) | async handleStorageQuotaExceeded() {
    method updateTrajectory (line 651) | async updateTrajectory(trajectory) {
    method cleanupAutoSaves (line 667) | cleanupAutoSaves() {
    method cleanupBackups (line 685) | cleanupBackups(maxKeep = this.maxBackups) {
    method generateId (line 702) | generateId() {
    method formatBytes (line 709) | formatBytes(bytes) {
    method readFileContent (line 720) | readFileContent(file) {
    method downloadFile (line 732) | downloadFile(content, filename, mimeType) {

FILE: app/dashboard/drone-dashboard/src/utilities/commandExecutionPolicy.js
  constant STRICT_SYNC_MISSION_TYPES (line 3) | const STRICT_SYNC_MISSION_TYPES = new Set([
  constant STRICT_SYNC_ACTION_KEYS (line 9) | const STRICT_SYNC_ACTION_KEYS = new Set([
  constant SCHEDULABLE_ACTION_KEYS (line 13) | const SCHEDULABLE_ACTION_KEYS = new Set([

FILE: app/dashboard/drone-dashboard/src/utilities/commandLifecycleFeedback.js
  constant OVERRIDE_COMMANDS (line 7) | const OVERRIDE_COMMANDS = new Set([101, 102, 104, 105]);
  constant PERSISTENT_MISSION_TYPES (line 8) | const PERSISTENT_MISSION_TYPES = new Set([2]);
  constant TERMINAL_PHASE (line 9) | const TERMINAL_PHASE = 'terminal';
  constant POLL_INTERVAL_MS (line 10) | const POLL_INTERVAL_MS = 1500;
  constant MAX_POLL_ERRORS (line 11) | const MAX_POLL_ERRORS = 3;
  constant DEFAULT_TRACK_TIMEOUT_MS (line 12) | const DEFAULT_TRACK_TIMEOUT_MS = 120000;
  constant DEFAULT_PROGRESS_LABELS (line 13) | const DEFAULT_PROGRESS_LABELS = {
  function resolveTrackTimeoutMs (line 27) | function resolveTrackTimeoutMs(response, overrideTimeoutMs) {
  function normalizeMissionType (line 41) | function normalizeMissionType(missionType) {
  function titleCaseSegment (line 46) | function titleCaseSegment(segment) {
  function humanizeCommandToken (line 58) | function humanizeCommandToken(value) {
  function formatCommandLabel (line 76) | function formatCommandLabel(commandData, response) {
  function isPersistentMission (line 82) | function isPersistentMission(commandData = {}, response = null, status =...
  function getAcceptedCount (line 89) | function getAcceptedCount(response) {
  function getTargetCount (line 94) | function getTargetCount(response) {
  function getAckSummary (line 99) | function getAckSummary(response) {
  function isFutureTrigger (line 117) | function isFutureTrigger(triggerTime, referenceNowMs = Date.now()) {
  function formatTriggerTime (line 123) | function formatTriggerTime(triggerTime) {
  function normalizeTargetDrones (line 140) | function normalizeTargetDrones(commandData, response, status) {
  function buildInitialProgress (line 145) | function buildInitialProgress(commandData, response) {
  function buildLifecycleSnapshot (line 192) | function buildLifecycleSnapshot({
  function extractTriggerTime (line 276) | function extractTriggerTime(commandData = {}, status = null) {
  function buildLifecycleSnapshotFromStatus (line 286) | function buildLifecycleSnapshotFromStatus(status) {
  function buildSubmissionToastMessage (line 312) | function buildSubmissionToastMessage(commandData, response) {
  function buildTerminalSuffix (line 391) | function buildTerminalSuffix(status) {
  function buildTerminalToast (line 420) | function buildTerminalToast(status, commandLabel) {
  function buildProgressToast (line 458) | function buildProgressToast(status, commandLabel) {
  function stripUiMeta (line 480) | function stripUiMeta(commandData = {}) {
  function emitToast (line 485) | function emitToast(level, message) {
  function trackCommandLifecycle (line 491) | async function trackCommandLifecycle(commandId, commandLabel, initialPha...
  function submitCommandWithLifecycleFeedback (line 582) | async function submitCommandWithLifecycleFeedback(commandData, options =...

FILE: app/dashboard/drone-dashboard/src/utilities/commandScheduling.js
  constant COMMAND_SCHEDULE_MODES (line 3) | const COMMAND_SCHEDULE_MODES = {
  constant COMMAND_DELAY_PRESETS (line 9) | const COMMAND_DELAY_PRESETS = [10, 30, 60];
  constant CLOCK_OFFSET_WARNING_THRESHOLD_MS (line 10) | const CLOCK_OFFSET_WARNING_THRESHOLD_MS = 30_000;
  function pad (line 12) | function pad(value) {
  function formatDateTimeLocalInput (line 16) | function formatDateTimeLocalInput(dateLike) {
  function getFleetReferenceClock (line 25) | function getFleetReferenceClock(drones = [], nowMs = Date.now()) {
  function formatClockOffsetLabel (line 56) | function formatClockOffsetLabel(offsetMs = 0) {
  function formatCommandAbsoluteTime (line 65) | function formatCommandAbsoluteTime(unixSeconds) {
  function buildCommandSchedule (line 83) | function buildCommandSchedule({

FILE: app/dashboard/drone-dashboard/src/utilities/dronePresentation.js
  constant DRONE_SEARCH_PLACEHOLDER (line 5) | const DRONE_SEARCH_PLACEHOLDER = 'Search, P1|H1, pos 1-5, or hw 2,4';
  constant DRONE_SEARCH_HELP_TEXT (line 6) | const DRONE_SEARCH_HELP_TEXT = 'Try P1|H1, pos 1-5, hw 2,4, free text, o...
  function readField (line 8) | function readField(drone, key, fallback = '') {
  function normalizeToken (line 16) | function normalizeToken(value) {
  function toSearchTermList (line 20) | function toSearchTermList(values = []) {
  function isNumericToken (line 32) | function isNumericToken(value) {
  function matchesRangeToken (line 36) | function matchesRangeToken(candidate, token) {
  function buildDroneSearchSnapshot (line 59) | function buildDroneSearchSnapshot(drone, additionalTerms = []) {
  function parseStructuredDroneQuery (line 86) | function parseStructuredDroneQuery(rawQuery) {
  function matchesStructuredFilter (line 144) | function matchesStructuredFilter(snapshot, filter) {
  function getDroneOperatorAlias (line 173) | function getDroneOperatorAlias(drone) {
  function getDroneDisplayIdentity (line 185) | function getDroneDisplayIdentity(drone) {
  function matchesDroneSearchQuery (line 226) | function matchesDroneSearchQuery(drone, rawQuery, additionalTerms = []) {

FILE: app/dashboard/drone-dashboard/src/utilities/droneReadiness.js
  constant STATUS_LABELS (line 4) | const STATUS_LABELS = {
  constant READINESS_SNAPSHOT_GRACE_THRESHOLD_MS (line 10) | const READINESS_SNAPSHOT_GRACE_THRESHOLD_MS = 90_000;
  function normalizeMessages (line 12) | function normalizeMessages(messages) {
  function normalizeChecks (line 27) | function normalizeChecks(checks) {
  function dedupeMessages (line 42) | function dedupeMessages(messages) {
  function getAvailabilityGuard (line 55) | function getAvailabilityGuard(runtimeStatus, canUseLastSnapshot = false) {
  function hasFreshReadinessSnapshot (line 81) | function hasFreshReadinessSnapshot(drone, runtimeStatus) {
  function getDroneReadinessModel (line 95) | function getDroneReadinessModel(drone, runtimeStatus = null) {

FILE: app/dashboard/drone-dashboard/src/utilities/droneRuntimeStatus.js
  constant LIVE_TELEMETRY_THRESHOLD_MS (line 4) | const LIVE_TELEMETRY_THRESHOLD_MS = 10_000;
  constant HEARTBEAT_GRACE_THRESHOLD_MS (line 5) | const HEARTBEAT_GRACE_THRESHOLD_MS = 35_000;
  constant OFFLINE_CONFIRMED_THRESHOLD_MS (line 6) | const OFFLINE_CONFIRMED_THRESHOLD_MS = 60_000;
  constant CLIENT_CLOCK_SKEW_TOLERANCE_MS (line 7) | const CLIENT_CLOCK_SKEW_TOLERANCE_MS = 30_000;
  constant MS_PER_SECOND (line 8) | const MS_PER_SECOND = 1_000;
  constant UNIX_MS_THRESHOLD (line 9) | const UNIX_MS_THRESHOLD = 1_000_000_000_000;
  function normalizeTimestampMs (line 11) | function normalizeTimestampMs(value) {
  function toAgeSeconds (line 24) | function toAgeSeconds(nowMs, timestampMs) {
  function formatAge (line 32) | function formatAge(ageSeconds, label) {
  function formatClockOffset (line 40) | function formatClockOffset(offsetMs) {
  function getDroneReferenceNowMs (line 49) | function getDroneReferenceNowMs(drone, nowMs = Date.now()) {
  function getDroneRuntimeStatus (line 69) | function getDroneRuntimeStatus(drone, nowMs = Date.now()) {

FILE: app/dashboard/drone-dashboard/src/utilities/fleetOpsViewModel.js
  constant HEALTHY_VALUES (line 3) | const HEALTHY_VALUES = new Set(['healthy', 'active', 'running', 'synced'...
  constant WARNING_VALUES (line 4) | const WARNING_VALUES = new Set(['warning', 'degraded', 'unknown', 'inact...
  constant ERROR_VALUES (line 5) | const ERROR_VALUES = new Set(['error', 'failed', 'unhealthy']);
  function normalizeRuntimeMode (line 7) | function normalizeRuntimeMode(value) {
  function formatRuntimeMode (line 18) | function formatRuntimeMode(value) {
  function formatRepoAccessMode (line 29) | function formatRepoAccessMode(value) {
  function compactCommit (line 44) | function compactCommit(commit) {
  function compactHash (line 48) | function compactHash(hash) {
  function buildGitHubDocsUrl (line 56) | function buildGitHubDocsUrl(remoteUrl, branch, docPath) {
  function formatHashMatch (line 80) | function formatHashMatch(runtime) {
  function classifyTone (line 89) | function classifyTone(value) {
  function classifyRuntimeStepTone (line 103) | function classifyRuntimeStepTone(value) {
  function classifyNodePresence (line 114) | function classifyNodePresence(heartbeat, payloadTimestamp) {
  function isAttentionTone (line 205) | function isAttentionTone(tone) {
  function worstTone (line 209) | function worstTone(...tones) {
  function classifyGitSync (line 222) | function classifyGitSync(gitStatus, gcsStatus) {
  function classifyGitAuth (line 253) | function classifyGitAuth(gitStatus) {
  function classifyGitSyncRuntime (line 272) | function classifyGitSyncRuntime(gitSyncRuntime) {
  function classifyMavlinkRuntime (line 305) | function classifyMavlinkRuntime(runtime, runtimeMode = 'unknown') {
  function classifyConnectivityRuntime (line 348) | function classifyConnectivityRuntime(runtime, runtimeMode = 'unknown') {
  function rowNeedsAttention (line 390) | function rowNeedsAttention(row) {
  function rowHasComplianceDrift (line 400) | function rowHasComplianceDrift(row) {
  function normalizeHeartbeatMap (line 407) | function normalizeHeartbeatMap(heartbeatPayload) {
  function makeRow (line 418) | function makeRow(gitKey, gitStatus, heartbeat, gcsStatus, payloadTimesta...
  function buildFleetOpsViewModel (line 463) | function buildFleetOpsViewModel(gitPayload, heartbeatPayload) {

FILE: app/dashboard/drone-dashboard/src/utilities/globeScreenInteractions.js
  constant DEFAULT_GLOBE_ANCHOR_HIT_RADIUS_PX (line 1) | const DEFAULT_GLOBE_ANCHOR_HIT_RADIUS_PX = 70;
  function getEventClientPoint (line 3) | function getEventClientPoint(event) {
  function findNearestScreenAnchor (line 16) | function findNearestScreenAnchor(

FILE: app/dashboard/drone-dashboard/src/utilities/globeTelemetryViewModel.js
  constant LOW_LATENCY_INTERVAL_MS (line 7) | const LOW_LATENCY_INTERVAL_MS = 1000;
  constant MEDIUM_FLEET_INTERVAL_MS (line 8) | const MEDIUM_FLEET_INTERVAL_MS = 1500;
  constant LARGE_FLEET_INTERVAL_MS (line 9) | const LARGE_FLEET_INTERVAL_MS = 2500;
  constant BACKGROUND_INTERVAL_MS (line 10) | const BACKGROUND_INTERVAL_MS = 6000;
  constant CONSTRAINED_NETWORK_INTERVAL_MS (line 11) | const CONSTRAINED_NETWORK_INTERVAL_MS = 3000;
  function toFiniteNumber (line 13) | function toFiniteNumber(value, fallback = null) {
  function hasNonZeroCoordinate (line 18) | function hasNonZeroCoordinate(lat, lon) {
  function getConnectionProfile (line 24) | function getConnectionProfile() {
  function calculateGlobeTelemetryIntervalMs (line 32) | function calculateGlobeTelemetryIntervalMs(droneCount = 0, options = {}) {
  function buildGlobeDroneViewModels (line 59) | function buildGlobeDroneViewModels(telemetryPayload = {}, configPayload ...

FILE: app/dashboard/drone-dashboard/src/utilities/logViewerUtils.js
  constant SESSION_ID_PATTERN (line 1) | const SESSION_ID_PATTERN = /^s_(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2...

FILE: app/dashboard/drone-dashboard/src/utilities/missionConfigFields.js
  constant CORE_IDENTITY_FIELDS (line 6) | const CORE_IDENTITY_FIELDS = ['hw_id', 'pos_id'];
  constant CORE_CONNECTIVITY_FIELDS (line 7) | const CORE_CONNECTIVITY_FIELDS = ['ip', 'mavlink_port', 'serial_port', '...
  constant CORE_MISSION_CONFIG_FIELDS (line 8) | const CORE_MISSION_CONFIG_FIELDS = [
  constant TRANSIENT_MISSION_CONFIG_FIELDS (line 13) | const TRANSIENT_MISSION_CONFIG_FIELDS = [
  constant RESERVED_MISSION_CONFIG_FIELDS (line 20) | const RESERVED_MISSION_CONFIG_FIELDS = new Set([
  constant CUSTOM_FIELD_TYPES (line 25) | const CUSTOM_FIELD_TYPES = {
  constant CUSTOM_FIELD_TYPE_OPTIONS (line 33) | const CUSTOM_FIELD_TYPE_OPTIONS = [
  constant FIELD_LABEL_OVERRIDES (line 41) | const FIELD_LABEL_OVERRIDES = {
  constant PROMOTED_CUSTOM_FIELD_KEYS (line 55) | const PROMOTED_CUSTOM_FIELD_KEYS = ['callsign', 'display_name', 'nicknam...
  constant CUSTOM_FIELD_KEY_PATTERN (line 56) | const CUSTOM_FIELD_KEY_PATTERN = /^[a-z][a-z0-9_]*$/;
  constant HEX_COLOR_PATTERN (line 57) | const HEX_COLOR_PATTERN = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
  constant ACRONYM_WORDS (line 58) | const ACRONYM_WORDS = new Set(['id', 'ip', 'gps', 'gcs', 'mavlink', 'rtl...
  constant DEFAULT_MARKER_COLOR (line 60) | const DEFAULT_MARKER_COLOR = '#00d4ff';
  constant MISSION_CUSTOM_FIELD_TEMPLATES (line 62) | const MISSION_CUSTOM_FIELD_TEMPLATES = [
  constant CUSTOM_FIELD_TEMPLATE_OPTIONS (line 97) | const CUSTOM_FIELD_TEMPLATE_OPTIONS = [
  function nextCustomFieldDraftId (line 107) | function nextCustomFieldDraftId() {
  function humanizeMissionConfigFieldKey (line 112) | function humanizeMissionConfigFieldKey(key) {
  function normalizeMissionCustomFieldKey (line 143) | function normalizeMissionCustomFieldKey(value) {
  function getMissionCustomFieldTemplate (line 153) | function getMissionCustomFieldTemplate(key) {
  function inferMissionCustomFieldType (line 158) | function inferMissionCustomFieldType(value, key = '') {
  function isReservedMissionConfigField (line 179) | function isReservedMissionConfigField(key) {
  function formatMissionCustomFieldValue (line 183) | function formatMissionCustomFieldValue(value, type = inferMissionCustomF...
  function getPromotedFieldPriority (line 209) | function getPromotedFieldPriority(key) {
  function getMissionConfigCustomFields (line 215) | function getMissionConfigCustomFields(drone = {}) {
  function getPromotedMissionConfigField (line 249) | function getPromotedMissionConfigField(drone = {}) {
  function createMissionCustomFieldDraft (line 253) | function createMissionCustomFieldDraft(overrides = {}) {
  function createMissionCustomFieldDraftFromTemplate (line 263) | function createMissionCustomFieldDraftFromTemplate(templateKey, override...
  function coerceMissionCustomFieldValueForEditor (line 277) | function coerceMissionCustomFieldValueForEditor(type, value) {
  function buildMissionConfigFormState (line 316) | function buildMissionConfigFormState(drone = {}) {
  function parseMissionCustomFieldDraftValue (line 350) | function parseMissionCustomFieldDraftValue(field) {
  function serializeMissionConfigFormState (line 365) | function serializeMissionConfigFormState(formState = {}) {
  function validateMissionCustomFields (line 389) | function validateMissionCustomFields(customFields = []) {

FILE: app/dashboard/drone-dashboard/src/utilities/missionConfigUtilities.js
  constant CORE_FIELDS (line 13) | const CORE_FIELDS = ['hw_id', 'pos_id', 'ip', 'mavlink_port', 'serial_po...

FILE: app/dashboard/drone-dashboard/src/utilities/missionIdentityUtils.js
  constant INTEGER_PATTERN (line 1) | const INTEGER_PATTERN = /^\d+$/;
  constant POSITIVE_INTEGER_PATTERN (line 2) | const POSITIVE_INTEGER_PATTERN = /^[1-9]\d*$/;
  function toTrimmedString (line 4) | function toTrimmedString(value, fallback = '') {
  function normalizeComparableId (line 12) | function normalizeComparableId(value, fallback = '') {
  function formatDroneLabel (line 25) | function formatDroneLabel(value, fallback = 'Drone') {
  function formatShowSlotLabel (line 30) | function formatShowSlotLabel(value, fallback = 'Show Slot') {
  function formatCompactDroneIdentity (line 35) | function formatCompactDroneIdentity(posValue, hwValue, fallback = 'Unass...
  function getIdentityDoctrineCopy (line 54) | function getIdentityDoctrineCopy(surface = 'default') {
  function normalizeRuntimeIp (line 133) | function normalizeRuntimeIp(value) {
  function areGitRevisionsEquivalent (line 147) | function areGitRevisionsEquivalent(leftValue, rightValue) {
  function isPositiveIntegerId (line 164) | function isPositiveIntegerId(value) {
  function compareMissionIds (line 168) | function compareMissionIds(leftValue, rightValue) {
  function sortMissionIds (line 189) | function sortMissionIds(values = []) {
  function normalizeDroneConfigEntry (line 199) | function normalizeDroneConfigEntry(entry = {}) {
  function normalizeDroneConfigData (line 222) | function normalizeDroneConfigData(entries = []) {
  function buildSuggestedHwIds (line 232) | function buildSuggestedHwIds(configData = []) {
  function buildKnownPositionIds (line 253) | function buildKnownPositionIds(configData = [], extraIds = []) {
  function findDuplicatePositionAssignment (line 260) | function findDuplicatePositionAssignment(configData = [], currentHwId, c...
  function getDuplicateAssignments (line 276) | function getDuplicateAssignments(configData = []) {
  function getRoleSwaps (line 309) | function getRoleSwaps(configData = []) {
  function getHeartbeatTimestamp (line 317) | function getHeartbeatTimestamp(heartbeat) {
  function getOnlineDroneCount (line 322) | function getOnlineDroneCount(heartbeats = {}, staleThresholdSeconds = 20) {
  function toBackendConfigDrone (line 335) | function toBackendConfigDrone(drone = {}) {

FILE: app/dashboard/drone-dashboard/src/utilities/missionSlotStatus.js
  function formatSlotValue (line 3) | function formatSlotValue(value) {
  function buildSlotChip (line 7) | function buildSlotChip(label, value, tone = 'neutral') {
  function determineMissionSlotStatus (line 16) | function determineMissionSlotStatus(configPosId, assignedPosId, autoPosI...
  function buildMissionSlotStatusPresentation (line 60) | function buildMissionSlotStatusPresentation(configPosId, assignedPosId, ...

FILE: app/dashboard/drone-dashboard/src/utilities/missionUtils.js
  constant MISSION_INT_TO_NAME (line 10) | const MISSION_INT_TO_NAME = {
  constant MISSION_DISPLAY_NAMES (line 35) | const MISSION_DISPLAY_NAMES = {
  constant EMPTY_MISSION_NAMES (line 57) | const EMPTY_MISSION_NAMES = new Set(['NONE', 'N/A', '']);

FILE: app/dashboard/drone-dashboard/src/utilities/plotThemeColors.js
  constant CSS_VAR_REFERENCE_PATTERN (line 1) | const CSS_VAR_REFERENCE_PATTERN = /var\(\s*(--[A-Za-z0-9-_]+)\s*(?:,\s*(...

FILE: app/dashboard/drone-dashboard/src/utilities/px4ParameterFiles.js
  constant MAV_PARAM_TYPES (line 1) | const MAV_PARAM_TYPES = Object.freeze({
  function buildQgcParameterFile (line 6) | function buildQgcParameterFile(snapshotResponse) {

FILE: app/dashboard/drone-dashboard/src/utilities/px4ParameterProfiles.js
  function buildMdsParameterProfileFile (line 1) | function buildMdsParameterProfileFile(profile) {

FILE: app/dashboard/drone-dashboard/src/utilities/quickScoutLaunchReadiness.js
  function normalizeId (line 6) | function normalizeId(value) {
  function summarizeIssue (line 10) | function summarizeIssue(issueMap) {
  function buildQuickScoutLaunchReadiness (line 14) | function buildQuickScoutLaunchReadiness({

FILE: app/dashboard/drone-dashboard/src/utilities/quickScoutMissionPresentation.js
  function formatQuickScoutArea (line 3) | function formatQuickScoutArea(areaSqM) {
  function formatQuickScoutDuration (line 15) | function formatQuickScoutDuration(seconds) {
  function formatQuickScoutDistance (line 35) | function formatQuickScoutDistance(distanceM) {
  function getQuickScoutMissionTemplateLabel (line 47) | function getQuickScoutMissionTemplateLabel(missionTemplate) {
  function getQuickScoutMissionPhaseLabel (line 57) | function getQuickScoutMissionPhaseLabel(operationPhase) {
  function formatCoordinate (line 82) | function formatCoordinate(point) {
  function buildQuickScoutGeometrySummary (line 89) | function buildQuickScoutGeometrySummary({

FILE: app/dashboard/drone-dashboard/src/utilities/quickScoutPlanningSignature.js
  function normalizePoint (line 1) | function normalizePoint(point = {}) {
  function normalizeSurveyConfig (line 11) | function normalizeSurveyConfig(surveyConfig = {}) {
  function normalizeIds (line 35) | function normalizeIds(values = []) {
  function buildQuickScoutPlanningSignature (line 43) | function buildQuickScoutPlanningSignature({

FILE: app/dashboard/drone-dashboard/src/utilities/quickScoutProfiles.js
  constant QUICKSCOUT_PROFILE_PRESETS (line 1) | const QUICKSCOUT_PROFILE_PRESETS = [
  constant DEFAULT_QUICKSCOUT_PROFILE_ID (line 52) | const DEFAULT_QUICKSCOUT_PROFILE_ID = QUICKSCOUT_PROFILE_PRESETS[0].id;

FILE: app/dashboard/drone-dashboard/src/utilities/quickScoutSearchGeometry.js
  constant EARTH_RADIUS_M (line 5) | const EARTH_RADIUS_M = 6378137;
  function hasFiniteCoordinate (line 7) | function hasFiniteCoordinate(value) {
  function hasFiniteLatLng (line 14) | function hasFiniteLatLng(point) {
  function calculateCircularAreaSqM (line 18) | function calculateCircularAreaSqM(radiusM) {
  function normalizeSearchPath (line 26) | function normalizeSearchPath(path = []) {
  function calculateSearchPathLengthM (line 33) | function calculateSearchPathLengthM(path = []) {
  function buildLastKnownPointGeoJSON (line 59) | function buildLastKnownPointGeoJSON(center, radiusM, steps = 48) {
  function buildCorridorPathGeoJSON (line 102) | function buildCorridorPathGeoJSON(path = []) {
  function buildCorridorGeoJSON (line 125) | function buildCorridorGeoJSON(path = [], corridorWidthM) {
  function calculateCorridorAreaSqM (line 153) | function calculateCorridorAreaSqM(path = [], corridorWidthM) {

FILE: app/dashboard/drone-dashboard/src/utilities/smartSwarmLaunchReadiness.js
  constant SMART_SWARM_MIN_AIRBORNE_ALTITUDE_M (line 5) | const SMART_SWARM_MIN_AIRBORNE_ALTITUDE_M = 0.3;
  function normalizeId (line 7) | function normalizeId(value) {
  function isFiniteNumber (line 11) | function isFiniteNumber(value) {
  function buildScopedTargets (line 15) | function buildScopedTargets({ drones = [], targetMode = 'all', selectedD...
  function buildSmartSwarmLaunchReadiness (line 29) | function buildSmartSwarmLaunchReadiness({

FILE: app/dashboard/drone-dashboard/src/utilities/swarmDesignUtils.js
  constant TOP_LEADER_FOLLOW_VALUE (line 4) | const TOP_LEADER_FOLLOW_VALUE = '0';
  constant VALID_FRAMES (line 6) | const VALID_FRAMES = new Set(['ned', 'body']);
  constant ROLE_ORDER (line 7) | const ROLE_ORDER = {
  constant BLOCKING_WARNING_CODES (line 13) | const BLOCKING_WARNING_CODES = new Set([
  function normalizeNumericString (line 19) | function normalizeNumericString(value, fallback = '') {
  function normalizeOffset (line 32) | function normalizeOffset(value) {
  function sortIds (line 37) | function sortIds(leftId, rightId) {
  function createDefaultAssignment (line 41) | function createDefaultAssignment(hwId) {
  function normalizeConfigDrone (line 52) | function normalizeConfigDrone(entry = {}) {
  function normalizeSwarmAssignment (line 68) | function normalizeSwarmAssignment(entry = {}, fallbackHwId = '') {
  function assignmentToComparableString (line 87) | function assignmentToComparableString(assignment) {
  function buildFollowerMap (line 96) | function buildFollowerMap(assignments) {
  function detectCycleIds (line 121) | function detectCycleIds(assignmentMap) {
  function getClusterResolution (line 155) | function getClusterResolution(droneId, assignmentMap, cycleIds) {
  function getDepth (line 197) | function getDepth(drone, assignmentMap, cycleIds, depthCache) {
  function getRoleKey (line 213) | function getRoleKey(drone, followerMap) {
  function getRoleLabel (line 221) | function getRoleLabel(roleKey) {
  function getRoleSummary (line 233) | function getRoleSummary(roleKey, drone, directFollowers) {
  function getOffsetAxisLabels (line 249) | function getOffsetAxisLabels(frame) {
  function formatSignedOffset (line 269) | function formatSignedOffset(value) {
  function formatOffsetSummary (line 275) | function formatOffsetSummary(drone) {
  function compareDrones (line 284) | function compareDrones(leftDrone, rightDrone) {
  function buildSummary (line 298) | function buildSummary(drones, clusters) {
  function buildFollowOptions (line 335) | function buildFollowOptions(drones) {
  function buildWorkingSwarmAssignments (line 344) | function buildWorkingSwarmAssignments(configData = [], swarmData = []) {
  function getDirtyAssignmentIds (line 382) | function getDirtyAssignmentIds(currentAssignments = [], baselineAssignme...
  function buildSwarmViewModel (line 397) | function buildSwarmViewModel(assignments = [], configData = []) {
  function calculateClusterOffset (line 580) | function calculateClusterOffset(droneId, assignmentMap, visited = new Se...
  function calculateClusterPlotData (line 609) | function calculateClusterPlotData(assignments = [], configData = [], clu...
  function buildClusterScopeOptions (line 695) | function buildClusterScopeOptions(clusters = [], fallbackTotal = 0) {
  function filterClustersByScope (line 738) | function filterClustersByScope(clusters = [], scopeId = 'all') {
  function toSwarmApiPayload (line 750) | function toSwarmApiPayload(assignments = []) {

FILE: app/dashboard/drone-dashboard/src/utilities/swarmRuntimeUtils.js
  constant SWARM_RUNTIME_SCOPE (line 6) | const SWARM_RUNTIME_SCOPE = {
  constant SWARM_RUNTIME_ACTIONS (line 11) | const SWARM_RUNTIME_ACTIONS = {
  function getTargetIdSet (line 46) | function getTargetIdSet(targetIds = []) {
  function formatRuntimeTargetList (line 50) | function formatRuntimeTargetList(targetIds = []) {
  function formatScopeCountLabel (line 58) | function formatScopeCountLabel(label, count) {
  function resolveSwarmRuntimeTargets (line 62) | function resolveSwarmRuntimeTargets(
  function getSwarmRuntimeStartBlockerReason (line 117) | function getSwarmRuntimeStartBlockerReason({
  function getSwarmRuntimeTelemetrySummary (line 165) | function getSwarmRuntimeTelemetrySummary(targetIds = [], telemetryById =...
  function buildSwarmRuntimeCommand (line 208) | function buildSwarmRuntimeCommand(actionKey, targetIds = []) {

FILE: app/dashboard/drone-dashboard/src/utilities/swarmScopeUtils.js
  function buildNormalizedIdSet (line 6) | function buildNormalizedIdSet(values = []) {
  function buildNormalizedFollowMap (line 14) | function buildNormalizedFollowMap(followMap = {}) {
  function getClusterMemberIds (line 29) | function getClusterMemberIds(cluster = {}) {
  function buildLeaderChainSelectionIssues (line 38) | function buildLeaderChainSelectionIssues({ followMap = {}, activeIds = [...

FILE: app/dashboard/drone-dashboard/src/utilities/swarmTrajectoryLaunchReadiness.js
  function buildSelectionScope (line 19) | function buildSelectionScope(clusterStatus = {}, selectedDroneIds = []) {
  function formatSelectionIssues (line 53) | function formatSelectionIssues(selectionIssues = []) {
  function aggregatePackageStats (line 84) | function aggregatePackageStats(statsList = []) {
  function normalizePackageStats (line 133) | function normalizePackageStats(stats = null) {
  function getPackageDroneStat (line 150) | function getPackageDroneStat(packageDroneStats = {}, droneId) {

FILE: app/dashboard/drone-dashboard/src/utilities/swarmTrajectoryViewModel.js
  constant CLUSTER_STATE_META (line 1) | const CLUSTER_STATE_META = {
  constant CLUSTER_STATE_ALIASES (line 30) | const CLUSTER_STATE_ALIASES = {
  function normalizeClusterState (line 34) | function normalizeClusterState(state) {
  function getClusterStateMeta (line 38) | function getClusterStateMeta(cluster = {}) {
  function buildFallbackClusters (line 45) | function buildFallbackClusters({
  function buildSwarmTrajectoryViewModel (line 79) | function buildSwarmTrajectoryViewModel({

FILE: app/dashboard/drone-dashboard/src/utilities/swarmTrajectoryWorkspaceModel.js
  function buildSwarmTrajectoryWorkspaceStatus (line 14) | function buildSwarmTrajectoryWorkspaceStatus({ viewModel, recommendation...
  function buildSwarmTrajectoryStages (line 102) | function buildSwarmTrajectoryStages({ viewModel, recommendation, hasProc...

FILE: app/dashboard/drone-dashboard/src/utilities/toastFeedback.js
  function toastThrottled (line 5) | function toastThrottled(level, key, message, options = {}) {
  function toastErrorThrottled (line 30) | function toastErrorThrottled(key, message, options = {}) {
  function toastWarningThrottled (line 34) | function toastWarningThrottled(key, message, options = {}) {
  function toastInfoThrottled (line 38) | function toastInfoThrottled(key, message, options = {}) {
  function clearThrottledToast (line 42) | function clearThrottledToast(key) {

FILE: app/dashboard/drone-dashboard/src/utilities/utilities.js
  function getTelemetryURL (line 14) | function getTelemetryURL() {
  function getElevationURL (line 18) | function getElevationURL(lat, lon) {
  function getCustomShowImageURL (line 27) | function getCustomShowImageURL() {
  constant LAT_TO_METERS (line 32) | const LAT_TO_METERS = 111321;
  constant LON_TO_METERS (line 33) | const LON_TO_METERS = 111321;
  constant WORLD_SIZE (line 34) | const WORLD_SIZE = 400;
  constant TEXTURE_REPEAT (line 35) | const TEXTURE_REPEAT = 10;
  constant POLLING_RATE_HZ (line 38) | const POLLING_RATE_HZ = 1;
  constant STALE_DATA_THRESHOLD_SECONDS (line 39) | const STALE_DATA_THRESHOLD_SECONDS = 5;
  function _snapElev (line 46) | function _snapElev(v) { return Math.round(v / _ELEV_GRID) * _ELEV_GRID; }
  function _elevKey (line 47) | function _elevKey(lat, lon) { return `${_snapElev(lat).toFixed(4)},${_sn...

FILE: app/dashboard/drone-dashboard/src/version.js
  constant DEFAULT_VERSION (line 13) | const DEFAULT_VERSION = '5.3';
  constant DEFAULT_GIT_COMMIT (line 14) | const DEFAULT_GIT_COMMIT = '9c300006';
  constant DEFAULT_GIT_BRANCH (line 15) | const DEFAULT_GIT_BRANCH = 'main';
  constant DEFAULT_GIT_REPO (line 16) | const DEFAULT_GIT_REPO = 'alireza787b/mavsdk_drone_show';
  constant VERSION (line 18) | const VERSION = process.env.REACT_APP_VERSION || DEFAULT_VERSION;
  constant GIT_COMMIT (line 19) | const GIT_COMMIT = process.env.REACT_APP_GIT_COMMIT || DEFAULT_GIT_COMMIT;
  constant GIT_BRANCH (line 20) | const GIT_BRANCH = process.env.REACT_APP_GIT_BRANCH || DEFAULT_GIT_BRANCH;
  constant GIT_REPO (line 21) | const GIT_REPO = process.env.REACT_APP_GIT_REPO || DEFAULT_GIT_REPO;
  constant VERSION_DISPLAY (line 22) | const VERSION_DISPLAY = `v${VERSION}`;
  constant VERSION_META_DISPLAY (line 23) | const VERSION_META_DISPLAY = `${GIT_BRANCH} • ${GIT_REPO}`;

FILE: coordinator.py
  class StartupState (line 58) | class StartupState(Enum):
  class StartupError (line 72) | class StartupError(Exception):
  function safe_init (line 81) | def safe_init(
  function validate_startup_prerequisites (line 125) | def validate_startup_prerequisites() -> bool:
  function schedule_missions_thread (line 189) | def schedule_missions_thread(drone_setup_instance):
  function schedule_missions_async (line 196) | async def schedule_missions_async(drone_setup_instance):
  function main_loop (line 249) | def main_loop():
  function main (line 360) | def main():

FILE: drone_show.py
  function str2bool (line 168) | def str2bool(v):
  function blender_north_west_up_to_ned (line 191) | def blender_north_west_up_to_ned(x_b, y_b, z_b=0.0):
  function read_config (line 216) | def read_config(filename: str) -> Drone:
  function extract_initial_positions (line 290) | def extract_initial_positions(first_waypoint: dict) -> tuple:
  function adjust_waypoints (line 315) | def adjust_waypoints(
  function get_current_ned_position (line 366) | async def get_current_ned_position(drone: System) -> PositionNedYaw:
  function read_trajectory_file (line 423) | def read_trajectory_file(
  function perform_trajectory (line 598) | async def perform_trajectory(
  function controlled_landing (line 997) | async def controlled_landing(drone: System):
  function wait_for_landing (line 1057) | async def wait_for_landing(drone: System):
  function initial_setup_and_connection (line 1081) | async def initial_setup_and_connection():
  function fetch_origin_with_fallback (line 1137) | async def fetch_origin_with_fallback(drone: System):
  function validate_drone_position (line 1294) | async def validate_drone_position(drone: System, origin: dict, config: d...
  function pre_flight_checks (line 1374) | async def pre_flight_checks(drone: System, require_global_position: bool):
  function arming_and_starting_offboard_mode (line 1465) | async def arming_and_starting_offboard_mode(drone: System, home_position...
  function compute_position_drift (line 1550) | async def compute_position_drift():
  function perform_landing (line 1594) | async def perform_landing(drone: System):
  function stop_offboard_mode (line 1623) | async def stop_offboard_mode(drone: System):
  function disarm_drone (line 1640) | async def disarm_drone(drone: System):
  function get_mavsdk_server_path (line 1666) | def get_mavsdk_server_path():
  function start_mavsdk_server (line 1677) | def start_mavsdk_server(udp_port: int):
  function check_mavsdk_server_running (line 1750) | def check_mavsdk_server_running(port):
  function wait_for_port (line 1771) | def wait_for_port(port, host="localhost", timeout=Params.PRE_FLIGHT_TIME...
  function log_mavsdk_output (line 1794) | async def log_mavsdk_output(mavsdk_server):
  function stop_mavsdk_server (line 1821) | def stop_mavsdk_server(mavsdk_server):
  function run_drone (line 1852) | async def run_drone(synchronized_start_time, custom_csv=None, auto_launc...
  function main (line 2182) | def main():

FILE: drone_show_src/utils.py
  function calculate_ned_origin (line 16) | def calculate_ned_origin(current_gps, ned_position):
  function read_hw_id (line 40) | def read_hw_id():
  function clamp_led_value (line 46) | def clamp_led_value(value):
  function get_expected_position_from_trajectory (line 64) | def get_expected_position_from_trajectory(pos_id, sim_mode=False):
  function global_to_local (line 136) | def global_to_local(global_position, home_position):
  function pre_flight_checks (line 174) | async def pre_flight_checks(drone: System):

FILE: functions/circle.py
  function generate_circle (line 6) | def generate_circle(params: CircleParameters):

FILE: functions/create_active_csv.py
  function takeoff_and_initial_climb (line 84) | def takeoff_and_initial_climb(initial_altitude, climb_rate, step_time, w...
  function hold_position (line 126) | def hold_position(hold_time, step_time, writer, last_time, last_step, la...
  function move_to (line 161) | def move_to(target_coordinates, move_speed, step_time, writer, last_time...
  function move_to_maneuver_start (line 211) | def move_to_maneuver_start(shape_fcn, maneuver_time, diameter, direction...
  function perform_maneuver (line 266) | def perform_maneuver(shape_fcn, maneuver_time, diameter, direction, init...
  function repeat_maneuver (line 306) | def repeat_maneuver(num_repeats, shape_fcn, maneuver_time, diameter, dir...
  function create_active_csv (line 347) | def create_active_csv(shape_name,num_repeats, diameter, direction, maneu...

FILE: functions/data_utils.py
  function safe_int (line 4) | def safe_int(value, default=0):
  function safe_float (line 13) | def safe_float(value, default=0.0):
  function safe_get (line 24) | def safe_get(dct, key, default=None):

FILE: functions/drone_show_metrics.py
  class DroneShowMetrics (line 12) | class DroneShowMetrics:
    method __init__ (line 21) | def __init__(self, processed_dir: str):
    method load_drone_data (line 27) | def load_drone_data(self) -> bool:
    method calculate_comprehensive_metrics (line 47) | def calculate_comprehensive_metrics(self) -> Dict:
    method calculate_basic_metrics (line 67) | def calculate_basic_metrics(self) -> Dict:
    method calculate_safety_metrics (line 240) | def calculate_safety_metrics(self) -> Dict:
    method calculate_performance_metrics (line 341) | def calculate_performance_metrics(self) -> Dict:
    method calculate_formation_metrics (line 411) | def calculate_formation_metrics(self) -> Dict:
    method calculate_quality_metrics (line 458) | def calculate_quality_metrics(self) -> Dict:
    method _generate_recommendations (line 501) | def _generate_recommendations(self, quality_score: float, smoothness: ...
    method save_metrics_to_file (line 514) | def save_metrics_to_file(self, metrics: Dict, filename: str = 'compreh...

FILE: functions/export_and_plot_shape.py
  function export_and_plot_shape (line 7) | def export_and_plot_shape(output_file):

FILE: functions/file_management.py
  function setup_logging (line 10) | def setup_logging():
  function ensure_directory_exists (line 20) | def ensure_directory_exists(directory):
  function clear_directory (line 26) | def clear_directory(directory):
  function copy_files (line 40) | def copy_files(source_dir, dest_dir):

FILE: functions/file_utils.py
  function load_csv (line 29) | def load_csv(file_path: str) -> List[Dict[str, Any]]:
  function save_csv (line 71) | def save_csv(
  function validate_csv_schema (line 125) | def validate_csv_schema(
  function load_json (line 158) | def load_json(file_path: str) -> Any:
  function save_json (line 175) | def save_json(data: Any, file_path: str, indent: int = 2) -> bool:
  function load_trajectory_csv (line 192) | def load_trajectory_csv(file_path: str) -> List[Dict[str, float]]:
  function get_trajectory_duration (line 228) | def get_trajectory_duration(waypoints: List[Dict[str, float]]) -> float:
  function get_trajectory_first_position (line 245) | def get_trajectory_first_position(file_path: str) -> Optional[Dict[str, ...

FILE: functions/git_manager.py
  function normalize_branch_name (line 33) | def normalize_branch_name(raw_branch: Optional[str]) -> str:
  function resolve_current_git_branch (line 49) | def resolve_current_git_branch(
  function filter_git_status_lines (line 98) | def filter_git_status_lines(status_lines: list[str]) -> list[str]:
  function parse_filtered_git_status (line 115) | def parse_filtered_git_status(status_output: Optional[str]) -> list[str]:
  function get_tracking_branch_sync_counts (line 122) | def get_tracking_branch_sync_counts(
  function describe_repo_access_mode (line 158) | def describe_repo_access_mode(
  function build_read_only_git_auth_health (line 175) | def build_read_only_git_auth_health(
  function execute_git_command (line 229) | def execute_git_command(command: list, cwd: Optional[str] = None) -> Opt...
  function get_local_git_report (line 255) | def get_local_git_report(repo_path: Optional[str] = None) -> Dict[str, A...
  function get_local_git_short_status (line 366) | def get_local_git_short_status(repo_path: Optional[str] = None) -> Dict[...
  function get_remote_git_status (line 402) | def get_remote_git_status(
  function compare_git_status (line 445) | def compare_git_status(local_status: Dict, remote_status: Dict) -> Dict[...

FILE: functions/global_to_local.py
  function global_to_local (line 4) | def global_to_local(global_position, home_position):

FILE: functions/plot_drone_paths.py
  function setup_matplotlib_style (line 11) | def setup_matplotlib_style():
  function extract_drone_id (line 27) | def extract_drone_id(filename: str) -> str:
  function compute_plot_limits (line 33) | def compute_plot_limits(data_list: List[pd.DataFrame]) -> Tuple[float, f...
  function plot_drone_paths (line 76) | def plot_drone_paths(

FILE: functions/process_drone_files.py
  function validate_drone_data (line 11) | def validate_drone_data(df: pd.DataFrame) -> bool:
  function smooth_trajectory (line 25) | def smooth_trajectory(data: np.ndarray, window_length: int = 11, poly_or...
  function build_output_time_vector (line 46) | def build_output_time_vector(t_end: float, dt: float) -> np.ndarray:
  function _build_interpolator (line 65) | def _build_interpolator(method: str, t_original: np.ndarray, values: pd....
  function process_drone_files (line 83) | def process_drone_files(

FILE: functions/seven_segment.py
  function generate_seven_segment (line 7) | def generate_seven_segment(params: SevenSegmentParameters):
  function generate_segment (line 47) | def generate_segment(segment_id, drones_per_segment, params):

FILE: functions/shapeParameters.py
  class ShapeParameters (line 5) | class ShapeParameters:
  class CircleParameters (line 20) | class CircleParameters(ShapeParameters):
  class SevenSegmentParameters (line 25) | class SevenSegmentParameters(ShapeParameters):

FILE: functions/shape_functions.py
  function rotate (line 8) | def rotate(points, heading):
  function closest_drones (line 32) | def closest_drones(points):
  function check_collision (line 50) | def check_collision(points,treshhold=0.5):

FILE: functions/shape_plots.py
  function plot_points (line 7) | def plot_points(points, viewer_position):
  function plot_2d_observer (line 85) | def plot_2d_observer(points, heading, plane):

FILE: functions/show_static_shape_results.py
  function show_static_shape_results (line 7) | def show_static_shape_results(points, params):

FILE: functions/swarm_analyzer.py
  function _validate_follow_chains (line 14) | def _validate_follow_chains(swarm_df):
  function get_backend_url (line 35) | def get_backend_url():
  function fetch_swarm_data (line 39) | def fetch_swarm_data():
  function analyze_swarm_structure (line 71) | def analyze_swarm_structure(swarm_data=None):
  function get_all_followers (line 126) | def get_all_followers(leader_id, swarm_df, lineage=None):
  function get_drone_config (line 143) | def get_drone_config(hw_id, swarm_config):
  function find_ultimate_leader (line 149) | def find_ultimate_leader(hw_id, swarm_df=None):

FILE: functions/swarm_global_calculator.py
  function calculate_follower_global_position (line 12) | def calculate_follower_global_position(leader_lat, leader_lon, leader_al...
  function calculate_follower_yaw (line 61) | def calculate_follower_yaw(leader_yaw, offset_config):

FILE: functions/swarm_kml_generator.py
  function generate_kml_for_drone (line 14) | def generate_kml_for_drone(drone_id: int, trajectory_df: pd.DataFrame, o...
  function _add_drone_styles (line 66) | def _add_drone_styles(document: Element, drone_id: int):
  function _add_animated_trajectory (line 99) | def _add_animated_trajectory(document: Element, drone_id: int, trajector...
  function _add_static_path (line 156) | def _add_static_path(document: Element, drone_id: int, trajectory_df: pd...
  function generate_cluster_kml (line 201) | def generate_cluster_kml(cluster_leader_id: int, cluster_drones: list, p...
  function _add_cluster_styles (line 286) | def _add_cluster_styles(document: Element, cluster_drones: list, leader_...
  function _add_cluster_animated_trajectory (line 345) | def _add_cluster_animated_trajectory(folder: Element, drone_id: int, tra...
  function _add_cluster_static_path (line 401) | def _add_cluster_static_path(folder: Element, drone_id: int, trajectory_...
  function _add_cluster_overview (line 448) | def _add_cluster_overview(document: Element, cluster_trajectories: dict,...
  function _calculate_path_distance (line 498) | def _calculate_path_distance(trajectory_df: pd.DataFrame) -> float:
  function generate_swarm_kml (line 522) | def generate_swarm_kml(processed_dir: str, plots_dir: str) -> dict:

FILE: functions/swarm_plotter.py
  function generate_swarm_plots (line 17) | def generate_swarm_plots(all_trajectories, swarm_structure, plots_dir):
  function plot_single_drone (line 59) | def plot_single_drone(hw_id, trajectory, plots_dir):
  function plot_cluster (line 102) | def plot_cluster(leader_id, cluster_trajectories, plots_dir):
  function plot_combined_swarm (line 148) | def plot_combined_swarm(all_trajectories, plots_dir):

FILE: functions/swarm_session_manager.py
  class ProcessingSession (line 20) | class ProcessingSession:
  class SwarmSessionManager (line 30) | class SwarmSessionManager:
    method __init__ (line 33) | def __init__(self):
    method generate_swarm_fingerprint (line 37) | def generate_swarm_fingerprint(self) -> str:
    method generate_parameters_hash (line 63) | def generate_parameters_hash(self) -> str:
    method generate_raw_inputs_hash (line 84) | def generate_raw_inputs_hash(self) -> str:
    method get_current_session (line 118) | def get_current_session(self) -> Optional[ProcessingSession]:
    method save_session (line 132) | def save_session(self, session: ProcessingSession):
    method get_uploaded_leaders (line 143) | def get_uploaded_leaders(self) -> List[int]:
    method get_expected_top_leaders (line 166) | def get_expected_top_leaders(self) -> List[int]:
    method detect_changes (line 182) | def detect_changes(self) -> Dict[str, Any]:
    method create_processing_session (line 244) | def create_processing_session(self, processed_leaders: List[int], tota...
    method clear_session (line 262) | def clear_session(self):
    method get_processing_recommendation (line 271) | def get_processing_recommendation(self) -> Dict[str, Any]:

FILE: functions/swarm_trajectory_processor.py
  function load_leader_trajectories (line 21) | def load_leader_trajectories(raw_dir: str, top_leaders: list) -> Dict[in...
  function calculate_follower_trajectory (line 60) | def calculate_follower_trajectory(leader_trajectory: pd.DataFrame, drone...
  function _normalize_swarm_dataframe (line 92) | def _normalize_swarm_dataframe(swarm_data: List[Dict[str, Any]]) -> pd.D...
  function _resolve_drone_trajectory (line 109) | def _resolve_drone_trajectory(
  function save_drone_trajectory (line 166) | def save_drone_trajectory(hw_id: int, trajectory: pd.DataFrame, processe...
  function clear_processed_data (line 177) | def clear_processed_data(force_clear: bool = False) -> Dict[str, Any]:
  function auto_reload_missing_leaders (line 220) | def auto_reload_missing_leaders(uploaded_leaders: List[int]) -> List[int]:
  function get_processing_recommendation (line 248) | def get_processing_recommendation() -> Dict[str, Any]:
  function process_swarm_trajectories (line 253) | def process_swarm_trajectories(force_clear: bool = False, auto_reload: b...
  function _execute_trajectory_processing (line 319) | def _execute_trajectory_processing(

FILE: functions/swarm_trajectory_service.py
  class SwarmTrajectoryError (line 31) | class SwarmTrajectoryError(Exception):
    method __init__ (line 34) | def __init__(self, message: str, status_code: int = 400):
  function _processing_failure_status_code (line 40) | def _processing_failure_status_code(result: Dict) -> int:
  function _load_swarm_structure (line 53) | def _load_swarm_structure() -> Dict:
  function _collect_drone_ids (line 58) | def _collect_drone_ids(directory: str) -> List[int]:
  function _remove_file (line 75) | def _remove_file(path: Path, removed_files: List[str], label: str) -> bool:
  function _clear_current_session (line 84) | def _clear_current_session() -> None:
  function _clear_session_file (line 88) | def _clear_session_file(session_file: Path, cleared_items: List[str]) ->...
  function _build_follow_map (line 94) | def _build_follow_map(structure: Dict) -> Dict[int, int]:
  function _build_empty_package_stats (line 108) | def _build_empty_package_stats() -> Dict:
  function _round_metric (line 122) | def _round_metric(value: Optional[float]) -> Optional[float]:
  function _collect_processed_package_drone_stats (line 128) | def _collect_processed_package_drone_stats(processed_dir: Path, drone_id...
  function _aggregate_package_stats_from_drone_stats (line 173) | def _aggregate_package_stats_from_drone_stats(drone_stats: Dict[int, Dic...
  function validate_target_scope_for_swarm_trajectory (line 209) | def validate_target_scope_for_swarm_trajectory(
  function _build_cluster_status (line 280) | def _build_cluster_status(
  function get_swarm_leaders_payload (line 377) | def get_swarm_leaders_payload() -> Dict:
  function save_uploaded_trajectory (line 397) | def save_uploaded_trajectory(leader_id: int, filename: str, content: byt...
  function process_trajectories_payload (line 423) | def process_trajectories_payload(force_clear: bool = False, auto_reload:...
  function get_processing_recommendation_payload (line 434) | def get_processing_recommendation_payload() -> Dict:
  function get_processing_status_payload (line 442) | def get_processing_status_payload() -> Dict:
  function clear_processed_payload (line 535) | def clear_processed_payload() -> Dict:
  function clear_all_payload (line 546) | def clear_all_payload() -> Dict:
  function remove_leader_trajectory_payload (line 597) | def remove_leader_trajectory_payload(leader_id: int) -> Dict:
  function clear_leader_trajectory_payload (line 650) | def clear_leader_trajectory_payload(leader_id: int) -> Dict:
  function get_processed_trajectory_download (line 659) | def get_processed_trajectory_download(drone_id: int) -> Tuple[str, str]:
  function get_drone_kml_download (line 669) | def get_drone_kml_download(drone_id: int) -> Tuple[bytes, str]:
  function get_cluster_kml_download (line 691) | def get_cluster_kml_download(leader_id: int) -> Tuple[bytes, str]:
  function clear_individual_drone_payload (line 718) | def clear_individual_drone_payload(drone_id: int) -> Dict:
  function commit_trajectory_changes_payload (line 784) | def commit_trajectory_changes_payload(commit_message: str | None = None)...

FILE: functions/swarm_trajectory_smoother.py
  function _build_local_metric_transformers (line 16) | def _build_local_metric_transformers(origin_lat, origin_lon):
  function smooth_trajectory_with_waypoints (line 28) | def smooth_trajectory_with_waypoints(waypoints_df, dt=None):
  function calculate_ned_velocities (line 113) | def calculate_ned_velocities(times, lats, lons, alts):
  function calculate_ned_accelerations (line 125) | def calculate_ned_accelerations(times, velocities):
  function create_trajectory_dataframe (line 133) | def create_trajectory_dataframe(times, lats, lons, alts, yaws, velocitie...
  function create_flyover_splines (line 159) | def create_flyover_splines(times, lats, lons, alts, yaws, curve_tightness):
  function create_flyby_splines (line 205) | def create_flyby_splines(times, lats, lons, alts, yaws, acceptance_radiu...
  function create_straight_line_trajectory (line 242) | def create_straight_line_trajectory(all_times, waypoint_times, lats, lon...
  function calculate_dynamic_acceptance_radius (line 272) | def calculate_dynamic_acceptance_radius(base_radius, current_speed, spee...

FILE: functions/swarm_trajectory_utils.py
  function get_project_root (line 11) | def get_project_root(base_dir=None):
  function get_swarm_trajectory_folders (line 19) | def get_swarm_trajectory_folders(sim_mode=None, base_dir=None):

FILE: functions/trajectories.py
  function map_shape_to_code (line 5) | def map_shape_to_code(shape_name):
  function sine_wave_trajectory (line 42) | def sine_wave_trajectory(step, maneuver_time, diameter, direction, initi...
  function infinity_shape_trajectory (line 63) | def infinity_shape_trajectory(step, maneuver_time, diameter, direction, ...
  function spiral_square_trajectory (line 82) | def spiral_square_trajectory(step, maneuver_time, diameter, direction, i...
  function star_shape_trajectory (line 101) | def star_shape_trajectory(step, maneuver_time, diameter, direction, init...
  function zigzag_trajectory (line 121) | def zigzag_trajectory(step, maneuver_time, diameter, direction, initial_...
  function heart_shape_trajectory (line 139) | def heart_shape_trajectory(step, maneuver_time, diameter, direction, ini...
  function stationary_trajectory (line 161) | def stationary_trajectory(step, maneuver_time, diameter, direction, init...
  function helix_trajectory (line 182) | def helix_trajectory(step, maneuver_time, diameter, direction, initial_a...
  function eight_shape_trajectory (line 203) | def eight_shape_trajectory(step, maneuver_time, diameter, direction,init...
  function circle_trajectory (line 222) | def circle_trajectory(step, maneuver_time, diameter, direction, initial_...
  function square_trajectory (line 240) | def square_trajectory(step, maneuver_time, diameter, direction, initial_...

FILE: gcs-server/api_errors.py
  function _error_title (line 41) | def _error_title(status_code: int) -> str:
  function build_error_payload (line 50) | def build_error_payload(
  function normalize_validation_errors (line 65) | def normalize_validation_errors(exc: RequestValidationError) -> list[dic...

FILE: gcs-server/api_routes/auth.py
  class LoginRequest (line 19) | class LoginRequest(BaseModel):
  class UserCreateRequest (line 24) | class UserCreateRequest(BaseModel):
  class UserUpdateRequest (line 32) | class UserUpdateRequest(BaseModel):
  class PasswordChangeRequest (line 39) | class PasswordChangeRequest(BaseModel):
  class TokenCreateRequest (line 44) | class TokenCreateRequest(BaseModel):
  function _current_auth (line 51) | def _current_auth(request: Request) -> dict[str, Any]:
  function _require_admin (line 55) | def _require_admin(request: Request) -> dict[str, Any]:
  function _cookie_options (line 62) | def _cookie_options(service) -> dict[str, Any]:
  function _csrf_cookie_options (line 72) | def _csrf_cookie_options(service) -> dict[str, Any]:
  function _status_payload (line 82) | def _status_payload(request: Request) -> dict[str, Any]:
  function create_auth_router (line 104) | def create_auth_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/commands.py
  function _build_precision_move_policy_payload (line 30) | def _build_precision_move_policy_payload(params: Any) -> dict[str, Any]:
  function create_command_router (line 66) | def create_command_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/configuration.py
  function _canonical_profile_bytes (line 25) | def _canonical_profile_bytes(profile: dict[str, Any]) -> bytes:
  function _profile_hash (line 29) | def _profile_hash(profile: dict[str, Any]) -> str:
  function _summarize_connectivity_profile (line 33) | def _summarize_connectivity_profile(profile: dict[str, Any]) -> dict[str...
  function _connectivity_profile_target (line 44) | def _connectivity_profile_target(deps: Any) -> tuple[Path, str, bool]:
  function _validate_connectivity_profile (line 61) | def _validate_connectivity_profile(profile: dict[str, Any]) -> None:
  function _read_connectivity_profile_status (line 80) | def _read_connectivity_profile_status(deps: Any, message: str | None = N...
  function _write_connectivity_profile (line 122) | def _write_connectivity_profile(path: Path, profile: dict[str, Any]) -> ...
  function _get_trajectory_start_position_payload (line 129) | def _get_trajectory_start_position_payload(deps: Any, pos_id: int) -> di...
  function create_configuration_router (line 144) | def create_configuration_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/core.py
  function _build_health_check_response (line 27) | def _build_health_check_response(deps: Any) -> HealthCheckResponse:
  function _build_typed_telemetry_response (line 36) | def _build_typed_telemetry_response(deps: Any, response: Response | None...
  function _build_heartbeat_response (line 53) | def _build_heartbeat_response(deps: Any) -> HeartbeatResponse:
  function _build_network_status_response (line 123) | def _build_network_status_response(deps: Any) -> NetworkStatusResponse:
  function _accept_heartbeat (line 140) | def _accept_heartbeat(deps: Any, heartbeat: HeartbeatRequest, request: R...
  function create_core_router (line 181) | def create_core_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/fleet_candidates.py
  function _translate_candidate_error (line 41) | def _translate_candidate_error(exc: Exception) -> HTTPException:
  function _build_list_response (line 51) | def _build_list_response(candidates: list[FleetCandidateRecord], *, runt...
  function _resolve_candidate_runtime_filter (line 69) | def _resolve_candidate_runtime_filter(runtime_mode: str | None) -> tuple...
  function _build_post_sync_plan (line 81) | def _build_post_sync_plan(
  function _build_mutation_response (line 136) | def _build_mutation_response(
  function create_fleet_candidates_router (line 162) | def create_fleet_candidates_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/git_status.py
  function _safe_int (line 27) | def _safe_int(value: Any, default: int = 0) -> int:
  function _safe_string_list (line 34) | def _safe_string_list(value: Any) -> list[str]:
  function _build_git_status_response (line 40) | def _build_git_status_response(deps: Any) -> GitStatusResponse:
  function _resolve_actionable_online_hw_ids (line 232) | def _resolve_actionable_online_hw_ids(deps: Any) -> set[str] | None:
  function create_git_router (line 268) | def create_git_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/management.py
  function _get_gcs_config_path (line 83) | def _get_gcs_config_path() -> Path:
  function _normalize_runtime_mode_value (line 87) | def _normalize_runtime_mode_value(value: str | None) -> str | None:
  function _persist_env_updates (line 99) | def _persist_env_updates(path: Path, updates: dict[str, Any]) -> list[str]:
  function _build_gcs_env_entry_response (line 103) | def _build_gcs_env_entry_response(entry: EnvRegistryEntry, values: dict[...
  function _build_gcs_env_response (line 132) | def _build_gcs_env_response() -> GCSRuntimeEnvResponse:
  function _validate_gcs_env_updates (line 162) | def _validate_gcs_env_updates(updates: dict[str, Any]) -> tuple[dict[str...
  function _validate_fleet_env_plan_updates (line 194) | def _validate_fleet_env_plan_updates(updates: dict[str, Any]) -> tuple[d...
  function _normalize_hw_id_list (line 226) | def _normalize_hw_id_list(values: list[Any]) -> list[str]:
  function _resolve_fleet_env_plan_targets (line 238) | def _resolve_fleet_env_plan_targets(deps: Any, requested_hw_ids: list[An...
  function _snapshot_git_status_env_reports (line 262) | def _snapshot_git_status_env_reports(deps: Any) -> dict[str, dict[str, A...
  function _normalize_hw_id (line 273) | def _normalize_hw_id(value: Any) -> str:
  function _drone_api_port (line 277) | def _drone_api_port(deps: Any) -> int:
  function _extract_node_host (line 287) | def _extract_node_host(row: dict[str, Any] | None) -> str | None:
  function _node_record_matches (line 309) | def _node_record_matches(row: dict[str, Any], key: Any, target: str) -> ...
  function _merge_node_records (line 315) | def _merge_node_records(config_row: dict[str, Any] | None, reported_row:...
  function _resolve_config_node_record (line 327) | def _resolve_config_node_record(deps: Any, target: str) -> dict[str, Any...
  function _resolve_node_record (line 338) | def _resolve_node_record(deps: Any, hw_id: str) -> dict[str, Any] | None:
  function _build_node_env_url (line 358) | def _build_node_env_url(deps: Any, host: str) -> str:
  function _extract_proxy_error (line 365) | def _extract_proxy_error(response: httpx.Response) -> str:
  function _proxy_node_env_request (line 377) | async def _proxy_node_env_request(
  function _build_fleet_env_plan_response (line 407) | def _build_fleet_env_plan_response(deps: Any, payload: FleetRuntimeEnvPl...
  function _gcs_env_restart_required (line 480) | def _gcs_env_restart_required(values: dict[str, str]) -> bool:
  function _resolve_requested_runtime_mode (line 492) | def _resolve_requested_runtime_mode(payload: GCSConfigUpdateRequest | No...
  function _resolve_configured_runtime_mode (line 511) | def _resolve_configured_runtime_mode(config_values: dict[str, str], fall...
  function _resolve_configured_git_auto_push (line 516) | def _resolve_configured_git_auto_push(config_values: dict[str, str], fal...
  function _log_event (line 520) | def _log_event(deps: Any, message: str, level: str = "INFO", subsystem: ...
  function _log_error (line 529) | def _log_error(deps: Any, message: str, subsystem: str = "runtime_admin"...
  function _list_sitl_instance_count (line 535) | def _list_sitl_instance_count(deps: Any) -> int | None:
  function _schedule_gcs_restart (line 547) | def _schedule_gcs_restart(*, target_mode: str) -> bool:
  function _build_gcs_config_response (line 581) | def _build_gcs_config_response(deps: Any) -> GCSConfigResponse:
  function _normalize_github_docs_base (line 607) | def _normalize_github_docs_base(repo_url: str, branch: str) -> str | None:
  function _describe_repo_access_mode (line 619) | def _describe_repo_access_mode(repo_url: str, token_file: str, ssh_key_f...
  function _build_git_auth_health (line 630) | def _build_git_auth_health(
  function _build_runtime_repo_sync_status_from_report (line 671) | def _build_runtime_repo_sync_status_from_report(report: dict[str, Any] |...
  function _build_runtime_repo_sync_status (line 720) | def _build_runtime_repo_sync_status(deps: Any) -> RuntimeRepoSyncStatusR...
  function _run_repo_command (line 728) | def _run_repo_command(args: list[str], *, timeout: int = 15) -> subproce...
  function _refresh_repo_sync_status (line 739) | def _refresh_repo_sync_status(deps: Any) -> RuntimeRepoSyncStatusResponse:
  function _list_pending_update_paths (line 756) | def _list_pending_update_paths(tracking_branch: str | None) -> list[str]:
  function _resolve_target_commit (line 769) | def _resolve_target_commit(tracking_branch: str | None) -> str | None:
  function _blocked_gcs_update_paths (line 780) | def _blocked_gcs_update_paths(paths: list[str]) -> list[str]:
  function _schedule_gcs_runtime_update (line 794) | def _schedule_gcs_runtime_update(*, target_mode: str, tracking_branch: s...
  function _build_mavlink_runtime_status (line 826) | def _build_mavlink_runtime_status(deployment_profile: Any) -> RuntimeMav...
  function _build_connectivity_runtime_status (line 830) | def _build_connectivity_runtime_status(deployment_profile: Any) -> Runti...
  function _build_runtime_status_response (line 834) | def _build_runtime_status_response(deps: Any) -> RuntimeStatusResponse:
  function create_management_router (line 917) | def create_management_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/origin.py
  function _coerce_origin_timestamp_ms (line 24) | def _coerce_origin_timestamp_ms(origin: dict[str, Any]) -> int | None:
  function _validate_origin (line 35) | def _validate_origin(origin: dict[str, Any] | None, *, detail: str, stat...
  function _build_origin_response (line 41) | def _build_origin_response(origin: dict[str, Any]) -> OriginResponse:
  function _render_launch_positions_csv (line 51) | def _render_launch_positions_csv(payload: dict[str, Any]) -> Response:
  function _render_launch_positions_kml (line 79) | def _render_launch_positions_kml(payload: dict[str, Any]) -> Response:
  function create_origin_router (line 131) | def create_origin_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/px4_params.py
  function create_px4_params_router (line 50) | def create_px4_params_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/show_management.py
  function create_show_management_router (line 30) | def create_show_management_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/sitl_control.py
  function _get_service (line 40) | def _get_service(deps: Any) -> SitlControlService:
  function create_sitl_control_router (line 47) | def create_sitl_control_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/static_assets.py
  function _resolve_static_plot_path (line 10) | def _resolve_static_plot_path(plots_dir: str, filename: str) -> Path:
  function create_static_assets_router (line 22) | def create_static_assets_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/swarm.py
  function _normalize_swarm_hw_id (line 18) | def _normalize_swarm_hw_id(value: Any) -> Optional[int]:
  function _extract_swarm_assignments (line 26) | def _extract_swarm_assignments(payload: Any):
  function _build_swarm_config_resource (line 34) | def _build_swarm_config_resource(assignments: list[dict[str, Any]]) -> d...
  function _parse_swarm_config_payload (line 41) | def _parse_swarm_config_payload(payload: Any) -> list[dict[str, Any]]:
  function _would_create_swarm_cycle (line 53) | def _would_create_swarm_cycle(assignments: list[dict[str, Any]], hw_id: ...
  function _validate_swarm_cycle_constraints (line 82) | def _validate_swarm_cycle_constraints(payload: Any) -> None:
  function _apply_swarm_assignment_patch (line 112) | def _apply_swarm_assignment_patch(deps: Any, hw_id: int, data: dict[str,...
  function create_swarm_router (line 175) | def create_swarm_router(deps: Any) -> APIRouter:

FILE: gcs-server/api_routes/swarm_trajectory.py
  function _swarm_error_response (line 29) | def _swarm_error_response(request: Request, exc: Exception) -> JSONRespo...
  function _swarm_problem_response (line 40) | def _swarm_problem_response(request: Request, *, status_code: int, detai...
  function _log_swarm_internal_error (line 51) | def _log_swarm_internal_error(deps: Any, message: str, exc: Exception) -...
  function _git_failure_status_code (line 55) | def _git_failure_status_code(message: str | None) -> int:
  function _build_swarm_trajectory_policy_payload (line 64) | def _build_swarm_trajectory_policy_payload(params: Any) -> dict[str, Any]:
  function create_swarm_trajectory_router (line 97) | def create_swarm_trajectory_router(deps: Any) -> APIRouter:

FILE: gcs-server/app_fastapi.py
  function _custom_show_csv_path (line 159) | def _custom_show_csv_path() -> str:
  function _custom_show_preview_path (line 163) | def _custom_show_preview_path() -> str:
  function _load_saved_metrics_if_current (line 171) | def _load_saved_metrics_if_current() -> Optional[Dict[str, Any]]:
  function _refresh_saved_show_metrics (line 179) | def _refresh_saved_show_metrics(show_filename: Optional[str] = None) -> ...
  class BackgroundServices (line 192) | class BackgroundServices:
    method __init__ (line 195) | def __init__(self):
    method _normalize_drones (line 202) | def _normalize_drones(self, drones: List[Dict]) -> List[Dict[str, Any]]:
    method apply_drone_targets (line 228) | def apply_drone_targets(self, drones: List[Dict]) -> dict[str, int]:
    method start (line 269) | async def start(self, drones: List[Dict]):
    method reconcile (line 303) | async def reconcile(self, drones: List[Dict]):
    method stop (line 320) | async def stop(self):
    method _poll_telemetry (line 351) | async def _poll_telemetry(self):
    method _poll_git_status (line 408) | async def _poll_git_status(self):
    method _poll_command_timeouts (line 448) | async def _poll_command_timeouts(self):
  function _normalize_heartbeat_first_seen (line 472) | def _normalize_heartbeat_first_seen(value: Any) -> Optional[int]:
  function _normalize_update_time_ms (line 491) | def _normalize_update_time_ms(value: Any) -> Optional[int]:
  function observe_fleet_candidate_heartbeat (line 509) | def observe_fleet_candidate_heartbeat(heartbeat: dict[str, Any]):
  function list_fleet_candidates (line 514) | def list_fleet_candidates(*, include_inactive: bool = False, runtime_mod...
  function get_fleet_candidate (line 523) | def get_fleet_candidate(candidate_id: str):
  function announce_fleet_candidate (line 528) | def announce_fleet_candidate(payload: FleetCandidateAnnounceRequest):
  function accept_fleet_candidate (line 533) | def accept_fleet_candidate(candidate_id: str, payload: FleetCandidateAcc...
  function replace_fleet_candidate (line 544) | def replace_fleet_candidate(candidate_id: str, payload: FleetCandidateRe...
  function recover_fleet_candidate (line 557) | def recover_fleet_candidate(candidate_id: str, payload: FleetCandidateRe...
  function set_fleet_candidate_state (line 568) | def set_fleet_candidate_state(
  function reconcile_background_services (line 583) | async def reconcile_background_services() -> list[dict[str, Any]]:
  function _local_mavlink_stale_threshold_ms (line 590) | def _local_mavlink_stale_threshold_ms() -> int:
  function _build_stale_background_blocker (line 601) | def _build_stale_background_blocker(message: str, timestamp_ms: int) -> ...
  function _has_valid_global_position (line 610) | def _has_valid_global_position(record: Dict[str, Any]) -> bool:
  function _position_unavailable_reason (line 623) | def _position_unavailable_reason(record: Dict[str, Any]) -> Optional[str]:
  function _ensure_position_quality_fields (line 635) | def _ensure_position_quality_fields(record: Dict[str, Any], now_ms: int)...
  function _build_background_unavailable_record (line 663) | def _build_background_unavailable_record(
  function _build_background_telemetry_record (line 743) | def _build_background_telemetry_record(hw_id: Any, ip: str, data: Dict[s...
  function lifespan (line 798) | async def lifespan(app: FastAPI):
  function log_requests (line 905) | async def log_requests(request: Request, call_next):
  function _select_sync_target_drones (line 931) | def _select_sync_target_drones(
  function _is_git_sync_verified (line 964) | def _is_git_sync_verified(
  function _verify_sync_targets (line 988) | async def _verify_sync_targets(
  function request_validation_error_handler (line 1040) | async def request_validation_error_handler(request: Request, exc: Reques...
  function http_error_handler (line 1053) | async def http_error_handler(request: Request, exc: StarletteHTTPExcepti...
  function internal_error_handler (line 1068) | async def internal_error_handler(request: Request, exc: Exception):

FILE: gcs-server/auth_runtime.py
  function _auth_error (line 45) | def _auth_error(status_code: int, error: str, message: str, recovery_hin...
  function _extract_bearer_token (line 56) | def _extract_bearer_token(value: str | None) -> str | None:
  function _is_public_path (line 66) | def _is_public_path(path: str) -> bool:
  function _is_admin_path (line 74) | def _is_admin_path(path: str) -> bool:
  function _is_machine_endpoint (line 78) | def _is_machine_endpoint(method: str, path: str) -> bool:
  function _role_allows_request (line 82) | def _role_allows_request(role: str, method: str, path: str) -> tuple[boo...
  class MDSAuthMiddleware (line 95) | class MDSAuthMiddleware(BaseHTTPMiddleware):
    method dispatch (line 98) | async def dispatch(self, request: Request, call_next):  # type: ignore...
  function authorize_websocket (line 154) | async def authorize_websocket(websocket: WebSocket) -> dict[str, Any] | ...

FILE: gcs-server/command.py
  function normalize_drone_id (line 81) | def normalize_drone_id(drone_id: Any) -> str:
  function normalize_drone_ids (line 86) | def normalize_drone_ids(drone_ids: Iterable[Any]) -> List[str]:
  function _partition_recently_online_drones (line 91) | def _partition_recently_online_drones(
  function resolve_mission_type (line 135) | def resolve_mission_type(mission_type: Any) -> Mission | None:
  function normalize_mission_type (line 173) | def normalize_mission_type(mission_type: Any) -> Tuple[str, str, Mission...
  function is_critical_mission (line 184) | def is_critical_mission(mission: Mission | None) -> bool:
  function mission_requires_launch_armability_probe (line 189) | def mission_requires_launch_armability_probe(mission: Mission | None) ->...
  function mission_requires_strict_sync_dispatch (line 194) | def mission_requires_strict_sync_dispatch(mission: Mission | None) -> bool:
  function _extract_trigger_time_seconds (line 199) | def _extract_trigger_time_seconds(command_payload: Dict[str, Any]) -> fl...
  function _get_sync_dispatch_deadline (line 212) | def _get_sync_dispatch_deadline(mission: Mission | None, command_payload...
  function _log_command_event (line 225) | def _log_command_event(message: str, level: str = "INFO", drone_id: Any ...
  function _log_drone_command_result (line 232) | def _log_drone_command_result(drone_id: Any, command_type: Any, success:...
  function _summarize_ack_error (line 242) | def _summarize_ack_error(payload: Dict[str, Any]) -> str:
  function parse_command_ack_response (line 251) | def parse_command_ack_response(response: requests.Response) -> Tuple[boo...
  function send_command_to_drone (line 288) | def send_command_to_drone(drone: Dict[str, str], command_data: Dict[str,...
  function probe_live_armability_for_drone (line 414) | def probe_live_armability_for_drone(
  function probe_live_armability_for_drones (line 462) | def probe_live_armability_for_drones(
  function send_commands_to_all (line 509) | def send_commands_to_all(drones: List[Dict[str, str]], command_data: Dic...
  function send_commands_to_selected (line 687) | def send_commands_to_selected(drones: List[Dict[str, str]], command_data...
  function validate_command_data (line 735) | def validate_command_data(command_data: Dict[str, Any]) -> Tuple[bool, s...
  function execute_drone_command (line 769) | def execute_drone_command(drones: List[Dict[str, str]], command_data: Di...

FILE: gcs-server/command_submission.py
  function _get_telemetry_record_for_hw_id (line 24) | def _get_telemetry_record_for_hw_id(
  function estimate_max_target_relative_altitude_m (line 47) | def estimate_max_target_relative_altitude_m(
  function build_results_summary (line 120) | def build_results_summary(results: dict[str, Any]) -> dict[str, int]:
  function derive_submission_status (line 129) | def derive_submission_status(results: dict[str, Any]) -> str:
  function _build_results_summary_from_status (line 144) | def _build_results_summary_from_status(command_status: Dict[str, Any]) -...
  function _derive_submission_status_from_status (line 154) | def _derive_submission_status_from_status(command_status: Dict[str, Any]...
  function build_submit_replay_response (line 161) | def build_submit_replay_response(command_status: Dict[str, Any]) -> Subm...
  function build_submit_request_fingerprint (line 203) | def build_submit_request_fingerprint(command: SubmitCommandRequest) -> str:
  function record_command_acknowledgements (line 216) | async def record_command_acknowledgements(tracker: Any, command_id: str,...
  function submit_tracked_command (line 252) | async def submit_tracked_command(deps: Any, command: SubmitCommandReques...

FILE: gcs-server/command_timeout_policy.py
  function _coerce_mission (line 17) | def _coerce_mission(value: Any) -> Mission | None:
  function _safe_int (line 41) | def _safe_int(value: Any, default: int) -> int:
  function _target_drone_file_names (line 48) | def _target_drone_file_names(target_drone_ids: Optional[Iterable[Any]]) ...
  function _extract_future_trigger_delay_ms (line 62) | def _extract_future_trigger_delay_ms(command_data: Optional[Dict[str, An...
  function _read_show_duration_ms (line 83) | def _read_show_duration_ms(
  function _read_custom_show_duration_ms (line 120) | def _read_custom_show_duration_ms(shapes_dir: Path) -> Optional[int]:
  function _read_swarm_processed_duration_s (line 142) | def _read_swarm_processed_duration_s(
  function estimate_command_tracking_timeout_ms (line 169) | def estimate_command_tracking_timeout_ms(

FILE: gcs-server/command_tracker.py
  class CommandIdempotencyConflictError (line 72) | class CommandIdempotencyConflictError(ValueError):
  class CommandCreationResult (line 77) | class CommandCreationResult:
  class DroneAck (line 85) | class DroneAck:
  class DroneExecution (line 97) | class DroneExecution:
  class TrackedCommand (line 109) | class TrackedCommand:
  class CommandTracker (line 154) | class CommandTracker:
    method __init__ (line 162) | def __init__(
    method _all_execution_failures_superseded (line 198) | def _all_execution_failures_superseded(command: TrackedCommand) -> bool:
    method _is_terminal (line 213) | def _is_terminal(command: TrackedCommand) -> bool:
    method _can_recover_from_offline_terminal (line 218) | def _can_recover_from_offline_terminal(command: TrackedCommand, hw_id:...
    method _reopen_offline_terminal_locked (line 241) | def _reopen_offline_terminal_locked(self, command: TrackedCommand, tim...
    method _get_mission_name (line 253) | def _get_mission_name(self, mission_type: int) -> str:
    method build_request_fingerprint (line 263) | def build_request_fingerprint(payload: Dict[str, Any]) -> str:
    method _validate_replay_fingerprint (line 284) | def _validate_replay_fingerprint(
    method _evict_oldest_command_locked (line 299) | def _evict_oldest_command_locked(self) -> None:
    method lookup_command_by_idempotency_key (line 307) | async def lookup_command_by_idempotency_key(
    method create_or_replay_command (line 334) | async def create_or_replay_command(
    method create_command (line 397) | async def create_command(
    method mark_submitted (line 424) | async def mark_submitted(self, command_id: str) -> bool:
    method record_ack (line 441) | async def record_ack(
    method _mark_execution_started_locked (line 577) | def _mark_execution_started_locked(
    method _record_late_ack_locked (line 602) | def _record_late_ack_locked(
    method _record_late_execution_start_locked (line 629) | def _record_late_execution_start_locked(
    method _record_late_execution_locked (line 648) | def _record_late_execution_locked(
    method _promote_execution_evidence_to_accepted_locked (line 679) | def _promote_execution_evidence_to_accepted_locked(
    method record_execution_start (line 727) | async def record_execution_start(
    method record_execution (line 775) | async def record_execution(
    method cancel_command (line 925) | async def cancel_command(self, command_id: str, reason: str = "User ca...
    method check_timeouts (line 946) | async def check_timeouts(self) -> List[str]:
    method get_status (line 994) | async def get_status(self, command_id: str) -> Optional[Dict[str, Any]]:
    method get_recent (line 1008) | async def get_recent(
    method get_statistics (line 1040) | async def get_statistics(self) -> Dict[str, Any]:
    method get_active_commands (line 1062) | async def get_active_commands(self) -> List[Dict[str, Any]]:
    method _build_result_summary (line 1072) | def _build_result_summary(self, command: TrackedCommand) -> str:
    method _extract_trigger_time_ms (line 1086) | def _extract_trigger_time_ms(params: Optional[Dict[str, Any]]) -> Opti...
    method _build_progress_summary (line 1108) | def _build_progress_summary(self, command: TrackedCommand) -> Dict[str...
    method _command_to_dict (line 1226) | def _command_to_dict(self, command: TrackedCommand) -> Dict[str, Any]:
  function get_command_tracker (line 1349) | def get_command_tracker() -> CommandTracker:
  function init_command_tracker (line 1357) | def init_command_tracker(mission_enum: Optional[type] = None, **kwargs) ...

FILE: gcs-server/config.py
  function load_config (line 31) | def load_config(file_path=None):
  function save_config (line 42) | def save_config(config, file_path=None):
  function load_swarm (line 49) | def load_swarm(file_path=None):
  function save_swarm (line 60) | def save_swarm(swarm, file_path=None):
  function get_gcs_git_report (line 67) | def get_gcs_git_report():
  function get_drone_git_status (line 76) | def get_drone_git_status(drone_uri):
  function validate_and_process_config (line 85) | def validate_and_process_config(config_data, sim_mode=None):
  function get_all_drone_positions (line 234) | def get_all_drone_positions(sim_mode=None):

FILE: gcs-server/fleet_candidates.py
  function get_fleet_candidate_registry (line 37) | def get_fleet_candidate_registry() -> "FleetCandidateRegistry":
  class FleetCandidateError (line 46) | class FleetCandidateError(RuntimeError):
  class FleetCandidateNotFoundError (line 50) | class FleetCandidateNotFoundError(FleetCandidateError):
  class FleetCandidateConflictError (line 54) | class FleetCandidateConflictError(FleetCandidateError):
  class FleetCandidateValidationError (line 58) | class FleetCandidateValidationError(FleetCandidateError):
  function _now_ms (line 62) | def _now_ms() -> int:
  function _normalize_string (line 66) | def _normalize_string(value: Any) -> Optional[str]:
  function _normalize_ip (line 75) | def _normalize_ip(value: Any) -> Optional[str]:
  function _normalize_runtime_mode (line 84) | def _normalize_runtime_mode(value: Any) -> Optional[str]:
  function _normalize_timestamp_ms (line 94) | def _normalize_timestamp_ms(value: Any, fallback_ms: Optional[int] = Non...
  function _normalize_hw_id_int (line 106) | def _normalize_hw_id_int(value: Any) -> int:
  function _active_candidate_sort_key (line 116) | def _active_candidate_sort_key(candidate: FleetCandidateRecord) -> tuple...
  class FleetCandidateRegistry (line 137) | class FleetCandidateRegistry:
    method __init__ (line 140) | def __init__(self, state_path: str | None = None, events_path: str | N...
    method _load_state (line 159) | def _load_state(self) -> None:
    method _persist_state_locked (line 177) | def _persist_state_locked(self) -> None:
    method _append_event_locked (line 188) | def _append_event_locked(self, event_type: str, candidate_id: str, pay...
    method _candidate_key_seed (line 199) | def _candidate_key_seed(self, *, runtime_mode: Optional[str], node_uui...
    method _candidate_runtime_matches (line 205) | def _candidate_runtime_matches(self, raw: dict[str, Any], runtime_mode...
    method _find_candidate_key_locked (line 210) | def _find_candidate_key_locked(
    method _build_candidate_locked (line 227) | def _build_candidate_locked(
    method _configured_maps (line 246) | def _configured_maps(self, config_entries: list[dict[str, Any]]) -> tu...
    method _refresh_candidate_state_locked (line 258) | def _refresh_candidate_state_locked(
    method list_candidates (line 328) | def list_candidates(
    method get_candidate (line 351) | def get_candidate(self, candidate_id: str, *, load_config) -> FleetCan...
    method observe_heartbeat (line 362) | def observe_heartbeat(self, heartbeat: dict[str, Any], *, load_config)...
    method announce_candidate (line 428) | def announce_candidate(self, request: FleetCandidateAnnounceRequest, *...
    method _require_candidate_locked (line 498) | def _require_candidate_locked(self, candidate_id: str) -> dict[str, Any]:
    method accept_candidate (line 505) | def accept_candidate(
    method replace_candidate (line 572) | def replace_candidate(
    method recover_candidate (line 668) | def recover_candidate(
    method update_candidate_state (line 744) | def update_candidate_state(

FILE: gcs-server/gcs_config_updater.py
  function validate_ip_address (line 16) | def validate_ip_address(ip_string):
  function update_gcs_ip_in_params (line 43) | def update_gcs_ip_in_params(new_ip):
  function get_current_gcs_ip (line 153) | def get_current_gcs_ip():

FILE: gcs-server/get_elevation.py
  function get_distance (line 11) | def get_distance(lat1, lon1, lat2, lon2):
  function fetch_elevation_data (line 21) | def fetch_elevation_data(lat, lon):
  function get_elevation (line 31) | def get_elevation(lat, lon):

FILE: gcs-server/git_status.py
  function commits_match (line 23) | def commits_match(left_commit: str, right_commit: str) -> bool:
  function check_git_sync_status (line 35) | def check_git_sync_status():

FILE: gcs-server/heartbeat.py
  function _normalize_runtime_mode (line 21) | def _normalize_runtime_mode(value):
  function _resolve_current_runtime_mode (line 33) | def _resolve_current_runtime_mode():
  function _log_missing_runtime_mode_once (line 40) | def _log_missing_runtime_mode_once(hw_id):
  function _log_runtime_mode_mismatch_once (line 52) | def _log_runtime_mode_mismatch_once(hw_id, declared_mode, current_mode):
  function handle_heartbeat_post (line 67) | def handle_heartbeat_post(pos_id, hw_id, detected_pos_id=None, ip=None, ...
  function get_all_heartbeats (line 167) | def get_all_heartbeats():
  function get_network_info_from_heartbeats (line 177) | def get_network_info_from_heartbeats():

FILE: gcs-server/link_presence.py
  function _normalize_hw_id (line 11) | def _normalize_hw_id(value: Any) -> str:
  function get_recent_link_presence (line 15) | def get_recent_link_presence(

FILE: gcs-server/log_background.py
  class BackgroundLogPuller (line 25) | class BackgroundLogPuller:
    method __init__ (line 28) | def __init__(self, log_dir: str | None = None):
    method set_enabled (line 34) | def set_enabled(self, enabled: bool) -> None:
    method start (line 42) | async def start(self) -> None:
    method stop (line 47) | async def stop(self) -> None:
    method _run_loop (line 58) | async def _run_loop(self) -> None:
    method _pull_once (line 69) | async def _pull_once(self) -> None:

FILE: gcs-server/log_proxy.py
  function _drone_api_port (line 30) | def _drone_api_port() -> int:
  class DroneProxyRequestError (line 43) | class DroneProxyRequestError(Exception):
  class DroneProxyUnavailableError (line 47) | class DroneProxyUnavailableError(DroneProxyRequestError):
  class DroneProxyResponseError (line 51) | class DroneProxyResponseError(DroneProxyRequestError):
    method __init__ (line 54) | def __init__(self, status_code: int, detail: str) -> None:
  function resolve_drone_ip (line 60) | def resolve_drone_ip(drone_id: int) -> Optional[str]:
  function _build_drone_url (line 73) | def _build_drone_url(drone_ip: str, path: str) -> str:
  function _extract_error_detail (line 77) | def _extract_error_detail(response: httpx.Response) -> str:
  function _request_json (line 90) | async def _request_json(
  function fetch_drone_sessions (line 115) | async def fetch_drone_sessions(drone_ip: str) -> Optional[dict]:
  function fetch_drone_session_content (line 127) | async def fetch_drone_session_content(
  function fetch_drone_ulog_policy (line 161) | async def fetch_drone_ulog_policy(drone_ip: str) -> dict:
  function fetch_drone_ulog_files (line 165) | async def fetch_drone_ulog_files(drone_ip: str) -> dict:
  function create_drone_ulog_download_job (line 169) | async def create_drone_ulog_download_job(
  function fetch_drone_ulog_download_job (line 187) | async def fetch_drone_ulog_download_job(drone_ip: str, job_id: str) -> d...
  function delete_drone_ulog_download_job (line 196) | async def delete_drone_ulog_download_job(drone_ip: str, job_id: str) -> ...
  function erase_all_drone_ulogs (line 205) | async def erase_all_drone_ulogs(drone_ip: str) -> dict:
  function open_drone_ulog_download_stream (line 209) | async def open_drone_ulog_download_stream(drone_ip: str, job_id: str) ->...
  function stream_drone_logs (line 233) | def stream_drone_logs(

FILE: gcs-server/log_routes.py
  function create_log_router (line 46) | def create_log_router(

FILE: gcs-server/origin.py
  function _get_telemetry_record_for_hw_id (line 18) | def _get_telemetry_record_for_hw_id(telemetry_snapshot, hw_id):
  function _normalize_origin_payload (line 47) | def _normalize_origin_payload(data: Dict[str, Any], *, default_alt_sourc...
  function _load_json_origin_file (line 66) | def _load_json_origin_file(path: str, *, default_alt_source: str) -> Opt...
  function load_sitl_default_origin (line 77) | def load_sitl_default_origin() -> Optional[Dict[str, Any]]:
  function save_origin (line 94) | def save_origin(data):
  function load_origin (line 128) | def load_origin():
  function calculate_position_deviations (line 173) | def calculate_position_deviations(telemetry_data_all_drones, drones_conf...
  function rotate_north_east (line 269) | def rotate_north_east(north: float, east: float, heading_deg: float) -> ...
  function build_position_deviation_report (line 277) | def build_position_deviation_report(
  function build_desired_launch_positions_report (line 469) | def build_desired_launch_positions_report(
  function compute_origin_from_drone (line 533) | def compute_origin_from_drone(current_lat, current_lon, intended_north, ...

FILE: gcs-server/presence.py
  class PresenceThresholds (line 17) | class PresenceThresholds:
  function _safe_float (line 24) | def _safe_float(value: Any, default: float) -> float:
  function resolve_presence_thresholds (line 32) | def resolve_presence_thresholds(params: Any | None = None) -> PresenceTh...
  function _normalize_timestamp_ms (line 69) | def _normalize_timestamp_ms(value: Any) -> int | None:
  function _age_sec (line 83) | def _age_sec(timestamp_ms: int | None, now_ms: int) -> float | None:
  function _pick_newest_source (line 89) | def _pick_newest_source(
  function build_presence_snapshot (line 104) | def build_presence_snapshot(

FILE: gcs-server/px4_param_store.py
  function build_px4_param_policy_payload (line 49) | def build_px4_param_policy_payload(params: Any) -> Px4ParamPolicyResponse:
  function _resolve_profile_dir (line 53) | def _resolve_profile_dir(params: Any) -> Path:
  function _load_profile_file (line 61) | def _load_profile_file(profile_path: Path) -> Px4ParamProfileResponse:
  function list_repo_profiles (line 80) | def list_repo_profiles(params: Any) -> Px4ParamProfileListResponse:
  function get_repo_profile (line 114) | def get_repo_profile(params: Any, profile_id: str) -> Px4ParamProfileRes...
  function save_snapshot (line 125) | def save_snapshot(snapshot: Px4ParamSnapshotResponse) -> None:
  function save_patch_job (line 130) | def save_patch_job(job: Px4ParamPatchJobResponse) -> None:
  function get_snapshot (line 135) | def get_snapshot(snapshot_id: str) -> Px4ParamSnapshotResponse | None:
  function get_patch_job (line 140) | def get_patch_job(job_id: str) -> Px4ParamPatchJobResponse | None:
  function build_snapshot_rows_response (line 145) | def build_snapshot_rows_response(snapshot_id: str) -> Px4ParamSnapshotRo...
  function fetch_snapshots_for_targets (line 157) | def fetch_snapshots_for_targets(deps: Any, request: Px4ParamFleetSnapsho...
  function _resolve_target_drone (line 200) | def _resolve_target_drone(deps: Any, hw_id: str) -> dict[str, Any] | None:
  function _build_drone_api_url (line 206) | def _build_drone_api_url(ip: str, port: int, route: str) -> str:
  function _request_json (line 210) | def _request_json(method: str, url: str, *, timeout_sec: float, payload:...
  function run_patch_job_for_targets (line 216) | def run_patch_job_for_targets(deps: Any, request: Px4ParamPatchJobReques...
  function import_qgc_parameter_file (line 318) | def import_qgc_parameter_file(request: Px4ParamImportRequest) -> Px4Para...
  function import_mds_patch (line 385) | def import_mds_patch(request: Px4ParamImportRequest) -> Px4ParamImportRe...
  function build_param_diff_response (line 408) | def build_param_diff_response(request: Px4ParamDiffRequest) -> Px4ParamD...

FILE: gcs-server/request_logging.py
  function is_routine_success_path (line 21) | def is_routine_success_path(path: str) -> bool:
  function get_request_log_level (line 38) | def get_request_log_level(path: str, status_code: int) -> str:

FILE: gcs-server/sar/coverage_planner.py
  function _require_shapely (line 40) | def _require_shapely():
  class BaseCoveragePlanner (line 50) | class BaseCoveragePlanner:
    method plan (line 53) | def plan(
  class BoustrophedonPlanner (line 73) | class BoustrophedonPlanner(BaseCoveragePlanner):
    method plan (line 89) | def plan(
    method _compute_sweep_angle (line 180) | def _compute_sweep_angle(self, enu_points: List[Tuple[float, float]]) ...
    method _generate_sweep_lines (line 195) | def _generate_sweep_lines(
    method _build_boustrophedon (line 243) | def _build_boustrophedon(self, lines: List[LineString]) -> List[LineSt...
    method _partition_lines (line 253) | def _partition_lines(self, lines: List[LineString], n: int) -> List[Li...
    method _assign_sectors (line 289) | def _assign_sectors(
    method _build_waypoints (line 326) | def _build_waypoints(
    method _compute_total_distance (line 373) | def _compute_total_distance(self, waypoints: List[CoverageWaypoint]) -...
    method _haversine_m (line 384) | def _haversine_m(lat1: float, lng1: float, lat2: float, lng2: float) -...

FILE: gcs-server/sar/mission_manager.py
  function get_mission_manager (line 20) | def get_mission_manager() -> "MissionManager":
  class MissionManager (line 27) | class MissionManager:
    method __init__ (line 30) | def __init__(self):
    method create_mission (line 33) | def create_mission(self, mission_id, plans, config):
    method get_status (line 36) | def get_status(self, mission_id: str):
    method get_plans (line 39) | def get_plans(self, mission_id: str):
    method get_config (line 42) | def get_config(self, mission_id: str):
    method start_mission (line 45) | def start_mission(self, mission_id: str):
    method update_drone_progress (line 48) | def update_drone_progress(
    method pause_mission (line 66) | def pause_mission(self, mission_id: str, hw_ids: Optional[List[str]] =...
    method resume_mission (line 69) | def resume_mission(self, mission_id: str, hw_ids: Optional[List[str]] ...
    method abort_mission (line 72) | def abort_mission(

FILE: gcs-server/sar/routes.py
  function create_sar_router (line 29) | def create_sar_router(deps: Any) -> APIRouter:

FILE: gcs-server/sar/schemas.py
  class ReturnBehavior (line 12) | class ReturnBehavior(str, Enum):
  class QuickScoutMissionTemplate (line 18) | class QuickScoutMissionTemplate(str, Enum):
  class SurveyState (line 24) | class SurveyState(str, Enum):
  class QuickScoutMissionPhase (line 33) | class QuickScoutMissionPhase(str, Enum):
  class QuickScoutControlEffect (line 44) | class QuickScoutControlEffect(str, Enum):
  class QuickScoutControlAvailability (line 50) | class QuickScoutControlAvailability(BaseModel):
  class FindingType (line 61) | class FindingType(str, Enum):
  class FindingPriority (line 72) | class FindingPriority(str, Enum):
  class FindingStatus (line 79) | class FindingStatus(str, Enum):
  class FindingConfidence (line 87) | class FindingConfidence(str, Enum):
  class FindingSource (line 93) | class FindingSource(str, Enum):
  class SearchAreaPoint (line 102) | class SearchAreaPoint(BaseModel):
  class SearchArea (line 108) | class SearchArea(BaseModel):
    method validate_shape_requirements (line 119) | def validate_shape_requirements(self):
  class SurveyConfig (line 142) | class SurveyConfig(BaseModel):
  class QuickScoutMissionRequest (line 160) | class QuickScoutMissionRequest(BaseModel):
  class CoverageWaypoint (line 179) | class CoverageWaypoint(BaseModel):
  class DroneCoveragePlan (line 193) | class DroneCoveragePlan(BaseModel):
  class CoveragePlanResponse (line 205) | class CoveragePlanResponse(BaseModel):
  class QuickScoutFinding (line 216) | class QuickScoutFinding(BaseModel):
  class QuickScoutFindingCreate (line 238) | class QuickScoutFindingCreate(BaseModel):
  class QuickScoutFindingUpdate (line 258) | class QuickScoutFindingUpdate(BaseModel):
  class DroneSurveyState (line 276) | class DroneSurveyState(BaseModel):
  class MissionStatus (line 290) | class MissionStatus(BaseModel):
  class QuickScoutMissionSummary (line 321) | class QuickScoutMissionSummary(BaseModel):
  class QuickScoutMissionCatalogResponse (line 346) | class QuickScoutMissionCatalogResponse(BaseModel):
  class QuickScoutLaunchSubmission (line 353) | class QuickScoutLaunchSubmission(BaseModel):
  class QuickScoutMissionLaunchResponse (line 366) | class QuickScoutMissionLaunchResponse(BaseModel):
  class QuickScoutMissionControlResponse (line 384) | class QuickScoutMissionControlResponse(BaseModel):
  class QuickScoutOperationRecord (line 404) | class QuickScoutOperationRecord(BaseModel):
  class QuickScoutMissionWorkspaceResponse (line 445) | class QuickScoutMissionWorkspaceResponse(BaseModel):
  class QuickScoutMissionHandoffFinding (line 452) | class QuickScoutMissionHandoffFinding(BaseModel):
  class QuickScoutMissionHandoff (line 468) | class QuickScoutMissionHandoff(BaseModel):
  class DroneProgressReport (line 501) | class DroneProgressReport(BaseModel):

FILE: gcs-server/sar/service.py
  function get_quickscout_service (line 59) | def get_quickscout_service() -> "QuickScoutService":
  class QuickScoutService (line 66) | class QuickScoutService:
    method __init__ (line 69) | def __init__(self, store=None, planner_factory=BoustrophedonPlanner):
    method _resolve_pos_ids_to_hw_ids (line 73) | def _resolve_pos_ids_to_hw_ids(
    method _build_operator_label (line 95) | def _build_operator_label(action: str, mission_id: str, hw_id: Optiona...
    method _accepted_hw_ids_from_response (line 100) | def _accepted_hw_ids_from_response(
    method _summarize_command_response (line 118) | def _summarize_command_response(response: Optional[SubmitCommandRespon...
    method _resolve_abort_mission_type (line 137) | def _resolve_abort_mission_type(return_behavior: ReturnBehavior) -> Mi...
    method _submit_control_command (line 144) | async def _submit_control_command(
    method _get_drone_gps_positions (line 162) | def _get_drone_gps_positions(self, deps: Any, pos_ids: Optional[List[i...
    method _build_ready_drone_states (line 178) | def _build_ready_drone_states(operation: QuickScoutOperationRecord) ->...
    method _calculate_total_coverage (line 193) | def _calculate_total_coverage(drone_states: Dict[str, DroneSurveyState...
    method _return_behavior_label (line 199) | def _return_behavior_label(return_behavior: ReturnBehavior) -> str:
    method _derive_operation_phase (line 206) | def _derive_operation_phase(self, operation: QuickScoutOperationRecord...
    method _build_control_availability (line 229) | def _build_control_availability(
    method _build_status_summary (line 278) | def _build_status_summary(
    method _build_last_known_point_polygon (line 333) | def _build_last_known_point_polygon(
    method _resolve_search_area_for_planning (line 351) | def _resolve_search_area_for_planning(
    method _build_corridor_search_polygon (line 394) | def _build_corridor_search_polygon(
    method plan_mission (line 448) | async def plan_mission(self, deps: Any, request: QuickScoutMissionRequ...
    method _apply_camera_interval (line 524) | def _apply_camera_interval(waypoints, camera_interval_s: float):
    method get_operation (line 532) | def get_operation(self, mission_id: str) -> Optional[QuickScoutOperati...
    method get_plans (line 535) | def get_plans(self, mission_id: str):
    method get_config (line 539) | def get_config(self, mission_id: str):
    method get_status (line 543) | def get_status(self, mission_id: str) -> Optional[MissionStatus]:
    method list_operation_summaries (line 568) | def list_operation_summaries(
    method get_workspace (line 606) | def get_workspace(self, mission_id: str) -> Optional[QuickScoutMission...
    method _handoff_sort_key (line 614) | def _handoff_sort_key(finding: QuickScoutFinding) -> Tuple[int, int, f...
    method _build_handoff_brief (line 630) | def _build_handoff_brief(
    method get_mission_handoff (line 676) | def get_mission_handoff(self, mission_id: str) -> Optional[QuickScoutM...
    method start_mission (line 754) | def start_mission(
    method update_drone_progress (line 789) | def update_drone_progress(
    method pause_mission (line 844) | def pause_mission(self, mission_id: str, hw_ids: Optional[List[str]] =...
    method resume_mission (line 865) | def resume_mission(self, mission_id: str, hw_ids: Optional[List[str]] ...
    method abort_mission (line 881) | def abort_mission(
    method _persist_last_command_summary (line 914) | def _persist_last_command_summary(
    method _build_launch_summary_payload (line 930) | def _build_launch_summary_payload(
    method _build_control_summary_payload (line 958) | def _build_control_summary_payload(
    method launch_mission (line 978) | async def launch_mission(self, deps: Any, mission_id: str) -> QuickSco...
    method pause_and_command (line 1085) | async def pause_and_command(
    method resume_and_record (line 1143) | def resume_and_record(
    method abort_and_command (line 1177) | async def abort_and_command(
    method report_progress (line 1238) | def report_progress(self, mission_id: str, report: DroneProgressReport...
    method add_finding (line 1251) | def add_finding(
    method get_findings (line 1273) | def get_findings(self, mission_id: str) -> List[QuickScoutFinding]:
    method update_finding (line 1276) | def update_finding(
    method delete_finding (line 1301) | def delete_finding(self, finding_id: str) -> bool:

FILE: gcs-server/sar/store.py
  function get_quickscout_store (line 30) | def get_quickscout_store() -> "QuickScoutStore":
  class QuickScoutStore (line 39) | class QuickScoutStore:
    method __init__ (line 42) | def __init__(self, db_path: str | None = None):
    method _resolve_default_db_path (line 49) | def _resolve_default_db_path() -> str:
    method _connect (line 57) | def _connect(self) -> sqlite3.Connection:
    method _initialize_schema (line 64) | def _initialize_schema(self) -> None:
    method save_operation (line 112) | def save_operation(self, operation: QuickScoutOperationRecord) -> Quic...
    method get_operation (line 136) | def get_operation(self, mission_id: str) -> Optional[QuickScoutOperati...
    method delete_operation (line 148) | def delete_operation(self, mission_id: str) -> bool:
    method save_finding (line 156) | def save_finding(self, mission_id: str, finding: QuickScoutFinding) ->...
    method list_findings (line 182) | def list_findings(self, mission_id: str) -> list[QuickScoutFinding]:
    method get_finding (line 195) | def get_finding(self, finding_id: str) -> Optional[QuickScoutFinding]:
    method delete_finding (line 205) | def delete_finding(self, finding_id: str) -> bool:
    method reset_all (line 213) | def reset_all(self) -> None:
    method list_operations (line 227) | def list_operations(self) -> Iterable[QuickScoutOperationRecord]:

FILE: gcs-server/sar/terrain.py
  function batch_get_elevations (line 24) | async def batch_get_elevations(points: List[dict], chunk_size: int = 100...
  function apply_terrain_following (line 51) | async def apply_terrain_following(

FILE: gcs-server/schemas.py
  class DroneState (line 30) | class DroneState(str, Enum):
  class FlightMode (line 42) | class FlightMode(str, Enum):
  class GitStatus (line 57) | class GitStatus(str, Enum):
  class DroneConfig (line 71) | class DroneConfig(BaseModel):
  class FleetConfig (line 85) | class FleetConfig(BaseModel):
  class FleetConfigEntryPayload (line 91) | class FleetConfigEntryPayload(BaseModel):
  class SwarmAssignment (line 101) | class SwarmAssignment(BaseModel):
  class SwarmConfig (line 113) | class SwarmConfig(BaseModel):
  class SwarmConfigSaveResponse (line 119) | class SwarmConfigSaveResponse(BaseModel):
  class SwarmAssignmentPatchRequest (line 127) | class SwarmAssignmentPatchRequest(BaseModel):
  class SwarmAssignmentUpdateResponse (line 138) | class SwarmAssignmentUpdateResponse(BaseModel):
  class ConfigListResponse (line 145) | class ConfigListResponse(BaseModel):
  class ConfigUpdateRequest (line 152) | class ConfigUpdateRequest(BaseModel):
  class ConfigUpdateResponse (line 157) | class ConfigUpdateResponse(BaseModel):
  class ConnectivityProfileUpdateRequest (line 165) | class ConnectivityProfileUpdateRequest(BaseModel):
  class ConnectivityProfileStatusResponse (line 173) | class ConnectivityProfileStatusResponse(BaseModel):
  class FleetCandidateState (line 191) | class FleetCandidateState(str, Enum):
  class FleetCandidateRecord (line 201) | class FleetCandidateRecord(BaseModel):
    method normalize_candidate_runtime_mode (line 241) | def normalize_candidate_runtime_mode(cls, value):
  class FleetCandidateListResponse (line 252) | class FleetCandidateListResponse(BaseModel):
  class FleetCandidateAnnounceRequest (line 262) | class FleetCandidateAnnounceRequest(BaseModel):
    method normalize_candidate_hw_id (line 285) | def normalize_candidate_hw_id(cls, value):
    method normalize_candidate_announce_runtime_mode (line 294) | def normalize_candidate_announce_runtime_mode(cls, value):
  class FleetCandidateActionRequest (line 305) | class FleetCandidateActionRequest(BaseModel):
  class FleetCandidateAcceptRequest (line 312) | class FleetCandidateAcceptRequest(BaseModel):
  class FleetCandidateReplaceRequest (line 325) | class FleetCandidateReplaceRequest(BaseModel):
  class FleetCandidateRecoverRequest (line 337) | class FleetCandidateRecoverRequest(BaseModel):
  class FleetCandidatePostSyncPlan (line 348) | class FleetCandidatePostSyncPlan(BaseModel):
  class FleetCandidateMutationResponse (line 358) | class FleetCandidateMutationResponse(BaseModel):
  class PositionNED (line 375) | class PositionNED(BaseModel):
  class PositionGPS (line 382) | class PositionGPS(BaseModel):
  class VelocityNED (line 389) | class VelocityNED(BaseModel):
  class AttitudeEuler (line 396) | class AttitudeEuler(BaseModel):
  class BatteryStatus (line 403) | class BatteryStatus(BaseModel):
  class TelemetryReadinessCheck (line 410) | class TelemetryReadinessCheck(BaseModel):
  class TelemetryReadinessMessage (line 418) | class TelemetryReadinessMessage(BaseModel):
  class DroneTelemetry (line 426) | class DroneTelemetry(BaseModel):
    method normalize_hw_id (line 493) | def normalize_hw_id(cls, value: Any) -> str:
  class TelemetryResponse (line 498) | class TelemetryResponse(BaseModel):
    method normalize_telemetry_keys (line 507) | def normalize_telemetry_keys(cls, value: Any) -> Any:
  class HeartbeatData (line 518) | class HeartbeatData(BaseModel):
  class HeartbeatResponse (line 532) | class HeartbeatResponse(BaseModel):
  class HeartbeatRequest (line 541) | class HeartbeatRequest(BaseModel):
    method normalize_hw_id (line 553) | def normalize_hw_id(cls, value):
    method normalize_ip (line 568) | def normalize_ip(cls, value):
    method normalize_runtime_mode (line 581) | def normalize_runtime_mode(cls, value):
  class HeartbeatPostResponse (line 594) | class HeartbeatPostResponse(BaseModel):
  class DroneMavlinkRuntimeStatus (line 605) | class DroneMavlinkRuntimeStatus(BaseModel):
  class DroneConnectivityRuntimeStatus (line 626) | class DroneConnectivityRuntimeStatus(BaseModel):
  class DroneGitSyncRuntimeStatus (line 647) | class DroneGitSyncRuntimeStatus(BaseModel):
  class DroneEnvRuntimeStatus (line 663) | class DroneEnvRuntimeStatus(BaseModel):
  class DroneGitStatus (line 685) | class DroneGitStatus(BaseModel):
  class GitStatusResponse (line 723) | class GitStatusResponse(BaseModel):
  class SyncReposRequest (line 734) | class SyncReposRequest(BaseModel):
  class SyncReposResponse (line 740) | class SyncReposResponse(BaseModel):
  class TrajectoryPoint (line 755) | class TrajectoryPoint(BaseModel):
  class DroneTrajectory (line 764) | class DroneTrajectory(BaseModel):
  class SwarmTrajectory (line 772) | class SwarmTrajectory(BaseModel):
  class SwarmTrajectoryLeaderListResponse (line 781) | class SwarmTrajectoryLeaderListResponse(BaseModel):
    method _normalize_swarm_mapping_keys (line 799) | def _normalize_swarm_mapping_keys(cls, value: Any) -> Any:
  class SwarmTrajectoryUploadResponse (line 805) | class SwarmTrajectoryUploadResponse(BaseModel):
  class SwarmTrajectoryProcessRequest (line 813) | class SwarmTrajectoryProcessRequest(BaseModel):
  class SwarmTrajectoryCommitRequest (line 822) | class SwarmTrajectoryCommitRequest(BaseModel):
    method _normalize_commit_message (line 831) | def _normalize_commit_message(cls, value: Any) -> Any:
  class SwarmTrajectoryProcessingChanges (line 838) | class SwarmTrajectoryProcessingChanges(BaseModel):
  class SwarmTrajectoryProcessingRecommendation (line 852) | class SwarmTrajectoryProcessingRecommendation(BaseModel):
  class SwarmTrajectoryRecommendationResponse (line 867) | class SwarmTrajectoryRecommendationResponse(BaseModel):
  class SwarmTrajectoryDronePackageStats (line 874) | class SwarmTrajectoryDronePackageStats(BaseModel):
  class SwarmTrajectoryPackageStats (line 886) | class SwarmTrajectoryPackageStats(BaseModel):
  class SwarmTrajectoryClusterSummary (line 900) | class SwarmTrajectoryClusterSummary(BaseModel):
  class SwarmTrajectoryClusterStatus (line 913) | class SwarmTrajectoryClusterStatus(BaseModel):
  class SwarmTrajectorySessionStatus (line 934) | class SwarmTrajectorySessionStatus(BaseModel):
  class SwarmTrajectoryStatusPayload (line 944) | class SwarmTrajectoryStatusPayload(BaseModel):
    method _normalize_status_mapping_keys (line 976) | def _normalize_status_mapping_keys(cls, value: Any) -> Any:
  class SwarmTrajectoryStatusResponse (line 982) | class SwarmTrajectoryStatusResponse(BaseModel):
  class SwarmTrajectoryProcessingStatistics (line 990) | class SwarmTrajectoryProcessingStatistics(BaseModel):
  class SwarmTrajectoryProcessResponse (line 998) | class SwarmTrajectoryProcessResponse(BaseModel):
  class SwarmTrajectoryPolicyAltitude (line 1017) | class SwarmTrajectoryPolicyAltitude(BaseModel):
  class SwarmTrajectoryPolicySpeed (line 1026) | class SwarmTrajectoryPolicySpeed(BaseModel):
  class SwarmTrajectoryPolicyTiming (line 1035) | class SwarmTrajectoryPolicyTiming(BaseModel):
  class SwarmTrajectoryPolicyTerrain (line 1043) | class SwarmTrajectoryPolicyTerrain(BaseModel):
  class SwarmTrajectoryPolicyPayload (line 1050) | class SwarmTrajectoryPolicyPayload(BaseModel):
  class SwarmTrajectoryPolicyResponse (line 1059) | class SwarmTrajectoryPolicyResponse(BaseModel):
  class SwarmTrajectoryClearProcessedResponse (line 1066) | class SwarmTrajectoryClearProcessedResponse(BaseModel):
  class SwarmTrajectoryClearAllResponse (line 1074) | class SwarmTrajectoryClearAllResponse(BaseModel):
  class SwarmTrajectoryRemoveLeaderResponse (line 1082) | class SwarmTrajectoryRemoveLeaderResponse(BaseModel):
  class SwarmTrajectoryClearLeaderResponse (line 1091) | class SwarmTrajectoryClearLeaderResponse(BaseModel):
  class SwarmTrajectoryClearDroneResponse (line 1099) | class SwarmTrajectoryClearDroneResponse(BaseModel):
  class SwarmTrajectoryCommitResponse (line 1107) | class SwarmTrajectoryCommitResponse(BaseModel):
  class ShowImportRequest (line 1119) | class ShowImportRequest(BaseModel):
  class ShowImportResponse (line 1125) | class ShowImportResponse(BaseModel):
  class ShowDeploymentRequest (line 1139) | class ShowDeploymentRequest(BaseModel):
    method _normalize_show_deployment_message (line 1147) | def _normalize_show_deployment_message(cls, value):
  class ShowDeploymentResponse (line 1154) | class ShowDeploymentResponse(BaseModel):
  class CustomShowInfoResponse (line 1161) | class CustomShowInfoResponse(BaseModel):
  class CustomShowImportResponse (line 1173) | class CustomShowImportResponse(BaseModel):
  class CommandRequest (line 1188) | class CommandRequest(BaseModel):
  class CommandResponse (line 1195) | class CommandResponse(BaseModel):
  class OriginRequest (line 1208) | class OriginRequest(BaseModel):
  class OriginComputeRequest (line 1216) | class OriginComputeRequest(BaseModel):
  class OriginComputeResponse (line 1223) | class OriginComputeResponse(BaseModel):
  class OriginResponse (line 1230) | class OriginResponse(BaseModel):
  class GPSGlobalOriginResponse (line 1239) | class GPSGlobalOriginResponse(BaseModel):
  class GCSConfigResponse (line 1247) | class GCSConfigResponse(BaseModel):
  class GCSConfigUpdateRequest (line 1264) | class GCSConfigUpdateRequest(BaseModel):
  class GCSConfigSaveResponse (line 1275) | class GCSConfigSaveResponse(BaseModel):
  class GCSConfigApplyResponse (line 1289) | class GCSConfigApplyResponse(BaseModel):
  class GCSRuntimeUpdateResponse (line 1302) | class GCSRuntimeUpdateResponse(BaseModel):
  class EnvRegistryEntryResponse (line 1319) | class EnvRegistryEntryResponse(BaseModel):
  class EnvRegistryResponse (line 1344) | class EnvRegistryResponse(BaseModel):
  class GCSRuntimeEnvEntryResponse (line 1353) | class GCSRuntimeEnvEntryResponse(BaseModel):
  class GCSRuntimeEnvResponse (line 1378) | class GCSRuntimeEnvResponse(BaseModel):
  class GCSRuntimeEnvUpdateRequest (line 1391) | class GCSRuntimeEnvUpdateRequest(BaseModel):
  class GCSRuntimeEnvUpdateResponse (line 1398) | class GCSRuntimeEnvUpdateResponse(BaseModel):
  class FleetRuntimeEnvPlanRequest (line 1411) | class FleetRuntimeEnvPlanRequest(BaseModel):
  class FleetRuntimeEnvNodePlan (line 1423) | class FleetRuntimeEnvNodePlan(BaseModel):
  class FleetRuntimeEnvPlanResponse (line 1439) | class FleetRuntimeEnvPlanResponse(BaseModel):
  class FleetRuntimeEnvNodeResponse (line 1456) | class FleetRuntimeEnvNodeResponse(BaseModel):
  class FleetRuntimeEnvNodeUpdateResponse (line 1473) | class FleetRuntimeEnvNodeUpdateResponse(BaseModel):
  class GCSRuntimeEnvApplyResponse (line 1488) | class GCSRuntimeEnvApplyResponse(BaseModel):
  class RuntimeDocsResponse (line 1500) | class RuntimeDocsResponse(BaseModel):
  class RuntimeFleetDefaultsResponse (line 1510) | class RuntimeFleetDefaultsResponse(BaseModel):
  class RuntimeGitAuthHealthResponse (line 1531) | class RuntimeGitAuthHealthResponse(BaseModel):
  class RuntimeRepoSyncStatusResponse (line 1539) | class RuntimeRepoSyncStatusResponse(BaseModel):
  class RuntimeMavlinkRuntimeResponse (line 1554) | class RuntimeMavlinkRuntimeResponse(BaseModel):
  class RuntimeConnectivityRuntimeResponse (line 1576) | class RuntimeConnectivityRuntimeResponse(BaseModel):
  class RuntimeStatusResponse (line 1598) | class RuntimeStatusResponse(BaseModel):
  class NetworkStatus (line 1637) | class NetworkStatus(BaseModel):
  class NetworkStatusResponse (line 1646) | class NetworkStatusResponse(BaseModel):
  class HealthCheckResponse (line 1654) | class HealthCheckResponse(BaseModel):
  class ErrorDetail (line 1666) | class ErrorDetail(BaseModel):
  class ErrorResponse (line 1673) | class ErrorResponse(BaseModel):
  class WebSocketMessage (line 1685) | class WebSocketMessage(BaseModel):
  class TelemetryStreamMessage (line 1692) | class TelemetryStreamMessage(WebSocketMessage):
    method normalize_data_keys (line 1699) | def normalize_data_keys(cls, value: Any) -> Any:
  class GitStatusStreamMessage (line 1706) | class GitStatusStreamMessage(WebSocketMessage):
  class HeartbeatStreamMessage (line 1713) | class HeartbeatStreamMessage(WebSocketMessage):
  class DroneAckDetail (line 1724) | class DroneAckDetail(BaseModel):
  class DroneExecutionDetail (line 1742) | class DroneExecutionDetail(BaseModel):
  class AckSummary (line 1751) | class AckSummary(BaseModel):
  class ExecutionSummary (line 1763) | class ExecutionSummary(BaseModel):
  class LateAckSummary (line 1774) | class LateAckSummary(BaseModel):
  class LateExecutionStartSummary (line 1784) | class LateExecutionStartSummary(BaseModel):
  class LateExecutionSummary (line 1790) | class LateExecutionSummary(BaseModel):
  class LateReportSummary (line 1798) | class LateReportSummary(BaseModel):
  class CommandProgressSummary (line 1805) | class CommandProgressSummary(BaseModel):
  class CommandStatusResponse (line 1819) | class CommandStatusResponse(BaseModel):
  class CommandListResponse (line 1847) | class CommandListResponse(BaseModel):
  class CommandStatisticsResponse (line 1854) | class CommandStatisticsResponse(BaseModel):
  class PrecisionMovePolicyDefaults (line 1868) | class PrecisionMovePolicyDefaults(BaseModel):
  class PrecisionMovePolicyLimits (line 1877) | class PrecisionMovePolicyLimits(BaseModel):
  class PrecisionMovePolicyExecution (line 1887) | class PrecisionMovePolicyExecution(BaseModel):
  class PrecisionMovePolicyResponse (line 1897) | class PrecisionMovePolicyResponse(BaseModel):
  class SubmitCommandRequest (line 1905) | class SubmitCommandRequest(SharedSubmitCommandRequest):
  class SubmitCommandResponse (line 1909) | class SubmitCommandResponse(BaseModel):
  class ExecutionReportRequest (line 1944) | class ExecutionReportRequest(BaseModel):
  class ExecutionStartRequest (line 1955) | class ExecutionStartRequest(BaseModel):
  class ExecutionStartResponse (line 1962) | class ExecutionStartResponse(BaseModel):
  class ExecutionReportResponse (line 1972) | class ExecutionReportResponse(BaseModel):

FILE: gcs-server/show_management.py
  function copy_directory_contents (line 25) | def copy_directory_contents(src_dir: str, dst_dir: str) -> None:
  function swarm_directory (line 36) | def swarm_directory(shapes_dir: str) -> str:
  function saved_metrics_path (line 40) | def saved_metrics_path(shapes_dir: str) -> str:
  function count_processed_drone_files (line 44) | def count_processed_drone_files(directory: str) -> int:
  function custom_show_csv_path (line 56) | def custom_show_csv_path(shapes_dir: str) -> str:
  function custom_show_preview_path (line 60) | def custom_show_preview_path(shapes_dir: str) -> str:
  function inspect_custom_show_csv (line 64) | def inspect_custom_show_csv(csv_path: str) -> Dict[str, Any]:
  function generate_custom_show_preview (line 146) | def generate_custom_show_preview(points: List[Dict[str, float]], preview...
  function load_saved_metrics_if_current (line 181) | def load_saved_metrics_if_current(
  function refresh_saved_show_metrics (line 215) | def refresh_saved_show_metrics(
  function import_show_archive (line 235) | def import_show_archive(
  function build_show_info_payload (line 364) | def build_show_info_payload(skybrush_dir: str) -> Dict[str, Any]:
  function build_custom_show_info_payload (line 412) | def build_custom_show_info_payload(shapes_dir: str) -> Dict[str, Any]:
  function import_custom_show_csv (line 432) | def import_custom_show_csv(
  function build_comprehensive_metrics_payload (line 499) | def build_comprehensive_metrics_payload(
  function build_safety_report_payload (line 515) | def build_safety_report_payload(
  function build_trajectory_validation_payload (line 548) | def build_trajectory_validation_payload(
  function resolve_show_plot_path (line 594) | def resolve_show_plot_path(plots_directory: str, filename: str) -> Path:
  function list_show_plots_payload (line 606) | def list_show_plots_payload(plots_directory: str) -> Dict[str, Any]:
  function resolve_custom_show_image_path (line 620) | def resolve_custom_show_image_path(shapes_dir: str) -> str:

FILE: gcs-server/telemetry.py
  function _build_link_blocker (line 38) | def _build_link_blocker(now_ms: int, message: str) -> Dict[str, Any]:
  function _build_telemetry_unavailable_record (line 47) | def _build_telemetry_unavailable_record(drone_id: str, drone_ip: str, er...
  function _normalize_heartbeat_first_seen (line 75) | def _normalize_heartbeat_first_seen(value):
  function _log_system_event (line 94) | def _log_system_event(message: str, level: str = "INFO", component: str ...
  function _format_log_value (line 101) | def _format_log_value(value):
  function _build_telemetry_message (line 109) | def _build_telemetry_message(details):
  function _log_drone_telemetry_event (line 140) | def _log_drone_telemetry_event(drone_id: str, success: bool, details) ->...
  function get_enum_name (line 156) | def get_enum_name(enum_class, value):
  function initialize_telemetry_tracking (line 169) | def initialize_telemetry_tracking(drones):
  function update_telemetry_stats (line 188) | def update_telemetry_stats(drone_id: str, success: bool):
  function _get_enhanced_armed_status (line 203) | def _get_enhanced_armed_status(telemetry_data):
  function should_log_telemetry_event (line 225) | def should_log_telemetry_event(drone_id: str, success: bool) -> bool:
  function poll_telemetry (line 272) | def poll_telemetry(drone):
  function start_telemetry_polling (line 515) | def start_telemetry_polling(drones):
  function _start_telemetry_reporter (line 554) | def _start_telemetry_reporter():
  function get_telemetry_summary (line 608) | def get_telemetry_summary():

FILE: gcs-server/utils.py
  function allowed_file (line 18) | def allowed_file(filename):
  function clear_show_directories (line 25) | def clear_show_directories(base_dir):
  function zip_directory (line 67) | def zip_directory(folder_path, zip_path):
  function ensure_directory (line 73) | def ensure_directory(directory):
  function _run_git_with_timeout (line 78) | def _run_git_with_timeout(git_cmd, args, timeout):
  function _rollback_auto_commit (line 93) | def _rollback_auto_commit(git, commit_hash):
  function git_operations (line 108) | def git_operations(base_dir, commit_message, timeout=30):

FILE: led_indicator.py
  function parse_arguments (line 84) | def parse_arguments():
  function get_rgb_from_name (line 115) | def get_rgb_from_name(name: str) -> tuple:
  function get_color (line 147) | def get_color(color_name: str):
  function initialize_strip (line 162) | def initialize_strip() -> PixelStrip:
  function set_strip_color (line 181) | def set_strip_color(strip: PixelStrip, color: Color):
  function list_available_states (line 193) | def list_available_states():
  function main (line 212) | def main():

FILE: mavsdk/_base.py
  class AsyncBase (line 4) | class AsyncBase:
    method __init__ (line 9) | def __init__(self, async_plugin_manager):
    method _init_plugin (line 12) | def _init_plugin(self, async_plugin_manager):
    method _setup_stub (line 19) | def _setup_stub(self, channel):

FILE: mavsdk/action.py
  class OrbitYawBehavior (line 9) | class OrbitYawBehavior(Enum):
    method translate_to_rpc (line 39) | def translate_to_rpc(self):
    method translate_from_rpc (line 52) | def translate_from_rpc(rpc_enum_value):
    method __str__ (line 65) | def __str__(self):
  class ActionResult (line 69) | class ActionResult:
    class Result (line 85) | class Result(Enum):
      method translate_to_rpc (line 151) | def translate_to_rpc(self):
      method translate_from_rpc (line 182) | def translate_from_rpc(rpc_enum_value):
      method __str__ (line 213) | def __str__(self):
    method __init__ (line 217) | def __init__(
    method __eq__ (line 225) | def __eq__(self, to_compare):
    method __str__ (line 237) | def __str__(self):
    method translate_from_rpc (line 247) | def translate_from_rpc(rpcActionResult):
    method translate_to_rpc (line 257) | def translate_to_rpc(self, rpcActionResult):
  class ActionError (line 276) | class ActionError(Exception):
    method __init__ (line 279) | def __init__(self, result, origin, *params):
    method __str__ (line 284) | def __str__(self):
  class Action (line 288) | class Action(AsyncBase):
    method _setup_stub (line 298) | def _setup_stub(self, channel):
    method _extract_result (line 303) | def _extract_result(self, response):
    method arm (line 308) | async def arm(self):
    method disarm (line 331) | async def disarm(self):
    method takeoff (line 354) | async def takeoff(self):
    method land (line 379) | async def land(self):
    method reboot (line 401) | async def reboot(self):
    method shutdown (line 423) | async def shutdown(self):
    method terminate (line 447) | async def terminate(self):
    method kill (line 469) | async def kill(self):
    method return_to_launch (line 492) | async def return_to_launch(self):
    method goto_location (line 516) | async def goto_location(self, latitude_deg, longitude_deg, absolute_al...
    method do_orbit (line 559) | async def do_orbit(self, radius_m, velocity_ms, yaw_behavior, latitude...
    method hold (line 610) | async def hold(self):
    method set_actuator (line 636) | async def set_actuator(self, index, value):
    method transition_to_fixedwing (line 666) | async def transition_to_fixedwing(self):
    method transition_to_multicopter (line 690) | async def transition_to_multicopter(self):
    method get_takeoff_altitude (line 714) | async def get_takeoff_altitude(self):
    method set_takeoff_altitude (line 742) | async def set_takeoff_altitude(self, altitude):
    method get_maximum_speed (line 768) | async def get_maximum_speed(self):
    method set_maximum_speed (line 796) | async def set_maximum_speed(self, speed):
    method get_return_to_launch_altitude (line 822) | async def get_return_to_launch_altitude(self):
    method set_return_to_launch_altitude (line 850) | async def set_return_to_launch_altitude(self, relative_altitude_m):
    method set_current_speed (line 876) | async def set_current_speed(self, speed_m_s):

FILE: mavsdk/action_pb2_grpc.py
  class ActionServiceStub (line 8) | class ActionServiceStub(object):
    method __init__ (line 12) | def __init__(self, channel):
  class ActionServiceServicer (line 130) | class ActionServiceServicer(object):
    method Arm (line 134) | def Arm(self, request, context):
    method Disarm (line 145) | def Disarm(self, request, context):
    method Takeoff (line 156) | def Takeoff(self, request, context):
    method Land (line 169) | def Land(self, request, context):
    method Reboot (line 179) | def Reboot(self, request, context):
    method Shutdown (line 189) | def Shutdown(self, request, context):
    method Terminate (line 201) | def Terminate(self, request, context):
    method Kill (line 211) | def Kill(self, request, context):
    method ReturnToLaunch (line 222) | def ReturnToLaunch(self, request, context):
    method GotoLocation (line 234) | def GotoLocation(self, request, context):
    method DoOrbit (line 247) | def DoOrbit(self, request, context):
    method Hold (line 257) | def Hold(self, request, context):
    method SetActuator (line 271) | def SetActuator(self, request, context):
    method TransitionToFixedwing (line 279) | def TransitionToFixedwing(self, request, context):
    method TransitionToMulticopter (line 291) | def TransitionToMulticopter(self, request, context):
    method GetTakeoffAltitude (line 303) | def GetTakeoffAltitude(self, request, context):
    method SetTakeoffAltitude (line 311) | def SetTakeoffAltitude(self, request, context):
    method GetMaximumSpeed (line 319) | def GetMaximumSpeed(self, request, context):
    method SetMaximumSpeed (line 327) | def SetMaximumSpeed(self, request, context):
    method GetReturnToLaunchAltitude (line 335) | def GetReturnToLaunchAltitude(self, request, context):
    method SetReturnToLaunchAltitude (line 343) | def SetReturnToLaunchAltitude(self, request, context):
    method SetCurrentSpeed (line 351) | def SetCurrentSpeed(self, request, context):
  function add_ActionServiceServicer_to_server (line 363) | def add_ActionServiceServicer_to_server(servicer, server):
  class ActionService (line 482) | class ActionService(object):
    method Arm (line 487) | def Arm(request,
    method Disarm (line 504) | def Disarm(request,
    method Takeoff (line 521) | def Takeoff(request,
    method Land (line 538) | def Land(request,
    method Reboot (line 555) | def Reboot(request,
    method Shutdown (line 572) | def Shutdown(request,
    method Terminate (line 589) | def Terminate(request,
    method Kill (line 606) | def Kill(request,
    method ReturnToLaunch (line 623) | def ReturnToLaunch(request,
    method GotoLocation (line 640) | def GotoLocation(request,
    method DoOrbit (line 657) | def DoOrbit(request,
    method Hold (line 674) | def Hold(request,
    method SetActuator (line 691) | def SetActuator(request,
    method TransitionToFixedwing (line 708) | def TransitionToFixedwing(request,
    method TransitionToMulticopter (line 725) | def TransitionToMulticopter(request,
    method GetTakeoffAltitude (line 742) | def GetTakeoffAltitude(request,
    method SetTakeoffAltitude (line 759) | def SetTakeoffAltitude(request,
    method GetMaximumSpeed (line 776) | def GetMaximumSpeed(request,
    method SetMaximumSpeed (line 793) | def SetMaximumSpeed(request,
    method GetReturnToLaunchAltitude (line 810) | def GetReturnToLaunchAltitude(request,
    method SetReturnToLaunchAltitude (line 827) | def SetReturnToLaunchAltitude(request,
    method SetCurrentSpeed (line 844) | def SetCurrentSpeed(request,

FILE: mavsdk/action_server.py
  class FlightMode (line 9) | class FlightMode(Enum):
    method translate_to_rpc (line 78) | def translate_to_rpc(self):
    method translate_from_rpc (line 109) | def translate_from_rpc(rpc_enum_value):
    method __str__ (line 140) | def __str__(self):
  class AllowableFlightModes (line 144) | class AllowableFlightModes:
    method __init__ (line 164) | def __init__(
    method __eq__ (line 174) | def __eq__(self, to_compare):
    method __str__ (line 187) | def __str__(self):
    method translate_from_rpc (line 198) | def translate_from_rpc(rpcAllowableFlightModes):
    method translate_to_rpc (line 211) | def translate_to_rpc(self, rpcAllowableFlightModes):
  class ArmDisarm (line 235) | class ArmDisarm:
    method __init__ (line 251) | def __init__(
    method __eq__ (line 259) | def __eq__(self, to_compare):
    method __str__ (line 271) | def __str__(self):
    method translate_from_rpc (line 281) | def translate_from_rpc(rpcArmDisarm):
    method translate_to_rpc (line 291) | def translate_to_rpc(self, rpcArmDisarm):
  class ActionServerResult (line 309) | class ActionServerResult:
    class Result (line 325) | class Result(Enum):
      method translate_to_rpc (line 387) | def translate_to_rpc(self):
      method translate_from_rpc (line 416) | def translate_from_rpc(rpc_enum_value):
      method __str__ (line 445) | def __str__(self):
    method __init__ (line 449) | def __init__(
    method __eq__ (line 457) | def __eq__(self, to_compare):
    method __str__ (line 469) | def __str__(self):
    method translate_from_rpc (line 479) | def translate_from_rpc(rpcActionServerResult):
    method translate_to_rpc (line 489) | def translate_to_rpc(self, rpcActionServerResult):
  class ActionServerError (line 508) | class ActionServerError(Exception):
    method __init__ (line 511) | def __init__(self, result, origin, *params):
    method __str__ (line 516) | def __str__(self):
  class ActionServer (line 520) | class ActionServer(AsyncBase):
    method _setup_stub (line 530) | def _setup_stub(self, channel):
    method _extract_result (line 535) | def _extract_result(self, response):
    method arm_disarm (line 540) | async def arm_disarm(self):
    method flight_mode_change (line 579) | async def flight_mode_change(self):
    method takeoff (line 618) | async def takeoff(self):
    method land (line 657) | async def land(self):
    method reboot (line 696) | async def reboot(self):
    method shutdown (line 735) | async def shutdown(self):
    method terminate (line 774) | async def terminate(self):
    method set_allow_takeoff (line 813) | async def set_allow_takeoff(self, allow_takeoff):
    method set_armable (line 839) | async def set_armable(self, armable, force_armable):
    method set_disarmable (line 869) | async def set_disarmable(self, disarmable, force_disarmable):
    method set_allowable_flight_modes (line 899) | async def set_allowable_flight_modes(self, flight_modes):
    method get_allowable_flight_modes (line 927) | async def get_allowable_flight_modes(self):

FILE: mavsdk/action_server_pb2_grpc.py
  class ActionServerServiceStub (line 8) | class ActionServerServiceStub(object):
    method __init__ (line 12) | def __init__(self, channel):
  class ActionServerServiceServicer (line 80) | class ActionServerServiceServicer(object):
    method SubscribeArmDisarm (line 84) | def SubscribeArmDisarm(self, request, context):
    method SubscribeFlightModeChange (line 91) | def SubscribeFlightModeChange(self, request, context):
    method SubscribeTakeoff (line 98) | def SubscribeTakeoff(self, request, context):
    method SubscribeLand (line 105) | def SubscribeLand(self, request, context):
    method SubscribeReboot (line 112) | def SubscribeReboot(self, request, context):
    method SubscribeShutdown (line 119) | def SubscribeShutdown(self, request, context):
    method SubscribeTerminate (line 126) | def SubscribeTerminate(self, request, context):
    method SetAllowTakeoff (line 133) | def SetAllowTakeoff(self, request, context):
    method SetArmable (line 140) | def SetArmable(self, request, context):
    method SetDisarmable (line 147) | def SetDisarmable(self, request, context):
    method SetAllowableFlightModes (line 154) | def SetAllowableFlightModes(self, request, context):
    method GetAllowableFlightModes (line 161) | def GetAllowableFlightModes(self, request, context):
  function add_ActionServerServiceServicer_to_server (line 169) | def add_ActionServerServiceServicer_to_server(servicer, server):
  class ActionServerService (line 238) | class ActionServerService(object):
    method SubscribeArmDisarm (line 243) | def SubscribeArmDisarm(request,
    method SubscribeFlightModeChange (line 260) | def SubscribeFlightModeChange(request,
    method SubscribeTakeoff (line 277) | def SubscribeTakeoff(request,
    method SubscribeLand (line 294) | def SubscribeLand(request,
    method SubscribeReboot (line 311) | def SubscribeReboot(request,
    method SubscribeShutdown (line 328) | def SubscribeShutdown(request,
    method SubscribeTerminate (line 345) | def SubscribeTerminate(request,
    method SetAllowTakeoff (line 362) | def SetAllowTakeoff(request,
    method SetArmable (line 379) | def SetArmable(request,
    method SetDisarmable (line 396) | def SetDisarmable(request,
    method SetAllowableFlightModes (line 413) | def SetAllowableFlightModes(request,
    method GetAllowableFlightModes (line 430) | def GetAllowableFlightModes(request,

FILE: mavsdk/async_plugin_manager.py
  class AsyncPluginManager (line 6) | class AsyncPluginManager:
    method create (line 11) | async def create(cls, host, port=50051):
    method _connect_backend (line 23) | async def _connect_backend(self):
    method channel (line 42) | def channel(self):

FILE: mavsdk/calibration.py
  class CalibrationResult (line 9) | class CalibrationResult:
    class Result (line 25) | class Result(Enum):
      method translate_to_rpc (line 83) | def translate_to_rpc(self):
      method translate_from_rpc (line 110) | def translate_from_rpc(rpc_enum_value):
      method __str__ (line 137) | def __str__(self):
    method __init__ (line 141) | def __init__(
    method __eq__ (line 149) | def __eq__(self, to_compare):
    method __str__ (line 161) | def __str__(self):
    method translate_from_rpc (line 171) | def translate_from_rpc(rpcCalibrationResult):
    method translate_to_rpc (line 181) | def translate_to_rpc(self, rpcCalibrationResult):
  class ProgressData (line 199) | class ProgressData:
    method __init__ (line 223) | def __init__(
    method __eq__ (line 235) | def __eq__(self, to_compare):
    method __str__ (line 249) | def __str__(self):
    method translate_from_rpc (line 261) | def translate_from_rpc(rpcProgressData):
    method translate_to_rpc (line 277) | def translate_to_rpc(self, rpcProgressData):
  class CalibrationError (line 308) | class CalibrationError(Exception):
    method __init__ (line 311) | def __init__(self, result, origin, *params):
    method __str__ (line 316) | def __str__(self):
  class Calibration (line 320) | class Calibration(AsyncBase):
    method _setup_stub (line 330) | def _setup_stub(self, channel):
    method _extract_result (line 335) | def _extract_result(self, response):
    method calibrate_gyro (line 340) | async def calibrate_gyro(self):
    method calibrate_accelerometer (line 380) | async def calibrate_accelerometer(self):
    method calibrate_magnetometer (line 420) | async def calibrate_magnetometer(self):
    method calibrate_level_horizon (line 460) | async def calibrate_level_horizon(self):
    method calibrate_gimbal_accelerometer (line 500) | async def calibrate_gimbal_accelerometer(self):
    method cancel (line 540) | async def cancel(self):

FILE: mavsdk/calibration_pb2_grpc.py
  class CalibrationServiceStub (line 8) | class CalibrationServiceStub(object):
    method __init__ (line 12) | def __init__(self, channel):
  class CalibrationServiceServicer (line 50) | class CalibrationServiceServicer(object):
    method SubscribeCalibrateGyro (line 54) | def SubscribeCalibrateGyro(self, request, context):
    method SubscribeCalibrateAccelerometer (line 61) | def SubscribeCalibrateAccelerometer(self, request, context):
    method SubscribeCalibrateMagnetometer (line 68) | def SubscribeCalibrateMagnetometer(self, request, context):
    method SubscribeCalibrateLevelHorizon (line 75) | def SubscribeCalibrateLevelHorizon(self, request, context):
    method SubscribeCalibrateGimbalAccelerometer (line 82) | def SubscribeCalibrateGimbalAccelerometer(self, request, context):
    method Cancel (line 89) | def Cancel(self, request, context):
  function add_CalibrationServiceServicer_to_server (line 97) | def add_CalibrationServiceServicer_to_server(servicer, server):
  class CalibrationService (line 136) | class CalibrationService(object):
    method SubscribeCalibrateGyro (line 141) | def SubscribeCalibrateGyro(request,
    method SubscribeCalibrateAccelerometer (line 158) | def SubscribeCalibrateAccelerometer(request,
    method SubscribeCalibrateMagnetometer (line 175) | def SubscribeCalibrateMagnetometer(request,
    method SubscribeCalibrateLevelHorizon (line 192) | def SubscribeCalibrateLevelHorizon(request,
    method SubscribeCalibrateGimbalAccelerometer (line 209) | def SubscribeCalibrateGimbalAccelerometer(request,
    method Cancel (line 226) | def Cancel(request,

FILE: mavsdk/camera.py
  class Mode (line 9) | class Mode(Enum):
    method translate_to_rpc (line 31) | def translate_to_rpc(self):
    method translate_from_rpc (line 40) | def translate_from_rpc(rpc_enum_value):
    method __str__ (line 49) | def __str__(self):
  class PhotosRange (line 53) | class PhotosRange(Enum):
    method translate_to_rpc (line 71) | def translate_to_rpc(self):
    method translate_from_rpc (line 78) | def translate_from_rpc(rpc_enum_value):
    method __str__ (line 85) | def __str__(self):
  class CameraResult (line 89) | class CameraResult:
    class Result (line 105) | class Result(Enum):
      method translate_to_rpc (line 155) | def translate_to_rpc(self):
      method translate_from_rpc (line 178) | def translate_from_rpc(rpc_enum_value):
      method __str__ (line 201) | def __str__(self):
    method __init__ (line 205) | def __init__(
    method __eq__ (line 213) | def __eq__(self, to_compare):
    method __str__ (line 225) | def __str__(self):
    method translate_from_rpc (line 235) | def translate_from_rpc(rpcCameraResult):
    method translate_to_rpc (line 245) | def translate_to_rpc(self, rpcCameraResult):
  class Position (line 263) | class Position:
    method __init__ (line 285) | def __init__(
    method __eq__ (line 297) | def __eq__(self, to_compare):
    method __str__ (line 311) | def __str__(self):
    method translate_from_rpc (line 323) | def translate_from_rpc(rpcPosition):
    method translate_to_rpc (line 339) | def translate_to_rpc(self, rpcPosition):
  class Quaternion (line 369) | class Quaternion:
    method __init__ (line 398) | def __init__(
    method __eq__ (line 410) | def __eq__(self, to_compare):
    method __str__ (line 424) | def __str__(self):
    method translate_from_rpc (line 436) | def translate_from_rpc(rpcQuaternion):
    method translate_to_rpc (line 452) | def translate_to_rpc(self, rpcQuaternion):
  class EulerAngle (line 482) | class EulerAngle:
    method __init__ (line 506) | def __init__(
    method __eq__ (line 516) | def __eq__(self, to_compare):
    method __str__ (line 529) | def __str__(self):
    method translate_from_rpc (line 540) | def translate_from_rpc(rpcEulerAngle):
    method translate_to_rpc (line 553) | def translate_to_rpc(self, rpcEulerAngle):
  class CaptureInfo (line 577) | class CaptureInfo:
    method __init__ (line 608) | def __init__(
    method __eq__ (line 626) | def __eq__(self, to_compare):
    method __str__ (line 643) | def __str__(self):
    method translate_from_rpc (line 658) | def translate_from_rpc(rpcCaptureInfo):
    method translate_to_rpc (line 683) | def translate_to_rpc(self, rpcCaptureInfo):
  class VideoStreamSettings (line 731) | class VideoStreamSettings:
    method __init__ (line 762) | def __init__(
    method __eq__ (line 780) | def __eq__(self, to_compare):
    method __str__ (line 797) | def __str__(self):
    method translate_from_rpc (line 812) | def translate_from_rpc(rpcVideoStreamSettings):
    method translate_to_rpc (line 837) | def translate_to_rpc(self, rpcVideoStreamSettings):
  class VideoStreamInfo (line 885) | class VideoStreamInfo:
    class VideoStreamStatus (line 904) | class VideoStreamStatus(Enum):
      method translate_to_rpc (line 922) | def translate_to_rpc(self):
      method translate_from_rpc (line 929) | def translate_from_rpc(rpc_enum_value):
      method __str__ (line 936) | def __str__(self):
    class VideoStreamSpe
Copy disabled (too large) Download .json
Condensed preview — 1261 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (56,999K chars).
[
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1782,
    "preview": "# Pull Request\n\n## Description\n\n<!-- Provide a brief description of the changes in this PR -->\n\n## Type of Change\n\n<!-- "
  },
  {
    "path": ".github/RELEASE_TEMPLATE.md",
    "chars": 3498,
    "preview": "# Release Checklist & Template\n\n**Version:** X.Y\n\n**Release Date:** YYYY-MM-DD\n\n---\n\n## Pre-Release Checklist\n\nBefore cr"
  },
  {
    "path": ".github/workflows/pr-validation.yml",
    "chars": 4005,
    "preview": "name: PR Validation\n\non:\n  pull_request:\n    branches: [main, main-candidate]\n    types: [opened, synchronize, reopened]"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 4645,
    "preview": "name: Automated Release\n\non:\n  push:\n    branches: [main]\n    paths-ignore:\n      - '**.md'\n      - 'docs/**'\n      - '."
  },
  {
    "path": ".gitignore",
    "chars": 3052,
    "preview": "# Compiled Python files\n**/__pycache__/\n*.py[cod]\n*.pyc\n*.pyo\n*.pyd\n__pycache__/\n.Python\n.pyc\n*$py.class\n\n# Specific cac"
  },
  {
    "path": "AGENTS.md",
    "chars": 7733,
    "preview": "# MDS Agent Operating Spec\n\nThis file is the canonical machine-oriented operating spec for terminal AI agents working in"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 186091,
    "preview": "# Changelog\n\nAll notable changes to MAVSDK Drone Show (MDS) project will be documented in this file.\n\nThe format is base"
  },
  {
    "path": "CLAUDE.md",
    "chars": 144,
    "preview": "@./AGENTS.md\n\n## Claude-specific note\n\n- Keep this file as a thin shim only.\n- Put shared repo operating instructions in"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 9588,
    "preview": "# Contributing to MAVSDK Drone Show\n\nThank you for your interest in contributing to MAVSDK Drone Show! This document pro"
  },
  {
    "path": "DISCLAIMER.md",
    "chars": 6605,
    "preview": "# Legal Disclaimer\n\n**MAVSDK Drone Show - Important Legal Information**\n\nPlease read this disclaimer carefully before us"
  },
  {
    "path": "ETHICAL-USE.md",
    "chars": 2640,
    "preview": "# Ethical Use Statement\n\n**MAVSDK Drone Show - Responsible Use Guidelines**\n\nVersion 3.6 | November 2025\n\n---\n\n## Purpos"
  },
  {
    "path": "GEMINI.md",
    "chars": 144,
    "preview": "@./AGENTS.md\n\n## Gemini-specific note\n\n- Keep this file as a thin shim only.\n- Put shared repo operating instructions in"
  },
  {
    "path": "LICENSE",
    "chars": 4267,
    "preview": "# MAVSDK Drone Show - License\n\nCopyright (c) 2025 Alireza Ghaderi\n\nThis software is available under multiple licenses to"
  },
  {
    "path": "LICENSE-COMMERCIAL.md",
    "chars": 10940,
    "preview": "# Commercial License for MAVSDK Drone Show\n\n**Need to use MAVSDK Drone Show for commercial purposes? You're in the right"
  },
  {
    "path": "LICENSE-NONCOMMERCIAL.md",
    "chars": 4915,
    "preview": "# PolyForm Noncommercial License 1.0.0\n\n**MAVSDK Drone Show - Noncommercial Use License**\n\nCopyright (c) 2025 Alireza Gh"
  },
  {
    "path": "LICENSE-SMALL-BUSINESS.md",
    "chars": 9362,
    "preview": "# PolyForm Small Business License 1.0.0\n## with MAVSDK Drone Show Drone Count Restriction\n\n**MAVSDK Drone Show - Small C"
  },
  {
    "path": "Makefile",
    "chars": 5292,
    "preview": "SHELL := /bin/bash\n\nGCS_API ?= http://localhost:5030\nSITL_COUNT ?= 4\nSTART_FLAGS ?=\nPYTEST_ARGS ?=\nNPM_TEST_ARGS ?= -- -"
  },
  {
    "path": "NOTICE",
    "chars": 6515,
    "preview": "# MAVSDK Drone Show - Third-Party Licenses and Attributions\n\nThis file contains required notices and attributions for th"
  },
  {
    "path": "README.md",
    "chars": 9313,
    "preview": "# MAVSDK Drone Show (MDS)\n\n**All-in-One PX4 Framework for Drone Shows, Smart Swarms, and SAR**\n\n[![Version](https://img."
  },
  {
    "path": "VERSION",
    "chars": 4,
    "preview": "5.3\n"
  },
  {
    "path": "actions.py",
    "chars": 48754,
    "preview": "#!/usr/bin/env python3\n\"\"\"\n===============================================================\nDrone Action Executor with MA"
  },
  {
    "path": "app/dashboard/drone-dashboard/.build_hash",
    "chars": 11,
    "preview": "1756624534\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/.gitignore",
    "chars": 326,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
  },
  {
    "path": "app/dashboard/drone-dashboard/FIELD_NAMING_STANDARD.md",
    "chars": 6793,
    "preview": "# Field Naming Standard - Flask to FastAPI Migration\n\n**Last Updated:** 2025-11-24\n**Migration Status:** ✅ Complete\n**Ba"
  },
  {
    "path": "app/dashboard/drone-dashboard/README.md",
    "chars": 3359,
    "preview": "# Getting Started with Create React App\n\nThis project was bootstrapped with [Create React App](https://github.com/facebo"
  },
  {
    "path": "app/dashboard/drone-dashboard/package.json",
    "chars": 2948,
    "preview": "{\n  \"name\": \"drone-dashboard\",\n  \"version\": \"5.3\",\n  \"private\": true,\n  \"license\": \"CC-BY-NC-SA-4.0\",\n  \"homepage\": \".\","
  },
  {
    "path": "app/dashboard/drone-dashboard/public/index.html",
    "chars": 3606,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <link rel=\"icon\" href=\"%PUBLIC_URL%/favicon.i"
  },
  {
    "path": "app/dashboard/drone-dashboard/public/manifest.json",
    "chars": 492,
    "preview": "{\n  \"short_name\": \"React App\",\n  \"name\": \"Create React App Sample\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n     "
  },
  {
    "path": "app/dashboard/drone-dashboard/public/robots.txt",
    "chars": 67,
    "preview": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/App.css",
    "chars": 13544,
    "preview": "/* Global Body Styles - Theme Aware */\nhtml {\n  max-width: 100%;\n  overflow-x: hidden;\n}\n\nbody {\n  font-family: var(--fo"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/App.js",
    "chars": 11213,
    "preview": "//app/dashboard/drone-dashboard/src/App.js\n/**\n * Copyright (c) 2025 Alireza Ghaderi\n * SPDX-License-Identifier: CC-BY-N"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/App.test.js",
    "chars": 5043,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\nimport App from './App';\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/__mocks__/styleMock.js",
    "chars": 21,
    "preview": "module.exports = {};\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/BriefingExport.js",
    "chars": 2537,
    "preview": "// app/dashboard/drone-dashboard/src/components/BriefingExport.js\n\nimport React, { useState } from 'react';\nimport { gen"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ClusterScopeBar.js",
    "chars": 2014,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport '../styles/ClusterScopeBar.css';\n\nconst ClusterSco"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/CommandPreflightSummary.js",
    "chars": 10479,
    "preview": "import React, { useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport useNormalizedTelemetry fro"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/CommandSender.js",
    "chars": 36212,
    "preview": "// src/components/CommandSender.js\n\nimport React, { useMemo, useRef, useState } from 'react';\nimport PropTypes from 'pro"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/CommandSender.test.js",
    "chars": 22140,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, waitFor, within } from '@testing-library/react';\n\nimport "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ControlButtons.js",
    "chars": 5081,
    "preview": "// src/components/ControlButtons.js\nimport React, { useRef } from 'react';\nimport PropTypes from 'prop-types';\nimport '."
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ControlButtons.test.js",
    "chars": 1578,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport ControlButtons fr"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/CurrentTime.js",
    "chars": 992,
    "preview": "// CurrentTime.js - Clean, minimal time display component\nimport React, { useState, useEffect } from 'react';\nimport '.."
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DeviationView.js",
    "chars": 13838,
    "preview": "// src/components/DeviationView.js\n\nimport React, { useState, useEffect } from 'react';\nimport Plot from 'react-plotly.j"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneActions.js",
    "chars": 11821,
    "preview": "// src/components/DroneActions.js\n\nimport React, { useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneActions.test.js",
    "chars": 4871,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport DroneActions from"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneCard.js",
    "chars": 8582,
    "preview": "import React, { forwardRef } from 'react';\nimport {\n  FaChevronDown,\n  FaChevronRight,\n  FaExclamationTriangle,\n  FaExch"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneConfigCard.js",
    "chars": 69181,
    "preview": "import React, { useState, useEffect, memo } from 'react';\nimport PropTypes from 'prop-types';\nimport DroneGitStatus from"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneConfigCard.test.js",
    "chars": 6526,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, within } from '@testing-library/react';\n\nimport DroneConf"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneCriticalCommands.js",
    "chars": 11933,
    "preview": "import React, { useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { toast } from 'react-toast"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneCriticalCommands.test.js",
    "chars": 5982,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, waitFor } from '@testing-library/react';\n\nimport DroneCri"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneDetail.js",
    "chars": 17920,
    "preview": "import React, { useState, useEffect } from 'react';\nimport { Marker } from 'react-leaflet';\nimport { FaMapMarkerAlt, FaW"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneGitStatus.js",
    "chars": 13394,
    "preview": "import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport '../styles/DroneGitStatus.css';\nimpo"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneGitStatus.test.js",
    "chars": 2099,
    "preview": "import React from 'react';\nimport { render, screen, fireEvent } from '@testing-library/react';\nimport DroneGitStatus fro"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneGraph.js",
    "chars": 6357,
    "preview": "import React, { useEffect, useRef } from 'react';\nimport CytoscapeComponent from 'react-cytoscapejs';\nimport { formatCom"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DronePositionMap.js",
    "chars": 14012,
    "preview": "import React, { useEffect, useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  CircleMarker"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DronePositionMap.test.js",
    "chars": 3410,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\n\njest.mock('geodesy/latlon-spherical"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneReadinessReport.js",
    "chars": 5791,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { FaCheckCircle, FaExclamationTriangle, FaInfoCirc"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneReadinessReport.test.js",
    "chars": 3465,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\n\nimport DroneReadinessReport from '."
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneWidget.js",
    "chars": 23724,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  FaCheckCircle,\n  FaBroadcastTower,\n  FaCog,\n  "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/DroneWidget.test.js",
    "chars": 4237,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\nimport { MemoryRouter } f"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/Environment.js",
    "chars": 955,
    "preview": "import React from 'react';\nimport { useLoader } from '@react-three/fiber';  // Removed TextureLoader from this import\nim"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ErrorBoundary.js",
    "chars": 1869,
    "preview": "// src/components/ErrorBoundary.js\nimport React from 'react';\nimport { reportFrontendError } from '../services/logServic"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ErrorBoundary.test.js",
    "chars": 1538,
    "preview": "// src/components/ErrorBoundary.test.js\nimport React from 'react';\nimport { render, screen } from '@testing-library/reac"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ExpandedDronePortal.js",
    "chars": 9458,
    "preview": "import React, { useEffect, useRef } from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ExportSection.js",
    "chars": 1742,
    "preview": "// src/components/ExportSection.js\nimport React from 'react';\nimport { Box, Typography, Button, Paper, Alert } from '@mu"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/GitInfo.js",
    "chars": 2863,
    "preview": "import React, { useState } from 'react';\nimport '../styles/GitInfo.css';\nimport useGcsGitInfo from '../hooks/useGcsGitIn"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/Globe.js",
    "chars": 23401,
    "preview": "import React, { useCallback, useState, useEffect, useRef } from 'react';\nimport { Canvas, useFrame, useThree } from '@re"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/GlobeControlBox.js",
    "chars": 5554,
    "preview": "// src/components/GlobeControlBox.js\nimport React from 'react';\nimport { FaTimes } from 'react-icons/fa';\nimport { FIELD"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/GlobeMapView.js",
    "chars": 14708,
    "preview": "// src/components/GlobeMapView.js\n// 2D map view for drone visualization — dual-provider (Mapbox + Leaflet fallback)\n\nim"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/Header.js",
    "chars": 353,
    "preview": "import React from 'react';\nimport '../styles/Header.css';\n\nconst Header = ({ toggleTheme, currentTheme }) => {\n  return "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/IdentityDoctrineStrip.js",
    "chars": 1337,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { getIdentityDoctrineCopy } from '../utilities/mi"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ImportSection.js",
    "chars": 15645,
    "preview": "import React, { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { toast } from "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/InfoHint.js",
    "chars": 1862,
    "preview": "import React, { useEffect, useId, useRef, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { FaInfoCi"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/InitialLaunchPlot.js",
    "chars": 6948,
    "preview": "// src/components/InitialLaunchPlot.js\nimport React from 'react';\nimport Plot from 'react-plotly.js';\nimport { formatCom"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MapSelector.js",
    "chars": 2435,
    "preview": "// src/components/MapSelector.js\n\nimport React, { useEffect, useState } from 'react';\nimport { useMapEvents, Marker, Pop"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionCard.js",
    "chars": 713,
    "preview": "import React from 'react';\n\nconst MissionCard = ({ missionType, icon, category, label, summary, note, onClick, isCancel "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionDetails.js",
    "chars": 46886,
    "preview": "import React from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n  FaCheckCircle,\n  FaExclamationTriangle,\n "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionDetails.test.js",
    "chars": 14651,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\nimport { MemoryRouter } f"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionLayout.js",
    "chars": 3958,
    "preview": "// src/components/MissionLayout.js\n\nimport React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionLayout.test.js",
    "chars": 1432,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\nimport MissionLayout from"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionReadinessCard.js",
    "chars": 21014,
    "preview": "import React, { useState, useEffect } from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n  MdAssessment,\n  "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionReadinessCard.test.js",
    "chars": 4035,
    "preview": "import React from 'react';\nimport { render, screen, waitFor } from '@testing-library/react';\nimport { MemoryRouter } fro"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionTrigger.js",
    "chars": 8818,
    "preview": "//app/dashboard/drone-dashboard/src/components/MissionTrigger.js\nimport React, { useState, useEffect } from 'react';\nimp"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/MissionTrigger.test.js",
    "chars": 1978,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\nimport MissionTrigger fro"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/OriginModal.js",
    "chars": 12857,
    "preview": "// src/components/OriginModal.js\n\nimport React, { useState, useEffect } from 'react';\nimport '../styles/OriginModal.css'"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/PositionTabs.js",
    "chars": 1221,
    "preview": "// src/components/PositionTabs.js\n\nimport React from 'react';\nimport DeviationView from './DeviationView';\nimport '../st"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/PrecisionMoveDialog.js",
    "chars": 42854,
    "preview": "import React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport ReactDOM from 'react-dom';\nimport PropT"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/PrecisionMoveDialog.test.js",
    "chars": 3330,
    "preview": "import React from 'react';\nimport { act, fireEvent, render, screen, waitFor } from '@testing-library/react';\n\nimport Pre"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/RouteDocsShortcut.js",
    "chars": 718,
    "preview": "import React from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { GIT_BRANCH, GIT_REPO } from '../ver"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/RuntimeModeBadge.js",
    "chars": 1922,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { FaExclamationTriangle } from 'react-icons/fa';\n\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/SaveReviewDialog.js",
    "chars": 10323,
    "preview": "// src/components/SaveReviewDialog.js\n\nimport React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimpo"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/SaveReviewDialog.test.js",
    "chars": 1257,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\nimport SaveReviewDialog from './Save"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/SidebarMenu.js",
    "chars": 21302,
    "preview": "//app/dashboard/drone-dashboard/src/components/SidebarMenu.js\nimport React, { useState } from 'react';\nimport { createPo"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/SidebarMenu.test.js",
    "chars": 5276,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, within } from '@testing-library/react';\nimport { MemoryRo"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/SwarmPlots.js",
    "chars": 9786,
    "preview": "import React, { useEffect, useMemo, useState } from 'react';\nimport Plot from 'react-plotly.js';\nimport { calculateClust"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/SwarmRuntimeControls.js",
    "chars": 16143,
    "preview": "import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  FaCrosshairs,\n  FaPauseCircle,\n "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/SwarmRuntimeControls.test.js",
    "chars": 3780,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, waitFor, within } from '@testing-library/react';\n\nimport "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/SyncWarningBanner.js",
    "chars": 3031,
    "preview": "import React, { useState, useEffect, useCallback, useRef } from 'react';\nimport { FaExclamationTriangle, FaSyncAlt, FaTi"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/TacticalDroneCard.js",
    "chars": 13007,
    "preview": "import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { toast } from 'react-toastify';\nimp"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/TacticalDroneCard.test.js",
    "chars": 2949,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\nimport { MemoryRouter } from 'react-"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ThemeToggle.js",
    "chars": 5467,
    "preview": "import React, { useState } from 'react';\nimport {\n  FaAdjust,\n  FaCheck,\n  FaChevronDown,\n  FaMoon,\n  FaSun,\n} from 'rea"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/TimePicker.js",
    "chars": 377,
    "preview": "import React from 'react';\n\nconst TimePicker = ({ selectedTime, onTimePickerChange }) => (\n  <div className=\"time-picker"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/VisualizationSection.js",
    "chars": 43465,
    "preview": "// src/components/VisualizationSection.js\n\nimport React, { useState, useEffect } from 'react';\nimport {\n  Alert,\n  Box,\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogActiveFilters.js",
    "chars": 1064,
    "preview": "// src/components/logs/LogActiveFilters.js\nimport React from 'react';\nimport { FaFilter, FaTimes } from 'react-icons/fa'"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogExportDialog.js",
    "chars": 3076,
    "preview": "// src/components/logs/LogExportDialog.js\nimport React, { useState } from 'react';\nimport { toast } from 'react-toastify"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogHealthBar.js",
    "chars": 2569,
    "preview": "// src/components/logs/LogHealthBar.js\nimport React, { useMemo } from 'react';\nimport { FaServer, FaPlane, FaExclamation"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogLiveIndicator.js",
    "chars": 460,
    "preview": "// src/components/logs/LogLiveIndicator.js\nimport React from 'react';\n\nconst LogLiveIndicator = ({ connected, paused }) "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogRowDetail.js",
    "chars": 3231,
    "preview": "// src/components/logs/LogRowDetail.js\nimport React, { useEffect, useId } from 'react';\nimport { createPortal } from 're"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogRowDetail.test.js",
    "chars": 1348,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\nimport LogRowDetail from "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogSessionSelector.js",
    "chars": 920,
    "preview": "// src/components/logs/LogSessionSelector.js\nimport React from 'react';\nimport { FaClock } from 'react-icons/fa';\nimport"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogSourceTree.js",
    "chars": 1140,
    "preview": "// src/components/logs/LogSourceTree.js\nimport React from 'react';\nimport { FaCircle } from 'react-icons/fa';\n\nconst Log"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogTable.js",
    "chars": 5738,
    "preview": "// src/components/logs/LogTable.js\nimport React, { useState, useEffect, useMemo } from 'react';\nimport { DataGrid, useGr"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogViewerToolbar.js",
    "chars": 6765,
    "preview": "// src/components/logs/LogViewerToolbar.js\nimport React from 'react';\nimport { FaEye, FaCode, FaPause, FaPlay, FaSearch,"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/LogViewerToolbar.test.js",
    "chars": 3735,
    "preview": "// src/components/logs/LogViewerToolbar.test.js\nimport React from 'react';\nimport { render, screen, fireEvent } from '@t"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/OnboardUlogDialog.js",
    "chars": 11380,
    "preview": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  FaCheckCircle,\n  FaCloudDow"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/logs/OnboardUlogDialog.test.js",
    "chars": 3088,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, waitFor } from '@testing-library/react';\nimport {\n  creat"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/map/LeafletCoveragePreview.js",
    "chars": 2273,
    "preview": "// src/components/map/LeafletCoveragePreview.js\n// Renders coverage paths as Leaflet Polylines — same data as CoveragePr"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/map/LeafletDrawControl.js",
    "chars": 11952,
    "preview": "// src/components/map/LeafletDrawControl.js\n// QuickScout geometry authoring for Leaflet without extra draw packages.\n//"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/map/LeafletFindingMarkers.js",
    "chars": 2875,
    "preview": "import React from 'react';\nimport { CircleMarker, Popup, useMapEvents } from 'react-leaflet';\nimport { toast } from 'rea"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/map/LeafletMapBase.js",
    "chars": 3214,
    "preview": "// src/components/map/LeafletMapBase.js\n// Reusable Leaflet map wrapper with a single controlled tile layer.\n\nimport Rea"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/map/MapFallbackBanner.js",
    "chars": 1702,
    "preview": "// src/components/map/MapFallbackBanner.js\n// Dismissible notification shown when Mapbox -> Leaflet fallback occurs\n\nimp"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/map/MapProviderToggle.js",
    "chars": 911,
    "preview": "// src/components/map/MapProviderToggle.js\n// Provider toggle — only visible when both providers are available\n\nimport R"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/map/ViewModeToggle.js",
    "chars": 928,
    "preview": "// src/components/map/ViewModeToggle.js\n// Segmented control for switching between 3D Scene and Map View modes\n\nimport R"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/missionConfig/MissionConfigAlertStack.js",
    "chars": 5760,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { FaExchangeAlt, FaExclamationTriangle, FaPlus } f"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/missionConfig/MissionConfigToolbar.js",
    "chars": 5420,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { CircularProgress } from '@mui/material';\nimport "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/missionConfig/PendingEnrollmentPanel.js",
    "chars": 3905,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { formatDroneLabel, formatShowSlotLabel } from '."
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/px4/Px4ParamInspector.js",
    "chars": 9926,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nconst trimTrailingZeros = (value) => String(value)\n  .re"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/px4/Px4ParamInspector.test.js",
    "chars": 2441,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\n\nimport Px4ParamInspector, { buildPa"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/px4/Px4ParamProfilePanel.js",
    "chars": 4600,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nconst renderValueSummary = (value) => {\n  if (value === "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/CoveragePreview.js",
    "chars": 3526,
    "preview": "// src/components/sar/CoveragePreview.js\n/**\n * Renders computed coverage paths as Mapbox GL Source/Layer (GeoJSON lines"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/DroneStatusCard.js",
    "chars": 1387,
    "preview": "// src/components/sar/DroneStatusCard.js\nimport React from 'react';\nimport { formatCompactDroneIdentity } from '../../ut"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/DroneStatusCard.test.js",
    "chars": 703,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\n\nimport DroneStatusCard from './Dron"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/FindingMarkerSystem.js",
    "chars": 3162,
    "preview": "import React, { useCallback } from 'react';\nimport { toast } from 'react-toastify';\n\nimport { createFinding } from '../."
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/FindingReviewPanel.js",
    "chars": 8895,
    "preview": "import React, { useEffect, useState } from 'react';\n\nconst FINDING_TYPE_OPTIONS = [\n  { value: 'person', label: 'Person'"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/FindingReviewPanel.test.js",
    "chars": 2676,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport FindingReviewPane"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionActionBar.js",
    "chars": 2188,
    "preview": "// src/components/sar/MissionActionBar.js\nimport React from 'react';\nimport { FaMapMarkedAlt, FaPause, FaHome, FaArrowDo"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionActionBar.test.js",
    "chars": 1033,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport MissionActionBar "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionHandoffPanel.js",
    "chars": 3083,
    "preview": "import React, { useMemo } from 'react';\n\nconst formatFindingLabel = (finding) => (\n  finding?.summary || String(finding?"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionHandoffPanel.test.js",
    "chars": 1603,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport MissionHandoffPan"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionMonitorSidebar.js",
    "chars": 9263,
    "preview": "// src/components/sar/MissionMonitorSidebar.js\n/**\n * Monitor mode sidebar: drone status cards and findings review.\n */\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionMonitorSidebar.test.js",
    "chars": 3647,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\n\nimport MissionMonitorSidebar from '"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionPlanSidebar.js",
    "chars": 22225,
    "preview": "// src/components/sar/MissionPlanSidebar.js\n/**\n * Plan mode sidebar: drone selection, survey config, compute/launch but"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionRecoveryPanel.js",
    "chars": 4152,
    "preview": "import React from 'react';\n\nconst ACTIVE_STATES = new Set(['executing', 'paused']);\n\nconst formatRelativeTime = (timesta"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionStatsBar.js",
    "chars": 2260,
    "preview": "// src/components/sar/MissionStatsBar.js\nimport React from 'react';\nimport { getQuickScoutMissionPhaseLabel } from '../."
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/MissionStatsBar.test.js",
    "chars": 994,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\n\nimport MissionStatsBar from './Miss"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/PlanMonitorToggle.js",
    "chars": 524,
    "preview": "// src/components/sar/PlanMonitorToggle.js\nimport React from 'react';\n\nconst PlanMonitorToggle = ({ mode, onModeChange }"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/QuickScoutLaunchReview.js",
    "chars": 8176,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport CommandPreflightSummary from '../CommandPreflight"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/QuickScoutLaunchReview.test.js",
    "chars": 2180,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\n\nimport QuickScoutLaunchReview from "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/sar/SearchAreaDrawer.js",
    "chars": 11114,
    "preview": "// src/components/sar/SearchAreaDrawer.js\n/**\n * QuickScout geometry authoring for Mapbox mode.\n *\n * Supports:\n * - pol"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/SearchBar.js",
    "chars": 12294,
    "preview": "// src/components/trajectory/SearchBar.js\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\nimpo"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/SwarmTrajectoryTransferDialog.js",
    "chars": 15841,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Link } from 'react-router-dom';\nimport { getClus"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/SwarmTrajectoryTransferDialog.test.js",
    "chars": 4062,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\nimport { MemoryRouter } from 'react-"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/SwarmTrajectoryWorkspaceSummary.js",
    "chars": 4723,
    "preview": "import React from 'react';\nimport { Link } from 'react-router-dom';\nimport PropTypes from 'prop-types';\nimport Trajector"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/SwarmTrajectoryWorkspaceSummary.test.js",
    "chars": 3550,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\nimport { MemoryRouter } from 'react-"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryExportDialog.js",
    "chars": 2486,
    "preview": "import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\n\nconst EXPORT_FORMATS = [\n  {\n    id: 'csv'"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryExportDialog.test.js",
    "chars": 892,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport TrajectoryExportD"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryLibraryDialog.js",
    "chars": 9464,
    "preview": "import React, { useEffect, useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { calculateTraj"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryLibraryDialog.test.js",
    "chars": 4937,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, within } from '@testing-library/react';\n\nimport Trajector"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryPolicyNotes.js",
    "chars": 1263,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport '../../styles/TrajectoryPolicyNotes.css';\n\nconst "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectorySegmentReview.js",
    "chars": 10309,
    "preview": "import React, { useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport {\n  getTrajectoryAltitudeI"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectorySegmentReview.test.js",
    "chars": 10580,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport TrajectorySegment"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryStats.js",
    "chars": 5387,
    "preview": "//app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryStats.js\nimport React from 'react';\nimport PropTypes"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryStats.test.js",
    "chars": 1669,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\n\nimport TrajectoryStats from './Traj"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryToolbar.js",
    "chars": 12537,
    "preview": "// src/components/trajectory/TrajectoryToolbar.js\n\nimport React, { useState } from 'react';\nimport PropTypes from 'prop-"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/TrajectoryToolbar.test.js",
    "chars": 3758,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\nimport TrajectoryToolbar "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/WaypointModal.js",
    "chars": 36617,
    "preview": "// src/components/trajectory/WaypointModal.js\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport PropTy"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/WaypointModal.test.js",
    "chars": 11300,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, waitFor } from '@testing-library/react';\nimport WaypointM"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/WaypointPanel.js",
    "chars": 48228,
    "preview": "// src/components/trajectory/WaypointPanel.js\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport PropTy"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/trajectory/WaypointPanel.test.js",
    "chars": 14155,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen, waitFor, within } from '@testing-library/react';\nimport W"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ui/OperatorPrimitives.js",
    "chars": 13243,
    "preview": "import React, { useEffect, useId } from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\ni"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ui/OperatorPrimitives.test.js",
    "chars": 4385,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport {\n  ActionIconBut"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/components/ui/index.js",
    "chars": 211,
    "preview": "export {\n  ActionIconButton,\n  ConfirmDialog,\n  DocsLink,\n  EmptyState,\n  MetricPill,\n  MetricStrip,\n  OperatorCard,\n  O"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/config/apiConfig.js",
    "chars": 2903,
    "preview": "// src/config/apiConfig.js\n// Centralized API configuration with auto-detection and one explicit override.\n\n/**\n * API C"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/config/mapConfig.js",
    "chars": 3425,
    "preview": "// src/config/mapConfig.js\n// Shared map configuration constants for dual-provider (Mapbox + Leaflet) system\n\nexport con"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/config/mapConfig.test.js",
    "chars": 1571,
    "preview": "import {\n  DEFAULT_LEAFLET_SUBDOMAINS,\n  getLeafletTileLayerConfig,\n  resolveTileLayerKey,\n} from './mapConfig';\n\ndescri"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/config/routeDocs.js",
    "chars": 4950,
    "preview": "// src/config/routeDocs.js\n// Route-to-documentation metadata used by operator help links and UI audit checks.\n\nexport c"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/config/routeDocs.test.js",
    "chars": 2004,
    "preview": "import {\n  buildDocsUrl,\n  getRouteDoc,\n  getRouteDocUrl,\n  normalizeGithubRepoUrl,\n  ROUTE_DOCS,\n} from './routeDocs';\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/droneConstants.js",
    "chars": 3071,
    "preview": "// src/constants/droneConstants.js\nimport {\n    buildGcsUrl,\n    buildShowPlotUrl,\n    GCS_ROUTE_KEYS,\n} from '../servic"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/droneStates.js",
    "chars": 1948,
    "preview": "/**\n * Drone Show Application States\n * \n * These are custom application states for the drone show system,\n * completely"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/fieldMappings.js",
    "chars": 11994,
    "preview": "// app/dashboard/drone-dashboard/src/constants/fieldMappings.js\n/**\n * Field Name Mappings - Flask to FastAPI Migration\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/flightModes.js.deprecated",
    "chars": 311,
    "preview": "// app/dashboard/drone-dashboard/src/constants/flightModes.js\nexport const FLIGHT_MODES = {\n    458752: 'Stabilized',\n  "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/logConstants.js",
    "chars": 1705,
    "preview": "// src/constants/logConstants.js\n// Constants for the Log Viewer UI\n\nexport const LOG_LEVELS = ['DEBUG', 'INFO', 'WARNIN"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/mavModeEnum.js.deprecated",
    "chars": 315,
    "preview": "export const MAV_MODE_ENUM = {\n    458752: 'Stabilized',\n    196608: 'Position',\n    100925440: 'Land',\n    393216: 'Off"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/px4FlightModes.js",
    "chars": 7033,
    "preview": "/**\n * PX4 Flight Mode Constants - Official Standards Implementation\n *\n * Based on official PX4-Autopilot source code v"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/trajectoryMissionPolicy.js",
    "chars": 6008,
    "preview": "const DEFAULT_TRAJECTORY_ALTITUDE_POLICY = Object.freeze({\n  DEFAULT_MSL: 100,\n  DEFAULT_TARGET_AGL: 100,\n  MIN_MSL: 1,\n"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/constants/trajectoryMissionPolicy.test.js",
    "chars": 3208,
    "preview": "import {\n  applyTrajectoryMissionPolicy,\n  resetTrajectoryMissionPolicy,\n  TRAJECTORY_ALTITUDE_POLICY,\n  TRAJECTORY_TERR"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/contexts/AuthContext.js",
    "chars": 2636,
    "preview": "import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';\n\nimport {\n  getAuth"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/contexts/CommandActivityContext.js",
    "chars": 6812,
    "preview": "import React, {\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from 'reac"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/contexts/CommandActivityContext.test.js",
    "chars": 4394,
    "preview": "import React from 'react';\nimport { act, render, screen, waitFor } from '@testing-library/react';\n\nimport { CommandActiv"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/contexts/MapContext.js",
    "chars": 3855,
    "preview": "// src/contexts/MapContext.js\n// Provider detection + context for dual Mapbox/Leaflet map system\n\nimport React, { create"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/contexts/ThemeContext.js",
    "chars": 5811,
    "preview": "import React, { createContext, useContext, useEffect, useState, useCallback } from 'react';\n\nconst META_THEME_COLOR_TOKE"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/contexts/ThemeContext.test.js",
    "chars": 2227,
    "preview": "import React from 'react';\nimport { fireEvent, render, screen } from '@testing-library/react';\n\nimport { ThemeProvider, "
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useComputeOrigin.js",
    "chars": 1867,
    "preview": "// src/hooks/useComputeOrigin.js\n\nimport { useState } from 'react';\nimport { computeOriginResponse } from '../services/g"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useFetch.js",
    "chars": 1812,
    "preview": "// src/hooks/useFetch.js\n\nimport { useState, useEffect } from 'react';\nimport { extractServerNowMs } from '../constants/"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useGcsGitInfo.js",
    "chars": 1754,
    "preview": "import { useEffect, useMemo, useState } from 'react';\n\nimport { getUnifiedGitStatusResponse } from '../services/gcsApiSe"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useGcsRuntimeStatus.js",
    "chars": 2612,
    "preview": "import useFetch from './useFetch';\nimport { GCS_ROUTE_KEYS } from '../services/gcsApiService';\nimport { useEffect, useSt"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useLogStream.js",
    "chars": 3997,
    "preview": "// src/hooks/useLogStream.js\n// SSE hook for real-time log streaming with batching and ring buffer\n\nimport { useState, u"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useLogStream.test.js",
    "chars": 1576,
    "preview": "// src/hooks/useLogStream.test.js\nimport { renderHook, act } from '@testing-library/react';\nimport useLogStream from './"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useNormalizedTelemetry.js",
    "chars": 4157,
    "preview": "// app/dashboard/drone-dashboard/src/hooks/useNormalizedTelemetry.js\n/**\n * Normalized Telemetry Hook\n * ==============="
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useSwarmClusterStatus.js",
    "chars": 1491,
    "preview": "import { useEffect, useState } from 'react';\n\nimport { getSwarmClusterStatus } from '../services/droneApiService';\n\ncons"
  },
  {
    "path": "app/dashboard/drone-dashboard/src/hooks/useSyncDrones.js",
    "chars": 1613,
    "preview": "import { useState, useCallback } from 'react';\nimport { toast } from 'react-toastify';\nimport { syncReposResponse } from"
  }
]

// ... and 1061 more files (download for full content)

About this extraction

This page contains the full source code of the alireza787b/mavsdk_drone_show GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1261 files (53.5 MB), approximately 14.1M tokens, and a symbol index with 8037 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!