wafer-cli 0.2.37__tar.gz → 0.2.39__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.
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/PKG-INFO +1 -1
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/pyproject.toml +1 -1
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/agent_defaults.py +48 -1
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/cli.py +54 -11
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/wevin_cli.py +36 -3
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer_cli.egg-info/PKG-INFO +1 -1
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/README.md +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/setup.cfg +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_analytics.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_auth.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_billing.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_cli_coverage.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_cli_parity_integration.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_config_integration.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_file_operations_integration.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_kernel_scope_cli.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_nsys_analyze.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_nsys_profile.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_output.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_rocprof_compute_integration.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_skill_commands.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_ssh_integration.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_targets_ops.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_wevin_cli.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/tests/test_workflow_integration.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/GUIDE.md +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/__init__.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/analytics.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/api_client.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/auth.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/autotuner.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/baseline.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/billing.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/cli_instructions.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/config.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/corpus.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/evaluate.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/global_config.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/gpu_run.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/inference.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/kernel_scope.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/ncu_analyze.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/nsys_analyze.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/nsys_profile.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/output.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/problems.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/rocprof_compute.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/rocprof_sdk.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/rocprof_systems.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/skills/wafer-guide/SKILL.md +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/specs_cli.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/ssh_keys.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/target_lock.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/targets.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/targets_cli.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/targets_ops.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/templates/__init__.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/templates/aiter_optimize.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/templates/ask_docs.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/templates/optimize_kernel.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/templates/optimize_kernelbench.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/templates/optimize_vllm.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/templates/trace_analyze.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/tests/test_eval_cli_parity.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/trace_compare.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/tracelens.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer/workspaces.py +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer_cli.egg-info/SOURCES.txt +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer_cli.egg-info/dependency_links.txt +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer_cli.egg-info/entry_points.txt +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer_cli.egg-info/requires.txt +0 -0
- {wafer_cli-0.2.37 → wafer_cli-0.2.39}/wafer_cli.egg-info/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Shared agent defaults for kernel
|
|
1
|
+
"""Shared agent defaults for kernel tasks.
|
|
2
2
|
|
|
3
3
|
Single source of truth for bash allowlists and enabled tools used by both:
|
|
4
4
|
- CLI templates (apps/wafer-cli/wafer/templates/*.py)
|
|
@@ -195,3 +195,50 @@ VLLM_BASH_ALLOWLIST: list[str] = [
|
|
|
195
195
|
"cd",
|
|
196
196
|
"git",
|
|
197
197
|
]
|
|
198
|
+
|
|
199
|
+
# Tools available to audit agents (read-only + bash for compilation/profiling)
|
|
200
|
+
AUDIT_ENABLED_TOOLS: list[str] = ["read", "glob", "grep", "bash"]
|
|
201
|
+
|
|
202
|
+
# Bash commands allowed for kernel audit agents.
|
|
203
|
+
AUDIT_BASH_ALLOWLIST: list[str] = [
|
|
204
|
+
# Read-only
|
|
205
|
+
"ls",
|
|
206
|
+
"cat",
|
|
207
|
+
"head",
|
|
208
|
+
"tail",
|
|
209
|
+
"wc",
|
|
210
|
+
"find",
|
|
211
|
+
"grep",
|
|
212
|
+
"rg",
|
|
213
|
+
"pwd",
|
|
214
|
+
"tree",
|
|
215
|
+
"which",
|
|
216
|
+
"diff",
|
|
217
|
+
"sort",
|
|
218
|
+
# Filesystem
|
|
219
|
+
"mkdir",
|
|
220
|
+
# Compilation
|
|
221
|
+
"make",
|
|
222
|
+
"cmake",
|
|
223
|
+
"nvcc",
|
|
224
|
+
"hipcc",
|
|
225
|
+
"g++",
|
|
226
|
+
"gcc",
|
|
227
|
+
"clang",
|
|
228
|
+
"python",
|
|
229
|
+
"python3",
|
|
230
|
+
# Execution — allows running compiled binaries via ./path.
|
|
231
|
+
# Security note: the agent can already compile arbitrary code via hipcc/gcc/etc,
|
|
232
|
+
# so blocking ./ execution doesn't add meaningful protection.
|
|
233
|
+
"./",
|
|
234
|
+
# Profiling
|
|
235
|
+
"wafer evaluate",
|
|
236
|
+
"wafer nvidia ncu",
|
|
237
|
+
"wafer nvidia nsys",
|
|
238
|
+
"wafer amd rocprof-compute",
|
|
239
|
+
"wafer amd rocprof-sdk",
|
|
240
|
+
"wafer amd rocprof-systems",
|
|
241
|
+
"wafer compiler-analyze",
|
|
242
|
+
# Misc
|
|
243
|
+
"timeout",
|
|
244
|
+
]
|
|
@@ -1497,6 +1497,7 @@ def _make_agent_alias(name: str, doc: str) -> None:
|
|
|
1497
1497
|
template_args: list[str] | None = typer.Option(None, "--args"),
|
|
1498
1498
|
corpus: str | None = typer.Option(None, "--corpus"),
|
|
1499
1499
|
no_sandbox: bool = typer.Option(False, "--no-sandbox"),
|
|
1500
|
+
no_proxy: bool = typer.Option(False, "--no-proxy"),
|
|
1500
1501
|
) -> None:
|
|
1501
1502
|
agent(
|
|
1502
1503
|
prompt=prompt,
|
|
@@ -1517,6 +1518,7 @@ def _make_agent_alias(name: str, doc: str) -> None:
|
|
|
1517
1518
|
template_args=template_args,
|
|
1518
1519
|
corpus=corpus,
|
|
1519
1520
|
no_sandbox=no_sandbox,
|
|
1521
|
+
no_proxy=no_proxy,
|
|
1520
1522
|
)
|
|
1521
1523
|
|
|
1522
1524
|
alias_cmd.__doc__ = doc
|
|
@@ -1860,6 +1862,12 @@ def kernelbench_evaluate( # noqa: PLR0913, PLR0915
|
|
|
1860
1862
|
help="Sync files and generate eval script but don't run. "
|
|
1861
1863
|
"Prints the command to run manually (useful for wrapping with rocprof, etc.)",
|
|
1862
1864
|
),
|
|
1865
|
+
pool_timeout: int = typer.Option(
|
|
1866
|
+
600,
|
|
1867
|
+
"--pool-timeout",
|
|
1868
|
+
help="Seconds to wait for a target from the pool before failing (default: 600). "
|
|
1869
|
+
"Set to 0 for immediate failure if all targets are busy.",
|
|
1870
|
+
),
|
|
1863
1871
|
json_output: bool = typer.Option(
|
|
1864
1872
|
False, "--json", help="Output as single JSON object (machine-readable)"
|
|
1865
1873
|
),
|
|
@@ -1951,14 +1959,24 @@ def kernelbench_evaluate( # noqa: PLR0913, PLR0915
|
|
|
1951
1959
|
collector.finalize()
|
|
1952
1960
|
raise typer.Exit(1) from None
|
|
1953
1961
|
|
|
1954
|
-
|
|
1955
|
-
|
|
1962
|
+
effective_timeout = pool_timeout if pool_timeout > 0 else None
|
|
1963
|
+
collector.emit("pool_acquire", pool=pool, count=len(usable_targets), timeout=pool_timeout)
|
|
1964
|
+
pool_lock_context = acquire_from_pool(usable_targets, timeout=effective_timeout)
|
|
1956
1965
|
acquired_target = pool_lock_context.__enter__()
|
|
1957
1966
|
|
|
1958
1967
|
if acquired_target is None:
|
|
1959
1968
|
# Exit context manager before raising to avoid resource leak
|
|
1960
1969
|
pool_lock_context.__exit__(None, None, None)
|
|
1961
|
-
|
|
1970
|
+
if pool_timeout > 0:
|
|
1971
|
+
collector.set_error(
|
|
1972
|
+
"pool",
|
|
1973
|
+
"AllTargetsBusy",
|
|
1974
|
+
pool=pool,
|
|
1975
|
+
targets=usable_targets,
|
|
1976
|
+
message=f"All targets busy after waiting {pool_timeout}s",
|
|
1977
|
+
)
|
|
1978
|
+
else:
|
|
1979
|
+
collector.set_error("pool", "AllTargetsBusy", pool=pool, targets=usable_targets)
|
|
1962
1980
|
collector.finalize()
|
|
1963
1981
|
raise typer.Exit(1)
|
|
1964
1982
|
|
|
@@ -2313,6 +2331,12 @@ def gpumode_evaluate( # noqa: PLR0913, PLR0915
|
|
|
2313
2331
|
True, "--sync-artifacts/--no-sync-artifacts", help="Download artifacts"
|
|
2314
2332
|
),
|
|
2315
2333
|
gpu_id: int | None = typer.Option(None, "--gpu-id", help="Override GPU ID"),
|
|
2334
|
+
pool_timeout: int = typer.Option(
|
|
2335
|
+
600,
|
|
2336
|
+
"--pool-timeout",
|
|
2337
|
+
help="Seconds to wait for a target from the pool before failing (default: 600). "
|
|
2338
|
+
"Set to 0 for immediate failure if all targets are busy.",
|
|
2339
|
+
),
|
|
2316
2340
|
) -> None:
|
|
2317
2341
|
"""Run kernel evaluation in GPUMode format (functional).
|
|
2318
2342
|
|
|
@@ -2392,14 +2416,21 @@ def gpumode_evaluate( # noqa: PLR0913, PLR0915
|
|
|
2392
2416
|
typer.echo(" Run 'wafer auth status' to see which providers need setup.", err=True)
|
|
2393
2417
|
raise typer.Exit(1) from None
|
|
2394
2418
|
|
|
2419
|
+
effective_timeout = pool_timeout if pool_timeout > 0 else None
|
|
2395
2420
|
typer.echo(f"Acquiring target from pool '{pool}' ({len(usable_targets)} targets)...")
|
|
2396
|
-
pool_lock_context = acquire_from_pool(usable_targets)
|
|
2421
|
+
pool_lock_context = acquire_from_pool(usable_targets, timeout=effective_timeout)
|
|
2397
2422
|
acquired_target = pool_lock_context.__enter__()
|
|
2398
2423
|
|
|
2399
2424
|
if acquired_target is None:
|
|
2400
2425
|
# Exit context manager before raising to avoid resource leak
|
|
2401
2426
|
pool_lock_context.__exit__(None, None, None)
|
|
2402
|
-
|
|
2427
|
+
if pool_timeout > 0:
|
|
2428
|
+
typer.echo(
|
|
2429
|
+
f"Error: All targets in pool '{pool}' are busy (waited {pool_timeout}s)",
|
|
2430
|
+
err=True,
|
|
2431
|
+
)
|
|
2432
|
+
else:
|
|
2433
|
+
typer.echo(f"Error: All targets in pool '{pool}' are busy", err=True)
|
|
2403
2434
|
typer.echo(f" Targets: {', '.join(usable_targets)}", err=True)
|
|
2404
2435
|
raise typer.Exit(1)
|
|
2405
2436
|
|
|
@@ -7749,16 +7780,24 @@ def compare_analyze(
|
|
|
7749
7780
|
"-f",
|
|
7750
7781
|
help="Output format: text, text-layers, csv, csv-layers, json",
|
|
7751
7782
|
),
|
|
7752
|
-
output: Path | None = typer.Option(
|
|
7783
|
+
output: Path | None = typer.Option(
|
|
7784
|
+
None, "--output", "-o", help="Output file (default: stdout)"
|
|
7785
|
+
),
|
|
7753
7786
|
phase: str = typer.Option(
|
|
7754
7787
|
"all",
|
|
7755
7788
|
"--phase",
|
|
7756
7789
|
help="Filter by phase: all, prefill, decode",
|
|
7757
7790
|
),
|
|
7758
7791
|
layers: bool = typer.Option(False, "--layers", help="Show layer-wise performance breakdown"),
|
|
7759
|
-
all: bool = typer.Option(
|
|
7760
|
-
|
|
7761
|
-
|
|
7792
|
+
all: bool = typer.Option(
|
|
7793
|
+
False, "--all", help="Show all items (no truncation for layers, operations, kernels)"
|
|
7794
|
+
),
|
|
7795
|
+
stack_traces: bool = typer.Option(
|
|
7796
|
+
False, "--stack-traces", help="Show Python stack traces for operations"
|
|
7797
|
+
),
|
|
7798
|
+
json: bool = typer.Option(
|
|
7799
|
+
False, "--json", hidden=True, help="Ignored (for compatibility with cliExecutor)"
|
|
7800
|
+
),
|
|
7762
7801
|
) -> None:
|
|
7763
7802
|
"""Compare GPU traces from two platforms platforms.
|
|
7764
7803
|
|
|
@@ -7822,13 +7861,17 @@ def compare_fusion_cmd(
|
|
|
7822
7861
|
"-f",
|
|
7823
7862
|
help="Output format: text, csv, json",
|
|
7824
7863
|
),
|
|
7825
|
-
output: Path | None = typer.Option(
|
|
7864
|
+
output: Path | None = typer.Option(
|
|
7865
|
+
None, "--output", "-o", help="Output file (default: stdout)"
|
|
7866
|
+
),
|
|
7826
7867
|
min_group_size: int = typer.Option(
|
|
7827
7868
|
50,
|
|
7828
7869
|
"--min-group-size",
|
|
7829
7870
|
help="Minimum correlation group size to analyze",
|
|
7830
7871
|
),
|
|
7831
|
-
json: bool = typer.Option(
|
|
7872
|
+
json: bool = typer.Option(
|
|
7873
|
+
False, "--json", hidden=True, help="Ignored (for compatibility with cliExecutor)"
|
|
7874
|
+
),
|
|
7832
7875
|
) -> None:
|
|
7833
7876
|
"""Analyze kernel fusion differences between AMD and NVIDIA traces.
|
|
7834
7877
|
|
|
@@ -326,13 +326,28 @@ def _build_environment(
|
|
|
326
326
|
tools_override: list[str] | None,
|
|
327
327
|
corpus_path: str | None,
|
|
328
328
|
no_sandbox: bool = False,
|
|
329
|
+
has_target: bool = False,
|
|
330
|
+
template_args: dict[str, str] | None = None,
|
|
329
331
|
) -> Environment:
|
|
330
|
-
"""Build a CodingEnvironment from template config.
|
|
332
|
+
"""Build a CodingEnvironment from template config.
|
|
333
|
+
|
|
334
|
+
Working directory priority:
|
|
335
|
+
1. Template arg "dir" (--args dir=./my_project) — scopes agent to a directory
|
|
336
|
+
2. corpus_path (--corpus cuda) — for doc-browsing templates
|
|
337
|
+
3. Current working directory
|
|
338
|
+
"""
|
|
331
339
|
from wafer_core.environments.coding import CodingEnvironment
|
|
332
340
|
from wafer_core.rollouts.templates import DANGEROUS_BASH_COMMANDS
|
|
333
341
|
from wafer_core.sandbox import SandboxMode
|
|
334
342
|
|
|
335
|
-
|
|
343
|
+
# Template arg "dir" takes priority over corpus_path
|
|
344
|
+
dir_arg = (template_args or {}).get("dir")
|
|
345
|
+
if dir_arg:
|
|
346
|
+
working_dir = Path(dir_arg).resolve()
|
|
347
|
+
elif corpus_path:
|
|
348
|
+
working_dir = Path(corpus_path)
|
|
349
|
+
else:
|
|
350
|
+
working_dir = Path.cwd()
|
|
336
351
|
resolved_tools = list(tools_override or tpl.tools)
|
|
337
352
|
|
|
338
353
|
# Add skill tool if skills are enabled
|
|
@@ -340,12 +355,18 @@ def _build_environment(
|
|
|
340
355
|
resolved_tools.append("skill")
|
|
341
356
|
|
|
342
357
|
sandbox_mode = SandboxMode.DISABLED if no_sandbox else SandboxMode.ENABLED
|
|
358
|
+
|
|
359
|
+
# Enable network when a target is configured — the agent needs to reach
|
|
360
|
+
# remote GPUs via SSH/HTTPS. Filesystem sandbox stays enforced.
|
|
361
|
+
allow_network = has_target
|
|
362
|
+
|
|
343
363
|
env: Environment = CodingEnvironment(
|
|
344
364
|
working_dir=working_dir,
|
|
345
365
|
enabled_tools=resolved_tools,
|
|
346
366
|
bash_allowlist=tpl.bash_allowlist,
|
|
347
367
|
bash_denylist=DANGEROUS_BASH_COMMANDS,
|
|
348
368
|
sandbox_mode=sandbox_mode,
|
|
369
|
+
allow_network=allow_network,
|
|
349
370
|
) # type: ignore[assignment]
|
|
350
371
|
return env
|
|
351
372
|
|
|
@@ -589,9 +610,21 @@ def main( # noqa: PLR0913, PLR0915
|
|
|
589
610
|
# CLI args override template values
|
|
590
611
|
resolved_single_turn = single_turn if single_turn is not None else tpl.single_turn
|
|
591
612
|
|
|
613
|
+
# Check if a default target is configured — if so, enable network access
|
|
614
|
+
# so the agent can reach remote GPUs via SSH/HTTPS.
|
|
615
|
+
has_target = False
|
|
616
|
+
try:
|
|
617
|
+
from wafer.targets import get_default_target
|
|
618
|
+
|
|
619
|
+
has_target = get_default_target() is not None
|
|
620
|
+
except Exception:
|
|
621
|
+
pass # No target configured — network stays disabled
|
|
622
|
+
|
|
592
623
|
# Build endpoint and environment
|
|
593
624
|
endpoint = _build_endpoint(tpl, model, api_base, api_key, api_key_refresh)
|
|
594
|
-
environment = _build_environment(
|
|
625
|
+
environment = _build_environment(
|
|
626
|
+
tpl, tools, corpus_path, no_sandbox, has_target=has_target, template_args=template_args
|
|
627
|
+
)
|
|
595
628
|
|
|
596
629
|
# Session store
|
|
597
630
|
session_store = FileSessionStore()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|