isaacus 0.6.0__tar.gz → 0.7.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.
Files changed (84) hide show
  1. isaacus-0.7.0/.release-please-manifest.json +3 -0
  2. {isaacus-0.6.0 → isaacus-0.7.0}/CHANGELOG.md +37 -0
  3. {isaacus-0.6.0 → isaacus-0.7.0}/CONTRIBUTING.md +1 -2
  4. {isaacus-0.6.0 → isaacus-0.7.0}/PKG-INFO +2 -2
  5. {isaacus-0.6.0 → isaacus-0.7.0}/README.md +1 -1
  6. {isaacus-0.6.0 → isaacus-0.7.0}/SECURITY.md +2 -2
  7. {isaacus-0.6.0 → isaacus-0.7.0}/pyproject.toml +1 -1
  8. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/__init__.py +5 -0
  9. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_base_client.py +6 -0
  10. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_models.py +2 -0
  11. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_types.py +2 -0
  12. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/_proxy.py +4 -1
  13. isaacus-0.7.0/src/isaacus/_utils/_resources_proxy.py +24 -0
  14. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_version.py +1 -1
  15. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/extractions/answer_extraction.py +2 -1
  16. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_client.py +54 -0
  17. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_utils/test_proxy.py +11 -0
  18. isaacus-0.6.0/.release-please-manifest.json +0 -3
  19. {isaacus-0.6.0 → isaacus-0.7.0}/.gitignore +0 -0
  20. {isaacus-0.6.0 → isaacus-0.7.0}/LICENSE +0 -0
  21. {isaacus-0.6.0 → isaacus-0.7.0}/api.md +0 -0
  22. {isaacus-0.6.0 → isaacus-0.7.0}/bin/check-release-environment +0 -0
  23. {isaacus-0.6.0 → isaacus-0.7.0}/bin/publish-pypi +0 -0
  24. {isaacus-0.6.0 → isaacus-0.7.0}/examples/.keep +0 -0
  25. {isaacus-0.6.0 → isaacus-0.7.0}/mypy.ini +0 -0
  26. {isaacus-0.6.0 → isaacus-0.7.0}/noxfile.py +0 -0
  27. {isaacus-0.6.0 → isaacus-0.7.0}/release-please-config.json +0 -0
  28. {isaacus-0.6.0 → isaacus-0.7.0}/requirements-dev.lock +0 -0
  29. {isaacus-0.6.0 → isaacus-0.7.0}/requirements.lock +0 -0
  30. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_client.py +0 -0
  31. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_compat.py +0 -0
  32. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_constants.py +0 -0
  33. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_exceptions.py +0 -0
  34. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_files.py +0 -0
  35. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_qs.py +0 -0
  36. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_resource.py +0 -0
  37. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_response.py +0 -0
  38. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_streaming.py +0 -0
  39. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/__init__.py +0 -0
  40. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/_logs.py +0 -0
  41. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/_reflection.py +0 -0
  42. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/_streams.py +0 -0
  43. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/_sync.py +0 -0
  44. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/_transform.py +0 -0
  45. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/_typing.py +0 -0
  46. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/_utils/_utils.py +0 -0
  47. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/lib/.keep +0 -0
  48. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/py.typed +0 -0
  49. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/resources/__init__.py +0 -0
  50. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/resources/classifications/__init__.py +0 -0
  51. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/resources/classifications/classifications.py +0 -0
  52. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/resources/classifications/universal.py +0 -0
  53. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/resources/extractions/__init__.py +0 -0
  54. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/resources/extractions/extractions.py +0 -0
  55. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/resources/extractions/qa.py +0 -0
  56. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/resources/rerankings.py +0 -0
  57. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/__init__.py +0 -0
  58. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/classifications/__init__.py +0 -0
  59. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/classifications/universal_classification.py +0 -0
  60. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/classifications/universal_create_params.py +0 -0
  61. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/extractions/__init__.py +0 -0
  62. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/extractions/qa_create_params.py +0 -0
  63. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/reranking.py +0 -0
  64. {isaacus-0.6.0 → isaacus-0.7.0}/src/isaacus/types/reranking_create_params.py +0 -0
  65. {isaacus-0.6.0 → isaacus-0.7.0}/tests/__init__.py +0 -0
  66. {isaacus-0.6.0 → isaacus-0.7.0}/tests/api_resources/__init__.py +0 -0
  67. {isaacus-0.6.0 → isaacus-0.7.0}/tests/api_resources/classifications/__init__.py +0 -0
  68. {isaacus-0.6.0 → isaacus-0.7.0}/tests/api_resources/classifications/test_universal.py +0 -0
  69. {isaacus-0.6.0 → isaacus-0.7.0}/tests/api_resources/extractions/__init__.py +0 -0
  70. {isaacus-0.6.0 → isaacus-0.7.0}/tests/api_resources/extractions/test_qa.py +0 -0
  71. {isaacus-0.6.0 → isaacus-0.7.0}/tests/api_resources/test_rerankings.py +0 -0
  72. {isaacus-0.6.0 → isaacus-0.7.0}/tests/conftest.py +0 -0
  73. {isaacus-0.6.0 → isaacus-0.7.0}/tests/sample_file.txt +0 -0
  74. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_deepcopy.py +0 -0
  75. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_extract_files.py +0 -0
  76. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_files.py +0 -0
  77. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_models.py +0 -0
  78. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_qs.py +0 -0
  79. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_required_args.py +0 -0
  80. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_response.py +0 -0
  81. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_streaming.py +0 -0
  82. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_transform.py +0 -0
  83. {isaacus-0.6.0 → isaacus-0.7.0}/tests/test_utils/test_typing.py +0 -0
  84. {isaacus-0.6.0 → isaacus-0.7.0}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.7.0"
3
+ }
@@ -1,5 +1,42 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.0 (2025-06-03)
4
+
5
+ Full Changelog: [v0.6.1...v0.7.0](https://github.com/isaacus-dev/isaacus-python/compare/v0.6.1...v0.7.0)
6
+
7
+ ### Features
8
+
9
+ * **client:** add follow_redirects request option ([40221d5](https://github.com/isaacus-dev/isaacus-python/commit/40221d56d887dcfb693d67883a47403c680f6062))
10
+
11
+
12
+ ### Chores
13
+
14
+ * **ci:** fix installation instructions ([157308b](https://github.com/isaacus-dev/isaacus-python/commit/157308b71eefc75af2e76acd10664eb5633b9110))
15
+ * **ci:** upload sdks to package manager ([9f9915c](https://github.com/isaacus-dev/isaacus-python/commit/9f9915ce18a288ab157b8f75c21de724507267d7))
16
+ * **docs:** grammar improvements ([eb2766f](https://github.com/isaacus-dev/isaacus-python/commit/eb2766f59d477222ae93c06c32e06ab1ff94645f))
17
+ * **docs:** remove reference to rye shell ([96a0239](https://github.com/isaacus-dev/isaacus-python/commit/96a0239f103261c69ead957c62fdee27497192ed))
18
+
19
+ ## 0.6.1 (2025-05-10)
20
+
21
+ Full Changelog: [v0.6.0...v0.6.1](https://github.com/isaacus-dev/isaacus-python/compare/v0.6.0...v0.6.1)
22
+
23
+ ### Bug Fixes
24
+
25
+ * **client:** fix bug where types occasionally wouldn't generate ([e1bec40](https://github.com/isaacus-dev/isaacus-python/commit/e1bec4066b30cfefa004cdddc620c4c8131bd0de))
26
+ * **package:** support direct resource imports ([46ada4d](https://github.com/isaacus-dev/isaacus-python/commit/46ada4d158767a9dc03f19222009a853c5626cc7))
27
+
28
+
29
+ ### Chores
30
+
31
+ * **internal:** avoid errors for isinstance checks on proxies ([e4ffb62](https://github.com/isaacus-dev/isaacus-python/commit/e4ffb62a053ec88a60667a8a1e149a15d5f61a86))
32
+ * **internal:** codegen related update ([ed8951f](https://github.com/isaacus-dev/isaacus-python/commit/ed8951f3943af3be84ea11a363e6ac3c23e37b2b))
33
+
34
+
35
+ ### Documentation
36
+
37
+ * **api:** fixed incorrect description of how extraction results are ordered ([4c6ee63](https://github.com/isaacus-dev/isaacus-python/commit/4c6ee63ab3b274ee76cb56f526004f2f63dbb0ac))
38
+ * remove or fix invalid readme examples ([71a39ed](https://github.com/isaacus-dev/isaacus-python/commit/71a39ed2e5608d44fec4c1c5d83f97af6eaa4527))
39
+
3
40
  ## 0.6.0 (2025-04-30)
4
41
 
5
42
  Full Changelog: [v0.5.0...v0.6.0](https://github.com/isaacus-dev/isaacus-python/compare/v0.5.0...v0.6.0)
@@ -17,8 +17,7 @@ $ rye sync --all-features
17
17
  You can then run scripts using `rye run python script.py` or by activating the virtual environment:
18
18
 
19
19
  ```sh
20
- $ rye shell
21
- # or manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work
20
+ # Activate the virtual environment - https://docs.python.org/3/library/venv.html#how-venvs-work
22
21
  $ source .venv/bin/activate
23
22
 
24
23
  # now you can omit the `rye run` prefix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: isaacus
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: The official Python library for the isaacus API
5
5
  Project-URL: Homepage, https://github.com/isaacus-dev/isaacus-python
6
6
  Project-URL: Repository, https://github.com/isaacus-dev/isaacus-python
@@ -131,7 +131,7 @@ universal_classification = client.classifications.universal.create(
131
131
  "size": 512,
132
132
  },
133
133
  )
134
- print(universal_classification.chunking_options)
134
+ print(universal_classification.classifications)
135
135
  ```
136
136
 
137
137
  ## Handling errors
@@ -100,7 +100,7 @@ universal_classification = client.classifications.universal.create(
100
100
  "size": 512,
101
101
  },
102
102
  )
103
- print(universal_classification.chunking_options)
103
+ print(universal_classification.classifications)
104
104
  ```
105
105
 
106
106
  ## Handling errors
@@ -16,11 +16,11 @@ before making any information public.
16
16
  ## Reporting Non-SDK Related Security Issues
17
17
 
18
18
  If you encounter security issues that are not directly related to SDKs but pertain to the services
19
- or products provided by Isaacus please follow the respective company's security reporting guidelines.
19
+ or products provided by Isaacus, please follow the respective company's security reporting guidelines.
20
20
 
21
21
  ### Isaacus Terms and Policies
22
22
 
23
- Please contact security@isaacus.com for any questions or concerns regarding security of our services.
23
+ Please contact security@isaacus.com for any questions or concerns regarding the security of our services.
24
24
 
25
25
  ---
26
26
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "isaacus"
3
- version = "0.6.0"
3
+ version = "0.7.0"
4
4
  description = "The official Python library for the isaacus API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -1,5 +1,7 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
+ import typing as _t
4
+
3
5
  from . import types
4
6
  from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes
5
7
  from ._utils import file_from_path
@@ -68,6 +70,9 @@ __all__ = [
68
70
  "DefaultAsyncHttpxClient",
69
71
  ]
70
72
 
73
+ if not _t.TYPE_CHECKING:
74
+ from ._utils._resources_proxy import resources as resources
75
+
71
76
  _setup_logging()
72
77
 
73
78
  # Update the __module__ attribute for exported symbols so that
@@ -935,6 +935,9 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
935
935
  if self.custom_auth is not None:
936
936
  kwargs["auth"] = self.custom_auth
937
937
 
938
+ if options.follow_redirects is not None:
939
+ kwargs["follow_redirects"] = options.follow_redirects
940
+
938
941
  log.debug("Sending HTTP Request: %s %s", request.method, request.url)
939
942
 
940
943
  response = None
@@ -1435,6 +1438,9 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1435
1438
  if self.custom_auth is not None:
1436
1439
  kwargs["auth"] = self.custom_auth
1437
1440
 
1441
+ if options.follow_redirects is not None:
1442
+ kwargs["follow_redirects"] = options.follow_redirects
1443
+
1438
1444
  log.debug("Sending HTTP Request: %s %s", request.method, request.url)
1439
1445
 
1440
1446
  response = None
@@ -737,6 +737,7 @@ class FinalRequestOptionsInput(TypedDict, total=False):
737
737
  idempotency_key: str
738
738
  json_data: Body
739
739
  extra_json: AnyMapping
740
+ follow_redirects: bool
740
741
 
741
742
 
742
743
  @final
@@ -750,6 +751,7 @@ class FinalRequestOptions(pydantic.BaseModel):
750
751
  files: Union[HttpxRequestFiles, None] = None
751
752
  idempotency_key: Union[str, None] = None
752
753
  post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
754
+ follow_redirects: Union[bool, None] = None
753
755
 
754
756
  # It should be noted that we cannot use `json` here as that would override
755
757
  # a BaseModel method in an incompatible fashion.
@@ -100,6 +100,7 @@ class RequestOptions(TypedDict, total=False):
100
100
  params: Query
101
101
  extra_json: AnyMapping
102
102
  idempotency_key: str
103
+ follow_redirects: bool
103
104
 
104
105
 
105
106
  # Sentinel class used until PEP 0661 is accepted
@@ -215,3 +216,4 @@ class _GenericAlias(Protocol):
215
216
 
216
217
  class HttpxSendArgs(TypedDict, total=False):
217
218
  auth: httpx.Auth
219
+ follow_redirects: bool
@@ -46,7 +46,10 @@ class LazyProxy(Generic[T], ABC):
46
46
  @property # type: ignore
47
47
  @override
48
48
  def __class__(self) -> type: # pyright: ignore
49
- proxied = self.__get_proxied__()
49
+ try:
50
+ proxied = self.__get_proxied__()
51
+ except Exception:
52
+ return type(self)
50
53
  if issubclass(type(proxied), LazyProxy):
51
54
  return type(proxied)
52
55
  return proxied.__class__
@@ -0,0 +1,24 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+ from typing_extensions import override
5
+
6
+ from ._proxy import LazyProxy
7
+
8
+
9
+ class ResourcesProxy(LazyProxy[Any]):
10
+ """A proxy for the `isaacus.resources` module.
11
+
12
+ This is used so that we can lazily import `isaacus.resources` only when
13
+ needed *and* so that users can just import `isaacus` and reference `isaacus.resources`
14
+ """
15
+
16
+ @override
17
+ def __load__(self) -> Any:
18
+ import importlib
19
+
20
+ mod = importlib.import_module("isaacus.resources")
21
+ return mod
22
+
23
+
24
+ resources = ResourcesProxy().__as_proxied__()
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "isaacus"
4
- __version__ = "0.6.0" # x-release-please-version
4
+ __version__ = "0.7.0" # x-release-please-version
@@ -61,7 +61,8 @@ class AnswerExtraction(BaseModel):
61
61
  extractions: List[Extraction]
62
62
  """
63
63
  The results of extracting answers from the texts, ordered from highest to lowest
64
- inextractability score.
64
+ answer confidence score (or else lowest to highest inextractability score if
65
+ there are no answers for a text).
65
66
  """
66
67
 
67
68
  usage: Usage
@@ -850,6 +850,33 @@ class TestIsaacus:
850
850
 
851
851
  assert response.http_request.headers.get("x-stainless-retry-count") == "42"
852
852
 
853
+ @pytest.mark.respx(base_url=base_url)
854
+ def test_follow_redirects(self, respx_mock: MockRouter) -> None:
855
+ # Test that the default follow_redirects=True allows following redirects
856
+ respx_mock.post("/redirect").mock(
857
+ return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
858
+ )
859
+ respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"}))
860
+
861
+ response = self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
862
+ assert response.status_code == 200
863
+ assert response.json() == {"status": "ok"}
864
+
865
+ @pytest.mark.respx(base_url=base_url)
866
+ def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None:
867
+ # Test that follow_redirects=False prevents following redirects
868
+ respx_mock.post("/redirect").mock(
869
+ return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
870
+ )
871
+
872
+ with pytest.raises(APIStatusError) as exc_info:
873
+ self.client.post(
874
+ "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response
875
+ )
876
+
877
+ assert exc_info.value.response.status_code == 302
878
+ assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected"
879
+
853
880
 
854
881
  class TestAsyncIsaacus:
855
882
  client = AsyncIsaacus(base_url=base_url, api_key=api_key, _strict_response_validation=True)
@@ -1707,3 +1734,30 @@ class TestAsyncIsaacus:
1707
1734
  raise AssertionError("calling get_platform using asyncify resulted in a hung process")
1708
1735
 
1709
1736
  time.sleep(0.1)
1737
+
1738
+ @pytest.mark.respx(base_url=base_url)
1739
+ async def test_follow_redirects(self, respx_mock: MockRouter) -> None:
1740
+ # Test that the default follow_redirects=True allows following redirects
1741
+ respx_mock.post("/redirect").mock(
1742
+ return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
1743
+ )
1744
+ respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"}))
1745
+
1746
+ response = await self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
1747
+ assert response.status_code == 200
1748
+ assert response.json() == {"status": "ok"}
1749
+
1750
+ @pytest.mark.respx(base_url=base_url)
1751
+ async def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None:
1752
+ # Test that follow_redirects=False prevents following redirects
1753
+ respx_mock.post("/redirect").mock(
1754
+ return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
1755
+ )
1756
+
1757
+ with pytest.raises(APIStatusError) as exc_info:
1758
+ await self.client.post(
1759
+ "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response
1760
+ )
1761
+
1762
+ assert exc_info.value.response.status_code == 302
1763
+ assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected"
@@ -21,3 +21,14 @@ def test_recursive_proxy() -> None:
21
21
  assert dir(proxy) == []
22
22
  assert type(proxy).__name__ == "RecursiveLazyProxy"
23
23
  assert type(operator.attrgetter("name.foo.bar.baz")(proxy)).__name__ == "RecursiveLazyProxy"
24
+
25
+
26
+ def test_isinstance_does_not_error() -> None:
27
+ class AlwaysErrorProxy(LazyProxy[Any]):
28
+ @override
29
+ def __load__(self) -> Any:
30
+ raise RuntimeError("Mocking missing dependency")
31
+
32
+ proxy = AlwaysErrorProxy()
33
+ assert not isinstance(proxy, dict)
34
+ assert isinstance(proxy, LazyProxy)
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.6.0"
3
- }
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