plain 0.68.0__tar.gz → 0.69.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 (182) hide show
  1. {plain-0.68.0 → plain-0.69.0}/.gitignore +1 -0
  2. {plain-0.68.0 → plain-0.69.0}/PKG-INFO +1 -1
  3. {plain-0.68.0 → plain-0.69.0}/plain/CHANGELOG.md +23 -1
  4. {plain-0.68.0 → plain-0.69.0}/plain/exceptions.py +1 -43
  5. {plain-0.68.0 → plain-0.69.0}/plain/preflight/registry.py +1 -1
  6. {plain-0.68.0 → plain-0.69.0}/plain/views/objects.py +13 -3
  7. {plain-0.68.0 → plain-0.69.0}/pyproject.toml +1 -1
  8. {plain-0.68.0 → plain-0.69.0}/LICENSE +0 -0
  9. {plain-0.68.0 → plain-0.69.0}/README.md +0 -0
  10. {plain-0.68.0 → plain-0.69.0}/plain/AGENTS.md +0 -0
  11. {plain-0.68.0 → plain-0.69.0}/plain/README.md +0 -0
  12. {plain-0.68.0 → plain-0.69.0}/plain/__main__.py +0 -0
  13. {plain-0.68.0 → plain-0.69.0}/plain/assets/README.md +0 -0
  14. {plain-0.68.0 → plain-0.69.0}/plain/assets/__init__.py +0 -0
  15. {plain-0.68.0 → plain-0.69.0}/plain/assets/compile.py +0 -0
  16. {plain-0.68.0 → plain-0.69.0}/plain/assets/finders.py +0 -0
  17. {plain-0.68.0 → plain-0.69.0}/plain/assets/fingerprints.py +0 -0
  18. {plain-0.68.0 → plain-0.69.0}/plain/assets/urls.py +0 -0
  19. {plain-0.68.0 → plain-0.69.0}/plain/assets/views.py +0 -0
  20. {plain-0.68.0 → plain-0.69.0}/plain/chores/README.md +0 -0
  21. {plain-0.68.0 → plain-0.69.0}/plain/chores/__init__.py +0 -0
  22. {plain-0.68.0 → plain-0.69.0}/plain/chores/registry.py +0 -0
  23. {plain-0.68.0 → plain-0.69.0}/plain/cli/README.md +0 -0
  24. {plain-0.68.0 → plain-0.69.0}/plain/cli/__init__.py +0 -0
  25. {plain-0.68.0 → plain-0.69.0}/plain/cli/agent/__init__.py +0 -0
  26. {plain-0.68.0 → plain-0.69.0}/plain/cli/agent/docs.py +0 -0
  27. {plain-0.68.0 → plain-0.69.0}/plain/cli/agent/llmdocs.py +0 -0
  28. {plain-0.68.0 → plain-0.69.0}/plain/cli/agent/md.py +0 -0
  29. {plain-0.68.0 → plain-0.69.0}/plain/cli/agent/prompt.py +0 -0
  30. {plain-0.68.0 → plain-0.69.0}/plain/cli/agent/request.py +0 -0
  31. {plain-0.68.0 → plain-0.69.0}/plain/cli/build.py +0 -0
  32. {plain-0.68.0 → plain-0.69.0}/plain/cli/changelog.py +0 -0
  33. {plain-0.68.0 → plain-0.69.0}/plain/cli/chores.py +0 -0
  34. {plain-0.68.0 → plain-0.69.0}/plain/cli/core.py +0 -0
  35. {plain-0.68.0 → plain-0.69.0}/plain/cli/docs.py +0 -0
  36. {plain-0.68.0 → plain-0.69.0}/plain/cli/formatting.py +0 -0
  37. {plain-0.68.0 → plain-0.69.0}/plain/cli/install.py +0 -0
  38. {plain-0.68.0 → plain-0.69.0}/plain/cli/output.py +0 -0
  39. {plain-0.68.0 → plain-0.69.0}/plain/cli/preflight.py +0 -0
  40. {plain-0.68.0 → plain-0.69.0}/plain/cli/print.py +0 -0
  41. {plain-0.68.0 → plain-0.69.0}/plain/cli/registry.py +0 -0
  42. {plain-0.68.0 → plain-0.69.0}/plain/cli/scaffold.py +0 -0
  43. {plain-0.68.0 → plain-0.69.0}/plain/cli/settings.py +0 -0
  44. {plain-0.68.0 → plain-0.69.0}/plain/cli/shell.py +0 -0
  45. {plain-0.68.0 → plain-0.69.0}/plain/cli/startup.py +0 -0
  46. {plain-0.68.0 → plain-0.69.0}/plain/cli/upgrade.py +0 -0
  47. {plain-0.68.0 → plain-0.69.0}/plain/cli/urls.py +0 -0
  48. {plain-0.68.0 → plain-0.69.0}/plain/cli/utils.py +0 -0
  49. {plain-0.68.0 → plain-0.69.0}/plain/csrf/README.md +0 -0
  50. {plain-0.68.0 → plain-0.69.0}/plain/csrf/middleware.py +0 -0
  51. {plain-0.68.0 → plain-0.69.0}/plain/csrf/views.py +0 -0
  52. {plain-0.68.0 → plain-0.69.0}/plain/debug.py +0 -0
  53. {plain-0.68.0 → plain-0.69.0}/plain/forms/README.md +0 -0
  54. {plain-0.68.0 → plain-0.69.0}/plain/forms/__init__.py +0 -0
  55. {plain-0.68.0 → plain-0.69.0}/plain/forms/boundfield.py +0 -0
  56. {plain-0.68.0 → plain-0.69.0}/plain/forms/exceptions.py +0 -0
  57. {plain-0.68.0 → plain-0.69.0}/plain/forms/fields.py +0 -0
  58. {plain-0.68.0 → plain-0.69.0}/plain/forms/forms.py +0 -0
  59. {plain-0.68.0 → plain-0.69.0}/plain/http/README.md +0 -0
  60. {plain-0.68.0 → plain-0.69.0}/plain/http/__init__.py +0 -0
  61. {plain-0.68.0 → plain-0.69.0}/plain/http/cookie.py +0 -0
  62. {plain-0.68.0 → plain-0.69.0}/plain/http/multipartparser.py +0 -0
  63. {plain-0.68.0 → plain-0.69.0}/plain/http/request.py +0 -0
  64. {plain-0.68.0 → plain-0.69.0}/plain/http/response.py +0 -0
  65. {plain-0.68.0 → plain-0.69.0}/plain/internal/__init__.py +0 -0
  66. {plain-0.68.0 → plain-0.69.0}/plain/internal/files/__init__.py +0 -0
  67. {plain-0.68.0 → plain-0.69.0}/plain/internal/files/base.py +0 -0
  68. {plain-0.68.0 → plain-0.69.0}/plain/internal/files/locks.py +0 -0
  69. {plain-0.68.0 → plain-0.69.0}/plain/internal/files/move.py +0 -0
  70. {plain-0.68.0 → plain-0.69.0}/plain/internal/files/temp.py +0 -0
  71. {plain-0.68.0 → plain-0.69.0}/plain/internal/files/uploadedfile.py +0 -0
  72. {plain-0.68.0 → plain-0.69.0}/plain/internal/files/uploadhandler.py +0 -0
  73. {plain-0.68.0 → plain-0.69.0}/plain/internal/files/utils.py +0 -0
  74. {plain-0.68.0 → plain-0.69.0}/plain/internal/handlers/__init__.py +0 -0
  75. {plain-0.68.0 → plain-0.69.0}/plain/internal/handlers/base.py +0 -0
  76. {plain-0.68.0 → plain-0.69.0}/plain/internal/handlers/exception.py +0 -0
  77. {plain-0.68.0 → plain-0.69.0}/plain/internal/handlers/wsgi.py +0 -0
  78. {plain-0.68.0 → plain-0.69.0}/plain/internal/middleware/__init__.py +0 -0
  79. {plain-0.68.0 → plain-0.69.0}/plain/internal/middleware/headers.py +0 -0
  80. {plain-0.68.0 → plain-0.69.0}/plain/internal/middleware/hosts.py +0 -0
  81. {plain-0.68.0 → plain-0.69.0}/plain/internal/middleware/https.py +0 -0
  82. {plain-0.68.0 → plain-0.69.0}/plain/internal/middleware/slash.py +0 -0
  83. {plain-0.68.0 → plain-0.69.0}/plain/json.py +0 -0
  84. {plain-0.68.0 → plain-0.69.0}/plain/logs/README.md +0 -0
  85. {plain-0.68.0 → plain-0.69.0}/plain/logs/__init__.py +0 -0
  86. {plain-0.68.0 → plain-0.69.0}/plain/logs/configure.py +0 -0
  87. {plain-0.68.0 → plain-0.69.0}/plain/logs/debug.py +0 -0
  88. {plain-0.68.0 → plain-0.69.0}/plain/logs/formatters.py +0 -0
  89. {plain-0.68.0 → plain-0.69.0}/plain/logs/loggers.py +0 -0
  90. {plain-0.68.0 → plain-0.69.0}/plain/logs/utils.py +0 -0
  91. {plain-0.68.0 → plain-0.69.0}/plain/packages/README.md +0 -0
  92. {plain-0.68.0 → plain-0.69.0}/plain/packages/__init__.py +0 -0
  93. {plain-0.68.0 → plain-0.69.0}/plain/packages/config.py +0 -0
  94. {plain-0.68.0 → plain-0.69.0}/plain/packages/registry.py +0 -0
  95. {plain-0.68.0 → plain-0.69.0}/plain/paginator.py +0 -0
  96. {plain-0.68.0 → plain-0.69.0}/plain/preflight/README.md +0 -0
  97. {plain-0.68.0 → plain-0.69.0}/plain/preflight/__init__.py +0 -0
  98. {plain-0.68.0 → plain-0.69.0}/plain/preflight/checks.py +0 -0
  99. {plain-0.68.0 → plain-0.69.0}/plain/preflight/files.py +0 -0
  100. {plain-0.68.0 → plain-0.69.0}/plain/preflight/results.py +0 -0
  101. {plain-0.68.0 → plain-0.69.0}/plain/preflight/security.py +0 -0
  102. {plain-0.68.0 → plain-0.69.0}/plain/preflight/urls.py +0 -0
  103. {plain-0.68.0 → plain-0.69.0}/plain/runtime/README.md +0 -0
  104. {plain-0.68.0 → plain-0.69.0}/plain/runtime/__init__.py +0 -0
  105. {plain-0.68.0 → plain-0.69.0}/plain/runtime/global_settings.py +0 -0
  106. {plain-0.68.0 → plain-0.69.0}/plain/runtime/user_settings.py +0 -0
  107. {plain-0.68.0 → plain-0.69.0}/plain/runtime/utils.py +0 -0
  108. {plain-0.68.0 → plain-0.69.0}/plain/signals/README.md +0 -0
  109. {plain-0.68.0 → plain-0.69.0}/plain/signals/__init__.py +0 -0
  110. {plain-0.68.0 → plain-0.69.0}/plain/signals/dispatch/__init__.py +0 -0
  111. {plain-0.68.0 → plain-0.69.0}/plain/signals/dispatch/dispatcher.py +0 -0
  112. {plain-0.68.0 → plain-0.69.0}/plain/signals/dispatch/license.txt +0 -0
  113. {plain-0.68.0 → plain-0.69.0}/plain/signing.py +0 -0
  114. {plain-0.68.0 → plain-0.69.0}/plain/templates/AGENTS.md +0 -0
  115. {plain-0.68.0 → plain-0.69.0}/plain/templates/README.md +0 -0
  116. {plain-0.68.0 → plain-0.69.0}/plain/templates/__init__.py +0 -0
  117. {plain-0.68.0 → plain-0.69.0}/plain/templates/core.py +0 -0
  118. {plain-0.68.0 → plain-0.69.0}/plain/templates/jinja/__init__.py +0 -0
  119. {plain-0.68.0 → plain-0.69.0}/plain/templates/jinja/environments.py +0 -0
  120. {plain-0.68.0 → plain-0.69.0}/plain/templates/jinja/extensions.py +0 -0
  121. {plain-0.68.0 → plain-0.69.0}/plain/templates/jinja/filters.py +0 -0
  122. {plain-0.68.0 → plain-0.69.0}/plain/templates/jinja/globals.py +0 -0
  123. {plain-0.68.0 → plain-0.69.0}/plain/test/README.md +0 -0
  124. {plain-0.68.0 → plain-0.69.0}/plain/test/__init__.py +0 -0
  125. {plain-0.68.0 → plain-0.69.0}/plain/test/client.py +0 -0
  126. {plain-0.68.0 → plain-0.69.0}/plain/test/encoding.py +0 -0
  127. {plain-0.68.0 → plain-0.69.0}/plain/test/exceptions.py +0 -0
  128. {plain-0.68.0 → plain-0.69.0}/plain/urls/README.md +0 -0
  129. {plain-0.68.0 → plain-0.69.0}/plain/urls/__init__.py +0 -0
  130. {plain-0.68.0 → plain-0.69.0}/plain/urls/converters.py +0 -0
  131. {plain-0.68.0 → plain-0.69.0}/plain/urls/exceptions.py +0 -0
  132. {plain-0.68.0 → plain-0.69.0}/plain/urls/patterns.py +0 -0
  133. {plain-0.68.0 → plain-0.69.0}/plain/urls/resolvers.py +0 -0
  134. {plain-0.68.0 → plain-0.69.0}/plain/urls/routers.py +0 -0
  135. {plain-0.68.0 → plain-0.69.0}/plain/urls/utils.py +0 -0
  136. {plain-0.68.0 → plain-0.69.0}/plain/utils/README.md +0 -0
  137. {plain-0.68.0 → plain-0.69.0}/plain/utils/__init__.py +0 -0
  138. {plain-0.68.0 → plain-0.69.0}/plain/utils/cache.py +0 -0
  139. {plain-0.68.0 → plain-0.69.0}/plain/utils/crypto.py +0 -0
  140. {plain-0.68.0 → plain-0.69.0}/plain/utils/datastructures.py +0 -0
  141. {plain-0.68.0 → plain-0.69.0}/plain/utils/dateparse.py +0 -0
  142. {plain-0.68.0 → plain-0.69.0}/plain/utils/deconstruct.py +0 -0
  143. {plain-0.68.0 → plain-0.69.0}/plain/utils/decorators.py +0 -0
  144. {plain-0.68.0 → plain-0.69.0}/plain/utils/duration.py +0 -0
  145. {plain-0.68.0 → plain-0.69.0}/plain/utils/encoding.py +0 -0
  146. {plain-0.68.0 → plain-0.69.0}/plain/utils/functional.py +0 -0
  147. {plain-0.68.0 → plain-0.69.0}/plain/utils/hashable.py +0 -0
  148. {plain-0.68.0 → plain-0.69.0}/plain/utils/html.py +0 -0
  149. {plain-0.68.0 → plain-0.69.0}/plain/utils/http.py +0 -0
  150. {plain-0.68.0 → plain-0.69.0}/plain/utils/inspect.py +0 -0
  151. {plain-0.68.0 → plain-0.69.0}/plain/utils/ipv6.py +0 -0
  152. {plain-0.68.0 → plain-0.69.0}/plain/utils/itercompat.py +0 -0
  153. {plain-0.68.0 → plain-0.69.0}/plain/utils/module_loading.py +0 -0
  154. {plain-0.68.0 → plain-0.69.0}/plain/utils/regex_helper.py +0 -0
  155. {plain-0.68.0 → plain-0.69.0}/plain/utils/safestring.py +0 -0
  156. {plain-0.68.0 → plain-0.69.0}/plain/utils/text.py +0 -0
  157. {plain-0.68.0 → plain-0.69.0}/plain/utils/timesince.py +0 -0
  158. {plain-0.68.0 → plain-0.69.0}/plain/utils/timezone.py +0 -0
  159. {plain-0.68.0 → plain-0.69.0}/plain/utils/tree.py +0 -0
  160. {plain-0.68.0 → plain-0.69.0}/plain/validators.py +0 -0
  161. {plain-0.68.0 → plain-0.69.0}/plain/views/README.md +0 -0
  162. {plain-0.68.0 → plain-0.69.0}/plain/views/__init__.py +0 -0
  163. {plain-0.68.0 → plain-0.69.0}/plain/views/base.py +0 -0
  164. {plain-0.68.0 → plain-0.69.0}/plain/views/errors.py +0 -0
  165. {plain-0.68.0 → plain-0.69.0}/plain/views/exceptions.py +0 -0
  166. {plain-0.68.0 → plain-0.69.0}/plain/views/forms.py +0 -0
  167. {plain-0.68.0 → plain-0.69.0}/plain/views/redirect.py +0 -0
  168. {plain-0.68.0 → plain-0.69.0}/plain/views/templates.py +0 -0
  169. {plain-0.68.0 → plain-0.69.0}/plain/wsgi.py +0 -0
  170. {plain-0.68.0 → plain-0.69.0}/tests/.gitignore +0 -0
  171. {plain-0.68.0 → plain-0.69.0}/tests/app/.gitignore +0 -0
  172. {plain-0.68.0 → plain-0.69.0}/tests/app/settings.py +0 -0
  173. {plain-0.68.0 → plain-0.69.0}/tests/app/test/__init__.py +0 -0
  174. {plain-0.68.0 → plain-0.69.0}/tests/app/test/default_settings.py +0 -0
  175. {plain-0.68.0 → plain-0.69.0}/tests/app/urls.py +0 -0
  176. {plain-0.68.0 → plain-0.69.0}/tests/conftest.py +0 -0
  177. {plain-0.68.0 → plain-0.69.0}/tests/test_cli.py +0 -0
  178. {plain-0.68.0 → plain-0.69.0}/tests/test_csrf.py +0 -0
  179. {plain-0.68.0 → plain-0.69.0}/tests/test_http_hosts.py +0 -0
  180. {plain-0.68.0 → plain-0.69.0}/tests/test_logs.py +0 -0
  181. {plain-0.68.0 → plain-0.69.0}/tests/test_runtime.py +0 -0
  182. {plain-0.68.0 → plain-0.69.0}/tests/test_wsgi.py +0 -0
@@ -15,3 +15,4 @@ plain*/tests/.plain
15
15
  .plain
16
16
 
17
17
  .vscode
18
+ /.claude
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.68.0
3
+ Version: 0.69.0
4
4
  Summary: A web framework for building products with Python.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-File: LICENSE
@@ -1,5 +1,27 @@
1
1
  # plain changelog
2
2
 
3
+ ## [0.69.0](https://github.com/dropseed/plain/releases/plain@0.69.0) (2025-09-29)
4
+
5
+ ### What's changed
6
+
7
+ - Model-related exceptions (`FieldDoesNotExist`, `FieldError`, `ObjectDoesNotExist`, `MultipleObjectsReturned`, `EmptyResultSet`, `FullResultSet`) moved from `plain.exceptions` to `plain.models.exceptions` ([1c02564](https://github.com/dropseed/plain/commit/1c02564561))
8
+ - Added `plain dev` alias prompt that suggests adding `p` as a shell alias for convenience ([d913b44](https://github.com/dropseed/plain/commit/d913b44fab))
9
+
10
+ ### Upgrade instructions
11
+
12
+ - Replace imports of `FieldDoesNotExist`, `FieldError`, `ObjectDoesNotExist`, `MultipleObjectsReturned`, `EmptyResultSet`, or `FullResultSet` from `plain.exceptions` to `plain.models.exceptions`
13
+ - If you're using `ObjectDoesNotExist` in views, update your import from `plain.exceptions.ObjectDoesNotExist` to `plain.models.exceptions.ObjectDoesNotExist`
14
+
15
+ ## [0.68.1](https://github.com/dropseed/plain/releases/plain@0.68.1) (2025-09-25)
16
+
17
+ ### What's changed
18
+
19
+ - Preflight checks are now sorted by name for consistent ordering ([cb8e160](https://github.com/dropseed/plain/commit/cb8e160934))
20
+
21
+ ### Upgrade instructions
22
+
23
+ - No changes required
24
+
3
25
  ## [0.68.0](https://github.com/dropseed/plain/releases/plain@0.68.0) (2025-09-25)
4
26
 
5
27
  ### What's changed
@@ -11,7 +33,7 @@
11
33
 
12
34
  ### Upgrade instructions
13
35
 
14
- - Use `plain preflight check` instead of `plain preflight` to run all checks
36
+ - Update any uses of the `plain preflight` command to `plain preflight check`, and remove the `--database` and `--fail-level` options which no longer exist
15
37
  - Custom preflight checks should be class based, extending `PreflightCheck` and implementing the `run()` method
16
38
  - Preflight checks need to be registered with a custom name (ex. `@register_check("app.my_custom_check")`) and optionally with `deploy=True` if it should run in only in deploy mode
17
39
  - Preflight results should use `PreflightResult` (optionally with `warning=True`) instead of `preflight.Warning` or `preflight.Error`
@@ -6,7 +6,7 @@ import operator
6
6
 
7
7
  from plain.utils.hashable import make_hashable
8
8
 
9
- # MARK: Configuration and Registry
9
+ # MARK: Configuration and Package Registry
10
10
 
11
11
 
12
12
  class PackageRegistryNotReady(Exception):
@@ -21,33 +21,6 @@ class ImproperlyConfigured(Exception):
21
21
  pass
22
22
 
23
23
 
24
- # MARK: Model and Field Errors
25
-
26
-
27
- class FieldDoesNotExist(Exception):
28
- """The requested model field does not exist"""
29
-
30
- pass
31
-
32
-
33
- class FieldError(Exception):
34
- """Some kind of problem with a model field."""
35
-
36
- pass
37
-
38
-
39
- class ObjectDoesNotExist(Exception):
40
- """The requested object does not exist"""
41
-
42
- pass
43
-
44
-
45
- class MultipleObjectsReturned(Exception):
46
- """The query returned multiple objects when only one was expected."""
47
-
48
- pass
49
-
50
-
51
24
  # MARK: Security and Suspicious Operations
52
25
 
53
26
 
@@ -210,18 +183,3 @@ class ValidationError(Exception):
210
183
  if hasattr(self, "error_dict"):
211
184
  return hash(make_hashable(self.error_dict))
212
185
  return hash(tuple(sorted(self.error_list, key=operator.attrgetter("message"))))
213
-
214
-
215
- # MARK: Database
216
-
217
-
218
- class EmptyResultSet(Exception):
219
- """A database query predicate is impossible."""
220
-
221
- pass
222
-
223
-
224
- class FullResultSet(Exception):
225
- """A database query predicate is matches everything."""
226
-
227
- pass
@@ -28,7 +28,7 @@ class CheckRegistry:
28
28
  "Check for typos or remove outdated check names."
29
29
  )
30
30
 
31
- for name, (check_class, deploy) in self.checks.items():
31
+ for name, (check_class, deploy) in sorted(self.checks.items()):
32
32
  # Skip silenced checks
33
33
  if name in silenced_checks:
34
34
  continue
@@ -1,7 +1,13 @@
1
1
  from functools import cached_property
2
2
  from typing import Any
3
3
 
4
- from plain.exceptions import ImproperlyConfigured, ObjectDoesNotExist
4
+ from plain.exceptions import ImproperlyConfigured
5
+
6
+ try:
7
+ from plain.models.exceptions import ObjectDoesNotExist
8
+ except ImportError:
9
+ ObjectDoesNotExist = None
10
+
5
11
  from plain.forms import Form
6
12
  from plain.http import Http404
7
13
 
@@ -42,8 +48,12 @@ class ObjectTemplateViewMixin:
42
48
  def object(self) -> Any:
43
49
  try:
44
50
  obj = self.get_object()
45
- except ObjectDoesNotExist:
46
- raise Http404
51
+ except Exception as e:
52
+ # If ObjectDoesNotExist is available and this is that exception, raise 404
53
+ if ObjectDoesNotExist and isinstance(e, ObjectDoesNotExist):
54
+ raise Http404
55
+ # Otherwise, let other exceptions bubble up
56
+ raise
47
57
 
48
58
  # Also raise 404 if get_object() returns None
49
59
  if not obj:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain"
3
- version = "0.68.0"
3
+ version = "0.69.0"
4
4
  description = "A web framework for building products with Python."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes