OpenSimula 0.5.1__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.
Files changed (44) hide show
  1. opensimula/Child.py +19 -0
  2. opensimula/Component.py +214 -0
  3. opensimula/Iterative_process.py +47 -0
  4. opensimula/Message.py +19 -0
  5. opensimula/Parameter_container.py +80 -0
  6. opensimula/Parameters.py +755 -0
  7. opensimula/Project.py +674 -0
  8. opensimula/Simulation.py +212 -0
  9. opensimula/Variable.py +37 -0
  10. opensimula/__init__.py +8 -0
  11. opensimula/components/Building.py +511 -0
  12. opensimula/components/Building_surface.py +318 -0
  13. opensimula/components/Calculator.py +51 -0
  14. opensimula/components/Construction.py +309 -0
  15. opensimula/components/Day_schedule.py +64 -0
  16. opensimula/components/File_data.py +117 -0
  17. opensimula/components/File_met.py +1035 -0
  18. opensimula/components/Frame.py +35 -0
  19. opensimula/components/Glazing.py +122 -0
  20. opensimula/components/HVAC_DX_equipment.py +210 -0
  21. opensimula/components/HVAC_DX_system.py +254 -0
  22. opensimula/components/HVAC_MZW_system.py +554 -0
  23. opensimula/components/HVAC_SZW_system.py +338 -0
  24. opensimula/components/HVAC_coil_equipment.py +206 -0
  25. opensimula/components/HVAC_fan_equipment.py +44 -0
  26. opensimula/components/HVAC_perfect_system.py +137 -0
  27. opensimula/components/Material.py +14 -0
  28. opensimula/components/Opening.py +409 -0
  29. opensimula/components/Opening_type.py +90 -0
  30. opensimula/components/Solar_surface.py +114 -0
  31. opensimula/components/Space.py +388 -0
  32. opensimula/components/Space_type.py +81 -0
  33. opensimula/components/Surface.py +129 -0
  34. opensimula/components/Test_component.py +76 -0
  35. opensimula/components/Week_schedule.py +30 -0
  36. opensimula/components/Year_schedule.py +65 -0
  37. opensimula/components/__init__.py +40 -0
  38. opensimula/visual_3D/Environment_3D.py +257 -0
  39. opensimula/visual_3D/Polygon_3D.py +262 -0
  40. opensimula-0.5.1.dist-info/METADATA +49 -0
  41. opensimula-0.5.1.dist-info/RECORD +44 -0
  42. opensimula-0.5.1.dist-info/WHEEL +5 -0
  43. opensimula-0.5.1.dist-info/licenses/LICENSE +21 -0
  44. opensimula-0.5.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,262 @@
1
+ import math
2
+ import numpy as np
3
+ from shapely.geometry import Polygon
4
+ import vedo
5
+ from triangle import triangulate
6
+
7
+ class Polygon_3D():
8
+ def __init__(self, name, origin, azimuth, altitude, polygon2D, holes2D=[], color="white", opacity=1.0, visible=True,shading=True,calculate_shadows=True):
9
+ self.name = name
10
+ self.origin = np.array(origin)
11
+ self.azimuth = azimuth
12
+ self.altitude = altitude
13
+ self.polygon2D = polygon2D
14
+ self.azimuth_rad = math.radians(self.azimuth)
15
+ self.altitude_rad = math.radians(self.altitude)
16
+ self.normal_vector = np.array((math.cos(self.altitude_rad)*math.sin(self.azimuth_rad),
17
+ -math.cos(self.altitude_rad) *
18
+ math.cos(self.azimuth_rad),
19
+ math.sin(self.altitude_rad)))
20
+ self.x_axis = np.array((math.cos(self.azimuth_rad),
21
+ math.sin(self.azimuth_rad),
22
+ 0))
23
+ self.y_axis = np.cross(self.normal_vector, self.x_axis)
24
+ self.polygon3D = self._convert_2D_to_3D_(self.polygon2D)
25
+ self.holes2D = holes2D
26
+ self.holes3D = []
27
+ for hole in self.holes2D:
28
+ self.holes3D.append(self._convert_2D_to_3D_(hole))
29
+ self.shapely_polygon = Polygon(self.polygon2D, self.holes2D)
30
+ self.area = self.shapely_polygon.area
31
+ # self.centroid2D = self.shapely_polygon.centroid.coords[0]
32
+ # self.centroid3D = self._convert_2D_to_3D_([self.centroid2D])[0]
33
+ self.equation_d = np.sum(self.normal_vector*self.origin)
34
+ self.color = color
35
+ self.opacity = opacity
36
+ self.visible = visible
37
+ self.shading = shading
38
+ self.calculate_shadows = calculate_shadows
39
+
40
+ def has_holes(self):
41
+ if (len(self.holes2D) > 0):
42
+ return True
43
+ else:
44
+ return False
45
+
46
+ def are_coplanar(self, polygon_3D):
47
+ if np.allclose(self.normal_vector, polygon_3D.normal_vector): # same normal verctor
48
+ if np.isclose(np.sum(self.normal_vector*polygon_3D.origin), self.equation_d): # in the plane
49
+ return True
50
+ else:
51
+ return False
52
+ else:
53
+ return False
54
+
55
+ def _convert_2D_to_3D_(self, pol_2D):
56
+ pol_3D = []
57
+ for vertex in pol_2D:
58
+ v_loc = np.array([self.origin[0] + vertex[0] * math.cos(self.azimuth_rad)
59
+ - vertex[1] * math.sin(self.altitude_rad) *
60
+ math.sin(self.azimuth_rad),
61
+ self.origin[1] + vertex[0] * math.sin(self.azimuth_rad)
62
+ + vertex[1] * math.sin(self.altitude_rad) *
63
+ math.cos(self.azimuth_rad),
64
+ self.origin[2] + vertex[1] * math.cos(self.altitude_rad)])
65
+ pol_3D.append(v_loc)
66
+ return pol_3D
67
+
68
+
69
+ # Functions for vedo
70
+ def get_vedo_mesh(self):
71
+ (points, faces) = self._triangulate_()
72
+ mesh = vedo.Mesh([points, faces])
73
+ mesh.c(self.color).alpha(self.opacity)
74
+ return mesh
75
+
76
+ def _triangulate_(self):
77
+ def edge_idxs(nv):
78
+ i = np.append(np.arange(nv), 0)
79
+ return np.stack([i[:-1], i[1:]], axis=1)
80
+
81
+ nv = 0
82
+ verts, edges = [], []
83
+ for loop in (self.polygon2D, *self.holes2D):
84
+ verts.append(loop)
85
+ edges.append(nv + edge_idxs(len(loop)))
86
+ nv += len(loop)
87
+
88
+ verts, edges = np.concatenate(verts), np.concatenate(edges)
89
+ # Triangulate needs to know a single interior point for each hole
90
+ holes = np.array([np.mean(h, axis=0) for h in self.holes2D])
91
+ # Because triangulate is a wrapper around a C library the syntax is a little weird, 'p' here means planar straight line graph
92
+ if self.has_holes():
93
+ d = triangulate(dict(vertices=verts, segments=edges, holes=holes), opts='p')
94
+ else:
95
+ d = triangulate(dict(vertices=verts, segments=edges), opts='p')
96
+ # Convert back
97
+ v, f = d['vertices'], d['triangles']
98
+ nv, nf = len(v), len(f)
99
+ points = np.concatenate([v, np.zeros((nv, 1))], axis=1)
100
+ # Creo que lo tengo que hacer en 2D y luego pasarlo a 3D
101
+ #faces = np.concatenate([np.full((nf, 1), 3), f], axis=1).reshape(-1)
102
+ return (self._convert_2D_to_3D_(points), f)
103
+
104
+ def _are_vertices_counterclockwise_(self,puntos):
105
+ # Se suma el primer punto al final para cerrar el polígono.
106
+ if puntos[-1][0] != puntos[0][0] or puntos[-1][1] != puntos[0][1]:
107
+ puntos_cerrados = np.vstack([puntos, puntos[0]])
108
+ else:
109
+ puntos_cerrados = puntos
110
+ x = puntos_cerrados[:, 0]
111
+ y = puntos_cerrados[:, 1]
112
+ # La suma de los productos cruzados
113
+ suma_productos_cruzados = np.sum(x[:-1] * y[1:] - x[1:] * y[:-1])
114
+ return suma_productos_cruzados > 0
115
+
116
+ # Shadow calculations
117
+ def is_facing_sun(self, sun_position):
118
+ escalar_p = np.sum(self.normal_vector*sun_position)
119
+ if escalar_p >= 1e-10:
120
+ return True
121
+ else:
122
+ return False
123
+
124
+ def _get_sunny_shadow_shapely_polygon_(self, environment_3D, sun_position):
125
+ if not self.is_facing_sun(sun_position):
126
+ sunny_polygon = None
127
+ shadow_polygon = self.shapely_polygon
128
+ else:
129
+ # Calculate projected shadows
130
+ shadows_2D = []
131
+ for shadow_polygon in environment_3D.pol_3D:
132
+ if shadow_polygon != self and shadow_polygon.shading == True:
133
+ if shadow_polygon.is_facing_sun(sun_position):
134
+ if not self.are_coplanar(shadow_polygon):
135
+ shadows_2D.append(self._calculate_shapely_projected_polygon_(shadow_polygon, sun_position))
136
+
137
+ # Calculate sunny polygon
138
+ sunny_polygon = self.shapely_polygon
139
+ for shadow_polygon in shadows_2D:
140
+ if shadow_polygon is not None:
141
+ sunny_polygon = sunny_polygon.difference(shadow_polygon)
142
+ if sunny_polygon.is_empty:
143
+ sunny_polygon = None
144
+ shadow_polygon = self.shapely_polygon
145
+ else:
146
+ shadow_polygon = self.shapely_polygon.difference(sunny_polygon)
147
+ if shadow_polygon.is_empty:
148
+ shadow_polygon = None
149
+ return sunny_polygon, shadow_polygon
150
+
151
+ def _calculate_shapely_projected_polygon_(self, polygon_to_project, sun_position):
152
+ exterior_points = self._get_projected_points_(polygon_to_project, sun_position)
153
+ if exterior_points is not None:
154
+ if polygon_to_project.has_holes():
155
+ holes = []
156
+ for hole in polygon_to_project.holes2D:
157
+ hole_points = self._get_projected_points_(
158
+ Polygon_3D("holes", polygon_to_project.origin, polygon_to_project.azimuth, polygon_to_project.altitude, hole), sun_position)
159
+ if hole_points is not None:
160
+ holes.append(hole_points)
161
+ return Polygon(exterior_points, holes)
162
+ else:
163
+ return Polygon(exterior_points)
164
+ else:
165
+ return None
166
+
167
+ def _get_projected_points_(self,polygon_to_project, sun_position):
168
+ projected_points = []
169
+ point_0 = polygon_to_project.polygon3D[-1]
170
+ projected_point_0 = self._get_projected_point_(point_0, sun_position)
171
+ for point_1 in polygon_to_project.polygon3D:
172
+ projected_point_1 = self._get_projected_point_(point_1, sun_position)
173
+ if len(projected_point_1) > 0 and len(projected_point_0) > 0:
174
+ projected_points.append(projected_point_1)
175
+ elif len(projected_point_1) > 0 and len(projected_point_0)==0:
176
+ intersection_point = self._get_intersection_with_plane_(point_0, point_1)
177
+ if len(intersection_point) > 0:
178
+ projected_intersection_point = self._get_projected_point_(intersection_point, sun_position)
179
+ projected_points.append(projected_intersection_point)
180
+ projected_points.append(projected_point_1)
181
+ elif len(projected_point_1) == 0 and len(projected_point_0) > 0:
182
+ intersection_point = self._get_intersection_with_plane_(point_0, point_1)
183
+ if len(intersection_point) > 0:
184
+ projected_intersection_point = self._get_projected_point_(intersection_point, sun_position)
185
+ projected_points.append(projected_intersection_point)
186
+ point_0 = np.array(point_1)
187
+ if len(projected_point_1) > 0:
188
+ projected_point_0 = np.array(projected_point_1)
189
+ else:
190
+ projected_point_0 = np.array([])
191
+ if len(projected_points) < 3:
192
+ return None
193
+ else:
194
+ return projected_points
195
+
196
+ def _get_projected_point_(self, point, sun_position):
197
+ d = np.sum(self.normal_vector*point)-self.equation_d
198
+ k = d/np.sum(self.normal_vector*sun_position)
199
+ if (k > -1e-6): # Por delante
200
+ projected_point_3D = point - k*sun_position
201
+ vector = projected_point_3D - self.origin
202
+ projected_point_2D = np.array([np.sum(self.x_axis*vector), np.sum(self.y_axis*vector)])
203
+ return projected_point_2D
204
+ else:
205
+ return np.array([])
206
+
207
+ def _get_intersection_with_plane_(self, point_0,point_1):
208
+ d0 = np.sum(self.normal_vector*point_0)-self.equation_d
209
+ d1 = np.sum(self.normal_vector*point_1)-self.equation_d
210
+ if (d0*d1 < -1e-10): # Si están en lados opuestos
211
+ t = d0/(d0-d1)
212
+ intersection_point = point_0 + t*(point_1-point_0)
213
+ return intersection_point
214
+ else:
215
+ return np.array([])
216
+
217
+ def get_sunny_shadow_polygon3D(self, environment_3D, sun_position):
218
+ sunny_polygons, shadow_polygons = self._get_sunny_shadow_shapely_polygon_(environment_3D, sun_position)
219
+ sunny_polygons_3D = self._shapely_multipolygon_to_polygons_3D_(sunny_polygons,"sunny")
220
+ shadow_polygons_3D = self._shapely_multipolygon_to_polygons_3D_(shadow_polygons,"shadow")
221
+ return sunny_polygons_3D, shadow_polygons_3D
222
+
223
+ # Para dibujarlos en 3D
224
+ def _shapely_multipolygon_to_polygons_3D_(self, shapely_polygon, type="sunny"):
225
+ polygon_list = []
226
+ if shapely_polygon is not None:
227
+ if shapely_polygon.geom_type == 'MultiPolygon':
228
+ polygons = list(shapely_polygon.geoms)
229
+ for pol in polygons:
230
+ polygon_list.append(self._shapely_to_polygon_3D_(pol,type))
231
+ elif shapely_polygon.geom_type == 'Polygon':
232
+ polygon_list.append(
233
+ self._shapely_to_polygon_3D_(shapely_polygon,type))
234
+ return polygon_list
235
+
236
+ def _shapely_to_polygon_3D_(self, shapely_pol, type="sunny"):
237
+ exterior_pol = np.asarray(shapely_pol.exterior.coords)
238
+ if not self._are_vertices_counterclockwise_(exterior_pol):
239
+ exterior_pol = exterior_pol[::-1]
240
+ if exterior_pol[-1][0] == exterior_pol[0][0] and exterior_pol[-1][1] == exterior_pol[0][1]:
241
+ exterior_pol = exterior_pol[:-1]
242
+ holes = []
243
+ for interior in shapely_pol.interiors:
244
+ interior_pol = np.asarray(interior.coords)
245
+ if not self._are_vertices_counterclockwise_(interior_pol):
246
+ interior_pol = interior_pol[::-1]
247
+ if interior_pol[-1][0] == interior_pol[0][0] and interior_pol[-1][1] == interior_pol[0][1]:
248
+ interior_pol = interior_pol[:-1]
249
+ holes.append(interior_pol)
250
+ if type=="sunny":
251
+ pol_3D = Polygon_3D(self.name+"_sunny",self.origin, self.azimuth, self.altitude, exterior_pol, holes,color=self.color,opacity=self.opacity)
252
+ else:
253
+ pol_3D = Polygon_3D(self.name+"_shadow",self.origin, self.azimuth, self.altitude, exterior_pol, holes, color="gray3")
254
+ return pol_3D
255
+
256
+ def get_angle_with_normal(self, sol_azimuth, sol_altitude):
257
+ azi_r = math.radians(sol_azimuth)
258
+ alt_r = math.radians(sol_altitude)
259
+ sol_vector = np.array([math.cos(alt_r)*math.cos(azi_r-math.pi/2),
260
+ math.cos(alt_r)*math.sin(azi_r-math.pi/2), math.sin(alt_r)])
261
+ return np.arccos(np.clip(np.dot(self.normal_vector, sol_vector), -1.0, 1.0))
262
+
@@ -0,0 +1,49 @@
1
+ Metadata-Version: 2.4
2
+ Name: opensimula
3
+ Version: 0.5.1
4
+ Summary: Component-based time simulation environment in Python
5
+ Author-email: "Juan F. Coronel" <jfc@us.es>
6
+ Requires-Python: >=3.12
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: dash>=3.2.0
10
+ Requires-Dist: dash-ag-grid>=32.3.2
11
+ Requires-Dist: dash-bootstrap-components>=2.0.4
12
+ Requires-Dist: nbformat>=5.10.4
13
+ Requires-Dist: numpy>=2.3.3
14
+ Requires-Dist: openpyxl>=3.1.5
15
+ Requires-Dist: pandas>=2.3.2
16
+ Requires-Dist: plotly>=6.3.0
17
+ Requires-Dist: psychrolib>=2.5.0
18
+ Requires-Dist: scipy>=1.16.2
19
+ Requires-Dist: shapely>=2.1.1
20
+ Requires-Dist: tqdm>=4.67.1
21
+ Requires-Dist: triangle>=20250106
22
+ Requires-Dist: vedo>=2025.5.4
23
+ Dynamic: license-file
24
+
25
+ ![Logo](https://jfcoronel.github.io/opensimula/img/logo_opensimula.png)
26
+ Component-based time simulation environment in Python
27
+
28
+ [Documentation page](https://jfcoronel.github.io/opensimula/)
29
+
30
+ ## Main Developers
31
+
32
+ * [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla
33
+
34
+ ## Package dependencies
35
+ - numpy
36
+ - pandas
37
+ - scipy
38
+ - shapely
39
+ - psychrolib
40
+ - plotly
41
+ - dash
42
+ - dash_bootstrap_components
43
+ - dash_ag_grid
44
+ - pyvista
45
+ - trame
46
+ - trame-vtk
47
+ - trame-vuetify
48
+ - ipywidgets
49
+
@@ -0,0 +1,44 @@
1
+ opensimula/Child.py,sha256=DEA6r-iIuH-cgV8mitnG3NyjSiIngOMmzf_JxwGRmGY,362
2
+ opensimula/Component.py,sha256=9IVfGsuO1eqTY1pAyvjr-GtPhvMmIxrqC1P7BTv6YHA,9299
3
+ opensimula/Iterative_process.py,sha256=nla1qrhi8zspGtXn-0181iAg4ksdzbrzsgpVnJfvzLk,1632
4
+ opensimula/Message.py,sha256=eUEK0ZGRaa64Eej7Khmm3bgQG9onXr-VV70Ql0y5cw4,439
5
+ opensimula/Parameter_container.py,sha256=G5lpMmbEo_LP7E3kfMyK14AnqAN_SzD5SarN3yxhV0s,2331
6
+ opensimula/Parameters.py,sha256=LwPAwDHszer5VNeY4rl7ur3yZaDpakvT4SqtPQN53dY,22793
7
+ opensimula/Project.py,sha256=OQFAEV_AD-cNmi-Icz6fxWOBQFH3eDCdw5gcPbwGLMc,25857
8
+ opensimula/Simulation.py,sha256=8abWXnPA95Ig0NnzQdInke0esdiXog6vNE7J2RyqfzQ,7849
9
+ opensimula/Variable.py,sha256=7r4XzxhJSsYSbpNFj_orX1a0d_LwJiagk5yQYE6RlWk,785
10
+ opensimula/__init__.py,sha256=NucwfvbCx6BbJJf2zRQYp8xZn98RJyn-aZvXKrKOBIQ,210
11
+ opensimula/components/Building.py,sha256=GsHCh31Uqt9g4C5NUFAfaztzf8zGu1tODuH6rxGVPSE,24507
12
+ opensimula/components/Building_surface.py,sha256=nlNNETh43ZuF8HzriLvRPM1Pes51w-Y0-15ZMxrw3V8,15701
13
+ opensimula/components/Calculator.py,sha256=BqSWDxsEk5AxfvKG9vEPcmyMLVzLsnoHsc2w8YHfOYk,2488
14
+ opensimula/components/Construction.py,sha256=k1lmMtyML5H5O4NBRcu1_Tgvd5P0ebg59gtvZ3nHLuI,10674
15
+ opensimula/components/Day_schedule.py,sha256=0YTmt4O6nKfHG_q_8Q2R_8xsTi0jYQHaycecpZEgIBM,2495
16
+ opensimula/components/File_data.py,sha256=7L1Kxc_z7Ywlcz2H5M_f94IqKKdoLJbrN3G0TIEbBdM,4798
17
+ opensimula/components/File_met.py,sha256=r3FySxCbPQOFKX410m7s8BOjMEn54xd7q8wrkkYWowM,52420
18
+ opensimula/components/Frame.py,sha256=Ju2_OBn5o97viZ-rCrZpZZClpwsdCZb4w58ym9fCIqY,1488
19
+ opensimula/components/Glazing.py,sha256=syaOCTuA-Qte1NAmNmcF9DI0Le-rHWA5-o2tbMHAdAE,5905
20
+ opensimula/components/HVAC_DX_equipment.py,sha256=74wysP0a39WrwNDo7x41BD5UmQXgiYVRib7KOAhy1OE,11272
21
+ opensimula/components/HVAC_DX_system.py,sha256=s9khWJG-O0tm5WBXLEAHxorMd_dSgfhXC53vFIWaBLM,13654
22
+ opensimula/components/HVAC_MZW_system.py,sha256=aUONkbR_UXHM7NAWYP2YBiIKp5BcBe_RmHfUdaZX0G0,25986
23
+ opensimula/components/HVAC_SZW_system.py,sha256=q99d1R5DpF4XOGYQVfYAVEbC4ENEUWRUALcvQ0tPIwc,19297
24
+ opensimula/components/HVAC_coil_equipment.py,sha256=eCxWWbEOaSh7IiuLkLbBdDmk47F8gY8JYbnzdN5qFWA,11561
25
+ opensimula/components/HVAC_fan_equipment.py,sha256=BRCwbx8VVAkZmXWa84iLZv3tNEzNSNOAI0RvuNDIqz8,1715
26
+ opensimula/components/HVAC_perfect_system.py,sha256=fNaeaSKmBeW2iQ_-FwHTkyUcicHe3q8o8TH8pXW9WWw,7431
27
+ opensimula/components/Material.py,sha256=SVDdHqPIGUYI3F5izSnLAw5pxxvBjt0uSG_Pp_iu1WY,768
28
+ opensimula/components/Opening.py,sha256=oUVXYXF54JND9hKmMI9xr88uBYFgSKBM0QbPMqnhtPQ,17256
29
+ opensimula/components/Opening_type.py,sha256=r_N0WyHX3HJx7K35H3V4YTgKM8b9RBSm1dOF1RrmIu0,3859
30
+ opensimula/components/Solar_surface.py,sha256=-sRPuTPch1GMwcVSmdZEK1eQ4xPDmrceYPYwRKdIJcc,5259
31
+ opensimula/components/Space.py,sha256=kNi9e-8LENGLG10aOih2-oDBf12OHeI74wdF7fMLFxM,18967
32
+ opensimula/components/Space_type.py,sha256=pMTmuCDFUZaW7ubpDEW37grMGdJL8MhKKQCFeFB9j_w,4216
33
+ opensimula/components/Surface.py,sha256=BOceDuL3BJiv6vK8RTa7fpJaORl_DuUQNQDgWSQKVpY,5611
34
+ opensimula/components/Test_component.py,sha256=j9REKz-0nKgIpfjfi9re57tYruCmPoN9VWWyLh72Kl0,3018
35
+ opensimula/components/Week_schedule.py,sha256=wBMt57u0BmpdxOZ2PCxMIoFNjjKbBCDFlgtfLOszrFA,1257
36
+ opensimula/components/Year_schedule.py,sha256=YZgXYL97IbHxI7GH2yZ2qZK97b2wXBwpTNQEejtNzhQ,2793
37
+ opensimula/components/__init__.py,sha256=_w0jRUsOWL2XGh8FJo1NLTHgAxm-3Ihi_g51UW6d0nw,1942
38
+ opensimula/visual_3D/Environment_3D.py,sha256=7XUGUnRm3hwnjy1FTyGOny3eL_jmCPAPlkpuQVONrGY,10303
39
+ opensimula/visual_3D/Polygon_3D.py,sha256=sZm5GERoZbq8e-1WMx-W4zs3lG_uQlNUYNk1UOZSFiE,12526
40
+ opensimula-0.5.1.dist-info/licenses/LICENSE,sha256=FXVlDFAOal91ai0_JYik1x4GGMFQEaIg00xBG42hqdM,1072
41
+ opensimula-0.5.1.dist-info/METADATA,sha256=G6_dg_gT5I7e3MuyOk5AKrZxpDVeTE_oRUpI392IbPo,1178
42
+ opensimula-0.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
43
+ opensimula-0.5.1.dist-info/top_level.txt,sha256=r48_O7VMDoHQWGuns6DMssWqOuyDdMQFBMbrX05g2Os,11
44
+ opensimula-0.5.1.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 Juan F. Coronel
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
+ opensimula