@scemoon/cdh 1.0.3 → 1.0.4
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.
- package/onecode/agent/onecode_agent_acp.py +2 -2
- package/package.json +1 -1
- package/tui/__pycache__/agents.cpython-314.pyc +0 -0
- package/tui/__pycache__/settings_schema.cpython-314.pyc +0 -0
- package/tui/acp/__pycache__/messages.cpython-314.pyc +0 -0
- package/tui/agents.py +8 -7
- package/tui/data/agents/ampcode.com.toml +1 -0
- package/tui/data/agents/augmentcode.com.toml +1 -0
- package/tui/data/agents/cdh.cloud-dev-harness.toml +3 -2
- package/tui/data/agents/crowai.dev.toml +1 -0
- package/tui/data/agents/deepagents.langchain.com +1 -0
- package/tui/data/agents/docker.com.toml +1 -0
- package/tui/data/agents/goose.ai.toml +1 -0
- package/tui/data/agents/inference.huggingface.co.toml +1 -1
- package/tui/data/agents/kiro.dev.toml +1 -0
- package/tui/data/agents/onecode.dev.toml +22 -0
- package/tui/data/agents/openclaw.ai.toml +1 -1
- package/tui/data/agents/openhands.dev.toml +1 -0
- package/tui/data/agents/stakpak.dev.toml +1 -0
- package/tui/data/agents/vibe.mistral.ai.toml +1 -0
- package/tui/data/agents/vtcode.dev.toml +1 -0
- package/tui/screens/store.py +1 -1
- package/tui/settings_schema.py +1 -1
- package/tui/widgets/__pycache__/modified_files.cpython-314.pyc +0 -0
- package/tui/widgets/modified_files.py +93 -99
- package/cdh/__pycache__/__init__.cpython-313.pyc +0 -0
- package/cdh/__pycache__/__main__.cpython-314.pyc +0 -0
- package/cdh/__pycache__/scaffold.cpython-313.pyc +0 -0
- package/onecode/__pycache__/config_screen.cpython-314.pyc +0 -0
- package/onecode/__pycache__/mock_data.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/cdh_agent_acp.cpython-313.pyc +0 -0
- package/onecode/agent/__pycache__/cdh_agent_acp.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/harness_skill.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/task_tools.cpython-314.pyc +0 -0
- package/onecode/codebase/__pycache__/config.cpython-314.pyc +0 -0
- package/onecode/models/providers/__pycache__/mock_provider.cpython-314.pyc +0 -0
- package/onecode/skills/__pycache__/manager.cpython-314.pyc +0 -0
- package/onecode/tasks/__pycache__/__init__.cpython-314.pyc +0 -0
- package/onecode/tasks/__pycache__/manager.cpython-314.pyc +0 -0
- package/onecode/tasks/__pycache__/models.cpython-314.pyc +0 -0
- package/tui/__pycache__/cli.cpython-314.pyc +0 -0
- package/tui/__pycache__/danger.cpython-314.pyc +0 -0
- package/tui/__pycache__/directory_suggester.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/agent_modal.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/component_picker.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/log.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/projects_app.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/projects_screen.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/sessions.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/settings.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/store.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/acp_content.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/conversation.cpython-313.pyc +0 -0
- package/tui/widgets/__pycache__/diff_view.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/directory_input.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/future_text.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/grid_select.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/mandelbrot.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/markdown_note.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/project_grid_select.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/project_summary.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/session_grid_select.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/session_summary.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/shell_result.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/subagent_screen.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/terminal.cpython-313.pyc +0 -0
- package/tui/widgets/__pycache__/tool_call.cpython-313.pyc +0 -0
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/tui/agents.py
CHANGED
|
@@ -28,14 +28,15 @@ async def read_agents() -> dict[str, Agent]:
|
|
|
28
28
|
List of agent dicts.
|
|
29
29
|
"""
|
|
30
30
|
agents: list[Agent] = []
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
for file in files("tui.data").joinpath("agents").iterdir():
|
|
32
|
+
if file.name.startswith("."):
|
|
33
|
+
continue
|
|
34
|
+
try:
|
|
33
35
|
agent: Agent = tomllib.load(file.open("rb"))
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
raise AgentReadError(f"Failed to read agents; {error}")
|
|
36
|
+
except Exception:
|
|
37
|
+
continue
|
|
38
|
+
if agent.get("active", True):
|
|
39
|
+
agents.append(agent)
|
|
39
40
|
|
|
40
41
|
return agents
|
|
41
42
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# CDH (Cloud Dev Harness) - Agent for A2TUI
|
|
2
2
|
# https://github.com/cloud-dev-harness/cdh
|
|
3
|
+
active = false
|
|
3
4
|
|
|
4
5
|
identity = "cdh.cloud-dev-harness"
|
|
5
|
-
name = "
|
|
6
|
+
name = "OneCode (legacy)"
|
|
6
7
|
short_name = "cdh"
|
|
7
8
|
url = "https://github.com/cloud-dev-harness/cdh"
|
|
8
9
|
protocol = "acp"
|
|
@@ -11,7 +12,7 @@ author_url = "https://github.com/cloud-dev-harness"
|
|
|
11
12
|
publisher_name = "CDH Team"
|
|
12
13
|
publisher_url = "https://github.com/cloud-dev-harness"
|
|
13
14
|
type = "coding"
|
|
14
|
-
description = "
|
|
15
|
+
description = "OneCode - cloud-native development Agent framework with LLM provider integration"
|
|
15
16
|
tags = []
|
|
16
17
|
recommended = true
|
|
17
18
|
help = "CDH Agent - Cloud Dev Harness\n\nA cloud-native development Agent framework with LLM provider integration.\n\nSupported providers: MiniMax, Anthropic, OpenAI, DeepSeek, GLM, Ollama"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# OneCode Agent for A2TUI
|
|
2
|
+
# https://github.com/cloud-dev-harness/cdh
|
|
3
|
+
|
|
4
|
+
identity = "onecode.dev"
|
|
5
|
+
name = "OneCode"
|
|
6
|
+
short_name = "onecode"
|
|
7
|
+
url = "https://github.com/cloud-dev-harness/cdh"
|
|
8
|
+
protocol = "acp"
|
|
9
|
+
author_name = "OneCode AI"
|
|
10
|
+
author_url = "https://github.com/cloud-dev-harness"
|
|
11
|
+
publisher_name = "onecode"
|
|
12
|
+
publisher_url = "https://github.com/cloud-dev-harness"
|
|
13
|
+
type = "coding"
|
|
14
|
+
description = "OneCode AI - terminal coding agent with multi-LLM provider integration"
|
|
15
|
+
tags = []
|
|
16
|
+
recommended = true
|
|
17
|
+
help = "OneCode AI Agent with LLM provider integration.\n\nSupported providers: MiniMax, Anthropic, OpenAI, DeepSeek, GLM, Ollama"
|
|
18
|
+
commands_module = "onecode.commands"
|
|
19
|
+
commands_prefix = "onecode:"
|
|
20
|
+
run_command."*" = "python3 -m onecode.agent.onecode_agent_acp"
|
|
21
|
+
|
|
22
|
+
[actions]
|
package/tui/screens/store.py
CHANGED
|
@@ -421,7 +421,7 @@ class StoreScreen(Screen):
|
|
|
421
421
|
async def on_mount(self) -> None:
|
|
422
422
|
self.app.settings_changed_signal.subscribe(self, self.setting_updated)
|
|
423
423
|
if not self.app.settings.get("launcher.agents", str).strip():
|
|
424
|
-
self.app.settings.set("launcher.agents", "
|
|
424
|
+
self.app.settings.set("launcher.agents", "onecode.dev")
|
|
425
425
|
await self.app.save_settings()
|
|
426
426
|
try:
|
|
427
427
|
self._agents = await read_agents()
|
package/tui/settings_schema.py
CHANGED
|
Binary file
|
|
@@ -11,6 +11,8 @@ from textual.widgets import Static
|
|
|
11
11
|
from textual import containers
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
CONTENT_WIDTH = 35
|
|
15
|
+
|
|
14
16
|
GIT_STATUS_TIMEOUT = 5.0
|
|
15
17
|
GIT_STATUS_DEBOUNCE = 0.2
|
|
16
18
|
|
|
@@ -33,47 +35,36 @@ IGNORED_DIRS = frozenset(
|
|
|
33
35
|
}
|
|
34
36
|
)
|
|
35
37
|
|
|
38
|
+
STATUS_ICONS = {"?": "?", "M": "M", "A": "A", "D": "D", "R": "R", "C": "C"}
|
|
39
|
+
STATUS_COLORS = {"?": "green", "M": "yellow", "A": "green", "D": "red", "R": "#888888", "C": "green"}
|
|
40
|
+
DIFF_COLORS: dict[str, str] = {"add": "green", "del": "red", "mix": "yellow", "dim": "#555555"}
|
|
36
41
|
|
|
37
|
-
class ModifiedFiles(containers.Vertical):
|
|
38
|
-
DEFAULT_CSS = """
|
|
39
|
-
ModifiedFiles {
|
|
40
|
-
height: auto;
|
|
41
|
-
max-height: 15;
|
|
42
|
-
overflow-y: auto;
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
def _status_info(raw: str) -> tuple[str, str]:
|
|
44
|
+
ch = raw.strip()[:1] or "M"
|
|
45
|
+
return STATUS_ICONS.get(ch, "M"), STATUS_COLORS.get(ch, "yellow")
|
|
47
46
|
|
|
48
|
-
.file-added {
|
|
49
|
-
color: $text-success;
|
|
50
|
-
}
|
|
51
47
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
def _tag_color(added: int, deleted: int) -> str:
|
|
49
|
+
if added and deleted:
|
|
50
|
+
return DIFF_COLORS["mix"]
|
|
51
|
+
if added:
|
|
52
|
+
return DIFF_COLORS["add"]
|
|
53
|
+
if deleted:
|
|
54
|
+
return DIFF_COLORS["del"]
|
|
55
|
+
return DIFF_COLORS["dim"]
|
|
55
56
|
|
|
56
|
-
.file-deleted {
|
|
57
|
-
color: $text-error;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.file-renamed {
|
|
61
|
-
color: $text-secondary;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.no-changes {
|
|
65
|
-
color: $text-secondary;
|
|
66
|
-
text-style: italic;
|
|
67
|
-
}
|
|
68
57
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
58
|
+
class ModifiedFiles(containers.Vertical):
|
|
59
|
+
DEFAULT_CSS = """
|
|
60
|
+
ModifiedFiles {
|
|
61
|
+
height: auto;
|
|
62
|
+
overflow-y: auto;
|
|
63
|
+
padding: 0 0 0 0;
|
|
73
64
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
65
|
+
#mf-files {
|
|
66
|
+
height: auto;
|
|
67
|
+
padding: 0 0 0 1;
|
|
77
68
|
}
|
|
78
69
|
}
|
|
79
70
|
"""
|
|
@@ -92,7 +83,6 @@ class ModifiedFiles(containers.Vertical):
|
|
|
92
83
|
self._debounce_timer: Timer | None = None
|
|
93
84
|
self._status_kind: str = "no-changes"
|
|
94
85
|
self._status_text: str = NO_CHANGES_TEXT
|
|
95
|
-
self._file_widgets: list[Static] = []
|
|
96
86
|
self._initial_path: Path | None = path
|
|
97
87
|
|
|
98
88
|
def on_mount(self) -> None:
|
|
@@ -102,17 +92,14 @@ class ModifiedFiles(containers.Vertical):
|
|
|
102
92
|
self.path = initial
|
|
103
93
|
|
|
104
94
|
def watch_path(self, path: Path | None) -> None:
|
|
105
|
-
"""Schedule a (debounced, async) git status when path changes."""
|
|
106
95
|
self._cancel_debounce()
|
|
107
96
|
if path is None:
|
|
108
97
|
self._show_status("no-changes", NO_CHANGES_TEXT)
|
|
109
|
-
self._clear_file_widgets()
|
|
110
98
|
return
|
|
111
99
|
self._show_status("-loading", LOADING_TEXT)
|
|
112
100
|
self._schedule_run(path)
|
|
113
101
|
|
|
114
102
|
def refresh_files(self) -> None:
|
|
115
|
-
"""Re-run git status manually (e.g. after file system changes)."""
|
|
116
103
|
if self.path is not None:
|
|
117
104
|
self._cancel_debounce()
|
|
118
105
|
self._show_status("-loading", LOADING_TEXT)
|
|
@@ -136,8 +123,6 @@ class ModifiedFiles(containers.Vertical):
|
|
|
136
123
|
|
|
137
124
|
@work(exclusive=True, group="modified-files-git-status", thread=True)
|
|
138
125
|
def _run_git_status(self, path: Path) -> None:
|
|
139
|
-
"""Worker entry: do the slow ``git status`` off the UI thread,
|
|
140
|
-
then marshal results back via ``app.call_from_thread``."""
|
|
141
126
|
app = self.app
|
|
142
127
|
outcome = self._do_git_status(path)
|
|
143
128
|
if outcome is None:
|
|
@@ -145,24 +130,18 @@ class ModifiedFiles(containers.Vertical):
|
|
|
145
130
|
kind, text, lines = outcome
|
|
146
131
|
if lines is None:
|
|
147
132
|
app.call_from_thread(self._show_status, kind, text)
|
|
148
|
-
app.call_from_thread(self._clear_file_widgets)
|
|
149
133
|
else:
|
|
150
134
|
app.call_from_thread(self._render_lines, lines)
|
|
151
135
|
|
|
152
136
|
def _do_git_status(
|
|
153
137
|
self, path: Path
|
|
154
138
|
) -> tuple[str, str, list[str] | None] | None:
|
|
155
|
-
"""Pure helper for ``git status``. Returns
|
|
156
|
-
``(kind, text, lines_or_None)`` for the UI to render, or ``None``
|
|
157
|
-
if the call should silently no-op (e.g. ignored path).
|
|
158
|
-
"""
|
|
159
139
|
if any(part in IGNORED_DIRS for part in path.parts):
|
|
160
140
|
return ("not-a-repo", NOT_A_REPO_TEXT, None)
|
|
161
141
|
try:
|
|
162
|
-
|
|
142
|
+
status = subprocess.run(
|
|
163
143
|
["git", "-C", str(path), "status", "--porcelain"],
|
|
164
|
-
capture_output=True,
|
|
165
|
-
text=True,
|
|
144
|
+
capture_output=True, text=True,
|
|
166
145
|
timeout=GIT_STATUS_TIMEOUT,
|
|
167
146
|
)
|
|
168
147
|
except subprocess.TimeoutExpired:
|
|
@@ -171,68 +150,83 @@ class ModifiedFiles(containers.Vertical):
|
|
|
171
150
|
return ("not-a-repo", NOT_A_REPO_TEXT, None)
|
|
172
151
|
except Exception:
|
|
173
152
|
return ("no-changes", NO_CHANGES_TEXT, None)
|
|
174
|
-
if
|
|
153
|
+
if status.returncode != 0:
|
|
175
154
|
return ("not-a-repo", NOT_A_REPO_TEXT, None)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
]
|
|
155
|
+
|
|
156
|
+
lines = [l for l in status.stdout.splitlines() if l.strip()]
|
|
179
157
|
if not lines:
|
|
180
|
-
return ("no-changes", NO_CHANGES_TEXT, [])
|
|
181
|
-
return ("file-modified", "", lines)
|
|
158
|
+
return ("no-changes", NO_CHANGES_TEXT, ([], {}))
|
|
182
159
|
|
|
183
|
-
|
|
160
|
+
diffmap: dict[str, tuple[int, int]] = {}
|
|
161
|
+
for diff_cmd in (
|
|
162
|
+
["git", "-C", str(path), "diff", "--numstat"],
|
|
163
|
+
["git", "-C", str(path), "diff", "--cached", "--numstat"],
|
|
164
|
+
):
|
|
165
|
+
try:
|
|
166
|
+
r = subprocess.run(
|
|
167
|
+
diff_cmd, capture_output=True, text=True,
|
|
168
|
+
timeout=GIT_STATUS_TIMEOUT,
|
|
169
|
+
)
|
|
170
|
+
except Exception:
|
|
171
|
+
continue
|
|
172
|
+
for dl in r.stdout.splitlines():
|
|
173
|
+
parts = dl.split("\t", 2)
|
|
174
|
+
if len(parts) == 3:
|
|
175
|
+
added, deleted = parts[0], parts[1]
|
|
176
|
+
if added != "-":
|
|
177
|
+
a, d = int(added), int(deleted)
|
|
178
|
+
fp = parts[2]
|
|
179
|
+
prev_a, prev_d = diffmap.get(fp, (0, 0))
|
|
180
|
+
diffmap[fp] = (prev_a + a, prev_d + d)
|
|
181
|
+
|
|
182
|
+
return ("file-modified", "", (lines, diffmap))
|
|
183
|
+
|
|
184
|
+
def _render_lines(self, data: tuple[list[str], dict[str, tuple[int, int]]]) -> None:
|
|
185
|
+
lines, diffmap = data
|
|
184
186
|
self.files = list(lines)
|
|
185
187
|
if not lines:
|
|
186
188
|
self._show_status("no-changes", NO_CHANGES_TEXT)
|
|
187
|
-
self._clear_file_widgets()
|
|
188
189
|
return
|
|
189
190
|
self._show_status("file-modified", "")
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
191
|
+
|
|
192
|
+
out: list[str] = []
|
|
193
|
+
for raw_line in lines:
|
|
194
|
+
filepath = raw_line[3:]
|
|
195
|
+
icon, sc = _status_info(raw_line[:2])
|
|
196
|
+
|
|
197
|
+
added, deleted = diffmap.get(filepath, (0, 0))
|
|
198
|
+
if "?" in raw_line[:2]:
|
|
199
|
+
tag = "new"
|
|
200
|
+
tc = DIFF_COLORS["dim"]
|
|
201
|
+
elif "D" in raw_line[:2]:
|
|
202
|
+
tag = "del"
|
|
203
|
+
tc = DIFF_COLORS["del"]
|
|
204
|
+
elif added or deleted:
|
|
205
|
+
tag = f"+{added}/-{deleted}"
|
|
206
|
+
tc = _tag_color(added, deleted)
|
|
207
|
+
else:
|
|
208
|
+
tag = ""
|
|
209
|
+
tc = ""
|
|
210
|
+
|
|
211
|
+
tag_s = f" [{tc}]{tag}[/]" if tag else ""
|
|
212
|
+
tag_len = len(tag) + 1 if tag else 0
|
|
213
|
+
max_fn = CONTENT_WIDTH - 2 - tag_len
|
|
214
|
+
if max_fn < 3:
|
|
215
|
+
max_fn = 3
|
|
216
|
+
disp = filepath[:max_fn - 1] + "…" if len(filepath) > max_fn else filepath
|
|
217
|
+
pad = CONTENT_WIDTH - 2 - len(disp) - tag_len
|
|
218
|
+
pad_s = " " * pad if pad > 0 else ""
|
|
219
|
+
out.append(f"[{sc}]{icon} {disp}[/]{pad_s}{tag_s}")
|
|
220
|
+
|
|
221
|
+
files_widget = self.query_one("#mf-files", Static)
|
|
222
|
+
files_widget.update("\n".join(out))
|
|
202
223
|
|
|
203
224
|
def _show_status(self, kind: str, text: str) -> None:
|
|
204
225
|
self._status_kind = kind
|
|
205
226
|
self._status_text = text
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
except Exception:
|
|
209
|
-
return
|
|
210
|
-
header.set_classes(kind)
|
|
211
|
-
header.update(text)
|
|
212
|
-
if kind != "file-modified":
|
|
213
|
-
self._clear_file_widgets()
|
|
214
|
-
|
|
215
|
-
def _clear_file_widgets(self) -> None:
|
|
216
|
-
for w in self._file_widgets:
|
|
217
|
-
try:
|
|
218
|
-
w.remove()
|
|
219
|
-
except Exception:
|
|
220
|
-
pass
|
|
221
|
-
self._file_widgets = []
|
|
227
|
+
status = self.query_one("#mf-status", Static)
|
|
228
|
+
status.update(text)
|
|
222
229
|
|
|
223
230
|
def compose(self) -> ComposeResult:
|
|
224
|
-
yield Static(self._status_text,
|
|
225
|
-
|
|
226
|
-
@staticmethod
|
|
227
|
-
def _class_for_status(status: str) -> str:
|
|
228
|
-
if "?" in status:
|
|
229
|
-
return "file-added"
|
|
230
|
-
if "D" in status:
|
|
231
|
-
return "file-deleted"
|
|
232
|
-
if "A" in status or "C" in status:
|
|
233
|
-
return "file-added"
|
|
234
|
-
if "R" in status:
|
|
235
|
-
return "file-renamed"
|
|
236
|
-
if "M" in status:
|
|
237
|
-
return "file-modified"
|
|
238
|
-
return "file-modified"
|
|
231
|
+
yield Static(self._status_text, id="mf-status")
|
|
232
|
+
yield Static("", id="mf-files")
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|