domd 2.2.1__tar.gz → 2.2.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.
- {domd-2.2.1 → domd-2.2.3}/PKG-INFO +1 -1
- {domd-2.2.1 → domd-2.2.3}/pyproject.toml +1 -1
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/project_detection/detector.py +112 -67
- {domd-2.2.1 → domd-2.2.3}/LICENSE +0 -0
- {domd-2.2.1 → domd-2.2.3}/README.md +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/api/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/api/flask_api.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/cli/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/cli/command_presenter.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/formatters/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/formatters/markdown_formatter.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/persistence/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/persistence/in_memory_command_repository.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/adapters/persistence/shell_command_executor.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/api.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/application/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/application/factory.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/cli.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/command_execution/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/command_execution/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/command_execution/command_executor.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/command_execution/command_recorder.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/command_execution/command_runner.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/command_execution/environment_detector.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/command_execution/executor.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/commands/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/commands/command.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/commands/executor.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/detector.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/domain/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/domain/command.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/ansible_galaxy.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/ansible_inventory.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/ansible_playbook.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/ansible_role.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/ansible_vault.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/base.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/cargo_toml.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/composer_json.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/go_mod.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/makefile.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/package_json.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/pyproject_toml.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsers/tox_ini.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsing/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsing/base.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsing/file_processor.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsing/parser_registry.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/parsing/pattern_matcher.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/ports/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/ports/command_executor.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/ports/command_repository.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/ports/report_formatter.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/project_detection/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/project_detection/command_handling.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/project_detection/config_files.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/project_detection/virtualenv.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/reporters/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/reporters/base.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/reporters/done_md.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/reporters/todo_md.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/reporting/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/reporting/formatters.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/reporting/reporter.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/services/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/services/command_service.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/services/report_service.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/utils/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/utils/command_utils.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/utils/environment.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/utils/file_utils.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/utils/logging_utils.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/core/utils/virtualenv.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/ansible.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/base.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/build_systems.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/ci_cd.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/docker/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/docker/docker_compose.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/docker/dockerfile.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/docker.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/javascript/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/javascript.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/package_json.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/python.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/test_build_systems.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/test_ci_cd.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/test_docker.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/test_javascript.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsers/test_python.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsing/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/parsing/base.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/reporters/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/reporters/console.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/reporters/json_reporter.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/reporters/test_console.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/reporters/test_json_reporter.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/reporters/test_todo_md.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/reporters/todo_md.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/reporting/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/utils/__init__.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/utils/command_runner.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/utils/file_utils.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/utils/test_command_runner.py +0 -0
- {domd-2.2.1 → domd-2.2.3}/src/domd/utils/test_file_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "domd"
|
|
3
|
-
version = "2.2.
|
|
3
|
+
version = "2.2.3"
|
|
4
4
|
description = "Project Command Detector - Automatically detects and tests project commands, generates TODO.md for failed commands"
|
|
5
5
|
authors = ["Tom Sapletta <info@softreck.dev>"]
|
|
6
6
|
maintainers = ["WRONAI Team"]
|
|
@@ -213,6 +213,56 @@ class ProjectCommandDetector:
|
|
|
213
213
|
"""
|
|
214
214
|
return get_virtualenv_environment(self.venv_info)
|
|
215
215
|
|
|
216
|
+
def _process_directory_readme(
|
|
217
|
+
self, directory: Path, all_commands: list, parent_dir: str = None
|
|
218
|
+
) -> None:
|
|
219
|
+
"""Process a README.md file in a directory and update command metadata.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
directory: Directory containing the README.md
|
|
223
|
+
all_commands: List to append found commands to
|
|
224
|
+
parent_dir: Name of parent directory (for second-level directories)
|
|
225
|
+
"""
|
|
226
|
+
logger.debug(f"Checking for README.md in: {directory}")
|
|
227
|
+
readme_path = directory / "README.md"
|
|
228
|
+
|
|
229
|
+
if not readme_path.exists():
|
|
230
|
+
logger.debug(f" README.md not found in {directory}")
|
|
231
|
+
return
|
|
232
|
+
|
|
233
|
+
if not readme_path.is_file():
|
|
234
|
+
logger.debug(f" README.md exists but is not a file in {directory}")
|
|
235
|
+
return
|
|
236
|
+
|
|
237
|
+
logger.info(f"Found README.md in directory: {directory}")
|
|
238
|
+
|
|
239
|
+
# Determine display path for logging and source
|
|
240
|
+
if parent_dir:
|
|
241
|
+
display_path = f"{parent_dir}/{directory.name}/README.md"
|
|
242
|
+
else:
|
|
243
|
+
display_path = f"{directory.name}/README.md"
|
|
244
|
+
|
|
245
|
+
logger.info(f"Found README.md: {display_path}")
|
|
246
|
+
|
|
247
|
+
# Process README.md in directory
|
|
248
|
+
commands = self._process_file_commands(readme_path)
|
|
249
|
+
|
|
250
|
+
# Update command metadata with directory context
|
|
251
|
+
for cmd in commands:
|
|
252
|
+
if isinstance(cmd, dict):
|
|
253
|
+
cmd_metadata = cmd.setdefault("metadata", {})
|
|
254
|
+
cmd_metadata["cwd"] = str(directory)
|
|
255
|
+
cmd_metadata["source"] = display_path
|
|
256
|
+
elif hasattr(cmd, "metadata"):
|
|
257
|
+
if not hasattr(cmd.metadata, "get") or not callable(cmd.metadata.get):
|
|
258
|
+
cmd.metadata = {"original_metadata": cmd.metadata}
|
|
259
|
+
cmd.metadata["cwd"] = str(directory)
|
|
260
|
+
if not getattr(cmd, "source", None):
|
|
261
|
+
cmd.source = display_path
|
|
262
|
+
|
|
263
|
+
all_commands.extend(commands)
|
|
264
|
+
logger.info(f"Found {len(commands)} commands in {display_path}")
|
|
265
|
+
|
|
216
266
|
def _process_file_commands(self, file_path: Path) -> List[Dict]:
|
|
217
267
|
"""Process a single file and extract commands.
|
|
218
268
|
|
|
@@ -220,54 +270,41 @@ class ProjectCommandDetector:
|
|
|
220
270
|
file_path: Path to the file to process
|
|
221
271
|
|
|
222
272
|
Returns:
|
|
223
|
-
List of command dictionaries
|
|
273
|
+
List of command dictionaries with metadata
|
|
224
274
|
"""
|
|
275
|
+
logger.debug(f"Processing file: {file_path}")
|
|
225
276
|
commands = []
|
|
226
|
-
try:
|
|
227
|
-
# Try to get parser from registry first
|
|
228
|
-
parser = self.parser_registry.get_parser_for_file(file_path)
|
|
229
|
-
|
|
230
|
-
# If no parser found in registry, try legacy method
|
|
231
|
-
if not parser:
|
|
232
|
-
parser = self._get_parser_for_file(file_path)
|
|
233
277
|
|
|
234
|
-
|
|
235
|
-
|
|
278
|
+
try:
|
|
279
|
+
if not file_path.exists():
|
|
280
|
+
logger.warning(f"File not found: {file_path}")
|
|
236
281
|
return commands
|
|
237
282
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
with open(file_path, "r", encoding="utf-8") as f:
|
|
243
|
-
content = f.read()
|
|
244
|
-
except Exception as e:
|
|
245
|
-
logger.error(f"Error reading file {file_path}: {e}")
|
|
283
|
+
# Get the appropriate parser for the file
|
|
284
|
+
parser = self._get_parser_for_file(file_path)
|
|
285
|
+
if not parser:
|
|
286
|
+
logger.debug(f"No parser found for file: {file_path}")
|
|
246
287
|
return commands
|
|
247
288
|
|
|
248
|
-
# Set the file_path on the parser if it has that attribute
|
|
249
|
-
if hasattr(parser, "file_path"):
|
|
250
|
-
parser.file_path = file_path
|
|
251
|
-
|
|
252
|
-
# Try different ways to call the parse method
|
|
253
289
|
try:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
290
|
+
# Read file content
|
|
291
|
+
content = file_path.read_text(encoding="utf-8")
|
|
292
|
+
|
|
293
|
+
# Parse commands from file content
|
|
294
|
+
file_commands = []
|
|
295
|
+
if hasattr(parser, "parse_file") and callable(parser.parse_file):
|
|
296
|
+
file_commands = parser.parse_file(file_path)
|
|
297
|
+
elif hasattr(parser, "parse") and callable(parser.parse):
|
|
298
|
+
# Try with content as string
|
|
299
|
+
try:
|
|
300
|
+
file_commands = parser.parse(content)
|
|
301
|
+
except TypeError:
|
|
302
|
+
# Last resort - try passing content as the first argument
|
|
303
|
+
file_commands = parser.parse(content)
|
|
267
304
|
|
|
268
305
|
# Add file path to commands if not already present
|
|
269
306
|
for cmd in file_commands:
|
|
270
|
-
if isinstance(cmd, dict)
|
|
307
|
+
if isinstance(cmd, dict):
|
|
271
308
|
cmd["file"] = str(file_path)
|
|
272
309
|
# Add relative path as source if not present
|
|
273
310
|
if "source" not in cmd:
|
|
@@ -309,37 +346,47 @@ class ProjectCommandDetector:
|
|
|
309
346
|
for file_path in config_files:
|
|
310
347
|
all_commands.extend(self._process_file_commands(file_path))
|
|
311
348
|
|
|
312
|
-
# 2. Scan first
|
|
349
|
+
# 2. Scan first and second level subdirectories for README.md files
|
|
313
350
|
try:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
all_commands.extend(commands)
|
|
351
|
+
logger.debug(f"Starting directory scan in: {self.project_path}")
|
|
352
|
+
# First level directories
|
|
353
|
+
for level1_item in sorted(self.project_path.iterdir()):
|
|
354
|
+
logger.debug(f"Checking first level item: {level1_item}")
|
|
355
|
+
if not level1_item.is_dir() or level1_item.name.startswith("."):
|
|
356
|
+
logger.debug(f"Skipping (not a directory or hidden): {level1_item}")
|
|
357
|
+
continue
|
|
358
|
+
|
|
359
|
+
logger.info(f"Processing first level directory: {level1_item.name}")
|
|
360
|
+
# Process level 1 README
|
|
361
|
+
self._process_directory_readme(level1_item, all_commands)
|
|
362
|
+
|
|
363
|
+
# Scan second level
|
|
364
|
+
try:
|
|
365
|
+
for level2_item in sorted(level1_item.iterdir()):
|
|
366
|
+
logger.debug(f" Checking second level item: {level2_item}")
|
|
367
|
+
if not level2_item.is_dir() or level2_item.name.startswith("."):
|
|
368
|
+
logger.debug(
|
|
369
|
+
f" Skipping (not a directory or hidden): {level2_item}"
|
|
370
|
+
)
|
|
371
|
+
continue
|
|
372
|
+
|
|
338
373
|
logger.info(
|
|
339
|
-
f"
|
|
374
|
+
f" Processing second level directory: {level1_item.name}/{level2_item.name}"
|
|
340
375
|
)
|
|
376
|
+
# Process level 2 README
|
|
377
|
+
self._process_directory_readme(
|
|
378
|
+
level2_item, all_commands, level1_item.name
|
|
379
|
+
)
|
|
380
|
+
except Exception as e:
|
|
381
|
+
logger.error(
|
|
382
|
+
f"Error scanning subdirectory {level1_item}: {e}", exc_info=True
|
|
383
|
+
)
|
|
341
384
|
except Exception as e:
|
|
342
|
-
logger.error(f"Error scanning
|
|
385
|
+
logger.error(f"Error scanning directories: {e}", exc_info=True)
|
|
386
|
+
|
|
387
|
+
logger.debug(
|
|
388
|
+
f"Finished directory scan. Found {len(all_commands)} commands total."
|
|
389
|
+
)
|
|
343
390
|
|
|
344
391
|
logger.info(f"Found {len(all_commands)} commands in total")
|
|
345
392
|
|
|
@@ -654,9 +701,7 @@ class ProjectCommandDetector:
|
|
|
654
701
|
source = cmd_dict.get("source", "Unknown")
|
|
655
702
|
|
|
656
703
|
f.write(f"### 🔧 Fix: {command}\n") # noqa: E231
|
|
657
|
-
f.write(
|
|
658
|
-
f"- [ ] **Command**: `{command}` \n"
|
|
659
|
-
) # noqa: E201,E231
|
|
704
|
+
f.write(f"- [ ] **Command**: `{command}` \n") # noqa: E201,E231
|
|
660
705
|
f.write(f"- **Error**: {error} \n") # noqa: E231
|
|
661
706
|
f.write(f"- **Source**: `{source}`\n") # noqa: E231
|
|
662
707
|
f.write("- **Fix Suggestion**: \n\n") # noqa: E231
|
|
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
|