atomicshop 2.20.3__py3-none-any.whl → 2.20.5__py3-none-any.whl

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.

Potentially problematic release.


This version of atomicshop might be problematic. Click here for more details.

atomicshop/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  """Atomic Basic functions and classes to make developer life easier"""
2
2
 
3
3
  __author__ = "Den Kras"
4
- __version__ = '2.20.3'
4
+ __version__ = '2.20.5'
@@ -20,31 +20,31 @@ def main():
20
20
  install_nodejs_windows.install_nodejs_windows()
21
21
  install_nodejs_windows.add_nodejs_to_path()
22
22
  if not install_nodejs_windows.is_nodejs_installed():
23
- print_api("Node.js installation failed.")
23
+ print_api("Node.js installation failed.", color="red")
24
24
  return 1
25
25
 
26
- print_api("PIP Installing Robocorp.")
26
+ print_api("PIP Installing Robocorp.", color="blue")
27
27
  subprocess.check_call(["pip", "install", "--upgrade", "rpaframework"])
28
28
 
29
- print_api("PIP Installing Robocorp-Browser.")
29
+ print_api("PIP Installing Robocorp-Browser.", color="blue")
30
30
  subprocess.check_call(["pip", "install", "--upgrade", "robotframework-browser"])
31
31
 
32
- print_api("PIP Installing Robocorp-Recognition.")
32
+ print_api("PIP Installing Robocorp-Recognition.", color="blue")
33
33
  subprocess.check_call(["pip", "install", "--upgrade", "rpaframework-recognition"])
34
34
 
35
- print_api("PIP Installing pynput.")
35
+ print_api("PIP Installing pynput.", color="blue")
36
36
  subprocess.check_call(["pip", "install", "--upgrade", "pynput"])
37
37
 
38
- print_api("Installing Playwright browsers.")
38
+ print_api("Installing Playwright browsers.", color="blue")
39
39
  subprocess.check_call(["playwright", "install"])
40
40
 
41
- print_api("Initializing Robocorp Browser.")
41
+ print_api("Initializing Robocorp Browser.", color="blue")
42
42
  subprocess.check_call(["rfbrowser", "init"])
43
43
 
44
- print_api("Installing Additional modules.")
44
+ print_api("Installing Additional modules.", color="blue")
45
45
  subprocess.check_call(["pip", "install", "--upgrade", "matplotlib", "imagehash"])
46
46
 
47
- print_api("Installing Tesseract OCR.")
47
+ print_api("Installing Tesseract OCR.", color="blue")
48
48
  github_wrapper = githubw.GitHubWrapper(
49
49
  user_name="tesseract-ocr",
50
50
  repo_name="tesseract",
@@ -61,6 +61,22 @@ def main():
61
61
  # Add Tesseract to the PATH.
62
62
  subprocess.check_call(["setx", "PATH", f"%PATH%;{WINDOWS_TESSERACT_DEFAULT_INSTALLATION_DIRECTORY}"])
63
63
 
64
+ # Patch robocorp: Remove mouse to the center of the screen on control command.
65
+ # Import the library to find its path.
66
+ print_api("Patching: .\RPA\Windows\keywords\window.py", color="blue")
67
+ import RPA.Windows.keywords.window as window
68
+ window_file_path = window.__file__
69
+
70
+ # Patch the file.
71
+ with open(window_file_path, "r") as file:
72
+ file_content = file.read()
73
+ file_content = file_content.replace(
74
+ "window.item.MoveCursorToMyCenter(simulateMove=self.ctx.simulate_move)",
75
+ "# window.item.MoveCursorToMyCenter(simulateMove=self.ctx.simulate_move) # Patched to remove center placement during foreground window control."
76
+ )
77
+ with open(window_file_path, "w") as file:
78
+ file.write(file_content)
79
+
64
80
 
65
81
  if __name__ == '__main__':
66
82
  sys.exit(main())
@@ -99,8 +99,7 @@ class TCPServer:
99
99
  engines_usage: bool
100
100
  server_response_mode: bool
101
101
 
102
- listening_interface: str
103
- listening_port_list: list[int]
102
+ listening_address_list: list[str]
104
103
 
105
104
  forwarding_dns_service_ipv4_list___only_for_localhost: list[str]
106
105
 
@@ -268,7 +268,8 @@ def mitm_server(config_file_path: str, script_version: str):
268
268
 
269
269
  # === Initialize DNS module ====================================================================================
270
270
  if config_static.DNSServer.enable:
271
- dns_process = multiprocessing.Process(
271
+ # dns_process = multiprocessing.Process(
272
+ dns_process = threading.Thread(
272
273
  target=dns_server.start_dns_server_multiprocessing_worker,
273
274
  kwargs={
274
275
  'listening_interface': config_static.DNSServer.listening_interface,
@@ -313,10 +314,10 @@ def mitm_server(config_file_path: str, script_version: str):
313
314
  engines_domains: dict = dict()
314
315
  for engine in engines_list:
315
316
  engines_domains[engine.engine_name] = engine.domain_list
317
+
316
318
  try:
317
319
  socket_wrapper_instance = socket_wrapper.SocketWrapper(
318
- listening_interface=config_static.TCPServer.listening_interface,
319
- listening_port_list=config_static.TCPServer.listening_port_list,
320
+ listening_address_list=config_static.TCPServer.listening_address_list,
320
321
  ca_certificate_name=config_static.MainConfig.ca_certificate_name,
321
322
  ca_certificate_filepath=config_static.MainConfig.ca_certificate_filepath,
322
323
  ca_certificate_crt_filepath=config_static.MainConfig.ca_certificate_crt_filepath,
@@ -128,17 +128,27 @@ class GoogleLLM:
128
128
  def ask_gemini(
129
129
  question: str,
130
130
  temperature: float,
131
- max_output_tokens: int,
132
- model_name: str = 'gemini-pro'
131
+ # max_output_tokens: int,
132
+ model_name: str = 'gemini-2.0-flash-thinking-exp-01-21'
133
133
  ) -> str:
134
134
  """
135
135
  Function to ask the Gemini API a question and get the response.
136
136
  :param question: str, the question to ask the Gemini API.
137
137
  :param temperature: float, the temperature parameter for the LLM.
138
138
  While 0 is deterministic, higher values can lead to more creative responses.
139
- :param max_output_tokens: int, the maximum number of tokens to generate in the LLM response.
140
139
  :param model_name: str, the name of the model to use for the LLM.
141
140
 
141
+ max_output_tokens: int, the maximum number of tokens to generate in the LLM response.
142
+ UPDATE: Disabled this feature since it gave exceptions in some situations.
143
+ Example:
144
+ File ".\Lib\site-packages\google\generativeai\types\generation_types.py", line 464, in text
145
+ parts = self.parts
146
+ ^^^^^^^^^^
147
+ File ".\Lib\site-packages\google\generativeai\types\generation_types.py", line 447, in parts
148
+ raise ValueError(msg)
149
+ ValueError: Invalid operation: The `response.parts` quick accessor requires a single candidate, but but `response.candidates` is empty.
150
+
151
+
142
152
  :return: str, the response from the Gemini API.
143
153
  """
144
154
  # Model Configuration
@@ -146,7 +156,7 @@ class GoogleLLM:
146
156
  "temperature": temperature,
147
157
  "top_p": 0.99,
148
158
  "top_k": 0,
149
- "max_output_tokens": max_output_tokens,
159
+ # "max_output_tokens": max_output_tokens,
150
160
  }
151
161
 
152
162
  # model = genai.GenerativeModel('gemini-1.5-pro-latest',
@@ -245,7 +245,7 @@ def wrap_socket_with_ssl_context_client___default_certs___ignore_verification(
245
245
 
246
246
  :param socket_object: socket.socket object
247
247
  :param server_hostname: string, hostname of the server. Default is None.
248
- :param custom_pem_client_certificate_file_path: string, full file path for the client certificate PWM file.
248
+ :param custom_pem_client_certificate_file_path: string, full file path for the client certificate PEM file.
249
249
  Default is None.
250
250
  :param enable_sslkeylogfile_env_to_client_ssl_context: boolean, enables the SSLKEYLOGFILE environment variable
251
251
  to the SSL context. Default is False.
@@ -261,12 +261,12 @@ class SNIHandler:
261
261
  self.sni_received_parameters.destination_name = self.domain_from_dns_server
262
262
  message = \
263
263
  f"SNI Handler: No SNI was passed, using domain from DNS Server: {self.domain_from_dns_server}"
264
- print_api(message, **(print_kwargs or {}))
264
+ print_api(message, color="yellow", **(print_kwargs or {}))
265
265
  # If DNS server is disabled, the domain from dns server will be empty.
266
266
  else:
267
267
  message = f"SNI Handler: No SNI was passed, No domain passed from DNS Server. " \
268
268
  f"Service name will be 'None'."
269
- print_api(message, **(print_kwargs or {}))
269
+ print_api(message, color="yellow", **(print_kwargs or {}))
270
270
 
271
271
  # Setting "server_hostname" as a domain.
272
272
  self.sni_received_parameters.ssl_socket.server_hostname = self.sni_received_parameters.destination_name
@@ -32,8 +32,7 @@ SNI_QUEUE = queues.NonBlockQueue()
32
32
  class SocketWrapper:
33
33
  def __init__(
34
34
  self,
35
- listening_interface: str,
36
- listening_port_list: list[int],
35
+ listening_address_list: list[str],
37
36
  forwarding_dns_service_ipv4_list___only_for_localhost: list = None,
38
37
  ca_certificate_name: str = None,
39
38
  ca_certificate_filepath: str = None,
@@ -76,9 +75,8 @@ class SocketWrapper:
76
75
  Socket Wrapper class that will be used to create sockets, listen on them, accept connections and send them to
77
76
  new threads.
78
77
 
79
- :param listening_interface: string, interface that will be listened on.
80
- Example: '0.0.0.0'. For all interfaces.
81
- :param listening_port_list: list, of ports that will be listened on.
78
+ :param listening_address_list: list, of ips+ports that will be listened on.
79
+ Example: ['0.0.0.0:443', '0.0.0.0:80']
82
80
  :param ca_certificate_name: CA certificate name.
83
81
  :param ca_certificate_filepath: CA certificate file path with '.pem' extension.
84
82
  :param ca_certificate_crt_filepath: CA certificate file path with '.crt' extension.
@@ -177,8 +175,7 @@ class SocketWrapper:
177
175
  by the domain name from the list in the dictionary.
178
176
  """
179
177
 
180
- self.listening_interface: str = listening_interface
181
- self.listening_port_list: list[int] = listening_port_list
178
+ self.listening_address_list: list[str] = listening_address_list
182
179
  self.ca_certificate_name: str = ca_certificate_name
183
180
  self.ca_certificate_filepath: str = ca_certificate_filepath
184
181
  self.ca_certificate_crt_filepath: str = ca_certificate_crt_filepath
@@ -321,11 +318,7 @@ class SocketWrapper:
321
318
  print_api(message, color='red', logger=self.logger)
322
319
  return 1
323
320
 
324
- ips_ports: list[str] = list()
325
- for port in self.listening_port_list:
326
- ips_ports.append(f"{self.listening_interface}:{port}")
327
-
328
- port_in_use = networks.get_processes_using_port_list(ips_ports)
321
+ port_in_use = networks.get_processes_using_port_list(self.listening_address_list)
329
322
  if port_in_use:
330
323
  error_messages: list = list()
331
324
  for port, process_info in port_in_use.items():
@@ -409,9 +402,11 @@ class SocketWrapper:
409
402
  self.listening_sockets = list()
410
403
 
411
404
  # Creating a socket for each port in the list set in configuration file
412
- for port in self.listening_port_list:
405
+ for address in self.listening_address_list:
406
+ ip_address, port_str = address.split(':')
407
+ port = int(port_str)
413
408
  socket_by_port = self.create_socket_ipv4_tcp(
414
- self.listening_interface, port)
409
+ ip_address, port)
415
410
 
416
411
  self.listening_sockets.append(socket_by_port)
417
412
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.20.3
3
+ Version: 2.20.5
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=jrfooKEB2n1xq7etpsauLw74Y-KUQXdITvpLqaKbRYc,123
1
+ atomicshop/__init__.py,sha256=Z75FDLaS8vnUFWiQFrirKh_qZ8-SdtlTuquf4ca5CFU,123
2
2
  atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
3
3
  atomicshop/_create_pdf_demo.py,sha256=Yi-PGZuMg0RKvQmLqVeLIZYadqEZwUm-4A9JxBl_vYA,3713
4
4
  atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
@@ -58,7 +58,7 @@ atomicshop/a_installs/win/fibratus.py,sha256=TU4e9gdZ_zI73C40uueJ59pD3qmN-UFGdX5
58
58
  atomicshop/a_installs/win/mongodb.py,sha256=AqyItXu19aaoe49pppDxtEkXey6PMy0PoT2Y_RmPpPE,179
59
59
  atomicshop/a_installs/win/nodejs.py,sha256=U519Dyt4bsQPbEg_PwnZL5tsbfqDr1BbhxwoQFZsSKo,200
60
60
  atomicshop/a_installs/win/pycharm.py,sha256=j_RSd7aDOyC3yDd-_GUTMLlQTmDrqtVFG--oUfGLiZk,140
61
- atomicshop/a_installs/win/robocorp.py,sha256=ExdMR705fW4iyNDZnH9YZMrio4FYEwNH_8nEP1GWkjM,2383
61
+ atomicshop/a_installs/win/robocorp.py,sha256=Ob8X9Czwd-OR3pudFIFft1dcUjDM0Pw0X03yfPaf3yw,3280
62
62
  atomicshop/a_installs/win/wsl_ubuntu_lts.py,sha256=dZbPRLNKFeMd6MotjkE6UDY9cOiIaaclIdR1kGYWI50,139
63
63
  atomicshop/a_mains/dns_gateway_setting.py,sha256=ncc2rFQCChxlNP59UshwmTonLqC6MWblrVAzbbz-13M,149
64
64
  atomicshop/a_mains/github_wrapper.py,sha256=F-PoZknVCxWPN0PTO6l7ZNiaYvo7OVFKFI_zlPt56ps,169
@@ -133,13 +133,13 @@ atomicshop/file_io/tomls.py,sha256=vZ_Wng5alLf8z6HSEZj7PS0XKDA-Iies9ihVWOkTcKo,1
133
133
  atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
134
134
  atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,2104
135
135
  atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
- atomicshop/mitm/config_static.py,sha256=DjSnDtMU8srdqca8s6Q-oFCWgjjiCjXRhyk-nafRAUk,7788
136
+ atomicshop/mitm/config_static.py,sha256=6naOZiB5dlZ4YlsgXuWhpmst17Bh3WaZbnrtYmjtOV4,7761
137
137
  atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
138
138
  atomicshop/mitm/connection_thread_worker.py,sha256=tn71RotrQOTo6dyAakuLlY4HrM5ia_0FbNKLCY6Xahg,29304
139
139
  atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
140
140
  atomicshop/mitm/initialize_engines.py,sha256=rijND1jxt3Zs8P0jhcQZc0tgcWD4-nq8ARODiWzhurU,8278
141
141
  atomicshop/mitm/message.py,sha256=CDhhm4BTuZE7oNZCjvIZ4BuPOW4MuIzQLOg91hJaxDI,3065
142
- atomicshop/mitm/mitm_main.py,sha256=DhkdUhe-l6wtX7eUDoy8lsOFhIZkfgxQhEdcYuZd2cQ,25228
142
+ atomicshop/mitm/mitm_main.py,sha256=YR_pgNQ45kX9sB3gjPWh2_5OrfAj1fIC0TafneZLARI,25197
143
143
  atomicshop/mitm/recs_files.py,sha256=ZAAD0twun-FtmbSniXe3XQhIlawvANNB_HxwbHj7kwI,3151
144
144
  atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
145
145
  atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
@@ -186,7 +186,7 @@ atomicshop/startup/win/startup_folder.py,sha256=2RZEyF-Mf8eWPlt_-OaoGKKnMs6YhELE
186
186
  atomicshop/startup/win/task_scheduler.py,sha256=qALe-8sfthYxsdCViH2r8OsH3x-WauDqteg5RzElPdk,4348
187
187
  atomicshop/web_apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
188
  atomicshop/web_apis/google_custom_search.py,sha256=R1BnUmBFWZIWkfizSRWoSYoZTdPEjLJ28F_sS2g1jGQ,1558
189
- atomicshop/web_apis/google_llm.py,sha256=JcWkorK0Fu5C3SkZLSzI0TO4CwDscjFsWu1bDhfGYww,7056
189
+ atomicshop/web_apis/google_llm.py,sha256=bOE91hGSz4I2DJK0LZHMCSDDYSTgP6SF_FWVvpV5LcY,7691
190
190
  atomicshop/wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
191
191
  atomicshop/wrappers/_process_wrapper_curl.py,sha256=XkZZXYl7D0Q6UfdWqy-18AvpU0yVp9i2BVD2qRcXlkk,841
192
192
  atomicshop/wrappers/_process_wrapper_tar.py,sha256=WUMZFKNrlG4nJP9tWZ51W7BR1j_pIjsjgyAStmWjRGs,655
@@ -315,23 +315,23 @@ atomicshop/wrappers/socketw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
315
315
  atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-AtqXZevvaYigE,1732
316
316
  atomicshop/wrappers/socketw/base.py,sha256=EcosGkD8VzgBY3GeIHDSG29ThQfXwg3-GQPmBTAqTdw,3048
317
317
  atomicshop/wrappers/socketw/certificator.py,sha256=mtWPJ_ew3OSwt0-1W4jaoco1VIY4NRCrMv3mDUxb_Cc,12418
318
- atomicshop/wrappers/socketw/creator.py,sha256=aSwfN_IwXXf4Hob35vHXUxD_OPeshZcRDZU2hMyfKs0,13243
318
+ atomicshop/wrappers/socketw/creator.py,sha256=ePGjde04Jgq1gscTfiIam9u7nx3GfszUz1Oi1_5j5b0,13243
319
319
  atomicshop/wrappers/socketw/dns_server.py,sha256=QEHIQ1onGIOpwZ_nLXvGOgFCM5m-jSwh2HZ2eZC30cE,53337
320
320
  atomicshop/wrappers/socketw/exception_wrapper.py,sha256=B-X5SHLSUIWToihH2MKnOB1F4A81_X0DpLLfnYKYbEc,7067
321
321
  atomicshop/wrappers/socketw/get_process.py,sha256=aJC-_qFUv3NgWCSUzDI72E4z8_-VTZE9NVZ0CwUoNlM,5698
322
322
  atomicshop/wrappers/socketw/receiver.py,sha256=9B3MvcDqr4C3x2fsnjG5SQognd1wRqsBgikxZa0wXG8,8243
323
323
  atomicshop/wrappers/socketw/sender.py,sha256=aX_K8l_rHjd5AWb8bi5mt8-YTkMYVRDB6DnPqK_XDUE,4754
324
- atomicshop/wrappers/socketw/sni.py,sha256=T9PXROiTYYxrd_7X4Hoj9hoNPXXTQpa2HdvmBJJIoeA,17607
324
+ atomicshop/wrappers/socketw/sni.py,sha256=q-F-R1KtE94g8WGrR3QHgi-otXZJUPBprEwQqnY80_A,17639
325
325
  atomicshop/wrappers/socketw/socket_client.py,sha256=oa3GwS4OPgokrJE5_Oc4-5_wlXHxSH9J5f2DKebms8k,22035
326
326
  atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
327
- atomicshop/wrappers/socketw/socket_wrapper.py,sha256=i2-1asl25n_RAVvI0zJMw9VSlb3Mu0AD43VZZuJe7Bk,38740
327
+ atomicshop/wrappers/socketw/socket_wrapper.py,sha256=4apajkc4fR3V01_VvYtMH60Z7-mt19OeF_fyPj2ZKhs,38517
328
328
  atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
329
329
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=WcNyaqEZ82S5-f3kzqi1nllNT2Nd2P_zg8HqCc7vW4s,4120
330
330
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
331
331
  atomicshop/wrappers/winregw/winreg_installed_software.py,sha256=Qzmyktvob1qp6Tjk2DjLfAqr_yXV0sgWzdMW_9kwNjY,2345
332
332
  atomicshop/wrappers/winregw/winreg_network.py,sha256=AENV88H1qDidrcpyM9OwEZxX5svfi-Jb4N6FkS1xtqA,8851
333
- atomicshop-2.20.3.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
334
- atomicshop-2.20.3.dist-info/METADATA,sha256=EIraBjAqtxnXnhDD7G-mdiXYggN0Fn99egvpmtoPrC4,10630
335
- atomicshop-2.20.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
336
- atomicshop-2.20.3.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
337
- atomicshop-2.20.3.dist-info/RECORD,,
333
+ atomicshop-2.20.5.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
334
+ atomicshop-2.20.5.dist-info/METADATA,sha256=LQKANBfTO98nz4OnyWuo6nP4cOx18fSAt3J5PryHQTg,10630
335
+ atomicshop-2.20.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
336
+ atomicshop-2.20.5.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
337
+ atomicshop-2.20.5.dist-info/RECORD,,