kiba-core 0.5.3.dev63__tar.gz → 0.5.3.dev64__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.
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/CHANGELOG.md +2 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/PKG-INFO +1 -1
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/queues/aqs.py +9 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/queues/cosmos.py +24 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/queues/message_queue.py +8 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/queues/sql.py +10 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/queues/sqs.py +12 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/kiba_core.egg-info/PKG-INFO +1 -1
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/pyproject.toml +1 -1
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/.github/pull_request_template.md +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/.github/workflows/deploy.yml +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/.github/workflows/pull-request.yml +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/.github/workflows/release.yml +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/.gitignore +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/Dockerfile +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/README.md +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/api_request.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/api_response.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/authorizer.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/default_routes.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/health.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/json_route.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/middleware/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/middleware/database_connection_middleware.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/middleware/exception_handling_middleware.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/middleware/logging_middleware.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/middleware/origin_ip_middleware.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/middleware/server_headers_middleware.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/openapi.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/rate_limit.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/request_context.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/route.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/route_auth.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/route_metadata.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/streaming_json_route.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/aws_requester.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/caching/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/caching/cache.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/caching/dict_cache.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/caching/file_cache.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/exceptions.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/http/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/http/basic_authentication.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/http/jwt.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/http/rest_method.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/logging.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/notifications/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/notifications/discord_client.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/notifications/notification_client.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/notifications/slack_client.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/py.typed +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/queues/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/queues/message_queue_processor.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/queues/model.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/requester/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/requester/requester.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/s3_manager.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/service_client.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/store/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/store/database.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/store/retriever.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/store/saver.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/async_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/chain_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/date_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/dict_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/file_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/hashing_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/http_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/json_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/list_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/string_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/typing_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/url_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/util/value_holder.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/web3/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/web3/eth_client.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/web3/multicall3.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/kiba_core.egg-info/SOURCES.txt +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/kiba_core.egg-info/dependency_links.txt +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/kiba_core.egg-info/requires.txt +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/kiba_core.egg-info/top_level.txt +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/makefile +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/setup.cfg +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_api_response.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_authorizer.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_exception_handling_middleware.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_json_route.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_openapi.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_origin_ip_middleware.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_rate_limit.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_request_context.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_route.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_streaming_json_route.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/caching/test_dict_cache.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/caching/test_file_cache.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/requester/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/requester/test_requester.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/test_database.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/test_exceptions.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_async_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_chain_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_date_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_dict_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_file_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_json_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_list_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_string_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/util/test_url_util.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/web3/__init__.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/web3/test_rest_eth_client.py +0 -0
- {kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/uv.lock +0 -0
|
@@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
|
+
- [MAJOR] Added abstract `MessageQueue.get_message_count` (implemented for SQS, AQS, SQL and Cosmos queues) for the number of messages waiting to be processed
|
|
12
|
+
- [MAJOR] Added abstract `MessageQueue.get_inflight_message_count` (implemented for SQS, SQL and Cosmos queues; AQS raises `NotImplementedError` as Azure does not expose it) for the number of messages currently being processed
|
|
11
13
|
- [MAJOR] Reworked `route` to compose JSON or streaming transport, application-resolved authorization, and rate limiting
|
|
12
14
|
- [MAJOR] Replaced authorization-decorator sequences with named `RouteAuthResolver` policies
|
|
13
15
|
- [MINOR] Added `authJwt`, `authBasic`, and `originIp` to `KibaApiRequest`
|
|
@@ -80,3 +80,12 @@ class AqsMessageQueue(MessageQueue[AqsMessage]):
|
|
|
80
80
|
if not self._aqsClient:
|
|
81
81
|
raise InternalServerErrorException('You need to call .connect() before trying to delete messages')
|
|
82
82
|
await self._aqsClient.delete_message(message=message.aqsId, pop_receipt=message.popReceipt)
|
|
83
|
+
|
|
84
|
+
async def get_message_count(self) -> int:
|
|
85
|
+
if not self._aqsClient:
|
|
86
|
+
raise InternalServerErrorException('You need to call .connect() before trying to count messages')
|
|
87
|
+
properties = await self._aqsClient.get_queue_properties()
|
|
88
|
+
return int(properties.approximate_message_count or 0)
|
|
89
|
+
|
|
90
|
+
async def get_inflight_message_count(self) -> int:
|
|
91
|
+
raise NotImplementedError('Azure Storage Queues do not expose an in-flight message count')
|
|
@@ -188,3 +188,27 @@ class CosmosMessageQueue(MessageQueue[CosmosMessage]):
|
|
|
188
188
|
],
|
|
189
189
|
partition_key=self.queueName,
|
|
190
190
|
)
|
|
191
|
+
|
|
192
|
+
async def get_message_count(self) -> int:
|
|
193
|
+
counts = self.container.query_items(
|
|
194
|
+
query='SELECT COUNT(1) AS messageCount FROM c WHERE c.itemType = @itemType AND c.queueName = @queueName AND c.visibleDate <= @now',
|
|
195
|
+
parameters=[
|
|
196
|
+
{'name': '@itemType', 'value': 'message'},
|
|
197
|
+
{'name': '@queueName', 'value': self.queueName},
|
|
198
|
+
{'name': '@now', 'value': time.time()},
|
|
199
|
+
],
|
|
200
|
+
partition_key=self.queueName,
|
|
201
|
+
)
|
|
202
|
+
return sum([int(item['messageCount']) async for item in counts])
|
|
203
|
+
|
|
204
|
+
async def get_inflight_message_count(self) -> int:
|
|
205
|
+
counts = self.container.query_items(
|
|
206
|
+
query='SELECT COUNT(1) AS messageCount FROM c WHERE c.itemType = @itemType AND c.queueName = @queueName AND c.leaseId != null AND c.visibleDate > @now',
|
|
207
|
+
parameters=[
|
|
208
|
+
{'name': '@itemType', 'value': 'message'},
|
|
209
|
+
{'name': '@queueName', 'value': self.queueName},
|
|
210
|
+
{'name': '@now', 'value': time.time()},
|
|
211
|
+
],
|
|
212
|
+
partition_key=self.queueName,
|
|
213
|
+
)
|
|
214
|
+
return sum([int(item['messageCount']) async for item in counts])
|
|
@@ -33,3 +33,11 @@ class MessageQueue[MessageType: Message](ABC):
|
|
|
33
33
|
@abc.abstractmethod
|
|
34
34
|
async def delete_message(self, message: MessageType) -> None:
|
|
35
35
|
raise NotImplementedError
|
|
36
|
+
|
|
37
|
+
@abc.abstractmethod
|
|
38
|
+
async def get_message_count(self) -> int:
|
|
39
|
+
raise NotImplementedError
|
|
40
|
+
|
|
41
|
+
@abc.abstractmethod
|
|
42
|
+
async def get_inflight_message_count(self) -> int:
|
|
43
|
+
raise NotImplementedError
|
|
@@ -163,3 +163,13 @@ class SqlMessageQueue(MessageQueue[SqlMessage]):
|
|
|
163
163
|
async with self.database.create_transaction() as connection:
|
|
164
164
|
deleteQuery = sqlalchemy.delete(self.table).where(self.table.c.id == message.id).where(self.table.c.lockToken == message.lockToken)
|
|
165
165
|
await self.database.execute(query=deleteQuery, connection=connection) # type: ignore[arg-type]
|
|
166
|
+
|
|
167
|
+
async def get_message_count(self) -> int:
|
|
168
|
+
countQuery = sqlalchemy.select(sqlalchemy.func.count()).select_from(self.table).where(self.table.c.queueName == self.queueName).where(self.table.c.visibleDate <= date_util.datetime_from_now())
|
|
169
|
+
result = await self.database.execute(query=countQuery)
|
|
170
|
+
return int(result.scalar_one())
|
|
171
|
+
|
|
172
|
+
async def get_inflight_message_count(self) -> int:
|
|
173
|
+
countQuery = sqlalchemy.select(sqlalchemy.func.count()).select_from(self.table).where(self.table.c.queueName == self.queueName).where(self.table.c.lockToken.is_not(None)).where(self.table.c.visibleDate > date_util.datetime_from_now())
|
|
174
|
+
result = await self.database.execute(query=countQuery)
|
|
175
|
+
return int(result.scalar_one())
|
|
@@ -96,3 +96,15 @@ class SqsMessageQueue(MessageQueue[SqsMessage]):
|
|
|
96
96
|
if not self._sqsClient:
|
|
97
97
|
raise InternalServerErrorException('You need to call .connect() before trying to delete messages')
|
|
98
98
|
await self._sqsClient.delete_message(QueueUrl=self.queueUrl, ReceiptHandle=message.receiptHandle)
|
|
99
|
+
|
|
100
|
+
async def get_message_count(self) -> int:
|
|
101
|
+
if not self._sqsClient:
|
|
102
|
+
raise InternalServerErrorException('You need to call .connect() before trying to count messages')
|
|
103
|
+
response = await self._sqsClient.get_queue_attributes(QueueUrl=self.queueUrl, AttributeNames=['ApproximateNumberOfMessages'])
|
|
104
|
+
return int(response['Attributes']['ApproximateNumberOfMessages'])
|
|
105
|
+
|
|
106
|
+
async def get_inflight_message_count(self) -> int:
|
|
107
|
+
if not self._sqsClient:
|
|
108
|
+
raise InternalServerErrorException('You need to call .connect() before trying to count messages')
|
|
109
|
+
response = await self._sqsClient.get_queue_attributes(QueueUrl=self.queueUrl, AttributeNames=['ApproximateNumberOfMessagesNotVisible'])
|
|
110
|
+
return int(response['Attributes']['ApproximateNumberOfMessagesNotVisible'])
|
|
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
|
{kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/middleware/exception_handling_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/core/api/middleware/server_headers_middleware.py
RENAMED
|
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
|
{kiba_core-0.5.3.dev63 → kiba_core-0.5.3.dev64}/tests/api/test_exception_handling_middleware.py
RENAMED
|
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
|