bppicker 0.2.2__tar.gz → 0.2.3__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.
- {bppicker-0.2.2 → bppicker-0.2.3}/.eslint-globals.json +3 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/CHANGELOG.md +36 -1
- bppicker-0.2.3/Dockerfile +130 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/NOTICE.txt +34 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/PKG-INFO +104 -30
- {bppicker-0.2.2 → bppicker-0.2.3}/README.md +103 -29
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/__init__.py +1 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/cli.py +4 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/model_attribution.py +9 -1
- bppicker-0.2.3/bpp/scoring/cpu_support.py +105 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face.py +1 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_mediapipe.py +3 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/install_hold.py +13 -3
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/model_base.py +10 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/concurrency.py +5 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/path_validation.py +5 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/subprocess_runner.py +18 -4
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_model_preflight.py +11 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_core.py +5 -5
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_install.py +9 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_extraction_phase5.py +10 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/library.mjs +7 -14
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/modals.mjs +4 -7
- bppicker-0.2.3/bpp/web/static/js/modules/native-pick.mjs +32 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/onboarding.mjs +8 -11
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/utils.mjs +7 -14
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/configuration.md +21 -0
- bppicker-0.2.3/docs/landing/assets/02-lightbox-1600.webp +0 -0
- bppicker-0.2.3/docs/landing/assets/02-lightbox-900.webp +0 -0
- bppicker-0.2.3/docs/landing/assets/03-faces-1600.webp +0 -0
- bppicker-0.2.3/docs/landing/assets/03-faces-900.webp +0 -0
- bppicker-0.2.3/docs/landing/assets/10-duplicates-1600.webp +0 -0
- bppicker-0.2.3/docs/landing/assets/10-duplicates-900.webp +0 -0
- bppicker-0.2.3/docs/landing/assets/apple-touch-icon.png +0 -0
- bppicker-0.2.3/docs/landing/assets/demo-960.mp4 +0 -0
- bppicker-0.2.3/docs/landing/assets/demo-poster.jpg +0 -0
- bppicker-0.2.3/docs/landing/assets/demo-poster.webp +0 -0
- bppicker-0.2.3/docs/landing/assets/demo.mp4 +0 -0
- bppicker-0.2.3/docs/landing/assets/favicon-32.png +0 -0
- bppicker-0.2.3/docs/landing/assets/favicon-64.png +0 -0
- bppicker-0.2.3/docs/landing/assets/favicon.svg +18 -0
- bppicker-0.2.3/docs/landing/assets/og.jpg +0 -0
- bppicker-0.2.3/docs/landing/index.html +1010 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/quickstart-gallery.md +6 -6
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/security.md +7 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/pyproject.toml +1 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_analyze_preflight_toggles.py +3 -0
- bppicker-0.2.3/tests/test_container_rough_edges.py +196 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_loopback_boot_key.py +4 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_packaging.py +69 -4
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_parallel_map_window.py +1 -1
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/dispatcher.test.mjs +3 -9
- bppicker-0.2.3/tests-js/native-pick.module.test.mjs +59 -0
- bppicker-0.2.2/Dockerfile +0 -108
- bppicker-0.2.2/docs/landing/index.html +0 -243
- {bppicker-0.2.2 → bppicker-0.2.3}/.gitignore +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/CODE_OF_CONDUCT.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/CONTRIBUTING.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/LICENSE +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/MANIFEST.in +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/MODEL_POLICY.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/SECURITY.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/ai/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/ai/inpainting.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/analyze.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/db_restore.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/db_restore_impl.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/demo.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/model.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/model_commands.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/pick.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/commands/serve.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/config.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/config_builtins.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/config_resolver.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/config_schema.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/constants.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/album_photos.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/albums.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/backup.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/batch_rename.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/calendar.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/clip.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/connection.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/dedupe.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/dialect.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/edits.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/event_hooks.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_cluster_ids.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_cluster_ops.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_embedding_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_feedback.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_identity_remap.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_name_matching.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_name_placement.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_name_relocate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_queries.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_same_photo.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_switch_finish.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/face_switch_record.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/groups.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/integrity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/journal.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/library.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/library_copy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/live_photo.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/live_photo_scan.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/memories.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/migrate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/migrations.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/migrations_latest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/migrations_recent.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/moments.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/people_placement.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/pets.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/photo_hooks.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/photos.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/photos_dates.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/photos_gps.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/photos_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/photos_missing.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/photos_sha.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/photos_updates.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/presets.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/schema.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/schema_migrate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/settings.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_builtins.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_document.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_domains.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_ensure.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_groups.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_people.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_pets.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_queries.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_refreshers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_sensitive.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_album_tags.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/smart_albums.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/sql_batches.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/stats.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/db/tags.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/dedupe/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/dedupe/cluster.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/dedupe/common.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/dedupe/phash.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/dedupe/select.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/dedupe/semantic.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/dedupe/strategy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/demo/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/demo/generate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/errors.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/exif_utils.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/io_scan.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/media_types.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/output/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/output/export.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/output/export_metadata.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/output/export_modes.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/output/export_pixels.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/output/export_reports.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/output/gallery.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/plugin_protocol.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/plugins/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/plugins/example.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/plugins/registry_protocol.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/acceptance.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/acceptance_log.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/acceptance_log_files.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/acceptance_log_parse.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/attribution_bundle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/builtins.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/builtins_bundled.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/byom.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/derived_data_purge.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/disclaimers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/download_chokepoint.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/labels.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/manifest_rollback.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/model_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/overlay.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/policy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/remote_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/removal.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/signed_manifest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/trusted_keys.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/use_context.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/registry/use_context_store.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/_registry_base.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/aggregate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/aggregate_video.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/blur.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/clip_embed.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/clip_tokenizer.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/composition.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/enhance.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/exposure.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_blazeface_fr.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_cluster.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_detector_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed_buffalo.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed_buffalo_s.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed_detect.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed_extractors.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed_landmarks.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed_plugin.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed_sface.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embed_sface_runtime.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_embedder_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_expression.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_fallback.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_hand_filter.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_pipeline.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_recognition_loader.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_score.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_scrfd.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_threshold.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/face_yunet.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/inference_log.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/model_download.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/model_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/model_load_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/model_manifest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/models/blaze_face_short_range.tflite +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/nudity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/onnx_providers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/pets.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/pose.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/segmentation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/skin.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/scoring/toggles.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/selection/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/selection/choose.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/selection/diversity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/cancel.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/config_snapshot.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/download.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/fresh_file.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/json_utils.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/logging.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/paths.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/raw.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/retry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/safe_subprocess.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/serving_lock.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/timing.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/utils/video.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/_deprecated_attr.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/album_siblings.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analysis_store.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_archive.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_face_extract.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_finalize.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_phases.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_run_steps.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_scoring.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_subprocess.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/analyze_worker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/app.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/auth_boundary.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/base_worker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/box_crop.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_album_overrides.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_albums.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_analysis.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_attribution.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_calendar.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_catalog.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_clip.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_export.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_faces.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_faces_bbox.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_faces_cluster_ops.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_faces_extract.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_faces_manage.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_faces_photo.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_faces_recluster.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_faces_review.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_groups.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_health.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_inpaint.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_library.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_logs.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_media.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_memories.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_model_admin.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_model_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_models.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_os_integration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_pets.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_photos.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_photos_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_photos_manage.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_photos_missing.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_recompute.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_search.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_settings.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_share.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/bp_tags.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/catalog_loaders.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/clip_cap.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/clip_worker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/derived_recovery.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/download_gates.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/e2e_fixture.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/export_worker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_create_helpers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_crop.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_extraction_journal.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_extraction_phase6.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_extraction_phases.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_lock.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_merge_core.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_method_reconcile.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_orchestrator.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_phase_classes.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_phase_pipeline.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_phase_types.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_recovery.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/face_worker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/faces_review_match.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/filters.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/health.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/host_allowlist.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/import_worker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/install_busy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/install_specs.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/install_status.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/install_stream.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/lan_redaction.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/library_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/media_support.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/model_cache.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/model_download_jobs.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/model_filter.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/models_status.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/paging.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/permanent_delete.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/photo_cache.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/photo_dict.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/photo_edits.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/picker_fields.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/pip_process.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/recompute.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/request_validation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/review_meta.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/share.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/share_devices.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/share_proxy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/share_qr.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/share_runtime.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/sse.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/state.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/state_compat.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/state_helpers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/state_init.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/state_init_phases.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/state_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/state_ops.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/state_startup_steps.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/css/app.css +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/img/apple-touch-icon.png +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/img/icon-192.png +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/img/icon-512.png +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/globals.js +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/action-registry.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/activity-humanize.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/activity-log.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/albums-menus.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/albums-render-helpers.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/albums-render-smart.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/albums-render.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/albums-switch.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/albums.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/analysis-install.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/analysis-preflight.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/analysis-recompute.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/analysis-status.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/analysis.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/api-client.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/app.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/attribution-consent.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/batch-rename.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/boot-health.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/boot-proof.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/calendar-render.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/calendar-selection.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/calendar.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/client-error-beacon.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/clip.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/compare-sibling.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/compare.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/constants.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/core.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/date-format.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/deleted-ctx-menu.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/deleted-enhance.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/deleted.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/dialog-focus.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/dialogs.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/download-jobs.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/dupe-review.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor-constants.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor-crop.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor-inpaint.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor-preview.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor-redeye.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor-rendering.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor-styles.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor-tools.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/editor.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-acceptance.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-actions.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-busy.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-catalog.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-cells.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-guesses.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-license.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-menu-render.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-popover.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-row-facts.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-rowstate.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/face-embedders-state.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/faces-extraction.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/faces.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/format-helpers.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/groups.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/import-worker.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/inspector.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/install-done.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-actions.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-ctxmenu.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-face-assign.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-face-commit.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-face-edit.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-face-overlays.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-face-picker-actions.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-face-picker.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-info.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-input.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox-open.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/lightbox.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/map.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/memories.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/menu-a11y.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/modal.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/modals-face-embedders.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/models-changed.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/moments-stacks.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/moments-view.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/navigation.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/nudges.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/on-this-day.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/paging.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-actions.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-album-bar.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-ctx-menu.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-merge.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-pair-review.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-pickers.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-rename.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-review-card.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-review.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people-view.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/people.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/pets-pickers.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/pets.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/phash-status.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photo-preview.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photos-batch.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photos-card.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photos-grid-filter.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photos-helpers.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photos-hover.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photos-select.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photos-vgrid.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/photos.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/picker-overlay.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/presets.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/review-meta.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/score-format.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/search-results-html.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/search.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/sensitive.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/settings-client.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/share-tab.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/sidebar-safety.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/slideshow.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/state.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/tags-view.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/tags.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/text-format.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/theme.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/timeline.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/toast.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/toolbar.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/tooltip.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/tour.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/ui-helpers.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/update-checker.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/use-context-options.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/view-guard.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/js/modules/wizard.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/manifest.json +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/README.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet/LICENSE +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet/dist/images/layers-2x.png +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet/dist/images/layers.png +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet/dist/images/marker-icon-2x.png +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet/dist/images/marker-icon.png +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet/dist/images/marker-shadow.png +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet/dist/leaflet.css +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet/dist/leaflet.js +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet.markercluster/MIT-LICENCE.txt +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet.markercluster/dist/MarkerCluster.Default.css +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet.markercluster/dist/MarkerCluster.css +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/static/vendor/leaflet.markercluster/dist/leaflet.markercluster.js +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/templates/index.html +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/templates/loopback_locked.html +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/templates/pair.html +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/templates/pair_needs_link.html +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/thumbnails.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/update_checker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/worker_pool.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/bpp/web/worker_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/API.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/adding-a-model.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/adr/0001-subprocess-runner.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/adr/0002-cancellation-contract.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/adr/0003-plugin-protocol.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/adr/0004-error-hierarchy.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/adr/0005-legal-posture-and-model-registry.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/adr/README.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/architecture-notes.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/macos-signing.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/docs/plugins.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/examples/plugin_example/README.md +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/examples/plugin_example/bpp_example_plugin/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/examples/plugin_example/bpp_example_plugin/plugin.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/examples/plugin_example/pyproject.toml +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/launch.command.template +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/sample_config.yaml +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/check_no_bundled_weights.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/export_clip_onnx.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/extract-js-names.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/function-loc.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/generate-eslint-globals.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/generate_demo_library.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/publish_registry_manifest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/run_e2e.sh +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/run_mock_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/setup_e2e_library.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/sign_registry_manifest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/third_party_bundled.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/third_party_inventory.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/third_party_sources.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/scripts/verify_live_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_authorize_request_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_blueprint_coverage_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_bp_analysis_photos_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_clip_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_clustering_stability_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_coverage_gaps_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_db_restore_command_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_db_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_detector_stubs.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_enhance_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_export_sidecar_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_export_utils_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_face_extraction_journal_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_face_landmark_validation_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_face_name_preservation_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_face_review_flow_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_face_scan_scoring_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_faces_create_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_faces_new_endpoints_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_git.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_install_support.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_integration_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_js_source_scan_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_log_redaction_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_media_state_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_model_quality_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_models.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_packaging_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_plugin_loader_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_recompute_coverage_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_robustness_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_smart_album_coverage_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_trust_proxy_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_video_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/_web_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/conftest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/owner_only/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/owner_only/_owner.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/owner_only/conftest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/owner_only/test_install_info_owner_only.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/owner_only/test_owner_only_endpoints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/owner_only/test_owner_only_mutations.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/owner_only/test_owner_only_paths.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/__init__.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/_acceptance_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/_download_chokepoint_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/_model_registry_shared.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/conftest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_acceptance.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_acceptance_endpoint_status.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_acceptance_revocation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_acceptance_row_coercion.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_acceptance_state.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_acceptance_strict_answers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_attribution_bundle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_attribution_bundle_endpoints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_buffalo_s_entry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_byom.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_catalog_weights_endpoints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_default_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_download_chokepoint.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_download_chokepoint_single_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_download_status_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_load_state_endpoints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_manifest_rollback.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_model_policy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_model_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_picker_entry_fields.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_policy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_primary_for_kind.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_redownload_legal_map.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_removal.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_restricted_entries.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_runtime_enforcement.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_signed_manifest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_stale_acceptance.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/registry/test_surface_parity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/scoring/test_face_embed_buffalo_s.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/scoring/test_runtime_reset.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_acceptance_log_fail_closed.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_activity_log.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_album_hierarchy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_album_type_constants.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_analysis_store.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_analyze_downstream_uses_worker_ctx.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_analyze_preflight_licenses.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_analyze_worker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_api_doc_no_dead_params.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_api_doc_response_fields.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_api_doc_status_and_install_state.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_api_versioning.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_attr_interpolation_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_auth_token.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_authorize_request.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_authorize_request_constant_time_token_compare.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_auto_purge_containment.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_auto_purge_journaled_with_cache_cleanup.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_auto_restore_uses_backup_wal.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_base_worker_error_emit.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_batch_name_sanitize.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_batch_rename.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_batch_rename_apply_refreshes.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_batching_and_layering.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_blueprint_coverage.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_blueprint_coverage_album_override.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_blueprint_coverage_album_workflow.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_blueprint_coverage_faces_merge.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_blueprint_coverage_faces_restore.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_blueprints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_bp_analysis_photos.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_bp_analysis_photos_api_batch_favorite.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_bp_analysis_photos_api_export.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_bp_library.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_bulk_untag_batch.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_bundled_model_gating.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cache_cleanup_on_delete.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cache_invalidation_audit.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cache_suffix_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cached_image_lock.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_calendar.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cancel.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cancel_propagation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_catalog_loader_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cli_model_accept_attribution.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cli_pick.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_cli_plugin_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clip.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clip_matrix_cache.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clip_memory.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clip_search.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clip_semantic_deduplicate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clip_worker_cancel.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clustering_stability.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clustering_stability_as_completed_order_bug.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clustering_stability_edges.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_clustering_stability_reanalysis_preserves_cluster_ids.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_commands.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_config_fallbacks_match_defaults.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_config_resolver.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_config_schema.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_config_snapshot.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_constants.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_coverage_gaps.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_coverage_gaps_core_blueprint_gaps.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_coverage_gaps_schema_migrations.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_csp.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_db.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_db_connection_count.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_db_migration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_db_restore_command.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_db_restore_command_restore_proceeds_after_corrupt_quarantine_cleanup.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_db_restore_command_running_server_lock.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_db_smart_albums.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_dedupe_defaults.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_dedupe_one_path.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_dedupe_phash.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_dedupe_strategy_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_default_library_isolation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_demo.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_desktop_failure_screens.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_desktop_shell_boot.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_dialect.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_diversity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_dlib_acceptance_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_docker_healthcheck.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_docs_paths_exist.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_download.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_dupe_review.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_embedding_size_contract.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_empty_states.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_endpoint_docstrings.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_enhance.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_enhance_apply_advanced_edits.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_enhance_apply_edits.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_enhance_blur.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_enhance_new_apply_edits.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_env_var_docs.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_errors.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_errors_flask_handler.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_eslint_globals_generator.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_exif.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_exif_parse_cache.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_disk_full.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_metadata_fail_closed.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_mode_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_never_writes_through_links.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_process_orientation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_raw_converted.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_resized_strips_metadata.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_sidecar.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_sidecar_export_selected_manifest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_sync_uses_shared_validation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_utils.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_utils_export_metadata_privacy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_utils_generate_gallery.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_utils_setup_logging.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_worker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_export_zip_keeps_existing_files.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_cap.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_chunk_clustering.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_cluster_id_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_cluster_map_cache.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_cluster_map_invalidated_after_extraction.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_cluster_ops.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_count_sync.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_data_safety_round2.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_data_safety_round3.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_data_safety_round4.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_detector_single_binding.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_embed_detect.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_embedding_method_dispatch.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_embedding_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extract_batching.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extraction_journal.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extraction_journal_orchestrator_resume.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extraction_journal_resume_recaptures_dismissed_slots.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extraction_journal_ship_criterion6k_signal_injection.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extraction_max_long_side.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extraction_phases.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extraction_phases_late.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_extraction_wal_checkpoint.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_fallback_blocked.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_feedback.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_group_photos.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_grouping_threshold.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_identity_boundaries.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_identity_by_face.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_landmark_validation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_landmark_validation_tiled_detection.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_lock_coverage.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_lock_timeout.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_name_final_placement.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_name_matching.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_name_placement.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_name_preservation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_name_preservation_empty_cluster_guard.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_name_retry_and_tags.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_name_switch.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_name_switch_edges.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_no_dlib_second_try.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_pipeline.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_recognition_loader.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_recovery_serialized.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_recovery_thread.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_registries.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_review_e2e.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_review_flow.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_scan_scoring.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_scan_scoring_hamming_distance.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_scan_scoring_suppress_hand_faces.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_switch_album_contents.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_switch_coverage.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_switch_guard.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_switch_races.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_switch_resume.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_thread_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_face_worker_row_factory.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_faces_create.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_faces_create_new_person.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_faces_new_endpoints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_faces_new_endpoints_embedding_validation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_faces_photo_bbox_dims.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_faces_update_bbox.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_final_sweep_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_final_sweep_perf.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_fresh_file.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_function_loc_cap.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_get_handlers_survive_write_failure.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_gps_columns_migration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_gps_pagination.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_groups.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_hardening_regressions.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_health_and_startup_logging.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_health_endpoint.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_health_install_downloads_phash.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_heif_registration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_host_allowlist.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_image_decode_cap.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_import_crash_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_import_raw_and_video_by_default.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_import_scoring_settings.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_init_app_db_helpers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_inpainting.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_install_claims.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_install_hold.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_install_left_over.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_install_paired_devices.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_install_progress.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_install_refusals.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_integration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_integration_library_switch_workflow.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_item14_followups.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_journal.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_journal_recovery.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_js_source_scan.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_js_source_scan_critical_function_refs.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_js_source_scan_mobile_lightbox.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_json_set_aside.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_json_shape.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_lan_payload_paths.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_large_library_caps.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_layering_endpoint_helpers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_libraries_paths.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_library_binding.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_library_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_library_rename_traversal.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_library_switch.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_license_check_per_photo.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_licenses.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_live_photo.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_live_photo_detect_and_link.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_loc_cap.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_log_redaction.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_log_redaction_werkzeug_redaction.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_map.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_max_content_length.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_media_auth_integration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_media_state.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_media_state_build_photo_dict.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_media_state_check_dedup_feedback.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_media_state_thumbnail_verified_integration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_media_types.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_mediapipe_inference_failures_logged.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_mediapipe_thread_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_memories.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_memory_soak.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_migration_multi_step.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_missing_coverage.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_missing_files_guard.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_missing_scan_flag_lifecycle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_missing_scan_refusal_surfaced.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_cache.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_constants_documented.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_download_jobs.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_download_locks.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_download_robustness.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_license_single_source.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_license_status.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_load_gate_freshness.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_manifest.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_quality.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_quality_pose_classification.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_singleton.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_model_singleton_unpinned.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_models_pending_endpoint.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_moments.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_mypy_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_nas_resilience.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_near_duplicate_clusters.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_no_duplicate_test_names.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_no_import_cycles.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_no_third_party_cdn.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_nudity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_nudity_active_switch.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_nudity_decode.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_nudity_download.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_nudity_integrity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_nudity_label_validation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_on_this_day.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_onnx_providers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_open_folder_restrict.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_orphan_person_albums.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_packaging_docs_consistency.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pair_endpoints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pair_status_touch.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pairing_requires_share_token.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_path_validation_helper.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_paths.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pattern_lint.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_assign_new_faces_vectorized.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_cache_cleanup_no_listing.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_face_cluster_blocked.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_face_clusters_no_decode.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_groups_single_pass.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_jpeg_draft.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_live_photo_backfill_queries.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_pagination.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_phash_backfill_batches.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_semantic_pass2_blocked.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_top_rated_refresh.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_perf_yunet_detector_reuse.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_permanent_delete_guard.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_permanent_delete_quarantine_edges.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_permanent_delete_recycle_bin.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_persist_atomicity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pet_cluster_iou_match.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pet_crop_cache_key.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pets.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pets_pet_detections_crud.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pets_smart_albums.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_phash_backfill_throttle.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_phash_generation_guard.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_photo_cache_edit_sweep.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_photo_dict_typed.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_photo_hooks.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_photo_summary_builders.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_photos_pagination.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_picker_tables_in_sync.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pip_process.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_pipeline_fixes.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_albums_exports_hooks.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_extensibility.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_face_backends.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_lifecycle_and_indexed_smart_person.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_loader.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_loader_loader_respects_version_requirement.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_models_visible.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_protocol.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_run_toggle_handoff.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_switch_in_picker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_toggle_keys.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugin_weight_keys_lazy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_plugins_doc_claims.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_polish_features.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_post_cluster_dispatch.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_privacy_claims.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_property_exif.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_property_paths.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_property_share.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_raw.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_raw_decode.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_raw_full_photo_edits.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_raw_readers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_reanalyze_keeps_provenance.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_recent_hidden.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_recompute_coverage.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_recompute_coverage_optimize.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_recompute_dedupe_cache.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_recompute_override_clamp.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_recovery_library_bound.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_redeye_points.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_refresh_domains_used.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_refresh_smart_albums_kinds.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_registry_protocol.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_release_hardening.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_remap_person_tags.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_rename_overwrite_guard.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_request_validation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_review_meta.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_robustness.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_robustness_first_run_api.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_robustness_per_step_migration_backup.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_route_registration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_sample_config_defaults.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scan_extensions_config.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scan_progress.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scan_skips_internal_dirs_deep.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scorer_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scores_sync.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scoring_blur.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scoring_subprocess.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scrfd.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_scrfd_license_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_search.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_search_like_escape.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_security_endpoints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_sensitive.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_serve_debug_flag.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_serve_host_default.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_serve_log_handler_ordering.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_serving_lock.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_settings_ui.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share_access_log.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share_auth_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share_cookie.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share_db.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share_devices.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share_endpoints.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share_schema_migration.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_share_token_rotation_backups.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_sidecar_entry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_sidecar_hidden_imports.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_smart_album_coverage.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_smart_album_coverage_thumbnail_cache.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_smart_album_presentation.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_smart_album_queries.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_smart_album_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_smart_album_unique.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_smart_person_cluster_id_v36.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_smoke.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_sql_variable_limit.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_sse_event.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_sse_shared_stream.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_ssl_context_normalization.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_startup_backup_failure_is_not_corruption.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_startup_integrity_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_state_change_logging.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_state_compat_delegates_logged.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_stats.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_subprocess_runner.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_subprocess_runner_user_message.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_tag_rename_collision.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_tags.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_third_party_inventory.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_thumbnail_write_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_timeline.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_trim_export_rename_safety.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_trust_proxy.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_trust_proxy_behind_proxy_gated_by_trusted_networks.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_update_checker.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_video.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_video_metadata_db.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_video_trim_updates_row.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_web.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_web_batch_routes.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_web_face_recluster.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_whole_tree_review_batch2.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_whole_tree_review_batch3.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_whole_tree_review_batch3b.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_whole_tree_review_fixes.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_worker_finalize.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_worker_pool.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_worker_registry.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_workers.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_yunet_sface.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_yunet_sface_acceptance_gate.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests/test_yunet_sface_integrity.py +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/_albums-setup.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/_analysis-setup.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/_deleted-setup.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/_editor-setup.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/_install-helpers.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/_lightbox-setup.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/_photos-setup.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/_toolbar-setup.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/action-registry.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/activity-humanize.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/activity-log.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/albums-presentation.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/albums-render-album-nav.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/albums-smart-album-context-menu.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/albums.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/analysis-refresh-status-right.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/analysis.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/api-client.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/attribution-consent.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/batch-rename.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/boot-health.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/boot-proof.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/calendar-keys-scope.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/calendar.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/cards-keyboard.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/client-error-beacon.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/clip.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/compare-sibling.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/compare.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/core.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/ctx-menu-shortcuts.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/date-format.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/deleted-batch-enhance.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/deleted.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/dialog-focus.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/dialogs.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/download-jobs.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/dupe-review.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/editor-crop.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/editor-inpaint.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/editor-redeye.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/editor.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/escape-order.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/face-embedders-blocker-text.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/face-embedders-escape.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/face-embedders-license-badge.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/face-embedders-load-failures.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/face-embedders-load-state.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/face-embedders-primary.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/face-embedders-reaccept.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/face-embedders-run-toggle.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/faces-reextract.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/faces.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/final-sweep-ui.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/format-helpers.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/function-loc-cap.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/groups.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/import-worker.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/inspector.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/install-done.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/install-packages-note.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/install-prompts.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/library.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox-add-face.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox-bbox-edit.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox-ctx-menu-clamp.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox-esc-dialog.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox-face-edit.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox-lb-delete.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox-map-guard.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox-map.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/lightbox.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/map.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/media-error-reload.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/media-url-auth.regression.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/memories.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/menu-a11y.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/menu-actions.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/modal.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/modals-face-embedders-busy-gate.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/modals-face-embedders-derive-row-state.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/modals-face-embedders-redownload-face-embedder-entry.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/modals-face-embedders-status-cell-menu-agree.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/modals-face-embedders.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/modals.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/models-changed-wiring.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/models-changed.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/moments-stacks.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/moments-view.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/mutation-error-toasts.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/nav-keyboard.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/navigation.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/no-local-escAttr.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/nudges.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/on-this-day.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/onboarding-use-context.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/onboarding.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/optimistic-handlers.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/paging.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/pair-page.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/pair-review-escape.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/pass-event-pattern.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/pattern-lint.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/people-actions.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/people-merge-bulk.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/people-merge-override-revert.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/people-pair-review.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/people-rename.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/people-review-esc.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/people-view-load.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/people-view.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/pet-crop-url.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/pets.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/phash-status.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/photo-load-error.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/photo-preview.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/photos-apply-zoom.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/photos-card-moment-preserve.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/photos-card-moment.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/photos-keynav.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/photos.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/picker-overlays.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/picker-server-fields.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/presets.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/review-meta.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/review15-ui-races.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/score-format.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/search-seq.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/search.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/sensitive.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/settings-client.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/settings-models-load.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/share-tab.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/sidebar-safety.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/sliders-delegation.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/slideshow.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/state.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/tags-view.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/tags.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/text-format.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/theme.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/timeline.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/toast.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/toolbar.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/tooltip.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/tour.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/types/globals.d.ts +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/ui-helpers.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/update-checker.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/use-context-options.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/utils.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/view-guard.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/whole-tree-review-batch2.module.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/window-pollution.test.mjs +0 -0
- {bppicker-0.2.2 → bppicker-0.2.3}/tests-js/wizard.module.test.mjs +0 -0
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"MODELS_CHANGED_EVENT": "writable",
|
|
26
26
|
"MONTHS_FULL": "writable",
|
|
27
27
|
"MONTHS_SHORT": "writable",
|
|
28
|
+
"NO_PICKER_LIBRARY_MESSAGE": "writable",
|
|
29
|
+
"NO_PICKER_MESSAGE": "writable",
|
|
28
30
|
"NUDGE_DEFS": "writable",
|
|
29
31
|
"RESUME_TEXT": "writable",
|
|
30
32
|
"ROW_LIFECYCLE": "writable",
|
|
@@ -769,6 +771,7 @@
|
|
|
769
771
|
"petsFilter": "writable",
|
|
770
772
|
"petsSort": "writable",
|
|
771
773
|
"photos": "writable",
|
|
774
|
+
"pickFolder": "writable",
|
|
772
775
|
"pickTagSuggestion": "writable",
|
|
773
776
|
"pickable": "writable",
|
|
774
777
|
"planBootHealth": "writable",
|
|
@@ -6,6 +6,40 @@ this project follows [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.2.3] — 2026-11-03
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **A ready-made Docker image for Linux servers**,
|
|
13
|
+
`ghcr.io/arkalogy/bppicker`, for Intel and 64-bit ARM (not yet
|
|
14
|
+
tried on a NAS). Run it headless
|
|
15
|
+
(`bpp run` copies the best photos of a folder into another one) or run
|
|
16
|
+
the full app, published to the server's loopback and opened with the
|
|
17
|
+
keyed link in `docker logs`. The README's Docker section has the
|
|
18
|
+
commands. The image keeps the boot key on, so other containers and
|
|
19
|
+
users on the server get a locked page.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- **Face grouping no longer hangs on Linux.** Worker processes were
|
|
23
|
+
started by copying the running server, background threads and all,
|
|
24
|
+
and the face-extraction worker could wait forever, ending after ten
|
|
25
|
+
minutes with no faces. Workers now start fresh on every system, as
|
|
26
|
+
they already did on macOS.
|
|
27
|
+
- **Intel processors without AVX** (many NAS Celerons and Atoms) no
|
|
28
|
+
longer crash analysis. MediaPipe's library needs AVX; the app now
|
|
29
|
+
checks once at start-up, skips the MediaPipe scorers (pose,
|
|
30
|
+
expression, hand, subject segmentation, BlazeFace short-range) with
|
|
31
|
+
one warning, and doesn't download their models.
|
|
32
|
+
- **No install buttons where installs can't work.** When pip can't
|
|
33
|
+
write anywhere (the Docker image), the app no longer offers in-app
|
|
34
|
+
installs that would fail.
|
|
35
|
+
- **Browse buttons say when there is no folder picker.** Off macOS the
|
|
36
|
+
button failed with an error; it now asks you to type the path.
|
|
37
|
+
- **`bpp model accept-attribution` without a terminal** explains how to
|
|
38
|
+
confirm instead of ending in a traceback.
|
|
39
|
+
- **Export and open-folder no longer trust a home folder of `/`**, which
|
|
40
|
+
a service account or a container user can have; it would have
|
|
41
|
+
allowed every path.
|
|
42
|
+
|
|
9
43
|
## [0.2.2] — 2026-10-24
|
|
10
44
|
|
|
11
45
|
### Fixed
|
|
@@ -584,7 +618,8 @@ External calls are limited to documented features:
|
|
|
584
618
|
desktop wrapper currently builds only the macOS bundle.
|
|
585
619
|
- Python 3.11 only (CI tests this version; 3.12+ is unvalidated).
|
|
586
620
|
|
|
587
|
-
[Unreleased]: https://github.com/Arkalogy/best-photo-picker/compare/v0.2.
|
|
621
|
+
[Unreleased]: https://github.com/Arkalogy/best-photo-picker/compare/v0.2.3...HEAD
|
|
622
|
+
[0.2.3]: https://github.com/Arkalogy/best-photo-picker/releases/tag/v0.2.3
|
|
588
623
|
[0.2.2]: https://github.com/Arkalogy/best-photo-picker/releases/tag/v0.2.2
|
|
589
624
|
[0.2.1]: https://github.com/Arkalogy/best-photo-picker/releases/tag/v0.2.1
|
|
590
625
|
[0.2.0]: https://github.com/Arkalogy/best-photo-picker/releases/tag/v0.2.0
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Self-hosting image, published to the GitHub Container Registry:
|
|
2
|
+
# docker pull ghcr.io/arkalogy/bppicker
|
|
3
|
+
# Two ways to use it (README "Docker" section has the full commands):
|
|
4
|
+
# * headless: `bpp run` picks the best photos from a mounted folder and
|
|
5
|
+
# copies them to another mounted folder; no browser needed;
|
|
6
|
+
# * the full app: `bpp serve` (the default command), published to the
|
|
7
|
+
# host's loopback only, opened with the keyed link it prints, and
|
|
8
|
+
# reached from another computer through an SSH tunnel.
|
|
9
|
+
# Build it yourself with `docker build -t bppicker .`.
|
|
10
|
+
#
|
|
11
|
+
# The image installs only pip wheels (no compiler): the web, HEIC and
|
|
12
|
+
# camera-RAW extras plus the wheel-only part of the `faces` extra
|
|
13
|
+
# (mediapipe, ai-edge-litert, scipy), which the pose, expression,
|
|
14
|
+
# segmentation and BlazeFace scorers need. A test keeps that list equal
|
|
15
|
+
# to `faces` in pyproject.toml. Only dlib / face_recognition are left out:
|
|
16
|
+
# they need a compiler, and their bundled landmark model has
|
|
17
|
+
# non-commercial training-data terms, so this image does not
|
|
18
|
+
# redistribute it. The default face models (YuNet / SFace) download at
|
|
19
|
+
# first use after the license prompt, exactly as in the app; the only
|
|
20
|
+
# model files in the image are the two small ones that ship inside the
|
|
21
|
+
# packages (bpp's BlazeFace short-range and OpenCV's Haar cascade).
|
|
22
|
+
FROM python:3.11-slim
|
|
23
|
+
|
|
24
|
+
# libgl1 / libglib2.0-0: mediapipe pulls in the full (non-headless)
|
|
25
|
+
# opencv-contrib-python wheel, which loads them at import time.
|
|
26
|
+
# libegl1 / libgles2: mediapipe's native Tasks library links EGL and
|
|
27
|
+
# GLES; without them every mediapipe scorer fails to load.
|
|
28
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
29
|
+
libgl1 libglib2.0-0 libegl1 libgles2 && \
|
|
30
|
+
rm -rf /var/lib/apt/lists/*
|
|
31
|
+
|
|
32
|
+
WORKDIR /app
|
|
33
|
+
# Dependencies first, in a layer that depends only on pyproject.toml, so
|
|
34
|
+
# a code change doesn't reinstall them: install against an empty
|
|
35
|
+
# package, then drop it.
|
|
36
|
+
# (README.md is a stub here, so a docs edit doesn't bust this layer.)
|
|
37
|
+
COPY pyproject.toml ./
|
|
38
|
+
RUN mkdir bpp && touch bpp/__init__.py README.md \
|
|
39
|
+
&& pip install --no-cache-dir ".[web,heic,raw]" \
|
|
40
|
+
"scipy>=1.10" "mediapipe>=0.10" "ai-edge-litert>=2.1" \
|
|
41
|
+
&& pip uninstall -y bppicker && rm -rf bpp README.md
|
|
42
|
+
COPY README.md ./
|
|
43
|
+
COPY bpp/ bpp/
|
|
44
|
+
RUN pip install --no-cache-dir --no-deps . && rm -rf /app/bpp
|
|
45
|
+
|
|
46
|
+
# Fail the build, not the user, if a native library is missing: import
|
|
47
|
+
# every optional scorer package, then load mediapipe's Tasks library the
|
|
48
|
+
# way the app does (cpu_support._PROBE). mediapipe goes last: exit 132
|
|
49
|
+
# (SIGILL) means the builder has no AVX (an emulated amd64 build), which
|
|
50
|
+
# the app checks for at run time, so only warn, with everything else
|
|
51
|
+
# already checked.
|
|
52
|
+
RUN python -c "import cv2, scipy, ai_edge_litert.interpreter, pillow_heif, rawpy, onnxruntime, flask, bpp" \
|
|
53
|
+
&& python -c "from bpp.scoring.cpu_support import _PROBE; exec(_PROBE)"; \
|
|
54
|
+
rc=$?; if [ "$rc" -eq 132 ]; then echo "warning: no AVX here; mediapipe load not checked"; \
|
|
55
|
+
elif [ "$rc" -ne 0 ]; then exit "$rc"; fi
|
|
56
|
+
|
|
57
|
+
# License notices travel with the image. NOTICE.txt lists the GPL / LGPL
|
|
58
|
+
# native libraries the wheels bundle and the written offer for their
|
|
59
|
+
# source.
|
|
60
|
+
COPY LICENSE NOTICE.txt /usr/share/doc/bppicker/
|
|
61
|
+
|
|
62
|
+
# Non-root user — defence-in-depth if an RCE is found
|
|
63
|
+
RUN useradd --create-home --shell /bin/false bpp \
|
|
64
|
+
&& mkdir -p /data && chown bpp /data
|
|
65
|
+
USER bpp
|
|
66
|
+
|
|
67
|
+
# Keep downloaded models and model acceptances on the volume so they
|
|
68
|
+
# survive container re-creation (default would be the container's home).
|
|
69
|
+
# HOME too: run with `--user "$(id -u):$(id -g)"` the uid has no passwd
|
|
70
|
+
# entry, and HOME would fall back to `/`, which the export and
|
|
71
|
+
# open-folder path checks would then treat as the home folder.
|
|
72
|
+
# PYTHONNOUSERSITE: the image's packages are fixed; without it an in-app
|
|
73
|
+
# install would land in /data/.local and shadow them across upgrades.
|
|
74
|
+
ENV HOME=/data \
|
|
75
|
+
BPP_CACHE_DIR=/data/.cache/bpp \
|
|
76
|
+
XDG_CONFIG_HOME=/data/.config \
|
|
77
|
+
PYTHONNOUSERSITE=1
|
|
78
|
+
|
|
79
|
+
EXPOSE 5001
|
|
80
|
+
|
|
81
|
+
# Liveness probe. It must hit a path the auth gate lets through WITHOUT a
|
|
82
|
+
# token: every /api/* route (including /api/v1/health) requires the
|
|
83
|
+
# per-boot app session token, which only the rendered index page carries,
|
|
84
|
+
# so probing /api/v1/health would get a 403 and mark the container
|
|
85
|
+
# unhealthy forever. /static/* is public by design (see
|
|
86
|
+
# bpp/web/share.py:authorize_request), a static file contains no secrets,
|
|
87
|
+
# and the request still runs the full Flask middleware (auth gate + DB
|
|
88
|
+
# connection), so a wedged server fails the probe. The probe originates
|
|
89
|
+
# inside the container (127.0.0.1 = loopback), so the LAN gate never
|
|
90
|
+
# blocks it. Pinned by tests/test_docker_healthcheck.py.
|
|
91
|
+
# start-period covers the processor check at start-up (cpu_support: up to
|
|
92
|
+
# 120 s on a slow NAS) before the server listens.
|
|
93
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=150s --retries=3 \
|
|
94
|
+
CMD python3 -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5001/static/manifest.json', timeout=4)" || exit 1
|
|
95
|
+
|
|
96
|
+
VOLUME /data
|
|
97
|
+
|
|
98
|
+
# Trust the Docker bridge gateway range AND Docker Desktop's host
|
|
99
|
+
# alias range. Requests whose immediate peer IP is in these ranges are
|
|
100
|
+
# treated exactly like loopback: like a local browser, they still need
|
|
101
|
+
# the boot key (below) before the page hands over the owner token. That
|
|
102
|
+
# is what lets you use your own container from the host browser, because
|
|
103
|
+
# host traffic reaches the container from the bridge gateway, not from
|
|
104
|
+
# 127.0.0.1. The ranges also cover every other container on the same
|
|
105
|
+
# Docker network, which is why the boot key stays on. (X-Forwarded-For is NOT consulted here; that additionally
|
|
106
|
+
# needs `behind_proxy: true` in the config — see bpp/commands/serve.py.)
|
|
107
|
+
#
|
|
108
|
+
# CRITICAL: this is only safe if the container port is published to
|
|
109
|
+
# host loopback:
|
|
110
|
+
# docker run -p 127.0.0.1:5001:5001 -v /path/to/library:/data <image>
|
|
111
|
+
# If you publish to all interfaces (`-p 5001:5001`), other machines on
|
|
112
|
+
# your network can reach the port, and their traffic can also arrive
|
|
113
|
+
# from an address inside these trusted ranges (e.g. via Docker
|
|
114
|
+
# Desktop's port forwarder): only the boot key would stand between
|
|
115
|
+
# them and owner access. LAN Sharing (phone access with device pairing) is therefore
|
|
116
|
+
# not a supported container setup: with a loopback-only publish phones
|
|
117
|
+
# can't reach the port, and with an all-interfaces publish whether LAN
|
|
118
|
+
# clients look like the trusted gateway depends on the Docker platform.
|
|
119
|
+
# For phone access, run bpp natively and use LAN Sharing there.
|
|
120
|
+
ENV BPP_TRUSTED_PROXIES=172.16.0.0/12,192.168.65.0/24
|
|
121
|
+
|
|
122
|
+
# Bind 0.0.0.0 INSIDE the container so Docker's port mapping can reach
|
|
123
|
+
# the server (a loopback bind inside the container is unreachable from
|
|
124
|
+
# the host). Exposure to the outside world is decided by the `-p` flag
|
|
125
|
+
# above, not by this bind.
|
|
126
|
+
# No --open-loopback: the server prints a keyed link
|
|
127
|
+
# (http://127.0.0.1:5001/?_boot=...) to `docker logs`, or takes a fixed
|
|
128
|
+
# key from BPP_BOOT_SECRET. Other containers and local users who can
|
|
129
|
+
# reach the port get a locked page without it.
|
|
130
|
+
CMD ["bpp", "serve", "--library", "/data", "--host", "0.0.0.0", "--no-browser"]
|
|
@@ -23,6 +23,9 @@ Trust model summary
|
|
|
23
23
|
- **Desktop app (.app / DMG)**: built with the optional extras
|
|
24
24
|
installed, so it DOES contain those LGPL / GPL components.
|
|
25
25
|
See "Desktop app (.app / DMG)" below.
|
|
26
|
+
- **Docker image**: built with the HEIC and RAW extras and most of
|
|
27
|
+
`faces`, so it contains the same kind of LGPL / GPL components.
|
|
28
|
+
See "Docker image" below.
|
|
26
29
|
- **Downloaded at first-use**: ML model weights fetched on demand,
|
|
27
30
|
some from the original publisher and some from third-party
|
|
28
31
|
re-hosts (listed per model below), never from Arkalogy. Some
|
|
@@ -285,6 +288,37 @@ source code for any GPL- or LGPL-licensed component listed in that
|
|
|
285
288
|
release's inventory, for no more than the cost of providing it. Email
|
|
286
289
|
support@arkalogy.com with the release version and the component name.
|
|
287
290
|
|
|
291
|
+
================================================================
|
|
292
|
+
Docker image (ghcr.io/arkalogy/bppicker)
|
|
293
|
+
================================================================
|
|
294
|
+
|
|
295
|
+
The self-hosting image is built from `python:3.11-slim` (Debian) with
|
|
296
|
+
`pip install ".[web,heic,raw]"` plus mediapipe, ai-edge-litert and
|
|
297
|
+
SciPy from the `faces` extra (not face_recognition or dlib). Like the
|
|
298
|
+
desktop app, it therefore contains the optional runtime components
|
|
299
|
+
and the native libraries their Linux wheels bundle, among others:
|
|
300
|
+
|
|
301
|
+
- pillow-heif with libx265 (GPL-2.0), libheif and libde265 (LGPL-3.0)
|
|
302
|
+
- rawpy with LibRaw (LGPL-2.1)
|
|
303
|
+
- FFmpeg libraries from the OpenCV wheels (LGPL-2.1), including
|
|
304
|
+
opencv-contrib-python, which mediapipe requires; that wheel also
|
|
305
|
+
bundles Qt 5 (LGPL-3.0) with the X11 / xcb libraries it uses, and
|
|
306
|
+
its full list and license texts ship in the image as
|
|
307
|
+
`opencv_contrib_python-*.dist-info/LICENSE-3RD-PARTY.txt`
|
|
308
|
+
- the Debian packages of the base image and the ones the image adds
|
|
309
|
+
(libgl1, libglib2.0-0, libegl1, libgles2), each under its own
|
|
310
|
+
license, listed in the image under /usr/share/doc/
|
|
311
|
+
|
|
312
|
+
This file and LICENSE are in the image at /usr/share/doc/bppicker/.
|
|
313
|
+
No model weights other than the two bundled detectors above are in
|
|
314
|
+
the image; the rest download at first use.
|
|
315
|
+
|
|
316
|
+
Written offer. For at least three years after each image is
|
|
317
|
+
published, Arkalogy will provide, to anyone who asks, the complete
|
|
318
|
+
corresponding source code for any GPL- or LGPL-licensed component in
|
|
319
|
+
that image, for no more than the cost of providing it. Email
|
|
320
|
+
support@arkalogy.com with the image tag and the component name.
|
|
321
|
+
|
|
288
322
|
Build toolchain
|
|
289
323
|
---------------
|
|
290
324
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: bppicker
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Local-first photo curation tool — score, deduplicate, and select the best photos from large collections
|
|
5
5
|
Project-URL: Homepage, https://github.com/Arkalogy/best-photo-picker
|
|
6
6
|
Project-URL: Repository, https://github.com/Arkalogy/best-photo-picker
|
|
@@ -70,20 +70,22 @@ Description-Content-Type: text/markdown
|
|
|
70
70
|
[](https://github.com/Arkalogy/best-photo-picker/blob/main/LICENSE)
|
|
71
71
|
[](https://www.python.org/downloads/)
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
Best Photo Picker scores a photo library on your own computer (sharpness, exposure, faces, composition), groups faces into people, folds near-duplicates, and gives you the best photos of the people you choose. Free, MIT, no account.
|
|
74
74
|
|
|
75
75
|
It **auto-scores your whole library for curation without uploading anything**, **clusters the near-duplicates**, and lets you **boost specific people** so the final pick favors the faces that matter — your kid, for the grandparents.
|
|
76
76
|
|
|
77
77
|
<p align="center">
|
|
78
|
-
<img src="https://raw.githubusercontent.com/Arkalogy/best-photo-picker/main/docs/screenshots/demo.gif" width="
|
|
79
|
-
<br><sub>The recording and the screenshots show a sample library
|
|
78
|
+
<img src="https://raw.githubusercontent.com/Arkalogy/best-photo-picker/main/docs/screenshots/demo.gif" width="800" alt="Demo: a library of 3,848 photos; Mia is picked from Faces and BPP Picks narrows her 26 photos to her best 7; the Family group gives its best 5; the winning photo opens with its sharpness, exposure, faces and composition scores">
|
|
79
|
+
<br><sub>The recording and the screenshots show a sample library of stock photos (<a href="https://www.pexels.com/license/">Pexels</a>) and generated test images.</sub>
|
|
80
80
|
</p>
|
|
81
81
|
|
|
82
82
|
> **Try it — no photos needed** (needs Python 3.11: `brew install python@3.11` on a Mac, or use the [desktop app](#desktop-app-macos-apple-silicon)):
|
|
83
83
|
> ```bash
|
|
84
|
-
> pipx install --python
|
|
84
|
+
> pipx install --python 3.11 "bppicker[web]" && bpp demo
|
|
85
85
|
> ```
|
|
86
|
-
> Generates a sample library, runs the full UI locally, and deletes the sample library when you stop it (Ctrl+C). **The first analysis asks before downloading the on-device AI models (
|
|
86
|
+
> Generates a sample library, runs the full UI locally, and deletes the sample library when you stop it (Ctrl+C). **The first analysis asks before downloading the on-device AI models (about 660 MB for the default set, mostly CLIP for visual search; optional features fetch their own later); they're cached, so that's a one-time download.** Your photos are never uploaded. bpp still makes a few small network calls of its own (a signed model-registry check at startup, an update check, map tiles) — all listed under [Privacy](#privacy).
|
|
87
|
+
|
|
88
|
+
**[Website and Mac download →](https://arkalogy.github.io/best-photo-picker/)**
|
|
87
89
|
|
|
88
90
|
*By Arkadiy Birger at [Arkalogy](https://arkalogy.com) — a PM-directed, AI-built product; the architectural decisions are captured in [`docs/adr/`](https://github.com/Arkalogy/best-photo-picker/tree/main/docs/adr). [Why & how it was built →](#about)*
|
|
89
91
|
|
|
@@ -96,11 +98,13 @@ More screenshots (faces, calendar, map, duplicates, the editor) and an annotated
|
|
|
96
98
|
Where it fits next to what you already use:
|
|
97
99
|
|
|
98
100
|
- **Apple Photos / Google Photos** are great at storing and browsing. bpp ranks and curates — and runs alongside them.
|
|
99
|
-
- **Lightroom, Aftershoot, Excire** are built for photographers culling a shoot. bpp is built for a family library that spans years — and it's free and open source.
|
|
101
|
+
- **Lightroom, Aftershoot, Narrative Select, Excire** are built for photographers culling a shoot. bpp is built for a family library that spans years — and it's free and open source.
|
|
100
102
|
- **digiKam / Immich** organize and manage your collection. bpp answers one question: which fifty are the best of *this person*?
|
|
101
103
|
|
|
102
104
|
If you live in the Apple/Google ecosystem and your collection fits their feeds, those tools work great. **bpp exists for the case they're bad at: you have thousands of photos of a specific subject — your kid, your dog, last summer's trip — and you want to find the actual best fifty without uploading anything anywhere.**
|
|
103
105
|
|
|
106
|
+
<sub>Other product names are trademarks of their respective owners; bpp is not affiliated with or endorsed by them.</sub>
|
|
107
|
+
|
|
104
108
|
## How it's built
|
|
105
109
|
|
|
106
110
|
Claude writes the code. I own the product and the architecture, and nothing ships without my sign-off. What keeps that honest:
|
|
@@ -114,7 +118,7 @@ Claude writes the code. I own the product and the architecture, and nothing ship
|
|
|
114
118
|
|
|
115
119
|
- The pip install needs Python 3.11 exactly
|
|
116
120
|
- The Mac app is Apple Silicon only; Windows should work via pip but hasn't been tested end to end
|
|
117
|
-
- The first analysis downloads
|
|
121
|
+
- The first analysis downloads about 660 MB of models (it asks first; optional features fetch their own later); after that they're cached
|
|
118
122
|
- Face detection occasionally finds a face in a dog, a plate of food, or a flower bed. One click on **Not a face** fixes it.
|
|
119
123
|
|
|
120
124
|
## Features
|
|
@@ -124,7 +128,8 @@ Claude writes the code. I own the product and the architecture, and nothing ship
|
|
|
124
128
|
- **Temporal diversity** — per-day caps and monthly coverage for balanced selection
|
|
125
129
|
- **Face recognition** — automatic clustering, per-person smart albums, merge, dismiss, reassign, drag-to-fix mis-detected bboxes
|
|
126
130
|
- **Library management** — import by copying to managed library with SHA-256 dedup
|
|
127
|
-
- **Album system** — manual +
|
|
131
|
+
- **Album system** — manual + 19 smart album types (person, time, score, duplicates, pets, etc.)
|
|
132
|
+
- **Sensitive-photo check (opt-in)** — an optional NudeNet model, downloaded only after you accept its license, flags photos that may be sensitive (bath time, the beach) into a Sensitive album; set Settings → Scoring → Sensitive photos to Exclude to keep them out of auto-picks you plan to share
|
|
128
133
|
- **Interactive web UI** — real-time slider tuning, photo grid, lightbox, compare view, batch operations
|
|
129
134
|
- **Desktop app** — native macOS app via Tauri v2 (wraps the web UI in a native window)
|
|
130
135
|
- **Soft delete** — 30-day recovery, Recently Deleted album
|
|
@@ -145,13 +150,13 @@ Recommended — [pipx](https://pipx.pypa.io/) keeps bpp in its own
|
|
|
145
150
|
environment and makes updating one command:
|
|
146
151
|
|
|
147
152
|
```bash
|
|
148
|
-
pipx install --python
|
|
153
|
+
pipx install --python 3.11 "bppicker[web,heic,raw]"
|
|
149
154
|
|
|
150
155
|
# Update to the latest release later:
|
|
151
156
|
pipx upgrade bppicker
|
|
152
157
|
```
|
|
153
158
|
|
|
154
|
-
`--python
|
|
159
|
+
`--python 3.11` matters: pipx otherwise uses whatever Python it
|
|
155
160
|
was installed with (Homebrew's is newer), and the install ends with
|
|
156
161
|
"No matching distribution found for bppicker".
|
|
157
162
|
|
|
@@ -191,7 +196,7 @@ update, download the newer `.dmg` the same way; your photo library and
|
|
|
191
196
|
settings live outside the app and carry over untouched.
|
|
192
197
|
|
|
193
198
|
> Apple Silicon (M1/M2/M3 and later) only. On an Intel Mac, or on
|
|
194
|
-
> Windows/Linux, use the `pipx install --python
|
|
199
|
+
> Windows/Linux, use the `pipx install --python 3.11 "bppicker[web,heic,raw]"` path above.
|
|
195
200
|
|
|
196
201
|
### Try the Demo
|
|
197
202
|
|
|
@@ -204,7 +209,8 @@ Generates sample photos and launches the web UI — no configuration needed.
|
|
|
204
209
|
### Library Mode (Recommended)
|
|
205
210
|
|
|
206
211
|
```bash
|
|
207
|
-
# Start the photo management server (default library
|
|
212
|
+
# Start the photo management server (default: the library you used last, or
|
|
213
|
+
# BestPhotoPicker inside the Pictures folder of your home directory, on every OS)
|
|
208
214
|
bpp serve
|
|
209
215
|
|
|
210
216
|
# Or specify a custom library path
|
|
@@ -297,7 +303,7 @@ crashing. Ordering matters — providers are tried in the order listed.
|
|
|
297
303
|
|---|---|---|---|
|
|
298
304
|
| **macOS arm64** (M1/M2/M3) — CPU | no (tested locally on the dev Mac) | yes | Primary dev target. Tauri desktop app ships only this. |
|
|
299
305
|
| **Linux x86_64** — CPU | yes (`ubuntu-latest`) | yes | Default for PyPI install. |
|
|
300
|
-
| **Linux arm64** — CPU |
|
|
306
|
+
| **Linux arm64** — CPU | image build at each release | yes | The Docker image is built for arm64 when a release is published; the arm64 test suite runs on demand only. |
|
|
301
307
|
| **Windows** — CPU | no | yes | Code path exists; never run end-to-end. Reports welcome via GitHub issues. |
|
|
302
308
|
| **macOS arm64** — CoreMLExecutionProvider (ANE) | no | yes | Code path exists. Expected 5-10× face inference speedup; correctness depends on the specific ONNX graph and ONNX Runtime version. |
|
|
303
309
|
| **Linux x86_64** — CUDAExecutionProvider | no | yes | Requires `pip install onnxruntime-gpu` (replaces base `onnxruntime`). Free-tier CI doesn't have a GPU runner. |
|
|
@@ -426,22 +432,90 @@ A double-clickable launcher template ships at
|
|
|
426
432
|
window with the documented default library path. Override via
|
|
427
433
|
`BPP_LIBRARY` env var.
|
|
428
434
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
image is published
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
435
|
+
### Docker
|
|
436
|
+
|
|
437
|
+
A self-hosting image is published to the GitHub Container Registry
|
|
438
|
+
for `linux/amd64` and `linux/arm64`:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
docker pull ghcr.io/arkalogy/bppicker
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
It has the web, HEIC and camera RAW support and every scorer except
|
|
445
|
+
the legacy dlib face backend. Apart from two small detectors that ship
|
|
446
|
+
inside the packages, models download on first use into the `/data`
|
|
447
|
+
volume, along with your model-license acceptances, so both survive
|
|
448
|
+
re-creating the container. Create the host folders you mount before
|
|
449
|
+
the first run: `--user` runs the container as you, so the files it
|
|
450
|
+
writes are yours, and Docker would otherwise create missing folders
|
|
451
|
+
owned by root, which the container then can't write to. There are two
|
|
452
|
+
ways to use it.
|
|
453
|
+
|
|
454
|
+
Built and run on Linux x86-64 and arm64 machines; it has not yet been
|
|
455
|
+
tried on a Synology, QNAP or Unraid box, so reports from one are welcome
|
|
456
|
+
in GitHub issues.
|
|
457
|
+
|
|
458
|
+
**Headless, on a NAS or server.** Point it at a photo folder and the
|
|
459
|
+
best photos are copied into another folder; your originals are
|
|
460
|
+
mounted read-only. Accept the free-license face models once (this
|
|
461
|
+
shows the terms and asks you to confirm), then run picks as often as
|
|
462
|
+
you like:
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
docker run --rm -it --no-healthcheck --user "$(id -u):$(id -g)" \
|
|
466
|
+
-v /path/to/bpp-data:/data ghcr.io/arkalogy/bppicker \
|
|
467
|
+
bpp model accept-attribution
|
|
468
|
+
docker run --rm --no-healthcheck --user "$(id -u):$(id -g)" \
|
|
469
|
+
-v /path/to/bpp-data:/data \
|
|
470
|
+
-v /path/to/photos:/photos:ro -v /path/to/best:/best \
|
|
471
|
+
ghcr.io/arkalogy/bppicker \
|
|
472
|
+
bpp run --input /photos --k 50 --out /best --copy
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
Use `--copy` rather than `--symlink` here: a link made inside the
|
|
476
|
+
container points at `/photos/...`, which doesn't exist on the host.
|
|
477
|
+
`--no-healthcheck` because the image's health check watches the
|
|
478
|
+
app's web server, which a headless run doesn't start.
|
|
479
|
+
|
|
480
|
+
**The full app.** `bpp serve` is the image's default command. Publish
|
|
481
|
+
the port to the host's loopback only, and mount your photos so you
|
|
482
|
+
can import them from `/photos`:
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
docker run -d --name bpp --user "$(id -u):$(id -g)" -p 127.0.0.1:5001:5001 \
|
|
486
|
+
-v /path/to/library:/data -v /path/to/photos:/photos:ro \
|
|
487
|
+
ghcr.io/arkalogy/bppicker
|
|
488
|
+
docker logs bpp 2>&1 | grep 'Open Best Photo Picker at' | tail -1
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
The second command shows the link to open, which carries a key the
|
|
492
|
+
server makes at each start (`http://127.0.0.1:5001/?_boot=...`); after
|
|
493
|
+
a restart, run it again for the new one. If you publish a different
|
|
494
|
+
host port (`-p 127.0.0.1:8080:5001`), change the port in the link to
|
|
495
|
+
match.
|
|
496
|
+
Without the key the app shows a locked page, so other containers and
|
|
497
|
+
other users on the server can't get in. On the same machine, open the
|
|
498
|
+
link. From another computer, start an SSH tunnel first (`ssh -L
|
|
499
|
+
5001:127.0.0.1:5001 you@your-server`), then open the same link there.
|
|
500
|
+
A reload keeps working; a new tab or browser session needs the link
|
|
501
|
+
again. In the app, type `/photos` into the import box (the folder
|
|
502
|
+
picker only works on a Mac), and export into a folder under `/data`,
|
|
503
|
+
which is your library folder on the host. Reaching the app directly
|
|
504
|
+
from another computer on your network, with a login, is planned for a
|
|
505
|
+
later release.
|
|
506
|
+
|
|
507
|
+
Why loopback only: the image sets `BPP_TRUSTED_PROXIES` to the Docker
|
|
508
|
+
bridge ranges, so requests through that mapping count as local, and
|
|
509
|
+
only the key stands between them and owner access. Publishing to all
|
|
510
|
+
interfaces (`-p 5001:5001`) lets other machines on your network reach
|
|
511
|
+
that locked page too. Don't put the container behind a reverse proxy
|
|
512
|
+
for the same reason. LAN sharing (phone pairing) is not supported from
|
|
513
|
+
a container, and neither is installing extra features from inside the
|
|
514
|
+
app (such as object removal): the image's packages are fixed.
|
|
515
|
+
|
|
516
|
+
To build the image yourself: `docker build -t bppicker .`
|
|
517
|
+
|
|
518
|
+
Running natively behind a reverse proxy, `X-Forwarded-For` is honored only if you also
|
|
445
519
|
set `behind_proxy: true` in the config, and the proxy's host name must
|
|
446
520
|
be listed in `BPP_TRUSTED_HOSTS` (the server answers only to its own
|
|
447
521
|
addresses); see
|