Adaptive Sensing

0 comments0 reviews

#What this repository does

adaptive-sensing is a research and prototype system for adaptive electronic-warfare spectrum surveillance.

Its purpose is to control a receiver that cannot listen to the entire radio-frequency spectrum at once. The receiver has a fixed set of frequency channels and can observe only one channel during each short time window, called a dwell. The system must decide:

  • Which channel should be scanned next?
  • Should it follow the normal sequential sweep?
  • Is it worth temporarily diverting to another channel?
  • Will that diversion help discover an unknown or intermittent emitter?
  • Will the diversion leave another channel unobserved for too long?

The project simulates this problem using synthetic radar/emitter data, evaluates multiple scheduling strategies, trains predictive models, and presents the results through a tactical web dashboard.

The central idea is:

Instead of repeatedly listening to the loudest channel, choose the next scan based on the expected long-term mission value of discovering previously unseen emitters while still maintaining safe coverage of the whole spectrum.

The repository calls this system Q-Scheduler.


#Overall architecture

The main data flow is:

Radar/emitter dataset
        |
        v
Dataset loading and PDW parsing
        |
        v
RF/time-frequency environment
        |
        v
Simulated receiver observations
        |
        v
Historical and causal feature extraction
        |
        v
Activity and mission-value prediction
        |
        v
Candidate scan actions
        |
        v
Scheduler/planner chooses next channel
        |
        v
Safety gate approves or vetoes the action
        |
        v
Receiver observes the selected channel
        |
        +----> Evaluation metrics and benchmark reports
        |
        +----> Frontend dashboard and comparison visualizations

The system has four broad layers:

LayerLocationPurpose
Research and simulation backendbackend/src/Receiver simulation, features, schedulers, evaluation
Advanced Q-Scheduler backendbackend/q_scheduler/Predictive models and mission-level planning
API layerbackend/api/server.pyExposes comparisons and live streams to the dashboard
Operator dashboardfrontend/ew-dashboard/Visualizes spectrum activity, scan decisions, threats, and policy comparisons

The repository also contains a large body of documentation and experimental artifacts under docs/ and reports/.


#The electronic-warfare problem being solved

The project models a receiver with approximately 36 frequency channels:

  • Some channels require a longer dwell, such as 100 ms.
  • Other channels require a shorter dwell, such as 50 ms.
  • A complete nominal sequential sweep takes about 2.15 seconds.

A simple receiver would scan channel 0, then channel 1, then channel 2, and so on. This guarantees coverage, but it may miss a short-lived emitter that transmits while the receiver is listening elsewhere.

A naïve adaptive scheduler has the opposite problem: it may discover many pulses on one busy channel and keep returning there, starving the rest of the spectrum.

This project therefore tries to balance:

  1. Exploration — visiting channels that may contain undiscovered threats.
  2. Exploitation — returning to channels where useful activity is predicted.
  3. Coverage — ensuring no channel remains unobserved for too long.
  4. Causal decision-making — only using information available up to the current time.
  5. Mission-level value — optimizing early emitter discovery rather than just immediate pulse count.

The main objective is cumulative undiscovered-emitter time, represented in the documentation as J. Lower J means emitters were discovered earlier.


#Top-level directories and files

This is the primary project explanation. It covers:

  • The EW problem
  • Terminology such as PDW, PRI, dwell, raster, and partial observability
  • The Q-Scheduler design
  • The Discovery-Aware and Opportunity-Cost planners
  • The safety-coverage rule
  • Benchmark results
  • Reproducibility commands
  • The intended directory structure

It is written partly for technical evaluators and partly for Smart India Hackathon judges.

This is the system’s formal architecture specification. It defines:

  • The dataset assumptions
  • What information the scheduler may and may not use
  • The receiver and observation model
  • Frequency and time representations
  • Feature and belief-state concepts
  • Scheduler interfaces
  • Reinforcement-learning formulation
  • Evaluation metrics
  • Experimental scenarios
  • Development phases and success criteria

This file describes the intended architecture at a conceptual level, including some structures that have since evolved in the implementation.

Contains repository-level GitHub configuration, likely including workflows, issue or contribution settings, and automation metadata.

Contains detailed technical specifications and phase-by-phase validation reports. Important documents include:

  • DATASET_ARCHITECTURE.md — dataset structure and data assumptions
  • OBSERVABILITY_RULES.md — rules preventing the scheduler from using future or hidden information
  • PHASE1_VALIDATION.md — initial dataset validation
  • PHASE2_RF_ENVIRONMENT.md — RF environment and receiver simulation
  • PHASE3_BASELINES.md — baseline scheduler definitions
  • PHASE4_FEATURE_ENGINEERING.md — engineered state features
  • PHASE5_2_ML_MODELS.md — predictive ML models
  • PHASE6_REINFORCEMENT_LEARNING.md — RL-related work
  • PHASE7.md and related files — later planning, predictive, and causal-state work
  • COUNTERFACTUAL_ENVIRONMENT_AUDIT.md — checks around counterfactual evaluation
  • POST_RESTRUCTURE_VALIDATION.md — validation after repository restructuring

These documents function as the project’s research notebook and audit trail.

Contains generated experiment outputs rather than core source code. There are many CSV, JSON, Markdown, PNG, and NumPy artifacts covering:

  • Benchmark summaries
  • Per-scenario metrics
  • Bootstrap confidence intervals
  • Calibration curves
  • Feature importance
  • Ablation studies
  • Leakage audits
  • Reproducibility runs
  • Reinforcement-learning experiments
  • Decision traces
  • Root-cause diagnostics
  • Phase 6 and Phase 7 validation

The reports directory is useful for verifying research claims and comparing policies, but it is not generally needed to understand the runtime architecture.

The repository-level scripts currently focus on later validation and experiment execution, including:

  • run_phase6_3_candidate_a_validation.py
  • run_phase6_3_candidate_b_validation.py
  • run_phase6_3_single_scenario.py

These scripts execute specific research experiments and generate trace or validation artifacts.


#Backend

The backend is Python-based. Its dependencies include NumPy, SciPy, h5py, Matplotlib, FastAPI, Uvicorn, and pytest.

This package is responsible for bringing raw scenario data into the system.

#dataset_loader.py

Defines structures such as:

  • RawPDWTable
  • ScenarioData
  • DatasetLoader

It loads and represents pulse data and scenario-level metadata.

#scan_parser.py

Defines receiver and transmitter metadata:

  • ChannelConfig
  • ReceiverConfig
  • TransmitterMetadata

It parses the hardware configuration of the receiver and the metadata describing simulated emitters.

#preprocessing.py

Provides data validation and time-unit conversion helpers, including conversion between microseconds and seconds.

#hardware_constants.py

Contains receiver-specific timing and channel rules, such as canonical dwell durations and wideband-channel identification.


This package simulates the physical RF world and the receiver’s limited view of it.

#rf_environment.py

Represents the RF environment containing channels, emitters, pulses, and activity over time.

#receiver.py

Implements the receiver simulator. It models what the receiver actually observes after selecting a channel and dwell duration.

#actions.py

Defines the scan action taken by the receiver, such as selecting a channel and observing it for a specific dwell.

#observations.py

Defines the observation returned after a dwell. This is the information available to the scheduler, rather than the full hidden ground truth.

#time_frequency_grid.py

Represents activity on a two-dimensional time/frequency grid.

#phase7_environment.py

Provides a later-stage environment for the Phase 7 planning and learning experiments.

#rl_environment.py

Contains reinforcement-learning environment abstractions such as discrete, box, and dictionary spaces.

#synthetic_world.py

Creates small synthetic scenarios for development and testing. It includes helpers for generating four-channel receivers and synthetic pulse streams.

#reward.py

Defines reward configuration and reward breakdown calculations for learning-based schedulers.

#potential.py

Implements potential-based state shaping, especially around channel staleness.

#lagrangian.py

Provides constraint-pressure and dual-variable logic for constrained scheduling experiments.


This package converts receiver history into scheduler features.

#extractor.py

The main feature-extraction layer. It produces structured spectrum feature state from the receiver’s observation history.

#types.py

Defines the feature data structures:

  • FeatureConfig
  • ActivityFeatures
  • StalenessFeatures
  • TemporalFeatures
  • SpectralFeatures
  • SpatialFeatures
  • CrossBandFeatures
  • BandFeatures

#Activity and history trackers

  • activity.py — tracks recent activity by band
  • staleness.py — tracks how long each channel has gone without observation
  • temporal.py — extracts temporal pulse behavior
  • spectral.py — extracts frequency and spectral behavior
  • spatial.py — tracks angle-of-arrival information
  • cross_band.py — captures relationships between channels
  • causal_temporal.py — tracks temporal state without using future data
  • compact_state.py — turns the state into compact vector representations

Together, these modules provide the information needed for a scheduler to make an informed decision without seeing the hidden future.


This contains the general predictive-model framework.

#predictor_service.py

Provides a service layer for loading and querying predictive models.

#models/activity/

This package contains activity-prediction models:

  • base.py — abstract predictor interface
  • historical_rate.py — predicts based on historical activity rate
  • persistence.py — predicts that recent activity will continue
  • logistic.py — logistic-regression-based predictor
  • gradient_boosting.py — gradient-boosting predictor
  • dataset.py — builds model-training datasets
  • targets.py — creates prediction targets
  • splits.py — controls scenario-level data splits
  • evaluator.py — evaluates prediction quality
  • pipeline.py — training, prediction, calibration, and reproducibility pipeline
  • config.py — model and pipeline configuration

The package supports both simple baselines and more sophisticated learned predictors.


This contains the scheduler implementations that choose the next scan action.

#Common interface

  • base.py — abstract BaseScheduler
  • actions.py — converts between channel actions and adaptive action representations
  • candidate.py — generates candidate channels and opportunities
  • policies.py — reusable candidate-selection policies
  • action_value.py — computes action values and feasibility

#Baseline schedulers

  • random.py — random channel selection
  • sequential.py — fixed cyclic sweep
  • greedy.py — immediate activity or recency-based selection
  • ucb.py — upper-confidence-bound exploration
  • thompson.py — Thompson sampling
  • whittle.py — Whittle-index-style scheduling
  • oracle.py — clairvoyant reference scheduler using privileged information
  • hierarchical.py — hierarchical scheduling
  • dqn_scheduler.py — deep Q-network-based scheduler

#More advanced schedulers

  • smartscan.py — adaptive scoring based on sensing value
  • temporal_predictor_scheduler.py — uses temporal activity prediction
  • short_horizon_planner.py — short-term planning baseline
  • residual.py — residual policy and safety gate logic
  • value.py — opportunity-value and SmartScan scoring
  • dqn.py — neural Q-network, replay buffer, and DDQN implementation
  • prioritized_replay.py — staleness-stratified prioritized replay

This package contains both simple reference policies and more experimental learned or value-based schedulers.


This package determines whether a scheduler is actually useful.

#counterfactual_replay.py

Replays scenarios and evaluates what would have happened if a different action had been selected. It includes:

  • Scenario loading
  • Dwell observation
  • Sequential baseline replay
  • Counterfactual decision evaluation
  • Mission-objective calculation
  • Continuation rollout

#metrics.py

Computes performance measures such as:

  • Coverage
  • Discovery success
  • Interception ratio
  • Discovery latency
  • Revisit gaps
  • Starvation gaps
  • Short-burst capture
  • Bootstrap confidence intervals

#ground_truth.py

Compares scan histories against the complete hidden scenario ground truth.

#engine.py and runner.py

Provide general experiment execution and result collection.

#benchmark_harness.py

Runs canonical benchmark experiments, builds schedulers, evaluates scenarios, and computes aggregate statistics.


Contains the general backend test suite. The repository currently contains approximately 68 test files in this area.

These tests enforce:

  • Receiver behavior
  • Partial observability
  • Feature correctness
  • Scheduler decisions
  • Evaluation metrics
  • Information-leakage restrictions
  • Environment invariants

Contains exploratory research notebooks:

  • phase2_environment_demo.ipynb
  • phase4_feature_exploration.ipynb

These are useful for understanding the project interactively rather than through production-style modules.

Contains compressed train, validation, and test CSV datasets for temporal modeling.


#The backend/q_scheduler/ subsystem

This is the most specialized part of the backend. It implements the mission-level Q-Scheduler rather than only the generic scheduler framework.

Its main decision is between:

  • KEEP — continue the nominal raster sweep.
  • OVERRIDE — temporarily scan a different channel because the predicted mission benefit justifies the diversion.

Contains configuration definitions for different research phases:

  • phase4b2_config.py
  • phase5_config.py
  • phase6_config.py
  • pilot_config.py
  • q_h_v2_config.py

These define feature schemas, cohort sizes, evaluation parameters, thresholds, and model paths.

Contains training and evaluation dataset construction tools:

  • Dataset generators
  • Counterfactual replay extractors
  • Dataset manifests
  • Pydantic row schemas
  • Scenario partition metadata
  • Replacement and deferred-training utilities

This package creates supervised examples from simulated decisions and counterfactual outcomes.

Contains the mission-level predictive models.

#q_h_bundle.py

Loads frozen multi-horizon Q_H regressors. These estimate the expected improvement or degradation in mission objective from taking a candidate action.

The repository includes several time horizons, such as:

  • 50 ms
  • 100 ms
  • 250 ms
  • 500 ms
  • 1 second
  • 2.15 seconds
  • Full mission horizon

#mission_risk_bundle.py

Loads the mission-risk model. This predicts the probability that an override will produce a positive mission outcome.

#Training modules

  • train_qh.py
  • train_mission_risk.py
  • mission_risk_factory.py
  • q_h_v2_training_preparation.py

These prepare and train the predictive models.

#Model artifacts

  • models/q_h/ contains frozen Q-H model files and metadata.
  • models/mission_risk/ contains the mission-risk model and its feature schema.
  • models/q_h_v2/ contains schema and metadata for the newer model version.

This is the central planning package.

#decision_planner.py

The main planner that routes candidate actions through the available policy logic.

#discovery_gate.py

Implements anti-repetition behavior. Once a channel has produced a useful discovery, the scheduler should not repeatedly return there simply because it remains active.

#opportunity_cost.py

Calculates the cost of diverting from the normal raster. It considers whether:

  • The current raster channel is becoming stale.
  • The candidate channel will naturally be visited soon anyway.
  • The override creates unnecessary displacement.
  • The candidate provides enough expected mission gain.

#dynamic_keep.py

Calculates a dynamic threshold for deciding whether an override is valuable enough to beat the KEEP action.

#contextual_gate.py

Allows a previously suppressed channel to become eligible again when new temporal or burst evidence appears.

#safety_feasibility.py

Performs safety prechecks on candidate actions.

#planner_types.py

Defines the planner’s core data structures, including candidates, policies, configurations, and inference results.

Contains CausalTemporalEpisodeTracker and related channel episode tracking logic.

It maintains state such as:

  • Recent observations
  • Channel visit history
  • Last scan times
  • Active burst episodes
  • Emitter-related temporal evidence

It is designed to ensure that planning decisions only use information available at the current point in time.

Analyzes periodic emitter behavior.

  • periodic_analyzer.py — PRI autocorrelation and harmonic analysis
  • periodic_types.py — result data structures
  • synthetic_benchmarks.py — synthetic periodic-signal generation
  • real_data_smoke_test.py — smoke tests against real scenario files
  • adversarial_audit.py — stress tests for periodic analysis

This supports detection of radar pulse trains and intelligent re-entry into channels with periodic activity.

Contains specialized evaluation tools:

  • baseline_evaluator.py — evaluates the sequential sweep
  • canonical_four_way_evaluation.py — compares several scheduler families
  • planner_ablation.py — runs model and policy ablations
  • counterfactual.py — constructs counterfactual targets
  • mission_risk_evaluator.py — evaluates risk prediction
  • qh_evaluator.py — validates Q-H models
  • protected_data_guard.py — prevents accidental use of protected holdout data
  • action_space_audit.py — checks candidate-action parity
  • q_h_v2_leakage_audit.py — searches for feature leakage

Contains approximately 32 focused tests for the advanced planner subsystem, including:

  • Opportunity-cost behavior
  • Discovery-gate cooldowns
  • Dynamic KEEP thresholds
  • Planner routing
  • Determinism
  • Causal state behavior
  • Safety and fallback behavior

#API layer

This is the FastAPI entry point for the dashboard-facing backend.

It exposes:

EndpointPurpose
GET /Basic API/root response
GET /api/training_curvesReturns training-curve data
GET /api/policiesLists available comparison policies
GET /api/configsLists available STARE scenario configurations
GET /api/comparison/{config_id}Runs a complete sequential-versus-adaptive comparison
GET /api/stream/{config_id}Streams comparison steps using Server-Sent Events

The available policies are:

  • da — Discovery-Aware
  • opp_cost — Opportunity-Cost
  • dynamic_keep — Dynamic KEEP
  • shp — Short-Horizon Planner

The server:

  1. Loads STARE scenario data.
  2. Parses receiver and emitter information.
  3. Builds a frequency/time heatmap.
  4. Simulates a sequential baseline.
  5. Simulates the selected adaptive policy.
  6. Tracks emitter discovery and mission objective values.
  7. Returns comparison steps, divergences, emitter data, and summary metrics.

It also maintains in-memory caches for scenario data, heatmaps, emitter metadata, preprocessing results, and comparison results.

The API expects scenario data in external runtime locations such as:

stare/
scan/

Those directories are not present in the attached repository, so a fresh checkout will need the corresponding scenario data before the API can run successfully.


#Frontend dashboard

The frontend is a Next.js application located at:

frontend/ew-dashboard/

It uses:

  • React
  • Next.js
  • TypeScript
  • Recharts
  • Framer Motion
  • Lucide icons
  • Tailwind CSS

#src/app/page.tsx

The main dashboard page.

It provides:

  • Scenario selection
  • Scan playback controls
  • Spectrum waterfall visualization
  • Emitter inspection
  • Decision log
  • Dataset explorer
  • Frequency, amplitude, PRF, AoA, and interception charts
  • Training curves
  • Sidebar and status bar controls

The page loads pre-generated JSON from paths such as:

/data/config_list.json
/data/test_stats.json
/data/config_0.json

#src/app/compare/page.tsx

A thin route wrapper that displays ComparisonPage.

#src/app/radar/page.tsx

A more focused radar-style view containing:

  • Radar scope
  • Mission scoreboard
  • Threat-band list
  • Radar event feed
  • Mission timeline
  • Playback controls

#src/app/layout.tsx

Defines global layout, metadata, viewport settings, and application-level wrappers.

#src/app/globals.css

Contains the dashboard’s global styling and visual theme.

#src/app/loading.tsx

Displays the loading UI while a page is being prepared.

#src/app/error.tsx

Provides the route-level error boundary.


#Frontend components

  • SpectrumWaterfall.tsx — time/frequency waterfall display
  • FrequencySpectrum.tsx — frequency distribution chart
  • AmplitudeDistribution.tsx — pulse-amplitude distribution
  • PRFHistogram.tsx — pulse-repetition-frequency visualization
  • AoAPolarPlot.tsx — angle-of-arrival plot
  • ScatterPlot.tsx — pulse feature scatter plot
  • BandEmitterHeatmap.tsx — emitter activity by band
  • EmitterFeatureSpace.tsx — emitter feature-space visualization
  • InterceptionRatioOverTime.tsx — interception performance over time
  • CumulativeDetectionCurve.tsx — cumulative discovery behavior
  • TrainingCurves.tsx — ML training and validation curves
  • ScanTimeline.tsx — scan progression over the mission
  • DecisionLog.tsx — chronological scheduler decisions
  • DatasetExplorer.tsx — scenario-level dataset statistics
  • EmitterDetailPanel.tsx — details for the selected emitter
  • Sidebar.tsx — channel/scenario navigation
  • StatusBar.tsx — system status and mission indicators
  • LoadingSkeleton.tsx — loading placeholders

The src/components/compare/ directory is dedicated to policy comparison:

  • ComparisonPage.tsx — orchestrates the comparison screen
  • ComparisonTopBar.tsx — policy and scenario controls
  • ComparisonMetrics.tsx — comparison metrics
  • ComparisonRadarScope.tsx — visual radar comparison
  • ComparisonWaterfall.tsx — sequential versus adaptive waterfall
  • ComparisonTimeline.tsx — side-by-side scan timeline
  • ComparisonThreatMatrix.tsx — threat-discovery comparison
  • ComparisonDivergenceBanner.tsx — highlights policy divergence
  • DivergenceLog.tsx — records moments where the policies choose differently
  • emitterColors.ts — consistent emitter coloring utilities

The src/components/radar/ directory provides the more tactical operator view:

  • RadarScope.tsx
  • MissionScoreboard.tsx
  • ThreatBandList.tsx
  • RadarEventFeed.tsx
  • MissionTimeline.tsx

#Frontend hooks and types

Central playback state for moving through mission time.

It manages:

  • Current scan step
  • Play and pause
  • Forward and backward stepping
  • Playback speed
  • Reset
  • Progress calculation

Animates numeric dashboard values.

Provides animation-frame utilities, interpolation, and clamping.

Defines the structure of scenario JSON data and test-stat records.

Defines policy identifiers and comparison types. It includes the four supported policy IDs and helper functions for displaying policy names.


#Frontend data-generation scripts

Reads HDF5 scan files and converts them into dashboard-friendly JSON.

It extracts information such as:

  • Pulse descriptors
  • Emitter types
  • Frequency data
  • Time-of-arrival values
  • Pulse widths
  • AoA
  • Amplitude
  • PRF information
  • Band statistics
  • Downsampled scatter data

The generated files are written to:

frontend/ew-dashboard/public/data/

Converts dataset-level CSV statistics into test_stats.json for the dashboard.

The scripts expect a repository-level scan/ directory. In the attached copy, that directory is not present, and the generated public/data/ files are also not present. Therefore, the frontend source exists, but the default dashboard data must be generated or supplied before it can operate as intended.


#How the key scheduling policies differ

The fixed baseline. It visits channels in order and provides predictable coverage.

Its strength is reliability and coverage. Its weakness is that it cannot react to short-lived opportunities.

Chooses a channel based mainly on immediate pulse or discovery opportunity. It is useful as a legacy or myopic baseline, but it can over-focus on currently active channels.

Prioritizes channels containing emitters that have not yet been discovered. It also uses an anti-repetition memory to avoid repeatedly scanning an already-understood channel.

Improves on Discovery-Aware behavior by charging an explicit cost for leaving the nominal raster. It asks:

  • Is the candidate channel about to be visited naturally?
  • Is the raster channel becoming stale?
  • Is the predicted gain large enough to justify the diversion?
  • Will this override cause unnecessary displacement?

Computes a dynamic hurdle for overriding the raster. The scheduler remains with the nominal scan unless the best candidate exceeds the current KEEP threshold.


#The safety mechanism

The system does not allow an adaptive policy to divert indefinitely.

The safety gate projects future channel revisit times and vetoes an override if it would cause a channel to remain unvisited beyond the allowed starvation limit. The documentation describes this limit as approximately 2.30 seconds, slightly longer than the nominal 2.15-second sweep to provide limited maneuvering slack.

When an override is rejected, the system falls back to the scheduled raster action.

This is important because the adaptive policy is not allowed to sacrifice broad spectrum surveillance merely to chase a locally attractive signal.


#What is production/runtime code versus research material?

The most operationally relevant files are:

backend/api/server.py
backend/src/data/
backend/src/environment/
backend/src/features/
backend/src/schedulers/
backend/src/evaluation/
backend/q_scheduler/planner/
backend/q_scheduler/models/
backend/q_scheduler/state/
frontend/ew-dashboard/src/

These areas are primarily for experimentation, validation, and scientific analysis:

backend/notebooks/
backend/q_scheduler/evaluation/
backend/q_scheduler/scripts/
scripts/
reports/
docs/

They are still important, but they are not all part of the live request path.


#Important repository observations

  1. The repository contains both a general scheduler framework and a more specialized Q-Scheduler framework.
    backend/src/schedulers/ contains the broader family of scheduling strategies, while backend/q_scheduler/ contains the newer mission-level planning architecture.

  2. The dashboard has two data paths.
    The main dashboard uses pre-generated JSON files under public/data/, while the comparison/training functionality communicates with the FastAPI backend.

  3. Some runtime inputs are external to the repository.
    The API expects stare/ and scan/ scenario data directories, but they are not included in the attached copy.

  4. The project is heavily research-oriented.
    The many phase reports, audits, manifests, traces, and statistical outputs show that the authors focused not only on implementing a scheduler but also on proving that it does not use future information and that its reported improvements are reproducible.

  5. The most important conceptual distinction is immediate reward versus mission value.
    The project deliberately moves away from “which channel has the most pulses right now?” toward “which action most improves discovery over the entire mission while preserving coverage?”

In short, this is an adaptive RF surveillance research platform: it simulates a constrained EW receiver, learns or estimates which scan actions are valuable, compares multiple scheduling policies, enforces coverage safety, and exposes the resulting behavior through an operator-style dashboard.