weeb-cli 2.14.0__tar.gz → 2.14.2__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 (114) hide show
  1. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/PKG-INFO +3 -3
  2. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/README.md +2 -2
  3. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/pyproject.toml +1 -1
  4. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/__init__.py +1 -1
  5. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/search/watch_flow.py +38 -24
  6. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli.egg-info/PKG-INFO +3 -3
  7. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/LICENSE +0 -0
  8. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/setup.cfg +0 -0
  9. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_anilist_tracker.py +0 -0
  10. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_aniworld_provider.py +0 -0
  11. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_api.py +0 -0
  12. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_cache.py +0 -0
  13. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_exceptions.py +0 -0
  14. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_kitsu_tracker.py +0 -0
  15. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_mal_tracker.py +0 -0
  16. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_providers.py +0 -0
  17. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_restful_api.py +0 -0
  18. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_sanitizer.py +0 -0
  19. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/tests/test_sanitizer_security.py +0 -0
  20. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/__main__.py +0 -0
  21. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/__init__.py +0 -0
  22. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/api.py +0 -0
  23. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/downloads.py +0 -0
  24. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/library.py +0 -0
  25. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/search/__init__.py +0 -0
  26. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/search/anime_details.py +0 -0
  27. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/search/download_flow.py +0 -0
  28. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/search/episode_utils.py +0 -0
  29. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/search/search_handlers.py +0 -0
  30. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/search/stream_utils.py +0 -0
  31. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/search.py +0 -0
  32. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/serve.py +0 -0
  33. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/serve_restful.py +0 -0
  34. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/__init__.py +0 -0
  35. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/settings_backup.py +0 -0
  36. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/settings_cache.py +0 -0
  37. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/settings_config.py +0 -0
  38. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/settings_download.py +0 -0
  39. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/settings_drives.py +0 -0
  40. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/settings_menu.py +0 -0
  41. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/settings_shortcuts.py +0 -0
  42. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings/settings_trackers.py +0 -0
  43. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/settings.py +0 -0
  44. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/setup.py +0 -0
  45. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/commands/watchlist.py +0 -0
  46. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/config.py +0 -0
  47. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/exceptions.py +0 -0
  48. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/i18n.py +0 -0
  49. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/locales/de.json +0 -0
  50. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/locales/en.json +0 -0
  51. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/locales/pl.json +0 -0
  52. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/locales/tr.json +0 -0
  53. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/main.py +0 -0
  54. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/__init__.py +0 -0
  55. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/base.py +0 -0
  56. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/de/__init__.py +0 -0
  57. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/de/aniworld.py +0 -0
  58. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/en/__init__.py +0 -0
  59. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/en/allanime.py +0 -0
  60. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/en/hianime.py +0 -0
  61. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/extractors/__init__.py +0 -0
  62. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/extractors/doodstream.py +0 -0
  63. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/extractors/filemoon.py +0 -0
  64. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/extractors/megacloud.py +0 -0
  65. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/extractors/streamtape.py +0 -0
  66. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/extractors/vidoza.py +0 -0
  67. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/extractors/voe.py +0 -0
  68. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/pl/__init__.py +0 -0
  69. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/pl/docchi.py +0 -0
  70. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/registry.py +0 -0
  71. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/tr/__init__.py +0 -0
  72. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/tr/animecix.py +0 -0
  73. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/tr/anizle.py +0 -0
  74. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/tr/turkanime.py +0 -0
  75. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/providers/tr/weeb.py +0 -0
  76. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/__init__.py +0 -0
  77. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/_base.py +0 -0
  78. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/_tracker_base.py +0 -0
  79. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/aniskip.py +0 -0
  80. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/cache.py +0 -0
  81. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/database.py +0 -0
  82. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/dependency_manager.py +0 -0
  83. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/details.py +0 -0
  84. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/discord_rpc.py +0 -0
  85. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/downloader.py +0 -0
  86. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/error_handler.py +0 -0
  87. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/headless_downloader.py +0 -0
  88. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/local_library.py +0 -0
  89. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/logger.py +0 -0
  90. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/notifier.py +0 -0
  91. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/player.py +0 -0
  92. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/progress.py +0 -0
  93. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/scraper.py +0 -0
  94. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/search.py +0 -0
  95. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/shortcuts.py +0 -0
  96. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/stream_validator.py +0 -0
  97. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/tracker.py +0 -0
  98. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/updater.py +0 -0
  99. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/services/watch.py +0 -0
  100. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/templates/anilist_error.html +0 -0
  101. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/templates/anilist_success.html +0 -0
  102. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/templates/mal_error.html +0 -0
  103. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/templates/mal_success.html +0 -0
  104. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/ui/__init__.py +0 -0
  105. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/ui/header.py +0 -0
  106. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/ui/menu.py +0 -0
  107. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/ui/prompt.py +0 -0
  108. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/utils/__init__.py +0 -0
  109. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli/utils/sanitizer.py +0 -0
  110. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli.egg-info/SOURCES.txt +0 -0
  111. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli.egg-info/dependency_links.txt +0 -0
  112. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli.egg-info/entry_points.txt +0 -0
  113. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli.egg-info/requires.txt +0 -0
  114. {weeb_cli-2.14.0 → weeb_cli-2.14.2}/weeb_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weeb-cli
3
- Version: 2.14.0
3
+ Version: 2.14.2
4
4
  Summary: No browser, no ads, no distractions. Just you and an unparalleled anime viewing experience.
5
5
  Author-email: ewgsta <ewgst@proton.me>
6
6
  License-Expression: GPL-3.0-only
@@ -55,7 +55,7 @@ Dynamic: license-file
55
55
  </p>
56
56
 
57
57
  <div align="center">
58
- <a href="README.md">English</a> | <a href="md/tr/README.md">Türkçe</a> | <a href="md/de/README.md">Deutsch</a> | <a href="md/pl/README.md">Polski</a>
58
+ <a href="README.md">English</a> | <a href="docs/md/tr/README.md">Türkçe</a> | <a href="docs/md/de/README.md">Deutsch</a> | <a href="docs/md/pl/README.md">Polski</a>
59
59
  </div>
60
60
  <br>
61
61
 
@@ -221,7 +221,7 @@ All available providers are loaded automatically. Select which provider to use v
221
221
 
222
222
  **Docker Support:**
223
223
  ```bash
224
- docker-compose -f docker-compose.restful.yml up -d
224
+ docker-compose -f docs/docker-compose.restful.yml up -d
225
225
  ```
226
226
 
227
227
  See [RESTful API Documentation](https://ewgsta.github.io/weeb-cli/cli/restful-api/) for full details.
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <div align="center">
12
- <a href="README.md">English</a> | <a href="md/tr/README.md">Türkçe</a> | <a href="md/de/README.md">Deutsch</a> | <a href="md/pl/README.md">Polski</a>
12
+ <a href="README.md">English</a> | <a href="docs/md/tr/README.md">Türkçe</a> | <a href="docs/md/de/README.md">Deutsch</a> | <a href="docs/md/pl/README.md">Polski</a>
13
13
  </div>
14
14
  <br>
15
15
 
@@ -175,7 +175,7 @@ All available providers are loaded automatically. Select which provider to use v
175
175
 
176
176
  **Docker Support:**
177
177
  ```bash
178
- docker-compose -f docker-compose.restful.yml up -d
178
+ docker-compose -f docs/docker-compose.restful.yml up -d
179
179
  ```
180
180
 
181
181
  See [RESTful API Documentation](https://ewgsta.github.io/weeb-cli/cli/restful-api/) for full details.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "weeb-cli"
7
- version = "2.14.0"
7
+ version = "2.14.2"
8
8
  description = "No browser, no ads, no distractions. Just you and an unparalleled anime viewing experience."
9
9
  readme = "README.md"
10
10
  authors = [{ name = "ewgsta", email = "ewgst@proton.me" }]
@@ -22,4 +22,4 @@ Attributes:
22
22
  __version__ (str): Current version of Weeb CLI.
23
23
  """
24
24
 
25
- __version__ = "2.14.0"
25
+ __version__ = "2.14.2"
@@ -8,6 +8,10 @@ from weeb_cli.services.player import player
8
8
  from weeb_cli.services.progress import progress_tracker
9
9
  from weeb_cli.services.scraper import scraper
10
10
  from weeb_cli.services.logger import error as log_error
11
+ from weeb_cli.services.stream_validator import stream_validator
12
+ from weeb_cli.config import config
13
+ from concurrent.futures import ThreadPoolExecutor
14
+ from weeb_cli.services.tracker import anilist_tracker, mal_tracker, kitsu_tracker
11
15
  from .episode_utils import get_episodes_safe, group_episodes_by_season, make_season_episode_id
12
16
  from .stream_utils import sort_streams, extract_streams_from_response
13
17
 
@@ -148,15 +152,7 @@ def _build_episode_choices(episodes, season, completed_ids, next_ep_num):
148
152
 
149
153
  return ep_choices
150
154
 
151
- def _play_episode(slug, selected_ep, details, season, episodes, completed_ids):
152
- ep_id = selected_ep.get("id")
153
- ep_num = selected_ep.get("number") or selected_ep.get("ep_num")
154
-
155
- if not ep_id:
156
- console.print(f"[red]{i18n.t('details.invalid_ep_id')}[/red]")
157
- time.sleep(1)
158
- return False
159
-
155
+ def _fetch_and_validate_streams(slug, ep_id):
160
156
  with console.status(i18n.t("common.processing"), spinner="dots"):
161
157
  stream_resp = get_streams(slug, ep_id)
162
158
 
@@ -168,24 +164,40 @@ def _play_episode(slug, selected_ep, details, season, episodes, completed_ids):
168
164
  error_msg += f" [{scraper.last_error}]"
169
165
  console.print(f"[red]{error_msg}[/red]")
170
166
  time.sleep(1.5)
171
- return False
167
+ return None
172
168
 
173
- from weeb_cli.services.stream_validator import stream_validator
174
- from weeb_cli.config import config
175
-
176
169
  valid_streams = []
177
170
  if config.get("scraping_source") == "docchi":
178
171
  valid_streams = streams_list
179
172
  else:
180
173
  console.print(f"[dim]{i18n.t('details.validating_streams')}...[/dim]")
181
- for stream in streams_list:
182
- is_valid, error = stream_validator.validate_url(stream.get("url"), timeout=3)
183
- if is_valid:
184
- valid_streams.append(stream)
174
+
175
+ def check_stream(stream):
176
+ is_valid, _ = stream_validator.validate_url(stream.get("url"), timeout=3)
177
+ return stream if is_valid else None
178
+
179
+ with ThreadPoolExecutor(max_workers=len(streams_list) if streams_list else 1) as executor:
180
+ results = executor.map(check_stream, streams_list)
181
+ valid_streams = [s for s in results if s is not None]
185
182
 
186
183
  if not valid_streams:
187
184
  console.print(f"[red]{i18n.t('details.no_valid_streams')}[/red]")
188
185
  time.sleep(1.5)
186
+ return None
187
+
188
+ return valid_streams
189
+
190
+ def _play_episode(slug, selected_ep, details, season, episodes, completed_ids):
191
+ ep_id = selected_ep.get("id")
192
+ ep_num = selected_ep.get("number") or selected_ep.get("ep_num")
193
+
194
+ if not ep_id:
195
+ console.print(f"[red]{i18n.t('details.invalid_ep_id')}[/red]")
196
+ time.sleep(1)
197
+ return False
198
+
199
+ valid_streams = _fetch_and_validate_streams(slug, ep_id)
200
+ if not valid_streams:
189
201
  return False
190
202
 
191
203
  streams_list = sort_streams(valid_streams)
@@ -222,7 +234,7 @@ def _play_episode(slug, selected_ep, details, season, episodes, completed_ids):
222
234
  title=details.get("title"),
223
235
  total_episodes=total_eps
224
236
  )
225
- _update_trackers(details, slug)
237
+ _update_trackers(details, slug, n)
226
238
  auto_watched["triggered"] = True
227
239
 
228
240
  play_success = player.play(
@@ -278,7 +290,7 @@ def _mark_episode_watched(slug, details, ep_num, season, episodes, completed_ids
278
290
  )
279
291
  console.print(f"[green]✓ {i18n.t('details.marked_watched')}[/green]")
280
292
 
281
- _update_trackers(details, slug)
293
+ _update_trackers(details, slug, n)
282
294
 
283
295
  completed_ids.add(season_ep_id)
284
296
  return True
@@ -286,12 +298,14 @@ def _mark_episode_watched(slug, details, ep_num, season, episodes, completed_ids
286
298
  log_error(f"Failed to mark episode as watched: {e}")
287
299
  return False
288
300
 
289
- def _update_trackers(details, slug):
290
- from weeb_cli.services.tracker import anilist_tracker, mal_tracker, kitsu_tracker
291
- from concurrent.futures import ThreadPoolExecutor
292
-
301
+ def _update_trackers(details, slug, ep_num=None):
293
302
  updated_prog = progress_tracker.get_anime_progress(slug)
294
- total_watched = len(updated_prog.get("completed", []))
303
+
304
+ if ep_num is not None:
305
+ total_watched = int(ep_num)
306
+ else:
307
+ total_watched = len(updated_prog.get("completed", []))
308
+
295
309
  total_eps = details.get("total_episodes", 0)
296
310
 
297
311
  trackers = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weeb-cli
3
- Version: 2.14.0
3
+ Version: 2.14.2
4
4
  Summary: No browser, no ads, no distractions. Just you and an unparalleled anime viewing experience.
5
5
  Author-email: ewgsta <ewgst@proton.me>
6
6
  License-Expression: GPL-3.0-only
@@ -55,7 +55,7 @@ Dynamic: license-file
55
55
  </p>
56
56
 
57
57
  <div align="center">
58
- <a href="README.md">English</a> | <a href="md/tr/README.md">Türkçe</a> | <a href="md/de/README.md">Deutsch</a> | <a href="md/pl/README.md">Polski</a>
58
+ <a href="README.md">English</a> | <a href="docs/md/tr/README.md">Türkçe</a> | <a href="docs/md/de/README.md">Deutsch</a> | <a href="docs/md/pl/README.md">Polski</a>
59
59
  </div>
60
60
  <br>
61
61
 
@@ -221,7 +221,7 @@ All available providers are loaded automatically. Select which provider to use v
221
221
 
222
222
  **Docker Support:**
223
223
  ```bash
224
- docker-compose -f docker-compose.restful.yml up -d
224
+ docker-compose -f docs/docker-compose.restful.yml up -d
225
225
  ```
226
226
 
227
227
  See [RESTful API Documentation](https://ewgsta.github.io/weeb-cli/cli/restful-api/) for full details.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes