# VSS Simulator Export Schema — v6

The VSS Simulator exports patient session data as a ZIP archive. The clinical portal imports and visualizes this data.

---

## ZIP Structure

```
VisualSnow_Export_<timestamp>.zip
├── symptom_logs.json          # All session entries (required)
├── eeg/
│   ├── eeg_index.json         # EEG session summary (optional)
│   └── eeg_<timestamp>.csv    # Raw EEG samples per session (optional)
└── README.txt                 # Human-readable field reference
```

---

## Root Object (`symptom_logs.json`)

| Field | Type | Description |
|---|---|---|
| `exportVersion` | int | Schema version. Current: `6` |
| `exportedAt` | string | `"yyyy-MM-dd HH:mm:ss"` export time |
| `totalEntries` | int | Count of entries |
| `medicalHistory` | object | Patient questionnaire (once per export, see below) |
| `entries` | array | Array of session log objects |

---

## `medicalHistory`

Present once at the root level — not repeated per entry.

| Field | Type | Description |
|---|---|---|
| `updatedAt` | long | Epoch ms of last update |
| `notes` | string | Free-text patient notes |
| `items` | object | Keyed boolean flags (e.g. `"migraines": true`) |

---

## Entry Object

Each element of `entries[]`:

```json
{
  "id": 1,
  "timestamp": 1748000000000,
  "date": "2026-05-30 12:00:00",
  "isPreset": false,

  "visualStatic":   { ... },
  "floaters":       { ... },
  "blueField":      { ... },
  "lightAnomalies": { ... },
  "postProcessing": { ... },
  "distortions":    { ... },
  "tinnitus":       { ... },
  "wellbeing":      { ... },
  "context":        { ... }
}
```

---

## `visualStatic`

| Field | Type | Range | Description |
|---|---|---|---|
| `intensity` | float | 0–1 | Snow grain density |
| `alpha` | float | 0–1 | Snow opacity |
| `grainSize` | float | 0–1 | Grain pixel size |
| `speed` | float | 0–1 | Animation speed |
| `pattern` | string | `"Random"`, `"PerlinNoise"` | Noise algorithm |
| `colorMode` | string | `"White"`, `"Color"` | Snow color mode |
| `colorArgb` | long | ARGB 32-bit | Snow tint color |

---

## `floaters`

| Field | Type | Range |
|---|---|---|
| `count` | int | 0–200 |
| `minSize` | float | 0–1 |
| `maxSize` | float | 0–1 |
| `alpha` | float | 0–1 |
| `colorArgb` | long | ARGB |
| `shape` | string | `"Circle"`, `"Blob"` |
| `brownianStrength` | float | 0–1 |
| `gyroSensitivity` | float | 0–1 |
| `damping` | float | 0–1 |

---

## `blueField`

| Field | Type | Values |
|---|---|---|
| `enabled` | boolean | |
| `count` | int | |
| `dotShape` | string | `"Circle"` |
| `movement` | string | `"Squiggly"`, `"Flow"` |
| `colorArgb` | long | ARGB |
| `alpha` | float | 0–1 |
| `speed` | float | |
| `size` | float | |

---

## `lightAnomalies`

Visual field conditions and optical phenomena.

### `aura`
| Field | Type | Values |
|---|---|---|
| `intensity` | float | 0–1 |
| `type` | string | `"Scotoma"`, `"Fortification"` |
| `scotomaCount` | int | |
| `scotomaPositions` | string | `"x1,y1;x2,y2"` normalized 0–1 |
| `scotomaColorArgb` | long | ARGB |
| `scotomaAlpha` | float | 0–1 |

### `photopsia`
| Field | Type |
|---|---|
| `intensity` | float 0–1 |

### `glare`
| Field | Type |
|---|---|
| `enabled` | boolean |
| `intensity` | float |
| `rayCount` | int |
| `colorArgb` | long |
| `sizeFraction` | float |

### `halo`
| Field | Type |
|---|---|
| `rainbowEnabled` | boolean |
| `nearEnabled` | boolean |

### `contrastLoss`
| Field | Type |
|---|---|
| `enabled` | boolean |
| `strength` | float 0–1 |

### `cvd` *(v6)*
| Field | Type | Values |
|---|---|---|
| `type` | string | `"None"`, `"Protanopia"`, `"Deuteranopia"`, `"Tritanopia"` |
| `severity` | float | 0–1 |

### `hemianopia` *(v6)*
| Field | Type | Values |
|---|---|---|
| `side` | string | `"None"`, `"Left"`, `"Right"` |
| `opacity` | float | 0–1 |

### `tunnelVision` *(v6)*
| Field | Type | Range |
|---|---|---|
| `radius` | float | 0–1 (1 = full field) |
| `softness` | float | 0–1 |

### `charlesBonnet` *(v6)*
| Field | Type |
|---|---|
| `intensity` | float 0–1 |

---

## `postProcessing`

### `glowingEdges`
| Field | Type |
|---|---|
| `enabled` | boolean |
| `alpha` | float |
| `processScale` | int |
| `tintArgb` | long |
| `levelsBlack` | float 0–1 |
| `levelsWhite` | float 0–1 |
| `levelsGamma` | float |
| `blurRadius` | int |
| `colorizeStrength` | float |
| `displacementX` | float |
| `displacementY` | float |

### `differenceClouds`
| Field | Type | Range |
|---|---|---|
| `enabled` | boolean | |
| `alpha` | float | 0–1 |
| `speed` | float | |
| `scale` | float | |
| `baseHue` | float | 0–360 |
| `hueRange` | float | |
| `saturation` | float | 0–1 |
| `contrast` | float | |
| `softLight` | boolean | |

---

## `distortions`

Dynamic perceptual distortions.

### `vibration`
| Field | Type |
|---|---|
| `intensity` | float 0–1 |

### `diplopia`
| Field | Type |
|---|---|
| `intensity` | float |
| `direction` | float (degrees) |
| `rotation` | float (degrees) |

### `palinopsia`
| Field | Type |
|---|---|
| `enabled` | boolean |
| `type` | string — `"Illusory"`, `"Hallucinatory"` |
| `shape` | string — `"Circle"`, `"SoftBox"` |
| `trailLayers` | int |
| `trailAlpha` | float |
| `ghostCount` | int |
| `ghostAlpha` | float |
| `ghostLifeSec` | float |
| `manualAngle` | float |
| `motionWeight` | float |
| `rotation` | float |
| `trailFadeRate` | float |
| `trailColorArgb` | long |

### `wavyVision` *(v6)*
| Field | Type |
|---|---|
| `intensity` | float 0–1 |
| `speed` | float |

### `edgeGlow` *(v6)*
| Field | Type |
|---|---|
| `intensity` | float 0–1 |

---

## `tinnitus`

| Field | Type |
|---|---|
| `enabled` | boolean |
| `type` | string — `"PureTone"`, `"Buzz"` |
| `baseFrequencyHz` | float |
| `volume` | float 0–1 |
| `fmDepthHz` | float |
| `pulseRateHz` | float |
| `secondaryFreqMultipliers` | string — comma-separated floats |

---

## `wellbeing`

Patient self-reported state for this session.

| Field | Type | Range |
|---|---|---|
| `anxietyLevel` | int | 0–10 |
| `energyLevel` | int | 0–10 |
| `depressionLevel` | int | 0–10 |
| `sleepHours` | float | 0–24 |
| `stressLevel` | int | 0–10 |
| `note` | string | Free text |

---

## `context`

| Field | Type | Description |
|---|---|---|
| `activeSymptoms` | string | Comma-separated symptom names reported this session |
| `recentTriggers` | string | Comma-separated trigger names |

---

## `eeg/eeg_index.json`

Array of EEG session summaries. Each entry links to a CSV via `csvFile`.

| Field | Type | Description |
|---|---|---|
| `sessionTimestamp` | long | Epoch ms — links to the session log entry |
| `boardName` | string | e.g. `"Synthetic"`, `"Ganglion"`, `"Muse S"` |
| `durationMs` | long | Recording duration |
| `sampleCount` | int | Total samples captured |
| `alphaMean` | float | Mean alpha band power |
| `alphaMin` | float | Min alpha band power |
| `alphaMax` | float | Max alpha band power |
| `channelCount` | int | Number of EEG channels |
| `csvFile` | string | Path within ZIP, e.g. `"eeg/eeg_1748000000000.csv"` |

## `eeg/<timestamp>.csv`

Raw EEG sample data. First line is a comment (`#`) with board name, alpha suppression index, and hyperexcitability level.

Columns: `timestamp_ms, alpha_power, gamma_power, alpha_gamma_ratio, ch0, ch1, ...`

---

## Version History

| Version | Delta |
|---|---|
| v4 | Initial schema |
| v5 | Added `medicalHistory`, tinnitus secondary freqs, palinopsia shape/fade |
| v6 | Added to `lightAnomalies`: `cvd`, `hemianopia`, `tunnelVision`, `charlesBonnet`. Added to `distortions`: `wavyVision`, `edgeGlow`. Updated README in ZIP. |

---

## Portal Compatibility

`portal/shared/fileParser.js` accepts exportVersion **4, 5, and 6**.

For v4/v5 exports the new `lightAnomalies` sub-keys (`cvd`, `hemianopia`, `tunnelVision`, `charlesBonnet`) and `distortions` sub-keys (`wavyVision`, `edgeGlow`) will be absent — portal consumers should treat missing keys as their default/zero values.
