diff --git a/KNOWLEDGE_BASE.md b/KNOWLEDGE_BASE.md new file mode 100644 index 0000000..efe55cc --- /dev/null +++ b/KNOWLEDGE_BASE.md @@ -0,0 +1,3919 @@ +# Polyglot Codebase Knowledge Graph + +> Generated offline by **readmenator**. Supports C, C++, Python, Go, Rust, JS/TS, Java, C#, Shell, PHP, Dart, GDScript, Nim, ASM, Ruby, Swift, Kotlin, Scala, Lua, Elixir. +> No LLMs. No tokens. Pure static analysis. See more [here](https://github.com/grisuno/ReadMenator) + +**Total Files Parsed:** 72 | **Total Symbols Extracted:** 434 | **Total Imports:** 364 + | **Resolved Imports:** 81 + + + + +## Table of Contents + +1. [Statistics Dashboard](#statistics-dashboard) +2. [Architectural Layers](#architectural-layers) +3. [Ranked Context](#ranked-context) +4. [God Nodes](#god-nodes) +5. [Community Analysis](#community-analysis) +6. [Surprising Connections](#surprising-connections) +7. [Suggested Questions](#suggested-questions) +8. [Hotspot Analysis](#hotspot-analysis) +9. [Dependency Cycles](#dependency-cycles) +10. [Change Impact Analysis](#change-impact-analysis) +11. [Architecture Violations](#architecture-violations) +12. [Suggested Linting Rules](#suggested-linting-rules) +13. [Orphans](#orphans) +14. [Query Recipes](#query-recipes) +15. [Structural Knowledge Map](#structural-knowledge-map) +16. [Code Property Graph](#code-property-graph) +17. [Architecture Reference](#architecture-reference) + - [GO (3 files)](#go-3-files) + - [JS (9 files)](#js-9-files) + - [PY (55 files)](#py-55-files) + - [SH (5 files)](#sh-5-files) + +--- + +## Statistics Dashboard + +| Metric | Value | +|--------|-------| +| Total Files | 72 | +| Total Symbols | 434 | +| Total Imports | 364 | +| Call Edges | 2363 | +| Inheritance Edges | 18 | +| Languages | 4 | +| Avg Symbols/File | 6.0 | +| Avg Imports/File | 5.1 | +| Resolved Imports | 81 | + +### Top Files by Import Count (Fan-Out) + +| File | Imports | Symbols | Language | +|------|---------|---------|----------| +| `app_factory.py` | 35 | 8 | py | +| `admin.py` | 18 | 11 | py | +| `auth.py` | 16 | 29 | py | +| `auth.py` | 15 | 14 | py | +| `security.py` | 15 | 10 | py | +| `enc_dec.go` | 14 | 4 | go | +| `subscription.py` | 12 | 4 | py | +| `scheduler.py` | 11 | 5 | py | +| `deniable_vault.py` | 10 | 22 | py | +| `enc_dec.py` | 10 | 5 | py | + +--- + +## Architectural Layers + +Auto-detected from path patterns, naming conventions, and imported frameworks. + +| Layer | Files | +|-------|-------| +| presentation | 29 | +| utility | 27 | +| testing | 8 | +| infrastructure | 4 | +| business_logic | 4 | + +### utility + +- `__init__.py` (py, 0 symbols) +- `app.py` (py, 2 symbols) +- `enc_dec.go` (go, 4 symbols) +- `enc_dec.py` (py, 5 symbols) +- `install.sh` (sh, 0 symbols) +- `lol.py` (py, 0 symbols) +- `make.sh` (sh, 0 symbols) +- `pq_decrypt_password.py` (py, 0 symbols) +- `doctor.py` (py, 0 symbols) +- `garage-init.sh` (sh, 1 symbols) +- `garage-native.sh` (sh, 3 symbols) +- `makeadmin.py` (py, 5 symbols) +- `server.go` (go, 2 symbols) +- `server.py` (py, 0 symbols) +- `account.js` (js, 9 symbols) +- *... and 12 more* + +### presentation + +- `app_factory.py` (py, 8 symbols) +- `__init__.py` (py, 0 symbols) +- `auth.py` (py, 14 symbols) +- `contact.py` (py, 4 symbols) +- `deniable_vault.py` (py, 22 symbols) +- `file.py` (py, 9 symbols) +- `message.py` (py, 4 symbols) +- `sync.py` (py, 3 symbols) +- `contact.py` (py, 9 symbols) +- `message.py` (py, 6 symbols) +- `user.py` (py, 27 symbols) +- `email_tool.py` (py, 6 symbols) +- `terms.py` (py, 1 symbols) +- `mailer.py` (py, 3 symbols) +- `scheduler.py` (py, 5 symbols) +- *... and 14 more* + +### infrastructure + +- `client.go` (go, 1 symbols) +- `client.py` (py, 0 symbols) +- `messages.js` (js, 6 symbols) +- `cache.py` (py, 5 symbols) + +### business_logic + +- `__init__.py` (py, 0 symbols) +- `deniable_vault.py` (py, 6 symbols) +- `plans.py` (py, 10 symbols) +- `superadmin_audit.py` (py, 5 symbols) + +### testing + +- `test_bloque1.py` (py, 8 symbols) +- `test.sh` (sh, 0 symbols) +- `__init__.py` (py, 0 symbols) +- `conftest.py` (py, 7 symbols) +- `test_auth_phone.py` (py, 3 symbols) +- `test_deniable_vault.py` (py, 55 symbols) +- `test_security.py` (py, 8 symbols) +- `test_srp.py` (py, 6 symbols) + +--- + +## Ranked Context + +Files ranked by composite score for the current query context. The ranking combines Personalized PageRank (query relevance), global authority, test coverage, documentation coverage, and code freshness. Model: v1.0. + +| Rank | File | Composite | PPR | Authority | Test | Doc | +|------|------|-----------|-----|-----------|------|-----| +| 1 | `garage-init.sh` | 0.2000 | 0.0000 | 0.0000 | 0.00 | 2.00 | +| 2 | `qv-crypto.js` | 0.1744 | 0.1991 | 0.1991 | 0.00 | 0.45 | +| 3 | `user.py` | 0.1282 | 0.0491 | 0.0491 | 0.00 | 0.96 | +| 4 | `register.js` | 0.1269 | 0.0927 | 0.0927 | 0.00 | 0.67 | +| 5 | `plans.py` | 0.1146 | 0.0224 | 0.0224 | 0.00 | 1.00 | +| 6 | `security.py` | 0.1141 | 0.0370 | 0.0370 | 0.00 | 0.90 | +| 7 | `contact.py` | 0.1130 | 0.0201 | 0.0201 | 0.00 | 1.00 | +| 8 | `mailer.py` | 0.1124 | 0.0191 | 0.0191 | 0.00 | 1.00 | +| 9 | `deniable_vault.py` | 0.1121 | 0.0186 | 0.0186 | 0.00 | 1.00 | +| 10 | `login.js` | 0.1103 | 0.0927 | 0.0927 | 0.00 | 0.50 | + +--- + +## God Nodes + +Most architecturally central files ranked by combined import/export degree and symbol richness. + +| File | Score | Connections | PageRank | +|------|-------|-------------|----------| +| `app_factory.py` | 38.8 | | 0.0000 | +| `user.py` | 26.7 | | 0.0491 | +| `auth.py` | 22.9 | | 0.0000 | +| `utils.py` | 18.7 | | 0.0000 | +| `admin.py` | 17.1 | | 0.0000 | +| `security.py` | 17.0 | | 0.0370 | +| `qv-crypto.js` | 16.0 | | 0.1991 | +| `auth.py` | 13.4 | | 0.0000 | +| `test_deniable_vault.py` | 11.5 | | 0.0000 | +| `deniable_vault.py` | 10.2 | | 0.0000 | + +--- + +## Community Analysis + +Files grouped by import-based community detection. Cohesion measures how tightly connected each community is internally. + +### views (Cohesion: 0.94) + +**34 files** in this community: + +- `app.py` (py, 2 symbols) +- `app_factory.py` (py, 8 symbols) +- `auth.py` (py, 14 symbols) +- `contact.py` (py, 4 symbols) +- `file.py` (py, 9 symbols) +- `message.py` (py, 4 symbols) +- `sync.py` (py, 3 symbols) +- `contact.py` (py, 9 symbols) +- `message.py` (py, 6 symbols) +- `plans.py` (py, 10 symbols) +- `superadmin_audit.py` (py, 5 symbols) +- `user.py` (py, 27 symbols) +- `email_tool.py` (py, 6 symbols) +- `makeadmin.py` (py, 5 symbols) +- `test_bloque1.py` (py, 8 symbols) +- `conftest.py` (py, 7 symbols) +- `test_security.py` (py, 8 symbols) +- `test_srp.py` (py, 6 symbols) +- `mailer.py` (py, 3 symbols) +- `scheduler.py` (py, 5 symbols) +- ... and 14 more files + +### controllers (Cohesion: 0.56) + +**4 files** in this community: + +- `deniable_vault.py` (py, 22 symbols) +- `deniable_vault.py` (py, 6 symbols) +- `test_deniable_vault.py` (py, 55 symbols) +- `account.py` (py, 5 symbols) + +### static/js (Cohesion: 1.00) + +**8 files** in this community: + +- `account.js` (js, 9 symbols) +- `login.js` (js, 2 symbols) +- `messages.js` (js, 6 symbols) +- `qv-crypto.js` (js, 40 symbols) +- `qv-deniable.js` (js, 7 symbols) +- `recover.js` (js, 3 symbols) +- `register.js` (js, 3 symbols) +- `upload.js` (js, 6 symbols) + +--- + +## Surprising Connections + +Files in different communities connected through 3+ indirect hops. + +- `contact.py` <-> `deniable_vault.py` (5 hops, across 2 communities) +- `contact.py` <-> `deniable_vault.py` (4 hops, across 2 communities) +- `deniable_vault.py` <-> `contact.py` (4 hops, across 2 communities) +- `deniable_vault.py` <-> `message.py` (4 hops, across 2 communities) +- `deniable_vault.py` <-> `superadmin_audit.py` (4 hops, across 2 communities) + +--- + +## Suggested Questions + +Auto-generated exploration prompts based on graph structure: + +- What does app_factory.py depend on, and what depends on it? (19 connections) +- What does user.py depend on, and what depends on it? (12 connections) +- What does auth.py depend on, and what depends on it? (10 connections) +- How are the 34 files in 'views' related to each other? +- Why are contact.py and deniable_vault.py connected through 5 hops across 2 communities? + +--- + +## Hotspot Analysis + +Files ranked by combined complexity (symbol count) and centrality (connection count). High-scoring files are architecturally critical and may need refactoring attention. + +| File | Complexity | Centrality | Combined | Symbols | Connections | +|------|-----------|------------|----------|---------|-------------| +| `garage-init.sh` | 0.018 | 0.000 | 0.007 | 1 | 0 | +| `qv-crypto.js` | 0.727 | 1.000 | 0.891 | 40 | 210 | +| `user.py` | 0.491 | 0.090 | 0.251 | 27 | 19 | +| `register.js` | 0.054 | 0.152 | 0.113 | 3 | 32 | +| `plans.py` | 0.182 | 0.029 | 0.090 | 10 | 6 | +| `security.py` | 0.182 | 0.110 | 0.138 | 10 | 23 | +| `contact.py` | 0.164 | 0.048 | 0.094 | 9 | 10 | +| `mailer.py` | 0.054 | 0.033 | 0.042 | 3 | 7 | +| `deniable_vault.py` | 0.109 | 0.033 | 0.064 | 6 | 7 | +| `login.js` | 0.036 | 0.090 | 0.069 | 2 | 19 | +| `test_deniable_vault.py` | 1.000 | 0.057 | 0.434 | 55 | 12 | +| `auth.py` | 0.527 | 0.124 | 0.285 | 29 | 26 | +| `account.js` | 0.164 | 0.276 | 0.231 | 9 | 58 | +| `app_factory.py` | 0.145 | 0.257 | 0.212 | 8 | 54 | +| `deniable_vault.py` | 0.400 | 0.067 | 0.200 | 22 | 14 | + +--- + +## Dependency Cycles + +Circular dependencies detected in the resolved import graph. Cycles increase coupling and make refactoring harder. + +| Cycle | Length | Files | +|-------|--------|-------| +| `qv-crypto.js -> register.js` | 2 | 2 | +| `qv-crypto.js -> login.js` | 2 | 2 | + +--- + +## Change Impact Analysis + +Files sorted by how many other files would be affected if they changed. High-impact files should be changed with caution. + +| File | Direct Dependents | Transitive Dependents | Total Impact | +|------|------------------|----------------------|--------------| +| `utils.py` | 9 | 11 | 20 | +| `user.py` | 12 | 5 | 17 | +| `security.py` | 7 | 9 | 16 | +| `mailer.py` | 4 | 9 | 13 | +| `plans.py` | 4 | 8 | 12 | +| `contact.py` | 1 | 10 | 11 | +| `auth.py` | 1 | 9 | 10 | +| `contact.py` | 2 | 8 | 10 | +| `auth.py` | 5 | 4 | 9 | +| `deniable_vault.py` | 3 | 5 | 8 | +| `message.py` | 2 | 6 | 8 | +| `deniable_vault.py` | 2 | 5 | 7 | +| `login.js` | 1 | 6 | 7 | +| `qv-crypto.js` | 6 | 1 | 7 | +| `register.js` | 1 | 6 | 7 | + +--- + +## Architecture Violations + +Violations of architectural layer rules detected in the import graph. **7 strict violations, 0 warnings.** + +| Source | Source Layer | Target | Target Layer | Description | Severity | +|--------|-------------|--------|-------------|-------------|----------| +| `test_bloque1.py` | testing | `user.py` | presentation | testing must not import presentation | strict | +| `test_bloque1.py` | testing | `admin.py` | presentation | testing must not import presentation | strict | +| `conftest.py` | testing | `app_factory.py` | presentation | testing must not import presentation | strict | +| `conftest.py` | testing | `security.py` | presentation | testing must not import presentation | strict | +| `test_deniable_vault.py` | testing | `deniable_vault.py` | presentation | testing must not import presentation | strict | +| `test_deniable_vault.py` | testing | `user.py` | presentation | testing must not import presentation | strict | +| `test_security.py` | testing | `security.py` | presentation | testing must not import presentation | strict | + +--- + +## Suggested Linting Rules + +Automatically suggested linting and security rules based on patterns detected in the codebase. These can be exported as Semgrep rules using the `--export-rules` flag. + +| Rule ID | Severity | Description | Language | Matches | +|---------|----------|-------------|----------|---------| +| `RM006` | error | Hardcoded credential detected | multi | 3 | +| `RM001` | info | Large number of functions in py: 302 total | py | 302 | +| `RM002` | info | Large number of functions in go: 7 total | go | 7 | +| `RM003` | info | Large number of functions in sh: 4 total | sh | 4 | +| `RM004` | info | Large number of functions in js: 79 total | js | 79 | +| `RM005` | info | Print statement found (consider logging instead) | python | 58 | + +--- + +## Orphans + +Files with no documentation or low connectivity. These are candidates for documentation investment or cleanup. + +- `__init__.py` (0 symbols, no doc) +- `client.go` (1 symbols, no doc) +- `client.py` (0 symbols, no doc) +- `__init__.py` (0 symbols, no doc) +- `enc_dec.go` (4 symbols, no doc) +- `lol.py` (0 symbols, no doc) +- `make.sh` (0 symbols, no doc) +- `__init__.py` (0 symbols, no doc) +- `pq_decrypt_password.py` (0 symbols, no doc) +- `doctor.py` (0 symbols, no doc) +- `test_bloque1.py` (8 symbols, no doc) +- `server.go` (2 symbols, no doc) +- `server.py` (0 symbols, no doc) +- `test.sh` (0 symbols, no doc) +- `__init__.py` (0 symbols, no doc) +- `test_security.py` (8 symbols, no doc) +- `__init__.py` (0 symbols, no doc) +- `__init__.py` (0 symbols, no doc) +- `wsgi.py` (0 symbols, no doc) + +--- + +## Query Recipes + +Example queries you can run against this knowledge base using the ranking engine: + +``` +# Find files most relevant to a concept +readmenator query "Where is the import resolver implemented?" + +# Rank files by relevance to a topic +readmenator query "How does documentation generation work?" + +# Explain why a file ranks highly +readmenator query "explain readmenator/_documentation.py" + +# Trace dependency paths with ranked context +readmenator query "path from CLI to exporter" +``` + +The ranking model uses the following signals: + +- **Personalized PageRank** (45% weight): query-specific relevance via seed propagation +- **Global Authority** (20% weight): structural importance via standard PageRank +- **Test Coverage** (15% weight): fraction of symbols referenced in test files +- **Doc Coverage** (10% weight): presence of docstrings and file-level docs +- **Freshness** (10% weight): recent modification activity + +Results include score decomposition and justification paths for each ranked item. + +--- + +## Structural Knowledge Map + +```mermaid +graph TD + classDef mod fill:#1e1e1e,stroke:#ff6666,stroke-width:2px,color:#fff; + classDef cls fill:#2d2d2d,stroke:#4ec9b0,stroke-width:2px,color:#fff; + classDef fn fill:#333,stroke:#dcdcaa,stroke-width:1px,color:#dcdcaa; + classDef ext fill:#111,stroke:#666,stroke-dasharray:5 5,color:#aaa; + subgraph community_2 ["static/js"] + static_js_qv_crypto_js["qv-crypto.js (js)"] + class static_js_qv_crypto_js mod; + static_js_qv_crypto_js_concatBytes["concatBytes"] + class static_js_qv_crypto_js_concatBytes fn; + static_js_qv_crypto_js --> static_js_qv_crypto_js_concatBytes + static_js_qv_crypto_js_hexToBytes["hexToBytes"] + class static_js_qv_crypto_js_hexToBytes fn; + static_js_qv_crypto_js --> static_js_qv_crypto_js_hexToBytes + static_js_qv_crypto_js_bytesToHex["bytesToHex"] + class static_js_qv_crypto_js_bytesToHex fn; + static_js_qv_crypto_js --> static_js_qv_crypto_js_bytesToHex + static_js_qv_crypto_js_bytesToBase64["bytesToBase64"] + class static_js_qv_crypto_js_bytesToBase64 fn; + static_js_qv_crypto_js --> static_js_qv_crypto_js_bytesToBase64 + static_js_qv_crypto_js_bytesToBase32["bytesToBase32"] + class static_js_qv_crypto_js_bytesToBase32 fn; + static_js_qv_crypto_js --> static_js_qv_crypto_js_bytesToBase32 + static_js_account_js["account.js (js)"] + class static_js_account_js mod; + end + subgraph community_0 ["views"] + app_factory_py["app_factory.py (py)"] + class app_factory_py mod; + static_js_upload_js["upload.js (js)"] + class static_js_upload_js mod; + static_js_qv_deniable_js["qv-deniable.js (js)"] + class static_js_qv_deniable_js mod; + static_js_messages_js["messages.js (js)"] + class static_js_messages_js mod; + static_js_recover_js["recover.js (js)"] + class static_js_recover_js mod; + static_js_register_js["register.js (js)"] + class static_js_register_js mod; + views_admin_py["admin.py (py)"] + class views_admin_py mod; + views_auth_py["auth.py (py)"] + class views_auth_py mod; + controllers_auth_py["auth.py (py)"] + class controllers_auth_py mod; + static_js_login_js["login.js (js)"] + class static_js_login_js mod; + static_js_coded_text_js["coded-text.js (js)"] + class static_js_coded_text_js mod; + utils_security_py["security.py (py)"] + class utils_security_py mod; + views_subscription_py["subscription.py (py)"] + class views_subscription_py mod; + utils_scheduler_py["scheduler.py (py)"] + class utils_scheduler_py mod; + enc_dec_go["enc_dec.go (go)"] + class enc_dec_go mod; + end + subgraph community_1 ["controllers"] + tests_test_deniable_vault_py["test_deniable_vault.py (py)"] + class tests_test_deniable_vault_py mod; + controllers_deniable_vault_py["deniable_vault.py (py)"] + class controllers_deniable_vault_py mod; + views_message_py["message.py (py)"] + class views_message_py mod; + scripts_email_tool_py["email_tool.py (py)"] + class scripts_email_tool_py mod; + views_account_py["account.py (py)"] + class views_account_py mod; + views_file_py["file.py (py)"] + class views_file_py mod; + scripts_test_bloque1_py["test_bloque1.py (py)"] + class scripts_test_bloque1_py mod; + enc_dec_py["enc_dec.py (py)"] + class enc_dec_py mod; + models_contact_py["contact.py (py)"] + class models_contact_py mod; + tests_conftest_py["conftest.py (py)"] + class tests_conftest_py mod; + models_message_py["message.py (py)"] + class models_message_py mod; + views_sync_py["sync.py (py)"] + class views_sync_py mod; + models_user_py["user.py (py)"] + class models_user_py mod; + controllers_file_py["file.py (py)"] + class controllers_file_py mod; + controllers_message_py["message.py (py)"] + class controllers_message_py mod; + client_go["client.go (go)"] + class client_go mod; + client_py["client.py (py)"] + class client_py mod; + utils_srp6a_py["srp6a.py (py)"] + class utils_srp6a_py mod; + tests_test_security_py["test_security.py (py)"] + class tests_test_security_py mod; + utils_utils_py["utils.py (py)"] + class utils_utils_py mod; + app_py["app.py (py)"] + class app_py mod; + views_views_py["views.py (py)"] + class views_views_py mod; + tests_test_srp_py["test_srp.py (py)"] + class tests_test_srp_py mod; + scripts_makeadmin_py["makeadmin.py (py)"] + class scripts_makeadmin_py mod; + server_go["server.go (go)"] + class server_go mod; + server_py["server.py (py)"] + class server_py mod; + models_deniable_vault_py["deniable_vault.py (py)"] + class models_deniable_vault_py mod; + controllers_sync_py["sync.py (py)"] + class controllers_sync_py mod; + models_superadmin_audit_py["superadmin_audit.py (py)"] + class models_superadmin_audit_py mod; + utils_cache_py["cache.py (py)"] + class utils_cache_py mod; + controllers_contact_py["contact.py (py)"] + class controllers_contact_py mod; + utils_mailer_py["mailer.py (py)"] + class utils_mailer_py mod; + views_faq_py["faq.py (py)"] + class views_faq_py mod; + scripts_doctor_py["doctor.py (py)"] + class scripts_doctor_py mod; + wsgi_py["wsgi.py (py)"] + class wsgi_py mod; + models_plans_py["plans.py (py)"] + class models_plans_py mod; + pq_decrypt_password_py["pq_decrypt_password.py (py)"] + class pq_decrypt_password_py mod; + tests_test_auth_phone_py["test_auth_phone.py (py)"] + class tests_test_auth_phone_py mod; + utils_plans_py["plans.py (py)"] + class utils_plans_py mod; + templates_terms_py["terms.py (py)"] + class templates_terms_py mod; + views_about_py["about.py (py)"] + class views_about_py mod; + views_privacy_py["privacy.py (py)"] + class views_privacy_py mod; + views_terms_py["terms.py (py)"] + class views_terms_py mod; + lol_py["lol.py (py)"] + class lol_py mod; + scripts_garage_native_sh["garage-native.sh (sh)"] + class scripts_garage_native_sh mod; + scripts_garage_init_sh["garage-init.sh (sh)"] + class scripts_garage_init_sh mod; + __init___py["__init__.py (py)"] + class __init___py mod; + controllers___init___py["__init__.py (py)"] + class controllers___init___py mod; + install_sh["install.sh (sh)"] + class install_sh mod; + make_sh["make.sh (sh)"] + class make_sh mod; + models___init___py["__init__.py (py)"] + class models___init___py mod; + test_sh["test.sh (sh)"] + class test_sh mod; + tests___init___py["__init__.py (py)"] + class tests___init___py mod; + utils___init___py["__init__.py (py)"] + class utils___init___py mod; + views___init___py["__init__.py (py)"] + class views___init___py mod; + end + app_py -- resolved_imports --> app_factory_py + app_py -- resolved_imports --> utils_utils_py + app_factory_py -- resolved_imports --> controllers_file_py + app_factory_py -- resolved_imports --> controllers_sync_py + app_factory_py -- resolved_imports --> models_user_py + app_factory_py -- resolved_imports --> utils_utils_py + app_factory_py -- resolved_imports --> views_about_py + app_factory_py -- resolved_imports --> views_account_py + app_factory_py -- resolved_imports --> views_admin_py + app_factory_py -- resolved_imports --> views_auth_py + app_factory_py -- resolved_imports --> views_faq_py + app_factory_py -- resolved_imports --> views_file_py + app_factory_py -- resolved_imports --> views_message_py + app_factory_py -- resolved_imports --> views_privacy_py + app_factory_py -- resolved_imports --> views_sync_py + app_factory_py -- resolved_imports --> views_terms_py + app_factory_py -- resolved_imports --> views_views_py + app_factory_py -- resolved_imports --> views_subscription_py + controllers_auth_py -- resolved_imports --> models_user_py + controllers_auth_py -- resolved_imports --> models_plans_py + controllers_auth_py -- resolved_imports --> utils_utils_py + controllers_auth_py -- resolved_imports --> utils_mailer_py + controllers_auth_py -- resolved_imports --> utils_security_py + controllers_contact_py -- resolved_imports --> models_contact_py + controllers_deniable_vault_py -- resolved_imports --> models_deniable_vault_py + controllers_deniable_vault_py -- resolved_imports --> utils_security_py + controllers_file_py -- resolved_imports --> utils_utils_py + controllers_message_py -- resolved_imports --> models_message_py + controllers_message_py -- resolved_imports --> models_user_py + scripts_email_tool_py -- resolved_imports --> models_user_py + scripts_email_tool_py -- resolved_imports --> utils_mailer_py + scripts_email_tool_py -- resolved_imports --> utils_utils_py + scripts_makeadmin_py -- resolved_imports --> models_user_py + scripts_test_bloque1_py -- resolved_imports --> app_py + scripts_test_bloque1_py -- resolved_imports --> models_user_py + scripts_test_bloque1_py -- resolved_imports --> views_admin_py + static_js_account_js -- resolved_imports --> static_js_qv_deniable_js + static_js_login_js -- resolved_imports --> static_js_qv_crypto_js + static_js_messages_js -- resolved_imports --> static_js_qv_crypto_js + static_js_qv_crypto_js -- resolved_imports --> static_js_register_js + static_js_qv_crypto_js -- resolved_imports --> static_js_login_js + static_js_qv_deniable_js -- resolved_imports --> static_js_qv_crypto_js + static_js_recover_js -- resolved_imports --> static_js_qv_crypto_js + static_js_register_js -- resolved_imports --> static_js_qv_crypto_js + static_js_upload_js -- resolved_imports --> static_js_qv_crypto_js + tests_conftest_py -- resolved_imports --> app_factory_py + tests_conftest_py -- resolved_imports --> utils_security_py + tests_test_deniable_vault_py -- resolved_imports --> controllers_deniable_vault_py + tests_test_deniable_vault_py -- resolved_imports --> models_deniable_vault_py + tests_test_deniable_vault_py -- resolved_imports --> models_user_py + tests_test_security_py -- resolved_imports --> utils_security_py + tests_test_srp_py -- resolved_imports --> utils_utils_py + utils_scheduler_py -- resolved_imports --> models_message_py + utils_scheduler_py -- resolved_imports --> models_user_py + utils_scheduler_py -- resolved_imports --> utils_mailer_py + utils_security_py -- resolved_imports --> utils_utils_py + views_account_py -- resolved_imports --> controllers_deniable_vault_py + views_account_py -- resolved_imports --> models_deniable_vault_py + views_account_py -- resolved_imports --> utils_security_py + views_admin_py -- resolved_imports --> models_user_py + views_admin_py -- resolved_imports --> models_plans_py + views_admin_py -- resolved_imports --> views_auth_py + views_admin_py -- resolved_imports --> controllers_contact_py + views_admin_py -- resolved_imports --> models_superadmin_audit_py + views_admin_py -- resolved_imports --> utils_utils_py + views_auth_py -- resolved_imports --> controllers_auth_py + views_auth_py -- resolved_imports --> controllers_contact_py + views_auth_py -- resolved_imports --> models_user_py + views_auth_py -- resolved_imports --> utils_mailer_py + views_auth_py -- resolved_imports --> utils_security_py + views_faq_py -- resolved_imports --> models_plans_py + views_file_py -- resolved_imports --> views_auth_py + views_message_py -- resolved_imports --> controllers_message_py + views_message_py -- resolved_imports --> views_auth_py + views_subscription_py -- resolved_imports --> models_user_py + views_subscription_py -- resolved_imports --> models_plans_py + views_subscription_py -- resolved_imports --> views_auth_py + views_sync_py -- resolved_imports --> utils_utils_py + views_sync_py -- resolved_imports --> utils_security_py + views_views_py -- resolved_imports --> models_user_py + wsgi_py -- resolved_imports --> app_factory_py + ext_os["os"] + class ext_os ext; + app_py -.->|imports| ext_os + ext_sys["sys"] + class ext_sys ext; + app_py -.->|imports| ext_sys + ext_app_factory["app_factory"] + class ext_app_factory ext; + app_py -.->|imports| ext_app_factory + ext_utils_utils["utils.utils"] + class ext_utils_utils ext; + app_py -.->|imports| ext_utils_utils + ext___future__["__future__"] + class ext___future__ ext; + app_factory_py -.->|imports| ext___future__ + ext_json["json"] + class ext_json ext; + app_factory_py -.->|imports| ext_json + ext_logging["logging"] + class ext_logging ext; + app_factory_py -.->|imports| ext_logging + app_factory_py -.->|imports| ext_os + ext_secrets["secrets"] + class ext_secrets ext; + app_factory_py -.->|imports| ext_secrets + app_factory_py -.->|imports| ext_sys + ext_datetime["datetime"] + class ext_datetime ext; + app_factory_py -.->|imports| ext_datetime + ext_typing["typing"] + class ext_typing ext; + app_factory_py -.->|imports| ext_typing + ext_boto3["boto3"] + class ext_boto3 ext; + app_factory_py -.->|imports| ext_boto3 + ext_botocore_config["botocore.config"] + class ext_botocore_config ext; + app_factory_py -.->|imports| ext_botocore_config + ext_flask["flask"] + class ext_flask ext; + app_factory_py -.->|imports| ext_flask + ext_flask_cors["flask_cors"] + class ext_flask_cors ext; + app_factory_py -.->|imports| ext_flask_cors + ext_flask_limiter["flask_limiter"] + class ext_flask_limiter ext; + app_factory_py -.->|imports| ext_flask_limiter + ext_flask_limiter_util["flask_limiter.util"] + class ext_flask_limiter_util ext; + app_factory_py -.->|imports| ext_flask_limiter_util + ext_flask_login["flask_login"] + class ext_flask_login ext; + app_factory_py -.->|imports| ext_flask_login + ext_flask_mail["flask_mail"] + class ext_flask_mail ext; + app_factory_py -.->|imports| ext_flask_mail + ext_flask_talisman["flask_talisman"] + class ext_flask_talisman ext; + app_factory_py -.->|imports| ext_flask_talisman + ext_flask_wtf_csrf["flask_wtf.csrf"] + class ext_flask_wtf_csrf ext; + app_factory_py -.->|imports| ext_flask_wtf_csrf + ext_werkzeug_middleware_proxy_fix["werkzeug.middleware.proxy_fix"] + class ext_werkzeug_middleware_proxy_fix ext; + app_factory_py -.->|imports| ext_werkzeug_middleware_proxy_fix + ext_controllers_file["controllers.file"] + class ext_controllers_file ext; + app_factory_py -.->|imports| ext_controllers_file + ext_controllers_sync["controllers.sync"] + class ext_controllers_sync ext; + app_factory_py -.->|imports| ext_controllers_sync + ext_models_user["models.user"] + class ext_models_user ext; + app_factory_py -.->|imports| ext_models_user + app_factory_py -.->|imports| ext_utils_utils + ext_views_about["views.about"] + class ext_views_about ext; + app_factory_py -.->|imports| ext_views_about + ext_views_account["views.account"] + class ext_views_account ext; + app_factory_py -.->|imports| ext_views_account + ext_views_admin["views.admin"] + class ext_views_admin ext; + app_factory_py -.->|imports| ext_views_admin + ext_views_auth["views.auth"] + class ext_views_auth ext; + app_factory_py -.->|imports| ext_views_auth + ext_views_faq["views.faq"] + class ext_views_faq ext; + app_factory_py -.->|imports| ext_views_faq + ext_views_file["views.file"] + class ext_views_file ext; + app_factory_py -.->|imports| ext_views_file + ext_views_message["views.message"] + class ext_views_message ext; + app_factory_py -.->|imports| ext_views_message + ext_views_privacy["views.privacy"] + class ext_views_privacy ext; + app_factory_py -.->|imports| ext_views_privacy + ext_views_sync["views.sync"] + class ext_views_sync ext; + app_factory_py -.->|imports| ext_views_sync + ext_views_terms["views.terms"] + class ext_views_terms ext; + app_factory_py -.->|imports| ext_views_terms + ext_views_views["views.views"] + class ext_views_views ext; + app_factory_py -.->|imports| ext_views_views + ext_views_subscription["views.subscription"] + class ext_views_subscription ext; + app_factory_py -.->|imports| ext_views_subscription + ext_crypto_aes["aes"] + class ext_crypto_aes ext; + client_go -.->|imports| ext_crypto_aes + ext_crypto_cipher["cipher"] + class ext_crypto_cipher ext; + client_go -.->|imports| ext_crypto_cipher + ext_crypto_rand["rand"] + class ext_crypto_rand ext; + client_go -.->|imports| ext_crypto_rand + ext_flag["flag"] + class ext_flag ext; + client_go -.->|imports| ext_flag + ext_fmt["fmt"] + class ext_fmt ext; + client_go -.->|imports| ext_fmt + ext_net["net"] + class ext_net ext; + client_go -.->|imports| ext_net + ext_github_com_open_quantum_safe_liboqs_go_oqs["oqs"] + class ext_github_com_open_quantum_safe_liboqs_go_oqs ext; + client_go -.->|imports| ext_github_com_open_quantum_safe_liboqs_go_oqs + ext_argparse["argparse"] + class ext_argparse ext; + client_py -.->|imports| ext_argparse + ext_socket["socket"] + class ext_socket ext; + client_py -.->|imports| ext_socket + ext_oqs["oqs"] + class ext_oqs ext; + client_py -.->|imports| ext_oqs + ext_cryptography_hazmat_primitives_ciphers_aead["cryptography.hazmat.primitives.ciphers.aead"] + class ext_cryptography_hazmat_primitives_ciphers_aead ext; + client_py -.->|imports| ext_cryptography_hazmat_primitives_ciphers_aead + ext_cryptography_hazmat_primitives["cryptography.hazmat.primitives"] + class ext_cryptography_hazmat_primitives ext; + client_py -.->|imports| ext_cryptography_hazmat_primitives + ext_cryptography_hazmat_primitives_kdf_pbkdf2["cryptography.hazmat.primitives.kdf.pbkdf2"] + class ext_cryptography_hazmat_primitives_kdf_pbkdf2 ext; + client_py -.->|imports| ext_cryptography_hazmat_primitives_kdf_pbkdf2 + client_py -.->|imports| ext_os + controllers_auth_py -.->|imports| ext_os + controllers_auth_py -.->|imports| ext_secrets + controllers_auth_py -.->|imports| ext_datetime + controllers_auth_py -.->|imports| ext_typing + ext_pytz["pytz"] + class ext_pytz ext; + controllers_auth_py -.->|imports| ext_pytz + controllers_auth_py -.->|imports| ext_flask + controllers_auth_py -.->|imports| ext_flask_mail + ext_clicksend_client["clicksend_client"] + class ext_clicksend_client ext; + controllers_auth_py -.->|imports| ext_clicksend_client + controllers_auth_py -.->|imports| ext_clicksend_client + ext_clicksend_client_rest["clicksend_client.rest"] + class ext_clicksend_client_rest ext; + controllers_auth_py -.->|imports| ext_clicksend_client_rest + controllers_auth_py -.->|imports| ext_models_user + ext_models_plans["models.plans"] + class ext_models_plans ext; + controllers_auth_py -.->|imports| ext_models_plans + ext_utils["utils"] + class ext_utils ext; + controllers_auth_py -.->|imports| ext_utils + ext_utils_mailer["utils.mailer"] + class ext_utils_mailer ext; + controllers_auth_py -.->|imports| ext_utils_mailer + ext_utils_security["utils.security"] + class ext_utils_security ext; + controllers_auth_py -.->|imports| ext_utils_security + ext_models_contact["models.contact"] + class ext_models_contact ext; + controllers_contact_py -.->|imports| ext_models_contact + controllers_contact_py -.->|imports| ext_flask + controllers_deniable_vault_py -.->|imports| ext___future__ + ext_binascii["binascii"] + class ext_binascii ext; + controllers_deniable_vault_py -.->|imports| ext_binascii + ext_base64["base64"] + class ext_base64 ext; + controllers_deniable_vault_py -.->|imports| ext_base64 + controllers_deniable_vault_py -.->|imports| ext_json + controllers_deniable_vault_py -.->|imports| ext_os + controllers_deniable_vault_py -.->|imports| ext_secrets + ext_dataclasses["dataclasses"] + class ext_dataclasses ext; + controllers_deniable_vault_py -.->|imports| ext_dataclasses + controllers_deniable_vault_py -.->|imports| ext_typing + ext_models_deniable_vault["models.deniable_vault"] + class ext_models_deniable_vault ext; + controllers_deniable_vault_py -.->|imports| ext_models_deniable_vault + controllers_deniable_vault_py -.->|imports| ext_utils_security + controllers_file_py -.->|imports| ext_os + controllers_file_py -.->|imports| ext_typing + controllers_file_py -.->|imports| ext_flask + ext_werkzeug_utils["werkzeug.utils"] + class ext_werkzeug_utils ext; + controllers_file_py -.->|imports| ext_werkzeug_utils + controllers_file_py -.->|imports| ext_boto3 + ext_botocore_exceptions["botocore.exceptions"] + class ext_botocore_exceptions ext; + controllers_file_py -.->|imports| ext_botocore_exceptions + controllers_message_py -.->|imports| ext_typing + ext_models_message["models.message"] + class ext_models_message ext; + controllers_message_py -.->|imports| ext_models_message + controllers_message_py -.->|imports| ext_models_user + ext_uuid["uuid"] + class ext_uuid ext; + controllers_message_py -.->|imports| ext_uuid + controllers_message_py -.->|imports| ext_flask + controllers_sync_py -.->|imports| ext_os + controllers_sync_py -.->|imports| ext_flask + controllers_sync_py -.->|imports| ext_boto3 + controllers_sync_py -.->|imports| ext_botocore_exceptions + ext_archive_tar["tar"] + class ext_archive_tar ext; + enc_dec_go -.->|imports| ext_archive_tar + ext_compress_gzip["gzip"] + class ext_compress_gzip ext; + enc_dec_go -.->|imports| ext_compress_gzip + enc_dec_go -.->|imports| ext_crypto_aes + enc_dec_go -.->|imports| ext_crypto_cipher + enc_dec_go -.->|imports| ext_crypto_rand + enc_dec_go -.->|imports| ext_flag + enc_dec_go -.->|imports| ext_fmt + ext_io["io"] + class ext_io ext; + enc_dec_go -.->|imports| ext_io + enc_dec_go -.->|imports| ext_os + ext_path_filepath["filepath"] + class ext_path_filepath ext; + enc_dec_go -.->|imports| ext_path_filepath + ext_strings["strings"] + class ext_strings ext; + enc_dec_go -.->|imports| ext_strings + enc_dec_go -.->|imports| ext_github_com_open_quantum_safe_liboqs_go_oqs + ext_golang_org_x_crypto_pbkdf2["pbkdf2"] + class ext_golang_org_x_crypto_pbkdf2 ext; + enc_dec_go -.->|imports| ext_golang_org_x_crypto_pbkdf2 + ext_crypto_sha256["sha256"] + class ext_crypto_sha256 ext; + enc_dec_go -.->|imports| ext_crypto_sha256 + enc_dec_py -.->|imports| ext_argparse + enc_dec_py -.->|imports| ext_os + enc_dec_py -.->|imports| ext_io + enc_dec_py -.->|imports| ext_oqs + enc_dec_py -.->|imports| ext_cryptography_hazmat_primitives_ciphers_aead + enc_dec_py -.->|imports| ext_cryptography_hazmat_primitives_kdf_pbkdf2 + enc_dec_py -.->|imports| ext_cryptography_hazmat_primitives + enc_dec_py -.->|imports| ext_boto3 + enc_dec_py -.->|imports| ext_botocore_exceptions + ext_pathlib["pathlib"] + class ext_pathlib ext; + enc_dec_py -.->|imports| ext_pathlib + lol_py -.->|imports| ext_base64 + ext_pydantic["pydantic"] + class ext_pydantic ext; + models_contact_py -.->|imports| ext_pydantic + models_contact_py -.->|imports| ext_typing + ext_sqlite3["sqlite3"] + class ext_sqlite3 ext; + models_contact_py -.->|imports| ext_sqlite3 + models_contact_py -.->|imports| ext_datetime + models_contact_py -.->|imports| ext_pytz + models_contact_py -.->|imports| ext_flask + models_contact_py -.->|imports| ext_flask + models_contact_py -.->|imports| ext_flask + models_contact_py -.->|imports| ext_flask + models_deniable_vault_py -.->|imports| ext___future__ + models_deniable_vault_py -.->|imports| ext_sqlite3 + models_deniable_vault_py -.->|imports| ext_datetime + models_deniable_vault_py -.->|imports| ext_typing + models_message_py -.->|imports| ext_pydantic + models_message_py -.->|imports| ext_typing + models_message_py -.->|imports| ext_os + ext_glob["glob"] + class ext_glob ext; + models_message_py -.->|imports| ext_glob + models_message_py -.->|imports| ext_base64 + models_message_py -.->|imports| ext_datetime + models_message_py -.->|imports| ext_uuid + models_message_py -.->|imports| ext_json + models_message_py -.->|imports| ext_flask + models_plans_py -.->|imports| ext_typing + models_plans_py -.->|imports| ext_sqlite3 + models_superadmin_audit_py -.->|imports| ext_sqlite3 + models_superadmin_audit_py -.->|imports| ext_datetime + models_superadmin_audit_py -.->|imports| ext_typing + models_user_py -.->|imports| ext_pydantic + models_user_py -.->|imports| ext_typing + models_user_py -.->|imports| ext_flask_login + models_user_py -.->|imports| ext_sqlite3 + models_user_py -.->|imports| ext_datetime + models_user_py -.->|imports| ext_pytz + models_user_py -.->|imports| ext_flask + pq_decrypt_password_py -.->|imports| ext_argparse + ext_utils_crypto["utils.crypto"] + class ext_utils_crypto ext; + pq_decrypt_password_py -.->|imports| ext_utils_crypto + scripts_doctor_py -.->|imports| ext_os + scripts_doctor_py -.->|imports| ext_sys + ext_importlib["importlib"] + class ext_importlib ext; + scripts_doctor_py -.->|imports| ext_importlib + scripts_email_tool_py -.->|imports| ext_argparse + scripts_email_tool_py -.->|imports| ext_os + scripts_email_tool_py -.->|imports| ext_sys + scripts_email_tool_py -.->|imports| ext_flask + scripts_email_tool_py -.->|imports| ext_flask_mail + scripts_email_tool_py -.->|imports| ext_models_user + scripts_email_tool_py -.->|imports| ext_utils_mailer + scripts_email_tool_py -.->|imports| ext_utils_utils + scripts_makeadmin_py -.->|imports| ext_argparse + scripts_makeadmin_py -.->|imports| ext_os + scripts_makeadmin_py -.->|imports| ext_sys + scripts_makeadmin_py -.->|imports| ext_models_user + scripts_test_bloque1_py -.->|imports| ext_os + scripts_test_bloque1_py -.->|imports| ext_sys + ext_shutil["shutil"] + class ext_shutil ext; + scripts_test_bloque1_py -.->|imports| ext_shutil + ext_re["re"] + class ext_re ext; + scripts_test_bloque1_py -.->|imports| ext_re + ext_app["app"] + class ext_app ext; + scripts_test_bloque1_py -.->|imports| ext_app + scripts_test_bloque1_py -.->|imports| ext_models_user + scripts_test_bloque1_py -.->|imports| ext_views_admin + server_go -.->|imports| ext_crypto_aes + server_go -.->|imports| ext_crypto_cipher + server_go -.->|imports| ext_fmt + server_go -.->|imports| ext_net + server_go -.->|imports| ext_github_com_open_quantum_safe_liboqs_go_oqs + server_py -.->|imports| ext_socket + server_py -.->|imports| ext_oqs + server_py -.->|imports| ext_cryptography_hazmat_primitives_ciphers_aead + server_py -.->|imports| ext_cryptography_hazmat_primitives + server_py -.->|imports| ext_cryptography_hazmat_primitives_kdf_pbkdf2 + ext___qv_deniable_js["qv-deniable.js"] + class ext___qv_deniable_js ext; + static_js_account_js -.->|imports| ext___qv_deniable_js + ext_notes["notes"] + class ext_notes ext; + static_js_account_js -.->|imports| ext_notes + ext_present["present"] + class ext_present ext; + static_js_account_js -.->|imports| ext_present + ext_setStatus["setStatus"] + class ext_setStatus ext; + static_js_account_js -.->|imports| ext_setStatus + ext_getElementById["getElementById"] + class ext_getElementById ext; + static_js_account_js -.->|imports| ext_getElementById + ext_add["add"] + class ext_add ext; + static_js_account_js -.->|imports| ext_add + ext_csrfToken["csrfToken"] + class ext_csrfToken ext; + static_js_account_js -.->|imports| ext_csrfToken + static_js_account_js -.->|imports| ext_getElementById + ext_apiRequest["apiRequest"] + class ext_apiRequest ext; + static_js_account_js -.->|imports| ext_apiRequest + static_js_account_js -.->|imports| ext_csrfToken + ext_stringify["stringify"] + class ext_stringify ext; + static_js_account_js -.->|imports| ext_stringify + ext_fetch["fetch"] + class ext_fetch ext; + static_js_account_js -.->|imports| ext_fetch + static_js_account_js -.->|imports| ext_json + ext_loadState["loadState"] + class ext_loadState ext; + static_js_account_js -.->|imports| ext_loadState + static_js_account_js -.->|imports| ext_apiRequest + ext_collectSlots["collectSlots"] + class ext_collectSlots ext; + static_js_account_js -.->|imports| ext_collectSlots + static_js_account_js -.->|imports| ext_getElementById + static_js_account_js -.->|imports| ext_getElementById + static_js_account_js -.->|imports| ext_getElementById + static_js_account_js -.->|imports| ext_getElementById + ext_push["push"] + class ext_push ext; + static_js_account_js -.->|imports| ext_push + ext_handleConfigure["handleConfigure"] + class ext_handleConfigure ext; + static_js_account_js -.->|imports| ext_handleConfigure + ext_preventDefault["preventDefault"] + class ext_preventDefault ext; + static_js_account_js -.->|imports| ext_preventDefault + static_js_account_js -.->|imports| ext_collectSlots + static_js_account_js -.->|imports| ext_setStatus + static_js_account_js -.->|imports| ext_setStatus + static_js_account_js -.->|imports| ext_setStatus + ext_buildDeniableVault["buildDeniableVault"] + class ext_buildDeniableVault ext; + static_js_account_js -.->|imports| ext_buildDeniableVault + static_js_account_js -.->|imports| ext_apiRequest + static_js_account_js -.->|imports| ext_setStatus + ext_reset["reset"] + class ext_reset ext; + static_js_account_js -.->|imports| ext_reset + ext_error["error"] + class ext_error ext; + static_js_account_js -.->|imports| ext_error + static_js_account_js -.->|imports| ext_setStatus + ext_handleOpen["handleOpen"] + class ext_handleOpen ext; + static_js_account_js -.->|imports| ext_handleOpen + static_js_account_js -.->|imports| ext_preventDefault + static_js_account_js -.->|imports| ext_getElementById + static_js_account_js -.->|imports| ext_getElementById + static_js_account_js -.->|imports| ext_setStatus + ext_openDeniableVault["openDeniableVault"] + class ext_openDeniableVault ext; + static_js_account_js -.->|imports| ext_openDeniableVault + static_js_account_js -.->|imports| ext_setStatus + static_js_account_js -.->|imports| ext_setStatus + ext_handleReset["handleReset"] + class ext_handleReset ext; + static_js_account_js -.->|imports| ext_handleReset + static_js_account_js -.->|imports| ext_apiRequest + static_js_account_js -.->|imports| ext_loadState + static_js_account_js -.->|imports| ext_setStatus + static_js_account_js -.->|imports| ext_setStatus + ext_init["init"] + class ext_init ext; + static_js_account_js -.->|imports| ext_init + static_js_account_js -.->|imports| ext_getElementById + static_js_account_js -.->|imports| ext_getElementById + static_js_account_js -.->|imports| ext_getElementById + ext_addEventListener["addEventListener"] + class ext_addEventListener ext; + static_js_account_js -.->|imports| ext_addEventListener + static_js_account_js -.->|imports| ext_addEventListener + static_js_account_js -.->|imports| ext_addEventListener + static_js_account_js -.->|imports| ext_loadState + static_js_account_js -.->|imports| ext_setStatus + static_js_account_js -.->|imports| ext_addEventListener + static_js_account_js -.->|imports| ext_init + ext_randomChar["randomChar"] + class ext_randomChar ext; + static_js_coded_text_js -.->|imports| ext_randomChar + ext_floor["floor"] + class ext_floor ext; + static_js_coded_text_js -.->|imports| ext_floor + ext_random["random"] + class ext_random ext; + static_js_coded_text_js -.->|imports| ext_random + ext_toUpperCase["toUpperCase"] + class ext_toUpperCase ext; + static_js_coded_text_js -.->|imports| ext_toUpperCase + ext_animateElement["animateElement"] + class ext_animateElement ext; + static_js_coded_text_js -.->|imports| ext_animateElement + ext_split["split"] + class ext_split ext; + static_js_coded_text_js -.->|imports| ext_split + ext_contains["contains"] + class ext_contains ext; + static_js_coded_text_js -.->|imports| ext_contains + ext_map["map"] + class ext_map ext; + static_js_coded_text_js -.->|imports| ext_map + ext_join["join"] + class ext_join ext; + static_js_coded_text_js -.->|imports| ext_join + ext_timeline["timeline"] + class ext_timeline ext; + static_js_coded_text_js -.->|imports| ext_timeline + static_js_coded_text_js -.->|imports| ext_floor + static_js_coded_text_js -.->|imports| ext_randomChar + static_js_coded_text_js -.->|imports| ext_init + ext_querySelectorAll["querySelectorAll"] + class ext_querySelectorAll ext; + static_js_coded_text_js -.->|imports| ext_querySelectorAll + ext_forEach["forEach"] + class ext_forEach ext; + static_js_coded_text_js -.->|imports| ext_forEach + static_js_coded_text_js -.->|imports| ext_addEventListener + static_js_coded_text_js -.->|imports| ext_init + ext___qv_crypto_js["qv-crypto.js"] + class ext___qv_crypto_js ext; + static_js_login_js -.->|imports| ext___qv_crypto_js + ext_controller["controller"] + class ext_controller ext; + static_js_login_js -.->|imports| ext_controller + ext_handleLogin["handleLogin"] + class ext_handleLogin ext; + static_js_login_js -.->|imports| ext_handleLogin + static_js_login_js -.->|imports| ext_preventDefault + ext_querySelector["querySelector"] + class ext_querySelector ext; + static_js_login_js -.->|imports| ext_querySelector + static_js_login_js -.->|imports| ext_getElementById + static_js_login_js -.->|imports| ext_getElementById + static_js_login_js -.->|imports| ext_querySelector + ext_alert["alert"] + class ext_alert ext; + static_js_login_js -.->|imports| ext_alert + ext_login["login"] + class ext_login ext; + static_js_login_js -.->|imports| ext_login + static_js_login_js -.->|imports| ext_error + static_js_login_js -.->|imports| ext_alert + static_js_login_js -.->|imports| ext_init + static_js_login_js -.->|imports| ext_getElementById + static_js_login_js -.->|imports| ext_addEventListener + static_js_login_js -.->|imports| ext_addEventListener + static_js_login_js -.->|imports| ext_init + static_js_messages_js -.->|imports| ext___qv_crypto_js + static_js_messages_js -.->|imports| ext_controller + ext_textContent["textContent"] + class ext_textContent ext; + static_js_messages_js -.->|imports| ext_textContent + ext_getCsrfToken["getCsrfToken"] + class ext_getCsrfToken ext; + static_js_messages_js -.->|imports| ext_getCsrfToken + static_js_messages_js -.->|imports| ext_querySelector + ext_handleSend["handleSend"] + class ext_handleSend ext; + static_js_messages_js -.->|imports| ext_handleSend + static_js_messages_js -.->|imports| ext_preventDefault + static_js_messages_js -.->|imports| ext_getElementById + static_js_messages_js -.->|imports| ext_getElementById + static_js_messages_js -.->|imports| ext_alert + ext_sendSecureMessage["sendSecureMessage"] + class ext_sendSecureMessage ext; + static_js_messages_js -.->|imports| ext_sendSecureMessage + static_js_messages_js -.->|imports| ext_error + static_js_messages_js -.->|imports| ext_alert + ext_collectEnvelopes["collectEnvelopes"] + class ext_collectEnvelopes ext; + static_js_messages_js -.->|imports| ext_collectEnvelopes + ext_from["from"] + class ext_from ext; + static_js_messages_js -.->|imports| ext_from + ext_parse["parse"] + class ext_parse ext; + static_js_messages_js -.->|imports| ext_parse + static_js_messages_js -.->|imports| ext_push + ext_envelope["envelope"] + class ext_envelope ext; + static_js_messages_js -.->|imports| ext_envelope + ext_handleDecryptInbox["handleDecryptInbox"] + class ext_handleDecryptInbox ext; + static_js_messages_js -.->|imports| ext_handleDecryptInbox + static_js_messages_js -.->|imports| ext_collectEnvelopes + static_js_messages_js -.->|imports| ext_alert + ext_prompt["prompt"] + class ext_prompt ext; + static_js_messages_js -.->|imports| ext_prompt + ext_decryptInbox["decryptInbox"] + class ext_decryptInbox ext; + static_js_messages_js -.->|imports| ext_decryptInbox + static_js_messages_js -.->|imports| ext_forEach + static_js_messages_js -.->|imports| ext_error + static_js_messages_js -.->|imports| ext_alert + ext_initEditor["initEditor"] + class ext_initEditor ext; + static_js_messages_js -.->|imports| ext_initEditor + static_js_messages_js -.->|imports| ext_getElementById + ext_value["value"] + class ext_value ext; + static_js_messages_js -.->|imports| ext_value + static_js_messages_js -.->|imports| ext_init + static_js_messages_js -.->|imports| ext_getElementById + static_js_messages_js -.->|imports| ext_addEventListener + static_js_messages_js -.->|imports| ext_getElementById + static_js_messages_js -.->|imports| ext_addEventListener + static_js_messages_js -.->|imports| ext_handleDecryptInbox + static_js_messages_js -.->|imports| ext_initEditor + static_js_messages_js -.->|imports| ext_addEventListener + static_js_messages_js -.->|imports| ext_init + ext___vendor_sha2_js["sha2.js"] + class ext___vendor_sha2_js ext; + static_js_qv_crypto_js -.->|imports| ext___vendor_sha2_js + ext___vendor_hkdf_js["hkdf.js"] + class ext___vendor_hkdf_js ext; + static_js_qv_crypto_js -.->|imports| ext___vendor_hkdf_js + ext___vendor_ml_kem_js["ml_kem.js"] + class ext___vendor_ml_kem_js ext; + static_js_qv_crypto_js -.->|imports| ext___vendor_ml_kem_js + ext___vendor_ed25519_js["ed25519.js"] + class ext___vendor_ed25519_js ext; + static_js_qv_crypto_js -.->|imports| ext___vendor_ed25519_js + ext_768["768"] + class ext_768 ext; + static_js_qv_crypto_js -.->|imports| ext_768 + static_js_qv_crypto_js -.->|imports| ext_768 + ext_concatBytes["concatBytes"] + class ext_concatBytes ext; + static_js_qv_crypto_js -.->|imports| ext_concatBytes + ext_reduce["reduce"] + class ext_reduce ext; + static_js_qv_crypto_js -.->|imports| ext_reduce + ext_set["set"] + class ext_set ext; + static_js_qv_crypto_js -.->|imports| ext_set + ext_hexToBytes["hexToBytes"] + class ext_hexToBytes ext; + static_js_qv_crypto_js -.->|imports| ext_hexToBytes + ext_parseInt["parseInt"] + class ext_parseInt ext; + static_js_qv_crypto_js -.->|imports| ext_parseInt + ext_bytesToHex["bytesToHex"] + class ext_bytesToHex ext; + static_js_qv_crypto_js -.->|imports| ext_bytesToHex + ext_toString["toString"] + class ext_toString ext; + static_js_qv_crypto_js -.->|imports| ext_toString + ext_padStart["padStart"] + class ext_padStart ext; + static_js_qv_crypto_js -.->|imports| ext_padStart + ext_bytesToBase64["bytesToBase64"] + class ext_bytesToBase64 ext; + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + ext_fromCharCode["fromCharCode"] + class ext_fromCharCode ext; + static_js_qv_crypto_js -.->|imports| ext_fromCharCode + ext_btoa["btoa"] + class ext_btoa ext; + static_js_qv_crypto_js -.->|imports| ext_btoa + ext_bytes["bytes"] + class ext_bytes ext; + static_js_qv_crypto_js -.->|imports| ext_bytes + ext_bytesToBase32["bytesToBase32"] + class ext_bytesToBase32 ext; + static_js_qv_crypto_js -.->|imports| ext_bytesToBase32 + ext_base64ToBytes["base64ToBytes"] + class ext_base64ToBytes ext; + static_js_qv_crypto_js -.->|imports| ext_base64ToBytes + ext_atob["atob"] + class ext_atob ext; + static_js_qv_crypto_js -.->|imports| ext_atob + ext_charCodeAt["charCodeAt"] + class ext_charCodeAt ext; + static_js_qv_crypto_js -.->|imports| ext_charCodeAt + ext_bytesToBigInt["bytesToBigInt"] + class ext_bytesToBigInt ext; + static_js_qv_crypto_js -.->|imports| ext_bytesToBigInt + ext_i2osp["i2osp"] + class ext_i2osp ext; + static_js_qv_crypto_js -.->|imports| ext_i2osp + ext_mod["mod"] + class ext_mod ext; + static_js_qv_crypto_js -.->|imports| ext_mod + ext_return["return"] + class ext_return ext; + static_js_qv_crypto_js -.->|imports| ext_return + ext_modPow["modPow"] + class ext_modPow ext; + static_js_qv_crypto_js -.->|imports| ext_modPow + static_js_qv_crypto_js -.->|imports| ext_mod + static_js_qv_crypto_js -.->|imports| ext_bytes + ext_randomBytes["randomBytes"] + class ext_randomBytes ext; + static_js_qv_crypto_js -.->|imports| ext_randomBytes + ext_min["min"] + class ext_min ext; + static_js_qv_crypto_js -.->|imports| ext_min + ext_getRandomValues["getRandomValues"] + class ext_getRandomValues ext; + static_js_qv_crypto_js -.->|imports| ext_getRandomValues + ext_sha256["sha256"] + class ext_sha256 ext; + static_js_qv_crypto_js -.->|imports| ext_sha256 + static_js_qv_crypto_js -.->|imports| ext_bytesToBigInt + ext_vault["vault"] + class ext_vault ext; + static_js_qv_crypto_js -.->|imports| ext_vault + ext_deriveKeyFromPassphrase["deriveKeyFromPassphrase"] + class ext_deriveKeyFromPassphrase ext; + static_js_qv_crypto_js -.->|imports| ext_deriveKeyFromPassphrase + ext_importKey["importKey"] + class ext_importKey ext; + static_js_qv_crypto_js -.->|imports| ext_importKey + ext_deriveBits["deriveBits"] + class ext_deriveBits ext; + static_js_qv_crypto_js -.->|imports| ext_deriveBits + ext_deriveMasterKey["deriveMasterKey"] + class ext_deriveMasterKey ext; + static_js_qv_crypto_js -.->|imports| ext_deriveMasterKey + static_js_qv_crypto_js -.->|imports| ext_deriveKeyFromPassphrase + ext_aesGcmEncrypt["aesGcmEncrypt"] + class ext_aesGcmEncrypt ext; + static_js_qv_crypto_js -.->|imports| ext_aesGcmEncrypt + static_js_qv_crypto_js -.->|imports| ext_importKey + static_js_qv_crypto_js -.->|imports| ext_randomBytes + static_js_qv_crypto_js -.->|imports| ext_concatBytes + ext_aesGcmDecrypt["aesGcmDecrypt"] + class ext_aesGcmDecrypt ext; + static_js_qv_crypto_js -.->|imports| ext_aesGcmDecrypt + static_js_qv_crypto_js -.->|imports| ext_importKey + ext_slice["slice"] + class ext_slice ext; + static_js_qv_crypto_js -.->|imports| ext_slice + static_js_qv_crypto_js -.->|imports| ext_slice + static_js_qv_crypto_js -.->|imports| ext_aesGcmEncrypt + ext_separate["separate"] + class ext_separate ext; + static_js_qv_crypto_js -.->|imports| ext_separate + ext_module["module"] + class ext_module ext; + static_js_qv_crypto_js -.->|imports| ext_module + ext_computeK["computeK"] + class ext_computeK ext; + static_js_qv_crypto_js -.->|imports| ext_computeK + static_js_qv_crypto_js -.->|imports| ext_i2osp + ext_deriveVerifier["deriveVerifier"] + class ext_deriveVerifier ext; + static_js_qv_crypto_js -.->|imports| ext_deriveVerifier + static_js_qv_crypto_js -.->|imports| ext_bytesToHex + ext_srpLogin["srpLogin"] + class ext_srpLogin ext; + static_js_qv_crypto_js -.->|imports| ext_srpLogin + static_js_qv_crypto_js -.->|imports| ext_bytesToBigInt + static_js_qv_crypto_js -.->|imports| ext_modPow + ext_postJson["postJson"] + class ext_postJson ext; + static_js_qv_crypto_js -.->|imports| ext_postJson + static_js_qv_crypto_js -.->|imports| ext_computeK + static_js_qv_crypto_js -.->|imports| ext_i2osp + static_js_qv_crypto_js -.->|imports| ext_modPow + static_js_qv_crypto_js -.->|imports| ext_map + static_js_qv_crypto_js -.->|imports| ext_i2osp + static_js_qv_crypto_js -.->|imports| ext_i2osp + static_js_qv_crypto_js -.->|imports| ext_postJson + ext_hybrid["hybrid"] + class ext_hybrid ext; + static_js_qv_crypto_js -.->|imports| ext_hybrid + ext_generateIdentity["generateIdentity"] + class ext_generateIdentity ext; + static_js_qv_crypto_js -.->|imports| ext_generateIdentity + ext_keygen["keygen"] + class ext_keygen ext; + static_js_qv_crypto_js -.->|imports| ext_keygen + static_js_qv_crypto_js -.->|imports| ext_keygen + static_js_qv_crypto_js -.->|imports| ext_keygen + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + ext_encode["encode"] + class ext_encode ext; + static_js_qv_crypto_js -.->|imports| ext_encode + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + ext_parsePublicKey["parsePublicKey"] + class ext_parsePublicKey ext; + static_js_qv_crypto_js -.->|imports| ext_parsePublicKey + static_js_qv_crypto_js -.->|imports| ext_parse + ext_decode["decode"] + class ext_decode ext; + static_js_qv_crypto_js -.->|imports| ext_decode + static_js_qv_crypto_js -.->|imports| ext_base64ToBytes + static_js_qv_crypto_js -.->|imports| ext_base64ToBytes + ext_parsePrivateBlob["parsePrivateBlob"] + class ext_parsePrivateBlob ext; + static_js_qv_crypto_js -.->|imports| ext_parsePrivateBlob + static_js_qv_crypto_js -.->|imports| ext_parse + static_js_qv_crypto_js -.->|imports| ext_decode + static_js_qv_crypto_js -.->|imports| ext_base64ToBytes + static_js_qv_crypto_js -.->|imports| ext_base64ToBytes + ext_deriveWrapKey["deriveWrapKey"] + class ext_deriveWrapKey ext; + static_js_qv_crypto_js -.->|imports| ext_deriveWrapKey + ext_hkdf["hkdf"] + class ext_hkdf ext; + static_js_qv_crypto_js -.->|imports| ext_hkdf + static_js_qv_crypto_js -.->|imports| ext_encode + ext_wrapKey["wrapKey"] + class ext_wrapKey ext; + static_js_qv_crypto_js -.->|imports| ext_wrapKey + static_js_qv_crypto_js -.->|imports| ext_parsePublicKey + ext_encapsulate["encapsulate"] + class ext_encapsulate ext; + static_js_qv_crypto_js -.->|imports| ext_encapsulate + static_js_qv_crypto_js -.->|imports| ext_keygen + ext_getSharedSecret["getSharedSecret"] + class ext_getSharedSecret ext; + static_js_qv_crypto_js -.->|imports| ext_getSharedSecret + static_js_qv_crypto_js -.->|imports| ext_deriveWrapKey + static_js_qv_crypto_js -.->|imports| ext_aesGcmEncrypt + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + ext_unwrapKey["unwrapKey"] + class ext_unwrapKey ext; + static_js_qv_crypto_js -.->|imports| ext_unwrapKey + static_js_qv_crypto_js -.->|imports| ext_parsePrivateBlob + static_js_qv_crypto_js -.->|imports| ext_parse + static_js_qv_crypto_js -.->|imports| ext_decode + ext_decapsulate["decapsulate"] + class ext_decapsulate ext; + static_js_qv_crypto_js -.->|imports| ext_decapsulate + static_js_qv_crypto_js -.->|imports| ext_getSharedSecret + static_js_qv_crypto_js -.->|imports| ext_deriveWrapKey + static_js_qv_crypto_js -.->|imports| ext_aesGcmDecrypt + ext_recovery["recovery"] + class ext_recovery ext; + static_js_qv_crypto_js -.->|imports| ext_recovery + static_js_qv_crypto_js -.->|imports| ext_bytes + ext_generateRecoveryCode["generateRecoveryCode"] + class ext_generateRecoveryCode ext; + static_js_qv_crypto_js -.->|imports| ext_generateRecoveryCode + static_js_qv_crypto_js -.->|imports| ext_bytesToBase32 + static_js_qv_crypto_js -.->|imports| ext_push + static_js_qv_crypto_js -.->|imports| ext_join + ext_normalizeRecoveryCode["normalizeRecoveryCode"] + class ext_normalizeRecoveryCode ext; + static_js_qv_crypto_js -.->|imports| ext_normalizeRecoveryCode + ext_trim["trim"] + class ext_trim ext; + static_js_qv_crypto_js -.->|imports| ext_trim + static_js_qv_crypto_js -.->|imports| ext_toUpperCase + ext_replace["replace"] + class ext_replace ext; + static_js_qv_crypto_js -.->|imports| ext_replace + ext_wrapPrivateKeyForRecovery["wrapPrivateKeyForRecovery"] + class ext_wrapPrivateKeyForRecovery ext; + static_js_qv_crypto_js -.->|imports| ext_wrapPrivateKeyForRecovery + static_js_qv_crypto_js -.->|imports| ext_bytesToHex + static_js_qv_crypto_js -.->|imports| ext_deriveMasterKey + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + ext_key["key"] + class ext_key ext; + static_js_qv_crypto_js -.->|imports| ext_key + ext_innerSK["innerSK"] + class ext_innerSK ext; + static_js_qv_crypto_js -.->|imports| ext_innerSK + ext_publicKey["publicKey"] + class ext_publicKey ext; + static_js_qv_crypto_js -.->|imports| ext_publicKey + ext_derivePublicKeyFromPrivateBlob["derivePublicKeyFromPrivateBlob"] + class ext_derivePublicKeyFromPrivateBlob ext; + static_js_qv_crypto_js -.->|imports| ext_derivePublicKeyFromPrivateBlob + static_js_qv_crypto_js -.->|imports| ext_parsePrivateBlob + static_js_qv_crypto_js -.->|imports| ext_slice + ext_getPublicKey["getPublicKey"] + class ext_getPublicKey ext; + static_js_qv_crypto_js -.->|imports| ext_getPublicKey + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + static_js_qv_crypto_js -.->|imports| ext_postJson + static_js_qv_crypto_js -.->|imports| ext_fetch + static_js_qv_crypto_js -.->|imports| ext_json + ext_endpoint["endpoint"] + class ext_endpoint ext; + static_js_qv_crypto_js -.->|imports| ext_endpoint + ext_buildRegistration["buildRegistration"] + class ext_buildRegistration ext; + static_js_qv_crypto_js -.->|imports| ext_buildRegistration + static_js_qv_crypto_js -.->|imports| ext_bytesToHex + static_js_qv_crypto_js -.->|imports| ext_bytesToHex + static_js_qv_crypto_js -.->|imports| ext_deriveVerifier + static_js_qv_crypto_js -.->|imports| ext_generateIdentity + static_js_qv_crypto_js -.->|imports| ext_deriveMasterKey + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + static_js_qv_crypto_js -.->|imports| ext_generateRecoveryCode + static_js_qv_crypto_js -.->|imports| ext_wrapPrivateKeyForRecovery + ext_register["register"] + class ext_register ext; + static_js_qv_crypto_js -.->|imports| ext_register + static_js_qv_crypto_js -.->|imports| ext_buildRegistration + static_js_qv_crypto_js -.->|imports| ext_postJson + ext_recoverAccount["recoverAccount"] + class ext_recoverAccount ext; + static_js_qv_crypto_js -.->|imports| ext_recoverAccount + static_js_qv_crypto_js -.->|imports| ext_fetch + static_js_qv_crypto_js -.->|imports| ext_json + static_js_qv_crypto_js -.->|imports| ext_json + static_js_qv_crypto_js -.->|imports| ext_deriveMasterKey + static_js_qv_crypto_js -.->|imports| ext_aesGcmDecrypt + static_js_qv_crypto_js -.->|imports| ext_derivePublicKeyFromPrivateBlob + static_js_qv_crypto_js -.->|imports| ext_bytesToHex + static_js_qv_crypto_js -.->|imports| ext_deriveVerifier + static_js_qv_crypto_js -.->|imports| ext_bytesToHex + static_js_qv_crypto_js -.->|imports| ext_deriveMasterKey + static_js_qv_crypto_js -.->|imports| ext_bytesToBase64 + static_js_qv_crypto_js -.->|imports| ext_postJson + static_js_qv_crypto_js -.->|imports| ext_login + static_js_qv_crypto_js -.->|imports| ext_srpLogin + ext_encryptAndUpload["encryptAndUpload"] + class ext_encryptAndUpload ext; + static_js_qv_crypto_js -.->|imports| ext_encryptAndUpload + static_js_qv_crypto_js -.->|imports| ext_randomBytes + static_js_qv_crypto_js -.->|imports| ext_aesGcmEncrypt + static_js_qv_crypto_js -.->|imports| ext_wrapKey + ext_append["append"] + class ext_append ext; + static_js_qv_crypto_js -.->|imports| ext_append + static_js_qv_crypto_js -.->|imports| ext_append + static_js_qv_crypto_js -.->|imports| ext_append + static_js_qv_crypto_js -.->|imports| ext_fetch + static_js_qv_crypto_js -.->|imports| ext_json + static_js_qv_crypto_js -.->|imports| ext_json + ext_downloadAndDecrypt["downloadAndDecrypt"] + class ext_downloadAndDecrypt ext; + static_js_qv_crypto_js -.->|imports| ext_downloadAndDecrypt + static_js_qv_crypto_js -.->|imports| ext_fetch + static_js_qv_crypto_js -.->|imports| ext_json + static_js_qv_crypto_js -.->|imports| ext_json + static_js_qv_crypto_js -.->|imports| ext_fetch + static_js_qv_crypto_js -.->|imports| ext_json + static_js_qv_crypto_js -.->|imports| ext_deriveMasterKey + static_js_qv_crypto_js -.->|imports| ext_aesGcmDecrypt + static_js_qv_crypto_js -.->|imports| ext_unwrapKey + static_js_qv_crypto_js -.->|imports| ext_aesGcmDecrypt + ext_fetchPublicKey["fetchPublicKey"] + class ext_fetchPublicKey ext; + static_js_qv_crypto_js -.->|imports| ext_fetchPublicKey + static_js_qv_crypto_js -.->|imports| ext_fetch + static_js_qv_crypto_js -.->|imports| ext_json + static_js_qv_crypto_js -.->|imports| ext_return + ext_recipient["recipient"] + class ext_recipient ext; + static_js_qv_crypto_js -.->|imports| ext_recipient + static_js_qv_crypto_js -.->|imports| ext_sendSecureMessage + static_js_qv_crypto_js -.->|imports| ext_randomBytes + static_js_qv_crypto_js -.->|imports| ext_aesGcmEncrypt + static_js_qv_crypto_js -.->|imports| ext_fetchPublicKey + static_js_qv_crypto_js -.->|imports| ext_wrapKey + static_js_qv_crypto_js -.->|imports| ext_fetchPublicKey + static_js_qv_crypto_js -.->|imports| ext_wrapKey + static_js_qv_crypto_js -.->|imports| ext_postJson + static_js_qv_crypto_js -.->|imports| ext_decryptInbox + static_js_qv_crypto_js -.->|imports| ext_fetch + static_js_qv_crypto_js -.->|imports| ext_json + static_js_qv_crypto_js -.->|imports| ext_deriveMasterKey + static_js_qv_crypto_js -.->|imports| ext_aesGcmDecrypt + static_js_qv_crypto_js -.->|imports| ext_unwrapKey + static_js_qv_crypto_js -.->|imports| ext_aesGcmDecrypt + static_js_qv_crypto_js -.->|imports| ext_push + static_js_qv_crypto_js -.->|imports| ext_push + static_js_qv_deniable_js -.->|imports| ext___qv_crypto_js + static_js_qv_deniable_js -.->|imports| ext_vault + ext_server["server"] + class ext_server ext; + static_js_qv_deniable_js -.->|imports| ext_server + ext_list["list"] + class ext_list ext; + static_js_qv_deniable_js -.->|imports| ext_list + ext_toBytes["toBytes"] + class ext_toBytes ext; + static_js_qv_deniable_js -.->|imports| ext_toBytes + static_js_qv_deniable_js -.->|imports| ext_encode + ext_len["len"] + class ext_len ext; + static_js_qv_deniable_js -.->|imports| ext_len + ext_frame["frame"] + class ext_frame ext; + static_js_qv_deniable_js -.->|imports| ext_frame + static_js_qv_deniable_js -.->|imports| ext_randomBytes + ext_setUint32["setUint32"] + class ext_setUint32 ext; + static_js_qv_deniable_js -.->|imports| ext_setUint32 + static_js_qv_deniable_js -.->|imports| ext_set + static_js_qv_deniable_js -.->|imports| ext_frame + ext_unframe["unframe"] + class ext_unframe ext; + static_js_qv_deniable_js -.->|imports| ext_unframe + ext_getUint32["getUint32"] + class ext_getUint32 ext; + static_js_qv_deniable_js -.->|imports| ext_getUint32 + static_js_qv_deniable_js -.->|imports| ext_slice + ext_sealSlot["sealSlot"] + class ext_sealSlot ext; + static_js_qv_deniable_js -.->|imports| ext_sealSlot + static_js_qv_deniable_js -.->|imports| ext_randomBytes + static_js_qv_deniable_js -.->|imports| ext_bytesToHex + static_js_qv_deniable_js -.->|imports| ext_deriveKeyFromPassphrase + static_js_qv_deniable_js -.->|imports| ext_aesGcmEncrypt + static_js_qv_deniable_js -.->|imports| ext_slice + static_js_qv_deniable_js -.->|imports| ext_slice + static_js_qv_deniable_js -.->|imports| ext_bytesToHex + static_js_qv_deniable_js -.->|imports| ext_bytesToBase64 + ext_openSlot["openSlot"] + class ext_openSlot ext; + static_js_qv_deniable_js -.->|imports| ext_openSlot + static_js_qv_deniable_js -.->|imports| ext_deriveKeyFromPassphrase + static_js_qv_deniable_js -.->|imports| ext_base64ToBytes + static_js_qv_deniable_js -.->|imports| ext_aesGcmDecrypt + static_js_qv_deniable_js -.->|imports| ext_unframe + static_js_qv_deniable_js -.->|imports| ext_buildDeniableVault + static_js_qv_deniable_js -.->|imports| ext_map + static_js_qv_deniable_js -.->|imports| ext_toBytes + static_js_qv_deniable_js -.->|imports| ext_push + static_js_qv_deniable_js -.->|imports| ext_randomBytes + static_js_qv_deniable_js -.->|imports| ext_frame + static_js_qv_deniable_js -.->|imports| ext_push + static_js_qv_deniable_js -.->|imports| ext_openDeniableVault + static_js_qv_deniable_js -.->|imports| ext_openSlot + static_js_qv_deniable_js -.->|imports| ext_decode + static_js_recover_js -.->|imports| ext___qv_crypto_js + static_js_recover_js -.->|imports| ext_controller + static_js_recover_js -.->|imports| ext_recoverAccount + static_js_recover_js -.->|imports| ext_setStatus + ext_toggle["toggle"] + class ext_toggle ext; + static_js_recover_js -.->|imports| ext_toggle + static_js_recover_js -.->|imports| ext_toggle + ext_handleRecover["handleRecover"] + class ext_handleRecover ext; + static_js_recover_js -.->|imports| ext_handleRecover + static_js_recover_js -.->|imports| ext_preventDefault + static_js_recover_js -.->|imports| ext_querySelector + static_js_recover_js -.->|imports| ext_getElementById + static_js_recover_js -.->|imports| ext_getElementById + static_js_recover_js -.->|imports| ext_trim + static_js_recover_js -.->|imports| ext_getElementById + static_js_recover_js -.->|imports| ext_trim + static_js_recover_js -.->|imports| ext_getElementById + static_js_recover_js -.->|imports| ext_getElementById + static_js_recover_js -.->|imports| ext_querySelector + static_js_recover_js -.->|imports| ext_setStatus + static_js_recover_js -.->|imports| ext_setStatus + static_js_recover_js -.->|imports| ext_setStatus + static_js_recover_js -.->|imports| ext_setStatus + static_js_recover_js -.->|imports| ext_recoverAccount + static_js_recover_js -.->|imports| ext_setStatus + static_js_recover_js -.->|imports| ext_error + static_js_recover_js -.->|imports| ext_setStatus + static_js_recover_js -.->|imports| ext_init + static_js_recover_js -.->|imports| ext_getElementById + static_js_recover_js -.->|imports| ext_addEventListener + static_js_recover_js -.->|imports| ext_addEventListener + static_js_recover_js -.->|imports| ext_init + static_js_register_js -.->|imports| ext___qv_crypto_js + static_js_register_js -.->|imports| ext_controller + ext_showRecoveryCode["showRecoveryCode"] + class ext_showRecoveryCode ext; + static_js_register_js -.->|imports| ext_showRecoveryCode + static_js_register_js -.->|imports| ext_getElementById + static_js_register_js -.->|imports| ext_getElementById + static_js_register_js -.->|imports| ext_getElementById + static_js_register_js -.->|imports| ext_alert + ext_resolve["resolve"] + class ext_resolve ext; + static_js_register_js -.->|imports| ext_resolve + ext_remove["remove"] + class ext_remove ext; + static_js_register_js -.->|imports| ext_remove + static_js_register_js -.->|imports| ext_addEventListener + static_js_register_js -.->|imports| ext_add + static_js_register_js -.->|imports| ext_resolve + ext_handleRegister["handleRegister"] + class ext_handleRegister ext; + static_js_register_js -.->|imports| ext_handleRegister + static_js_register_js -.->|imports| ext_preventDefault + ext_fromEntries["fromEntries"] + class ext_fromEntries ext; + static_js_register_js -.->|imports| ext_fromEntries + static_js_register_js -.->|imports| ext_alert + static_js_register_js -.->|imports| ext_alert + static_js_register_js -.->|imports| ext_querySelector + ext_payload["payload"] + class ext_payload ext; + static_js_register_js -.->|imports| ext_payload + static_js_register_js -.->|imports| ext_buildRegistration + static_js_register_js -.->|imports| ext_fetch + static_js_register_js -.->|imports| ext_json + static_js_register_js -.->|imports| ext_showRecoveryCode + static_js_register_js -.->|imports| ext_error + static_js_register_js -.->|imports| ext_alert + static_js_register_js -.->|imports| ext_init + static_js_register_js -.->|imports| ext_getElementById + static_js_register_js -.->|imports| ext_addEventListener + static_js_register_js -.->|imports| ext_addEventListener + static_js_register_js -.->|imports| ext_init + static_js_upload_js -.->|imports| ext___qv_crypto_js + static_js_upload_js -.->|imports| ext_controller + static_js_upload_js -.->|imports| ext_getCsrfToken + static_js_upload_js -.->|imports| ext_querySelector + ext_getUsername["getUsername"] + class ext_getUsername ext; + static_js_upload_js -.->|imports| ext_getUsername + static_js_upload_js -.->|imports| ext_getPublicKey + static_js_upload_js -.->|imports| ext_fetch + static_js_upload_js -.->|imports| ext_getCsrfToken + static_js_upload_js -.->|imports| ext_json + static_js_upload_js -.->|imports| ext_json + ext_handleUpload["handleUpload"] + class ext_handleUpload ext; + static_js_upload_js -.->|imports| ext_handleUpload + static_js_upload_js -.->|imports| ext_preventDefault + static_js_upload_js -.->|imports| ext_alert + static_js_upload_js -.->|imports| ext_getPublicKey + static_js_upload_js -.->|imports| ext_encryptAndUpload + static_js_upload_js -.->|imports| ext_alert + ext_reload["reload"] + class ext_reload ext; + static_js_upload_js -.->|imports| ext_reload + static_js_upload_js -.->|imports| ext_alert + ext_handleDownload["handleDownload"] + class ext_handleDownload ext; + static_js_upload_js -.->|imports| ext_handleDownload + static_js_upload_js -.->|imports| ext_preventDefault + static_js_upload_js -.->|imports| ext_prompt + static_js_upload_js -.->|imports| ext_downloadAndDecrypt + ext_createObjectURL["createObjectURL"] + class ext_createObjectURL ext; + static_js_upload_js -.->|imports| ext_createObjectURL + ext_createElement["createElement"] + class ext_createElement ext; + static_js_upload_js -.->|imports| ext_createElement + ext_appendChild["appendChild"] + class ext_appendChild ext; + static_js_upload_js -.->|imports| ext_appendChild + ext_click["click"] + class ext_click ext; + static_js_upload_js -.->|imports| ext_click + ext_revokeObjectURL["revokeObjectURL"] + class ext_revokeObjectURL ext; + static_js_upload_js -.->|imports| ext_revokeObjectURL + static_js_upload_js -.->|imports| ext_remove + static_js_upload_js -.->|imports| ext_alert + static_js_upload_js -.->|imports| ext_init + static_js_upload_js -.->|imports| ext_getElementById + static_js_upload_js -.->|imports| ext_getElementById + static_js_upload_js -.->|imports| ext_getElementById + static_js_upload_js -.->|imports| ext_addEventListener + static_js_upload_js -.->|imports| ext_handleUpload + static_js_upload_js -.->|imports| ext_getUsername + static_js_upload_js -.->|imports| ext_querySelectorAll + static_js_upload_js -.->|imports| ext_forEach + static_js_upload_js -.->|imports| ext_addEventListener + static_js_upload_js -.->|imports| ext_handleDownload + static_js_upload_js -.->|imports| ext_addEventListener + static_js_upload_js -.->|imports| ext_init + templates_terms_py -.->|imports| ext_flask + tests_conftest_py -.->|imports| ext___future__ + tests_conftest_py -.->|imports| ext_logging + tests_conftest_py -.->|imports| ext_os + tests_conftest_py -.->|imports| ext_sys + ext_pytest["pytest"] + class ext_pytest ext; + tests_conftest_py -.->|imports| ext_pytest + tests_conftest_py -.->|imports| ext_app_factory + tests_conftest_py -.->|imports| ext_utils_security + tests_test_auth_phone_py -.->|imports| ext___future__ + tests_test_deniable_vault_py -.->|imports| ext___future__ + tests_test_deniable_vault_py -.->|imports| ext_base64 + ext_copy["copy"] + class ext_copy ext; + tests_test_deniable_vault_py -.->|imports| ext_copy + tests_test_deniable_vault_py -.->|imports| ext_json + tests_test_deniable_vault_py -.->|imports| ext_datetime + tests_test_deniable_vault_py -.->|imports| ext_pytest + ext_controllers_deniable_vault["controllers.deniable_vault"] + class ext_controllers_deniable_vault ext; + tests_test_deniable_vault_py -.->|imports| ext_controllers_deniable_vault + tests_test_deniable_vault_py -.->|imports| ext_models_deniable_vault + tests_test_deniable_vault_py -.->|imports| ext_models_user + tests_test_security_py -.->|imports| ext___future__ + tests_test_security_py -.->|imports| ext_json + tests_test_security_py -.->|imports| ext_flask_wtf_csrf + tests_test_security_py -.->|imports| ext_utils_security + tests_test_security_py -.->|imports| ext_flask + tests_test_srp_py -.->|imports| ext___future__ + ext_hashlib["hashlib"] + class ext_hashlib ext; + tests_test_srp_py -.->|imports| ext_hashlib + tests_test_srp_py -.->|imports| ext_secrets + tests_test_srp_py -.->|imports| ext_utils + utils_cache_py -.->|imports| ext_typing + ext_redis["redis"] + class ext_redis ext; + utils_cache_py -.->|imports| ext_redis + utils_cache_py -.->|imports| ext_json + utils_mailer_py -.->|imports| ext_typing + utils_mailer_py -.->|imports| ext_flask + utils_mailer_py -.->|imports| ext_flask_mail + utils_plans_py -.->|imports| ext_typing + utils_scheduler_py -.->|imports| ext___future__ + utils_scheduler_py -.->|imports| ext_logging + utils_scheduler_py -.->|imports| ext_datetime + utils_scheduler_py -.->|imports| ext_typing + utils_scheduler_py -.->|imports| ext_pytz + ext_apscheduler_schedulers_background["apscheduler.schedulers.background"] + class ext_apscheduler_schedulers_background ext; + utils_scheduler_py -.->|imports| ext_apscheduler_schedulers_background + utils_scheduler_py -.->|imports| ext_flask + utils_scheduler_py -.->|imports| ext_flask_mail + utils_scheduler_py -.->|imports| ext_models_message + utils_scheduler_py -.->|imports| ext_models_user + utils_scheduler_py -.->|imports| ext_utils_mailer + utils_security_py -.->|imports| ext___future__ + ext_functools["functools"] + class ext_functools ext; + utils_security_py -.->|imports| ext_functools + utils_security_py -.->|imports| ext_hashlib + ext_hmac["hmac"] + class ext_hmac ext; + utils_security_py -.->|imports| ext_hmac + utils_security_py -.->|imports| ext_json + utils_security_py -.->|imports| ext_logging + utils_security_py -.->|imports| ext_os + utils_security_py -.->|imports| ext_secrets + ext_time["time"] + class ext_time ext; + utils_security_py -.->|imports| ext_time + utils_security_py -.->|imports| ext_uuid + utils_security_py -.->|imports| ext_typing + utils_security_py -.->|imports| ext_flask + utils_security_py -.->|imports| ext_flask_wtf_csrf + ext_wtforms["wtforms"] + class ext_wtforms ext; + utils_security_py -.->|imports| ext_wtforms + utils_security_py -.->|imports| ext_utils_utils + utils_srp6a_py -.->|imports| ext_hashlib + utils_srp6a_py -.->|imports| ext_hmac + utils_srp6a_py -.->|imports| ext_json + utils_srp6a_py -.->|imports| ext_secrets + utils_srp6a_py -.->|imports| ext_typing + utils_srp6a_py -.->|imports| ext_redis + utils_utils_py -.->|imports| ext_json + utils_utils_py -.->|imports| ext_typing + utils_utils_py -.->|imports| ext_re + utils_utils_py -.->|imports| ext_os + utils_utils_py -.->|imports| ext_werkzeug_utils + ext_dotenv["dotenv"] + class ext_dotenv ext; + utils_utils_py -.->|imports| ext_dotenv + views_about_py -.->|imports| ext_flask + views_account_py -.->|imports| ext___future__ + views_account_py -.->|imports| ext_flask + views_account_py -.->|imports| ext_flask_limiter + views_account_py -.->|imports| ext_flask_limiter_util + views_account_py -.->|imports| ext_flask_login + views_account_py -.->|imports| ext_controllers_deniable_vault + views_account_py -.->|imports| ext_models_deniable_vault + views_account_py -.->|imports| ext_utils_security + views_admin_py -.->|imports| ext_flask + views_admin_py -.->|imports| ext_flask_login + views_admin_py -.->|imports| ext_models_user + views_admin_py -.->|imports| ext_models_plans + ext_flask_wtf["flask_wtf"] + class ext_flask_wtf ext; + views_admin_py -.->|imports| ext_flask_wtf + views_admin_py -.->|imports| ext_wtforms + ext_wtforms_validators["wtforms.validators"] + class ext_wtforms_validators ext; + views_admin_py -.->|imports| ext_wtforms_validators + views_admin_py -.->|imports| ext_flask_limiter + views_admin_py -.->|imports| ext_flask_limiter_util + ext_auth["auth"] + class ext_auth ext; + views_admin_py -.->|imports| ext_auth + ext_controllers_contact["controllers.contact"] + class ext_controllers_contact ext; + views_admin_py -.->|imports| ext_controllers_contact + ext_models_superadmin_audit["models.superadmin_audit"] + class ext_models_superadmin_audit ext; + views_admin_py -.->|imports| ext_models_superadmin_audit + views_admin_py -.->|imports| ext_os + views_admin_py -.->|imports| ext_secrets + views_admin_py -.->|imports| ext_datetime + views_admin_py -.->|imports| ext_pytz + views_admin_py -.->|imports| ext_utils_utils + views_admin_py -.->|imports| ext_sqlite3 + views_auth_py -.->|imports| ext_hmac + views_auth_py -.->|imports| ext_os + views_auth_py -.->|imports| ext_functools + views_auth_py -.->|imports| ext_flask + views_auth_py -.->|imports| ext_flask_limiter + views_auth_py -.->|imports| ext_flask_limiter_util + views_auth_py -.->|imports| ext_flask_login + views_auth_py -.->|imports| ext_flask_wtf + views_auth_py -.->|imports| ext_flask_wtf_csrf + views_auth_py -.->|imports| ext_wtforms + views_auth_py -.->|imports| ext_wtforms_validators + ext_controllers_auth["controllers.auth"] + class ext_controllers_auth ext; + views_auth_py -.->|imports| ext_controllers_auth + views_auth_py -.->|imports| ext_controllers_contact + views_auth_py -.->|imports| ext_models_user + views_auth_py -.->|imports| ext_utils_mailer + views_auth_py -.->|imports| ext_utils_security + views_faq_py -.->|imports| ext_flask + views_faq_py -.->|imports| ext_models_plans + views_file_py -.->|imports| ext_flask + views_file_py -.->|imports| ext_flask_login + views_file_py -.->|imports| ext_flask_wtf + views_file_py -.->|imports| ext_wtforms + views_file_py -.->|imports| ext_wtforms_validators + views_file_py -.->|imports| ext_flask_limiter + views_file_py -.->|imports| ext_flask_limiter_util + views_file_py -.->|imports| ext_auth + views_file_py -.->|imports| ext_os + views_file_py -.->|imports| ext_base64 + views_message_py -.->|imports| ext_flask + views_message_py -.->|imports| ext_flask_login + ext_controllers_message["controllers.message"] + class ext_controllers_message ext; + views_message_py -.->|imports| ext_controllers_message + views_message_py -.->|imports| ext_flask_wtf + views_message_py -.->|imports| ext_wtforms + views_message_py -.->|imports| ext_wtforms_validators + views_message_py -.->|imports| ext_flask_limiter + views_message_py -.->|imports| ext_flask_limiter_util + views_message_py -.->|imports| ext_auth + views_message_py -.->|imports| ext_os + views_privacy_py -.->|imports| ext_flask + views_subscription_py -.->|imports| ext_os + views_subscription_py -.->|imports| ext_flask + views_subscription_py -.->|imports| ext_flask_login + views_subscription_py -.->|imports| ext_models_user + views_subscription_py -.->|imports| ext_models_plans + ext_paypalrestsdk["paypalrestsdk"] + class ext_paypalrestsdk ext; + views_subscription_py -.->|imports| ext_paypalrestsdk + views_subscription_py -.->|imports| ext_flask_wtf + views_subscription_py -.->|imports| ext_wtforms + views_subscription_py -.->|imports| ext_wtforms_validators + views_subscription_py -.->|imports| ext_flask_limiter + views_subscription_py -.->|imports| ext_flask_limiter_util + views_subscription_py -.->|imports| ext_auth + views_sync_py -.->|imports| ext_os + views_sync_py -.->|imports| ext_flask + views_sync_py -.->|imports| ext_flask_limiter + views_sync_py -.->|imports| ext_flask_limiter_util + views_sync_py -.->|imports| ext_flask_login + views_sync_py -.->|imports| ext_werkzeug_utils + views_sync_py -.->|imports| ext_utils_security + views_terms_py -.->|imports| ext_flask + views_views_py -.->|imports| ext_flask + views_views_py -.->|imports| ext_flask_login + views_views_py -.->|imports| ext_flask_wtf + views_views_py -.->|imports| ext_wtforms + views_views_py -.->|imports| ext_models_user + wsgi_py -.->|imports| ext_os + wsgi_py -.->|imports| ext_app_factory +``` + +--- + +## Code Property Graph + +Machine-readable Code Property Graph (CPG) in JSON-LD format. This block allows AI agents to parse the full structural graph without additional file reads. Compatible with GraphRAG pipelines. + +```json +{"@context": "https://readmenator.dev/cpg/v1", "analysis": {"communities": [{"cohesion": 0.94, "id": 0, "label": "views", "size": 34}, {"cohesion": 0.556, "id": 1, "label": "controllers", "size": 4}, {"cohesion": 1.0, "id": 2, "label": "static/js", "size": 8}], "god_nodes": [{"node_id": "app_factory.py", "score": 38.8}, {"node_id": "models/user.py", "score": 26.7}, {"node_id": "views/auth.py", "score": 22.9}, {"node_id": "utils/utils.py", "score": 18.7}, {"node_id": "views/admin.py", "score": 17.1}, {"node_id": "utils/security.py", "score": 17.0}, {"node_id": "static/js/qv-crypto.js", "score": 16.0}, {"node_id": "controllers/auth.py", "score": 13.4}, {"node_id": "tests/test_deniable_vault.py", "score": 11.5}, {"node_id": "controllers/deniable_vault.py", "score": 10.2}], "surprising_connections": [{"hops": 5, "source": "models/contact.py", "target": "models/deniable_vault.py"}, {"hops": 4, "source": "controllers/contact.py", "target": "models/deniable_vault.py"}, {"hops": 4, "source": "controllers/deniable_vault.py", "target": "models/contact.py"}, {"hops": 4, "source": "controllers/deniable_vault.py", "target": "models/message.py"}, {"hops": 4, "source": "controllers/deniable_vault.py", "target": "models/superadmin_audit.py"}]}, "edges": [{"confidence": "EXTRACTED", "relation": "imports", "source": "app.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app.py", "target": "sys"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app.py", "target": "app_factory"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app.py", "target": "utils.utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "logging"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "secrets"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "sys"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "boto3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "botocore.config"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "flask_cors"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "flask_limiter"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "flask_limiter.util"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "flask_mail"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "flask_talisman"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "flask_wtf.csrf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "werkzeug.middleware.proxy_fix"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "controllers.file"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "controllers.sync"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "utils.utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.about"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.account"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.admin"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.auth"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.faq"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.file"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.message"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.privacy"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.sync"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.terms"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.views"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "app_factory.py", "target": "views.subscription"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.go", "target": "crypto/aes"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.go", "target": "crypto/cipher"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.go", "target": "crypto/rand"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.go", "target": "flag"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.go", "target": "fmt"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.go", "target": "net"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.go", "target": "github.com/open-quantum-safe/liboqs-go/oqs"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.py", "target": "argparse"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.py", "target": "socket"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.py", "target": "oqs"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.py", "target": "cryptography.hazmat.primitives.ciphers.aead"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.py", "target": "cryptography.hazmat.primitives"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.py", "target": "cryptography.hazmat.primitives.kdf.pbkdf2"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "client.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "secrets"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "pytz"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "flask_mail"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "clicksend_client"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "clicksend_client"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "clicksend_client.rest"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "models.plans"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "utils.mailer"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/auth.py", "target": "utils.security"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/contact.py", "target": "models.contact"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/contact.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "binascii"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "base64"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "secrets"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "dataclasses"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "models.deniable_vault"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/deniable_vault.py", "target": "utils.security"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/file.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/file.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/file.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/file.py", "target": "werkzeug.utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/file.py", "target": "boto3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/file.py", "target": "botocore.exceptions"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/message.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/message.py", "target": "models.message"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/message.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/message.py", "target": "uuid"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/message.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/sync.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/sync.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/sync.py", "target": "boto3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "controllers/sync.py", "target": "botocore.exceptions"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "archive/tar"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "compress/gzip"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "crypto/aes"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "crypto/cipher"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "crypto/rand"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "flag"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "fmt"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "io"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "path/filepath"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "strings"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "github.com/open-quantum-safe/liboqs-go/oqs"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "golang.org/x/crypto/pbkdf2"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.go", "target": "crypto/sha256"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "argparse"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "io"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "oqs"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "cryptography.hazmat.primitives.ciphers.aead"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "cryptography.hazmat.primitives.kdf.pbkdf2"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "cryptography.hazmat.primitives"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "boto3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "botocore.exceptions"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "enc_dec.py", "target": "pathlib"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "lol.py", "target": "base64"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "pydantic"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "sqlite3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "pytz"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/contact.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/deniable_vault.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/deniable_vault.py", "target": "sqlite3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/deniable_vault.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/deniable_vault.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "pydantic"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "glob"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "base64"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "uuid"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/message.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/plans.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/plans.py", "target": "sqlite3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/superadmin_audit.py", "target": "sqlite3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/superadmin_audit.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/superadmin_audit.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/user.py", "target": "pydantic"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/user.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/user.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/user.py", "target": "sqlite3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/user.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/user.py", "target": "pytz"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "models/user.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "pq_decrypt_password.py", "target": "argparse"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "pq_decrypt_password.py", "target": "utils.crypto"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/doctor.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/doctor.py", "target": "sys"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/doctor.py", "target": "importlib"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/email_tool.py", "target": "argparse"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/email_tool.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/email_tool.py", "target": "sys"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/email_tool.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/email_tool.py", "target": "flask_mail"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/email_tool.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/email_tool.py", "target": "utils.mailer"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/email_tool.py", "target": "utils.utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/makeadmin.py", "target": "argparse"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/makeadmin.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/makeadmin.py", "target": "sys"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/makeadmin.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/test_bloque1.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/test_bloque1.py", "target": "sys"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/test_bloque1.py", "target": "shutil"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/test_bloque1.py", "target": "re"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/test_bloque1.py", "target": "app"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/test_bloque1.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "scripts/test_bloque1.py", "target": "views.admin"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.go", "target": "crypto/aes"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.go", "target": "crypto/cipher"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.go", "target": "fmt"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.go", "target": "net"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.go", "target": "github.com/open-quantum-safe/liboqs-go/oqs"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.py", "target": "socket"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.py", "target": "oqs"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.py", "target": "cryptography.hazmat.primitives.ciphers.aead"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.py", "target": "cryptography.hazmat.primitives"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "server.py", "target": "cryptography.hazmat.primitives.kdf.pbkdf2"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/account.js", "target": "./qv-deniable.js"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "notes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "present"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "add"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "csrfToken"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "apiRequest"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "csrfToken"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "stringify"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "loadState"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "apiRequest"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "collectSlots"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "push"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "handleConfigure"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "preventDefault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "collectSlots"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "buildDeniableVault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "apiRequest"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "reset"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "error"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "handleOpen"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "preventDefault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "openDeniableVault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "handleReset"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "apiRequest"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "loadState"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "loadState"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/account.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "randomChar"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "floor"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "random"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "toUpperCase"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "animateElement"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "split"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "contains"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "map"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "join"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "timeline"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "floor"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "randomChar"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "querySelectorAll"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "forEach"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/coded-text.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/login.js", "target": "./qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "controller"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "handleLogin"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "preventDefault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "querySelector"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "querySelector"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "login"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "error"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/login.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/messages.js", "target": "./qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "controller"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "textContent"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "getCsrfToken"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "querySelector"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "handleSend"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "preventDefault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "sendSecureMessage"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "error"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "collectEnvelopes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "from"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "parse"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "push"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "envelope"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "handleDecryptInbox"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "collectEnvelopes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "prompt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "decryptInbox"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "forEach"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "error"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "initEditor"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "value"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "handleDecryptInbox"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "initEditor"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/messages.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/qv-crypto.js", "target": "./vendor/sha2.js"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/qv-crypto.js", "target": "./vendor/hkdf.js"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/qv-crypto.js", "target": "./vendor/ml_kem.js"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/qv-crypto.js", "target": "./vendor/ed25519.js"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "768"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "768"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "concatBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "reduce"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "set"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "hexToBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parseInt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "toString"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "padStart"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fromCharCode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "btoa"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase32"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "base64ToBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "atob"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "charCodeAt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBigInt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "i2osp"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "mod"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "return"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "modPow"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "mod"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "randomBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "min"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "getRandomValues"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "sha256"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBigInt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "vault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveKeyFromPassphrase"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "importKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveBits"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveMasterKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveKeyFromPassphrase"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmEncrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "importKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "randomBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "concatBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "importKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "slice"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "slice"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmEncrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "separate"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "module"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "computeK"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "i2osp"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveVerifier"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "srpLogin"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBigInt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "modPow"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "postJson"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "computeK"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "i2osp"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "modPow"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "map"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "i2osp"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "i2osp"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "postJson"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "hybrid"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "generateIdentity"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "keygen"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "keygen"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "keygen"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "encode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parsePublicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parse"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "decode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "base64ToBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "base64ToBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parsePrivateBlob"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parse"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "decode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "base64ToBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "base64ToBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveWrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "hkdf"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "encode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "wrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parsePublicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "encapsulate"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "keygen"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "getSharedSecret"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveWrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmEncrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "unwrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parsePrivateBlob"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parse"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "decode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "decapsulate"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "getSharedSecret"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveWrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "recovery"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "generateRecoveryCode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase32"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "push"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "join"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "normalizeRecoveryCode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "trim"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "toUpperCase"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "replace"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "wrapPrivateKeyForRecovery"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveMasterKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "key"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "innerSK"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "publicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "derivePublicKeyFromPrivateBlob"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "parsePrivateBlob"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "slice"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "getPublicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "postJson"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "endpoint"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "buildRegistration"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveVerifier"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "generateIdentity"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveMasterKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "generateRecoveryCode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "wrapPrivateKeyForRecovery"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "register"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "buildRegistration"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "postJson"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "recoverAccount"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveMasterKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "derivePublicKeyFromPrivateBlob"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveVerifier"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveMasterKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "postJson"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "login"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "srpLogin"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "encryptAndUpload"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "randomBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmEncrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "wrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "append"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "append"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "append"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "downloadAndDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveMasterKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "unwrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetchPublicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "return"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "recipient"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "sendSecureMessage"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "randomBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmEncrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetchPublicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "wrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetchPublicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "wrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "postJson"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "decryptInbox"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "deriveMasterKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "unwrapKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "aesGcmDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "push"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-crypto.js", "target": "push"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/qv-deniable.js", "target": "./qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "vault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "server"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "list"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "toBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "encode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "len"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "frame"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "randomBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "setUint32"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "set"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "frame"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "unframe"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "getUint32"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "slice"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "sealSlot"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "randomBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "deriveKeyFromPassphrase"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "aesGcmEncrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "slice"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "slice"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "bytesToHex"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "bytesToBase64"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "openSlot"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "deriveKeyFromPassphrase"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "base64ToBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "aesGcmDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "unframe"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "buildDeniableVault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "map"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "toBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "push"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "randomBytes"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "frame"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "push"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "openDeniableVault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "openSlot"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/qv-deniable.js", "target": "decode"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/recover.js", "target": "./qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "controller"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "recoverAccount"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "toggle"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "toggle"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "handleRecover"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "preventDefault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "querySelector"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "trim"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "trim"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "querySelector"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "recoverAccount"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "error"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "setStatus"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/recover.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/register.js", "target": "./qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "controller"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "showRecoveryCode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "resolve"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "remove"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "add"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "resolve"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "handleRegister"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "preventDefault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "fromEntries"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "querySelector"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "payload"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "buildRegistration"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "showRecoveryCode"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "error"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/register.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "static/js/upload.js", "target": "./qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "controller"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getCsrfToken"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "querySelector"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getUsername"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getPublicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "fetch"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getCsrfToken"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "json"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "handleUpload"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "preventDefault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getPublicKey"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "encryptAndUpload"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "reload"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "handleDownload"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "preventDefault"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "prompt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "downloadAndDecrypt"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "createObjectURL"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "createElement"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "appendChild"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "click"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "revokeObjectURL"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "remove"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "alert"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getElementById"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "handleUpload"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "getUsername"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "querySelectorAll"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "forEach"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "handleDownload"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "addEventListener"}, {"confidence": "EXTRACTED", "relation": "calls", "source": "static/js/upload.js", "target": "init"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "templates/terms.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/conftest.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/conftest.py", "target": "logging"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/conftest.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/conftest.py", "target": "sys"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/conftest.py", "target": "pytest"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/conftest.py", "target": "app_factory"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/conftest.py", "target": "utils.security"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_auth_phone.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "base64"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "copy"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "pytest"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "controllers.deniable_vault"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "models.deniable_vault"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_deniable_vault.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_security.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_security.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_security.py", "target": "flask_wtf.csrf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_security.py", "target": "utils.security"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_security.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_srp.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_srp.py", "target": "hashlib"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_srp.py", "target": "secrets"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "tests/test_srp.py", "target": "utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/cache.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/cache.py", "target": "redis"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/cache.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/mailer.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/mailer.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/mailer.py", "target": "flask_mail"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/plans.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "logging"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "pytz"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "apscheduler.schedulers.background"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "flask_mail"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "models.message"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/scheduler.py", "target": "utils.mailer"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "functools"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "hashlib"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "hmac"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "logging"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "secrets"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "time"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "uuid"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "flask_wtf.csrf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "wtforms"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/security.py", "target": "utils.utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/srp6a.py", "target": "hashlib"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/srp6a.py", "target": "hmac"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/srp6a.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/srp6a.py", "target": "secrets"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/srp6a.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/srp6a.py", "target": "redis"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/utils.py", "target": "json"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/utils.py", "target": "typing"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/utils.py", "target": "re"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/utils.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/utils.py", "target": "werkzeug.utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "utils/utils.py", "target": "dotenv"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/about.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/account.py", "target": "__future__"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/account.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/account.py", "target": "flask_limiter"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/account.py", "target": "flask_limiter.util"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/account.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/account.py", "target": "controllers.deniable_vault"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/account.py", "target": "models.deniable_vault"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/account.py", "target": "utils.security"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "models.plans"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "flask_wtf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "wtforms"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "wtforms.validators"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "flask_limiter"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "flask_limiter.util"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "auth"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "controllers.contact"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "models.superadmin_audit"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "secrets"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "datetime"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "pytz"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "utils.utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/admin.py", "target": "sqlite3"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "hmac"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "functools"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "flask_limiter"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "flask_limiter.util"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "flask_wtf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "flask_wtf.csrf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "wtforms"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "wtforms.validators"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "controllers.auth"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "controllers.contact"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "utils.mailer"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/auth.py", "target": "utils.security"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/faq.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/faq.py", "target": "models.plans"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "flask_wtf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "wtforms"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "wtforms.validators"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "flask_limiter"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "flask_limiter.util"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "auth"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/file.py", "target": "base64"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "controllers.message"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "flask_wtf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "wtforms"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "wtforms.validators"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "flask_limiter"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "flask_limiter.util"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "auth"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/message.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/privacy.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "models.plans"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "paypalrestsdk"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "flask_wtf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "wtforms"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "wtforms.validators"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "flask_limiter"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "flask_limiter.util"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/subscription.py", "target": "auth"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/sync.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/sync.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/sync.py", "target": "flask_limiter"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/sync.py", "target": "flask_limiter.util"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/sync.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/sync.py", "target": "werkzeug.utils"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/sync.py", "target": "utils.security"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/terms.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/views.py", "target": "flask"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/views.py", "target": "flask_login"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/views.py", "target": "flask_wtf"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/views.py", "target": "wtforms"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "views/views.py", "target": "models.user"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "wsgi.py", "target": "os"}, {"confidence": "EXTRACTED", "relation": "imports", "source": "wsgi.py", "target": "app_factory"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app.py", "target": "app_factory.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "controllers/file.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "controllers/sync.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/about.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/account.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/admin.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/auth.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/faq.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/file.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/message.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/privacy.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/sync.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/terms.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/views.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "app_factory.py", "target": "views/subscription.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/auth.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/auth.py", "target": "models/plans.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/auth.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/auth.py", "target": "utils/mailer.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/auth.py", "target": "utils/security.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/contact.py", "target": "models/contact.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/deniable_vault.py", "target": "models/deniable_vault.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/deniable_vault.py", "target": "utils/security.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/file.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/message.py", "target": "models/message.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "controllers/message.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "scripts/email_tool.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "scripts/email_tool.py", "target": "utils/mailer.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "scripts/email_tool.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "scripts/makeadmin.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "scripts/test_bloque1.py", "target": "app.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "scripts/test_bloque1.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "scripts/test_bloque1.py", "target": "views/admin.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/account.js", "target": "static/js/qv-deniable.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/login.js", "target": "static/js/qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/messages.js", "target": "static/js/qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/qv-crypto.js", "target": "static/js/register.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/qv-crypto.js", "target": "static/js/login.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/qv-deniable.js", "target": "static/js/qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/recover.js", "target": "static/js/qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/register.js", "target": "static/js/qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "static/js/upload.js", "target": "static/js/qv-crypto.js"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "tests/conftest.py", "target": "app_factory.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "tests/conftest.py", "target": "utils/security.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "tests/test_deniable_vault.py", "target": "controllers/deniable_vault.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "tests/test_deniable_vault.py", "target": "models/deniable_vault.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "tests/test_deniable_vault.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "tests/test_security.py", "target": "utils/security.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "tests/test_srp.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "utils/scheduler.py", "target": "models/message.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "utils/scheduler.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "utils/scheduler.py", "target": "utils/mailer.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "utils/security.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/account.py", "target": "controllers/deniable_vault.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/account.py", "target": "models/deniable_vault.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/account.py", "target": "utils/security.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/admin.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/admin.py", "target": "models/plans.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/admin.py", "target": "views/auth.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/admin.py", "target": "controllers/contact.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/admin.py", "target": "models/superadmin_audit.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/admin.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/auth.py", "target": "controllers/auth.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/auth.py", "target": "controllers/contact.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/auth.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/auth.py", "target": "utils/mailer.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/auth.py", "target": "utils/security.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/faq.py", "target": "models/plans.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/file.py", "target": "views/auth.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/message.py", "target": "controllers/message.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/message.py", "target": "views/auth.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/subscription.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/subscription.py", "target": "models/plans.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/subscription.py", "target": "views/auth.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/sync.py", "target": "utils/utils.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/sync.py", "target": "utils/security.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "views/views.py", "target": "models/user.py"}, {"confidence": "EXTRACTED", "relation": "resolved_imports", "source": "wsgi.py", "target": "app_factory.py"}], "generator": "readmenator", "metadata": {"edge_count": 2826, "file_count": 72, "language_count": 4, "symbol_count": 434}, "nodes": [{"id": "__init__.py", "kind": "module", "label": "__init__.py", "language": "py", "sha256": "d49aa57081b0bd6f", "symbol_count": 0, "symbols": []}, {"id": "app.py", "kind": "module", "label": "app.py", "language": "py", "sha256": "6a1b831f5e9cac11", "symbol_count": 2, "symbols": [{"kind": "function", "line": 21, "name": "main", "signature": "def main()"}, {"doc": "Return True if the runtime looks like a public-facing deployment.\n\nThe heuristic is intentionally conservative: any deployment with a\nnon-loopback bind address is treated as production. The Werkzeug\ndebugger is forbidden on those binds.", "kind": "function", "line": 58, "name": "_is_production_like", "signature": "def _is_production_like()"}]}, {"id": "app_factory.py", "kind": "module", "label": "app_factory.py", "language": "py", "sha256": "019d52475d730166", "symbol_count": 8, "symbols": [{"doc": "Return True unless the operator explicitly opts into dev mode.", "kind": "function", "line": 70, "name": "_is_production", "signature": "def _is_production()"}, {"doc": "Return the strict Content-Security-Policy used in production.\n\nThe policy allows:\n\n- ``'self'`` for everything by default\n- the JSDelivr CDN pinned to the specific packages the SPA needs\n (Bootstrap CSS, EasyMDE CSS/JS, marked). These are loaded with\n SRI from the templates.\n- ``'unsafe-inline'`` for styles is required because EasyMDE injects\n inline styles; for scripts it is forbidden.\n- WebAssembly is allowed (``'wasm-unsafe-eval'``) so the client can\n later compile liboqs-portable to WASM and avoid pure-JS PQ.\n\nAdding a new third-party origin to this list is a security review\ngate. Do not add origins without updating docs/SECURITY_TODO.md.", "kind": "function", "line": 81, "name": "_build_csp", "signature": "def _build_csp()"}, {"doc": "Return kwargs to pass to ``Talisman`` based on the runtime env.", "kind": "function", "line": 112, "name": "_build_talisman_kwargs", "signature": "def _build_talisman_kwargs()"}, {"doc": "Set ``app.config['SECRET_KEY']`` from env, payload.json, or a random value.\n\nThe previous code set a fresh 24-byte hex on every process start.\nThat is correct for development (sessions reset, no surprises) but\nin production the operator MUST set ``FLASK_SECRET_KEY`` (or\n``SECRET_KEY``) to a stable, 32+ byte value. Otherwise every\ngunicorn worker restart invalidates every session, including\nCSRF tokens, and the audit log will show a flood of CSRF rejections.\n\nFor backward compatibility, ``payload.json``'s ``SECRET_KEY`` is\naccepted as a third source so a project that was bootstrapped by\n``make env`` keeps working without a code change. The env var\nalways wins over ``payload.json`` so an operator can override.", "kind": "function", "line": 153, "name": "_configure_secret_key", "signature": "def _configure_secret_key(app, config)"}, {"doc": "Apply session lifetime and cookie hardening.\n\nThe defaults are deliberately conservative:\n\n- 8 hours of permanent session lifetime (then user must re-login)\n- 30 minutes of idle lifetime (rolling refresh on every request)\n- Cookies are HttpOnly, SameSite=Lax, and Secure in production", "kind": "function", "line": 196, "name": "_configure_session", "signature": "def _configure_session(app)"}, {"doc": "Wire up a structured application logger.\n\nThe Werkzeug access log goes through Flask's default handler at\nINFO. Application errors use the standard ``app.logger``. The\naudit logger (``quantumvault.audit``) is configured separately in\n:mod:`utils.security` and writes one-line JSON to stdout.", "kind": "function", "line": 213, "name": "_configure_logging", "signature": "def _configure_logging(app)"}, {"doc": "Build and return a fully-configured Flask application.\n\nArgs:\n config_overrides: Values to merge into ``app.config`` after\n defaults are applied. Useful for tests that need to swap\n the database path or disable the rate limiter.\n security_overrides: Values to merge into the Talisman kwargs.\n Used by tests to disable CSP and the HTTPS redirect without\n forking the whole factory.\n\nReturns:\n A Flask application ready to be served by gunicorn or the\n Werkzeug dev server.", "kind": "function", "line": 230, "name": "create_app", "signature": "def create_app(config_overrides, security_overrides)"}, {"kind": "function", "line": 408, "name": "load_user", "signature": "def load_user(user_id)"}]}, {"id": "client.go", "kind": "module", "label": "client.go", "language": "go", "sha256": "0fa0dc65ccec2be4", "symbol_count": 1, "symbols": [{"kind": "function", "line": 13, "name": "main", "signature": "func main("}]}, {"id": "client.py", "kind": "module", "label": "client.py", "language": "py", "sha256": "12ebaa00b85321ba", "symbol_count": 0, "symbols": []}, {"id": "controllers/__init__.py", "kind": "module", "label": "__init__.py", "language": "py", "sha256": "8e4c24fce4d70f9f", "symbol_count": 0, "symbols": []}, {"id": "controllers/auth.py", "kind": "module", "label": "auth.py", "language": "py", "sha256": "a490b4969f120259", "symbol_count": 14, "symbols": [{"doc": "Return the current time as a timezone-aware UTC datetime.\n\nAvoids the deprecated ``datetime.utcnow()`` which returns a naive\nvalue and triggers a DeprecationWarning in Python 3.12+.", "kind": "function", "line": 48, "name": "_now_utc", "signature": "def _now_utc()"}, {"doc": "Handles zero-knowledge registration and SRP-6a authentication.", "kind": "class", "line": 57, "name": "AuthController", "signature": "class AuthController"}, {"doc": "Initialize the controller.\n\nArgs:\n db_path: Path to the SQLite user database.\n mail: Configured Flask-Mail instance for transactional email.\n storage_uri: Redis URI backing the ephemeral SRP session store.", "kind": "method", "line": 60, "name": "__init__", "signature": "def __init__(self, db_path, mail, storage_uri)"}, {"doc": "Register a user from client-generated zero-knowledge credentials.\n\nArgs:\n username: The desired unique username.\n srp_salt: SRP salt (hex) generated on the client.\n srp_verifier: SRP verifier (hex) generated on the client.\n public_key: The user's hybrid public key blob (opaque).\n encrypted_private_key: The password-encrypted private key blob (opaque).\n kdf_salt: Salt (hex) for the client-side key derivation function.\n email: The user's email address.\n phone: The user's phone number.\n first_name: The user's first name.\n last_name: The user's last name.\n recovery_salt: Optional QV-RECOVERY-1 PBKDF2 salt (hex), generated on the client.\n encrypted_private_key_recovery: Optional QV-RECOVERY-1 AES-256-GCM\n wrapping of the same private key blob, keyed by a\n client-generated recovery code instead of the password.\n\nReturns:\n True on success, False if validation fails or persistence errors.", "kind": "method", "line": 75, "name": "register", "signature": "def register(self, username, srp_salt, srp_verifier, public_key, encrypted_private_key, kdf_salt, email, phone, first_name, last_name, recovery_salt, encrypted_private_key_recovery)"}, {"doc": "Email the account-confirmation link to a freshly registered user.\n\nThe link targets :func:`views.auth.confirm_email`. When SMTP is not\nconfigured, or the send fails, the link is logged at WARNING so an\noperator can still verify the account from the server logs; this keeps\nlocal and bare-VPS deployments usable before mail credentials exist.\n\nArgs:\n email: The recipient address.\n username: The account username (used for the greeting).\n token: The single-use confirmation token stored on the account.\n\nReturns:\n True if the mail server accepted the message, False otherwise.", "kind": "method", "line": 155, "name": "send_confirmation_email", "signature": "def send_confirmation_email(self, email, username, token)"}, {"doc": "Begin an SRP-6a login and return the salt and server challenge B.", "kind": "method", "line": 201, "name": "srp_hello", "signature": "def srp_hello(self, username, client_a_hex)"}, {"doc": "Complete an SRP-6a login and return the authenticated user and proof.", "kind": "method", "line": 220, "name": "srp_verify", "signature": "def srp_verify(self, username, client_m1_hex)"}, {"doc": "Send a verification code via SMS.", "kind": "method", "line": 252, "name": "send_sms_verification", "signature": "def send_sms_verification(self, phone, code, username)"}, {"doc": "Verify a phone verification code for a user.\n\nThe stored value is the peppered hash; the supplied code is\nhashed in the same way and the two digests are compared in\nconstant time.", "kind": "method", "line": 273, "name": "verify_phone_code", "signature": "def verify_phone_code(self, username, code)"}, {"doc": "Issue and send a fresh phone verification code.\n\nGenerates a new one-time code, stores its peppered hash with a\n30-minute expiry (overwriting any previous pending code), and\ndispatches it by SMS. Returns False when the account is unknown,\nhas no phone number, is already verified, or the SMS provider is\nnot configured, so the caller can surface an honest result.\n\nArgs:\n username: The account requesting a new code.\n\nReturns:\n True if a new code was generated, stored, and accepted by the\n SMS provider; False otherwise.", "kind": "method", "line": 309, "name": "resend_phone_code", "signature": "def resend_phone_code(self, username)"}, {"doc": "Return True if a verification code has not yet expired.", "kind": "method", "line": 348, "name": "_is_code_valid", "signature": "def _is_code_valid(self, expires_at)"}, {"doc": "Verify a multi-factor authentication code for a user.", "kind": "method", "line": 368, "name": "verify_mfa_code", "signature": "def verify_mfa_code(self, username, code)"}, {"doc": "Generate, store, and send an MFA code to the user's phone.", "kind": "method", "line": 392, "name": "send_mfa_code", "signature": "def send_mfa_code(self, username)"}, {"doc": "Enable or disable MFA for a user.", "kind": "method", "line": 415, "name": "toggle_mfa", "signature": "def toggle_mfa(self, username, enable)"}]}, {"id": "controllers/contact.py", "kind": "module", "label": "contact.py", "language": "py", "sha256": "2f6924b47953e9cf", "symbol_count": 4, "symbols": [{"doc": "Handles logic related to contact messages.", "kind": "class", "line": 4, "name": "ContactController", "signature": "class ContactController"}, {"doc": "Initialize the ContactController with the database path.\n\nArgs:\n db_path (str): Path to the SQLite database file.", "kind": "method", "line": 6, "name": "__init__", "signature": "def __init__(self, db_path)"}, {"doc": "Create a new contact message.\n\nArgs:\n user_id (int): ID of the user sending the message.\n subject (str): Subject of the message.\n message (str): Content of the message.\n\nReturns:\n bool: True if the message was created successfully, False otherwise.", "kind": "method", "line": 14, "name": "create_contact", "signature": "def create_contact(self, user_id, subject, message)"}, {"doc": "Retrieve all contact messages for a user.\n\nArgs:\n user_id (int): ID of the user.\n\nReturns:\n list[ContactModel]: List of contact messages.", "kind": "method", "line": 36, "name": "get_user_contacts", "signature": "def get_user_contacts(self, user_id)"}]}, {"id": "controllers/deniable_vault.py", "kind": "module", "label": "deniable_vault.py", "language": "py", "sha256": "55e81f6ade0d13ee", "symbol_count": 22, "symbols": [{"doc": "Return the length of the standard base64 encoding of ``byte_length`` bytes.", "kind": "function", "line": 81, "name": "_base64_length", "signature": "def _base64_length(byte_length)"}, {"doc": "Serialize an envelope deterministically for storage and sizing.\n\nKeys are sorted and separators are compact so the same logical\nenvelope always serializes to the same bytes. Both the size check in\n:class:`EnvelopeValidator` and the persistence path in\n:class:`DeniableVaultController` use this single function, so the\nbytes that are measured are exactly the bytes that are stored.\n\nArgs:\n envelope: The envelope mapping to serialize.\n\nReturns:\n The canonical JSON string.", "kind": "function", "line": 86, "name": "canonical_json", "signature": "def canonical_json(envelope)"}, {"doc": "Raised when an envelope violates a structural invariant.", "kind": "class", "line": 104, "name": "EnvelopeValidationError", "signature": "class EnvelopeValidationError(ValueError)"}, {"doc": "Return ``value`` coerced to int, falling back to ``default``.", "kind": "method", "line": 108, "name": "_coerce_int", "signature": "def _coerce_int(value, default)"}, {"doc": "Return an allow-list of KDF identifiers from a value.\n\nAccepts a comma-separated string (as found in environment variables)\nor any iterable of strings.", "kind": "method", "line": 118, "name": "_coerce_kdf", "signature": "def _coerce_kdf(value, default)"}, {"doc": "Immutable structural limits for a deniable vault container.", "kind": "class", "line": 134, "name": "DeniableVaultConfig", "signature": "class DeniableVaultConfig"}, {"doc": "Validate the structure of an opaque deniable vault envelope.\n\nThe validator never decrypts. It checks only the shape: the schema\nversion, the KDF identifier and iteration count, the exact slot count,\neach slot's hex and base64 fields, and the fixed ciphertext length\nthat makes every container identical in size.", "kind": "class", "line": 272, "name": "EnvelopeValidator", "signature": "class EnvelopeValidator"}, {"doc": "Coordinate validation, provisioning, persistence, and auditing.", "kind": "class", "line": 393, "name": "DeniableVaultController", "signature": "class DeniableVaultController"}, {"doc": "Build a config from a mapping, with environment overrides.\n\nResolution order for every field is: environment variable, then\n``mapping`` entry (e.g. ``app.config``), then the module default.\nDefaults are intentionally not written to ``payload.json`` so the\nrepository carries no per-deployment hint that the feature exists;\nan operator overrides them per-host via the environment.\n\nArgs:\n mapping: A mapping such as ``app.config``.\n env: Environment to read overrides from. Defaults to\n ``os.environ``; injectable for tests.\n\nReturns:\n The resolved, immutable configuration.", "kind": "method", "line": 148, "name": "from_mapping", "signature": "def from_mapping(cls, mapping, env)"}, {"doc": "Return the exact base64 length every slot ciphertext must have.\n\nA slot's ciphertext is the fixed plaintext length plus the GCM\ntag, base64-encoded. Fixing it makes every container byte-for-byte\nthe same shape.", "kind": "method", "line": 213, "name": "expected_ct_b64_length", "signature": "def expected_ct_b64_length(self)"}, {"doc": "Return a well-formed container filled with random, unopenable data.\n\nUsed to provision an account that has not activated the feature and\nto reset one. The result is structurally indistinguishable from an\nactivated container: random hex salts and nonces, and random\nbase64 ciphertext of exactly the expected length. No passphrase can\nopen it, which is the correct behavior for an unactivated vault.\n\nReturns:\n A fresh random envelope dict.", "kind": "method", "line": 222, "name": "random_container", "signature": "def random_container(self)"}, {"doc": "Return the parameters the browser needs to build a container.\n\nThe browser reads these instead of hard-coding them, so a change\nto the server policy propagates to clients without a code change.\nThe values are non-secret: they describe the container shape,\nwhich is identical for every account.", "kind": "method", "line": 250, "name": "public_parameters", "signature": "def public_parameters(self)"}, {"doc": "Bind the validator to a configuration.", "kind": "method", "line": 281, "name": "__init__", "signature": "def __init__(self, config)"}, {"doc": "Validate ``envelope``, raising on the first violation.\n\nArgs:\n envelope: The decoded JSON envelope to validate.\n\nRaises:\n EnvelopeValidationError: If any structural invariant is\n violated. The message names the violated invariant and\n never echoes ciphertext.", "kind": "method", "line": 285, "name": "validate", "signature": "def validate(self, envelope)"}, {"doc": "Validate a single slot.\n\nArgs:\n index: The slot's position, used only in error messages.\n slot: The slot mapping to validate.\n\nRaises:\n EnvelopeValidationError: If the slot is malformed or its\n ciphertext is not the fixed expected length.", "kind": "method", "line": 339, "name": "_validate_slot", "signature": "def _validate_slot(self, index, slot)"}, {"doc": "Validate that ``value`` is hex of exactly ``expected_length``.\n\nRaises:\n EnvelopeValidationError: If the value is not a hex string of\n the expected length.", "kind": "method", "line": 376, "name": "_validate_hex", "signature": "def _validate_hex(value, expected_length, index, field)"}, {"doc": "Initialize the controller.\n\nArgs:\n db: The opaque container store.\n config: The structural limits in force.\n validator: The validator to use. Defaults to one bound to\n ``config``; injectable for tests.", "kind": "method", "line": 401, "name": "__init__", "signature": "def __init__(self, db, config, validator)"}, {"doc": "Return ``username``'s container, minting a random one if absent.\n\nThe mint-on-read behavior is what makes \"has a container\"\nuniversal: any account that has ever opened its settings has an\nindistinguishable container, so the mere existence of one is not\nevidence of a hidden vault.\n\nArgs:\n username: The owning account.\n\nReturns:\n The decoded envelope, always present.", "kind": "method", "line": 419, "name": "load_or_provision", "signature": "def load_or_provision(self, username)"}, {"doc": "Validate and persist a container for ``username``.\n\nArgs:\n username: The owning account.\n envelope: The decoded JSON envelope from the client.\n\nRaises:\n EnvelopeValidationError: If the envelope is structurally\n invalid; nothing is persisted in that case.", "kind": "method", "line": 441, "name": "save", "signature": "def save(self, username, envelope)"}, {"doc": "Overwrite ``username``'s container with a fresh random one.\n\nReset replaces rather than deletes: removing the row would leave a\ngap that distinguishes a user who deactivated from one who never\nactivated. A random container keeps existence universal.\n\nArgs:\n username: The owning account.\n\nReturns:\n The new random envelope.", "kind": "method", "line": 456, "name": "reset", "signature": "def reset(self, username)"}, {"doc": "Return True if ``username`` already has a stored container.", "kind": "method", "line": 474, "name": "exists", "signature": "def exists(self, username)"}, {"kind": "method", "line": 171, "name": "read", "signature": "def read(key)"}]}, {"id": "controllers/file.py", "kind": "module", "label": "file.py", "language": "py", "sha256": "6a9b9231e327627c", "symbol_count": 9, "symbols": [{"doc": "Log a failed S3 operation without raising further.", "kind": "function", "line": 26, "name": "_log_s3_error", "signature": "def _log_s3_error(operation, error)"}, {"doc": "Return a filename safe to embed in an S3 key.\n\nApplies :func:`werkzeug.utils.secure_filename` to strip any path\ncomponents and control characters, then rejects any residual\nshell-meta characters and NUL bytes. Returns an empty string\nfor empty/None input.", "kind": "function", "line": 31, "name": "safe_filename", "signature": "def safe_filename(name)"}, {"doc": "Persistence for end-to-end encrypted files and their wrapped FEKs.", "kind": "class", "line": 49, "name": "FileController", "signature": "class FileController"}, {"kind": "method", "line": 52, "name": "__init__", "signature": "def __init__(self, users_path, s3_bucket, s3_client)"}, {"doc": "Build the S3 key for a user's encrypted file or FEK.\n\nThe username is the server's truth (it came from the\nauthenticated session), so it does not need additional\nvalidation. The filename is expected to have been normalized\nvia :func:`safe_filename` by the caller.", "kind": "method", "line": 57, "name": "_key", "signature": "def _key(self, username, filename, suffix)"}, {"doc": "Sum the bytes used by ``username``'s encrypted files in S3.", "kind": "method", "line": 69, "name": "get_storage_usage", "signature": "def get_storage_usage(self, username)"}, {"doc": "Persist an already-encrypted file and its wrapped FEK to S3.", "kind": "method", "line": 83, "name": "upload_encrypted_file", "signature": "def upload_encrypted_file(self, username, file_storage, wrapped_fek)"}, {"doc": "Fetch a user's encrypted file and its wrapped FEK from S3.\n\nReturns:\n A 3-tuple of ``(ciphertext, wrapped_fek, error)``. On success\n ``error`` is ``None``; on failure it contains a human-readable\n reason and the byte values are ``None``.", "kind": "method", "line": 107, "name": "get_encrypted_file_and_key", "signature": "def get_encrypted_file_and_key(self, username, filename)"}, {"doc": "List the encrypted files that belong to ``username``.", "kind": "method", "line": 137, "name": "list_encrypted_files", "signature": "def list_encrypted_files(self, username)"}]}, {"id": "controllers/message.py", "kind": "module", "label": "message.py", "language": "py", "sha256": "98fd349c05ee9825", "symbol_count": 4, "symbols": [{"doc": "Handles message persistence in the zero-knowledge flow.", "kind": "class", "line": 15, "name": "MessageController", "signature": "class MessageController"}, {"doc": "Initialize the controller.\n\nArgs:\n users_path: Base directory under which each user has a\n ``messages/`` subdirectory.\n users_db_path: Path to the SQLite user database, used to verify\n that a message recipient is a registered account.", "kind": "method", "line": 18, "name": "__init__", "signature": "def __init__(self, users_path, users_db_path)"}, {"doc": "Persist an opaque message envelope for the recipient.\n\nArgs:\n sender: Sender's username.\n recipient: Recipient's username.\n encrypted_message_b64: AES-256-GCM ciphertext (base64) of the\n message body, with the IV prepended by the browser.\n cek_for_recipient: Hybrid-wrapped CEK to the recipient's public\n key (base64 JSON from qv-crypto).\n cek_for_sender: Hybrid-wrapped CEK to the sender's public key\n (so the outbox copy is readable).\n\nReturns:\n True on success, False otherwise.", "kind": "method", "line": 31, "name": "send_encrypted_message", "signature": "def send_encrypted_message(self, sender, recipient, encrypted_message_b64, cek_for_recipient, cek_for_sender)"}, {"doc": "Return opaque message envelopes for the user.\n\nThe browser unwraps each CEK with the user's private blob; the\nserver only returns the opaque envelopes.\n\nArgs:\n username: User whose mailbox to read.\n page: 1-indexed page number.\n per_page: Messages per page.\n\nReturns:\n A tuple ``(messages, total_pages)`` of opaque messages.", "kind": "method", "line": 73, "name": "get_messages", "signature": "def get_messages(self, username, page, per_page)"}]}, {"doc": "controllers/sync.py", "id": "controllers/sync.py", "kind": "module", "label": "sync.py", "language": "py", "sha256": "95b000a830b9ff47", "symbol_count": 3, "symbols": [{"kind": "class", "line": 7, "name": "SyncController", "signature": "class SyncController"}, {"kind": "method", "line": 8, "name": "__init__", "signature": "def __init__(self, users_path, s3_bucket, s3_client, file_controller)"}, {"doc": "Calcula el uso de almacenamiento del usuario en S3.", "kind": "method", "line": 14, "name": "get_storage_usage", "signature": "def get_storage_usage(self, username)"}]}, {"id": "enc_dec.go", "kind": "module", "label": "enc_dec.go", "language": "go", "sha256": "392403d8bf14ea26", "symbol_count": 4, "symbols": [{"kind": "function", "line": 20, "name": "deriveAESKey", "signature": "func deriveAESKey("}, {"kind": "function", "line": 24, "name": "encryptFile", "signature": "func encryptFile("}, {"kind": "function", "line": 45, "name": "decryptFile", "signature": "func decryptFile("}, {"kind": "function", "line": 69, "name": "main", "signature": "func main("}]}, {"id": "enc_dec.py", "kind": "module", "label": "enc_dec.py", "language": "py", "sha256": "89bde689095c84ba", "symbol_count": 5, "symbols": [{"doc": "Derive a 32-byte AES key from an ML-KEM shared secret.\n\nArgs:\n shared_secret: The raw shared secret bytes from ``KeyEncapsulation``.\n\nReturns:\n A 32-byte AES-256 key suitable for use with :class:`AESGCM`.", "kind": "function", "line": 36, "name": "derive_aes_key", "signature": "def derive_aes_key(shared_secret)"}, {"doc": "Encrypt ``data`` in memory with AES-256-GCM and return nonce + ciphertext.\n\nArgs:\n data: The plaintext bytes to encrypt.\n aes_key: The 32-byte AES key.\n\nReturns:\n A tuple ``(nonce, ciphertext)`` where ``nonce`` is 12 random bytes.", "kind": "function", "line": 49, "name": "encrypt_file_in_memory", "signature": "def encrypt_file_in_memory(data, aes_key)"}, {"doc": "Decrypt ``ciphertext`` in memory with AES-256-GCM and return the plaintext.\n\nArgs:\n nonce: The 12-byte nonce from the encrypt step.\n ciphertext: The encrypted bytes.\n aes_key: The 32-byte AES key.\n\nReturns:\n The original plaintext bytes.", "kind": "function", "line": 65, "name": "decrypt_file_in_memory", "signature": "def decrypt_file_in_memory(nonce, ciphertext, aes_key)"}, {"doc": "Build a boto3 S3 client honoring the zero-trust environment convention.\n\nArgs:\n region: The region name (overrides ``S3_REGION`` for this call).\n\nReturns:\n A configured ``boto3.client('s3')`` instance.", "kind": "function", "line": 81, "name": "_build_s3_client", "signature": "def _build_s3_client(region)"}, {"doc": "Run the offline admin CLI (encrypt or decrypt a single object).", "kind": "function", "line": 103, "name": "main", "signature": "def main()"}]}, {"doc": "install.sh: Script para instalar prerrequisitos y compilar el proyecto postcuantum Fecha: 26 de junio de 2025 Autor: Grok 3 (xAI)", "id": "install.sh", "kind": "module", "label": "install.sh", "language": "sh", "sha256": "c907d80fd6734993", "symbol_count": 0, "symbols": []}, {"id": "lol.py", "kind": "module", "label": "lol.py", "language": "py", "sha256": "3e3ea327c4195c9c", "symbol_count": 0, "symbols": []}, {"id": "make.sh", "kind": "module", "label": "make.sh", "language": "sh", "sha256": "6b19313760683dc6", "symbol_count": 0, "symbols": []}, {"id": "models/__init__.py", "kind": "module", "label": "__init__.py", "language": "py", "sha256": "95bdfaea458995a4", "symbol_count": 0, "symbols": []}, {"id": "models/contact.py", "kind": "module", "label": "contact.py", "language": "py", "sha256": "e61cfbd31022bbc2", "symbol_count": 9, "symbols": [{"doc": "Pydantic model for a contact message.\n\nAttributes:\n id: Unique contact ID.\n user_id: ID of the user who sent the message.\n subject: Subject of the contact message.\n message: Content of the contact message.\n created_at: Timestamp when the message was created.\n status: Status of the message (e.g. 'pending', 'resolved').", "kind": "class", "line": 8, "name": "ContactModel", "signature": "class ContactModel(BaseModel)"}, {"doc": "Database operations for contact messages.", "kind": "class", "line": 26, "name": "ContactDB", "signature": "class ContactDB"}, {"doc": "Initialize the ContactDB with the database path.\n\nArgs:\n db_path: Path to the SQLite database file.", "kind": "method", "line": 29, "name": "__init__", "signature": "def __init__(self, db_path)"}, {"doc": "Initialize the contacts table with all required fields.", "kind": "method", "line": 38, "name": "_init_db", "signature": "def _init_db(self)"}, {"doc": "Create a new contact message.\n\nArgs:\n user_id: ID of the user sending the message.\n subject: Subject of the message.\n message: Content of the message.\n\nReturns:\n True on success, False if validation fails or the DB write fails.", "kind": "method", "line": 52, "name": "create_contact", "signature": "def create_contact(self, user_id, subject, message)"}, {"doc": "Retrieve all contact messages for a user.\n\nArgs:\n user_id: ID of the user.\n\nReturns:\n List of contact message dictionaries, newest first. On DB\n error, returns an empty list and logs the failure.", "kind": "method", "line": 89, "name": "get_user_contacts", "signature": "def get_user_contacts(self, user_id)"}, {"doc": "Convert an SQLite row to a dictionary.\n\nArgs:\n row: SQLite row.\n\nReturns:\n Contact data as a dictionary.", "kind": "method", "line": 115, "name": "_convert_row_to_dict", "signature": "def _convert_row_to_dict(self, row)"}, {"doc": "Retrieve all contact messages with pagination.\n\nArgs:\n page: 1-based page number.\n per_page: Number of contacts per page.\n\nReturns:\n ``(rows, total_count)``. ``rows`` may be empty on DB error.", "kind": "method", "line": 139, "name": "get_all_contacts", "signature": "def get_all_contacts(self, page, per_page)"}, {"doc": "Convert an SQLite row to a dictionary, including username.", "kind": "method", "line": 168, "name": "_convert_row_to_dict_with_username", "signature": "def _convert_row_to_dict_with_username(self, row)"}]}, {"id": "models/deniable_vault.py", "kind": "module", "label": "deniable_vault.py", "language": "py", "sha256": "21c36a0304dee37e", "symbol_count": 6, "symbols": [{"doc": "Persistence for per-user opaque deniable vault containers.", "kind": "class", "line": 30, "name": "DeniableVaultDB", "signature": "class DeniableVaultDB"}, {"doc": "Initialize the store and ensure its table exists.\n\nArgs:\n db_path: Path to the SQLite database file, shared with\n :class:`models.user.UserDB`.", "kind": "method", "line": 33, "name": "__init__", "signature": "def __init__(self, db_path)"}, {"doc": "Create the ``deniable_vaults`` table on first use.", "kind": "method", "line": 43, "name": "_init_db", "signature": "def _init_db(self)"}, {"doc": "Insert or replace the container for ``username``.\n\nThe whole container is replaced atomically: a deniable vault has\nno partial state, so a replace is always a full rewrite of the\nopaque envelope.\n\nArgs:\n username: The owning account's username.\n envelope: The opaque container text to store verbatim.", "kind": "method", "line": 57, "name": "upsert", "signature": "def upsert(self, username, envelope)"}, {"doc": "Return the stored container for ``username``, or ``None``.\n\nArgs:\n username: The account to look up.\n\nReturns:\n A dict with ``username``, ``envelope``, and ``updated_at``,\n or ``None`` when the account has no container.", "kind": "method", "line": 82, "name": "get", "signature": "def get(self, username)"}, {"doc": "Return True if ``username`` has a stored container.", "kind": "method", "line": 101, "name": "exists", "signature": "def exists(self, username)"}]}, {"id": "models/message.py", "kind": "module", "label": "message.py", "language": "py", "sha256": "d0c2dcf76191f54c", "symbol_count": 6, "symbols": [{"doc": "Pydantic model for a stored message envelope.\n\nAttributes:\n id (Optional[str]): Message ID.\n sender (str): Sender username.\n message (str): Display text. With ZK messages this is the opaque\n payload returned to the client (the browser decrypts it).\n timestamp (Optional[datetime]): When the message was stored.", "kind": "class", "line": 27, "name": "MessageModel", "signature": "class MessageModel(BaseModel)"}, {"doc": "File-based operations for end-to-end encrypted messages.", "kind": "class", "line": 43, "name": "MessageDB", "signature": "class MessageDB"}, {"doc": "Initialize the MessageDB with the base directory for per-user mailboxes.\n\nArgs:\n base_path (str): Filesystem path under which each user has a\n ``messages/`` subdirectory.", "kind": "method", "line": 46, "name": "__init__", "signature": "def __init__(self, base_path)"}, {"doc": "Persist an opaque message envelope for the recipient.\n\nArgs:\n recipient (str): Recipient username.\n sender (str): Sender username.\n encrypted_message_b64 (str): AES-256-GCM(CEK, plaintext) as base64\n (IV prepended by the browser).\n cek_for_recipient (str): Hybrid-wrapped CEK to the recipient's\n public key (base64-encoded JSON from qv-crypto).\n cek_for_sender (str): Hybrid-wrapped CEK to the sender's public\n key (so the outbox copy is readable).\n message_id (str): Unique message ID.", "kind": "method", "line": 55, "name": "save_message", "signature": "def save_message(self, recipient, sender, encrypted_message_b64, cek_for_recipient, cek_for_sender, message_id)"}, {"doc": "Return opaque message envelopes for the recipient.\n\nThe browser unwraps the CEK with the user's private blob. This\nmethod never derives any key material.\n\nArgs:\n recipient (str): Username whose mailbox to read.\n page (int): 1-indexed page number.\n per_page (int): Messages per page.\n\nReturns:\n A tuple ``(messages, total_pages)`` where each message is\n opaque; the ``message`` field carries the JSON envelope\n ``{encrypted_message_b64, cek_for_recipient, cek_for_sender}``\n so the browser can decrypt it.", "kind": "method", "line": 87, "name": "get_messages", "signature": "def get_messages(self, recipient, page, per_page)"}, {"doc": "Delete messages older than ``days`` days from the recipient's mailbox.\n\nArgs:\n recipient (str): Username whose mailbox to prune.\n days (int): Age threshold in days; older messages are removed.", "kind": "method", "line": 172, "name": "delete_old_messages", "signature": "def delete_old_messages(self, recipient, days)"}]}, {"id": "models/plans.py", "kind": "module", "label": "plans.py", "language": "py", "sha256": "b39dfc7604a9fa06", "symbol_count": 10, "symbols": [{"doc": "Database operations for subscription plans.", "kind": "class", "line": 4, "name": "PlanDB", "signature": "class PlanDB"}, {"doc": "Initialize the PlanDB with the database path.\n\nArgs:\n db_path (str): Path to the SQLite database file.", "kind": "method", "line": 6, "name": "__init__", "signature": "def __init__(self, db_path)"}, {"doc": "Initialize the plans table with required fields.", "kind": "method", "line": 15, "name": "_init_db", "signature": "def _init_db(self)"}, {"doc": "Retrieve a plan by name.\n\nArgs:\n plan_name (str): Name of the plan to search for.\n\nReturns:\n Optional[Dict]: Plan data as a dictionary or None if not found.", "kind": "method", "line": 37, "name": "get_plan", "signature": "def get_plan(self, plan_name)"}, {"doc": "Retrieve all plans.\n\nReturns:\n List[Dict]: List of dictionaries containing plan data.", "kind": "method", "line": 50, "name": "get_all_plans", "signature": "def get_all_plans(self)"}, {"doc": "Create a new plan.\n\nArgs:\n name (str): Name of the plan.\n storage_quota (int): Storage quota in bytes.\n trial_days (int): Number of trial days.\n price (float): Price of the plan.", "kind": "method", "line": 60, "name": "create_plan", "signature": "def create_plan(self, name, storage_quota, trial_days, price)"}, {"doc": "Update an existing plan.\n\nArgs:\n name (str): Name of the plan to update.\n storage_quota (Optional[int]): New storage quota in bytes.\n trial_days (Optional[int]): New number of trial days.\n price (Optional[float]): New price of the plan.", "kind": "method", "line": 78, "name": "update_plan", "signature": "def update_plan(self, name, storage_quota, trial_days, price)"}, {"doc": "Delete a plan by name.\n\nArgs:\n name (str): Name of the plan to delete.", "kind": "method", "line": 113, "name": "delete_plan", "signature": "def delete_plan(self, name)"}, {"doc": "Convert an SQLite row to a dictionary.", "kind": "method", "line": 127, "name": "_convert_row_to_dict", "signature": "def _convert_row_to_dict(self, row)"}, {"doc": "Validate that the paid amount matches the plan price.\n\nArgs:\n plan_name (str): Name of the plan.\n amount_paid (float): Amount paid.\n\nReturns:\n bool: True if the amount matches the plan price within tolerance.", "kind": "method", "line": 139, "name": "validate_plan_payment", "signature": "def validate_plan_payment(self, plan_name, amount_paid)"}]}, {"id": "models/superadmin_audit.py", "kind": "module", "label": "superadmin_audit.py", "language": "py", "sha256": "304d2be2b4bcb78d", "symbol_count": 5, "symbols": [{"doc": "Database operations for the superadmin audit log.", "kind": "class", "line": 32, "name": "SuperadminAuditDB", "signature": "class SuperadminAuditDB"}, {"doc": "Initialize the audit log and ensure its table exists.\n\nArgs:\n db_path: Path to the SQLite database file (shared with\n ``UserDB`` so the two are backed up together).", "kind": "method", "line": 35, "name": "__init__", "signature": "def __init__(self, db_path)"}, {"doc": "Create the audit table on first use; no-op if it already exists.", "kind": "method", "line": 45, "name": "_init_db", "signature": "def _init_db(self)"}, {"doc": "Append one audit row and return its id.\n\nThe timestamp is generated server-side in UTC so two operators\nin different timezones can correlate a single incident. The\nreturn value is the new row's primary key, useful for tests\nand for linking related log lines in the response.\n\nArgs:\n actor: Username of the superadmin performing the action.\n action: Short verb-noun identifier (e.g. ``reset_mfa``,\n ``resend_confirmation``, ``toggle_suspend``).\n target_user: Username the action was applied to, or None\n for global actions (none today, kept for future use).\n ip: Remote address that issued the request. ``None`` when\n the request did not carry one (e.g. background job).\n details: Free-text context, kept short. Use it for the\n state transition (e.g. ``active->inactive``) not for\n payloads that should never leave the audit log.\n\nReturns:\n The new row's ``id``.", "kind": "method", "line": 75, "name": "record", "signature": "def record(self, actor, action, target_user, ip, details)"}, {"doc": "Return the most recent ``limit`` audit rows, newest first.\n\nArgs:\n limit: Maximum rows to return. Capped at 500 to bound\n template rendering cost on a noisy superadmin.\n\nReturns:\n List of dicts with keys ``id``, ``ts``, ``actor``,\n ``action``, ``target_user``, ``ip``, ``details``.", "kind": "method", "line": 119, "name": "recent", "signature": "def recent(self, limit)"}]}, {"id": "models/user.py", "kind": "module", "label": "user.py", "language": "py", "sha256": "108bcc05840884d2", "symbol_count": 27, "symbols": [{"doc": "Pydantic model for a user with Flask-Login support.\n\nAttributes:\n id: Unique user ID.\n username: Unique username.\n role: User role (free, bronze, silver, gold, admin, superadmin).\n email: User's email address.\n phone: User's phone number.\n first_name: User's first name.\n last_name: User's last name.\n storage_quota: Storage quota in bytes.\n trial_start: Trial period start date.\n trial_end: Trial period end date.\n subscription_status: Subscription status (active, inactive).\n email_verified: Whether the email is verified.\n confirmation_token: Email confirmation token.\n phone_verified: Whether the phone number is verified.\n phone_verification_code_hash: Peppered hash of the phone verification code.\n phone_code_expires: Phone verification code expiration.\n mfa_code_hash: Peppered hash of the current MFA code.\n mfa_code_expires: MFA code expiration.\n mfa_enabled: Whether MFA is enabled for the user.", "kind": "class", "line": 8, "name": "UserModel", "signature": "class UserModel(BaseModel, UserMixin)"}, {"doc": "Database operations for users.", "kind": "class", "line": 83, "name": "UserDB", "signature": "class UserDB"}, {"doc": "Return the user ID as a string (required by Flask-Login).\n\nReturns:\n str: The user ID as a string, or an empty string when the\n user is anonymous.", "kind": "method", "line": 52, "name": "get_id", "signature": "def get_id(self)"}, {"doc": "Return True while the user can use the application.\n\nInactive (lapsed-subscription) users can still sign in to renew\nor download their data, so we do NOT tie this to\n``subscription_status``. The previous implementation returned\nFalse for inactive users, which logged them out of every\n@login_required route. Subscription-gated features should\ncheck ``subscription_status`` directly in the view that needs\nthe gate, not via Flask-Login's activation hook.", "kind": "method", "line": 70, "name": "is_active", "signature": "def is_active(self)"}, {"doc": "Initialize the UserDB with the database path.\n\nArgs:\n db_path (str): Path to the SQLite database file.", "kind": "method", "line": 85, "name": "__init__", "signature": "def __init__(self, db_path)"}, {"doc": "Initialize the users table with all fields for zero-knowledge auth.\n\nThe table stores only zero-knowledge credential material: the SRP salt\nand verifier (the password itself is never received), the user's public\nkey, the password-encrypted private key blob, and the key-derivation\nsalt used to protect that blob. The server can decrypt none of it.\n\nPhone verification codes and MFA codes are stored as peppered\nSHA-256 digests (``*_code_hash`` columns) instead of plaintext so\na database dump does not hand an attacker ready-to-use codes.\n\nThe ``phone`` column is not unique: phone numbers are recycled by\ncarriers and SIM-swap attacks invalidate the uniqueness guarantee\nanyway. ``email`` remains unique because it is the primary\nrecovery identity.\n\nIf the table was created by an older v7 schema (which carried\nNOT NULL KEM blob columns the v8 controller never writes),\nmigrate in place: rebuild the table under the v8 shape and preserve\nthe surviving identity columns. The legacy password blobs are\nintentionally dropped: v7 ciphertexts are useless without the\nmatching v7 KEM code path that has been removed.", "kind": "method", "line": 105, "name": "_init_db", "signature": "def _init_db(self)"}, {"doc": "Return True if the ``users.phone`` column is UNIQUE.\n\nSQLite does not expose UNIQUE column constraints via ``PRAGMA\ntable_info``; the only reliable signal is the auto-index that\nSQLite materialises for any ``UNIQUE`` column (``sqlite_autoindex_users_N``).", "kind": "method", "line": 193, "name": "_has_phone_unique_constraint", "signature": "def _has_phone_unique_constraint(self)"}, {"doc": "Remove the UNIQUE constraint on ``users.phone``.\n\nThe v7 schema declared ``phone TEXT UNIQUE``. Carriers recycle\nnumbers, so the uniqueness guarantee is illusory; it also makes\naccount recovery hostile when a number changes hands.\n\nSQLite forbids ``DROP INDEX`` on an auto-index backing a UNIQUE\ncolumn, so we have to rebuild the table. The rebuild follows\nthe same shape as :meth:`_migrate_from_v7` but copies every\ncolumn by position (the schema is now already v8-shaped thanks\nto the prior migration step, so we know the column order).", "kind": "method", "line": 214, "name": "_drop_phone_unique_if_present", "signature": "def _drop_phone_unique_if_present(self)"}, {"doc": "Rebuild the users table to drop legacy v7 NOT NULL KEM columns.\n\nSQLite cannot drop a column or relax a NOT NULL constraint in place,\nso we rename the old table, create a fresh v8-shaped users table,\ncopy every surviving column, then drop the renamed legacy table.", "kind": "method", "line": 271, "name": "_migrate_from_v7", "signature": "def _migrate_from_v7(self, legacy_columns)"}, {"doc": "Persist a new user from client-provided zero-knowledge credentials.\n\nAll cryptographic material (salt, verifier, public key, encrypted\nprivate key, KDF salt) is generated on the client; this method only\nstores opaque values and never derives or sees the password.\nPhone and MFA codes are stored as the peppered hash supplied by\nthe controller; the plaintext only ever lives in the SMS that\nleaves the building.\n\n``recovery_salt`` and ``encrypted_private_key_recovery`` are the\nQV-RECOVERY-1 fields: an independent PBKDF2 salt and AES-256-GCM\nwrapping of the same ``privateBlob``, keyed by a client-generated\nhigh-entropy recovery code instead of the account password. Both\nare optional so older clients that do not yet generate a recovery\ncode can still register.", "kind": "method", "line": 325, "name": "create_user", "signature": "def create_user(self, username, srp_salt, srp_verifier, public_key, encrypted_private_key, kdf_salt, email, phone, first_name, last_name, role, storage_quota, trial_start, trial_end, subscription_status, email_verified, confirmation_token, phone_verified, phone_verification_code_hash, phone_code_expires, mfa_enabled, recovery_salt, encrypted_private_key_recovery)"}, {"doc": "Update phone verification status and related fields.\n\nThe ``phone_verification_code_hash`` parameter accepts the\npeppered SHA-256 digest. Passing ``None`` clears the stored\nhash (e.g. after the user verifies successfully).", "kind": "method", "line": 362, "name": "update_user_phone_status", "signature": "def update_user_phone_status(self, username, phone_verified, phone_verification_code_hash, phone_code_expires)"}, {"doc": "Update MFA code, expiration, and enabled status.\n\nThe ``mfa_code_hash`` parameter accepts the peppered SHA-256\ndigest of the freshly-generated 6-digit code. ``mfa_enabled`` is\na tri-state: ``None`` leaves the value alone.", "kind": "method", "line": 396, "name": "update_user_mfa_status", "signature": "def update_user_mfa_status(self, username, mfa_code_hash, mfa_code_expires, mfa_enabled)"}, {"doc": "Update specific user fields.", "kind": "method", "line": 430, "name": "update_user", "signature": "def update_user(self, username, email_verified, confirmation_token)"}, {"doc": "Retrieve a user by username.\n\nArgs:\n username (str): Username to search for.\n\nReturns:\n Optional[dict]: User data as a dictionary or None if not found.", "kind": "method", "line": 454, "name": "get_user", "signature": "def get_user(self, username)"}, {"doc": "Retrieve a user by ID.\n\nArgs:\n user_id (int): ID of the user to search for.\n\nReturns:\n Optional[dict]: User data as a dictionary or None if not found.", "kind": "method", "line": 468, "name": "get_user_by_id", "signature": "def get_user_by_id(self, user_id)"}, {"doc": "Retrieve a user by email address.\n\nArgs:\n email (str): Email address to search for.\n\nReturns:\n Optional[dict]: User data as a dictionary or None if not found.", "kind": "method", "line": 482, "name": "get_user_by_email", "signature": "def get_user_by_email(self, email)"}, {"doc": "Retrieve a user by phone number.\n\nArgs:\n phone (str): Phone number to search for.\n\nReturns:\n Optional[dict]: User data as a dictionary or None if not found.", "kind": "method", "line": 496, "name": "get_user_by_phone", "signature": "def get_user_by_phone(self, phone)"}, {"doc": "Retrieve a user by confirmation token.\n\nArgs:\n token (str): Confirmation token to search for.\n\nReturns:\n Optional[dict]: User data as a dictionary or None if not found.", "kind": "method", "line": 510, "name": "get_user_by_confirmation_token", "signature": "def get_user_by_confirmation_token(self, token)"}, {"doc": "Return the QV-RECOVERY-1 bundle for a username, if one exists.\n\nArgs:\n username (str): Username to look up.\n\nReturns:\n A dict with ``recovery_salt``, ``encrypted_private_key_recovery``,\n and ``public_key`` if the account has a recovery bundle\n configured, or ``None`` if the account does not exist or has\n not generated a recovery code (e.g. accounts created before\n QV-RECOVERY-1 was added).", "kind": "method", "line": 524, "name": "get_recovery_bundle", "signature": "def get_recovery_bundle(self, username)"}, {"doc": "Replace a user's password-derived credentials after a verified recovery.\n\nCalled only after the caller has verified ``public_key_proof``\nagainst the stored ``public_key`` (proof that the requester\npossesses the recovery code, since it is the only way to recover\nthe matching ``privateBlob`` and re-derive the public key). The\n``public_key`` and the underlying keypair are unchanged; only the\nSRP verifier and the password-wrapping of the existing private key\nblob are replaced.\n\nArgs:\n username (str): Username whose credentials are being reset.\n srp_salt (str): New SRP salt, hex-encoded.\n srp_verifier (str): New SRP verifier, hex-encoded.\n kdf_salt (str): New PBKDF2 salt for the password-wrapped private key, hex-encoded.\n encrypted_private_key (str): The same private key blob, re-wrapped under the new password.", "kind": "method", "line": 548, "name": "reset_credentials_with_recovery", "signature": "def reset_credentials_with_recovery(self, username, srp_salt, srp_verifier, kdf_salt, encrypted_private_key)"}, {"doc": "Update a user's role, storage quota, and subscription status.\n\nArgs:\n username (str): Username of the user to update.\n role (str): New role for the user.\n storage_quota (int): New storage quota in bytes (default: 10MB).\n subscription_status (str): New subscription status (default: 'active').", "kind": "method", "line": 579, "name": "update_role", "signature": "def update_role(self, username, role, storage_quota, subscription_status)"}, {"doc": "Return the total number of users.\n\nImplemented as ``SELECT COUNT(*)`` rather than ``len(get_all_users())``\nso the home page does not materialise the entire table on every\nrequest.", "kind": "method", "line": 592, "name": "count_users", "signature": "def count_users(self)"}, {"doc": "Retrieve all users.\n\nReturns:\n list[dict]: List of dictionaries containing user data.", "kind": "method", "line": 603, "name": "get_all_users", "signature": "def get_all_users(self)"}, {"doc": "Parse a stored timestamp into a datetime, tolerating the format.\n\nArgs:\n value: A datetime, an ISO-like timestamp string, or None.\n\nReturns:\n The parsed datetime, or None when the value is empty or unparseable.", "kind": "method", "line": 615, "name": "_parse_datetime", "signature": "def _parse_datetime(value)"}, {"doc": "Convert a name-keyed SQLite row into a plain dictionary.\n\nReads access columns by name (the connection uses ``sqlite3.Row``), so\nthe mapping is robust to column ordering and additive migrations.\n\nArgs:\n row: A ``sqlite3.Row`` produced by a read query, or None.\n\nReturns:\n A dictionary of user fields, or None when the row is empty.", "kind": "method", "line": 638, "name": "_convert_row_to_dict", "signature": "def _convert_row_to_dict(self, row)"}, {"doc": "Execute a query and return the first result as a dictionary.\n\nArgs:\n query (str): SQL query to execute.\n params (tuple): Parameters for the query (default: empty tuple).\n\nReturns:\n Optional[dict]: First row as a dictionary or None if no results or an error occurs.", "kind": "method", "line": 694, "name": "fetch_one", "signature": "def fetch_one(self, query, params)"}, {"kind": "method", "line": 655, "name": "value", "signature": "def value(name, default)"}]}, {"id": "pq_decrypt_password.py", "kind": "module", "label": "pq_decrypt_password.py", "language": "py", "sha256": "f019755bae8bda62", "symbol_count": 0, "symbols": []}, {"id": "scripts/doctor.py", "kind": "module", "label": "doctor.py", "language": "py", "sha256": "8a7490941776c853", "symbol_count": 0, "symbols": []}, {"id": "scripts/email_tool.py", "kind": "module", "label": "email_tool.py", "language": "py", "sha256": "1bc02bf7a93dff05", "symbol_count": 6, "symbols": [{"doc": "Build a minimal Flask app that only carries the mail configuration.\n\nIntentionally avoids the full application factory (object storage, Redis,\nsecurity headers) so this tool runs on a bare host with nothing but SMTP\nreachable.", "kind": "function", "line": 40, "name": "_build_mail_app", "signature": "def _build_mail_app(config)"}, {"doc": "Send a test email through the configured SMTP server.", "kind": "function", "line": 63, "name": "cmd_test_smtp", "signature": "def cmd_test_smtp(args)"}, {"doc": "Print the confirmation URL for a user without sending email.", "kind": "function", "line": 91, "name": "cmd_link", "signature": "def cmd_link(args)"}, {"doc": "Mark a user's email as verified directly in the database.", "kind": "function", "line": 114, "name": "cmd_confirm", "signature": "def cmd_confirm(args)"}, {"doc": "Construct the argument parser for the three subcommands.", "kind": "function", "line": 133, "name": "build_parser", "signature": "def build_parser()"}, {"doc": "Parse arguments and dispatch to the selected subcommand.", "kind": "function", "line": 153, "name": "main", "signature": "def main()"}]}, {"doc": "Bootstrap a fresh Garage deployment for QuantumVault. What this does: 1. Waits for the admin API to respond. 2. Connects the local node to the cluster (single-node layout). 3. Creates the quantumvault bucket. 4. Creates a scoped API key with read+write on that bucket only. 5. Emits the credentials for .env (S3_ACCESS_KEY / S3_SECRET_KEY). Usage: docker compose up -d garage scripts/garage-init.sh The script reads GARAGE_RPC_SECRET and GARAGE_ADMIN_TOKEN from the .env file (or the environment) so the admin API can be authenticated.", "id": "scripts/garage-init.sh", "kind": "module", "label": "garage-init.sh", "language": "sh", "sha256": "6e9fe8a9d44648c8", "symbol_count": 1, "symbols": [{"doc": "Insert or update a KEY=value line in .env without disturbing other lines.", "kind": "function", "line": 35, "name": "upsert_env"}]}, {"doc": "Run Garage (S3-compatible object storage) natively, without Docker. Idempotent: if the S3 API is already reachable on :3900 it does nothing. Otherwise it ensures a local garage binary exists (downloading a pinned release and verifying its checksum when necessary), writes a development config with project-local data directories under .run/garage, starts the server in the background, provisions the bucket and a scoped access key, and writes the resulting S3 credentials into .env so the app picks them up. Override knobs via the environment: GARAGE_VERSION release to download (default 1.0.1) GARAGE_BIN path to (or destination for) garage (default .run/garage-bin/garage) GARAGE_SHA256 pin the binary checksum (optional, recommended) This script is invoked by `make garage-up`, which `make run` calls as a prerequisite when Docker is not available.", "id": "scripts/garage-native.sh", "kind": "module", "label": "garage-native.sh", "language": "sh", "sha256": "e4e0897859d0f948", "symbol_count": 3, "symbols": [{"doc": "Insert or update a KEY=value line in .env without disturbing other lines.", "kind": "function", "line": 46, "name": "upsert_env"}, {"kind": "function", "line": 56, "name": "s3_reachable"}, {"kind": "function", "line": 141, "name": "gcmd"}]}, {"id": "scripts/makeadmin.py", "kind": "module", "label": "makeadmin.py", "language": "py", "sha256": "bf6eee53c78fd78b", "symbol_count": 5, "symbols": [{"doc": "Return the absolute users.db path, anchored at the project root.\n\nA bare ``instance/users.db`` only resolves when the script is run\nfrom the project root. Anchoring at ``_PROJECT_ROOT`` lets an operator\ninvoke it from anywhere (cron, CI, a different cwd) without surprises.", "kind": "function", "line": 51, "name": "_resolve_db_path", "signature": "def _resolve_db_path()"}, {"doc": "Print the post-update user record so the operator can eyeball it.", "kind": "function", "line": 64, "name": "_print_user_summary", "signature": "def _print_user_summary(user)"}, {"doc": "Promote ``args.username`` to the requested role (default: superadmin).", "kind": "function", "line": 75, "name": "cmd_promote", "signature": "def cmd_promote(args)"}, {"doc": "Construct the argument parser for the makeadmin subcommands.", "kind": "function", "line": 126, "name": "build_parser", "signature": "def build_parser()"}, {"doc": "Parse arguments and dispatch to the selected subcommand.", "kind": "function", "line": 152, "name": "main", "signature": "def main()"}]}, {"id": "scripts/test_bloque1.py", "kind": "module", "label": "test_bloque1.py", "language": "py", "sha256": "7ecb72997b4f6e91", "symbol_count": 8, "symbols": [{"kind": "class", "line": 48, "name": "_FakeUser", "signature": "class _FakeUser"}, {"kind": "method", "line": 62, "name": "_load_user", "signature": "def _load_user(uid)"}, {"kind": "method", "line": 86, "name": "check", "signature": "def check(name, ok, detail)"}, {"kind": "method", "line": 49, "name": "__init__", "signature": "def __init__(self, row)"}, {"kind": "method", "line": 54, "name": "is_authenticated", "signature": "def is_authenticated(self)"}, {"kind": "method", "line": 56, "name": "is_active", "signature": "def is_active(self)"}, {"kind": "method", "line": 58, "name": "is_anonymous", "signature": "def is_anonymous(self)"}, {"kind": "method", "line": 59, "name": "get_id", "signature": "def get_id(self)"}]}, {"id": "server.go", "kind": "module", "label": "server.go", "language": "go", "sha256": "cd8b3decdbde4a81", "symbol_count": 2, "symbols": [{"kind": "function", "line": 11, "name": "main", "signature": "func main("}, {"kind": "function", "line": 40, "name": "handleConnection", "signature": "func handleConnection("}]}, {"id": "server.py", "kind": "module", "label": "server.py", "language": "py", "sha256": "f38a106bc85e3411", "symbol_count": 0, "symbols": []}, {"doc": "Account settings controller: secure notes (QV-DENIABLE-1). Loaded as an external ES module to comply with the strict Content-Security-Policy (script-src 'self'), which forbids inline scripts. All container building and opening happens in qv-deniable.js, in the browser. The server returns and accepts an opaque container plus the non-secret structural parameters; it never sees a passphrase or any note text, and it never reports whether a second set of notes exists.", "id": "static/js/account.js", "kind": "module", "label": "account.js", "language": "js", "sha256": "26b2425785b35b10", "symbol_count": 9, "symbols": [{"kind": "function", "line": 19, "name": "setStatus"}, {"kind": "function", "line": 30, "name": "csrfToken"}, {"kind": "function", "line": 36, "name": "apiRequest"}, {"kind": "function", "line": 54, "name": "loadState"}, {"kind": "function", "line": 59, "name": "collectSlots"}, {"kind": "function", "line": 73, "name": "handleConfigure"}, {"kind": "function", "line": 98, "name": "handleOpen"}, {"kind": "function", "line": 120, "name": "handleReset"}, {"kind": "function", "line": 133, "name": "init"}]}, {"doc": "Decipher animation for elements tagged with the \"codedText\" class. Extracted from an inline