dynamicforms-fastapi-viewsets 0.14.2__tar.gz → 0.15.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.
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/PKG-INFO +1 -1
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/backends/django_orm.py +2 -5
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/collection_viewset.py +1 -8
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/changes.py +10 -3
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/mixins.py +29 -9
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/pyproject.toml +1 -1
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/pyproject.toml.orig +1 -1
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/LICENSE +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/README.md +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/action_configuration.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/backends/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/conf.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/context/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/context/auth/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/context/auth/django.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/context/auth/jwt.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/context/auth/static.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/cursor.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/build_schema.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/celery_viewset/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/celery_viewset/client.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/celery_viewset/payload.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/celery_viewset/result_reader.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/celery_viewset/server.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/celery_viewset/transport.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/conftest.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/lifecycle_runner.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/primary_key_model_helper.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/query_model.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/route_viewset.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/decorators/sub_viewsets.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/endpoint_docs.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/error_namespace.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/error_responses.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/authorizers.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/conftest.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/delivery.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/event.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/lifecycle.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/redis.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/scopes.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/sources.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/store.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/topics.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/events/viewset.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/exceptions.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/filters/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/filters/base.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/filters/declaration.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/filters/operators.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/filters/registry.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/list_query.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/list_shapes.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/middleware/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/middleware/auth/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/middleware/auth/authorization.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/middleware/cookies.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/middleware/idempotency.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/middleware/rate_limiter.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/mux_ws/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/mux_ws/asgi.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/mux_ws/protocol.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/mux_ws/registry.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/mux_ws/server.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/mux_ws/transports.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/py.typed +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/response_classes.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/routing.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/save_state/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/save_state/save_state.py +0 -0
- {dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/fastapi_viewsets/save_state/serialize_state.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dynamicforms-fastapi-viewsets
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: Django REST Framework-style viewsets for FastAPI, with optional Celery-backed async execution and a Vue/TypeScript client counterpart.
|
|
5
5
|
Keywords: fastapi,viewsets,rest,dynamicforms,celery,django-rest-framework
|
|
6
6
|
Author: Jure Erznožnik
|
|
@@ -286,13 +286,10 @@ class DjangoORMViewSet(ImplMixin[K, T], Generic[K, T]):
|
|
|
286
286
|
instance.save()
|
|
287
287
|
return [self.to_record(rows[pk]) for pk in records]
|
|
288
288
|
|
|
289
|
-
async def perform_destroy(self, context: Context, pk: K) -> dict:
|
|
289
|
+
async def perform_destroy(self, context: Context, pk: K) -> dict[K, None]:
|
|
290
290
|
instance = await self._get_or_404(context, pk)
|
|
291
291
|
await instance.adelete()
|
|
292
|
-
return {
|
|
293
|
-
|
|
294
|
-
async def perform_bulk_destroy(self, context: Context, pk: list[K]) -> list[dict]:
|
|
295
|
-
return [await self.perform_destroy(context, one) for one in pk]
|
|
292
|
+
return {pk: None}
|
|
296
293
|
|
|
297
294
|
# -----------------------------------------------------------------------
|
|
298
295
|
|
|
@@ -66,17 +66,10 @@ class AsyncCollectionViewSet(
|
|
|
66
66
|
results.append(await self.container_update(pk, data, partial))
|
|
67
67
|
return results
|
|
68
68
|
|
|
69
|
-
async def perform_destroy(self, _context: Context, pk: K) -> dict[K,
|
|
69
|
+
async def perform_destroy(self, _context: Context, pk: K) -> dict[K, None]:
|
|
70
70
|
await self.container_delete(pk)
|
|
71
71
|
return {pk: None}
|
|
72
72
|
|
|
73
|
-
async def perform_bulk_destroy(self, _context: Context, pk: list[K]) -> list[dict[K, Any]]:
|
|
74
|
-
results = []
|
|
75
|
-
for p in pk:
|
|
76
|
-
await self.container_delete(p)
|
|
77
|
-
results.append({p: None})
|
|
78
|
-
return results
|
|
79
|
-
|
|
80
73
|
|
|
81
74
|
class CollectionViewSet(AsyncCollectionViewSet[K, T]):
|
|
82
75
|
def __init__(self, container: ReadableCollection[T] | MutableCollection[K, T], pk_field: str = "id"):
|
|
@@ -241,12 +241,19 @@ class ChangeEvents(Middleware):
|
|
|
241
241
|
return name
|
|
242
242
|
|
|
243
243
|
def changes_for(self, execution: ActionExecution, op: str, result: Any) -> list[Change]:
|
|
244
|
-
"""
|
|
244
|
+
"""
|
|
245
|
+
For `deleted`, one change per pk of the `pk` argument; of a bulk, only the pks the result maps to None
|
|
246
|
+
(destroyed). Otherwise one per returned record. A `ViewSetResult` contributes its `body`.
|
|
247
|
+
"""
|
|
245
248
|
bulk = execution.action in _BULK_ACTIONS
|
|
249
|
+
body = result.body if isinstance(result, ViewSetResult) else result
|
|
246
250
|
if op == "deleted":
|
|
247
251
|
pk = _argument(execution, "pk")
|
|
248
|
-
|
|
249
|
-
|
|
252
|
+
if not bulk:
|
|
253
|
+
return [Change(pk=pk)]
|
|
254
|
+
if isinstance(body, Mapping):
|
|
255
|
+
return [Change(pk=one) for one in dict.fromkeys(pk) if one in body and body[one] is None]
|
|
256
|
+
return [Change(pk=one) for one in pk]
|
|
250
257
|
field = self.pk_field_for(execution)
|
|
251
258
|
return [Change(pk=_read_pk(execution, record, field)) for record in (body if bulk else [body])]
|
|
252
259
|
|
|
@@ -5,8 +5,10 @@ from enum import Enum
|
|
|
5
5
|
from typing import Annotated, Any, final, Generic, get_args, get_origin, Union
|
|
6
6
|
|
|
7
7
|
from fastapi import APIRouter, Header, Query
|
|
8
|
+
from fastapi.exceptions import RequestValidationError
|
|
8
9
|
from pydantic import BaseModel, ConfigDict, create_model
|
|
9
10
|
from pydantic.alias_generators import to_camel
|
|
11
|
+
from starlette.exceptions import HTTPException
|
|
10
12
|
from typing_extensions import TypeVar
|
|
11
13
|
|
|
12
14
|
from fastapi_viewsets.conf import settings
|
|
@@ -23,6 +25,7 @@ from fastapi_viewsets.cursor import (
|
|
|
23
25
|
make_predicate,
|
|
24
26
|
position_of,
|
|
25
27
|
)
|
|
28
|
+
from fastapi_viewsets.error_responses import ApiErrorBody, error_body
|
|
26
29
|
from fastapi_viewsets.exceptions import CursorRequestError, UnsupportedListShapeError
|
|
27
30
|
from fastapi_viewsets.filters import filters_from, FilterSet
|
|
28
31
|
from fastapi_viewsets.list_query import (
|
|
@@ -95,18 +98,29 @@ class ImplMixin(Generic[K, T], ABC):
|
|
|
95
98
|
raise NotImplementedError("Method 'perform_bulk_update' must be implemented.")
|
|
96
99
|
|
|
97
100
|
@abstractmethod
|
|
98
|
-
async def perform_destroy(self, context: Context, pk: K) -> dict[K,
|
|
101
|
+
async def perform_destroy(self, context: Context, pk: K) -> dict[K, None]:
|
|
99
102
|
"""
|
|
100
|
-
|
|
103
|
+
Destroys record `pk` and returns `{pk: None}`; raises `NotFoundError` for a missing record.
|
|
101
104
|
"""
|
|
102
105
|
raise NotImplementedError("Method 'perform_destroy' must be implemented.")
|
|
103
106
|
|
|
104
|
-
|
|
105
|
-
async def perform_bulk_destroy(self, context: Context, pk: list[K]) -> list[dict[K, Any]]:
|
|
107
|
+
async def perform_bulk_destroy(self, context: Context, pk: list[K]) -> dict[K, ApiErrorBody | None]:
|
|
106
108
|
"""
|
|
107
|
-
|
|
109
|
+
Destroys each key with `perform_destroy`, independently of the others: None for a destroyed key, the
|
|
110
|
+
`ApiErrorBody` of an `HTTPException` or `RequestValidationError` its destruction raised. Any other
|
|
111
|
+
exception propagates. A repeated key is destroyed once.
|
|
108
112
|
"""
|
|
109
|
-
|
|
113
|
+
results: dict[K, ApiErrorBody | None] = {}
|
|
114
|
+
for one in pk:
|
|
115
|
+
if one in results:
|
|
116
|
+
continue
|
|
117
|
+
try:
|
|
118
|
+
await self.perform_destroy(context, one)
|
|
119
|
+
except (HTTPException, RequestValidationError) as error:
|
|
120
|
+
results[one] = ApiErrorBody.model_validate(error_body(error))
|
|
121
|
+
else:
|
|
122
|
+
results[one] = None
|
|
123
|
+
return results
|
|
110
124
|
|
|
111
125
|
|
|
112
126
|
###################################################################################################
|
|
@@ -649,14 +663,15 @@ class BulkUpdateMixin(UpdateMixin[K, T], BulkOnlyUpdateMixin[K, T]):
|
|
|
649
663
|
###################################################################################################
|
|
650
664
|
class DestroyMixin(Generic[K, T], ABC):
|
|
651
665
|
"""
|
|
652
|
-
Destroy a model instance.
|
|
666
|
+
Destroy a model instance.
|
|
653
667
|
"""
|
|
654
668
|
|
|
655
669
|
__router = APIRouter()
|
|
656
670
|
|
|
657
671
|
@final
|
|
658
672
|
@__router.delete("/{pk}", responses=NOT_FOUND_RESPONSE)
|
|
659
|
-
async def destroy(self: "ImplMixin[K, T] | DestroyMixin[K, T]", context: Context, pk: K) -> dict[K,
|
|
673
|
+
async def destroy(self: "ImplMixin[K, T] | DestroyMixin[K, T]", context: Context, pk: K) -> dict[K, None]:
|
|
674
|
+
"""Destroy one record. Answers `{pk: null}`; 404 `fastapi-viewsets.not_found` for a missing record."""
|
|
660
675
|
return await self.perform_destroy(context, pk)
|
|
661
676
|
|
|
662
677
|
|
|
@@ -671,7 +686,12 @@ class BulkOnlyDestroyMixin(Generic[K, T], ABC):
|
|
|
671
686
|
@__router.delete("bulk")
|
|
672
687
|
async def bulk_destroy(
|
|
673
688
|
self: "ImplMixin[K, T] | BulkOnlyDestroyMixin[K, T]", context: Context, pk: list[K]
|
|
674
|
-
) ->
|
|
689
|
+
) -> dict[K, ApiErrorBody | None]:
|
|
690
|
+
"""
|
|
691
|
+
Destroy the records of the keys in the body, each independently of the others. Answers 200 with an
|
|
692
|
+
object keyed by pk: `null` for a destroyed record, the `ApiErrorBody` of the failure otherwise
|
|
693
|
+
(`fastapi-viewsets.not_found` for a missing record). A failed key does not stop the others.
|
|
694
|
+
"""
|
|
675
695
|
return await self.perform_bulk_destroy(context, pk)
|
|
676
696
|
|
|
677
697
|
|
{dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/pyproject.toml
RENAMED
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dynamicforms-fastapi-viewsets"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.15.0"
|
|
8
8
|
description = "Django REST Framework-style viewsets for FastAPI, with optional Celery-backed async execution and a Vue/TypeScript client counterpart."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
{dynamicforms_fastapi_viewsets-0.14.2 → dynamicforms_fastapi_viewsets-0.15.0}/pyproject.toml.orig
RENAMED
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dynamicforms-fastapi-viewsets"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.15.0"
|
|
8
8
|
description = "Django REST Framework-style viewsets for FastAPI, with optional Celery-backed async execution and a Vue/TypeScript client counterpart."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|