chatstrata 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {chatstrata-0.2.0 → chatstrata-0.2.2}/CHANGELOG.md +8 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/PKG-INFO +50 -16
- {chatstrata-0.2.0 → chatstrata-0.2.2}/README.md +48 -14
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/__init__.py +1 -1
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/claude_code/adapter.py +33 -3
- {chatstrata-0.2.0 → chatstrata-0.2.2}/pyproject.toml +2 -2
- {chatstrata-0.2.0 → chatstrata-0.2.2}/.gitignore +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/CONTRIBUTING.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/LICENSE +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/SECURITY.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/analysis/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/analysis/cli.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/analysis/queries/activity.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/analysis/queries/conversations.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/analysis/queries/example_queries.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/analysis/queries/models.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/analysis/queries/projects.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/analysis/queries/tools.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/cli.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/db.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/ingest.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/migrations/0001_initial.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/migrations/0002_fts_index.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/migrations/0003_conversation_mtime.sql +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/migrations/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/models.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/search.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/embed/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/embed/base.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/embed/cli.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/embed/local_provider.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/embed/search.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/mcp/README.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/mcp/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/mcp/safety.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/mcp/server.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/base.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/cli.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/presidio_engine.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/recognizers/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/recognizers/api_keys.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/recognizers/connection_strings.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/recognizers/paths.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/redact/recognizers/tokens.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/schedule/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/schedule/cli.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/schedule/launchd.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/base.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/claude_code/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/claude_code/manifest.yaml +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/claude_export/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/claude_export/adapter.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/claude_export/manifest.yaml +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/codex_cli/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/codex_cli/adapter.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/codex_cli/manifest.yaml +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/opencode/__init__.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/opencode/adapter.py +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/sources/opencode/manifest.yaml +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/adapter-guide.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/adr/0001-use-duckdb.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/adr/0002-store-raw-alongside-normalized.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/adr/0003-adapter-pattern-entry-points.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/images/chatstrata.png +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/redaction.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/release.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/schema.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/sources/claude_export.md +0 -0
- {chatstrata-0.2.0 → chatstrata-0.2.2}/docs/sources/codex_cli.md +0 -0
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.2 - 2026-07-29
|
|
4
|
+
|
|
5
|
+
- Cap the `mcp` dependency at `>=1.12.0,<2`. `mcp` 2.0.0 removed the `mcp.server.fastmcp` module that `chatstrata/mcp/server.py` imports, so the previously unbounded pin resolved 2.0.0 and crashed `chatstrata-mcp` on startup with `ModuleNotFoundError: No module named 'mcp.server.fastmcp'`.
|
|
6
|
+
|
|
7
|
+
## 0.2.1 - 2026-07-22
|
|
8
|
+
|
|
9
|
+
- Fix `claude_code` conversation `project` paths: derive the project from the lossless `cwd` recorded in each transcript instead of decoding the session folder name. The folder-name encoding collapses `/`, `_`, `-`, and `.` all into `-`, so decoding it produced wrong, non-existent paths (e.g. `bstaq_git/pepstaq` became `bstaq/git`). New ingests are now correct automatically; `codex_cli` and `opencode` were unaffected.
|
|
10
|
+
|
|
3
11
|
## 0.2.0 - 2026-06-16
|
|
4
12
|
|
|
5
13
|
- Add `chatstrata schedule` command group for automatic background sync.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chatstrata
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A personal, queryable archive of your AI conversations across providers
|
|
5
5
|
Project-URL: Homepage, https://github.com/brandonbosch/chatstrata
|
|
6
6
|
Project-URL: Repository, https://github.com/brandonbosch/chatstrata
|
|
@@ -34,7 +34,7 @@ Provides-Extra: embeddings
|
|
|
34
34
|
Requires-Dist: sentence-transformers>=3.0; extra == 'embeddings'
|
|
35
35
|
Requires-Dist: torch>=2.0; extra == 'embeddings'
|
|
36
36
|
Provides-Extra: mcp
|
|
37
|
-
Requires-Dist: mcp[cli]
|
|
37
|
+
Requires-Dist: mcp[cli]<2,>=1.12.0; extra == 'mcp'
|
|
38
38
|
Provides-Extra: redact
|
|
39
39
|
Requires-Dist: presidio-analyzer>=2.2; extra == 'redact'
|
|
40
40
|
Requires-Dist: presidio-anonymizer>=2.2; extra == 'redact'
|
|
@@ -75,30 +75,64 @@ Concretely, with chatstrata you can:
|
|
|
75
75
|
|
|
76
76
|
## Status
|
|
77
77
|
|
|
78
|
-
**
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
**Alpha.** Published on [PyPI](https://pypi.org/project/chatstrata/). Includes
|
|
79
|
+
adapters for Claude Code, claude.ai exports, Codex CLI, and OpenCode, plus
|
|
80
|
+
scheduled background sync so your archive stays current without manual runs. The
|
|
81
|
+
architecture is built so that adding more sources (ChatGPT exports, Cursor, etc.)
|
|
82
|
+
is the work of one adapter — see [docs/adapter-guide.md](docs/adapter-guide.md).
|
|
82
83
|
|
|
83
84
|
## Quickstart
|
|
84
85
|
|
|
85
|
-
Requires Python 3.10+.
|
|
86
|
-
|
|
86
|
+
Requires Python 3.10+. We recommend [uv](https://docs.astral.sh/uv/) — it's the
|
|
87
|
+
fastest way to get started (no virtualenv wrangling, no dependency conflicts).
|
|
88
|
+
|
|
89
|
+
### 1. Install
|
|
87
90
|
|
|
88
91
|
```bash
|
|
89
92
|
uv tool install "chatstrata[embeddings]"
|
|
90
|
-
|
|
93
|
+
```
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
<details>
|
|
96
|
+
<summary>Alternative: pipx</summary>
|
|
94
97
|
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
```bash
|
|
99
|
+
pipx install "chatstrata[embeddings]"
|
|
100
|
+
```
|
|
101
|
+
</details>
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
### 2. Initialize and ingest
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
chatstrata init # create the local DuckDB archive
|
|
107
|
+
chatstrata ingest --auto # auto-detect transcripts and generate embeddings
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. Set up background sync
|
|
111
|
+
|
|
112
|
+
Never think about syncing again — chatstrata can keep your archive up to date
|
|
113
|
+
automatically in the background:
|
|
100
114
|
|
|
101
|
-
|
|
115
|
+
```bash
|
|
116
|
+
chatstrata schedule install # sync every 15 minutes (default)
|
|
117
|
+
chatstrata schedule install --interval 1h # or pick your own interval
|
|
118
|
+
chatstrata schedule status # check that it's running
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
On macOS this installs a launchd agent that runs `chatstrata ingest --auto`
|
|
122
|
+
on the configured interval. Logs go to `~/Library/Logs/chatstrata/`. To stop
|
|
123
|
+
background sync:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
chatstrata schedule uninstall
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
> **Linux:** systemd scheduling is not yet implemented. Use cron as a workaround:
|
|
130
|
+
> `*/15 * * * * chatstrata ingest --auto`
|
|
131
|
+
|
|
132
|
+
### 4. Query your archive
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
chatstrata stats
|
|
102
136
|
chatstrata query "SELECT model, COUNT(*) FROM messages GROUP BY model"
|
|
103
137
|
```
|
|
104
138
|
|
|
@@ -32,30 +32,64 @@ Concretely, with chatstrata you can:
|
|
|
32
32
|
|
|
33
33
|
## Status
|
|
34
34
|
|
|
35
|
-
**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
**Alpha.** Published on [PyPI](https://pypi.org/project/chatstrata/). Includes
|
|
36
|
+
adapters for Claude Code, claude.ai exports, Codex CLI, and OpenCode, plus
|
|
37
|
+
scheduled background sync so your archive stays current without manual runs. The
|
|
38
|
+
architecture is built so that adding more sources (ChatGPT exports, Cursor, etc.)
|
|
39
|
+
is the work of one adapter — see [docs/adapter-guide.md](docs/adapter-guide.md).
|
|
39
40
|
|
|
40
41
|
## Quickstart
|
|
41
42
|
|
|
42
|
-
Requires Python 3.10+.
|
|
43
|
-
|
|
43
|
+
Requires Python 3.10+. We recommend [uv](https://docs.astral.sh/uv/) — it's the
|
|
44
|
+
fastest way to get started (no virtualenv wrangling, no dependency conflicts).
|
|
45
|
+
|
|
46
|
+
### 1. Install
|
|
44
47
|
|
|
45
48
|
```bash
|
|
46
49
|
uv tool install "chatstrata[embeddings]"
|
|
47
|
-
|
|
50
|
+
```
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
<details>
|
|
53
|
+
<summary>Alternative: pipx</summary>
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
```bash
|
|
56
|
+
pipx install "chatstrata[embeddings]"
|
|
57
|
+
```
|
|
58
|
+
</details>
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
### 2. Initialize and ingest
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
chatstrata init # create the local DuckDB archive
|
|
64
|
+
chatstrata ingest --auto # auto-detect transcripts and generate embeddings
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 3. Set up background sync
|
|
68
|
+
|
|
69
|
+
Never think about syncing again — chatstrata can keep your archive up to date
|
|
70
|
+
automatically in the background:
|
|
57
71
|
|
|
58
|
-
|
|
72
|
+
```bash
|
|
73
|
+
chatstrata schedule install # sync every 15 minutes (default)
|
|
74
|
+
chatstrata schedule install --interval 1h # or pick your own interval
|
|
75
|
+
chatstrata schedule status # check that it's running
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
On macOS this installs a launchd agent that runs `chatstrata ingest --auto`
|
|
79
|
+
on the configured interval. Logs go to `~/Library/Logs/chatstrata/`. To stop
|
|
80
|
+
background sync:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
chatstrata schedule uninstall
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> **Linux:** systemd scheduling is not yet implemented. Use cron as a workaround:
|
|
87
|
+
> `*/15 * * * * chatstrata ingest --auto`
|
|
88
|
+
|
|
89
|
+
### 4. Query your archive
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
chatstrata stats
|
|
59
93
|
chatstrata query "SELECT model, COUNT(*) FROM messages GROUP BY model"
|
|
60
94
|
```
|
|
61
95
|
|
|
@@ -49,16 +49,39 @@ def _parse_timestamp(s: Any) -> datetime | None:
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def _decode_project_dir(dir_name: str) -> str:
|
|
52
|
-
"""Claude Code
|
|
52
|
+
"""Decode Claude Code's encoded project-folder name back into a path.
|
|
53
53
|
|
|
54
54
|
e.g. '-Users-alice-code-myproj' -> '/Users/alice/code/myproj'
|
|
55
|
-
|
|
55
|
+
|
|
56
|
+
This decode is *lossy and irreversible*: Claude Code collapses '/', '_',
|
|
57
|
+
'-', and '.' in the cwd all into '-' when naming the folder, so a '-' in
|
|
58
|
+
the folder name could have been any of those characters. As a result many
|
|
59
|
+
distinct cwds map to the same decoded path (e.g. both '.../my_proj' and
|
|
60
|
+
'.../my/proj' decode identically). Prefer the lossless cwd recorded inside
|
|
61
|
+
the transcript (see `_project_from_events`); this decode is only a
|
|
62
|
+
last-resort fallback for transcripts that never recorded a cwd.
|
|
56
63
|
"""
|
|
57
64
|
if dir_name.startswith("-"):
|
|
58
65
|
return "/" + dir_name[1:].replace("-", "/")
|
|
59
66
|
return dir_name
|
|
60
67
|
|
|
61
68
|
|
|
69
|
+
def _project_from_events(events: list[dict[str, Any]]) -> str | None:
|
|
70
|
+
"""Return the real working directory recorded in the transcript.
|
|
71
|
+
|
|
72
|
+
Every Claude Code event carries the session cwd, e.g.
|
|
73
|
+
``"cwd": "/Users/alice/code/my_project"``. This is the lossless source of
|
|
74
|
+
truth for the project path -- unlike the encoded folder name, which cannot
|
|
75
|
+
be reversed (see `_decode_project_dir`). Use the first event that records a
|
|
76
|
+
non-empty cwd; the cwd is constant across a session.
|
|
77
|
+
"""
|
|
78
|
+
for ev in events:
|
|
79
|
+
cwd = ev.get("cwd")
|
|
80
|
+
if isinstance(cwd, str) and cwd:
|
|
81
|
+
return cwd
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
|
|
62
85
|
def _role_from_event(event: dict[str, Any]) -> Role | None:
|
|
63
86
|
t = event.get("type")
|
|
64
87
|
if t == "user":
|
|
@@ -153,6 +176,8 @@ class ClaudeCodeAdapter:
|
|
|
153
176
|
return
|
|
154
177
|
for jsonl in sorted(root.glob("*/*.jsonl")):
|
|
155
178
|
session_id = jsonl.stem
|
|
179
|
+
# Lossy fallback only: parse() prefers the lossless cwd from the
|
|
180
|
+
# transcript and uses this decoded folder name just as a backstop.
|
|
156
181
|
project = _decode_project_dir(jsonl.parent.name)
|
|
157
182
|
yield ConversationHandle(
|
|
158
183
|
source_native_id=session_id,
|
|
@@ -228,7 +253,12 @@ class ClaudeCodeAdapter:
|
|
|
228
253
|
)
|
|
229
254
|
)
|
|
230
255
|
|
|
231
|
-
|
|
256
|
+
# Prefer the lossless cwd recorded in the transcript over the lossy
|
|
257
|
+
# folder-name decode carried on the handle. Fall back to the decoded
|
|
258
|
+
# folder name only for transcripts that never recorded a cwd.
|
|
259
|
+
project = _project_from_events(events)
|
|
260
|
+
if project is None and handle.metadata:
|
|
261
|
+
project = handle.metadata.get("project")
|
|
232
262
|
# If no summary, fall back to the first user text block as a title.
|
|
233
263
|
if title is None:
|
|
234
264
|
for m in messages:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "chatstrata"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.2"
|
|
4
4
|
description = "A personal, queryable archive of your AI conversations across providers"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -45,7 +45,7 @@ redact = [
|
|
|
45
45
|
"spacy>=3.7",
|
|
46
46
|
]
|
|
47
47
|
mcp = [
|
|
48
|
-
"mcp[cli]>=1.12.0",
|
|
48
|
+
"mcp[cli]>=1.12.0,<2",
|
|
49
49
|
]
|
|
50
50
|
dev = [
|
|
51
51
|
"pytest>=8.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{chatstrata-0.2.0 → chatstrata-0.2.2}/chatstrata/core/migrations/0003_conversation_mtime.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|