Skip to content

[codex] Add export preview diagnostics#11

Open
EtienneLescot wants to merge 4 commits into
mainfrom
codex/export-preview-diagnostics
Open

[codex] Add export preview diagnostics#11
EtienneLescot wants to merge 4 commits into
mainfrom
codex/export-preview-diagnostics

Conversation

@EtienneLescot

@EtienneLescot EtienneLescot commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds focused export/preview diagnostics around the issue where, after export, the editor preview can show only the wallpaper while the source video disappears.
  • Logs the preview video state before and after export, including src, readyState, networkState, media error, time, duration, and decoded dimensions.
  • Logs suspicious preview video events (emptied, stalled, suspend, abort, error) so affected users can send actionable traces even when maintainers cannot reproduce locally.
  • Forwards renderer console.info / console.warn / console.error output to the main process so the diagnostics reach the terminal where npm run dev is running. Without this, renderer logs only show up in DevTools, which is invisible to users following the steps below.

Fixes #8

Why

I cannot reproduce the Manjaro-specific preview loss locally. The fast path is not expected to cover the affected Linux recording flow because Linux/browser recordings are saved as WebM, while the current source-copy fast path only accepts readable MP4 sources. This instrumentation targets the normal export path instead.

The renderer console-message forwarding was added after the first run on Manjaro produced no [VideoEditor] lines in the terminal — Electron renderer console output goes to DevTools, not stdout, by default. The new forwarding uses webContents.on("console-message", …) with the non-deprecated event-based API and prefixes every message with [renderer INFO|WARNING|ERROR] so it is easy to grep out from the surrounding OpenH264 / Wayland noise.

How to generate diagnostics

  1. Open a terminal.
  2. Install the basic tools, if needed:
sudo pacman -S --needed git nodejs npm
  1. Clone this repository and enter it:
git clone https://github.com/EtienneLescot/openscreen.git
cd openscreen
  1. Check out this diagnostic branch:
git fetch origin codex/export-preview-diagnostics
git checkout codex/export-preview-diagnostics
  1. Install dependencies:
npm ci
  1. Start OpenScreen from the same terminal:
npm run dev

If Electron fails with a chrome-sandbox permission error, run this once and start again:

sudo chown root:root node_modules/electron/dist/chrome-sandbox
sudo chmod 4755 node_modules/electron/dist/chrome-sandbox
npm run dev
  1. In the app, record or open the same kind of project that triggers the bug.
  2. Export the video normally.
  3. If the preview becomes only the wallpaper, go back to the terminal.
  4. Copy the log lines around the export that start with:
[renderer INFO] [VideoEditor] export started
[renderer INFO] [VideoEditor] export finished
[renderer INFO] [VideoPlayback] preview video <event>

They are prefixed with [renderer INFO] (or WARNING / ERROR) because the main process forwards every renderer console call — ignore any other renderer lines that are not part of the export flow.

  1. Paste those lines into issue [Bug]: Video disappears from editor after exporting (only background remains) #8, together with:
  • Linux distribution and desktop environment, for example Manjaro KDE
  • whether the recording was full screen or a window
  • whether webcam, microphone, or system audio were enabled
  • export format and resolution selected
  • whether the source file path shown in the log ends in .webm or .mp4

It is safe to ignore noisy terminal messages about DBus, dconf, or OpenH264 unless they appear right next to the [VideoEditor] or [VideoPlayback] diagnostic lines.

Validation

  • npx tsc --noEmit
  • npx biome check electron/main.ts
  • Manual smoke test: a minimal Electron script that loads a data: URL calling console.info / console.warn / console.error and forwarding via the same handler shows all three lines on stdout.
  • npm run build-vite

Summary by CodeRabbit

  • New Features
    • Forwarded renderer console output to the main terminal with formatted severity tags (INFO/WARNING/ERROR), skipping low-signal debug messages.
    • Added a global one-time trap for uncaught errors and unhandled promise rejections, logging structured details to the console.
  • Debugging & Diagnostics
    • Enhanced preview video diagnostics (readiness/network state, errors, timing/dimensions, and playback flags).
    • Added detailed preview lifecycle and export start/finish logs, including diagnostic snapshots before and after export.

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds structured diagnostics around renderer logs, runtime errors, preview video events, and export start/finish state snapshots.

Changes

Diagnostic instrumentation for video export debugging

Layer / File(s) Summary
Renderer console forwarding
electron/main.ts
Registers a browser-window-created listener that forwards renderer console-message output to the main process terminal, skips debug logs, and maps warning/error levels to console.warn and console.error.
Global error trap
src/main.tsx
Adds window listeners for error and unhandledrejection that normalize the payload and log structured uncaught error details.
Preview video diagnostics
src/components/video-editor/VideoPlayback.tsx
Adds an HTMLVideoElement diagnostics helper, logs preview event details with videoPath, and routes additional interruption/error events through the same logger.
Export start and finish logs
src/components/video-editor/VideoEditor.tsx
Adds preview diagnostics helpers around export start/finish logging, including pre-export and post-export video snapshots plus export settings data.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I hopped through logs both bright and deep,
To watch the video wake from sleep.
With export notes and errors in sight,
The console now glows just right.
A carrot of clues, a trail so neat —
The preview mystery has found its feet.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds diagnostics, but it does not fix the post-export preview loss described in issue #8. Either implement the actual preview-retention fix for issue #8 or relabel this as diagnostic work and use Refs #8 instead of Fixes #8.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately reflects the PR’s main focus on export preview diagnostics.
Description check ✅ Passed Mostly complete; it covers summary, issue link, rationale, and testing, but omits template sections like type, release impact, desktop impact, and screenshots.
Out of Scope Changes check ✅ Passed The added console forwarding and error trapping all support troubleshooting the export/preview bug and stay within scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/export-preview-diagnostics

Comment @coderabbitai help to get the list of available commands.

EtienneLescot pushed a commit that referenced this pull request Jun 22, 2026
Adds `webContents.on('console-message', …)` forwarding on every
browser window created in `electron/main.ts`. Renderer
`console.info` / `console.warn` / `console.error` calls now show
up in the terminal where `npm run dev` is running, prefixed with
`[renderer INFO|WARNING|ERROR]` so they are easy to grep out from
the surrounding OpenH264 / Wayland noise.

This makes the export-preview diagnostics from PR #11 actually
visible to users following terminal instructions — without it the
`[VideoEditor]` / `[VideoPlayback]` lines only land in DevTools,
which is exactly the gap that caused the first Manjaro run to
produce no usable data (cfinnberg, issue #8 comment 4757223195).

Uses the non-deprecated event-based signature
(`details: { level, message, … }`) with `level` already typed as
"info" | "warning" | "error" | "debug".

Smoke-tested locally with a minimal Electron script: `console.info`,
`console.warn`, and `console.error` from a `data:` URL all
appear on stdout.
@EtienneLescot EtienneLescot marked this pull request as ready for review June 22, 2026 10:05
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

EtienneLescot pushed a commit that referenced this pull request Jun 22, 2026
Adds `webContents.on('console-message', …)` forwarding on every
browser window created in `electron/main.ts`. Renderer
`console.info` / `console.warn` / `console.error` calls now show
up in the terminal where `npm run dev` is running, prefixed with
`[renderer INFO|WARNING|ERROR]` so they are easy to grep out from
the surrounding OpenH264 / Wayland noise.

This makes the export-preview diagnostics from PR #11 actually
visible to users following terminal instructions — without it the
`[VideoEditor]` / `[VideoPlayback]` lines only land in DevTools,
which is exactly the gap that caused the first Manjaro run to
produce no usable data (cfinnberg, issue #8 comment 4757223195).

Uses the non-deprecated event-based signature
(`details: { level, message, … }`) with `level` already typed as
"info" | "warning" | "error" | "debug".

Smoke-tested locally with a minimal Electron script: `console.info`,
`console.warn`, and `console.error` from a `data:` URL all
appear on stdout.
@EtienneLescot EtienneLescot force-pushed the codex/export-preview-diagnostics branch from 13878d6 to 1b8e210 Compare June 22, 2026 10:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@electron/main.ts`:
- Around line 134-150: The renderer console message listener in the
"browser-window-created" event handler is enabled unconditionally for all
windows, which can leak sensitive user data (paths, state, diagnostics) into
terminal and system logs during normal operation. Wrap the
window.webContents.on("console-message") listener registration inside a
conditional check that only enables it when an explicit diagnostic flag is set,
and ensure this flag is disabled by default in packaged builds. This makes
console forwarding opt-in rather than always-on.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 844f6f36-b459-435a-9dda-48d59a79c5a9

📥 Commits

Reviewing files that changed from the base of the PR and between 8246d07 and 1b8e210.

📒 Files selected for processing (3)
  • electron/main.ts
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/VideoPlayback.tsx

Comment thread electron/main.ts
Comment on lines +134 to +150
app.on("browser-window-created", (_event, window) => {
window.webContents.on("console-message", (details) => {
// New API: details.level is "info" | "warning" | "error" | "debug".
// Skip debug to keep the terminal readable; the user can still inspect
// DevTools for that.
const { level, message } = details;
if (level === "debug") return;
const tag = level.toUpperCase();
const line = `[renderer ${tag}] ${message}`;
if (level === "error") {
console.error(line);
} else if (level === "warning") {
console.warn(line);
} else {
console.log(line);
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Gate renderer-console forwarding behind an explicit diagnostic flag.

On Line 134, this is enabled unconditionally for every window. Since renderer logs include user paths/state (e.g., export diagnostics), this can leak sensitive data into terminal/system logs in normal runs. Make forwarding opt-in (or dev-only) and keep it disabled by default in packaged builds.

Suggested patch
- app.on("browser-window-created", (_event, window) => {
- 	window.webContents.on("console-message", (details) => {
+const shouldForwardRendererConsole =
+	!app.isPackaged || process.env.OPENSCREEN_ENABLE_RENDERER_CONSOLE_FORWARDING === "1";
+
+if (shouldForwardRendererConsole) {
+	app.on("browser-window-created", (_event, window) => {
+		window.webContents.on("console-message", (details) => {
 		// New API: details.level is "info" | "warning" | "error" | "debug".
 		// Skip debug to keep the terminal readable; the user can still inspect
 		// DevTools for that.
 		const { level, message } = details;
 		if (level === "debug") return;
 		const tag = level.toUpperCase();
 		const line = `[renderer ${tag}] ${message}`;
 		if (level === "error") {
 			console.error(line);
 		} else if (level === "warning") {
 			console.warn(line);
 		} else {
 			console.log(line);
 		}
-	});
-});
+		});
+	});
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
app.on("browser-window-created", (_event, window) => {
window.webContents.on("console-message", (details) => {
// New API: details.level is "info" | "warning" | "error" | "debug".
// Skip debug to keep the terminal readable; the user can still inspect
// DevTools for that.
const { level, message } = details;
if (level === "debug") return;
const tag = level.toUpperCase();
const line = `[renderer ${tag}] ${message}`;
if (level === "error") {
console.error(line);
} else if (level === "warning") {
console.warn(line);
} else {
console.log(line);
}
});
const shouldForwardRendererConsole =
!app.isPackaged || process.env.OPENSCREEN_ENABLE_RENDERER_CONSOLE_FORWARDING === "1";
if (shouldForwardRendererConsole) {
app.on("browser-window-created", (_event, window) => {
window.webContents.on("console-message", (details) => {
// New API: details.level is "info" | "warning" | "error" | "debug".
// Skip debug to keep the terminal readable; the user can still inspect
// DevTools for that.
const { level, message } = details;
if (level === "debug") return;
const tag = level.toUpperCase();
const line = `[renderer ${tag}] ${message}`;
if (level === "error") {
console.error(line);
} else if (level === "warning") {
console.warn(line);
} else {
console.log(line);
}
});
});
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@electron/main.ts` around lines 134 - 150, The renderer console message
listener in the "browser-window-created" event handler is enabled
unconditionally for all windows, which can leak sensitive user data (paths,
state, diagnostics) into terminal and system logs during normal operation. Wrap
the window.webContents.on("console-message") listener registration inside a
conditional check that only enables it when an explicit diagnostic flag is set,
and ensure this flag is disabled by default in packaged builds. This makes
console forwarding opt-in rather than always-on.

EtienneLescot and others added 3 commits June 22, 2026 13:53
Adds `webContents.on('console-message', …)` forwarding on every
browser window created in `electron/main.ts`. Renderer
`console.info` / `console.warn` / `console.error` calls now show
up in the terminal where `npm run dev` is running, prefixed with
`[renderer INFO|WARNING|ERROR]` so they are easy to grep out from
the surrounding OpenH264 / Wayland noise.

This makes the export-preview diagnostics from PR #11 actually
visible to users following terminal instructions — without it the
`[VideoEditor]` / `[VideoPlayback]` lines only land in DevTools,
which is exactly the gap that caused the first Manjaro run to
produce no usable data (cfinnberg, issue #8 comment 4757223195).

Uses the non-deprecated event-based signature
(`details: { level, message, … }`) with `level` already typed as
"info" | "warning" | "error" | "debug".

Smoke-tested locally with a minimal Electron script: `console.info`,
`console.warn`, and `console.error` from a `data:` URL all
appear on stdout.
…] logs

The console-message event in Electron's webContents only delivers the
first argument as a string in details.message. The original PR #11
passed the diagnostic object as the second argument to console.info,
which got collapsed to [object Object] in the forwarded log line -
defeating the whole point of capturing structured diagnostic data.

This folds the payload into the first argument via template literal +
JSON.stringify, so the structured src/readyState/networkState/error/
dimensions/duration/currentTime reaches stdout through the existing
console-message forwarding.

Also rebase onto current main so the branch keeps moving forward.
@EtienneLescot EtienneLescot force-pushed the codex/export-preview-diagnostics branch from 1b8e210 to b1c5ee5 Compare June 22, 2026 12:22
…eref

Mirrors the cfinnberg-reported failure log by capturing filename, lineno,
colno, and stack from window 'error' and 'unhandledrejection' events so the
next repro run produces a stack trace, not just the bare TypeError message.

One-shot diagnostic — to be removed once the .geometry null deref is pinned
and fixed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/video-editor/VideoEditor.tsx`:
- Around line 1883-1908: The export trace in VideoEditor’s export logging is
serializing raw filesystem paths and preview metadata with src values, which can
leak local file details. Update the console.info diagnostics in the export flow
(including the previewBeforeExport/previewAfter data and the export payload) to
redact path-like fields using getFileNameForDiagnostics() or equivalent before
JSON.stringify. Apply the same sanitization in the other export trace block
referenced by the comment so both logs consistently omit raw sourcePath,
videoPath, and webcamVideoPath values.

In `@src/components/video-editor/VideoPlayback.tsx`:
- Around line 369-375: The preview logging in logPreviewVideoEvent is leaking
local file paths by emitting videoPath and diagnostics.src verbatim. Update the
VideoPlayback preview event logging to redact local file:// sources before
calling console.info, replacing the raw path with a basename or a stable token
while keeping the rest of getVideoElementDiagnostics output intact. Ensure any
reference to videoPath or diagnostics.src in this callback is sanitized so
terminal logs do not expose user home-directory details.

In `@src/main.tsx`:
- Around line 16-20: The window error handler in main.tsx is using err?.message
as the only message source, which logs undefined/null when event.error is
missing on non-rejection ErrorEvent cases. Update the error-trap logic around
the event handling to fall back to evt.message for non-rejection errors before
String(err), while keeping the existing source, lineno, colno, and stack
behavior in the same handler.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2a0e345d-7e65-445a-9b9e-adc1da3fd770

📥 Commits

Reviewing files that changed from the base of the PR and between 0819961 and 3065705.

📒 Files selected for processing (4)
  • electron/main.ts
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/VideoPlayback.tsx
  • src/main.tsx

Comment on lines +1883 to +1908
const previewBeforeExport = getPreviewVideoDiagnostics(video);
console.info(
`[VideoEditor] export started ${JSON.stringify({
format: settings.format,
sourcePath: videoSourcePath ?? videoPath,
videoPath,
webcamVideoPath,
preview: previewBeforeExport,
settings: {
exportQuality: settings.quality || exportQuality,
aspectRatio,
padding,
borderRadius,
shadowIntensity,
showBlur,
motionBlurAmount,
cropRegion,
zoomRegions: zoomRegions.length,
trimRegions: trimRegions.length,
speedRegions: speedRegions.length,
annotations: annotationRegions.length,
effectiveShowCursor,
cursorSize,
},
})}`,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Avoid logging raw source file paths in export traces.

These diagnostics include raw sourcePath / videoPath / webcamVideoPath, and previewBefore / previewAfter also carry src. Because these traces are meant to be shared, they can leak local filesystem details. Please reuse getFileNameForDiagnostics() (or similar redaction) before serializing.

Also applies to: 2135-2142

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/video-editor/VideoEditor.tsx` around lines 1883 - 1908, The
export trace in VideoEditor’s export logging is serializing raw filesystem paths
and preview metadata with src values, which can leak local file details. Update
the console.info diagnostics in the export flow (including the
previewBeforeExport/previewAfter data and the export payload) to redact
path-like fields using getFileNameForDiagnostics() or equivalent before
JSON.stringify. Apply the same sanitization in the other export trace block
referenced by the comment so both logs consistently omit raw sourcePath,
videoPath, and webcamVideoPath values.

Comment on lines +369 to +375
const logPreviewVideoEvent = useCallback(
(event: React.SyntheticEvent<HTMLVideoElement>) => {
console.info(
`[VideoPlayback] preview video ${event.type} ${JSON.stringify({
videoPath,
diagnostics: getVideoElementDiagnostics(event.currentTarget),
})}`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Redact local paths from preview diagnostics.

This payload currently emits both videoPath and diagnostics.src verbatim. For local file:// sources that exposes usernames/home-directory paths in terminal logs that users may paste into bug reports. Log a basename or stable redacted token instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/video-editor/VideoPlayback.tsx` around lines 369 - 375, The
preview logging in logPreviewVideoEvent is leaking local file paths by emitting
videoPath and diagnostics.src verbatim. Update the VideoPlayback preview event
logging to redact local file:// sources before calling console.info, replacing
the raw path with a basename or a stable token while keeping the rest of
getVideoElementDiagnostics output intact. Ensure any reference to videoPath or
diagnostics.src in this callback is sanitized so terminal logs do not expose
user home-directory details.

Comment thread src/main.tsx
Comment on lines +16 to +20
message: err?.message ?? String(err),
source: isRej ? null : evt.filename,
lineno: isRej ? null : evt.lineno,
colno: isRej ? null : evt.colno,
stack: err?.stack ?? null,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fall back to ErrorEvent.message for non-rejection errors.

On window "error" events, event.error is often missing even when event.message, filename, and line info are populated. The current fallback logs "undefined"/"null" in that case, which defeats the diagnostic value of this trap for a common browser error shape.

Suggested fix
 		JSON.stringify({
-			message: err?.message ?? String(err),
+			message: isRej
+				? err?.message ?? String(err)
+				: err?.message ?? evt.message ?? String(err),
 			source: isRej ? null : evt.filename,
 			lineno: isRej ? null : evt.lineno,
 			colno: isRej ? null : evt.colno,
 			stack: err?.stack ?? null,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
message: err?.message ?? String(err),
source: isRej ? null : evt.filename,
lineno: isRej ? null : evt.lineno,
colno: isRej ? null : evt.colno,
stack: err?.stack ?? null,
message: isRej
? err?.message ?? String(err)
: err?.message ?? evt.message ?? String(err),
source: isRej ? null : evt.filename,
lineno: isRej ? null : evt.lineno,
colno: isRej ? null : evt.colno,
stack: err?.stack ?? null,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main.tsx` around lines 16 - 20, The window error handler in main.tsx is
using err?.message as the only message source, which logs undefined/null when
event.error is missing on non-rejection ErrorEvent cases. Update the error-trap
logic around the event handling to fall back to evt.message for non-rejection
errors before String(err), while keeping the existing source, lineno, colno, and
stack behavior in the same handler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Video disappears from editor after exporting (only background remains)

1 participant