primitive 0.1.74__tar.gz → 0.1.76__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 (106) hide show
  1. {primitive-0.1.74 → primitive-0.1.76}/Makefile +3 -12
  2. {primitive-0.1.74 → primitive-0.1.76}/PKG-INFO +4 -3
  3. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/__about__.py +1 -1
  4. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/agent/runner.py +9 -12
  5. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/agent/uploader.py +1 -1
  6. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/auth/commands.py +4 -3
  7. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/graphql/sdk.py +3 -1
  8. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/auth.py +23 -0
  9. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/files.py +1 -1
  10. {primitive-0.1.74 → primitive-0.1.76}/uv.lock +1 -3
  11. {primitive-0.1.74 → primitive-0.1.76}/.git-hooks/pre-commit +0 -0
  12. {primitive-0.1.74 → primitive-0.1.76}/.gitattributes +0 -0
  13. {primitive-0.1.74 → primitive-0.1.76}/.github/workflows/lint.yml +0 -0
  14. {primitive-0.1.74 → primitive-0.1.76}/.github/workflows/publish.yml +0 -0
  15. {primitive-0.1.74 → primitive-0.1.76}/.gitignore +0 -0
  16. {primitive-0.1.74 → primitive-0.1.76}/.vscode/settings.json +0 -0
  17. {primitive-0.1.74 → primitive-0.1.76}/LICENSE.txt +0 -0
  18. {primitive-0.1.74 → primitive-0.1.76}/README.md +0 -0
  19. {primitive-0.1.74 → primitive-0.1.76}/linux setup.md +0 -0
  20. {primitive-0.1.74 → primitive-0.1.76}/pyproject.toml +0 -0
  21. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/__init__.py +0 -0
  22. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/agent/__init__.py +0 -0
  23. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/agent/actions.py +0 -0
  24. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/agent/commands.py +0 -0
  25. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/agent/process.py +0 -0
  26. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/agent/provision.py +0 -0
  27. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/auth/__init__.py +0 -0
  28. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/auth/actions.py +0 -0
  29. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/auth/graphql/__init__.py +0 -0
  30. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/auth/graphql/queries.py +0 -0
  31. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/cli.py +0 -0
  32. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/client.py +0 -0
  33. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/daemons/__init__.py +0 -0
  34. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/daemons/actions.py +0 -0
  35. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/daemons/commands.py +0 -0
  36. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/daemons/launch_agents.py +0 -0
  37. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/daemons/launch_service.py +0 -0
  38. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/exec/__init__.py +0 -0
  39. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/exec/actions.py +0 -0
  40. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/exec/commands.py +0 -0
  41. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/exec/interactive.py +0 -0
  42. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/files/__init__.py +0 -0
  43. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/files/actions.py +0 -0
  44. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/files/commands.py +0 -0
  45. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/files/graphql/__init__.py +0 -0
  46. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/files/graphql/fragments.py +0 -0
  47. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/files/graphql/mutations.py +0 -0
  48. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/files/graphql/queries.py +0 -0
  49. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/git/__init__.py +0 -0
  50. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/git/actions.py +0 -0
  51. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/git/commands.py +0 -0
  52. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/git/graphql/__init__.py +0 -0
  53. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/git/graphql/queries.py +0 -0
  54. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/graphql/__init__.py +0 -0
  55. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/graphql/relay.py +0 -0
  56. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/graphql/utility_fragments.py +0 -0
  57. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/hardware/__init__.py +0 -0
  58. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/hardware/actions.py +0 -0
  59. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/hardware/commands.py +0 -0
  60. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/hardware/graphql/__init__.py +0 -0
  61. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/hardware/graphql/fragments.py +0 -0
  62. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/hardware/graphql/mutations.py +0 -0
  63. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/hardware/graphql/queries.py +0 -0
  64. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/jobs/__init__.py +0 -0
  65. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/jobs/actions.py +0 -0
  66. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/jobs/commands.py +0 -0
  67. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/jobs/graphql/__init__.py +0 -0
  68. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/jobs/graphql/fragments.py +0 -0
  69. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/jobs/graphql/mutations.py +0 -0
  70. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/jobs/graphql/queries.py +0 -0
  71. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/organizations/__init__.py +0 -0
  72. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/organizations/actions.py +0 -0
  73. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/organizations/commands.py +0 -0
  74. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/organizations/graphql/__init__.py +0 -0
  75. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/organizations/graphql/fragments.py +0 -0
  76. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/organizations/graphql/mutations.py +0 -0
  77. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/organizations/graphql/queries.py +0 -0
  78. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/projects/__init__.py +0 -0
  79. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/projects/actions.py +0 -0
  80. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/projects/commands.py +0 -0
  81. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/projects/graphql/__init__.py +0 -0
  82. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/projects/graphql/fragments.py +0 -0
  83. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/projects/graphql/mutations.py +0 -0
  84. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/projects/graphql/queries.py +0 -0
  85. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/provisioning/__init__.py +0 -0
  86. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/provisioning/actions.py +0 -0
  87. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/provisioning/graphql/__init__.py +0 -0
  88. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/provisioning/graphql/queries.py +0 -0
  89. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/reservations/__init__.py +0 -0
  90. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/reservations/actions.py +0 -0
  91. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/reservations/commands.py +0 -0
  92. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/reservations/graphql/__init__.py +0 -0
  93. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/reservations/graphql/fragments.py +0 -0
  94. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/reservations/graphql/mutations.py +0 -0
  95. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/reservations/graphql/queries.py +0 -0
  96. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/__init__.py +0 -0
  97. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/actions.py +0 -0
  98. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/cache.py +0 -0
  99. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/chunk_size.py +0 -0
  100. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/config.py +0 -0
  101. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/git.py +0 -0
  102. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/memory_size.py +0 -0
  103. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/printer.py +0 -0
  104. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/shell.py +0 -0
  105. {primitive-0.1.74 → primitive-0.1.76}/src/primitive/utils/verible.py +0 -0
  106. {primitive-0.1.74 → primitive-0.1.76}/tests/__init__.py +0 -0
@@ -8,32 +8,23 @@ SHELL := /opt/homebrew/bin/fish
8
8
  # .SHELLFLAGS += -e
9
9
  setup : ## Setup Environment
10
10
  @make setup-git-hooks
11
- uv venv
12
- source .venv/bin/activate.fish
13
11
  uv sync
14
- uv pip install -e .
15
12
 
16
13
  setup-ci: ## Setup the environment for CI
17
- uv venv
18
- source .venv/bin/activate.fish
19
14
  uv sync
20
- uv pip install -e .
21
15
 
22
16
  test: ## test
23
17
  @ENVIRONMENT=test python run pytest
24
18
 
25
19
  lint: ## Lint Python Files
26
- @source .venv/bin/activate.fish
27
- ruff check
20
+ uv run ruff check
28
21
  # pyright
29
22
 
30
23
  format: ## Format Python Files
31
- @source .venv/bin/activate.fish
32
- ruff format
33
- ruff check --fix
24
+ uv run ruff format
25
+ uv run ruff check --fix
34
26
 
35
27
  install: ## Install dependencies
36
- @source .venv/bin/activate.fish
37
28
  uv sync
38
29
 
39
30
  setup-git-hooks: ## Setup Git Hook
@@ -1,11 +1,12 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: primitive
3
- Version: 0.1.74
3
+ Version: 0.1.76
4
4
  Project-URL: Documentation, https://github.com//primitivecorp/primitive-cli#readme
5
5
  Project-URL: Issues, https://github.com//primitivecorp/primitive-cli/issues
6
6
  Project-URL: Source, https://github.com//primitivecorp/primitive-cli
7
7
  Author-email: Dylan Stein <dylan@primitive.tech>, Chase Zimmerman <chase@primitive.tech>
8
- License: MIT
8
+ License-Expression: MIT
9
+ License-File: LICENSE.txt
9
10
  Classifier: Development Status :: 4 - Beta
10
11
  Classifier: Programming Language :: Python
11
12
  Classifier: Programming Language :: Python :: 3
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2024-present Dylan Stein <dylan@primitive.tech>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "0.1.74"
4
+ __version__ = "0.1.76"
@@ -1,7 +1,6 @@
1
1
  import os
2
2
  import threading
3
3
  import typing
4
- import json
5
4
  from pathlib import Path, PurePath
6
5
  from time import sleep
7
6
  from typing import Dict, Iterable, List, Optional, TypedDict, Callable
@@ -109,18 +108,16 @@ class AgentRunner:
109
108
  if "step" in record["extra"]:
110
109
  step = record["extra"]["step"]
111
110
 
112
- log = {
113
- "time": record["time"].strftime("%Y-%m-%d %H:%M:%S.%f"),
114
- "utc": record["time"].strftime("%Y-%m-%d %H:%M:%S.%f%z"),
115
- "level": record["level"].name,
116
- "message": record["message"],
117
- "name": record["name"],
118
- "step": step,
119
- }
120
-
121
- record["extra"]["serialized"] = json.dumps(log)
111
+ log = (
112
+ "<green>{time:YYYY-MM-DD HH:mm:ss.SSS!UTC}</green> | "
113
+ "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
114
+ "<level>{level}</level> | "
115
+ f"{step} | "
116
+ "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
117
+ "<level>{message}</level>\n"
118
+ )
122
119
 
123
- return "{extra[serialized]}\n"
120
+ return log
124
121
 
125
122
  return fmt
126
123
 
@@ -47,7 +47,7 @@ class Uploader:
47
47
  for file in files:
48
48
  result = self.primitive.files.upload_file_direct(
49
49
  path=file,
50
- key_prefix=str(PurePath(file).relative_to(cache.parent).parent)
50
+ key_prefix=str(PurePath(file).relative_to(cache.parent).parent),
51
51
  )
52
52
  upload_id = result.data["fileUpdate"]["id"]
53
53
 
@@ -1,11 +1,12 @@
1
1
  import os
2
+ import typing
2
3
  import webbrowser
4
+
3
5
  import click
4
- from .actions import Auth
6
+
5
7
  from ..utils.config import PRIMITIVE_CREDENTIALS_FILEPATH
6
8
  from ..utils.printer import print_result
7
-
8
- import typing
9
+ from .actions import Auth
9
10
 
10
11
  if typing.TYPE_CHECKING:
11
12
  from ..client import Primitive
@@ -1,7 +1,9 @@
1
1
  from typing import Dict
2
+
3
+ import requests
2
4
  from gql import Client
3
5
  from gql.transport.aiohttp import AIOHTTPTransport
4
- import requests
6
+
5
7
  from primitive.__about__ import __version__
6
8
 
7
9
 
@@ -1,9 +1,23 @@
1
1
  import sys
2
2
 
3
+ import backoff
4
+ from aiohttp.client_exceptions import ClientConnectorError
5
+ from gql.transport.exceptions import TransportServerError
3
6
  from loguru import logger
4
7
 
5
8
  from ..graphql.sdk import create_session
6
9
 
10
+ MAX_TIME_FOR_BACKOFF = 60 * 15 # 15 minutes
11
+
12
+
13
+ def connection_backoff_handler(details):
14
+ logger.enable("primitive")
15
+ logger.error(
16
+ "Cannot connect to API. Waiting {wait:0.1f} seconds after {tries} tries.".format(
17
+ **details
18
+ )
19
+ )
20
+
7
21
 
8
22
  def create_new_session(primitive):
9
23
  token = primitive.host_config.get("token")
@@ -26,6 +40,15 @@ def create_new_session(primitive):
26
40
 
27
41
 
28
42
  def guard(func):
43
+ @backoff.on_exception(
44
+ backoff.expo,
45
+ (
46
+ ClientConnectorError,
47
+ TransportServerError,
48
+ ),
49
+ on_backoff=connection_backoff_handler,
50
+ max_time=MAX_TIME_FOR_BACKOFF,
51
+ )
29
52
  def wrapper(self, *args, **kwargs):
30
53
  if self.primitive.session is None:
31
54
  self.primitive.session = create_new_session(self.primitive)
@@ -19,7 +19,7 @@ def find_files_for_extension(source: Path, extensions: Tuple[str]) -> List[Path]
19
19
  for filename in filenames:
20
20
  if filename.endswith(extensions):
21
21
  matching_files.append(Path(dirpath).joinpath(filename))
22
-
22
+
23
23
  logger.debug(
24
24
  f"Found {len(matching_files)} following files that match: {matching_files}"
25
25
  )
@@ -319,7 +319,6 @@ wheels = [
319
319
  { url = "https://files.pythonhosted.org/packages/98/65/13d9e76ca19b0ba5603d71ac8424b5694415b348e719db277b5edc985ff5/cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", size = 3915420 },
320
320
  { url = "https://files.pythonhosted.org/packages/b1/07/40fe09ce96b91fc9276a9ad272832ead0fddedcba87f1190372af8e3039c/cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", size = 4154498 },
321
321
  { url = "https://files.pythonhosted.org/packages/75/ea/af65619c800ec0a7e4034207aec543acdf248d9bffba0533342d1bd435e1/cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", size = 3932569 },
322
- { url = "https://files.pythonhosted.org/packages/4e/d5/9cc182bf24c86f542129565976c21301d4ac397e74bf5a16e48241aab8a6/cryptography-44.0.0-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:60eb32934076fa07e4316b7b2742fa52cbb190b42c2df2863dbc4230a0a9b385", size = 4164756 },
323
322
  { url = "https://files.pythonhosted.org/packages/c7/af/d1deb0c04d59612e3d5e54203159e284d3e7a6921e565bb0eeb6269bdd8a/cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", size = 4016721 },
324
323
  { url = "https://files.pythonhosted.org/packages/bd/69/7ca326c55698d0688db867795134bdfac87136b80ef373aaa42b225d6dd5/cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", size = 4240915 },
325
324
  { url = "https://files.pythonhosted.org/packages/ef/d4/cae11bf68c0f981e0413906c6dd03ae7fa864347ed5fac40021df1ef467c/cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", size = 2757925 },
@@ -330,7 +329,6 @@ wheels = [
330
329
  { url = "https://files.pythonhosted.org/packages/d0/c7/c656eb08fd22255d21bc3129625ed9cd5ee305f33752ef2278711b3fa98b/cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", size = 3915417 },
331
330
  { url = "https://files.pythonhosted.org/packages/ef/82/72403624f197af0db6bac4e58153bc9ac0e6020e57234115db9596eee85d/cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", size = 4155160 },
332
331
  { url = "https://files.pythonhosted.org/packages/a2/cd/2f3c440913d4329ade49b146d74f2e9766422e1732613f57097fea61f344/cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", size = 3932331 },
333
- { url = "https://files.pythonhosted.org/packages/31/d9/90409720277f88eb3ab72f9a32bfa54acdd97e94225df699e7713e850bd4/cryptography-44.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9abcc2e083cbe8dde89124a47e5e53ec38751f0d7dfd36801008f316a127d7ba", size = 4165207 },
334
332
  { url = "https://files.pythonhosted.org/packages/7f/df/8be88797f0a1cca6e255189a57bb49237402b1880d6e8721690c5603ac23/cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", size = 4017372 },
335
333
  { url = "https://files.pythonhosted.org/packages/af/36/5ccc376f025a834e72b8e52e18746b927f34e4520487098e283a719c205e/cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", size = 4239657 },
336
334
  { url = "https://files.pythonhosted.org/packages/46/b0/f4f7d0d0bcfbc8dd6296c1449be326d04217c57afb8b2594f017eed95533/cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", size = 2758672 },
@@ -693,7 +691,7 @@ wheels = [
693
691
 
694
692
  [[package]]
695
693
  name = "primitive"
696
- version = "0.1.68"
694
+ version = "0.1.76"
697
695
  source = { editable = "." }
698
696
  dependencies = [
699
697
  { name = "click" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes