nlbone 0.8.6__tar.gz → 0.9.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.
- {nlbone-0.8.6 → nlbone-0.9.0}/PKG-INFO +1 -1
- {nlbone-0.8.6 → nlbone-0.9.0}/pyproject.toml +1 -1
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/auth/auth_service.py +18 -3
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/engine.py +0 -2
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/dependencies/async_auth.py +3 -3
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/dependencies/auth.py +5 -8
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/middleware/authentication.py +1 -1
- {nlbone-0.8.6 → nlbone-0.9.0}/.gitignore +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/LICENSE +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/README.md +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/auth/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/auth/keycloak.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/auth/token_provider.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/cache/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/cache/async_redis.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/cache/memory.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/cache/pubsub_listener.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/cache/redis.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/audit.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/base.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/query_builder.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/repository.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/schema.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/types.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/postgres/uow.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/redis/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/db/redis/client.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/http_clients/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/http_clients/pricing/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/http_clients/pricing/pricing_service.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/http_clients/uploadchi/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/http_clients/uploadchi/uploadchi.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/http_clients/uploadchi/uploadchi_async.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/i18n/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/i18n/engine.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/i18n/loaders.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/i18n/locales/fa-IR.json +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/messaging/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/messaging/event_bus.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/messaging/rabbitmq.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/outbox/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/outbox/outbox_consumer.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/outbox/outbox_repo.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/percolation/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/percolation/connection.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/repositories/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/snowflake.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/ticketing/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/adapters/ticketing/client.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/config/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/config/logging.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/config/settings.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/container.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/application/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/application/base_worker.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/application/bus.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/application/di.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/application/registry.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/application/services/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/application/use_case.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/domain/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/domain/base.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/domain/models.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/auth.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/cache.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/event_bus.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/files.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/outbox.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/repository.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/translation.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/core/ports/uow.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/additional_filed/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/additional_filed/assembler.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/additional_filed/default_field_rules/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/additional_filed/default_field_rules/image_field_rules.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/additional_filed/field_registry.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/additional_filed/resolver.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/dependencies/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/dependencies/client_credential.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/dependencies/db.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/dependencies/uow.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/exception_handlers.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/exceptions.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/middleware/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/middleware/access_log.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/middleware/add_request_context.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/pagination/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/pagination/offset_base.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/routers.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/schema/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/schema/adaptive_schema.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/schema/base_response_model.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/api/schemas.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/cli/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/cli/crypto.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/cli/init_db.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/cli/main.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/cli/ticket.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/jobs/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/jobs/dispatch_outbox.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/interfaces/jobs/sync_tokens.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/types.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/__init__.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/cache.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/cache_keys.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/cache_registry.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/context.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/crypto.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/flatten_dict.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/flatten_sqlalchemy_result.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/http.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/normalize_mobile.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/read_files.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/redactor.py +0 -0
- {nlbone-0.8.6 → nlbone-0.9.0}/src/nlbone/utils/time.py +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
|
|
1
3
|
import requests
|
|
2
4
|
|
|
3
5
|
from nlbone.config.settings import get_settings
|
|
@@ -15,7 +17,12 @@ class AuthService(BaseAuthService):
|
|
|
15
17
|
self._timeout = float(s.HTTP_TIMEOUT_SECONDS)
|
|
16
18
|
self._client = requests.session()
|
|
17
19
|
|
|
18
|
-
def has_access(self, token: str, permissions: list[str]) -> bool:
|
|
20
|
+
def has_access(self, token: str, permissions: list[str]) -> bool:
|
|
21
|
+
data = self.verify_token(token)
|
|
22
|
+
if not data:
|
|
23
|
+
return False
|
|
24
|
+
has_access = [self.client_id + "#" + perm in data.get("allowed_permissions", []) for perm in permissions]
|
|
25
|
+
return all(has_access)
|
|
19
26
|
|
|
20
27
|
@cached(ttl=15 * 60)
|
|
21
28
|
def verify_token(self, token: str) -> dict:
|
|
@@ -41,7 +48,9 @@ class AuthService(BaseAuthService):
|
|
|
41
48
|
return result.json()
|
|
42
49
|
return None
|
|
43
50
|
|
|
44
|
-
def is_client_token(self, token: str, allowed_clients: set[str] | None = None) -> bool:
|
|
51
|
+
def is_client_token(self, token: str, allowed_clients: set[str] | None = None) -> bool:
|
|
52
|
+
data = self.verify_token(token)
|
|
53
|
+
return data.get('preferred_username').startswith('service-account')
|
|
45
54
|
|
|
46
55
|
def client_has_access(self, token: str, permissions: list[str], allowed_clients: set[str] | None = None) -> bool:
|
|
47
56
|
data = self.verify_token(token)
|
|
@@ -50,4 +59,10 @@ class AuthService(BaseAuthService):
|
|
|
50
59
|
has_access = [self.client_id + "#" + perm in data.get("allowed_permissions", []) for perm in permissions]
|
|
51
60
|
return all(has_access)
|
|
52
61
|
|
|
53
|
-
def get_permissions(self, token: str) -> list[str]:
|
|
62
|
+
def get_permissions(self, token: str) -> list[str]:
|
|
63
|
+
data = self.verify_token(token)
|
|
64
|
+
return data.get('allowed_permissions', [])
|
|
65
|
+
|
|
66
|
+
@functools.lru_cache(maxsize=1)
|
|
67
|
+
def get_auth_service() -> AuthService:
|
|
68
|
+
return AuthService()
|
|
@@ -57,7 +57,6 @@ async def async_session() -> AsyncGenerator[AsyncSession, Any]:
|
|
|
57
57
|
session = _async_session_factory()
|
|
58
58
|
try:
|
|
59
59
|
yield session
|
|
60
|
-
await session.commit()
|
|
61
60
|
except Exception:
|
|
62
61
|
await session.rollback()
|
|
63
62
|
raise
|
|
@@ -104,7 +103,6 @@ def sync_session() -> Generator[Session, None, None]:
|
|
|
104
103
|
s = _sync_session_factory()
|
|
105
104
|
try:
|
|
106
105
|
yield s
|
|
107
|
-
s.commit()
|
|
108
106
|
except Exception:
|
|
109
107
|
s.rollback()
|
|
110
108
|
raise
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
|
|
3
|
-
from nlbone.adapters.auth import
|
|
3
|
+
from nlbone.adapters.auth.auth_service import get_auth_service
|
|
4
4
|
from nlbone.interfaces.api.exceptions import ForbiddenException, UnauthorizedException
|
|
5
5
|
from nlbone.utils.context import current_request
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ async def current_user_id() -> int:
|
|
|
16
16
|
|
|
17
17
|
async def current_client_id() -> str:
|
|
18
18
|
request = current_request()
|
|
19
|
-
if client_id :=
|
|
19
|
+
if client_id := get_auth_service().get_client_id(request.state.token):
|
|
20
20
|
return str(client_id)
|
|
21
21
|
raise UnauthorizedException()
|
|
22
22
|
|
|
@@ -50,7 +50,7 @@ def has_access(*, permissions=None):
|
|
|
50
50
|
request = current_request()
|
|
51
51
|
if not await current_user_id():
|
|
52
52
|
raise UnauthorizedException()
|
|
53
|
-
if not
|
|
53
|
+
if not get_auth_service().has_access(request.state.token, permissions=permissions):
|
|
54
54
|
raise ForbiddenException(f"Forbidden {permissions}")
|
|
55
55
|
|
|
56
56
|
return await func(*args, **kwargs)
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
|
|
3
3
|
from nlbone.core.domain.models import CurrentUserData
|
|
4
|
-
from nlbone.adapters.auth import
|
|
5
|
-
from nlbone.adapters.auth.keycloak import get_auth_service
|
|
4
|
+
from nlbone.adapters.auth.auth_service import get_auth_service
|
|
6
5
|
from nlbone.config.settings import get_settings
|
|
7
6
|
from nlbone.interfaces.api.exceptions import ForbiddenException, UnauthorizedException
|
|
8
7
|
from nlbone.utils.context import current_request
|
|
@@ -31,14 +30,14 @@ def current_user() -> CurrentUserData:
|
|
|
31
30
|
|
|
32
31
|
def current_client_id() -> str:
|
|
33
32
|
request = current_request()
|
|
34
|
-
if client_id :=
|
|
33
|
+
if client_id := get_auth_service().get_client_id(request.state.token):
|
|
35
34
|
return str(client_id)
|
|
36
35
|
raise UnauthorizedException()
|
|
37
36
|
|
|
38
37
|
|
|
39
38
|
def client_has_access_func(*, permissions=None):
|
|
40
39
|
request = current_request()
|
|
41
|
-
if not
|
|
40
|
+
if not get_auth_service().client_has_access(request.state.token, permissions=permissions):
|
|
42
41
|
raise ForbiddenException(f"Forbidden {permissions}")
|
|
43
42
|
return True
|
|
44
43
|
|
|
@@ -71,10 +70,8 @@ def user_has_access_func(*, permissions=None):
|
|
|
71
70
|
request = current_request()
|
|
72
71
|
if not current_user_id():
|
|
73
72
|
raise UnauthorizedException()
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if p not in user_permissions:
|
|
77
|
-
raise ForbiddenException(f"Forbidden {permissions}")
|
|
73
|
+
if not get_auth_service().has_access(request.state.token, permissions=permissions):
|
|
74
|
+
raise ForbiddenException(f"Forbidden {permissions}")
|
|
78
75
|
return True
|
|
79
76
|
|
|
80
77
|
|
|
@@ -88,7 +88,7 @@ class AuthenticationMiddleware(BaseHTTPMiddleware):
|
|
|
88
88
|
return await call_next(request)
|
|
89
89
|
if request.headers.get("X-Client-Id") == "website" and request.headers.get("Authorization"):
|
|
90
90
|
authenticate_user(request)
|
|
91
|
-
elif request.cookies.get("access_token"):
|
|
91
|
+
elif request.cookies.get("access_token") or request.headers.get("Authorization"):
|
|
92
92
|
authenticate_user(request)
|
|
93
93
|
elif request.headers.get("Authorization"):
|
|
94
94
|
authenticate_admin_user(request, auth_service=self._get_auth)
|
|
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
|
|
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
|