salabim 24.0.11.post1__py3-none-any.whl → 24.0.13__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- salabim/salabim.py +277 -47
- {salabim-24.0.11.post1.dist-info → salabim-24.0.13.dist-info}/METADATA +1 -1
- salabim-24.0.13.dist-info/RECORD +10 -0
- {salabim-24.0.11.post1.dist-info → salabim-24.0.13.dist-info}/WHEEL +1 -1
- salabim-24.0.11.post1.dist-info/RECORD +0 -10
- {salabim-24.0.11.post1.dist-info → salabim-24.0.13.dist-info}/top_level.txt +0 -0
salabim/salabim.py
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
# _ _ _ ____ _ _ ___ _
|
2
|
-
# ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | || | / _ \ /
|
3
|
-
# / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) || || |_ | | | | |
|
4
|
-
# \__ \| (_| || || (_| || |_) || || | | | | | / __/ |__ _| _ | |_| | _ |
|
5
|
-
# |___/ \__,_||_| \__,_||_.__/ |_||_| |_| |_| |_____| |_| (_) \___/ (_)|_||
|
1
|
+
# _ _ _ ____ _ _ ___ _ _____
|
2
|
+
# ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | || | / _ \ / ||___ /
|
3
|
+
# / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) || || |_ | | | | | | |_ \
|
4
|
+
# \__ \| (_| || || (_| || |_) || || | | | | | / __/ |__ _| _ | |_| | _ | | ___) |
|
5
|
+
# |___/ \__,_||_| \__,_||_.__/ |_||_| |_| |_| |_____| |_| (_) \___/ (_)|_||____/
|
6
6
|
# discrete event simulation
|
7
7
|
#
|
8
8
|
# see www.salabim.org for more information, the documentation and license information
|
9
9
|
|
10
|
-
__version__ = "24.0.
|
10
|
+
__version__ = "24.0.13"
|
11
11
|
|
12
12
|
import heapq
|
13
13
|
import random
|
@@ -60,7 +60,7 @@ PyDroid = sys.platform == "linux" and any("pydroid" in v for v in os.environ.val
|
|
60
60
|
PyPy = platform.python_implementation() == "PyPy"
|
61
61
|
Chromebook = "penguin" in platform.uname()
|
62
62
|
PythonInExcel = not ("__file__" in globals())
|
63
|
-
AnacondaCode = sys.platform=="emscripten"
|
63
|
+
AnacondaCode = sys.platform == "emscripten"
|
64
64
|
|
65
65
|
|
66
66
|
def a_log(*args):
|
@@ -154,8 +154,9 @@ nan = float("nan")
|
|
154
154
|
if Pythonista or AnacondaCode or PythonInExcel:
|
155
155
|
_yieldless = False
|
156
156
|
else:
|
157
|
-
_yieldless=True
|
158
|
-
|
157
|
+
_yieldless = True
|
158
|
+
|
159
|
+
|
159
160
|
class QueueFullError(Exception):
|
160
161
|
pass
|
161
162
|
|
@@ -4144,7 +4145,7 @@ if Pythonista:
|
|
4144
4145
|
try:
|
4145
4146
|
ims = scene.load_pil_image(capture_image)
|
4146
4147
|
except SystemError:
|
4147
|
-
im_file = "temp.png" # hack for Pythonista 3.4
|
4148
|
+
im_file = "temp.png" # hack for Pythonista 3.4
|
4148
4149
|
capture_image.save(im_file, "PNG")
|
4149
4150
|
ims = scene.load_image_file(im_file)
|
4150
4151
|
scene.image(ims, 0, 0, *capture_image.size)
|
@@ -5716,15 +5717,19 @@ class Queue:
|
|
5716
5717
|
|
5717
5718
|
|
5718
5719
|
class Store(Queue):
|
5719
|
-
def __init__(self, name: str = None, capacity:
|
5720
|
-
super().__init__(name=name, capacity=capacity, env=env, *args, **kwargs)
|
5720
|
+
def __init__(self, name: str = None, monitor: Any = True, fill: Iterable = None, capacity: float = inf, env: "Environment" = None, *args, **kwargs) -> None:
|
5721
|
+
super().__init__(name=name, monitor=monitor, fill=None, capacity=capacity, env=env, *args, **kwargs)
|
5722
|
+
|
5721
5723
|
with self.env.suppress_trace():
|
5722
5724
|
self._to_store_requesters = Queue(f"{name}.to_store_requesters", env=env)
|
5723
5725
|
self._to_store_requesters._isinternal = True
|
5724
5726
|
self._from_store_requesters = Queue(f"{name}.from_store_requesters", env=env)
|
5725
5727
|
self._from_store_requesters._isinternal = True
|
5726
5728
|
|
5727
|
-
|
5729
|
+
if fill is not None: # this cannot be done by Queue.__init__ as the requesters are not defined at that time
|
5730
|
+
with self.env.suppress_trace():
|
5731
|
+
for c in fill:
|
5732
|
+
c.enter(self)
|
5728
5733
|
|
5729
5734
|
def set_capacity(self, cap: float) -> None:
|
5730
5735
|
"""
|
@@ -7977,6 +7982,10 @@ by adding:
|
|
7977
7982
|
----
|
7978
7983
|
Only if yieldless is False: if to be used for the current component, use ``yield self.cancel()``.
|
7979
7984
|
"""
|
7985
|
+
if self.status.value == data:
|
7986
|
+
if self.env._trace:
|
7987
|
+
self.env.print_trace("", "", "cancel (on data component) " + self.name() + " " + self._modetxt())
|
7988
|
+
return
|
7980
7989
|
if self.status.value != current:
|
7981
7990
|
self._checkisnotdata()
|
7982
7991
|
self._remove()
|
@@ -9044,10 +9053,8 @@ by adding:
|
|
9044
9053
|
self.status._value = waiting
|
9045
9054
|
self._reschedule(scheduled_time, schedule_priority, urgent, "wait", cap_now)
|
9046
9055
|
else:
|
9047
|
-
return
|
9048
|
-
|
9049
|
-
if self is self.env._current_component:
|
9050
|
-
self.env._glet.switch()
|
9056
|
+
return
|
9057
|
+
|
9051
9058
|
|
9052
9059
|
def _trywait(self):
|
9053
9060
|
if self.status.value == interrupted:
|
@@ -9996,6 +10003,211 @@ by adding:
|
|
9996
10003
|
return None
|
9997
10004
|
|
9998
10005
|
|
10006
|
+
class Event(Component):
|
10007
|
+
"""
|
10008
|
+
Event object
|
10009
|
+
|
10010
|
+
An event object is a specialized Component that is usually not subclassed.
|
10011
|
+
|
10012
|
+
Apart from the usual Component parameters it has an action parameter, to specifies what should
|
10013
|
+
happen after becoming active. This action is usually a lambda function.
|
10014
|
+
|
10015
|
+
Parameters
|
10016
|
+
----------
|
10017
|
+
action : callable
|
10018
|
+
function called when the component becomes current.
|
10019
|
+
|
10020
|
+
action_string : str
|
10021
|
+
string to be printed in trace when action gets executed (default: "action")
|
10022
|
+
|
10023
|
+
name : str
|
10024
|
+
name of the component.
|
10025
|
+
|
10026
|
+
if the name ends with a period (.),
|
10027
|
+
auto serializing will be applied
|
10028
|
+
|
10029
|
+
if the name end with a comma,
|
10030
|
+
auto serializing starting at 1 will be applied
|
10031
|
+
|
10032
|
+
if omitted, the name will be derived from the class
|
10033
|
+
it is defined in (lowercased)
|
10034
|
+
|
10035
|
+
at : float or distribution
|
10036
|
+
schedule time
|
10037
|
+
|
10038
|
+
if omitted, now is used
|
10039
|
+
|
10040
|
+
if distribution, the distribution is sampled
|
10041
|
+
|
10042
|
+
delay : float or distributiom
|
10043
|
+
schedule with a delay
|
10044
|
+
|
10045
|
+
if omitted, no delay
|
10046
|
+
|
10047
|
+
if distribution, the distribution is sampled
|
10048
|
+
|
10049
|
+
priority : float
|
10050
|
+
priority
|
10051
|
+
|
10052
|
+
default: 0
|
10053
|
+
|
10054
|
+
if a component has the same time on the event list, this component is sorted accoring to
|
10055
|
+
the priority.
|
10056
|
+
|
10057
|
+
urgent : bool
|
10058
|
+
urgency indicator
|
10059
|
+
|
10060
|
+
if False (default), the component will be scheduled
|
10061
|
+
behind all other components scheduled
|
10062
|
+
for the same time and priority
|
10063
|
+
|
10064
|
+
if True, the component will be scheduled
|
10065
|
+
in front of all components scheduled
|
10066
|
+
for the same time and priority
|
10067
|
+
|
10068
|
+
suppress_trace : bool
|
10069
|
+
suppress_trace indicator
|
10070
|
+
|
10071
|
+
if True, this component will be excluded from the trace
|
10072
|
+
|
10073
|
+
If False (default), the component will be traced
|
10074
|
+
|
10075
|
+
Can be queried or set later with the suppress_trace method.
|
10076
|
+
|
10077
|
+
suppress_pause_at_step : bool
|
10078
|
+
suppress_pause_at_step indicator
|
10079
|
+
|
10080
|
+
if True, if this component becomes current, do not pause when stepping
|
10081
|
+
|
10082
|
+
If False (default), the component will be paused when stepping
|
10083
|
+
|
10084
|
+
Can be queried or set later with the suppress_pause_at_step method.
|
10085
|
+
|
10086
|
+
skip_standby : bool
|
10087
|
+
skip_standby indicator
|
10088
|
+
|
10089
|
+
if True, after this component became current, do not activate standby components
|
10090
|
+
|
10091
|
+
If False (default), after the component became current activate standby components
|
10092
|
+
|
10093
|
+
Can be queried or set later with the skip_standby method.
|
10094
|
+
|
10095
|
+
mode : str preferred
|
10096
|
+
mode
|
10097
|
+
|
10098
|
+
will be used in trace and can be used in animations
|
10099
|
+
|
10100
|
+
if omitted, the mode will be "".
|
10101
|
+
|
10102
|
+
also mode_time will be set to now.
|
10103
|
+
|
10104
|
+
cap_now : bool
|
10105
|
+
indicator whether times (at, delay) in the past are allowed. If, so now() will be used.
|
10106
|
+
default: sys.default_cap_now(), usualy False
|
10107
|
+
|
10108
|
+
env : Environment
|
10109
|
+
environment where the component is defined
|
10110
|
+
|
10111
|
+
if omitted, default_env will be used
|
10112
|
+
"""
|
10113
|
+
|
10114
|
+
def __init__(
|
10115
|
+
self,
|
10116
|
+
action: Callable,
|
10117
|
+
action_string="action",
|
10118
|
+
name: str = None,
|
10119
|
+
at: Union[float, Callable] = None,
|
10120
|
+
delay: Union[float, Callable] = None,
|
10121
|
+
priority: float = None,
|
10122
|
+
urgent: bool = None,
|
10123
|
+
suppress_trace: bool = False,
|
10124
|
+
suppress_pause_at_step: bool = False,
|
10125
|
+
skip_standby: bool = False,
|
10126
|
+
mode: str = "",
|
10127
|
+
cap_now: bool = None,
|
10128
|
+
env: "Environment" = None,
|
10129
|
+
**kwargs,
|
10130
|
+
):
|
10131
|
+
self._action = action
|
10132
|
+
self._action_string = action_string
|
10133
|
+
self._action_taken = False
|
10134
|
+
if env is None:
|
10135
|
+
env = g.default_env
|
10136
|
+
super().__init__(
|
10137
|
+
name=name,
|
10138
|
+
at=at,
|
10139
|
+
delay=delay,
|
10140
|
+
priority=priority,
|
10141
|
+
urgent=urgent,
|
10142
|
+
suppress_trace=suppress_trace,
|
10143
|
+
suppress_pause_at_step=suppress_pause_at_step,
|
10144
|
+
skip_standby=skip_standby,
|
10145
|
+
mode=mode,
|
10146
|
+
cap_now=cap_now,
|
10147
|
+
env=env,
|
10148
|
+
process="process" if env._yieldless else "process_yield",
|
10149
|
+
**kwargs,
|
10150
|
+
)
|
10151
|
+
|
10152
|
+
def process_yield(self):
|
10153
|
+
self.env.print_trace("", "", self._action_string, "")
|
10154
|
+
self._action()
|
10155
|
+
self._action_taken = True
|
10156
|
+
return
|
10157
|
+
yield 1 # just to make it a generator
|
10158
|
+
|
10159
|
+
def process(self):
|
10160
|
+
self.env.print_trace("", "", self._action_string, "")
|
10161
|
+
self._action()
|
10162
|
+
self._action_taken = True
|
10163
|
+
|
10164
|
+
def action(self, value=None):
|
10165
|
+
"""
|
10166
|
+
action
|
10167
|
+
|
10168
|
+
Parameters
|
10169
|
+
----------
|
10170
|
+
value : callable
|
10171
|
+
new action callable
|
10172
|
+
|
10173
|
+
Returns
|
10174
|
+
-------
|
10175
|
+
current action : callable
|
10176
|
+
"""
|
10177
|
+
if value is not None:
|
10178
|
+
self._action = value
|
10179
|
+
return self._action
|
10180
|
+
|
10181
|
+
def action_string(self, value=None):
|
10182
|
+
"""
|
10183
|
+
action_string
|
10184
|
+
|
10185
|
+
Parameters
|
10186
|
+
----------
|
10187
|
+
value : string
|
10188
|
+
new action_string
|
10189
|
+
|
10190
|
+
Returns
|
10191
|
+
-------
|
10192
|
+
current action_string : string
|
10193
|
+
"""
|
10194
|
+
|
10195
|
+
if value is not None:
|
10196
|
+
self._action_string = value
|
10197
|
+
return self._action_string
|
10198
|
+
|
10199
|
+
def action_taken(self):
|
10200
|
+
"""
|
10201
|
+
action_taken
|
10202
|
+
|
10203
|
+
Returns
|
10204
|
+
-------
|
10205
|
+
action taken: bool
|
10206
|
+
True if action has been taken, False if not
|
10207
|
+
"""
|
10208
|
+
return self._action_taken
|
10209
|
+
|
10210
|
+
|
9999
10211
|
class Environment:
|
10000
10212
|
"""
|
10001
10213
|
environment object
|
@@ -10787,7 +10999,7 @@ class Environment:
|
|
10787
10999
|
if c.overridden_lineno:
|
10788
11000
|
self.print_trace(self.time_to_str(self._now - self._offset), c.name(), "current", s0=un_na(c.overridden_lineno))
|
10789
11001
|
else:
|
10790
|
-
self.print_trace(self.time_to_str(self._now - self._offset), c.name(), "current", s0=un_na(c.lineno_txt()))
|
11002
|
+
self.print_trace(self.time_to_str(self._now - self._offset), c.name(), "current", s0=un_na(c.lineno_txt()))
|
10791
11003
|
if c == self._main:
|
10792
11004
|
self.running = False
|
10793
11005
|
return
|
@@ -11502,7 +11714,7 @@ class Environment:
|
|
11502
11714
|
if self._video_pingpong:
|
11503
11715
|
self._images.extend(self._images[::-1])
|
11504
11716
|
if self._video_repeat == 1: # in case of repeat == 1, loop should not be specified (otherwise, it might show twice)
|
11505
|
-
if PythonInExcel or AnacondaCode:
|
11717
|
+
if PythonInExcel or AnacondaCode:
|
11506
11718
|
with b64_file_handler(self._video_name, mode="b", result=_pie_result) as f:
|
11507
11719
|
self._images[0].save(
|
11508
11720
|
f,
|
@@ -11523,7 +11735,7 @@ class Environment:
|
|
11523
11735
|
optimize=False,
|
11524
11736
|
)
|
11525
11737
|
else:
|
11526
|
-
if PythonInExcel or AnacondaCode:
|
11738
|
+
if PythonInExcel or AnacondaCode:
|
11527
11739
|
with b64_file_handler(self._video_name, mode="b", result=_pie_result) as f:
|
11528
11740
|
self._images[0].save(
|
11529
11741
|
f,
|
@@ -15308,8 +15520,6 @@ class Animate2dBase(DynamicClass):
|
|
15308
15520
|
|
15309
15521
|
if not self.screen_coordinates:
|
15310
15522
|
fontsize = fontsize * self.env._scale
|
15311
|
-
# offsetx = offsetx * self.env._scale # ***
|
15312
|
-
# offsety = offsety * self.env._scale # ***
|
15313
15523
|
text_anchor = self.text_anchor(t)
|
15314
15524
|
|
15315
15525
|
if self.attached_to:
|
@@ -15343,6 +15553,7 @@ class Animate2dBase(DynamicClass):
|
|
15343
15553
|
qx = (x - self.env._x0) * self.env._scale
|
15344
15554
|
qy = (y - self.env._y0) * self.env._scale
|
15345
15555
|
max_lines = self.max_lines(t)
|
15556
|
+
|
15346
15557
|
self._image_ident = (text, fontname, fontsize, angle, textcolor, max_lines)
|
15347
15558
|
if self._image_ident != self._image_ident_prev:
|
15348
15559
|
font, heightA = getfont(fontname, fontsize)
|
@@ -19818,6 +20029,13 @@ class ComponentGenerator(Component):
|
|
19818
20029
|
|
19819
20030
|
e.g. env.main().activate()
|
19820
20031
|
|
20032
|
+
moments : iterable
|
20033
|
+
specifies the moments when the components have to be generated. It is not required that these are sorted.
|
20034
|
+
|
20035
|
+
note that the moments are specified in the current time unit
|
20036
|
+
|
20037
|
+
cannot be used together with at, delay, till, duration, number, iat,force_at, force_till, disturbance or equidistant
|
20038
|
+
|
19821
20039
|
env : Environment
|
19822
20040
|
environment where the component is defined
|
19823
20041
|
|
@@ -19846,6 +20064,7 @@ class ComponentGenerator(Component):
|
|
19846
20064
|
disturbance: Callable = None,
|
19847
20065
|
equidistant: bool = False,
|
19848
20066
|
at_end: Callable = None,
|
20067
|
+
moments: Iterable = None,
|
19849
20068
|
env: "Environment" = None,
|
19850
20069
|
**kwargs,
|
19851
20070
|
):
|
@@ -19863,6 +20082,15 @@ class ComponentGenerator(Component):
|
|
19863
20082
|
|
19864
20083
|
if not callable(component_class):
|
19865
20084
|
raise ValueError("component_class must be a callable")
|
20085
|
+
if moments is not None:
|
20086
|
+
if any(prop for prop in (at, delay, till, duration, number, iat, force_at, force_till, disturbance, equidistant)):
|
20087
|
+
raise ValueError(
|
20088
|
+
"specifying at, delay, till,duration, number, iat,force_at, force_till, disturbance or equidistant is not allowed, if moments is specified"
|
20089
|
+
)
|
20090
|
+
if callable(moments):
|
20091
|
+
moments = moments()
|
20092
|
+
moments = sorted([env.spec_to_time(moment) for moment in moments])
|
20093
|
+
|
19866
20094
|
self.component_class = component_class
|
19867
20095
|
self.iat = iat
|
19868
20096
|
self.disturbance = disturbance
|
@@ -19905,25 +20133,26 @@ class ComponentGenerator(Component):
|
|
19905
20133
|
at = None
|
19906
20134
|
process = ""
|
19907
20135
|
else:
|
19908
|
-
if self.iat is None and not equidistant:
|
19909
|
-
if
|
19910
|
-
|
19911
|
-
|
19912
|
-
|
19913
|
-
|
19914
|
-
|
19915
|
-
|
19916
|
-
if
|
19917
|
-
if
|
19918
|
-
|
19919
|
-
|
19920
|
-
|
19921
|
-
|
19922
|
-
|
19923
|
-
|
19924
|
-
|
19925
|
-
|
19926
|
-
|
20136
|
+
if (self.iat is None and not equidistant) or moments:
|
20137
|
+
if not moments:
|
20138
|
+
if till == inf or self.number == inf:
|
20139
|
+
raise ValueError("iat not specified --> till and number need to be specified")
|
20140
|
+
if disturbance is not None:
|
20141
|
+
raise ValueError("iat not specified --> disturbance not allowed")
|
20142
|
+
|
20143
|
+
moments = sorted([Uniform(at, till)() for _ in range(self.number)])
|
20144
|
+
if force_at or force_till:
|
20145
|
+
if number == 1:
|
20146
|
+
if force_at and force_till:
|
20147
|
+
raise ValueError("force_at and force_till does not allow number=1")
|
20148
|
+
moments = [at] if force_at else [till]
|
20149
|
+
else:
|
20150
|
+
v_at = at if force_at else moments[0]
|
20151
|
+
v_till = till if force_till else moments[-1]
|
20152
|
+
min_moment = moments[0]
|
20153
|
+
max_moment = moments[-1]
|
20154
|
+
moments = [interpolate(moment, min_moment, max_moment, v_at, v_till) for moment in moments]
|
20155
|
+
self.intervals = [t1 - t0 for t0, t1 in zip([0] + moments, moments)]
|
19927
20156
|
at = self.intervals[0]
|
19928
20157
|
self.intervals[0] = 0
|
19929
20158
|
process = "do_spread_yieldless" if env._yieldless else "do_spread"
|
@@ -26312,7 +26541,7 @@ def fonts():
|
|
26312
26541
|
|
26313
26542
|
for dir, recursive in dir_recursives:
|
26314
26543
|
for file_path in dir.glob("**/*.*" if recursive else "*.*"):
|
26315
|
-
if file_path.suffix.lower() == ".ttf":
|
26544
|
+
if file_path.suffix.lower() == ".ttf":
|
26316
26545
|
file = str(file_path)
|
26317
26546
|
fn = os.path.basename(file).split(".")[0]
|
26318
26547
|
if "_std_fonts" in globals() and fn in _std_fonts(): # test for availabiitly, because of minimized version
|
@@ -26372,7 +26601,8 @@ def getfont(fontname, fontsize):
|
|
26372
26601
|
return getfont.lookup[(fontname, fontsize)]
|
26373
26602
|
else:
|
26374
26603
|
getfont.lookup = {}
|
26375
|
-
|
26604
|
+
if fontname=="":
|
26605
|
+
a=1
|
26376
26606
|
if isinstance(fontname, str):
|
26377
26607
|
fontlist1 = [fontname]
|
26378
26608
|
else:
|
@@ -26405,7 +26635,8 @@ def getfont(fontname, fontsize):
|
|
26405
26635
|
result = ImageFont.truetype(filename, size=int(fontsize))
|
26406
26636
|
else:
|
26407
26637
|
# refer to https://github.com/python-pillow/Pillow/issues/3730 for explanation (in order to load >= 500 fonts)
|
26408
|
-
|
26638
|
+
with open(filename, "rb") as f:
|
26639
|
+
result = ImageFont.truetype(font=io.BytesIO(f.read()), size=int(fontsize))
|
26409
26640
|
break
|
26410
26641
|
except Exception:
|
26411
26642
|
raise
|
@@ -26798,7 +27029,7 @@ class ImageContainer:
|
|
26798
27029
|
if not (0 <= t_from < t_to):
|
26799
27030
|
raise ValueError(f"animation_from={t_from} not with 0 and animation_to={t_to}")
|
26800
27031
|
if t_to > self._duration:
|
26801
|
-
raise ValueError(f"animation_to={t_to} > duration={
|
27032
|
+
raise ValueError(f"animation_to={t_to} > duration={self._duration}")
|
26802
27033
|
if pingpong:
|
26803
27034
|
interval = 2 * (t_to - t_from)
|
26804
27035
|
else:
|
@@ -26944,7 +27175,7 @@ def reset() -> None:
|
|
26944
27175
|
g.tkinter_loaded = "?"
|
26945
27176
|
g.image_container_cache = {}
|
26946
27177
|
g._default_cap_now = False
|
26947
|
-
g._captured_stdout=[]
|
27178
|
+
g._captured_stdout = []
|
26948
27179
|
|
26949
27180
|
random_seed() # always start with seed 1234567
|
26950
27181
|
|
@@ -27177,7 +27408,6 @@ reset()
|
|
27177
27408
|
set_environment_aliases()
|
27178
27409
|
|
27179
27410
|
if __name__ == "__main__":
|
27180
|
-
|
27181
27411
|
sys.path.insert(0, str(Path(__file__).parent / ".." / "misc"))
|
27182
27412
|
try:
|
27183
27413
|
import salabim_exp
|
@@ -0,0 +1,10 @@
|
|
1
|
+
salabim/DejaVuSansMono.ttf,sha256=Z_oIXp5yp1Zaw2y2p3vaxwHhjHpG0MFbmwhxSh4aIEI,335068
|
2
|
+
salabim/LICENSE.txt,sha256=qHlBa-POyexatCxDTjSKMlYtkBFQDn9lu-YV_1L6V0U,1106
|
3
|
+
salabim/__init__.py,sha256=r7qPLvlmX0dkZDyjuTo8Jo3ex3sD1L4pmK6K5ib9vyw,56
|
4
|
+
salabim/calibri.ttf,sha256=RWpf8Uo31RfvGGNaSt9-2sXSuN87AVE_NFMRsV3LhBk,1330156
|
5
|
+
salabim/mplus-1m-regular.ttf,sha256=EuFHr90BJjuAn_r5MleJFN-WfkeWJ4tf7DweI5zr8tU,289812
|
6
|
+
salabim/salabim.py,sha256=NzhLkqRi8niqF9eQQPZRxJueQBROP0084q6qHrY6Qzc,1103953
|
7
|
+
salabim-24.0.13.dist-info/METADATA,sha256=-xWemNdEOZ-EbstXw49IqGKhr97mg85QxyuDLa2LtGA,3450
|
8
|
+
salabim-24.0.13.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
9
|
+
salabim-24.0.13.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
|
10
|
+
salabim-24.0.13.dist-info/RECORD,,
|
@@ -1,10 +0,0 @@
|
|
1
|
-
salabim/DejaVuSansMono.ttf,sha256=Z_oIXp5yp1Zaw2y2p3vaxwHhjHpG0MFbmwhxSh4aIEI,335068
|
2
|
-
salabim/LICENSE.txt,sha256=qHlBa-POyexatCxDTjSKMlYtkBFQDn9lu-YV_1L6V0U,1106
|
3
|
-
salabim/__init__.py,sha256=r7qPLvlmX0dkZDyjuTo8Jo3ex3sD1L4pmK6K5ib9vyw,56
|
4
|
-
salabim/calibri.ttf,sha256=RWpf8Uo31RfvGGNaSt9-2sXSuN87AVE_NFMRsV3LhBk,1330156
|
5
|
-
salabim/mplus-1m-regular.ttf,sha256=EuFHr90BJjuAn_r5MleJFN-WfkeWJ4tf7DweI5zr8tU,289812
|
6
|
-
salabim/salabim.py,sha256=8dANioKbD1covX06fZohLeNttQVbalrN6q8eODdZYTU,1097286
|
7
|
-
salabim-24.0.11.post1.dist-info/METADATA,sha256=g39m6E1GfEa8lmL3Ji7vWbz2MpGvYClI1oedRWT2zQc,3456
|
8
|
-
salabim-24.0.11.post1.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
|
9
|
-
salabim-24.0.11.post1.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
|
10
|
-
salabim-24.0.11.post1.dist-info/RECORD,,
|
File without changes
|