voidaccess 1.3.0__tar.gz → 1.4.2__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.
- {voidaccess-1.3.0 → voidaccess-1.4.2}/PKG-INFO +2 -3
- {voidaccess-1.3.0 → voidaccess-1.4.2}/pyproject.toml +4 -5
- {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/PKG-INFO +2 -3
- {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/SOURCES.txt +15 -15
- voidaccess-1.4.2/voidaccess.egg-info/entry_points.txt +2 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/top_level.txt +1 -1
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/__init__.py +1 -1
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/configure.py +1 -1
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/enrich.py +3 -3
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/export.py +11 -7
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/investigate.py +26 -6
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/show.py +26 -4
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/config.py +6 -0
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/main.py +46 -9
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/tor_detect.py +1 -1
- voidaccess-1.3.0/voidaccess.egg-info/entry_points.txt +0 -2
- {voidaccess-1.3.0 → voidaccess-1.4.2}/LICENSE +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/README.md +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/analysis/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/analysis/opsec.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/analysis/patterns.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/analysis/temporal.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/auth.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/main.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/admin.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/auth.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/entities.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/export.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/investigations.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/monitors.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/search.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/settings.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/auth/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/auth/token_blacklist.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/config.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/dedup.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/frontier.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/spider.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/utils.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/env.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0001_initial_schema.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0002_add_investigation_status_column.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0002_add_missing_tables.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0003_add_canonical_value_and_entity_links.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0004_add_page_posted_at.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0005_add_extraction_method.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0006_add_monitor_alerts.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0007_add_actor_style_profiles.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0008_add_users_table.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0009_add_investigation_id_to_relationships.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0010_add_composite_index_entity_relationships.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0011_add_page_extraction_cache.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0013_add_graph_status.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0015_add_progress_fields.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0016_backfill_graph_status.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0017_add_user_api_keys.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0018_add_user_id_to_investigations.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0019_add_content_safety_log.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0020_add_entity_source_tracking.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/models.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/queries.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/db/session.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/export/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/export/misp.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/export/sigma.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/export/stix.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/llm_extract.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/ner.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/normalizer.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/pipeline.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/regex_patterns.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/fingerprint/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/fingerprint/profiler.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/fingerprint/stylometry.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/builder.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/export.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/model.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/queries.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/visualize.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/i18n/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/i18n/detect.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/i18n/query_expand.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/i18n/translate.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/_db.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/alerts.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/config.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/diff.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/jobs.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/scheduler.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/scraper/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/scraper/scrape.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/scraper/scrape_js.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/search/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/search/circuit_breaker.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/search/search.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/setup.cfg +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/blockchain.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/cache.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/cisa.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/dns_enrichment.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/domain_reputation.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/email_reputation.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/engines.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/enrichment.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/github_scraper.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/gitlab_scraper.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/hash_reputation.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/historical_intel.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/ip_reputation.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/paste_scraper.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/pastes.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/rss_scraper.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/seed_manager.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/seeds.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/shodan.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/telegram.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/virustotal.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_analysis_opsec.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_analysis_stylometry.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_analysis_temporal.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_api.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_api_monitors.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_blockchain.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_config.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_crawler.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_db.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_dns_enrichment.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_domain_reputation.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_email_reputation.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_fingerprint.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_github_scraper.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_gitlab_scraper.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_graph.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_hash_reputation.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_i18n.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_ip_reputation.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_llm.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_llm_utils.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_model_singleton.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_monitor.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_pagination.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_paste_scraper.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_rss_scraper.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_scrape_js.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_settings.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_sources.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_sources_enrichment_new.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_vector.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/async_utils.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/content_safety.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/defang.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/encryption.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/ioc_freshness.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/user_keys.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/embedder.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/model_singleton.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/search.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/store.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess/__init__.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess/llm.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess/llm_utils.py +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/dependency_links.txt +0 -0
- {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/requires.txt +0 -0
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/adapters/__init__.py +0 -0
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/adapters/sqlite.py +0 -0
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/browser.py +0 -0
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/__init__.py +0 -0
- {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/display.py +0 -0
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voidaccess
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.2
|
|
4
4
|
Summary: Dark web OSINT CLI — automated threat intelligence from query to report
|
|
5
5
|
Author: VoidAccess
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Keywords: osint,darkweb,threat-intelligence,tor,cli
|
|
8
8
|
Classifier: Development Status :: 4 - Beta
|
|
9
9
|
Classifier: Environment :: Console
|
|
10
10
|
Classifier: Intended Audience :: Information Technology
|
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
12
11
|
Classifier: Operating System :: OS Independent
|
|
13
12
|
Classifier: Programming Language :: Python :: 3
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "voidaccess"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.4.2"
|
|
8
8
|
description = "Dark web OSINT CLI — automated threat intelligence from query to report"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
license =
|
|
10
|
+
license = "MIT"
|
|
11
11
|
requires-python = ">=3.10"
|
|
12
12
|
authors = [{ name = "VoidAccess" }]
|
|
13
13
|
keywords = ["osint", "darkweb", "threat-intelligence", "tor", "cli"]
|
|
@@ -15,7 +15,6 @@ classifiers = [
|
|
|
15
15
|
"Development Status :: 4 - Beta",
|
|
16
16
|
"Environment :: Console",
|
|
17
17
|
"Intended Audience :: Information Technology",
|
|
18
|
-
"License :: OSI Approved :: MIT License",
|
|
19
18
|
"Operating System :: OS Independent",
|
|
20
19
|
"Programming Language :: Python :: 3",
|
|
21
20
|
"Programming Language :: Python :: 3.11",
|
|
@@ -51,7 +50,7 @@ dependencies = [
|
|
|
51
50
|
dev = ["pytest", "pytest-asyncio"]
|
|
52
51
|
|
|
53
52
|
[project.scripts]
|
|
54
|
-
voidaccess = "
|
|
53
|
+
voidaccess = "voidaccess_cli.main:app"
|
|
55
54
|
|
|
56
55
|
[tool.setuptools]
|
|
57
56
|
py-modules = ["config"]
|
|
@@ -59,7 +58,7 @@ py-modules = ["config"]
|
|
|
59
58
|
[tool.setuptools.packages.find]
|
|
60
59
|
where = ["."]
|
|
61
60
|
include = [
|
|
62
|
-
"
|
|
61
|
+
"voidaccess_cli*",
|
|
63
62
|
"db*",
|
|
64
63
|
"sources*",
|
|
65
64
|
"extractor*",
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voidaccess
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.2
|
|
4
4
|
Summary: Dark web OSINT CLI — automated threat intelligence from query to report
|
|
5
5
|
Author: VoidAccess
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Keywords: osint,darkweb,threat-intelligence,tor,cli
|
|
8
8
|
Classifier: Development Status :: 4 - Beta
|
|
9
9
|
Classifier: Environment :: Console
|
|
10
10
|
Classifier: Intended Audience :: Information Technology
|
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
12
11
|
Classifier: Operating System :: OS Independent
|
|
13
12
|
Classifier: Programming Language :: Python :: 3
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -20,20 +20,6 @@ api/routes/search.py
|
|
|
20
20
|
api/routes/settings.py
|
|
21
21
|
auth/__init__.py
|
|
22
22
|
auth/token_blacklist.py
|
|
23
|
-
cli/__init__.py
|
|
24
|
-
cli/browser.py
|
|
25
|
-
cli/config.py
|
|
26
|
-
cli/display.py
|
|
27
|
-
cli/main.py
|
|
28
|
-
cli/tor_detect.py
|
|
29
|
-
cli/adapters/__init__.py
|
|
30
|
-
cli/adapters/sqlite.py
|
|
31
|
-
cli/commands/__init__.py
|
|
32
|
-
cli/commands/configure.py
|
|
33
|
-
cli/commands/enrich.py
|
|
34
|
-
cli/commands/export.py
|
|
35
|
-
cli/commands/investigate.py
|
|
36
|
-
cli/commands/show.py
|
|
37
23
|
crawler/__init__.py
|
|
38
24
|
crawler/dedup.py
|
|
39
25
|
crawler/frontier.py
|
|
@@ -173,4 +159,18 @@ voidaccess.egg-info/SOURCES.txt
|
|
|
173
159
|
voidaccess.egg-info/dependency_links.txt
|
|
174
160
|
voidaccess.egg-info/entry_points.txt
|
|
175
161
|
voidaccess.egg-info/requires.txt
|
|
176
|
-
voidaccess.egg-info/top_level.txt
|
|
162
|
+
voidaccess.egg-info/top_level.txt
|
|
163
|
+
voidaccess_cli/__init__.py
|
|
164
|
+
voidaccess_cli/browser.py
|
|
165
|
+
voidaccess_cli/config.py
|
|
166
|
+
voidaccess_cli/display.py
|
|
167
|
+
voidaccess_cli/main.py
|
|
168
|
+
voidaccess_cli/tor_detect.py
|
|
169
|
+
voidaccess_cli/adapters/__init__.py
|
|
170
|
+
voidaccess_cli/adapters/sqlite.py
|
|
171
|
+
voidaccess_cli/commands/__init__.py
|
|
172
|
+
voidaccess_cli/commands/configure.py
|
|
173
|
+
voidaccess_cli/commands/enrich.py
|
|
174
|
+
voidaccess_cli/commands/export.py
|
|
175
|
+
voidaccess_cli/commands/investigate.py
|
|
176
|
+
voidaccess_cli/commands/show.py
|
|
@@ -15,7 +15,7 @@ from rich.console import Console
|
|
|
15
15
|
from rich.prompt import Prompt, Confirm
|
|
16
16
|
from rich.table import Table
|
|
17
17
|
|
|
18
|
-
from
|
|
18
|
+
from voidaccess_cli import config as cli_config
|
|
19
19
|
|
|
20
20
|
app = typer.Typer(help="Configure the voidaccess CLI.", no_args_is_help=False, invoke_without_command=True)
|
|
21
21
|
console = Console()
|
|
@@ -30,7 +30,7 @@ def run(
|
|
|
30
30
|
skip_emails: bool = typer.Option(False, "--skip-emails"),
|
|
31
31
|
) -> None:
|
|
32
32
|
"""Re-enrich entities for an existing investigation."""
|
|
33
|
-
from
|
|
33
|
+
from voidaccess_cli import config as cli_config
|
|
34
34
|
cli_config.apply_env()
|
|
35
35
|
|
|
36
36
|
inv_id = _resolve_investigation_id(target)
|
|
@@ -50,7 +50,7 @@ def _resolve_investigation_id(target: str) -> Optional[str]:
|
|
|
50
50
|
except Exception:
|
|
51
51
|
return None
|
|
52
52
|
return data.get("investigation", {}).get("id") or data.get("id")
|
|
53
|
-
from
|
|
53
|
+
from voidaccess_cli.adapters import sqlite as sqlite_adapter
|
|
54
54
|
sqlite_adapter.init_db()
|
|
55
55
|
resolved = sqlite_adapter.resolve_investigation_id(target) or target
|
|
56
56
|
row = sqlite_adapter.get_investigation(resolved)
|
|
@@ -89,7 +89,7 @@ _TYPE_MAP = {
|
|
|
89
89
|
|
|
90
90
|
def _load_extraction_results(investigation_id: str) -> list:
|
|
91
91
|
"""Reconstruct ExtractionResult-shaped objects from the DB."""
|
|
92
|
-
from
|
|
92
|
+
from voidaccess_cli.adapters import sqlite as sqlite_adapter
|
|
93
93
|
rows = sqlite_adapter.get_entities(investigation_id)
|
|
94
94
|
fakes = []
|
|
95
95
|
for r in rows:
|
|
@@ -25,7 +25,7 @@ def run(
|
|
|
25
25
|
output: Optional[Path] = typer.Option(None, "--output", help="Output file"),
|
|
26
26
|
) -> None:
|
|
27
27
|
"""Export an investigation."""
|
|
28
|
-
from
|
|
28
|
+
from voidaccess_cli import config as cli_config
|
|
29
29
|
cli_config.apply_env()
|
|
30
30
|
|
|
31
31
|
fmt = fmt.lower()
|
|
@@ -39,7 +39,7 @@ def run(
|
|
|
39
39
|
raise typer.Exit(code=1)
|
|
40
40
|
|
|
41
41
|
payload, suffix = _render(fmt, inv_id, data)
|
|
42
|
-
out_path = output or _default_out_path(target, suffix)
|
|
42
|
+
out_path = output or _default_out_path(target, suffix, fmt=fmt)
|
|
43
43
|
out_path = Path(out_path).expanduser()
|
|
44
44
|
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
45
45
|
if isinstance(payload, bytes):
|
|
@@ -58,7 +58,7 @@ def _load_target(target: str) -> tuple[Optional[str], Optional[dict]]:
|
|
|
58
58
|
return None, None
|
|
59
59
|
inv_id = data.get("investigation", {}).get("id") or data.get("id")
|
|
60
60
|
return inv_id, data
|
|
61
|
-
from
|
|
61
|
+
from voidaccess_cli.adapters import sqlite as sqlite_adapter
|
|
62
62
|
sqlite_adapter.init_db()
|
|
63
63
|
resolved = sqlite_adapter.resolve_investigation_id(target) or target
|
|
64
64
|
data = sqlite_adapter.investigation_to_export_dict(resolved)
|
|
@@ -75,7 +75,7 @@ def _render(fmt: str, inv_id: Optional[str], data: dict) -> tuple[str | bytes, s
|
|
|
75
75
|
return _csv_from_data(data), ".csv"
|
|
76
76
|
|
|
77
77
|
if fmt == "md":
|
|
78
|
-
from
|
|
78
|
+
from voidaccess_cli.commands.investigate import _render_markdown # reuse renderer
|
|
79
79
|
# Adapt shape: _render_markdown expects flat payload
|
|
80
80
|
flat = _flatten_for_md(data)
|
|
81
81
|
return _render_markdown(flat), ".md"
|
|
@@ -150,9 +150,13 @@ def _flatten_for_md(data: dict) -> dict:
|
|
|
150
150
|
return data
|
|
151
151
|
|
|
152
152
|
|
|
153
|
-
def _default_out_path(target: str, suffix: str) -> Path:
|
|
153
|
+
def _default_out_path(target: str, suffix: str, fmt: str = "") -> Path:
|
|
154
154
|
p = Path(target).expanduser()
|
|
155
155
|
if p.exists():
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
candidate = p.with_suffix(suffix)
|
|
157
|
+
# Avoid overwriting input when suffix is the same (e.g. stix/misp .json)
|
|
158
|
+
if candidate == p and fmt and fmt not in ("json",):
|
|
159
|
+
return p.parent / f"{p.stem}-{fmt}{suffix}"
|
|
160
|
+
return candidate
|
|
161
|
+
from voidaccess_cli import config as cli_config
|
|
158
162
|
return cli_config.get_output_dir() / f"{target}{suffix}"
|
|
@@ -46,12 +46,31 @@ def run(
|
|
|
46
46
|
quiet: bool = typer.Option(False, "--quiet", help="No live display; print final summary only"),
|
|
47
47
|
) -> None:
|
|
48
48
|
"""Run an investigation: query → search → scrape → extract → enrich → report."""
|
|
49
|
-
from
|
|
49
|
+
from voidaccess_cli import config as cli_config
|
|
50
50
|
|
|
51
51
|
cli_config.apply_env()
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
import spacy
|
|
55
|
+
spacy.load("en_core_web_sm")
|
|
56
|
+
except Exception:
|
|
57
|
+
import subprocess, sys
|
|
58
|
+
from rich.console import Console
|
|
59
|
+
Console().print(" [dim]→[/dim] Installing spaCy NER model (one-time)...")
|
|
60
|
+
subprocess.run(
|
|
61
|
+
[sys.executable, "-m", "spacy", "download", "en_core_web_sm"],
|
|
62
|
+
capture_output=True,
|
|
63
|
+
)
|
|
64
|
+
|
|
52
65
|
if quiet:
|
|
53
66
|
logging.getLogger().setLevel(logging.ERROR)
|
|
54
67
|
|
|
68
|
+
from utils.content_safety import is_blocked_query
|
|
69
|
+
blocked, reason = is_blocked_query(query)
|
|
70
|
+
if blocked:
|
|
71
|
+
console.print(f"[red]Query blocked:[/red] {reason}")
|
|
72
|
+
raise typer.Exit(code=1)
|
|
73
|
+
|
|
55
74
|
if not cli_config.is_configured() and not no_llm:
|
|
56
75
|
console.print("[yellow]No LLM configured.[/yellow] Run [bold]voidaccess configure[/bold] first, or pass --no-llm.")
|
|
57
76
|
raise typer.Exit(code=2)
|
|
@@ -106,10 +125,10 @@ async def _run_investigation(
|
|
|
106
125
|
fmt: str,
|
|
107
126
|
quiet: bool,
|
|
108
127
|
) -> None:
|
|
109
|
-
from
|
|
110
|
-
from
|
|
111
|
-
from
|
|
112
|
-
from
|
|
128
|
+
from voidaccess_cli import config as cli_config
|
|
129
|
+
from voidaccess_cli.adapters import sqlite as sqlite_adapter
|
|
130
|
+
from voidaccess_cli.display import InvestigationDisplay
|
|
131
|
+
from voidaccess_cli.tor_detect import detect_tor, tor_unavailable_message
|
|
113
132
|
|
|
114
133
|
cfg = cli_config.load_config()
|
|
115
134
|
preset = DEPTH_PRESETS[depth]
|
|
@@ -382,6 +401,7 @@ async def _run_investigation(
|
|
|
382
401
|
"query": query,
|
|
383
402
|
"refined_query": refined,
|
|
384
403
|
"model_used": chosen_model if llm is not None else None,
|
|
404
|
+
"status": "completed" if final_entities or scraped_pages else "completed_no_results",
|
|
385
405
|
"created_at": datetime.now(timezone.utc).isoformat(),
|
|
386
406
|
"summary": summary_text,
|
|
387
407
|
"sources_used": sources_used,
|
|
@@ -500,7 +520,7 @@ def _build_cooccurrence_edges(investigation_id: str) -> int:
|
|
|
500
520
|
from db.session import get_session
|
|
501
521
|
except Exception:
|
|
502
522
|
return 0
|
|
503
|
-
from
|
|
523
|
+
from voidaccess_cli.adapters.sqlite import save_relationships
|
|
504
524
|
|
|
505
525
|
edges: list[dict] = []
|
|
506
526
|
inv_uuid = uuid.UUID(investigation_id)
|
|
@@ -24,14 +24,18 @@ def run(
|
|
|
24
24
|
target: Optional[str] = typer.Argument(
|
|
25
25
|
None, help="Investigation id or path to a .json export"
|
|
26
26
|
),
|
|
27
|
+
no_tui: bool = typer.Option(False, "--no-tui", help="Print summary table without launching TUI (for scripted use)."),
|
|
27
28
|
) -> None:
|
|
28
29
|
"""Open the entity browser TUI."""
|
|
29
|
-
from
|
|
30
|
+
from voidaccess_cli import config as cli_config
|
|
30
31
|
cli_config.apply_env()
|
|
31
32
|
|
|
32
33
|
data: Optional[dict] = None
|
|
33
34
|
|
|
34
35
|
if target is None:
|
|
36
|
+
if no_tui:
|
|
37
|
+
console.print("[yellow]No target specified.[/yellow]")
|
|
38
|
+
raise typer.Exit(code=1)
|
|
35
39
|
target = _pick_recent()
|
|
36
40
|
if target is None:
|
|
37
41
|
console.print("[yellow]No investigations found. Run `voidaccess investigate` first.[/yellow]")
|
|
@@ -41,7 +45,7 @@ def run(
|
|
|
41
45
|
if candidate_path.exists() and candidate_path.suffix == ".json":
|
|
42
46
|
data = json.loads(candidate_path.read_text(encoding="utf-8"))
|
|
43
47
|
else:
|
|
44
|
-
from
|
|
48
|
+
from voidaccess_cli.adapters import sqlite as sqlite_adapter
|
|
45
49
|
sqlite_adapter.init_db()
|
|
46
50
|
resolved = sqlite_adapter.resolve_investigation_id(target) or target
|
|
47
51
|
data = sqlite_adapter.investigation_to_export_dict(resolved)
|
|
@@ -49,13 +53,31 @@ def run(
|
|
|
49
53
|
console.print(f"[red]Unknown investigation:[/red] {target}")
|
|
50
54
|
raise typer.Exit(code=1)
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
if no_tui:
|
|
57
|
+
_print_summary(data)
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
from voidaccess_cli.browser import EntityBrowserApp
|
|
53
61
|
app = EntityBrowserApp(data=data)
|
|
54
62
|
app.run()
|
|
55
63
|
|
|
56
64
|
|
|
65
|
+
def _print_summary(data: dict) -> None:
|
|
66
|
+
inv = data.get("investigation") or data
|
|
67
|
+
entities = data.get("entities", [])
|
|
68
|
+
table = Table(title="Investigation summary")
|
|
69
|
+
table.add_column("Field", style="bold")
|
|
70
|
+
table.add_column("Value")
|
|
71
|
+
table.add_row("Query", str(inv.get("query") or ""))
|
|
72
|
+
table.add_row("Status", str(inv.get("status") or ""))
|
|
73
|
+
table.add_row("Entities", str(len(entities)))
|
|
74
|
+
table.add_row("Created", str(inv.get("created_at") or "")[:19])
|
|
75
|
+
table.add_row("Summary", (str(inv.get("summary") or "—"))[:120])
|
|
76
|
+
console.print(table)
|
|
77
|
+
|
|
78
|
+
|
|
57
79
|
def _pick_recent() -> Optional[str]:
|
|
58
|
-
from
|
|
80
|
+
from voidaccess_cli.adapters import sqlite as sqlite_adapter
|
|
59
81
|
sqlite_adapter.init_db()
|
|
60
82
|
rows = sqlite_adapter.list_investigations(limit=20)
|
|
61
83
|
if not rows:
|
|
@@ -178,3 +178,9 @@ def apply_env(config: Optional[dict[str, Any]] = None) -> None:
|
|
|
178
178
|
# Enrichment keys
|
|
179
179
|
for k, v in (cfg.get("enrichment_keys") or {}).items():
|
|
180
180
|
_set_env_if_present(k, v, clear_if_empty=True)
|
|
181
|
+
|
|
182
|
+
# Keyless APIs (ThreatFox/URLhaus/MalwareBazaar/abuse.ch) must never
|
|
183
|
+
# receive an empty auth header — clear any empty env remnant.
|
|
184
|
+
for key in ("ABUSECH_API_KEY", "VT_API_KEY", "OTX_API_KEY"):
|
|
185
|
+
if not os.environ.get(key):
|
|
186
|
+
os.environ.pop(key, None)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
cli/main.py — typer entry point exposed as the `voidaccess` script.
|
|
3
3
|
|
|
4
4
|
Defined as the [project.scripts] target in pyproject.toml:
|
|
5
|
-
voidaccess = "
|
|
5
|
+
voidaccess = "voidaccess_cli.main:app"
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
@@ -14,6 +14,7 @@ import sys
|
|
|
14
14
|
# Force UTF-8 on Windows consoles so rich glyphs render reliably
|
|
15
15
|
if sys.platform == "win32":
|
|
16
16
|
os.environ.setdefault("PYTHONIOENCODING", "utf-8")
|
|
17
|
+
os.environ.setdefault("PYTHONUTF8", "1")
|
|
17
18
|
try:
|
|
18
19
|
sys.stdout.reconfigure(encoding="utf-8") # type: ignore[attr-defined]
|
|
19
20
|
sys.stderr.reconfigure(encoding="utf-8") # type: ignore[attr-defined]
|
|
@@ -21,14 +22,28 @@ if sys.platform == "win32":
|
|
|
21
22
|
pass
|
|
22
23
|
|
|
23
24
|
import typer
|
|
25
|
+
from rich.align import Align
|
|
24
26
|
from rich.console import Console
|
|
25
27
|
from rich.table import Table
|
|
26
28
|
|
|
27
|
-
from
|
|
28
|
-
from
|
|
29
|
-
from
|
|
29
|
+
from voidaccess_cli import __version__
|
|
30
|
+
from voidaccess_cli import config as cli_config
|
|
31
|
+
from voidaccess_cli.commands import configure, enrich, export, investigate, show
|
|
30
32
|
|
|
31
33
|
console = Console()
|
|
34
|
+
BANNER = """\
|
|
35
|
+
[color(183)] ░░░░░[color(141)]█[color(183)]░░░░░[/]
|
|
36
|
+
[color(183)] ░░[color(141)]█████████████[color(183)]░░[/]
|
|
37
|
+
[color(183)] ░[color(141)]█████████████████[color(183)]░[/]
|
|
38
|
+
[color(183)]░[color(141)]███████████████████[color(183)]░[/]
|
|
39
|
+
[color(183)]░[color(141)]███████████████████[color(183)]░[/]
|
|
40
|
+
[color(141)]██████[/] [bright_white]void[/] [color(141)]███████[/]
|
|
41
|
+
[color(183)]░[color(141)]███████████████████[color(183)]░[/]
|
|
42
|
+
[color(183)]░[color(141)]███████████████████[color(183)]░[/]
|
|
43
|
+
[color(183)] ░[color(141)]█████████████████[color(183)]░[/]
|
|
44
|
+
[color(183)] ░░[color(141)]█████████████[color(183)]░░[/]
|
|
45
|
+
[color(183)] ░░░░░[color(141)]█[color(183)]░░░░░[/]
|
|
46
|
+
[dim white] dark web osint intelligence[/dim white]"""
|
|
32
47
|
|
|
33
48
|
app = typer.Typer(
|
|
34
49
|
name="voidaccess",
|
|
@@ -63,7 +78,7 @@ def _ensure_first_run() -> None:
|
|
|
63
78
|
@app.command("status")
|
|
64
79
|
def status() -> None:
|
|
65
80
|
"""Show current config, Tor status, and detected API keys."""
|
|
66
|
-
from
|
|
81
|
+
from voidaccess_cli.tor_detect import detect_tor
|
|
67
82
|
cli_config.apply_env()
|
|
68
83
|
cfg = cli_config.load_config()
|
|
69
84
|
|
|
@@ -112,7 +127,7 @@ def list_investigations(
|
|
|
112
127
|
) -> None:
|
|
113
128
|
"""List saved investigations."""
|
|
114
129
|
cli_config.apply_env()
|
|
115
|
-
from
|
|
130
|
+
from voidaccess_cli.adapters import sqlite as sqlite_adapter
|
|
116
131
|
sqlite_adapter.init_db()
|
|
117
132
|
rows = sqlite_adapter.list_investigations(limit=limit)
|
|
118
133
|
if as_json:
|
|
@@ -144,10 +159,32 @@ def version() -> None:
|
|
|
144
159
|
console.print(f"voidaccess {__version__}")
|
|
145
160
|
|
|
146
161
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
""
|
|
162
|
+
def show_banner(console: Console) -> None:
|
|
163
|
+
import shutil
|
|
164
|
+
if os.environ.get("TERM") == "dumb":
|
|
165
|
+
return
|
|
166
|
+
if not sys.stdout.isatty() and "PS1" not in os.environ and os.name != "nt":
|
|
167
|
+
return
|
|
168
|
+
console.print()
|
|
169
|
+
raw_line = " oooooXooooo " # widest line, 21 chars
|
|
170
|
+
pad = max(0, (console.width - len(raw_line)) // 2)
|
|
171
|
+
for line in BANNER.split("\n"):
|
|
172
|
+
console.print(" " * pad + line)
|
|
173
|
+
console.print()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@app.callback(invoke_without_command=True)
|
|
177
|
+
def main(
|
|
178
|
+
ctx: typer.Context,
|
|
179
|
+
no_banner: bool = typer.Option(
|
|
180
|
+
False, "--no-banner",
|
|
181
|
+
help="Skip banner"
|
|
182
|
+
),
|
|
183
|
+
) -> None:
|
|
184
|
+
"""Set env vars and render banner before command execution."""
|
|
150
185
|
cli_config.apply_env()
|
|
186
|
+
if not no_banner and ctx.invoked_subcommand:
|
|
187
|
+
show_banner(console)
|
|
151
188
|
|
|
152
189
|
|
|
153
190
|
if __name__ == "__main__":
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0002_add_investigation_status_column.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0007_add_actor_style_profiles.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0011_add_page_extraction_cache.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0018_add_user_id_to_investigations.py
RENAMED
|
File without changes
|
|
File without changes
|
{voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0020_add_entity_source_tracking.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|