ltcodecs 4.1.0__tar.gz → 4.2.1__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 (52) hide show
  1. ltcodecs-4.2.1/.gitlab-ci.yml +197 -0
  2. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/PKG-INFO +1 -1
  3. ltcodecs-4.2.1/docker/tests.Dockerfile.ros1 +22 -0
  4. ltcodecs-4.2.1/docker/tests.Dockerfile.ros2 +10 -0
  5. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/__init__.py +1 -0
  6. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs.egg-info/PKG-INFO +1 -1
  7. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs.egg-info/SOURCES.txt +4 -3
  8. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/tests/test_codecs.py +7 -6
  9. ltcodecs-4.1.0/.gitlab-ci.yml +0 -114
  10. ltcodecs-4.1.0/tests/tests.Dockerfile +0 -6
  11. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/.gitignore +0 -0
  12. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/.gitlab/merge_request_templates/Default.md +0 -0
  13. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/CONTRIBUTING.md +0 -0
  14. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/LICENSE +0 -0
  15. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/README.md +0 -0
  16. {ltcodecs-4.1.0/docs → ltcodecs-4.2.1/docker}/auto-docs.Dockerfile +0 -0
  17. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/docs/Makefile +0 -0
  18. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/docs/conf.py +0 -0
  19. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/docs/index.rst +0 -0
  20. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/docs/ltcodecs.rst +0 -0
  21. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/docs/tests.rst +0 -0
  22. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/pyproject.toml +0 -0
  23. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/requirements.txt +0 -0
  24. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/setup.cfg +0 -0
  25. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/bool_codec.py +0 -0
  26. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/bytes_codec.py +0 -0
  27. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/ccl_latlon_bcd_codec.py +0 -0
  28. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/ccl_latlon_codec.py +0 -0
  29. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/exceptions.py +0 -0
  30. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/exponentialgolomb_integer_codec.py +0 -0
  31. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/field_codec.py +0 -0
  32. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/fixed_len_array_codec.py +0 -0
  33. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/fixedint_codec.py +0 -0
  34. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/float_codec.py +0 -0
  35. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/ieee_float_codec.py +0 -0
  36. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/linspace_float_codec.py +0 -0
  37. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/lzma_codec.py +0 -0
  38. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/multiple_field_codec.py +0 -0
  39. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/optional_field_codec.py +0 -0
  40. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/padding_codec.py +0 -0
  41. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/ros_message_codec.py +0 -0
  42. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/ros_msg_field_codec.py +0 -0
  43. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/rostime_codec.py +0 -0
  44. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/string_codecs.py +0 -0
  45. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/string_enum_codec.py +0 -0
  46. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/variable_len_array_codec.py +0 -0
  47. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs/varint_codec.py +0 -0
  48. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs.egg-info/dependency_links.txt +0 -0
  49. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs.egg-info/requires.txt +0 -0
  50. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/src/ltcodecs.egg-info/top_level.txt +0 -0
  51. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/tests/__init__.py +0 -0
  52. {ltcodecs-4.1.0 → ltcodecs-4.2.1}/tests/string_msg_codec.yaml +0 -0
@@ -0,0 +1,197 @@
1
+ workflow:
2
+ rules:
3
+ - when: always
4
+
5
+ stages:
6
+ - build
7
+ - test
8
+ - combine_coverage
9
+ - deploy
10
+
11
+ variables:
12
+ # Requires two additional vars, REGISTRY_URL and REGISTRY_REPO to be defined
13
+ # in CI/CD variables on gitlab
14
+
15
+ # dockerfile locations
16
+ ROS1_DOCKERFILE_PATH: "docker/tests.Dockerfile.ros1"
17
+ ROS2_DOCKERFILE_PATH: "docker/tests.Dockerfile.ros2"
18
+ DOCKERFILE_AUTODOCS_PATH: "docker/auto-docs.Dockerfile"
19
+
20
+ # version based configurations
21
+ ROS1_DISTRO: "noetic"
22
+ ROS2_DISTRO: "jazzy"
23
+ ROS1_BASE_IMAGE: "ros:${ROS1_DISTRO}-ros-base"
24
+ ROS2_BASE_IMAGE: "ros:${ROS2_DISTRO}-ros-base"
25
+
26
+ ROS_TEST_IMAGE_NAME: "ltcodec_tests"
27
+ ROS1_TAG: "ros1-test-pipeline-${CI_PIPELINE_ID}"
28
+ ROS2_TAG: "ros2-test-pipeline-${CI_PIPELINE_ID}"
29
+
30
+ DOCS_IMAGE_NAME: "ltcodec_auto_docs"
31
+ DOCS_TAG: "auto-doc-pipeline-${CI_PIPELINE_ID}"
32
+
33
+ ARMW_BRANCH: ""
34
+ PYACOMMS_BRANCH: ""
35
+ LTCODEC_BRANCH: ""
36
+
37
+ ROS_ACOMMS_BRANCH: "devel"
38
+ ROS_ACOMMS_NET_BRANCH: "devel"
39
+
40
+ .build_image_template:
41
+ image: docker:stable
42
+ stage: build
43
+ tags:
44
+ - privileged
45
+ services:
46
+ - name: docker:dind
47
+ script:
48
+ - docker build --rm --build-arg ROS_DISTRO=${ROS_DISTRO} --build-arg BASE_IMAGE=${ROS_BASE_IMAGE} -t $ROS_TEST_IMAGE_NAME:${IMAGE_TAG} -f $ROS_DOCKERFILE_PATH .
49
+ - docker tag ${ROS_TEST_IMAGE_NAME}:${IMAGE_TAG} ${REGISTRY_URL}/${REGISTRY_REPO}/${ROS_TEST_IMAGE_NAME}:${IMAGE_TAG}
50
+ - docker push ${REGISTRY_URL}/${REGISTRY_REPO}/${ROS_TEST_IMAGE_NAME}:${IMAGE_TAG}
51
+
52
+ build_ros_test_image_ros1:
53
+ extends: .build_image_template
54
+ variables:
55
+ IMAGE_TAG: "${ROS1_TAG}"
56
+ ROS_BASE_IMAGE: $ROS1_BASE_IMAGE
57
+ ROS_DOCKERFILE_PATH: $ROS1_DOCKERFILE_PATH
58
+
59
+ build_ros_test_image_ros2:
60
+ extends: .build_image_template
61
+ variables:
62
+ IMAGE_TAG: "${ROS2_TAG}"
63
+ ROS_DOCKERFILE_PATH: $ROS2_DOCKERFILE_PATH
64
+ ROS_BASE_IMAGE: $ROS2_BASE_IMAGE
65
+
66
+ build_auto_doc_image:
67
+ image: docker:stable
68
+ stage: build
69
+ tags:
70
+ - privileged
71
+ services:
72
+ - name: docker:dind
73
+ script:
74
+ - docker build --rm -t ${DOCS_IMAGE_NAME}:${DOCS_TAG} -f $DOCKERFILE_AUTODOCS_PATH .
75
+ - docker tag ${DOCS_IMAGE_NAME}:${DOCS_TAG} ${REGISTRY_URL}/${REGISTRY_REPO}/${DOCS_IMAGE_NAME}:${DOCS_TAG}
76
+ - docker push ${REGISTRY_URL}/${REGISTRY_REPO}/${DOCS_IMAGE_NAME}:${DOCS_TAG}
77
+
78
+ trigger-ros_acomms-pipeline:
79
+ stage: test
80
+ trigger:
81
+ project: acomms/ros_acomms
82
+ branch: $ROS_ACOMMS_BRANCH
83
+ strategy: depend
84
+ variables:
85
+ LTCODEC_BRANCH: $LTCODEC_BRANCH
86
+ PYACOMMS_BRANCH: $PYACOMMS_BRANCH
87
+ ARMW_BRANCH: $ARMW_BRANCH
88
+ rules:
89
+ - if: '$CI_PIPELINE_SOURCE != "pipeline"'
90
+
91
+ .test_template:
92
+ stage: test
93
+ script:
94
+ - pip install -r requirements.txt
95
+ - pip install .
96
+ - |
97
+ if [[ "$ARMW_BRANCH" != "" ]]; then
98
+ git clone -b "$ARMW_BRANCH" "https://gitlab-ci-token:$CI_JOB_TOKEN@git.whoi.edu/ros/armw.git" /armw && \
99
+ pip install /armw/.;
100
+ fi
101
+ - pytest --capture=no --junitxml=results.xml --cov=ltcodecs --cov-report=term --cov-report=xml --cov-report=html tests/
102
+ artifacts:
103
+ paths:
104
+ - 'coverage.xml'
105
+ - 'htmlcov/'
106
+ reports:
107
+ junit: 'results.xml'
108
+ coverage_report:
109
+ coverage_format: cobertura
110
+ path: coverage.xml
111
+ coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+)%/'
112
+
113
+ .ros_version_selector:
114
+ variables:
115
+ ROS_DISTRO: $ROS1_DISTRO
116
+ ROS_WORKSPACE_OUTPUT_DIR: "devel"
117
+ IMAGE_FULL_NAME: "$REGISTRY_URL/$REGISTRY_REPO/$ROS_TEST_IMAGE_NAME:$ROS1_TAG"
118
+ rules:
119
+ - if: $ROS_VERSION == "ros2"
120
+ variables:
121
+ ROS_DISTRO: $ROS2_DISTRO
122
+ ROS_WORKSPACE_OUTPUT_DIR: "install"
123
+ IMAGE_FULL_NAME: "$REGISTRY_URL/$REGISTRY_REPO/$ROS_TEST_IMAGE_NAME:$ROS2_TAG"
124
+ - when: on_success
125
+ image: $IMAGE_FULL_NAME
126
+
127
+ test:
128
+ extends:
129
+ - .test_template
130
+ - .ros_version_selector
131
+ parallel:
132
+ matrix:
133
+ - ROS_VERSION: [ros1, ros2]
134
+
135
+ test_coverage:
136
+ image: "$REGISTRY_URL/$REGISTRY_REPO/$ROS_TEST_IMAGE_NAME:$ROS1_TAG"
137
+ stage: combine_coverage
138
+ script:
139
+ - ls *.coverage
140
+ - coverage combine --keep *.${ROS1_DISTRO}.coverage
141
+ - coverage xml
142
+ - coverage html
143
+ - coverage report --omit=*__init__.py
144
+ coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+)%/'
145
+ artifacts:
146
+ paths:
147
+ - ".coverage"
148
+ - "htmlcov/"
149
+ - "coverage.xml"
150
+ reports:
151
+ coverage_report:
152
+ coverage_format: cobertura
153
+ path: coverage.xml
154
+ except:
155
+ - dev/autodocs
156
+
157
+ auto-docs:
158
+ image: "$REGISTRY_URL/$REGISTRY_REPO/$DOCS_IMAGE_NAME:$DOCS_TAG"
159
+ stage: deploy
160
+ script:
161
+ - pip install -r requirements.txt
162
+ - pip install .
163
+ - cd docs
164
+ - make latexpdf
165
+ - mv _build/latex/ltcodecs.pdf ..
166
+ artifacts:
167
+ paths:
168
+ - ltcodecs.pdf
169
+
170
+ pages:
171
+ image: "$REGISTRY_URL/$REGISTRY_REPO/$DOCS_IMAGE_NAME:$DOCS_TAG"
172
+ stage: deploy
173
+ script:
174
+ - pip install -r requirements.txt
175
+ - pip install .
176
+ - cd docs
177
+ - sphinx-build -b html . ../public
178
+ artifacts:
179
+ paths:
180
+ - public
181
+ only:
182
+ - tags
183
+ - master
184
+
185
+ pypi:
186
+ image: python
187
+ stage: deploy
188
+ script:
189
+ - pip install -r requirements.txt
190
+ - pip install build twine
191
+ - python -m build
192
+ - twine upload --username __token__ --password $PYPI_TOKEN dist/*
193
+ artifacts:
194
+ paths:
195
+ - dist/
196
+ only:
197
+ - tags
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ltcodecs
3
- Version: 4.1.0
3
+ Version: 4.2.1
4
4
  Summary: LT Codecs: Lightweight codecs for use over low-throughput links
5
5
  Author: Woods Hole Oceanographic Institution, Acoustic Communications Group
6
6
  License: LGPL-3.0-or-later
@@ -0,0 +1,22 @@
1
+ ARG BASE_IMAGE=ros:noetic-ros-base
2
+ FROM ${BASE_IMAGE}
3
+
4
+ # first lets ensure the GPG key is up to date
5
+ RUN apt update; \
6
+ apt upgrade -y; \
7
+ apt install -y \
8
+ curl
9
+
10
+ RUN rm /etc/apt/sources.list.d/ros1*
11
+ RUN curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
12
+
13
+ # Now lets get what else we need
14
+ RUN apt update; \
15
+ apt upgrade -y; \
16
+ apt install -y \
17
+ python3-pip \
18
+ python3-venv \
19
+ curl \
20
+ git \
21
+ socat
22
+ RUN pip install pytest pytest-cov
@@ -0,0 +1,10 @@
1
+ ARG BASE_IMAGE=ros:jazzy-ros-base
2
+ FROM ${BASE_IMAGE}
3
+
4
+ RUN apt-get update && apt-get upgrade -y
5
+ RUN apt install python3-pip python3-venv git -y
6
+
7
+ RUN python3 -m venv /opt/venv
8
+ ENV PATH="/opt/venv/bin:$PATH"
9
+
10
+ RUN pip install -U pytest pytest-cov lark argcomplete numpy psutil
@@ -41,6 +41,7 @@ field_codec_classes = {
41
41
  "float32": IeeeFloat32Codec,
42
42
  "float64": IeeeFloat64Codec,
43
43
  "bool": BoolCodec,
44
+ "boolean": BoolCodec,
44
45
  "string": AsciiStringCodec,
45
46
  "ascii": AsciiStringCodec,
46
47
  "bytes": BytesCodec,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ltcodecs
3
- Version: 4.1.0
3
+ Version: 4.2.1
4
4
  Summary: LT Codecs: Lightweight codecs for use over low-throughput links
5
5
  Author: Woods Hole Oceanographic Institution, Acoustic Communications Group
6
6
  License: LGPL-3.0-or-later
@@ -6,8 +6,10 @@ README.md
6
6
  pyproject.toml
7
7
  requirements.txt
8
8
  .gitlab/merge_request_templates/Default.md
9
+ docker/auto-docs.Dockerfile
10
+ docker/tests.Dockerfile.ros1
11
+ docker/tests.Dockerfile.ros2
9
12
  docs/Makefile
10
- docs/auto-docs.Dockerfile
11
13
  docs/conf.py
12
14
  docs/index.rst
13
15
  docs/ltcodecs.rst
@@ -43,5 +45,4 @@ src/ltcodecs.egg-info/requires.txt
43
45
  src/ltcodecs.egg-info/top_level.txt
44
46
  tests/__init__.py
45
47
  tests/string_msg_codec.yaml
46
- tests/test_codecs.py
47
- tests/tests.Dockerfile
48
+ tests/test_codecs.py
@@ -9,8 +9,10 @@ import sys
9
9
  import pytest
10
10
  from bitstring import ConstBitStream
11
11
 
12
- import rospy
13
- from std_msgs.msg import String, ColorRGBA
12
+ import armw
13
+
14
+ String = armw.import_message("std_msgs", "String")
15
+ ColorRGBA = armw.import_message("std_msgs", "ColorRGBA")
14
16
 
15
17
  import ltcodecs
16
18
 
@@ -337,7 +339,7 @@ class TestCodecs:
337
339
  # use a ColorRGBA message because it's part of std_msgs and has a field that we can cast as a boolean
338
340
  msg = ColorRGBA(r=1, g=1234.5678, b=3.14, a=4)
339
341
  message_dict = {}
340
- for field in msg.__slots__:
342
+ for field in ['r', 'g', 'b', 'a']:
341
343
  message_dict[field] = getattr(msg, field)
342
344
 
343
345
  codec = ltcodecs.OptionalFieldCodec(target_fields={'g': {'codec': 'float32'}, 'b': {'codec': 'float32'}})
@@ -381,15 +383,14 @@ class TestCodecs:
381
383
  def test_ros_time_codec(self) -> None:
382
384
  """test functionality of the ros time field codec"""
383
385
 
384
- input_time = rospy.Time.from_sec(time.time())
386
+ input_time = armw.Time().from_sec(time.time())
385
387
 
386
388
  codec = ltcodecs.rostime_codec.RosTimeCodec(precision=20)
387
389
  encoded_time = codec.encode(input_time)
388
390
 
389
391
  bit_stream = ConstBitStream(encoded_time[0])
390
392
 
391
- decoded_time = codec.decode(bit_stream)
392
-
393
+ decoded_time = armw.get_time_object(codec.decode(bit_stream))
393
394
  assert decoded_time == input_time, "Decoded time does not match input time"
394
395
 
395
396
  def test_string_enum_codec(self) -> None:
@@ -1,114 +0,0 @@
1
- build_test_image:
2
- image: docker:stable
3
- stage: build
4
- tags:
5
- - privileged
6
- services:
7
- - name: docker:dind
8
- script:
9
- - docker build --rm -t ltcodecs-tests:latest -f tests/tests.Dockerfile .
10
-
11
- build_auto-doc_image:
12
- image: docker:stable
13
- stage: build
14
- tags:
15
- - privileged
16
- services:
17
- - name: docker:dind
18
- script:
19
- - docker build --rm -t ltcodecs-docs:latest -f docs/auto-docs.Dockerfile .
20
-
21
- trigger-ros_acomms-master-pipeline:
22
- trigger:
23
- project: acomms/ros_acomms
24
- branch: master
25
- strategy: depend
26
-
27
- trigger-ros_acomms-devel-pipeline:
28
- trigger:
29
- project: acomms/ros_acomms
30
- branch: devel
31
- strategy: depend
32
-
33
- test:
34
- image: ltcodecs-tests:latest
35
- stage: test
36
- script:
37
- - source /ros_entrypoint.sh
38
- - pip install -r requirements.txt
39
- - pip install .
40
- - pytest --capture=no --junitxml=results.xml --cov=ltcodecs --cov-report=term --cov-report=xml --cov-report=html tests/
41
- artifacts:
42
- paths:
43
- - 'coverage.xml'
44
- - 'htmlcov/'
45
- reports:
46
- junit: 'results.xml'
47
- coverage_report:
48
- coverage_format: cobertura
49
- path: coverage.xml
50
- coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+)%/'
51
-
52
- test-gitlab:
53
- image: ltcodecs-tests:latest
54
- stage: test
55
- script:
56
- - source /ros_entrypoint.sh
57
- - pip install -r requirements.txt
58
- - git clone https://gitlab-ci-token:$CI_JOB_TOKEN@git.whoi.edu/ros/armw.git ~/armw
59
- - cd ~/armw && pip install .
60
- - cd $CI_PROJECT_DIR
61
- - pip install .
62
- - pytest --capture=no --junitxml=results.xml --cov=ltcodecs --cov-report=term --cov-report=xml --cov-report=html tests/
63
- artifacts:
64
- paths:
65
- - 'coverage.xml'
66
- - 'htmlcov/'
67
- reports:
68
- junit: 'results.xml'
69
- coverage_report:
70
- coverage_format: cobertura
71
- path: coverage.xml
72
- coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+)%/'
73
-
74
- auto-docs:
75
- image: ltcodecs-docs:latest
76
- stage: deploy
77
- script:
78
- - pip install -r requirements.txt
79
- - pip install .
80
- - cd docs
81
- - make latexpdf
82
- - mv _build/latex/ltcodecs.pdf ..
83
- artifacts:
84
- paths:
85
- - ltcodecs.pdf
86
-
87
- pages:
88
- image: ltcodecs-docs:latest
89
- stage: deploy
90
- script:
91
- - pip install -r requirements.txt
92
- - pip install .
93
- - cd docs
94
- - sphinx-build -b html . ../public
95
- artifacts:
96
- paths:
97
- - public
98
- only:
99
- - tags
100
- - master
101
-
102
- pypi:
103
- image: python
104
- stage: deploy
105
- script:
106
- - pip install -r requirements.txt
107
- - pip install build twine
108
- - python -m build
109
- - twine upload --username __token__ --password $PYPI_TOKEN dist/*
110
- artifacts:
111
- paths:
112
- - dist/
113
- only:
114
- - tags
@@ -1,6 +0,0 @@
1
- FROM ros:noetic-ros-core
2
-
3
- # install ros package
4
- RUN apt-get update && apt-get upgrade -y
5
- RUN apt install python3-pip git ros-noetic-dynamic-reconfigure -y
6
- RUN pip install -U pytest pytest-cov
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