splitsmith 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- splitsmith-0.3.0/CHANGELOG.md +34 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/PKG-INFO +23 -24
- {splitsmith-0.2.0 → splitsmith-0.3.0}/README.md +22 -23
- {splitsmith-0.2.0 → splitsmith-0.3.0}/pyproject.toml +1 -1
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/__init__.py +1 -1
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/config.py +2 -3
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/fcpxml_gen.py +1 -1
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/__init__.py +1 -2
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/server.py +13 -5
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/AuditControls.tsx +8 -6
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/BeepSection.tsx +226 -57
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/HelpOverlay.tsx +7 -5
- splitsmith-0.3.0/src/splitsmith/ui_static/src/components/audit/BeepAnomalyBanner.tsx +71 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/BeepStatusChip.tsx +17 -38
- splitsmith-0.3.0/src/splitsmith/ui_static/src/components/audit/ShortcutHints.tsx +148 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/StageActionBar.tsx +8 -5
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/api.ts +11 -3
- splitsmith-0.3.0/src/splitsmith/ui_static/src/lib/keyboard.ts +45 -0
- splitsmith-0.3.0/src/splitsmith/ui_static/src/lib/platform.ts +50 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Audit.tsx +132 -368
- splitsmith-0.3.0/src/splitsmith/ui_static/src/pages/BeepReview.tsx +1049 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Coach.tsx +5 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Design.tsx +3 -2
- splitsmith-0.3.0/src/splitsmith/ui_static/tsconfig.app.tsbuildinfo +1 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/uv.lock +1 -1
- splitsmith-0.2.0/CHANGELOG.md +0 -19
- splitsmith-0.2.0/src/splitsmith/ui_static/src/components/audit/SyncBanner.tsx +0 -157
- splitsmith-0.2.0/src/splitsmith/ui_static/src/pages/BeepReview.tsx +0 -759
- splitsmith-0.2.0/src/splitsmith/ui_static/tsconfig.app.tsbuildinfo +0 -1
- {splitsmith-0.2.0 → splitsmith-0.3.0}/.gitignore +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/LICENSE +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/docs/local-slim/README.md +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/docs/saas-readiness/README.md +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/site/README.md +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/skills/splitsmith-match/README.md +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/audit.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/automation.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/backup.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/beep_calibration.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/beep_detect.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/cleanup.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/cli.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/coach.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/coach_distributions.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/compare/__init__.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/compare/cli.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/compare/emitter.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/compare/filler.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/compare/layout.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/compare/manifest.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/compare/project_loader.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/composition.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/cross_align.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/csv_gen.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/ensemble_calibration.json +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/fonts/Antonio-OFL.txt +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/fonts/Antonio-VariableFont.ttf +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/fonts/JetBrainsMono-Bold.ttf +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/fonts/JetBrainsMono-OFL.txt +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/overlay_theme.json +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/templates/action-cut.yaml +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/templates/match-recap.yaml +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/voter_c_gbdt.joblib +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/data/voter_e_visual_probe.joblib +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/__init__.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/agc_state.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/api.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/backend.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/calibration.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/clap_mel.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/features.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/fixtures.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/tta.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/visual.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ensemble/voters.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/fcp7xml_render.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/fixture_schema.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/lab/__init__.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/lab/core.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/lab/promote.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/lab/snap_window.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/lab/sweeps.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/lab_cli.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/match_cli.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/match_model.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/match_registry.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mcp/__init__.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mcp/__main__.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mcp/detect_tools.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mcp/export_tools.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mcp/sandbox.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mcp/server.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mcp/tools.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mcp/write_tools.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/model_cli.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/models/__init__.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/models/cache.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/models/download.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/models/errors.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/models/manifest.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/models/registry.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/mp4_render.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/overlay_render.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/overlay_theme.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/relink.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/report.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/runtime.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/shot_detect.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/shot_refine.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/system_check.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/templates.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/thumbnail.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/trim.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/audio.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/embedded.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/exports.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/jobs.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/logging_setup.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/match_exports.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/project.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/scoreboard/__init__.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/scoreboard/cache.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/scoreboard/http.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/scoreboard/local.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/scoreboard/models.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui/scoreboard/protocol.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/.gitignore +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/index.html +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/package-lock.json +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/package.json +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/pnpm-lock.yaml +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/App.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/AddFootageModal.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/AppShell.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/CameraModelSelect.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/CleanupDialog.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/DirectoryPickerModal.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/FolderPicker.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/HitlQueuePanel.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/Jobs.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ListDrawer.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/MarkerGlyph.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/MarkerLayer.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/MountSelect.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/RelinkDialog.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/SettingProvenance.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ShooterScopedRoute.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ShotStepper.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/StageTimeSection.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/SweepsCard.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/VideoPanel.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/Waveform.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/AnomalyChips.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/AnomalyPins.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/CamGridModal.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/CamSyncPill.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/MultiCamColumn.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/PrereqGate.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/SessionSummary.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/audit/StageChipRail.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/developer/DeveloperShell.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/match/MatchShell.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/match/MatchSidebar.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/match/ShooterChipStrip.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/AvatarStack.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/Brand.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/ContextBar.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/DisplayHeading.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/IconButton.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/Kbd.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/Kicker.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/ModeSwitch.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/Readout.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/ShotTimerShell.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/StageDot.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/StatusPill.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/Tick.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/badge.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/button.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/card.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/index.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/ui/skeleton.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/anomalies.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/audit-input.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/audit-next-step.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/features.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/matchHref.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/mode.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/slugify.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/stageStatus.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/lib/utils.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/main.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Compare.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/CreateMatch.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Export.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Home.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Ingest.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Lab.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/MergeMatches.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Pick.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/PromoteReview.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Review.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/Shooters.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/dev/DevCorpus.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/dev/DevRetrain.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/dev/DevReviewQueue.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/pages/dev/DevValidate.tsx +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/styles/index.css +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/tsconfig.app.json +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/tsconfig.json +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/tsconfig.node.json +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/tsconfig.node.tsbuildinfo +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/vite.config.ts +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/user_config.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/video_match.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/video_probe.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/waveform.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/youtube_sidecar.py +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/tests/fixtures/beep_calibration/README.md +0 -0
- {splitsmith-0.2.0 → splitsmith-0.3.0}/tests/fixtures/schemas/README.md +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.3.0](https://github.com/mandakan/splitsmith/compare/v0.2.1...v0.3.0) (2026-05-25)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **beep-review:** single home for beep work; trim audit page ([#399](https://github.com/mandakan/splitsmith/issues/399)) ([9ecf999](https://github.com/mandakan/splitsmith/commit/9ecf9998f94edeb5420e3a982f97ae4edb2114f0))
|
|
9
|
+
* **brand:** hero + og:image, new tagline, audit shortcut hints ([#401](https://github.com/mandakan/splitsmith/issues/401)) ([40aa55a](https://github.com/mandakan/splitsmith/commit/40aa55ac56da0e9c81ae373554b9dc8816f4b2e0))
|
|
10
|
+
|
|
11
|
+
## [0.2.1](https://github.com/mandakan/splitsmith/compare/v0.2.0...v0.2.1) (2026-05-24)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* **docs:** use absolute GitHub URLs for README images on PyPI ([#398](https://github.com/mandakan/splitsmith/issues/398)) ([de435a6](https://github.com/mandakan/splitsmith/commit/de435a6981b0532f05c159a73da86a9d107bf6af))
|
|
17
|
+
|
|
18
|
+
## 0.2.0 (2026-05-24)
|
|
19
|
+
|
|
20
|
+
First public release.
|
|
21
|
+
|
|
22
|
+
Extract IPSC shot splits from head-mounted camera footage. Detect shots
|
|
23
|
+
via a 3-voter ensemble (envelope onset / CLAP / GBDT-with-PANN), produce
|
|
24
|
+
a CSV of splits, and emit an FCPXML timeline with per-shot markers and
|
|
25
|
+
optional overlay clips for Final Cut Pro.
|
|
26
|
+
|
|
27
|
+
Install:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
uv tool install splitsmith
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
After install, run `splitsmith fetch-models` to pre-download the ~440 MB
|
|
34
|
+
of ONNX detection artifacts (otherwise they download on first detection).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: splitsmith
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Extract IPSC shot splits from head-mounted camera footage
|
|
5
5
|
Author: Mathias Axell
|
|
6
6
|
License: MIT
|
|
@@ -29,9 +29,14 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
|
|
30
30
|
# splitsmith
|
|
31
31
|
|
|
32
|
+
[](https://pypi.org/project/splitsmith/)
|
|
33
|
+
[](https://pypi.org/project/splitsmith/)
|
|
34
|
+
[](https://github.com/mandakan/splitsmith/blob/main/LICENSE)
|
|
35
|
+
[](https://github.com/mandakan/splitsmith/actions/workflows/ci.yml)
|
|
36
|
+
|
|
32
37
|
Extract per-shot split times from head-mounted camera footage of IPSC matches and generate Final Cut Pro timelines with per-shot markers.
|
|
33
38
|
|
|
34
|
-

|
|
35
40
|
|
|
36
41
|
Built to do two things from a single stage video: get per-shot splits for analysis and coaching, and prepare frame-marked clips for match-footage review. Your head-mounted cam (Insta360 Go 3S in this case) already captures audio of every shot; the RO's timer only records your total stage time, so the splits live in the video and nowhere else. Splitsmith extracts them and turns them into a CSV plus an FCPXML timeline with per-shot markers you can step through in Final Cut Pro.
|
|
37
42
|
|
|
@@ -42,30 +47,24 @@ Built to do two things from a single stage video: get per-shot splits for analys
|
|
|
42
47
|
|
|
43
48
|
| | |
|
|
44
49
|
|---|---|
|
|
45
|
-
|  | **Ingest.** Drop a folder of GoPro clips; the engine auto-matches them to stages by file timestamp. |
|
|
46
|
-
|  | **Beep review.** Auto-snap to the start beep on each stage; low-confidence detections land in a HITL queue. |
|
|
47
|
-
|  | **Audit.** Waveform + per-shot markers from the 3-voter ensemble. Click a marker to inspect votes; drag to fine-tune. |
|
|
48
|
-
|  | **Compare.** Multi-shooter grid, all beep-aligned to t=0. Audio from one shooter, video tiles for everyone else. |
|
|
49
|
-
|  | **Export.** Per-stage or whole-match FCPXML. Open in Final Cut Pro, M / Shift+M to navigate markers. |
|
|
50
|
+
|  | **Ingest.** Drop a folder of GoPro clips; the engine auto-matches them to stages by file timestamp. |
|
|
51
|
+
|  | **Beep review.** Auto-snap to the start beep on each stage; low-confidence detections land in a HITL queue. |
|
|
52
|
+
|  | **Audit.** Waveform + per-shot markers from the 3-voter ensemble. Click a marker to inspect votes; drag to fine-tune. |
|
|
53
|
+
|  | **Compare.** Multi-shooter grid, all beep-aligned to t=0. Audio from one shooter, video tiles for everyone else. |
|
|
54
|
+
|  | **Export.** Per-stage or whole-match FCPXML. Open in Final Cut Pro, M / Shift+M to navigate markers. |
|
|
50
55
|
|
|
51
|
-
> Screenshots regenerate from a live `splitsmith ui` via `scripts/capture_screenshots.py`. See [
|
|
56
|
+
> Screenshots regenerate from a live `splitsmith ui` via `scripts/capture_screenshots.py`. See [Regenerating screenshots](#regenerating-screenshots) below.
|
|
52
57
|
|
|
53
58
|
## Quickstart
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
You need: `uv`, `ffmpeg`/`ffprobe` on PATH, and (for source checkouts) Node 20 + `pnpm` to build the SPA. See [Install](#install) for OS-specific package commands.
|
|
60
|
+
You need: `uv` and `ffmpeg`/`ffprobe` on PATH. See [Install](#install) for OS-specific package commands.
|
|
58
61
|
|
|
59
62
|
```bash
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
cd splitsmith
|
|
63
|
-
uv sync # slim runtime deps only (~100 MB)
|
|
64
|
-
(cd src/splitsmith/ui_static && pnpm install && pnpm build)
|
|
65
|
-
uv run splitsmith fetch-models # ~440 MB ONNX artifacts; one-time
|
|
63
|
+
uv tool install splitsmith # slim runtime, ~100 MB
|
|
64
|
+
splitsmith fetch-models # ~440 MB ONNX artifacts; one-time
|
|
66
65
|
|
|
67
66
|
# Bring your own head-cam clip and stage time (or use any IPSC video at hand)
|
|
68
|
-
|
|
67
|
+
splitsmith single \
|
|
69
68
|
--video path/to/your_stage.mp4 \
|
|
70
69
|
--time 14.74 \
|
|
71
70
|
--output ./demo_analysis \
|
|
@@ -79,7 +78,7 @@ cat ./demo_analysis/stage3_per-told-me-to-do-it_report.txt
|
|
|
79
78
|
For the full ingest -> audit -> export workflow with persistent project state, use the UI:
|
|
80
79
|
|
|
81
80
|
```bash
|
|
82
|
-
|
|
81
|
+
splitsmith ui --project ~/matches/your-match
|
|
83
82
|
```
|
|
84
83
|
|
|
85
84
|
The repo ships a real Stage 3 audio sample at `tests/fixtures/stage-shots-tallmilan-2026-stage3-s97dcec94.wav` (Tallmilan 2026, 14.74s, 14 audited shots) plus its sibling JSON with ground-truth shot times. The companion source MP4 is gitignored -- bring your own video to exercise the full ingest pipeline.
|
|
@@ -105,17 +104,17 @@ The repo ships a real Stage 3 audio sample at `tests/fixtures/stage-shots-tallmi
|
|
|
105
104
|
|
|
106
105
|
`splitsmith ui` checks for both on first launch and prints a copy-pasteable install hint if they're missing.
|
|
107
106
|
|
|
108
|
-
### Option 1: slim wheel (end users, ~100 MB)
|
|
109
|
-
|
|
110
|
-
The shipped install will be `uv tool install splitsmith` once the first release-please release lands on `main` (see [Releases](#releases) below). Detection models (~440 MB total) download from `models.splitsmith.app` on first detection -- pre-fetch with `splitsmith fetch-models`. No torch, transformers, or panns_inference in the install.
|
|
107
|
+
### Option 1: slim wheel (end users, ~100 MB)
|
|
111
108
|
|
|
112
109
|
```bash
|
|
113
|
-
uv tool install splitsmith #
|
|
110
|
+
uv tool install splitsmith # from PyPI
|
|
114
111
|
splitsmith fetch-models # pre-fetch ONNX artifacts (optional)
|
|
115
112
|
splitsmith ui --project ~/matches/your-match
|
|
116
113
|
```
|
|
117
114
|
|
|
118
|
-
|
|
115
|
+
Detection models (~440 MB total) download from `models.splitsmith.app` on first detection -- pre-fetch with `splitsmith fetch-models`. No torch, transformers, or panns_inference in the install.
|
|
116
|
+
|
|
117
|
+
### Option 2: from source (required for contributors)
|
|
119
118
|
|
|
120
119
|
```bash
|
|
121
120
|
git clone https://github.com/mandakan/splitsmith.git
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# splitsmith
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/splitsmith/)
|
|
4
|
+
[](https://pypi.org/project/splitsmith/)
|
|
5
|
+
[](https://github.com/mandakan/splitsmith/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/mandakan/splitsmith/actions/workflows/ci.yml)
|
|
7
|
+
|
|
3
8
|
Extract per-shot split times from head-mounted camera footage of IPSC matches and generate Final Cut Pro timelines with per-shot markers.
|
|
4
9
|
|
|
5
|
-

|
|
6
11
|
|
|
7
12
|
Built to do two things from a single stage video: get per-shot splits for analysis and coaching, and prepare frame-marked clips for match-footage review. Your head-mounted cam (Insta360 Go 3S in this case) already captures audio of every shot; the RO's timer only records your total stage time, so the splits live in the video and nowhere else. Splitsmith extracts them and turns them into a CSV plus an FCPXML timeline with per-shot markers you can step through in Final Cut Pro.
|
|
8
13
|
|
|
@@ -13,30 +18,24 @@ Built to do two things from a single stage video: get per-shot splits for analys
|
|
|
13
18
|
|
|
14
19
|
| | |
|
|
15
20
|
|---|---|
|
|
16
|
-
|  | **Ingest.** Drop a folder of GoPro clips; the engine auto-matches them to stages by file timestamp. |
|
|
17
|
-
|  | **Beep review.** Auto-snap to the start beep on each stage; low-confidence detections land in a HITL queue. |
|
|
18
|
-
|  | **Audit.** Waveform + per-shot markers from the 3-voter ensemble. Click a marker to inspect votes; drag to fine-tune. |
|
|
19
|
-
|  | **Compare.** Multi-shooter grid, all beep-aligned to t=0. Audio from one shooter, video tiles for everyone else. |
|
|
20
|
-
|  | **Export.** Per-stage or whole-match FCPXML. Open in Final Cut Pro, M / Shift+M to navigate markers. |
|
|
21
|
+
|  | **Ingest.** Drop a folder of GoPro clips; the engine auto-matches them to stages by file timestamp. |
|
|
22
|
+
|  | **Beep review.** Auto-snap to the start beep on each stage; low-confidence detections land in a HITL queue. |
|
|
23
|
+
|  | **Audit.** Waveform + per-shot markers from the 3-voter ensemble. Click a marker to inspect votes; drag to fine-tune. |
|
|
24
|
+
|  | **Compare.** Multi-shooter grid, all beep-aligned to t=0. Audio from one shooter, video tiles for everyone else. |
|
|
25
|
+
|  | **Export.** Per-stage or whole-match FCPXML. Open in Final Cut Pro, M / Shift+M to navigate markers. |
|
|
21
26
|
|
|
22
|
-
> Screenshots regenerate from a live `splitsmith ui` via `scripts/capture_screenshots.py`. See [
|
|
27
|
+
> Screenshots regenerate from a live `splitsmith ui` via `scripts/capture_screenshots.py`. See [Regenerating screenshots](#regenerating-screenshots) below.
|
|
23
28
|
|
|
24
29
|
## Quickstart
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
You need: `uv`, `ffmpeg`/`ffprobe` on PATH, and (for source checkouts) Node 20 + `pnpm` to build the SPA. See [Install](#install) for OS-specific package commands.
|
|
31
|
+
You need: `uv` and `ffmpeg`/`ffprobe` on PATH. See [Install](#install) for OS-specific package commands.
|
|
29
32
|
|
|
30
33
|
```bash
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
cd splitsmith
|
|
34
|
-
uv sync # slim runtime deps only (~100 MB)
|
|
35
|
-
(cd src/splitsmith/ui_static && pnpm install && pnpm build)
|
|
36
|
-
uv run splitsmith fetch-models # ~440 MB ONNX artifacts; one-time
|
|
34
|
+
uv tool install splitsmith # slim runtime, ~100 MB
|
|
35
|
+
splitsmith fetch-models # ~440 MB ONNX artifacts; one-time
|
|
37
36
|
|
|
38
37
|
# Bring your own head-cam clip and stage time (or use any IPSC video at hand)
|
|
39
|
-
|
|
38
|
+
splitsmith single \
|
|
40
39
|
--video path/to/your_stage.mp4 \
|
|
41
40
|
--time 14.74 \
|
|
42
41
|
--output ./demo_analysis \
|
|
@@ -50,7 +49,7 @@ cat ./demo_analysis/stage3_per-told-me-to-do-it_report.txt
|
|
|
50
49
|
For the full ingest -> audit -> export workflow with persistent project state, use the UI:
|
|
51
50
|
|
|
52
51
|
```bash
|
|
53
|
-
|
|
52
|
+
splitsmith ui --project ~/matches/your-match
|
|
54
53
|
```
|
|
55
54
|
|
|
56
55
|
The repo ships a real Stage 3 audio sample at `tests/fixtures/stage-shots-tallmilan-2026-stage3-s97dcec94.wav` (Tallmilan 2026, 14.74s, 14 audited shots) plus its sibling JSON with ground-truth shot times. The companion source MP4 is gitignored -- bring your own video to exercise the full ingest pipeline.
|
|
@@ -76,17 +75,17 @@ The repo ships a real Stage 3 audio sample at `tests/fixtures/stage-shots-tallmi
|
|
|
76
75
|
|
|
77
76
|
`splitsmith ui` checks for both on first launch and prints a copy-pasteable install hint if they're missing.
|
|
78
77
|
|
|
79
|
-
### Option 1: slim wheel (end users, ~100 MB)
|
|
80
|
-
|
|
81
|
-
The shipped install will be `uv tool install splitsmith` once the first release-please release lands on `main` (see [Releases](#releases) below). Detection models (~440 MB total) download from `models.splitsmith.app` on first detection -- pre-fetch with `splitsmith fetch-models`. No torch, transformers, or panns_inference in the install.
|
|
78
|
+
### Option 1: slim wheel (end users, ~100 MB)
|
|
82
79
|
|
|
83
80
|
```bash
|
|
84
|
-
uv tool install splitsmith #
|
|
81
|
+
uv tool install splitsmith # from PyPI
|
|
85
82
|
splitsmith fetch-models # pre-fetch ONNX artifacts (optional)
|
|
86
83
|
splitsmith ui --project ~/matches/your-match
|
|
87
84
|
```
|
|
88
85
|
|
|
89
|
-
|
|
86
|
+
Detection models (~440 MB total) download from `models.splitsmith.app` on first detection -- pre-fetch with `splitsmith fetch-models`. No torch, transformers, or panns_inference in the install.
|
|
87
|
+
|
|
88
|
+
### Option 2: from source (required for contributors)
|
|
90
89
|
|
|
91
90
|
```bash
|
|
92
91
|
git clone https://github.com/mandakan/splitsmith.git
|
|
@@ -328,8 +328,7 @@ class ShotRefineConfig(BaseModel):
|
|
|
328
328
|
method: Literal["envelope", "aic"] = "envelope"
|
|
329
329
|
# Half-width of the audio window scanned around each approximate time.
|
|
330
330
|
# 200 ms covers reverb-anchored cases where the candidate generator
|
|
331
|
-
# placed its rise foot 100-200 ms after the true onset
|
|
332
|
-
# PRECISION_LIMITS.md section 4a).
|
|
331
|
+
# placed its rise foot 100-200 ms after the true onset.
|
|
333
332
|
search_half_window_ms: float = 200.0
|
|
334
333
|
# Reject refinements whose confidence falls below this threshold and
|
|
335
334
|
# keep the original timestamp instead. 0.0 = always accept.
|
|
@@ -338,7 +337,7 @@ class ShotRefineConfig(BaseModel):
|
|
|
338
337
|
# least this much louder than the local-position peak. Small ratios
|
|
339
338
|
# (< 2.0) mean the original was already on a peak; tight rise-foot
|
|
340
339
|
# adjustment is used instead. Mirrors the same heuristic as the
|
|
341
|
-
# candidate-time reverb-chain re-anchor
|
|
340
|
+
# candidate-time reverb-chain re-anchor.
|
|
342
341
|
reanchor_ratio: float = 2.0
|
|
343
342
|
# AIC-only: bandpass before AIC. Muzzle-blast energy concentrates above
|
|
344
343
|
# ~500 Hz; bandpassing reduces wind/handling noise that can mask the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Generate Final Cut Pro XML timelines (FCPXML 1.10).
|
|
2
2
|
|
|
3
|
-
v1 scope (
|
|
3
|
+
v1 scope (intentionally minimal):
|
|
4
4
|
- One asset (the trimmed video) + one sequence at the source frame rate.
|
|
5
5
|
- V1 = ref-clip of the trimmed video.
|
|
6
6
|
- One ``<marker>`` per shot, frame-aligned, with a descriptive name that
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"""Production UI package for splitsmith.
|
|
2
2
|
|
|
3
3
|
The UI is a localhost SPA driven by a FastAPI backend that orchestrates the
|
|
4
|
-
existing engine modules unchanged.
|
|
5
|
-
for the v1 contract.
|
|
4
|
+
existing engine modules unchanged.
|
|
6
5
|
|
|
7
6
|
Sub-packages:
|
|
8
7
|
- ``project``: Pydantic models for the on-disk match-project layout
|
|
@@ -1059,7 +1059,7 @@ class BeepQueueItem(BaseModel):
|
|
|
1059
1059
|
beep_time: float | None
|
|
1060
1060
|
beep_confidence: float | None
|
|
1061
1061
|
beep_reviewed: bool
|
|
1062
|
-
status: Literal["missing", "low_confidence", "unreviewed"]
|
|
1062
|
+
status: Literal["missing", "low_confidence", "unreviewed", "confirmed"]
|
|
1063
1063
|
alt_candidates: list[BeepQueueAltCandidate]
|
|
1064
1064
|
# Auto-computed cross-align suggestion for secondaries lives on the
|
|
1065
1065
|
# shooter's other videos; the SPA fetches them lazily if needed.
|
|
@@ -7257,16 +7257,21 @@ def create_app(
|
|
|
7257
7257
|
# ----------------------------------------------------------------------
|
|
7258
7258
|
|
|
7259
7259
|
@app.get("/api/match/beep-queue", response_model=BeepQueueResponse)
|
|
7260
|
-
def get_beep_queue() -> BeepQueueResponse:
|
|
7260
|
+
def get_beep_queue(include_confirmed: bool = Query(default=False)) -> BeepQueueResponse:
|
|
7261
7261
|
"""Pending beep items across every shooter in the bound match.
|
|
7262
7262
|
|
|
7263
|
-
Surfaces three states per primary video:
|
|
7263
|
+
Surfaces three pending states per primary video:
|
|
7264
7264
|
- ``missing``: detector hasn't run or didn't find a beep
|
|
7265
7265
|
- ``low_confidence``: detector found one but below the project's
|
|
7266
7266
|
auto-trust threshold
|
|
7267
7267
|
- ``unreviewed``: detector found one above threshold but the
|
|
7268
7268
|
user hasn't yet listened + approved
|
|
7269
7269
|
|
|
7270
|
+
When ``include_confirmed`` is true the response also includes
|
|
7271
|
+
items whose beep has been reviewed, with ``status="confirmed"``.
|
|
7272
|
+
The SPA uses this for the "Show confirmed" toggle so the user
|
|
7273
|
+
can revisit a settled beep without having to clear-and-redo it.
|
|
7274
|
+
|
|
7270
7275
|
Items are grouped by stage; per-stage shot detection is gated on
|
|
7271
7276
|
every shooter's primary in that stage being ``beep_reviewed``.
|
|
7272
7277
|
"""
|
|
@@ -7320,12 +7325,15 @@ def create_app(
|
|
|
7320
7325
|
elif primary.beep_reviewed:
|
|
7321
7326
|
grp.confirmed += 1
|
|
7322
7327
|
total_confirmed += 1
|
|
7323
|
-
|
|
7328
|
+
if not include_confirmed:
|
|
7329
|
+
continue
|
|
7330
|
+
status = "confirmed"
|
|
7324
7331
|
elif primary.beep_confidence is not None and primary.beep_confidence < threshold:
|
|
7325
7332
|
status = "low_confidence"
|
|
7326
7333
|
else:
|
|
7327
7334
|
status = "unreviewed"
|
|
7328
|
-
|
|
7335
|
+
if status != "confirmed":
|
|
7336
|
+
total_pending += 1
|
|
7329
7337
|
alts = [
|
|
7330
7338
|
BeepQueueAltCandidate(
|
|
7331
7339
|
time=cand.time,
|
{splitsmith-0.2.0 → splitsmith-0.3.0}/src/splitsmith/ui_static/src/components/AuditControls.tsx
RENAMED
|
@@ -12,6 +12,7 @@ import { Maximize2, Minus, Plus } from "lucide-react";
|
|
|
12
12
|
|
|
13
13
|
import { MarkerGlyph, type MarkerKind } from "@/components/MarkerGlyph";
|
|
14
14
|
import { Button } from "@/components/ui/button";
|
|
15
|
+
import { modKeyLabel } from "@/lib/platform";
|
|
15
16
|
import { cn } from "@/lib/utils";
|
|
16
17
|
|
|
17
18
|
export interface MarkerFilters {
|
|
@@ -152,6 +153,7 @@ export function ZoomControls({ zoom, onZoomChange, className }: ZoomControlsProp
|
|
|
152
153
|
const next = base / ZOOM_STEP;
|
|
153
154
|
onZoomChange(next <= MIN_ZOOM ? null : next);
|
|
154
155
|
};
|
|
156
|
+
const mod = modKeyLabel();
|
|
155
157
|
|
|
156
158
|
return (
|
|
157
159
|
<div className={cn("inline-flex items-center gap-1", className)} role="group" aria-label="Zoom">
|
|
@@ -159,8 +161,8 @@ export function ZoomControls({ zoom, onZoomChange, className }: ZoomControlsProp
|
|
|
159
161
|
size="sm"
|
|
160
162
|
variant="ghost"
|
|
161
163
|
onClick={zoomOut}
|
|
162
|
-
aria-label=
|
|
163
|
-
title=
|
|
164
|
+
aria-label={`Zoom out (${mod}+3)`}
|
|
165
|
+
title={`Zoom out (${mod}+3)`}
|
|
164
166
|
>
|
|
165
167
|
<Minus className="size-3" />
|
|
166
168
|
</Button>
|
|
@@ -168,8 +170,8 @@ export function ZoomControls({ zoom, onZoomChange, className }: ZoomControlsProp
|
|
|
168
170
|
size="sm"
|
|
169
171
|
variant="ghost"
|
|
170
172
|
onClick={() => onZoomChange(null)}
|
|
171
|
-
aria-label=
|
|
172
|
-
title=
|
|
173
|
+
aria-label={`Fit waveform (${mod}+2)`}
|
|
174
|
+
title={`Fit waveform (${mod}+2)`}
|
|
173
175
|
aria-pressed={zoom == null}
|
|
174
176
|
>
|
|
175
177
|
<Maximize2 className="size-3" />
|
|
@@ -178,8 +180,8 @@ export function ZoomControls({ zoom, onZoomChange, className }: ZoomControlsProp
|
|
|
178
180
|
size="sm"
|
|
179
181
|
variant="ghost"
|
|
180
182
|
onClick={zoomIn}
|
|
181
|
-
aria-label=
|
|
182
|
-
title=
|
|
183
|
+
aria-label={`Zoom in (${mod}+1)`}
|
|
184
|
+
title={`Zoom in (${mod}+1)`}
|
|
183
185
|
>
|
|
184
186
|
<Plus className="size-3" />
|
|
185
187
|
</Button>
|