ras-commander 0.71.0__py3-none-any.whl → 0.73.0__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.
@@ -0,0 +1,252 @@
1
+ """
2
+ RasMap - Parses HEC-RAS mapper configuration files (.rasmap)
3
+
4
+ This module provides functionality to extract and organize information from
5
+ HEC-RAS mapper configuration files, including paths to terrain, soil, and land cover data.
6
+
7
+ This module is part of the ras-commander library and uses a centralized logging configuration.
8
+
9
+ Logging Configuration:
10
+ - The logging is set up in the logging_config.py file.
11
+ - A @log_call decorator is available to automatically log function calls.
12
+ - Log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
13
+
14
+ Classes:
15
+ RasMap: Class for parsing and accessing HEC-RAS mapper configuration.
16
+ """
17
+
18
+ import os
19
+ import re
20
+ import xml.etree.ElementTree as ET
21
+ from pathlib import Path
22
+ import pandas as pd
23
+ from typing import Union, Optional, Dict, List, Any
24
+
25
+ from .RasPrj import ras
26
+ from .LoggingConfig import get_logger
27
+ from .Decorators import log_call
28
+
29
+ logger = get_logger(__name__)
30
+
31
+ class RasMap:
32
+ """
33
+ Class for parsing and accessing information from HEC-RAS mapper configuration files (.rasmap).
34
+
35
+ This class provides methods to extract paths to terrain, soil, land cover data,
36
+ and various project settings from the .rasmap file associated with a HEC-RAS project.
37
+ """
38
+
39
+ @staticmethod
40
+ @log_call
41
+ def parse_rasmap(rasmap_path: Union[str, Path], ras_object=None) -> pd.DataFrame:
42
+ """
43
+ Parse a .rasmap file and extract relevant information.
44
+
45
+ Args:
46
+ rasmap_path (Union[str, Path]): Path to the .rasmap file.
47
+ ras_object: Optional RAS object instance.
48
+
49
+ Returns:
50
+ pd.DataFrame: DataFrame containing extracted information from the .rasmap file.
51
+ """
52
+ ras_obj = ras_object or ras
53
+ ras_obj.check_initialized()
54
+
55
+ rasmap_path = Path(rasmap_path)
56
+ if not rasmap_path.exists():
57
+ logger.error(f"RASMapper file not found: {rasmap_path}")
58
+ # Create a single row DataFrame with all empty values
59
+ return pd.DataFrame({
60
+ 'projection_path': [None],
61
+ 'profile_lines_path': [[]],
62
+ 'soil_layer_path': [[]],
63
+ 'infiltration_hdf_path': [[]],
64
+ 'landcover_hdf_path': [[]],
65
+ 'terrain_hdf_path': [[]],
66
+ 'current_settings': [{}]
67
+ })
68
+
69
+ try:
70
+ # Initialize data for the DataFrame - just one row with lists
71
+ data = {
72
+ 'projection_path': [None],
73
+ 'profile_lines_path': [[]],
74
+ 'soil_layer_path': [[]],
75
+ 'infiltration_hdf_path': [[]],
76
+ 'landcover_hdf_path': [[]],
77
+ 'terrain_hdf_path': [[]],
78
+ 'current_settings': [{}]
79
+ }
80
+
81
+ # Read the file content
82
+ with open(rasmap_path, 'r', encoding='utf-8') as f:
83
+ xml_content = f.read()
84
+
85
+ # Check if it's a valid XML file
86
+ if not xml_content.strip().startswith('<'):
87
+ logger.error(f"File does not appear to be valid XML: {rasmap_path}")
88
+ return pd.DataFrame(data)
89
+
90
+ # Parse the XML file
91
+ try:
92
+ tree = ET.parse(rasmap_path)
93
+ root = tree.getroot()
94
+ except ET.ParseError as e:
95
+ logger.error(f"Error parsing XML in {rasmap_path}: {e}")
96
+ return pd.DataFrame(data)
97
+
98
+ # Helper function to convert relative paths to absolute paths
99
+ def to_absolute_path(relative_path: str) -> str:
100
+ if not relative_path:
101
+ return None
102
+ # Remove any leading .\ or ./
103
+ relative_path = relative_path.lstrip('.\\').lstrip('./')
104
+ # Convert to absolute path relative to project folder
105
+ return str(ras_obj.project_folder / relative_path)
106
+
107
+ # Extract projection path
108
+ try:
109
+ projection_elem = root.find(".//RASProjectionFilename")
110
+ if projection_elem is not None and 'Filename' in projection_elem.attrib:
111
+ data['projection_path'][0] = to_absolute_path(projection_elem.attrib['Filename'])
112
+ except Exception as e:
113
+ logger.warning(f"Error extracting projection path: {e}")
114
+
115
+ # Extract profile lines path
116
+ try:
117
+ profile_lines_elem = root.find(".//Features/Layer[@Name='Profile Lines']")
118
+ if profile_lines_elem is not None and 'Filename' in profile_lines_elem.attrib:
119
+ data['profile_lines_path'][0].append(to_absolute_path(profile_lines_elem.attrib['Filename']))
120
+ except Exception as e:
121
+ logger.warning(f"Error extracting profile lines path: {e}")
122
+
123
+ # Extract soil layer paths
124
+ try:
125
+ soil_layers = root.findall(".//Layer[@Name='Hydrologic Soil Groups']")
126
+ for layer in soil_layers:
127
+ if 'Filename' in layer.attrib:
128
+ data['soil_layer_path'][0].append(to_absolute_path(layer.attrib['Filename']))
129
+ except Exception as e:
130
+ logger.warning(f"Error extracting soil layer paths: {e}")
131
+
132
+ # Extract infiltration HDF paths
133
+ try:
134
+ infiltration_layers = root.findall(".//Layer[@Name='Infiltration']")
135
+ for layer in infiltration_layers:
136
+ if 'Filename' in layer.attrib:
137
+ data['infiltration_hdf_path'][0].append(to_absolute_path(layer.attrib['Filename']))
138
+ except Exception as e:
139
+ logger.warning(f"Error extracting infiltration HDF paths: {e}")
140
+
141
+ # Extract landcover HDF paths
142
+ try:
143
+ landcover_layers = root.findall(".//Layer[@Name='LandCover']")
144
+ for layer in landcover_layers:
145
+ if 'Filename' in layer.attrib:
146
+ data['landcover_hdf_path'][0].append(to_absolute_path(layer.attrib['Filename']))
147
+ except Exception as e:
148
+ logger.warning(f"Error extracting landcover HDF paths: {e}")
149
+
150
+ # Extract terrain HDF paths
151
+ try:
152
+ terrain_layers = root.findall(".//Terrains/Layer")
153
+ for layer in terrain_layers:
154
+ if 'Filename' in layer.attrib:
155
+ data['terrain_hdf_path'][0].append(to_absolute_path(layer.attrib['Filename']))
156
+ except Exception as e:
157
+ logger.warning(f"Error extracting terrain HDF paths: {e}")
158
+
159
+ # Extract current settings
160
+ current_settings = {}
161
+ try:
162
+ settings_elem = root.find(".//CurrentSettings")
163
+ if settings_elem is not None:
164
+ # Extract ProjectSettings
165
+ project_settings_elem = settings_elem.find("ProjectSettings")
166
+ if project_settings_elem is not None:
167
+ for child in project_settings_elem:
168
+ current_settings[child.tag] = child.text
169
+
170
+ # Extract Folders
171
+ folders_elem = settings_elem.find("Folders")
172
+ if folders_elem is not None:
173
+ for child in folders_elem:
174
+ current_settings[child.tag] = child.text
175
+
176
+ data['current_settings'][0] = current_settings
177
+ except Exception as e:
178
+ logger.warning(f"Error extracting current settings: {e}")
179
+
180
+ # Create DataFrame
181
+ df = pd.DataFrame(data)
182
+ logger.info(f"Successfully parsed RASMapper file: {rasmap_path}")
183
+ return df
184
+
185
+ except Exception as e:
186
+ logger.error(f"Unexpected error processing RASMapper file {rasmap_path}: {e}")
187
+ # Create a single row DataFrame with all empty values
188
+ return pd.DataFrame({
189
+ 'projection_path': [None],
190
+ 'profile_lines_path': [[]],
191
+ 'soil_layer_path': [[]],
192
+ 'infiltration_hdf_path': [[]],
193
+ 'landcover_hdf_path': [[]],
194
+ 'terrain_hdf_path': [[]],
195
+ 'current_settings': [{}]
196
+ })
197
+
198
+ @staticmethod
199
+ @log_call
200
+ def get_rasmap_path(ras_object=None) -> Optional[Path]:
201
+ """
202
+ Get the path to the .rasmap file based on the current project.
203
+
204
+ Args:
205
+ ras_object: Optional RAS object instance.
206
+
207
+ Returns:
208
+ Optional[Path]: Path to the .rasmap file if found, None otherwise.
209
+ """
210
+ ras_obj = ras_object or ras
211
+ ras_obj.check_initialized()
212
+
213
+ project_name = ras_obj.project_name
214
+ project_folder = ras_obj.project_folder
215
+ rasmap_path = project_folder / f"{project_name}.rasmap"
216
+
217
+ if not rasmap_path.exists():
218
+ logger.warning(f"RASMapper file not found: {rasmap_path}")
219
+ return None
220
+
221
+ return rasmap_path
222
+
223
+ @staticmethod
224
+ @log_call
225
+ def initialize_rasmap_df(ras_object=None) -> pd.DataFrame:
226
+ """
227
+ Initialize the rasmap_df as part of project initialization.
228
+
229
+ Args:
230
+ ras_object: Optional RAS object instance.
231
+
232
+ Returns:
233
+ pd.DataFrame: DataFrame containing information from the .rasmap file.
234
+ """
235
+ ras_obj = ras_object or ras
236
+ ras_obj.check_initialized()
237
+
238
+ rasmap_path = RasMap.get_rasmap_path(ras_obj)
239
+ if rasmap_path is None:
240
+ logger.warning("No .rasmap file found for this project. Creating empty rasmap_df.")
241
+ # Create a single row DataFrame with all empty values
242
+ return pd.DataFrame({
243
+ 'projection_path': [None],
244
+ 'profile_lines_path': [[]],
245
+ 'soil_layer_path': [[]],
246
+ 'infiltration_hdf_path': [[]],
247
+ 'landcover_hdf_path': [[]],
248
+ 'terrain_hdf_path': [[]],
249
+ 'current_settings': [{}]
250
+ })
251
+
252
+ return RasMap.parse_rasmap(rasmap_path, ras_obj)
ras_commander/RasPrj.py CHANGED
@@ -137,13 +137,14 @@ class RasPrj:
137
137
  2. Loading project data (plans, geometries, flows)
138
138
  3. Extracting boundary conditions
139
139
  4. Setting the initialization flag
140
+ 5. Loading RASMapper data (.rasmap)
140
141
  """
141
142
  self.suppress_logging = suppress_logging # Store suppress_logging state
142
143
  self.project_folder = Path(project_folder)
143
144
  self.prj_file = self.find_ras_prj(self.project_folder)
144
145
  if self.prj_file is None:
145
146
  logger.error(f"No HEC-RAS project file found in {self.project_folder}")
146
- raise ValueError(f"No HEC-RAS project file found in {self.project_folder}")
147
+ raise ValueError(f"No HEC-RAS project file found in {self.project_folder}. Please check the path and try again.")
147
148
  self.project_name = Path(self.prj_file).stem
148
149
  self.ras_exe_path = ras_exe_path
149
150
 
@@ -153,6 +154,22 @@ class RasPrj:
153
154
  # Now load the project data
154
155
  self._load_project_data()
155
156
  self.boundaries_df = self.get_boundary_conditions()
157
+
158
+ # Load RASMapper data if available
159
+ try:
160
+ # Import here to avoid circular imports
161
+ from .RasMap import RasMap
162
+ self.rasmap_df = RasMap.initialize_rasmap_df(self)
163
+ except ImportError:
164
+ logger.warning("RasMap module not available. RASMapper data will not be loaded.")
165
+ self.rasmap_df = pd.DataFrame(columns=['projection_path', 'profile_lines_path', 'soil_layer_path',
166
+ 'infiltration_hdf_path', 'landcover_hdf_path', 'terrain_hdf_path',
167
+ 'current_settings'])
168
+ except Exception as e:
169
+ logger.error(f"Error initializing RASMapper data: {e}")
170
+ self.rasmap_df = pd.DataFrame(columns=['projection_path', 'profile_lines_path', 'soil_layer_path',
171
+ 'infiltration_hdf_path', 'landcover_hdf_path', 'terrain_hdf_path',
172
+ 'current_settings'])
156
173
 
157
174
  if not suppress_logging:
158
175
  logger.info(f"Initialization complete for project: {self.project_name}")
@@ -160,6 +177,7 @@ class RasPrj:
160
177
  f"Unsteady entries: {len(self.unsteady_df)}, Geometry entries: {len(self.geom_df)}, "
161
178
  f"Boundary conditions: {len(self.boundaries_df)}")
162
179
  logger.info(f"Geometry HDF files found: {self.plan_df['Geom_File'].notna().sum()}")
180
+ logger.info(f"RASMapper data loaded: {not self.rasmap_df.empty}")
163
181
 
164
182
  @log_call
165
183
  def _load_project_data(self):
ras_commander/__init__.py CHANGED
@@ -10,7 +10,7 @@ try:
10
10
  __version__ = version("ras-commander")
11
11
  except PackageNotFoundError:
12
12
  # package is not installed
13
- __version__ = "0.71.0"
13
+ __version__ = "0.73.0"
14
14
 
15
15
  # Set up logging
16
16
  setup_logging()
@@ -23,6 +23,7 @@ from .RasUnsteady import RasUnsteady
23
23
  from .RasUtils import RasUtils
24
24
  from .RasExamples import RasExamples
25
25
  from .RasCmdr import RasCmdr
26
+ from .RasMap import RasMap
26
27
  from .HdfFluvialPluvial import HdfFluvialPluvial
27
28
 
28
29
  # HDF handling
@@ -49,7 +50,7 @@ __all__ = [
49
50
  # Core functionality
50
51
  'RasPrj', 'init_ras_project', 'get_ras_exe', 'ras',
51
52
  'RasPlan', 'RasGeo', 'RasUnsteady', 'RasUtils',
52
- 'RasExamples', 'RasCmdr', 'HdfFluvialPluvial',
53
+ 'RasExamples', 'RasCmdr', 'RasMap', 'HdfFluvialPluvial',
53
54
 
54
55
  # HDF handling
55
56
  'HdfBase', 'HdfBndry', 'HdfMesh', 'HdfPlan',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ras-commander
3
- Version: 0.71.0
3
+ Version: 0.73.0
4
4
  Summary: A Python library for automating HEC-RAS 6.x operations
5
5
  Home-page: https://github.com/gpt-cmdr/ras-commander
6
6
  Author: William M. Katzenmeyer, P.E., C.F.M.
@@ -59,7 +59,7 @@ This repository has several methods of interaction with Large Language Models an
59
59
  The RAS-Commander library Assistant is a full-featured interface for multi-turn conversations, using your own API keys and the ras-commander library for context. The library assistant allows you to load your own scripts and chat with specific examples and/or function classes in the RAS-Commander library to effectively utilize the library's functions in your workflow. To reduce hallucinations, a file browser is included which adds full files to the conversation to ensure grounded responses. A dashboard shows you the total context and estimated cost of each request. **Now with support for Claude 3.7, OpenAI's o1 and o3-mini, and Deepseek V3 and R1 models using US-based Together.ai, and available as a standalone windows executable that runs within the repository**
60
60
 
61
61
 
62
- 8. **[RAS Commander Library Assistant on ChatGPT](https://chatgpt.com/g/g-TZRPR3oAO-ras-commander-library-assistant)**: A specialized ChatGPT "GPT" with access to the ras-commander codebase and library, available for answering queries and providing code suggestions. You can even upload your own plan, unsteady and HDF files to inspect and help determine how to automate your workflows or visualize your results. _NOTE: GPT's are still quite limited by OpenAI's GPT frameworks and may not be useful for long conversations. Code interpreter cannot run HEC-RAS but can open and view smaller HDF files and projects for demonstration purposes_
62
+ 8. **[RAS Commander Library Assistant on ChatGPT](https://chatgpt.com/g/g-TZRPR3oAO-ras-commander-library-assistant)**: A specialized ChatGPT "GPT" with access to the ras-commander codebase and library, available for answering queries and providing code suggestions. You can even upload your own plan, unsteady and HDF files to inspect and help determine how to automate your workflows or visualize your results. _NOTE: GPT's are still quite limited by OpenAI's GPT frameworks and may not be useful for long conversations. Code interpreter cannot run HEC-RAS but can [open and view smaller HDF files and projects for demonstration purposes](https://chatgpt.com/share/67e7cdb7-49e0-8010-bbac-61d2c54d473f)_
63
63
 
64
64
 
65
65
  ## Background
@@ -85,6 +85,25 @@ HDF Data Access & Analysis
85
85
  - Pipe network and pump station analysis
86
86
  - Fluvial-pluvial boundary calculations
87
87
  - Infiltration and precipitation data handling
88
+ - Infiltration and soil data handling
89
+ - Land cover and terrain data integration
90
+ - Weighted parameter calculations for hydrologic modeling
91
+
92
+ RASMapper Data Integration
93
+ - RASMapper configuration parsing (.rasmap files)
94
+ - Terrain, soil, and land cover HDF paths
95
+ - Profile line paths
96
+
97
+ Manning's n Coefficient Management
98
+ - Base Manning's n table extraction and modification
99
+ - Regional overrides for spatially-varied roughness
100
+ - Direct editing of geometry file Manning values
101
+
102
+ Infiltration & Soil Analysis
103
+ - Soil statistics calculation and analysis
104
+ - Infiltration parameter management and scaling
105
+ - Weighted average parameter calculation
106
+ - Raster-based soil data processing
88
107
 
89
108
  RAS ASCII File Operations
90
109
  - Plan file creation and modification
@@ -266,6 +285,7 @@ This is useful for comparing different river systems, running scenario analyses
266
285
  - `RasGeo`: Handles operations related to geometry files
267
286
  - `RasUnsteady`: Manages unsteady flow file operations
268
287
  - `RasUtils`: Contains utility functions for file operations and data management
288
+ - `RasMap`: Parses and manages RASMapper configuration data
269
289
  - `RasExamples`: Manages and loads HEC-RAS example projects
270
290
 
271
291
  #### HDF Data Access Classes
@@ -280,7 +300,6 @@ This is useful for comparing different river systems, running scenario analyses
280
300
  - `HdfPipe`: Pipe network analysis tools
281
301
  - `HdfPump`: Pump station analysis capabilities
282
302
  - `HdfFluvialPluvial`: Fluvial-pluvial boundary analysis
283
- - `RasMapper`: RASMapper Functions
284
303
  - `HdfPlot` & `HdfResultsPlot`: Specialized plotting utilities
285
304
 
286
305
  ### Project Organization Diagram
@@ -2,13 +2,13 @@ ras_commander/Decorators.py,sha256=EOYi20fyV6JgArpHO3lQEVAU6LPHbpa3wGlmIYS40K0,1
2
2
  ras_commander/HdfBase.py,sha256=Jws6Y8JFkharuiM6Br5ivp6MS64X2fL6y87FOpe3FQw,14219
3
3
  ras_commander/HdfBndry.py,sha256=FBNFoTz4sXVB-MOsbHJBP8P0dMqJUfBROloKTaxmzCo,16377
4
4
  ras_commander/HdfFluvialPluvial.py,sha256=dlqoFX5i7uSA2BvuRNrV-Fg-z2JaeUxY86_fbZAdGqI,25933
5
- ras_commander/HdfInfiltration.py,sha256=SB8EsB-w1zrUHXqn3G8ihEahViTIZF7c7AyPHIrSrOU,15473
5
+ ras_commander/HdfInfiltration.py,sha256=HiifhbzgUs4kdtJkKfhxo1IsE-FBp5XspKkrJnnCDuc,66171
6
6
  ras_commander/HdfMesh.py,sha256=zI_4AqxDxb2_31G9RUmWibyld6KDMGhDpI3F8qwzVAw,19139
7
7
  ras_commander/HdfPipe.py,sha256=m-yvPL2GIP23NKt2tcwzOlS7khvgcDPGAshlTPMUAeI,32154
8
8
  ras_commander/HdfPlan.py,sha256=_KIWMoMpAftUp2wc2PQ9psl78IvW0disN0yKt7sNfqU,11807
9
9
  ras_commander/HdfPlot.py,sha256=7MNI5T9qIz-Ava1RdlnB6O9oJElE5BEB29QVF5Y2Xuc,3401
10
10
  ras_commander/HdfPump.py,sha256=Vc2ff16kRISR7jwtnaAqxI0p-gfBSuZKzR3rQbBLQoE,12951
11
- ras_commander/HdfResultsMesh.py,sha256=kjk5zXowgfscayiyKmSFdTDXa8-kPUI4SYKJ2okw3F0,31738
11
+ ras_commander/HdfResultsMesh.py,sha256=MKnSJxcWVDccHaRRGgAK0szm7B-VtrKBtgL1Uz0kAiw,44662
12
12
  ras_commander/HdfResultsPlan.py,sha256=L3IOdF6R3XiA7mbFAyLdczrZJQJogd8hhl7UYJWT5fY,16246
13
13
  ras_commander/HdfResultsPlot.py,sha256=ylzfT78CfgoDO0XAlRwlgMNRzvNQYBMn9eyXyBfjv_w,7660
14
14
  ras_commander/HdfResultsXsec.py,sha256=-P7nXnbjOLAeUnrdSC_lJQSfzrlWKmDF9Z5gEjmxbJY,13031
@@ -18,14 +18,15 @@ ras_commander/HdfXsec.py,sha256=flREnFFrIZu4SSKGRQeX9w3SS49q0UWPJnq4zO7DbUM,2734
18
18
  ras_commander/LoggingConfig.py,sha256=gWe5K5XTmMQpSczsTysAqpC9my24i_IyM8dvD85fxYg,2704
19
19
  ras_commander/RasCmdr.py,sha256=37GnchoQ0fIAkPnssnCr1mRUXY8gm-hIMTmuHZlnYP8,34591
20
20
  ras_commander/RasExamples.py,sha256=6IZ96LcAsk5LYFehdD0zDW5wyZWxQa6OQu2N9upxWXA,17536
21
- ras_commander/RasGeo.py,sha256=Fi1APh3G6Q1FmX3H3Pc-oL_TD3Q6T8HeqN1jl31V39I,17427
21
+ ras_commander/RasGeo.py,sha256=CQ1VjJ4uWWyXC9KsoVStbhlRf_5AiDm8yWvtDM3l4ac,21675
22
+ ras_commander/RasMap.py,sha256=4cVzaaQure-CXdXB1BY29iE20S00eldUqoL96PvJPbw,10635
22
23
  ras_commander/RasPlan.py,sha256=7cgwsKjD40ZSj9uOnsHd-OfmBJFxkS2xFhWmlHQflak,62179
23
- ras_commander/RasPrj.py,sha256=IFy5CAQdZAQtqAnKQUFUqsDx8WQtYGXiRTG9IErBUE8,56457
24
+ ras_commander/RasPrj.py,sha256=ivAHB3vexH6GQi-Aa4kqAabRwdthllMkTp8xphh5Ldc,57655
24
25
  ras_commander/RasUnsteady.py,sha256=TO08CT2GC4G5rcXO_Wbia2t4PhiWRu9-nC9F0IW7Gyo,37187
25
26
  ras_commander/RasUtils.py,sha256=0fm4IIs0LH1dgDj3pGd66mR82DhWLEkRKUvIo2M_5X0,35886
26
- ras_commander/__init__.py,sha256=KI_tROSOPwLR6JNKttQZHfvcTD0m-5zXAbd35c0Knrs,2001
27
- ras_commander-0.71.0.dist-info/licenses/LICENSE,sha256=_pbd6qHnlsz1iQ-ozDW_49r86BZT6CRwO2iBtw0iN6M,457
28
- ras_commander-0.71.0.dist-info/METADATA,sha256=nhua8P2v_aWC8BmNnLMC6PqHNSBNoHSu5CP_QiRxrHs,26588
29
- ras_commander-0.71.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
30
- ras_commander-0.71.0.dist-info/top_level.txt,sha256=i76S7eKLFC8doKcXDl3aiOr9RwT06G8adI6YuKbQDaA,14
31
- ras_commander-0.71.0.dist-info/RECORD,,
27
+ ras_commander/__init__.py,sha256=Tl8kx5SQQ8UocWSQ1tFzg4FGNb702k2yikfD6_hwXIw,2039
28
+ ras_commander-0.73.0.dist-info/licenses/LICENSE,sha256=_pbd6qHnlsz1iQ-ozDW_49r86BZT6CRwO2iBtw0iN6M,457
29
+ ras_commander-0.73.0.dist-info/METADATA,sha256=GiwhfJNCCL8ZH9XY1bpVa3huCeU84E1oOr7zIlrj4vs,27365
30
+ ras_commander-0.73.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
31
+ ras_commander-0.73.0.dist-info/top_level.txt,sha256=i76S7eKLFC8doKcXDl3aiOr9RwT06G8adI6YuKbQDaA,14
32
+ ras_commander-0.73.0.dist-info/RECORD,,