PyAres 0.1.4__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,208 @@
1
+ from ares_datamodel import ares_struct_pb2
2
+ from typing import Union, Dict
3
+
4
+ from . import ares_value_utils
5
+ import copy
6
+
7
+ def ares_struct_to_dict(ares_struct: ares_struct_pb2.AresStruct) -> Dict[str, any]:
8
+ """Converts an AresStruct protobuf message to a Python dictionary."""
9
+ return {k: ares_value_utils.ares_value_to_py(v) for k, v in ares_struct.fields.items()}
10
+
11
+ def ares_string_array_to_list(string_array: ares_struct_pb2.StringArray) -> list[str]:
12
+ """Convert an Ares String Array protobuf message to a Python list of strings."""
13
+ return [item for item in string_array.strings]
14
+
15
+ def ares_number_array_to_list(number_array: ares_struct_pb2.NumberArray) -> Union[list[int], list[float]]:
16
+ """Convert an Ares String Array protobuf message to a Python list of strings."""
17
+ return [item for item in number_array.numbers]
18
+
19
+ def dict_to_ares_struct(py_dict: dict, ares_struct: ares_struct_pb2.AresStruct):
20
+ """Converts a Python dictionary to an AresStruct protobuf message."""
21
+ for k, v in py_dict.items():
22
+ ares_value_utils.py_to_ares_value(v, ares_struct.fields[k])
23
+
24
+ def create_string_struct(key: str, value: str) -> ares_struct_pb2.AresStruct:
25
+ """
26
+ Creates a new AresStruct with a string initialized using the provided key and value.
27
+
28
+ Args:
29
+ key (str): The associated key to be used when storing the given value.
30
+ value (str): The string to be stored in the new AresStruct.
31
+
32
+ Returns:
33
+ (AresStruct): A new AresStruct containing the provided key and value.
34
+ """
35
+ new_struct = ares_struct_pb2.AresStruct()
36
+ new_struct.fields[key] = ares_value_utils.create_string(value)
37
+ return new_struct
38
+
39
+ def create_number_struct(key: str, value: Union[int, float]) -> ares_struct_pb2.AresStruct:
40
+ """
41
+ Creates a new AresStruct with the provided integer or float and key.
42
+
43
+ Args:
44
+ key (str): The associated key to be used when storing the given value.
45
+ value (Union[int, float]): The number to be stored in the new AresStruct.
46
+
47
+ Returns:
48
+ (AresStruct): A new AresStruct containing the provided key and value.
49
+ """
50
+ new_struct = ares_struct_pb2.AresStruct()
51
+ new_struct.fields[key] = ares_value_utils.create_number(value)
52
+ return new_struct
53
+
54
+ def create_bool_struct(key: str, value: bool) -> ares_struct_pb2.AresStruct:
55
+ """
56
+ Creates a new AresStruct with the provided bool and key.
57
+
58
+ Args:
59
+ key (str): The associated key to be used when storing the given value.
60
+ value (bool): The boolean to be stored in the new AresStruct.
61
+
62
+ Returns:
63
+ (AresStruct): A new AresStruct containing the provided key and value.
64
+ """
65
+
66
+ def create_null_struct(key: str) -> ares_struct_pb2.AresStruct:
67
+ """
68
+ Creates a new AresStruct with a null value initialized using the provided key.
69
+
70
+ Args:
71
+ key (str): The associated key to be used when storing the given value.
72
+
73
+ Returns:
74
+ (AresStruct): A new AresStruct containing the provided key and a null value.
75
+ """
76
+ new_struct = ares_struct_pb2.AresStruct()
77
+ new_struct.fields[key] = ares_value_utils.create_null()
78
+ return new_struct
79
+
80
+ def create_string_array_struct(key: str, value: list[str]) -> ares_struct_pb2.AresStruct:
81
+ """
82
+ Creates a new AresStruct with a string array initialized using the provided key and value.
83
+
84
+ Args:
85
+ key (str): The associated key to be used when storing the given value.
86
+ value (list[str]): The list of strings to be stored in the new AresStruct.
87
+
88
+ Returns:
89
+ (AresStruct): A new AresStruct containing the provided key and value
90
+ """
91
+ new_struct = ares_struct_pb2.AresStruct()
92
+ new_struct.fields[key] = ares_value_utils.create_string_array(value)
93
+ return new_struct
94
+
95
+ def create_number_array_struct(key: str, value: list[Union[int, float]]) -> ares_struct_pb2.AresStruct:
96
+ """
97
+ Creates a new AresStruct with a number array initialized using the provided key and value.
98
+
99
+ Args:
100
+ key (str): The associated key to be used when storing the given value.
101
+ value (Union[list[int], list[float]]): The list of integers or floats to be stored in the new AresStruct.
102
+
103
+ Returns:
104
+ (AresStruct): A new AresStruct containing the provided key and value
105
+ """
106
+ new_struct = ares_struct_pb2.AresStruct()
107
+ new_struct.fields[key] = ares_value_utils.create_number_array(value)
108
+ return new_struct
109
+
110
+ def create_bool_array_struct(key: str, value: list[bool]) -> ares_struct_pb2.AresStruct:
111
+ """
112
+ Creates a new AresStruct with a bool array initialized using the provided key and value.
113
+
114
+ Args:
115
+ key (str): The associated key to be used when storing the given value.
116
+ value (list[bool]): The list of bools to be stored in the new AresStruct.
117
+
118
+ Returns:
119
+ (AresStruct): A new AresStruct containing the provided key and value
120
+ """
121
+ new_struct = ares_struct_pb2.AresStruct()
122
+ new_struct.fields[key] = ares_value_utils.create_bool_array(value)
123
+ return new_struct
124
+
125
+ def create_bytes_array_struct(key: str, value: bytes) -> ares_struct_pb2.AresStruct:
126
+ """
127
+ Creates a new AresStruct with a byte array initialized using the provided key and value.
128
+
129
+ Args:
130
+ key (str): The associated key to be used when storing the given value.
131
+ value (bytes): The byte array to be stored in the new AresStruct.
132
+
133
+ Returns:
134
+ (AresStruct): A new AresStruct containing the provided key and value
135
+ """
136
+ new_struct = ares_struct_pb2.AresStruct()
137
+ new_struct.fields[key] = ares_value_utils.create_bytes(value)
138
+ return new_struct
139
+
140
+ def add_value_to_struct(existing_struct: ares_struct_pb2.AresStruct, key: str, new_value: ares_struct_pb2.AresValue, replace: bool = True) -> ares_struct_pb2.AresStruct:
141
+ """
142
+ Adds a provided value to an existing struct, with an optional bool value that determines whether any existing value should be overwritten
143
+
144
+ Args:
145
+ existing_struct (AresStruct): The AresStruct that the new value appended to.
146
+ key (str): The key to be associated with the new value.
147
+ new_value (ares_struct_pb2.AresValue): The AresValue that will be added to the provided struct.
148
+ replace (bool): An optional boolean value that determines whether to overwrite any existing values in your struct.
149
+
150
+ Returns:
151
+ (AresStruct): The provided struct with the new value appended.
152
+ """
153
+ if replace or key not in existing_struct.fields:
154
+ new_entry = existing_struct.fields[key]
155
+ new_entry.CopyFrom(new_value)
156
+
157
+ return existing_struct
158
+
159
+ def copy_struct(existing_struct: ares_struct_pb2.AresStruct) -> ares_struct_pb2.AresStruct:
160
+ """
161
+ Creates a deep copy of an existing AresStruct.
162
+
163
+ Args:
164
+ existing_struct (AresStruct): The struct you want the contents of copied.
165
+
166
+ Returns:
167
+ (AresStruct): A new struct with all the items copied over.
168
+ """
169
+ return copy.deepcopy(existing_struct)
170
+
171
+ def create_ares_struct(key: str, value: any):
172
+ """
173
+ Creates a new AresStruct using the provided key and value.
174
+
175
+ Args:
176
+ key (str): The key used to store the first AresValue created in this AresStruct.
177
+ value (any): The value to be associated with the provided key.
178
+
179
+ Returns:
180
+ (AresStruct): The newly created AresStruct.
181
+ """
182
+
183
+ if(isinstance(value, str)):
184
+ return create_string_struct(value)
185
+
186
+ elif(isinstance(value, (int, float))):
187
+ return create_number_struct(value)
188
+
189
+ elif(isinstance(value, bool)):
190
+ return create_bool_struct(value)
191
+
192
+ elif(isinstance(value, (list[int], list[float]))):
193
+ return create_number_array_struct(value)
194
+
195
+ elif(isinstance(value, bytes)):
196
+ return create_bytes_array_struct(value)
197
+
198
+ elif(isinstance(value, list[str])):
199
+ return create_string_array_struct(value)
200
+
201
+ elif(isinstance(value, list[bool])):
202
+ return create_bool_array_struct(value)
203
+
204
+ else:
205
+ return create_null_struct()
206
+
207
+
208
+
@@ -0,0 +1,214 @@
1
+ from ares_datamodel import ares_struct_pb2
2
+ from ares_datamodel import ares_data_type_pb2
3
+ from typing import Union
4
+
5
+ from . import ares_struct_utils
6
+ from . import ares_data_type_utils
7
+ from ..Models import AresDataType
8
+
9
+ def ares_value_to_py(ares_value: ares_struct_pb2.AresValue):
10
+ """Converts an AresValue protobuf message to a Python native type."""
11
+ type_map = {
12
+ "null_value": None,
13
+ "number_value": ares_value.number_value,
14
+ "string_value": ares_value.string_value,
15
+ "bool_value": ares_value.bool_value,
16
+ "string_array_value": ares_value.string_array_value.strings,
17
+ "number_array_value": ares_value.number_array_value.numbers,
18
+ "bytes_value": ares_value.bytes_value
19
+ }
20
+
21
+ field = ares_value.WhichOneof("kind")
22
+ if field in type_map:
23
+ return type_map[field]
24
+ return None
25
+
26
+ def py_to_ares_value(py_value, ares_value: ares_struct_pb2.AresValue):
27
+ """Sets the appropriate field in an AresValue protobuf message from a Python native type."""
28
+ if isinstance(py_value, str):
29
+ ares_value.string_value = py_value
30
+ elif isinstance(py_value, bool):
31
+ ares_value.bool_value = py_value
32
+ elif isinstance(py_value, (int, float)):
33
+ ares_value.number_value = py_value
34
+ elif isinstance(py_value, bytes):
35
+ ares_value.bytes_value = py_value
36
+ elif isinstance(py_value, dict):
37
+ ares_struct_utils.dict_to_ares_struct(py_value, ares_value.struct_value)
38
+ elif isinstance(py_value, list):
39
+ for item in py_value:
40
+ new_val = ares_value.list_value.values.add()
41
+ py_to_ares_value(item, new_val)
42
+ elif py_value is None:
43
+ ares_value.null_value = 0 # google.protobuf.NullValue.NULL_VALUE
44
+ else:
45
+ raise TypeError(f"Unsupported type for AresValue: {type(py_value)}")
46
+
47
+ def create_number(value: Union[int, float]) -> ares_struct_pb2.AresValue:
48
+ """
49
+ Creates a new AresValue, initialized to the provided number value.
50
+
51
+ Args:
52
+ value (Union[int, float]): The integer or float to be stored in the new AresValue.
53
+
54
+ Returns:
55
+ (AresValue): A new AresValue containing the provided number value.
56
+ """
57
+ return ares_struct_pb2.AresValue(number_value=value)
58
+
59
+ def create_string(value: str) -> ares_struct_pb2.AresValue:
60
+ """
61
+ Creates a new AresValue, initialized to the provided string value.
62
+
63
+ Args:
64
+ value (str): The string to be stored in the new AresValue.
65
+
66
+ Returns:
67
+ (AresValue): A new AresValue containing the provided string value.
68
+ """
69
+ return ares_struct_pb2.AresValue(string_value=value)
70
+
71
+ def create_number_array(value: list[Union[int, float]]) -> ares_struct_pb2.AresValue:
72
+ """
73
+ Creates a new AresValue, initialized to the provided list of numbers.
74
+
75
+ Args:
76
+ value (list[Union[int, float]]): The list of numbers to be stored in the new AresValue.
77
+
78
+ Returns:
79
+ (AresValue): A new AresValue containing the provided list of numbers.
80
+ """
81
+ num_array = ares_struct_pb2.NumberArray(numbers=value)
82
+ return ares_struct_pb2.AresValue(number_array_value=num_array)
83
+
84
+ def create_string_array(value: list[str]) -> ares_struct_pb2.AresValue:
85
+ """
86
+ Creates a new AresValue, initialized to the provided list of strings.
87
+
88
+ Args:
89
+ value (list[str]): The list of strings to be stored in the new AresValue.
90
+
91
+ Returns:
92
+ (AresValue): A new AresValue containing the provided list of strings.
93
+ """
94
+ str_array = ares_struct_pb2.StringArray(strings=value)
95
+ return ares_struct_pb2.AresValue(string_array_value=str_array)
96
+
97
+ def create_null() -> ares_struct_pb2.AresValue:
98
+ """
99
+ Creates a new AresValue, initialized to a null value.
100
+
101
+ Returns:
102
+ (AresValue): A new AresValue containing a null value.
103
+ """
104
+ return ares_struct_pb2.AresValue(null_value=ares_struct_pb2.NullValue.NULL_VALUE)
105
+
106
+ def create_bool(value: bool) -> ares_struct_pb2.AresValue:
107
+ """
108
+ Creates a new AresValue, initialized to the provided boolean value.
109
+
110
+ Args:
111
+ value (bool): The boolean to be stored in the new AresValue.
112
+
113
+ Returns:
114
+ (AresValue): A new AresValue containing the provided boolean value.
115
+ """
116
+ return ares_struct_pb2.AresValue(bool_value=value)
117
+
118
+ def create_bytes(value: bytes) -> ares_struct_pb2.AresValue:
119
+ """
120
+ Creates a new AresValue, initialized to the provided bytes value.
121
+
122
+ Args:
123
+ value (bytes): The bytes to be stored in the new AresValue.
124
+
125
+ Returns:
126
+ (AresValue): A new AresValue containing the provided bytes value.
127
+ """
128
+ return ares_struct_pb2.AresValue(bytes_value=value)
129
+
130
+ def create_bool_array(value: list[bool]) -> ares_struct_pb2.AresValue:
131
+ """
132
+ Creates a new AresValue, initialized to the provided list of booleans.
133
+
134
+ Args:
135
+ value (list[bool]): The list of booleans to be stored in the new AresValue.
136
+
137
+ Returns:
138
+ (AresValue): A new AresValue containing the provided list of booleans.
139
+ """
140
+ return ares_struct_pb2.AresValue(bool_array_value=value)
141
+
142
+ def create_default(python_datatype: AresDataType) -> ares_struct_pb2.AresValue:
143
+ """
144
+ Creates a new AresValue with a default value for the given AresDataType.
145
+
146
+ Args:
147
+ dataType (ares_data_type_pb2.AresDataType): The data type for which to create a default value.
148
+
149
+ Returns:
150
+ (AresValue): A new AresValue containing the default value.
151
+ """
152
+ dataType = ares_data_type_utils.python_ares_type_to_proto_ares_type(python_datatype)
153
+
154
+ if(dataType == ares_data_type_pb2.AresDataType.NULL):
155
+ return create_null()
156
+
157
+ elif(dataType == ares_data_type_pb2.AresDataType.NUMBER):
158
+ return create_number(0)
159
+
160
+ elif(dataType == ares_data_type_pb2.AresDataType.STRING):
161
+ return create_string("")
162
+
163
+ elif(dataType == ares_data_type_pb2.AresDataType.BOOLEAN):
164
+ return create_bool(False)
165
+
166
+ elif(dataType == ares_data_type_pb2.AresDataType.STRING_ARRAY):
167
+ return create_string_array([])
168
+
169
+ elif(dataType == ares_data_type_pb2.AresDataType.NUMBER_ARRAY):
170
+ return create_number_array([])
171
+
172
+ elif(dataType == ares_data_type_pb2.AresDataType.BOOL_ARRAY):
173
+ return create_bool_array([])
174
+
175
+ elif(dataType == ares_data_type_pb2.AresDataType.BYTE_ARRAY):
176
+ return create_bytes(bytes())
177
+ else:
178
+ return create_null()
179
+
180
+ def create_ares_value(value: any) -> ares_struct_pb2.AresValue:
181
+ """
182
+ Creates a new AresValue using the provided value.
183
+ If the provided value is not valid for use in an AresValue, a null AresValue is returned.
184
+
185
+ Args:
186
+ value (any): An any that is stored in the newly created AresValue.
187
+
188
+ Returns:
189
+ (AresValue): A new AresValue with the provided value stored.
190
+ """
191
+ if(isinstance(value, str)):
192
+ return create_string(value)
193
+
194
+ elif(isinstance(value, (int, float))):
195
+ return create_number(value)
196
+
197
+ elif(isinstance(value, bool)):
198
+ return create_bool(value)
199
+
200
+ elif(isinstance(value, bytes)):
201
+ return create_bool_array(value)
202
+
203
+ elif(isinstance(value, list)):
204
+ if all(isinstance(x, (int, float)) for x in value):
205
+ return create_number_array(value)
206
+
207
+ elif all(isinstance(x, str) for x in value):
208
+ return create_string_array(value)
209
+
210
+ elif all(isinstance(x, bool) for x in value):
211
+ return create_bool_array(value)
212
+
213
+ else:
214
+ return create_null()
PyAres/__init__.py ADDED
@@ -0,0 +1,14 @@
1
+ from .Planning import AresPlannerService
2
+ from .Planning import PlanResponse
3
+ from .Planning import PlanRequest
4
+ from .Planning import PlanningParameter
5
+ from .Planning import ParameterHistoryItem
6
+ from .Analyzing import AresAnalyzerService
7
+ from .Analyzing import Analysis
8
+ from .Analyzing import AnalysisRequest
9
+ from .Analyzing import InfoResponse
10
+ from .Device import AresDeviceService
11
+ from .Device import DeviceCommandDescriptor
12
+ from .Device import DeviceSchemaEntry
13
+ from .Models import AresDataType
14
+ from .Models import Outcome
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.4
2
+ Name: PyAres
3
+ Version: 0.1.4
4
+ Summary: The official Python library for ARES.
5
+ Author-email: AFRL <AFRL.RX.AREScontact@us.af.mil>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/AFRL-ARES
8
+ Requires-Python: >=3.10
9
+ License-File: LICENSE
10
+ Requires-Dist: grpcio-tools>=1.75.1
11
+ Requires-Dist: grpcio<2.0.0,>=1.71.0
12
+ Requires-Dist: ares-datamodel>=0.13.2b1
13
+ Dynamic: license-file
@@ -0,0 +1,27 @@
1
+ PyAres/__init__.py,sha256=fw1q1rsLkAPYP170xEwXfJ94tqhk4pqkVUR-7D21HpU,523
2
+ PyAres/Analyzing/__init__.py,sha256=nfsCl1WxhmPNoAl7GOOB8MgRuMo6n52HcA5XxHC4vRU,219
3
+ PyAres/Analyzing/analysis_service.py,sha256=TQLBJDogPOUG9_R2Y_bSYBOb8Kj2iUdytc8LPpl6BlA,12146
4
+ PyAres/Analyzing/analyzer_models.py,sha256=eux-iIIT-fxns92UZiGRaxr1eDhkbraFic-yug1Y7Sc,1783
5
+ PyAres/Device/__init__.py,sha256=NuPbt6feaM9tEwtlLC15gHwP4l91ARtHRkEetF-KD9s,141
6
+ PyAres/Device/device_models.py,sha256=9wk8AhZdMlOBHguAAfxI_1Bc8_mGJWNJeZCg-RDXe4Q,1949
7
+ PyAres/Device/device_service.py,sha256=U5cGcqtav89NPFlUXXb12lEkmBGlL43jWUnVWrapaDE,13082
8
+ PyAres/Device/device_warnings.py,sha256=R-oizQzC150ol_5s-jbMKRKQlo1OPE9OUCX9xUliqLY,51
9
+ PyAres/Models/__init__.py,sha256=-rue6Zb1wND953XI40Yt93TwMa9FwVijfXxw2939IFY,140
10
+ PyAres/Models/ares_data_models.py,sha256=r3bPpImSQEcQNRHILSVpH4a8ITbprvuHctKzuDcAmjk,696
11
+ PyAres/Planning/__init__.py,sha256=7OlkP6MFSOXaACjMHViUSLfT878Ukaz5OH4HHqAk0pc,248
12
+ PyAres/Planning/planner_models.py,sha256=9a9B79dp0BYg2KcVZAFMqXuZltQNc9GbMCaRtMwVJ_E,3622
13
+ PyAres/Planning/planning_service.py,sha256=zrmC7_041JF_EdZ9Bhj7bul7U4qwVF85o8u48f272ic,12620
14
+ PyAres/Test/analyzer_test.py,sha256=tVs3fiEKyAHvSfbA0HZ1nc1hoRehVoo-GyeIDqqJkmM,891
15
+ PyAres/Test/device_test.py,sha256=__9XAAfRLJPRhJOylSje1_Jm72CM8ldHRv216d4XgmQ,1941
16
+ PyAres/Test/planner_test.py,sha256=VM-WD6XKrGOJ9WCPoBakO8Vf19UVN2ASNwIDib2XCOk,2861
17
+ PyAres/Utils/ares_data_schema_utils.py,sha256=-ieU-w3iJnWV6O9ccNYio3lRq61_gfZdPHERhrb-iMo,1697
18
+ PyAres/Utils/ares_data_type_utils.py,sha256=fGGHHuGpXVZyB0dOConTey9TYeJcxkz3Low1jR5bxog,1505
19
+ PyAres/Utils/ares_device_command_utils.py,sha256=8a-vMJFSzvDl9gi60aOG7_mknSN8HmJU-tcGn4glDZc,2046
20
+ PyAres/Utils/ares_outcome_utils.py,sha256=1xrxg557iFDOM4gXekgpXGS4UmAdoTlpPkWPxjnwikU,512
21
+ PyAres/Utils/ares_struct_utils.py,sha256=QFQcuEhUHprNF482vTkkMyB76U-ivg7ofoeK6zRdL4k,7991
22
+ PyAres/Utils/ares_value_utils.py,sha256=g1oav-D1V3vcDcQ3G9rIsdmF9GwdzkXq6gJrW_-gDK4,7455
23
+ pyares-0.1.4.dist-info/licenses/LICENSE,sha256=AcN8QJ8RT55t8sjrZn-qC6NnM-_kxcm6Cv2ctvymVXQ,1066
24
+ pyares-0.1.4.dist-info/METADATA,sha256=p-lPdX4uUzzBQ3PHhS-h6OdOS98_8n12G70YsiJAjGI,405
25
+ pyares-0.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ pyares-0.1.4.dist-info/top_level.txt,sha256=wsglLR2yee2009OqgcP2efHcZvvpOq7iMlZVzU77k80,7
27
+ pyares-0.1.4.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 AFRL-ARES
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ PyAres