anemoi-utils 0.3.17__tar.gz → 0.4.0__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.
Potentially problematic release.
This version of anemoi-utils might be problematic. Click here for more details.
- anemoi_utils-0.4.0/.github/CODEOWNERS +6 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.pre-commit-config.yaml +6 -6
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/CHANGELOG.md +13 -2
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/PKG-INFO +2 -1
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/conf.py +4 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/index.rst +1 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/pyproject.toml +3 -1
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/_version.py +2 -2
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/provenance.py +34 -0
- anemoi_utils-0.3.17/src/anemoi/utils/sanetize.py → anemoi_utils-0.4.0/src/anemoi/utils/sanitize.py +2 -2
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi_utils.egg-info/PKG-INFO +2 -1
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi_utils.egg-info/SOURCES.txt +2 -1
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi_utils.egg-info/requires.txt +3 -0
- anemoi_utils-0.4.0/tests/test_provenance.py +14 -0
- anemoi_utils-0.3.17/.github/CODEOWNERS +0 -6
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.gitattributes +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.github/ci-hpc-config.yml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.github/workflows/changelog-pr-update.yml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.github/workflows/changelog-release-update.yml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.github/workflows/ci.yml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.github/workflows/label-public-pr.yml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.github/workflows/python-publish.yml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.github/workflows/python-pull-request.yml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.github/workflows/readthedocs-pr-update.yml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.gitignore +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/.readthedocs.yaml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/LICENSE +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/README.md +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/Makefile +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/_static/logo.png +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/_static/style.css +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/_templates/.gitkeep +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/installing.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/modules/checkpoints.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/modules/config.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/modules/dates.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/modules/grib.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/modules/humanize.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/modules/provenance.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/modules/s3.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/docs/modules/text.rst +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/setup.cfg +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/__init__.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/__main__.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/caching.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/checkpoints.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/cli.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/commands/__init__.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/commands/config.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/config.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/dates.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/grib.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/hindcasts.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/humanize.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/mars/__init__.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/mars/mars.yaml +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/s3.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/sanitise.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/text.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi/utils/timer.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi_utils.egg-info/dependency_links.txt +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi_utils.egg-info/entry_points.txt +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/src/anemoi_utils.egg-info/top_level.txt +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/tests/test_dates.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/tests/test_frequency.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/tests/test_sanetise.py +0 -0
- {anemoi_utils-0.3.17 → anemoi_utils-0.4.0}/tests/test_utils.py +0 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# CODEOWNERS file
|
|
2
|
+
|
|
3
|
+
# Protect workflow files
|
|
4
|
+
/.github/ @theissenhelen @jesperdramsch @gmertes @b8raoult @floriankrb
|
|
5
|
+
/.pre-commit-config.yaml @theissenhelen @jesperdramsch @gmertes @b8raoult @floriankrb
|
|
6
|
+
/pyproject.toml @theissenhelen @jesperdramsch @gmertes @b8raoult @floriankrb
|
|
@@ -5,12 +5,12 @@ repos:
|
|
|
5
5
|
- id: clear-notebooks-output
|
|
6
6
|
name: clear-notebooks-output
|
|
7
7
|
files: tools/.*\.ipynb$
|
|
8
|
-
stages: [commit]
|
|
8
|
+
stages: [pre-commit]
|
|
9
9
|
language: python
|
|
10
10
|
entry: jupyter nbconvert --ClearOutputPreprocessor.enabled=True --inplace
|
|
11
11
|
additional_dependencies: [jupyter]
|
|
12
12
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
13
|
-
rev:
|
|
13
|
+
rev: v5.0.0
|
|
14
14
|
hooks:
|
|
15
15
|
- id: check-yaml # Check YAML files for syntax errors only
|
|
16
16
|
args: [--unsafe, --allow-multiple-documents]
|
|
@@ -40,11 +40,11 @@ repos:
|
|
|
40
40
|
- --force-single-line-imports
|
|
41
41
|
- --profile black
|
|
42
42
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
43
|
-
rev: v0.6.
|
|
43
|
+
rev: v0.6.9
|
|
44
44
|
hooks:
|
|
45
45
|
- id: ruff
|
|
46
46
|
# Next line if for documenation cod snippets
|
|
47
|
-
exclude: '
|
|
47
|
+
exclude: '.*/[^_].*_\.py$'
|
|
48
48
|
args:
|
|
49
49
|
- --line-length=120
|
|
50
50
|
- --fix
|
|
@@ -66,11 +66,11 @@ repos:
|
|
|
66
66
|
- id: docconvert
|
|
67
67
|
args: ["numpy"]
|
|
68
68
|
- repo: https://github.com/tox-dev/pyproject-fmt
|
|
69
|
-
rev: "2.2.
|
|
69
|
+
rev: "2.2.4"
|
|
70
70
|
hooks:
|
|
71
71
|
- id: pyproject-fmt
|
|
72
72
|
- repo: https://github.com/jshwi/docsig # Check docstrings against function sig
|
|
73
|
-
rev: v0.
|
|
73
|
+
rev: v0.64.0
|
|
74
74
|
hooks:
|
|
75
75
|
- id: docsig
|
|
76
76
|
args:
|
|
@@ -8,17 +8,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
Please add your functional changes to the appropriate section in the PR.
|
|
9
9
|
Keep it human-readable, your future self will thank you!
|
|
10
10
|
|
|
11
|
-
## [Unreleased]
|
|
11
|
+
## [Unreleased](https://github.com/ecmwf/anemoi-utils/compare/0.3.18...HEAD)
|
|
12
12
|
|
|
13
13
|
### Added
|
|
14
|
+
|
|
15
|
+
- Add anemoi-transform link to documentation
|
|
16
|
+
|
|
17
|
+
## [0.3.17](https://github.com/ecmwf/anemoi-utils/compare/0.3.13...0.3.17) - 2024-10-01
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
14
21
|
- Codeowners file
|
|
15
22
|
- Pygrep precommit hooks
|
|
16
23
|
- Docsig precommit hooks
|
|
17
24
|
- Changelog merge strategy- Codeowners file
|
|
18
25
|
- Create dependency on wcwidth. MIT licence.
|
|
26
|
+
- Add distribution name dictionary to provenance [#15](https://github.com/ecmwf/anemoi-utils/pull/15) & [#19](https://github.com/ecmwf/anemoi-utils/pull/19)
|
|
19
27
|
- Add anonimize() function.
|
|
20
28
|
|
|
21
29
|
### Changed
|
|
30
|
+
|
|
22
31
|
- downstream-ci should only runs for changes in src and tests
|
|
23
32
|
- bugfixes for CI
|
|
24
33
|
- python3.9 support
|
|
@@ -28,21 +37,23 @@ Keep it human-readable, your future self will thank you!
|
|
|
28
37
|
## [0.3.0] - Initial Release, utility functions
|
|
29
38
|
|
|
30
39
|
### Added
|
|
40
|
+
|
|
31
41
|
- Command line interface utility
|
|
32
42
|
|
|
33
43
|
## [0.2.0] - Initial Release, utility functions
|
|
34
44
|
|
|
35
45
|
### Changed
|
|
46
|
+
|
|
36
47
|
- updated documentation
|
|
37
48
|
|
|
38
49
|
## [0.1.0] - Initial Release, utility functions
|
|
39
50
|
|
|
40
51
|
### Added
|
|
52
|
+
|
|
41
53
|
- Documentation
|
|
42
54
|
- Initial implementation for a series of utility functions for used by the rest of the Anemoi packages
|
|
43
55
|
|
|
44
56
|
<!-- Add Git Diffs for Links above -->
|
|
45
|
-
[unreleased]: https://github.com/ecmwf/anemoi-utils/compare/0.3.13...HEAD
|
|
46
57
|
https://github.com/ecmwf/anemoi-utils/compare/0.2.0...0.3.0
|
|
47
58
|
https://github.com/ecmwf/anemoi-utils/compare/0.1.0...0.2.0
|
|
48
59
|
[0.1.0]: https://github.com/ecmwf/anemoi-utils/releases/tag/0.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: anemoi-utils
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A package to hold various functions to support training of ML models on ECMWF data.
|
|
5
5
|
Author-email: "European Centre for Medium-Range Weather Forecasts (ECMWF)" <software.support@ecmwf.int>
|
|
6
6
|
License: Apache License
|
|
@@ -224,6 +224,7 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
|
224
224
|
Requires-Python: >=3.9
|
|
225
225
|
License-File: LICENSE
|
|
226
226
|
Requires-Dist: aniso8601
|
|
227
|
+
Requires-Dist: importlib-metadata; python_version < "3.10"
|
|
227
228
|
Requires-Dist: pyyaml
|
|
228
229
|
Requires-Dist: tomli
|
|
229
230
|
Requires-Dist: tqdm
|
|
@@ -101,6 +101,10 @@ intersphinx_mapping = {
|
|
|
101
101
|
"https://anemoi-registry.readthedocs.io/en/latest/",
|
|
102
102
|
("../../anemoi-registry/docs/_build/html/objects.inv", None),
|
|
103
103
|
),
|
|
104
|
+
"anemoi-transform": (
|
|
105
|
+
"https://anemoi-transform.readthedocs.io/en/latest/",
|
|
106
|
+
("../../anemoi-transform/docs/_build/html/objects.inv", None),
|
|
107
|
+
),
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
# -- Options for HTML output -------------------------------------------------
|
|
@@ -45,6 +45,7 @@ of the *Anemoi* packages.
|
|
|
45
45
|
*****************
|
|
46
46
|
|
|
47
47
|
- :ref:`anemoi-utils <anemoi-utils:index-page>`
|
|
48
|
+
- :ref:`anemoi-transform <anemoi-transform:index-page>`
|
|
48
49
|
- :ref:`anemoi-datasets <anemoi-datasets:index-page>`
|
|
49
50
|
- :ref:`anemoi-models <anemoi-models:index-page>`
|
|
50
51
|
- :ref:`anemoi-graphs <anemoi-graphs:index-page>`
|
|
@@ -21,6 +21,7 @@ import os
|
|
|
21
21
|
import subprocess
|
|
22
22
|
import sys
|
|
23
23
|
import sysconfig
|
|
24
|
+
from functools import cache
|
|
24
25
|
|
|
25
26
|
LOG = logging.getLogger(__name__)
|
|
26
27
|
|
|
@@ -143,6 +144,37 @@ def _module_versions(full):
|
|
|
143
144
|
return versions, paths
|
|
144
145
|
|
|
145
146
|
|
|
147
|
+
@cache
|
|
148
|
+
def package_distributions() -> dict[str, list[str]]:
|
|
149
|
+
# Takes a significant amount of time to run
|
|
150
|
+
# so cache the result
|
|
151
|
+
from importlib import metadata
|
|
152
|
+
|
|
153
|
+
# For python 3.9 support
|
|
154
|
+
if not hasattr(metadata, "packages_distributions"):
|
|
155
|
+
import importlib_metadata as metadata
|
|
156
|
+
|
|
157
|
+
return metadata.packages_distributions()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def import_name_to_distribution_name(packages: list):
|
|
161
|
+
distribution_names = {}
|
|
162
|
+
package_distribution_names = package_distributions()
|
|
163
|
+
|
|
164
|
+
for package in [p for p in packages if p in package_distribution_names]:
|
|
165
|
+
distr_name = package_distribution_names[package]
|
|
166
|
+
if isinstance(distr_name, list):
|
|
167
|
+
if len(distr_name) > 1:
|
|
168
|
+
# Multiple distributions for the same package, i.e. anemoi-graphs, anemoi-utils, ..., Don't know how to handle this
|
|
169
|
+
continue
|
|
170
|
+
distr_name = distr_name[0]
|
|
171
|
+
|
|
172
|
+
if distr_name != package:
|
|
173
|
+
distribution_names[package] = distr_name
|
|
174
|
+
|
|
175
|
+
return distribution_names
|
|
176
|
+
|
|
177
|
+
|
|
146
178
|
def module_versions(full):
|
|
147
179
|
versions, paths = _module_versions(full)
|
|
148
180
|
git_versions = _check_for_git(paths, full)
|
|
@@ -339,6 +371,7 @@ def gather_provenance_info(assets=[], full=False) -> dict:
|
|
|
339
371
|
time=datetime.datetime.utcnow().isoformat(),
|
|
340
372
|
python=f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
|
341
373
|
module_versions=versions,
|
|
374
|
+
distribution_names=import_name_to_distribution_name(versions.keys()),
|
|
342
375
|
git_versions=git_versions,
|
|
343
376
|
)
|
|
344
377
|
else:
|
|
@@ -349,6 +382,7 @@ def gather_provenance_info(assets=[], full=False) -> dict:
|
|
|
349
382
|
python_path=sys.path,
|
|
350
383
|
config_paths=sysconfig.get_paths(),
|
|
351
384
|
module_versions=versions,
|
|
385
|
+
distribution_names=import_name_to_distribution_name(versions.keys()),
|
|
352
386
|
git_versions=git_versions,
|
|
353
387
|
platform=platform_info(),
|
|
354
388
|
gpus=gpu_info(),
|
anemoi_utils-0.3.17/src/anemoi/utils/sanetize.py → anemoi_utils-0.4.0/src/anemoi/utils/sanitize.py
RENAMED
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
# granted to it by virtue of its status as an intergovernmental organisation
|
|
6
6
|
# nor does it submit to any jurisdiction.
|
|
7
7
|
|
|
8
|
-
from .
|
|
8
|
+
from .sanitise import sanitise as sanitize
|
|
9
9
|
|
|
10
|
-
__all__ = ["
|
|
10
|
+
__all__ = ["sanitize"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: anemoi-utils
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A package to hold various functions to support training of ML models on ECMWF data.
|
|
5
5
|
Author-email: "European Centre for Medium-Range Weather Forecasts (ECMWF)" <software.support@ecmwf.int>
|
|
6
6
|
License: Apache License
|
|
@@ -224,6 +224,7 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
|
224
224
|
Requires-Python: >=3.9
|
|
225
225
|
License-File: LICENSE
|
|
226
226
|
Requires-Dist: aniso8601
|
|
227
|
+
Requires-Dist: importlib-metadata; python_version < "3.10"
|
|
227
228
|
Requires-Dist: pyyaml
|
|
228
229
|
Requires-Dist: tomli
|
|
229
230
|
Requires-Dist: tqdm
|
|
@@ -43,8 +43,8 @@ src/anemoi/utils/hindcasts.py
|
|
|
43
43
|
src/anemoi/utils/humanize.py
|
|
44
44
|
src/anemoi/utils/provenance.py
|
|
45
45
|
src/anemoi/utils/s3.py
|
|
46
|
-
src/anemoi/utils/sanetize.py
|
|
47
46
|
src/anemoi/utils/sanitise.py
|
|
47
|
+
src/anemoi/utils/sanitize.py
|
|
48
48
|
src/anemoi/utils/text.py
|
|
49
49
|
src/anemoi/utils/timer.py
|
|
50
50
|
src/anemoi/utils/commands/__init__.py
|
|
@@ -59,5 +59,6 @@ src/anemoi_utils.egg-info/requires.txt
|
|
|
59
59
|
src/anemoi_utils.egg-info/top_level.txt
|
|
60
60
|
tests/test_dates.py
|
|
61
61
|
tests/test_frequency.py
|
|
62
|
+
tests/test_provenance.py
|
|
62
63
|
tests/test_sanetise.py
|
|
63
64
|
tests/test_utils.py
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# (C) Copyright 2024 European Centre for Medium-Range Weather Forecasts.
|
|
2
|
+
# This software is licensed under the terms of the Apache Licence Version 2.0
|
|
3
|
+
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
4
|
+
# In applying this licence, ECMWF does not waive the privileges and immunities
|
|
5
|
+
# granted to it by virtue of its status as an intergovernmental organisation
|
|
6
|
+
# nor does it submit to any jurisdiction.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from anemoi.utils import provenance
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_gather():
|
|
13
|
+
"""Test success of gather_provenance_info"""
|
|
14
|
+
provenance.gather_provenance_info()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|