ase-python 0.1.0__tar.gz → 0.1.2__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.
Files changed (157) hide show
  1. {ase_python-0.1.0 → ase_python-0.1.2}/PKG-INFO +1 -1
  2. {ase_python-0.1.0 → ase_python-0.1.2}/docs/releasing.md +3 -3
  3. {ase_python-0.1.0 → ase_python-0.1.2}/pyproject.toml +1 -1
  4. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/__init__.py +1 -1
  5. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/examples_cmd.py +6 -1
  6. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/examples_matrix.py +17 -0
  7. ase_python-0.1.2/tests/unit/test_examples_cmd.py +18 -0
  8. ase_python-0.1.2/tests/unit/test_examples_matrix.py +21 -0
  9. {ase_python-0.1.0 → ase_python-0.1.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  10. {ase_python-0.1.0 → ase_python-0.1.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  11. {ase_python-0.1.0 → ase_python-0.1.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  12. {ase_python-0.1.0 → ase_python-0.1.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  13. {ase_python-0.1.0 → ase_python-0.1.2}/.github/workflows/certify.yml +0 -0
  14. {ase_python-0.1.0 → ase_python-0.1.2}/.github/workflows/publish-pypi.yml +0 -0
  15. {ase_python-0.1.0 → ase_python-0.1.2}/.gitignore +0 -0
  16. {ase_python-0.1.0 → ase_python-0.1.2}/.gitlab-ci.yml +0 -0
  17. {ase_python-0.1.0 → ase_python-0.1.2}/CODE_OF_CONDUCT.md +0 -0
  18. {ase_python-0.1.0 → ase_python-0.1.2}/CONTRIBUTING.md +0 -0
  19. {ase_python-0.1.0 → ase_python-0.1.2}/LICENSE +0 -0
  20. {ase_python-0.1.0 → ase_python-0.1.2}/README.md +0 -0
  21. {ase_python-0.1.0 → ase_python-0.1.2}/README_PYPI.md +0 -0
  22. {ase_python-0.1.0 → ase_python-0.1.2}/SECURITY.md +0 -0
  23. {ase_python-0.1.0 → ase_python-0.1.2}/conformance/bundles/mcp/mcp-python/events.jsonl +0 -0
  24. {ase_python-0.1.0 → ase_python-0.1.2}/conformance/bundles/mcp/mcp-python/manifest.yaml +0 -0
  25. {ase_python-0.1.0 → ase_python-0.1.2}/constraints/py311.txt +0 -0
  26. {ase_python-0.1.0 → ase_python-0.1.2}/docs/README.md +0 -0
  27. {ase_python-0.1.0 → ase_python-0.1.2}/docs/architecture-boundaries.md +0 -0
  28. {ase_python-0.1.0 → ase_python-0.1.2}/docs/assets/README.md +0 -0
  29. {ase_python-0.1.0 → ase_python-0.1.2}/docs/assets/before-after-regression.svg +0 -0
  30. {ase_python-0.1.0 → ase_python-0.1.2}/docs/assets/before-after-safety.svg +0 -0
  31. {ase_python-0.1.0 → ase_python-0.1.2}/docs/assets/before-after-side-effects.svg +0 -0
  32. {ase_python-0.1.0 → ase_python-0.1.2}/docs/assets/dev-loop.svg +0 -0
  33. {ase_python-0.1.0 → ase_python-0.1.2}/docs/assets/how-ase-works.svg +0 -0
  34. {ase_python-0.1.0 → ase_python-0.1.2}/docs/assets/workflow-overview.svg +0 -0
  35. {ase_python-0.1.0 → ase_python-0.1.2}/docs/build-an-adapter.md +0 -0
  36. {ase_python-0.1.0 → ase_python-0.1.2}/docs/case-studies/README.md +0 -0
  37. {ase_python-0.1.0 → ase_python-0.1.2}/docs/case-studies/langgraph-wrong-record.md +0 -0
  38. {ase_python-0.1.0 → ase_python-0.1.2}/docs/case-studies/openai-prompt-regression.md +0 -0
  39. {ase_python-0.1.0 → ase_python-0.1.2}/docs/case-studies/pydantic-approval-gate.md +0 -0
  40. {ase_python-0.1.0 → ase_python-0.1.2}/docs/certify-a-framework.md +0 -0
  41. {ase_python-0.1.0 → ase_python-0.1.2}/docs/ci-cd.md +0 -0
  42. {ase_python-0.1.0 → ase_python-0.1.2}/docs/compatibility-matrix.md +0 -0
  43. {ase_python-0.1.0 → ase_python-0.1.2}/docs/compatibility-policy.md +0 -0
  44. {ase_python-0.1.0 → ase_python-0.1.2}/docs/example-workflows.md +0 -0
  45. {ase_python-0.1.0 → ase_python-0.1.2}/docs/how-ase-works.md +0 -0
  46. {ase_python-0.1.0 → ase_python-0.1.2}/docs/interoperability.md +0 -0
  47. {ase_python-0.1.0 → ase_python-0.1.2}/docs/release-checklist.md +0 -0
  48. {ase_python-0.1.0 → ase_python-0.1.2}/docs/setup.md +0 -0
  49. {ase_python-0.1.0 → ase_python-0.1.2}/docs/what-ase-certifies.md +0 -0
  50. {ase_python-0.1.0 → ase_python-0.1.2}/docs/why-ase-is-critical.md +0 -0
  51. {ase_python-0.1.0 → ase_python-0.1.2}/examples/mcp-python/README.md +0 -0
  52. {ase_python-0.1.0 → ase_python-0.1.2}/examples/mcp-python/agent.py +0 -0
  53. {ase_python-0.1.0 → ase_python-0.1.2}/examples/mcp-python/manifest.yaml +0 -0
  54. {ase_python-0.1.0 → ase_python-0.1.2}/examples/mcp-python/requirements.txt +0 -0
  55. {ase_python-0.1.0 → ase_python-0.1.2}/examples/mcp-python/scenario.yaml +0 -0
  56. {ase_python-0.1.0 → ase_python-0.1.2}/examples/openai-agents-typescript/README.md +0 -0
  57. {ase_python-0.1.0 → ase_python-0.1.2}/examples/openai-agents-typescript/package.json +0 -0
  58. {ase_python-0.1.0 → ase_python-0.1.2}/schemas/ase_conformance_manifest.schema.json +0 -0
  59. {ase_python-0.1.0 → ase_python-0.1.2}/schemas/ase_conformance_result.schema.json +0 -0
  60. {ase_python-0.1.0 → ase_python-0.1.2}/schemas/ase_scenario.schema.json +0 -0
  61. {ase_python-0.1.0 → ase_python-0.1.2}/scripts/bootstrap_upstream_validations.py +0 -0
  62. {ase_python-0.1.0 → ase_python-0.1.2}/scripts/generate_compatibility_matrix.py +0 -0
  63. {ase_python-0.1.0 → ase_python-0.1.2}/scripts/materialize_recovery_pyc.py +0 -0
  64. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/__init__.py +0 -0
  65. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/contract.py +0 -0
  66. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/frameworks/__init__.py +0 -0
  67. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/frameworks/base.py +0 -0
  68. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/frameworks/langgraph.py +0 -0
  69. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/frameworks/mcp.py +0 -0
  70. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/frameworks/openai_agents.py +0 -0
  71. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/frameworks/pydantic_ai.py +0 -0
  72. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/io.py +0 -0
  73. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/model.py +0 -0
  74. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/protocol.py +0 -0
  75. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/adapters/replay.py +0 -0
  76. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/__init__.py +0 -0
  77. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/_trace_outputs.py +0 -0
  78. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/adapter_cmd.py +0 -0
  79. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/certify_cmd.py +0 -0
  80. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/compare.py +0 -0
  81. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/doctor_cmd.py +0 -0
  82. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/history_cmd.py +0 -0
  83. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/import_cmd.py +0 -0
  84. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/main.py +0 -0
  85. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/replay_cmd.py +0 -0
  86. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/report.py +0 -0
  87. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/spec_cmd.py +0 -0
  88. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/cli/test_cmd.py +0 -0
  89. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/config/env_loader.py +0 -0
  90. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/config/loader.py +0 -0
  91. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/config/model.py +0 -0
  92. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/conformance/__init__.py +0 -0
  93. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/conformance/matrix.py +0 -0
  94. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/conformance/model.py +0 -0
  95. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/conformance/schema.py +0 -0
  96. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/conformance/service.py +0 -0
  97. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/core/engine.py +0 -0
  98. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/errors.py +0 -0
  99. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/__init__.py +0 -0
  100. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/base.py +0 -0
  101. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/consistency.py +0 -0
  102. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/correctness.py +0 -0
  103. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/efficiency.py +0 -0
  104. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/engine.py +0 -0
  105. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/policy.py +0 -0
  106. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/scoring.py +0 -0
  107. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/evaluation/trace_summary.py +0 -0
  108. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/reporting/__init__.py +0 -0
  109. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/reporting/json_report.py +0 -0
  110. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/reporting/junit.py +0 -0
  111. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/reporting/markdown.py +0 -0
  112. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/reporting/terminal.py +0 -0
  113. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/scenario/__init__.py +0 -0
  114. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/scenario/model.py +0 -0
  115. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/scenario/parser.py +0 -0
  116. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/storage/__init__.py +0 -0
  117. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/storage/trace_store.py +0 -0
  118. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/trace/__init__.py +0 -0
  119. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/trace/builder.py +0 -0
  120. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/trace/model.py +0 -0
  121. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/trace/otel_export.py +0 -0
  122. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/trace/otel_import.py +0 -0
  123. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/trace/redaction.py +0 -0
  124. {ase_python-0.1.0 → ase_python-0.1.2}/src/ase/trace/serializer.py +0 -0
  125. {ase_python-0.1.0 → ase_python-0.1.2}/tests/integration/test_framework_examples.py +0 -0
  126. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_case_study_layout.py +0 -0
  127. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_conformance_matrix.py +0 -0
  128. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_efficiency.py +0 -0
  129. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_env_loader.py +0 -0
  130. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_mcp_adapter.py +0 -0
  131. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_open_source_layout.py +0 -0
  132. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_release_metadata.py +0 -0
  133. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_report_compare.py +0 -0
  134. {ase_python-0.1.0 → ase_python-0.1.2}/tests/unit/test_trace_storage.py +0 -0
  135. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/README.md +0 -0
  136. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/langgraph_wrong_record/ase_agent.py +0 -0
  137. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/langgraph_wrong_record/scenario.bad.yaml +0 -0
  138. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/langgraph_wrong_record/scenario.fixed.yaml +0 -0
  139. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/openai_prompt_regression/ase_agent.py +0 -0
  140. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/openai_prompt_regression/scenario.bad.yaml +0 -0
  141. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/openai_prompt_regression/scenario.fixed.yaml +0 -0
  142. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/pydantic_missing_approval/ase_agent.py +0 -0
  143. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/pydantic_missing_approval/scenario.bad.yaml +0 -0
  144. {ase_python-0.1.0 → ase_python-0.1.2}/validation/case_studies/pydantic_missing_approval/scenario.fixed.yaml +0 -0
  145. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/README.md +0 -0
  146. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/langgraph-python/ase-manifest.yaml +0 -0
  147. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/langgraph-python/ase-scenario.yaml +0 -0
  148. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/langgraph-python/ase_agent.py +0 -0
  149. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/openai-agents-js/ase-manifest.yaml +0 -0
  150. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/openai-agents-js/ase-scenario.yaml +0 -0
  151. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/openai-agents-js/ase_agent.ts +0 -0
  152. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/openai-agents-python/ase-manifest.yaml +0 -0
  153. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/openai-agents-python/ase-scenario.yaml +0 -0
  154. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/openai-agents-python/ase_agent.py +0 -0
  155. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/pydantic-ai-python/ase-manifest.yaml +0 -0
  156. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/pydantic-ai-python/ase-scenario.yaml +0 -0
  157. {ase_python-0.1.0 → ase_python-0.1.2}/validation/upstream/pydantic-ai-python/ase_agent.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ase-python
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Agent Simulation Engine — pytest for AI agent tool calls
5
5
  Project-URL: Homepage, https://github.com/rkd0608/ase-python
6
6
  Project-URL: Repository, https://github.com/rkd0608/ase-python
@@ -35,15 +35,15 @@ python -m pip install --upgrade pip
35
35
  python -m pip install build twine
36
36
  python -m build
37
37
  python -m twine check dist/*
38
- python -m pip install dist/ase_python-0.1.0-py3-none-any.whl
38
+ python -m pip install dist/ase_python-0.1.2-py3-none-any.whl
39
39
  ase --help
40
40
  ```
41
41
 
42
42
  ## GitHub release flow
43
43
 
44
44
  ```bash
45
- git tag v0.1.0
46
- git push origin v0.1.0
45
+ git tag v0.1.2
46
+ git push origin v0.1.2
47
47
  ```
48
48
 
49
49
  The `publish-pypi` workflow will:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ase-python"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "Agent Simulation Engine — pytest for AI agent tool calls"
9
9
  requires-python = ">=3.11"
10
10
  readme = { file = "README_PYPI.md", content-type = "text/markdown" }
@@ -17,5 +17,5 @@ os.environ.setdefault("PYDANTIC_DISABLE_PLUGINS", "1")
17
17
 
18
18
  from ase.errors import ASEError
19
19
 
20
- __version__ = "0.1.0"
20
+ __version__ = "0.1.2"
21
21
  __all__ = ["ASEError", "__version__"]
@@ -7,6 +7,7 @@ from typing import Annotated
7
7
  import typer
8
8
  from rich.console import Console
9
9
 
10
+ from ase.errors import CLIError
10
11
  from ase.examples_matrix import run_examples
11
12
 
12
13
  app = typer.Typer(help="Run ASE's public example matrix.")
@@ -21,7 +22,11 @@ def run(
21
22
  ] = None,
22
23
  ) -> None:
23
24
  """Run the supported example matrix with the same commands users run."""
24
- results = run_examples(example)
25
+ try:
26
+ results = run_examples(example)
27
+ except CLIError as exc:
28
+ _console.print(f"[red]{exc}[/red]")
29
+ raise typer.Exit(code=1) from exc
25
30
  for result in results:
26
31
  status = "[green]passed[/green]" if result.passed else "[red]failed[/red]"
27
32
  _console.print(f"{result.example_name}: {status}")
@@ -37,6 +37,7 @@ class ExampleRunResult(BaseModel):
37
37
 
38
38
  def run_examples(example_names: list[str] | None = None) -> list[ExampleRunResult]:
39
39
  """Run the requested examples with the same commands users run manually."""
40
+ _require_repo_checkout()
40
41
  selected = example_names or list(SUPPORTED_EXAMPLES)
41
42
  _validate_examples(selected)
42
43
  return [_run_example(name) for name in selected]
@@ -116,3 +117,19 @@ def _validate_examples(example_names: list[str]) -> None:
116
117
  if unsupported:
117
118
  joined = ", ".join(unsupported)
118
119
  raise CLIError(f"unknown example names: {joined}")
120
+
121
+
122
+ def _require_repo_checkout() -> None:
123
+ """Fail clearly when examples are invoked from a wheel install."""
124
+ required_paths = [
125
+ ROOT / "examples",
126
+ ROOT / "validation",
127
+ ROOT / "src",
128
+ PYTHON,
129
+ ]
130
+ if all(path.exists() for path in required_paths):
131
+ return
132
+ raise CLIError(
133
+ "ase examples run requires the ASE source checkout; "
134
+ "clone https://github.com/rkd0608/ase-python and run it from the repo root"
135
+ )
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ from typer.testing import CliRunner
4
+
5
+ from ase.cli.examples_cmd import app
6
+
7
+
8
+ def test_examples_run_renders_cli_error_without_traceback(monkeypatch) -> None:
9
+ def _raise(_: list[str] | None) -> list[object]:
10
+ from ase.errors import CLIError
11
+
12
+ raise CLIError("requires the ASE source checkout")
13
+
14
+ monkeypatch.setattr("ase.cli.examples_cmd.run_examples", _raise)
15
+ result = CliRunner().invoke(app, [])
16
+ assert result.exit_code == 1
17
+ assert "requires the ASE source checkout" in result.stdout
18
+ assert "Traceback" not in result.stdout
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ import pytest
6
+
7
+ from ase.errors import CLIError
8
+ from ase.examples_matrix import _require_repo_checkout, _validate_examples
9
+
10
+
11
+ def test_validate_examples_rejects_unknown_names() -> None:
12
+ with pytest.raises(CLIError, match="unknown example names: nope"):
13
+ _validate_examples(["nope"])
14
+
15
+
16
+ def test_require_repo_checkout_fails_without_repo_layout(monkeypatch: pytest.MonkeyPatch) -> None:
17
+ fake_root = Path("/tmp/ase-wheel-layout")
18
+ monkeypatch.setattr("ase.examples_matrix.ROOT", fake_root)
19
+ monkeypatch.setattr("ase.examples_matrix.PYTHON", fake_root / ".venv" / "bin" / "python")
20
+ with pytest.raises(CLIError, match="requires the ASE source checkout"):
21
+ _require_repo_checkout()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes