comodor 0.8.3__tar.gz → 0.8.4__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.
- {comodor-0.8.3 → comodor-0.8.4}/PKG-INFO +1 -1
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/_version.py +2 -2
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/browser/launch.py +34 -15
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_real_browser.py +28 -7
- {comodor-0.8.3 → comodor-0.8.4}/.gitignore +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/LICENSE +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/README.md +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/pyproject.toml +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/__main__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/agent/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/agent/context.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/agent/loop.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/agent/prompts.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/agent/spawn.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/agent/tokens.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/browser/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/browser/cdp.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/browser/page.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/catalogue.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/cli.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/config.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/doctor.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/events.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/associations.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/bm25.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/hotindex.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/memory.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/progress.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/reflect.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/rules.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/signals.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/store.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/learning/writer.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/mcp/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/mcp/catalogue.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/mcp/commands.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/mcp/http.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/mcp/manager.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/mcp/protocol.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/net/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/net/http.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/net/sse.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/paths.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/providers/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/providers/anthropic.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/providers/base.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/providers/caching.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/providers/fake.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/providers/gateway.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/providers/openai_compat.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/providers/registry.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/safety/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/safety/checkpoints.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/safety/permissions.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/safety/redact.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/session/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/session/search.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/session/store.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/setup.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/skills/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/skills/catalogue.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/skills/commands.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/skills/examples.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/skills/loader.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/skills/propose.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/skills/registry.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/base.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/browse.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/browser.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/delegate.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/fs.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/history.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/mcp.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/overflow.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/registry.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/search.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/shell.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/skills.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/todo.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/tools/web.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/app.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/bidi.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/chooser.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/console.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/input/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/input/keys.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/input/reader.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/layout.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/markdown.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/screen.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/theme.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/buttons.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/chat.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/history.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/overlay.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/panel.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/progress.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/prompt.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/statusbar.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/ui/widgets/toast.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/uninstall.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/update.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/web/__init__.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/web/commands.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/web/index.html +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/web/server.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/web/session.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/src/comodor/workspace.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/conftest.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/support/fake_mcp_server.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_agent_loop.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_app.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_associations.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_bidi.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_browser.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_caching.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_chooser.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_delegate.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_doctor.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_history.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_input.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_layout.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_learning.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_markdown.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_mcp.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_mcp_http.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_overflow.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_performance.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_prefix_stability.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_progress.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_propose.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_providers.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_reflex.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_run_loop.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_setup.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_skill_budget.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_skill_catalogue.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_skills.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_tools.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_uninstall.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_update.py +0 -0
- {comodor-0.8.3 → comodor-0.8.4}/tests/test_web.py +0 -0
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.8.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 8,
|
|
21
|
+
__version__ = version = '0.8.4'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 8, 4)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -96,32 +96,47 @@ def free_port() -> int:
|
|
|
96
96
|
|
|
97
97
|
|
|
98
98
|
#: What Chromium says when it will not run unprotected and cannot protect
|
|
99
|
-
#: itself. Matched
|
|
100
|
-
#:
|
|
99
|
+
#: itself. Matched against everything it printed rather than the first line:
|
|
100
|
+
#: it does not put the useful part first, and which line comes first depends on
|
|
101
|
+
#: how the container was started.
|
|
101
102
|
_NO_SANDBOX_SIGNS = (
|
|
102
103
|
"no usable sandbox",
|
|
103
104
|
"failed to move to new namespace",
|
|
104
|
-
"
|
|
105
|
+
"setuid sandbox",
|
|
105
106
|
"sandboxhelper",
|
|
106
107
|
"chrome-sandbox",
|
|
108
|
+
"zygote_host",
|
|
107
109
|
)
|
|
108
110
|
|
|
109
111
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return any(sign in text for sign in _NO_SANDBOX_SIGNS)
|
|
112
|
+
class SandboxUnavailable(BrowserError):
|
|
113
|
+
"""It will not start because it cannot isolate its renderers here.
|
|
113
114
|
|
|
115
|
+
Its own class rather than a string match at the call site, because the
|
|
116
|
+
decision belongs where the full output is: by the time this reaches a
|
|
117
|
+
caller the message has been trimmed to the one line worth showing.
|
|
118
|
+
"""
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
|
|
121
|
+
def _looks_like_a_sandbox_problem(output: str) -> bool:
|
|
122
|
+
lowered = output.lower()
|
|
123
|
+
return any(sign in lowered for sign in _NO_SANDBOX_SIGNS)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _read_all(handle) -> str:
|
|
117
127
|
try:
|
|
118
128
|
handle.seek(0)
|
|
119
|
-
|
|
129
|
+
return handle.read(20_000).decode("utf-8", "replace").strip()
|
|
120
130
|
except (OSError, ValueError):
|
|
121
131
|
return ""
|
|
122
|
-
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _first_line(output: str) -> str:
|
|
135
|
+
"""One line for a person. Forty lines of Chromium logging is not an error
|
|
136
|
+
message, it is a haystack."""
|
|
137
|
+
if not output:
|
|
123
138
|
return ""
|
|
124
|
-
first = next((line for line in
|
|
139
|
+
first = next((line for line in output.splitlines() if line.strip()), "")
|
|
125
140
|
return f" It said: {first.strip()[:300]}"
|
|
126
141
|
|
|
127
142
|
|
|
@@ -155,9 +170,8 @@ class Browser:
|
|
|
155
170
|
try:
|
|
156
171
|
return cls._spawn(binary, profile, chosen, headless, window,
|
|
157
172
|
sandboxed=True)
|
|
158
|
-
except
|
|
159
|
-
|
|
160
|
-
raise
|
|
173
|
+
except SandboxUnavailable:
|
|
174
|
+
pass
|
|
161
175
|
# It will not run its renderers in a user namespace here — almost
|
|
162
176
|
# always a container, whose own confinement is the stronger boundary
|
|
163
177
|
# anyway. Give up the inner one rather than weaken the outer one, and
|
|
@@ -205,7 +219,12 @@ class Browser:
|
|
|
205
219
|
try:
|
|
206
220
|
browser._await_port()
|
|
207
221
|
except BrowserError as error:
|
|
208
|
-
|
|
222
|
+
printed = _read_all(complaints)
|
|
223
|
+
message = f"{error}{_first_line(printed)}"
|
|
224
|
+
# Judged on everything it printed; reported as one line.
|
|
225
|
+
if sandboxed and _looks_like_a_sandbox_problem(printed):
|
|
226
|
+
raise SandboxUnavailable(message) from None
|
|
227
|
+
raise BrowserError(message) from None
|
|
209
228
|
finally:
|
|
210
229
|
complaints.close()
|
|
211
230
|
return browser
|
|
@@ -480,14 +480,33 @@ def test_a_screenshot_is_a_real_png(tmp_path):
|
|
|
480
480
|
def test_only_a_missing_sandbox_causes_a_retry():
|
|
481
481
|
"""Restarting a browser that failed for some other reason — with a weaker
|
|
482
482
|
configuration, silently — would be a bad way to hide a real problem."""
|
|
483
|
-
from comodor.browser.launch import
|
|
483
|
+
from comodor.browser.launch import _looks_like_a_sandbox_problem
|
|
484
484
|
|
|
485
|
-
assert
|
|
486
|
-
"No usable sandbox! If this is a Debian system
|
|
487
|
-
assert
|
|
485
|
+
assert _looks_like_a_sandbox_problem(
|
|
486
|
+
"No usable sandbox! If this is a Debian system...")
|
|
487
|
+
assert _looks_like_a_sandbox_problem(
|
|
488
488
|
"Failed to move to new namespace: Operation not permitted")
|
|
489
|
-
assert not
|
|
490
|
-
assert not
|
|
489
|
+
assert not _looks_like_a_sandbox_problem("could not start: file not found")
|
|
490
|
+
assert not _looks_like_a_sandbox_problem("the browser did not open a port")
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
def test_the_useful_line_is_not_always_the_first_one():
|
|
494
|
+
"""Chromium under compose says the setuid helper failed, and only mentions
|
|
495
|
+
the namespace four lines later. Matching the first line alone made the same
|
|
496
|
+
bug appear or not depending on how the container was started."""
|
|
497
|
+
from comodor.browser.launch import _first_line, _looks_like_a_sandbox_problem
|
|
498
|
+
|
|
499
|
+
printed = "\n".join([
|
|
500
|
+
"The setuid sandbox is not running as root. Common causes:",
|
|
501
|
+
" * An unprivileged process using ptrace on it, like a debugger.",
|
|
502
|
+
" * A parent process set prctl(PR_SET_NO_NEW_PRIVS, ...)",
|
|
503
|
+
"Failed to move to new namespace: ... errno = Operation not permitted",
|
|
504
|
+
])
|
|
505
|
+
|
|
506
|
+
assert _looks_like_a_sandbox_problem(printed)
|
|
507
|
+
# And what a person is shown stays one line.
|
|
508
|
+
assert "\n" not in _first_line(printed)
|
|
509
|
+
assert "setuid sandbox is not running as root" in _first_line(printed)
|
|
491
510
|
|
|
492
511
|
|
|
493
512
|
def test_a_browser_that_fails_for_another_reason_is_not_restarted(tmp_path,
|
|
@@ -517,9 +536,11 @@ def test_a_missing_sandbox_is_retried_once_without_one(tmp_path, monkeypatch):
|
|
|
517
536
|
attempts = []
|
|
518
537
|
|
|
519
538
|
def once(cls, binary, profile, port, headless, window, sandboxed):
|
|
539
|
+
from comodor.browser.launch import SandboxUnavailable
|
|
540
|
+
|
|
520
541
|
attempts.append(sandboxed)
|
|
521
542
|
if sandboxed:
|
|
522
|
-
raise
|
|
543
|
+
raise SandboxUnavailable("it exited. It said: No usable sandbox!")
|
|
523
544
|
return Browser("/bin/true", profile, port, sandboxed=False)
|
|
524
545
|
|
|
525
546
|
monkeypatch.setattr(Browser, "_spawn", classmethod(once))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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
|