teardrop-cli 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/PKG-INFO +4 -2
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/README.md +2 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/docs/cli-reference.md +3 -1
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/pyproject.toml +2 -2
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/auth.py +3 -1
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/marketplace.py +74 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/conftest.py +31 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_auth.py +3 -1
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_marketplace.py +49 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/.github/workflows/publish.yml +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/.github/workflows/test.yml +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/.gitignore +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/.vscode/settings.json +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/LICENSE +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/docs/cli-json-schema.md +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/_fixtures.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/_lazy.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/_templates.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/cli.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/__init__.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/agent_tools.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/balance.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/chat.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/config_cmd.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/earnings.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/event_triggers.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/llm_config.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/mcp.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/models.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/quickstart.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/run.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/schedules.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/tools.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/commands/usage.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/config.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/formatting.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/src/teardrop_cli/pricing.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/README.md +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/__init__.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/conftest.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/test_auth_e2e.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/test_billing_e2e.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/test_marketplace_e2e.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/test_run_e2e.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/test_signup_e2e.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/e2e/test_siwe_login_e2e.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/smoke/__init__.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/smoke/conftest.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/smoke/test_config_persistence.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/smoke/test_keyring_integration.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/smoke/test_perf_lazygroup.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/smoke/test_siwe_signing.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_billing.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_chat.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_config_cmd.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_credential_priority.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_earnings.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_event_triggers.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_init_and_byok.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_llm_config.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_mcp.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_models.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_quickstart.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_run.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_schedules.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_signup.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_token_expiry_fallback.py +0 -0
- {teardrop_cli-0.3.2 → teardrop_cli-0.3.3}/tests/test_tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: teardrop-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Command-line interface for the Teardrop AI agent platform
|
|
5
5
|
Project-URL: Homepage, https://github.com/teardrop-ai/teardrop-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/teardrop-ai/teardrop-cli
|
|
@@ -45,7 +45,7 @@ Requires-Dist: httpx>=0.27
|
|
|
45
45
|
Requires-Dist: keyring>=25.0
|
|
46
46
|
Requires-Dist: platformdirs>=4.0
|
|
47
47
|
Requires-Dist: rich>=13.0
|
|
48
|
-
Requires-Dist: teardrop-sdk>=0.3.
|
|
48
|
+
Requires-Dist: teardrop-sdk>=0.3.2
|
|
49
49
|
Requires-Dist: tomli-w>=1.0
|
|
50
50
|
Requires-Dist: typer>=0.12
|
|
51
51
|
Provides-Extra: dev
|
|
@@ -315,6 +315,8 @@ New email-authenticated organizations may receive optional promotional credit af
|
|
|
315
315
|
teardrop marketplace list
|
|
316
316
|
teardrop marketplace search "weather"
|
|
317
317
|
teardrop marketplace info acme/weather
|
|
318
|
+
teardrop marketplace reputation
|
|
319
|
+
teardrop marketplace reputation acme/weather --json
|
|
318
320
|
teardrop marketplace subscribe acme/weather
|
|
319
321
|
teardrop marketplace subscriptions
|
|
320
322
|
```
|
|
@@ -255,6 +255,8 @@ New email-authenticated organizations may receive optional promotional credit af
|
|
|
255
255
|
teardrop marketplace list
|
|
256
256
|
teardrop marketplace search "weather"
|
|
257
257
|
teardrop marketplace info acme/weather
|
|
258
|
+
teardrop marketplace reputation
|
|
259
|
+
teardrop marketplace reputation acme/weather --json
|
|
258
260
|
teardrop marketplace subscribe acme/weather
|
|
259
261
|
teardrop marketplace subscriptions
|
|
260
262
|
```
|
|
@@ -192,7 +192,7 @@ teardrop usage --json
|
|
|
192
192
|
|
|
193
193
|
The CLI does not support direct top-ups. To add credits or manage your billing methods, please visit the dashboard:
|
|
194
194
|
|
|
195
|
-
[https://teardrop.dev
|
|
195
|
+
[https://teardrop.dev](https://teardrop.dev)
|
|
196
196
|
|
|
197
197
|
If you run out of credits during an agent run, the agent will pause and provide this link.
|
|
198
198
|
|
|
@@ -315,6 +315,8 @@ teardrop marketplace list
|
|
|
315
315
|
teardrop marketplace list --category data --json
|
|
316
316
|
teardrop marketplace search "weather"
|
|
317
317
|
teardrop marketplace info acme/weather
|
|
318
|
+
teardrop marketplace reputation
|
|
319
|
+
teardrop marketplace reputation acme/weather --json
|
|
318
320
|
teardrop marketplace subscribe acme/weather
|
|
319
321
|
teardrop marketplace subscribe acme/weather --yes # skip confirmation
|
|
320
322
|
teardrop marketplace subscriptions
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "teardrop-cli"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "Command-line interface for the Teardrop AI agent platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -24,7 +24,7 @@ classifiers = [
|
|
|
24
24
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
25
|
]
|
|
26
26
|
dependencies = [
|
|
27
|
-
"teardrop-sdk>=0.3.
|
|
27
|
+
"teardrop-sdk>=0.3.2",
|
|
28
28
|
"typer>=0.12",
|
|
29
29
|
"rich>=13.0",
|
|
30
30
|
"platformdirs>=4.0",
|
|
@@ -462,7 +462,9 @@ async def _siwe_auth_async(
|
|
|
462
462
|
|
|
463
463
|
async with AsyncTeardropClient(url) as client:
|
|
464
464
|
nonce_resp = await client.get_siwe_nonce()
|
|
465
|
-
|
|
465
|
+
# get_siwe_nonce() returns a SiweNonceResponse pydantic model (nonce: str),
|
|
466
|
+
# not a dict — access the attribute directly.
|
|
467
|
+
nonce = nonce_resp.nonce
|
|
466
468
|
|
|
467
469
|
from urllib.parse import urlparse
|
|
468
470
|
|
|
@@ -240,6 +240,80 @@ def info(
|
|
|
240
240
|
data_console.print_json(json.dumps(schema, default=str))
|
|
241
241
|
|
|
242
242
|
|
|
243
|
+
# ---------------------------------------------------------------------------
|
|
244
|
+
# reputation
|
|
245
|
+
# ---------------------------------------------------------------------------
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@app.command()
|
|
249
|
+
def reputation(
|
|
250
|
+
qualified_name: Annotated[
|
|
251
|
+
str | None,
|
|
252
|
+
typer.Argument(metavar="ORG/TOOL", help="Optional qualified tool name filter."),
|
|
253
|
+
] = None,
|
|
254
|
+
as_json: Annotated[bool, typer.Option("--json", help="Output as JSON.")] = False,
|
|
255
|
+
base_url: Annotated[str | None, typer.Option("--base-url", hidden=True)] = None,
|
|
256
|
+
) -> None:
|
|
257
|
+
"""Show public reputation metrics for marketplace tools (no auth required)."""
|
|
258
|
+
from teardrop_cli import config
|
|
259
|
+
from teardrop_cli.formatting import data_console, print_error, print_json, print_table, spinner
|
|
260
|
+
|
|
261
|
+
client = config.get_client(base_url, require_auth=False)
|
|
262
|
+
|
|
263
|
+
async def _fetch() -> dict:
|
|
264
|
+
try:
|
|
265
|
+
response = await client.get_public_reputation()
|
|
266
|
+
return response.model_dump() if hasattr(response, "model_dump") else dict(response)
|
|
267
|
+
finally:
|
|
268
|
+
await client.close()
|
|
269
|
+
|
|
270
|
+
with spinner("Fetching public reputation…"):
|
|
271
|
+
data = asyncio.run(_fetch())
|
|
272
|
+
|
|
273
|
+
tools = data.get("tools", [])
|
|
274
|
+
if qualified_name is not None:
|
|
275
|
+
tools = [tool for tool in tools if tool.get("qualified_tool_name") == qualified_name]
|
|
276
|
+
if not tools:
|
|
277
|
+
print_error(f"No public reputation found for {qualified_name!r}.")
|
|
278
|
+
raise typer.Exit(1)
|
|
279
|
+
data["tools"] = tools
|
|
280
|
+
|
|
281
|
+
if as_json:
|
|
282
|
+
print_json(data)
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
if not tools:
|
|
286
|
+
data_console.print("[dim]No public reputation data available.[/dim]")
|
|
287
|
+
return
|
|
288
|
+
|
|
289
|
+
data_console.print(
|
|
290
|
+
f"Schema: {data.get('schema_version', '—')} | "
|
|
291
|
+
f"Generated: {data.get('generated_at') or '—'} | "
|
|
292
|
+
f"Methodology: {data.get('methodology_url') or '—'}"
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
rows = [
|
|
296
|
+
[
|
|
297
|
+
tool.get("qualified_tool_name", "—"),
|
|
298
|
+
(
|
|
299
|
+
f"score={tool.get('reputation_score', '—')} "
|
|
300
|
+
f"success={tool.get('success_rate', '—')} "
|
|
301
|
+
f"sample={tool.get('sample_size', '—')} "
|
|
302
|
+
f"confidence={tool.get('confidence', '—')} "
|
|
303
|
+
f"freshness={tool.get('freshness', '—')} "
|
|
304
|
+
f"latency_ms={tool.get('average_latency_ms', '—')} "
|
|
305
|
+
f"callers={tool.get('unique_caller_count', '—')}"
|
|
306
|
+
),
|
|
307
|
+
]
|
|
308
|
+
for tool in tools
|
|
309
|
+
]
|
|
310
|
+
print_table(
|
|
311
|
+
["Tool", "Metrics"],
|
|
312
|
+
rows,
|
|
313
|
+
title="Public Tool Reputation",
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
|
|
243
317
|
# ---------------------------------------------------------------------------
|
|
244
318
|
# subscribe
|
|
245
319
|
# ---------------------------------------------------------------------------
|
|
@@ -159,6 +159,37 @@ def mock_client():
|
|
|
159
159
|
"next_cursor": None,
|
|
160
160
|
}
|
|
161
161
|
)
|
|
162
|
+
client.get_public_reputation = AsyncMock(
|
|
163
|
+
return_value=MagicMock(
|
|
164
|
+
model_dump=lambda: {
|
|
165
|
+
"schema_version": "1.0",
|
|
166
|
+
"generated_at": "2026-08-02T12:00:00Z",
|
|
167
|
+
"methodology_url": "https://teardrop.dev/reputation-methodology",
|
|
168
|
+
"tools": [
|
|
169
|
+
{
|
|
170
|
+
"qualified_tool_name": "acme/weather",
|
|
171
|
+
"reputation_score": 0.91,
|
|
172
|
+
"success_rate": 0.96,
|
|
173
|
+
"sample_size": 125.0,
|
|
174
|
+
"confidence": 0.88,
|
|
175
|
+
"freshness": 0.97,
|
|
176
|
+
"average_latency_ms": 142.5,
|
|
177
|
+
"unique_caller_count": 18,
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"qualified_tool_name": "acme/search",
|
|
181
|
+
"reputation_score": 0.84,
|
|
182
|
+
"success_rate": 0.9,
|
|
183
|
+
"sample_size": 80.0,
|
|
184
|
+
"confidence": 0.75,
|
|
185
|
+
"freshness": 0.92,
|
|
186
|
+
"average_latency_ms": 210.0,
|
|
187
|
+
"unique_caller_count": None,
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
)
|
|
162
193
|
client.subscribe = AsyncMock(
|
|
163
194
|
return_value=MagicMock(
|
|
164
195
|
model_dump=lambda: {"id": "sub_1", "qualified_tool_name": "acme/weather"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from types import SimpleNamespace
|
|
5
6
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
6
7
|
|
|
7
8
|
import pytest
|
|
@@ -140,7 +141,8 @@ class TestSiweLogin:
|
|
|
140
141
|
return None
|
|
141
142
|
|
|
142
143
|
async def get_siwe_nonce(self):
|
|
143
|
-
|
|
144
|
+
# Mirrors the real SDK: returns a SiweNonceResponse pydantic model.
|
|
145
|
+
return SimpleNamespace(nonce="abc123")
|
|
144
146
|
|
|
145
147
|
async def authenticate_siwe(self, message, signature):
|
|
146
148
|
seen["message"] = message
|
|
@@ -91,6 +91,55 @@ class TestInfo:
|
|
|
91
91
|
assert result.exit_code == 1
|
|
92
92
|
|
|
93
93
|
|
|
94
|
+
class TestReputation:
|
|
95
|
+
def test_reputation_table(self, runner: CliRunner, patch_get_client):
|
|
96
|
+
result = runner.invoke(app, ["marketplace", "reputation"])
|
|
97
|
+
assert result.exit_code == 0, result.output
|
|
98
|
+
assert "Public Tool Reputation" in result.output
|
|
99
|
+
assert "Schema: 1.0" in result.output
|
|
100
|
+
assert "acme/weather" in result.output
|
|
101
|
+
assert "0.91" in result.output
|
|
102
|
+
assert "142.5" in result.output
|
|
103
|
+
assert "acme/search" in result.output
|
|
104
|
+
|
|
105
|
+
def test_reputation_json(self, runner: CliRunner, patch_get_client):
|
|
106
|
+
import json
|
|
107
|
+
|
|
108
|
+
result = runner.invoke(app, ["marketplace", "reputation", "--json"])
|
|
109
|
+
assert result.exit_code == 0, result.output
|
|
110
|
+
data = json.loads(result.output)
|
|
111
|
+
assert data["schema_version"] == "1.0"
|
|
112
|
+
assert data["methodology_url"].endswith("reputation-methodology")
|
|
113
|
+
assert len(data["tools"]) == 2
|
|
114
|
+
assert data["tools"][0]["unique_caller_count"] == 18
|
|
115
|
+
assert data["tools"][1]["unique_caller_count"] is None
|
|
116
|
+
|
|
117
|
+
def test_reputation_filters_by_qualified_name(self, runner: CliRunner, patch_get_client):
|
|
118
|
+
import json
|
|
119
|
+
|
|
120
|
+
result = runner.invoke(app, ["marketplace", "reputation", "acme/weather", "--json"])
|
|
121
|
+
assert result.exit_code == 0, result.output
|
|
122
|
+
data = json.loads(result.output)
|
|
123
|
+
assert [tool["qualified_tool_name"] for tool in data["tools"]] == ["acme/weather"]
|
|
124
|
+
|
|
125
|
+
def test_reputation_missing_tool(self, runner: CliRunner, patch_get_client):
|
|
126
|
+
result = runner.invoke(app, ["marketplace", "reputation", "nope/none"])
|
|
127
|
+
assert result.exit_code == 1
|
|
128
|
+
assert "No public reputation found" in result.output
|
|
129
|
+
|
|
130
|
+
def test_reputation_does_not_require_auth(self, runner: CliRunner, mock_client, monkeypatch):
|
|
131
|
+
calls = {}
|
|
132
|
+
|
|
133
|
+
def get_client(*args, **kwargs):
|
|
134
|
+
calls.update(kwargs)
|
|
135
|
+
return mock_client
|
|
136
|
+
|
|
137
|
+
monkeypatch.setattr("teardrop_cli.config.get_client", get_client)
|
|
138
|
+
result = runner.invoke(app, ["marketplace", "reputation"])
|
|
139
|
+
assert result.exit_code == 0, result.output
|
|
140
|
+
assert calls["require_auth"] is False
|
|
141
|
+
|
|
142
|
+
|
|
94
143
|
class TestSubscribe:
|
|
95
144
|
def test_subscribe_with_yes(self, runner: CliRunner, patch_get_client, mock_client):
|
|
96
145
|
result = runner.invoke(app, ["marketplace", "subscribe", "acme/weather", "--yes"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|