ivoryos 0.1.10__py3-none-any.whl → 0.1.12__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 ivoryos might be problematic. Click here for more details.
- ivoryos/__init__.py +4 -0
- ivoryos/routes/control/control.py +1 -1
- ivoryos/routes/design/design.py +4 -2
- ivoryos/routes/design/templates/design/experiment_builder.html +4 -4
- ivoryos/routes/design/templates/design/experiment_run.html +2 -2
- ivoryos/utils/db_models.py +29 -3
- ivoryos/utils/form.py +20 -8
- ivoryos/utils/script_runner.py +2 -1
- ivoryos/utils/utils.py +14 -2
- ivoryos/version.py +1 -1
- {ivoryos-0.1.10.dist-info → ivoryos-0.1.12.dist-info}/METADATA +1 -1
- {ivoryos-0.1.10.dist-info → ivoryos-0.1.12.dist-info}/RECORD +15 -15
- {ivoryos-0.1.10.dist-info → ivoryos-0.1.12.dist-info}/LICENSE +0 -0
- {ivoryos-0.1.10.dist-info → ivoryos-0.1.12.dist-info}/WHEEL +0 -0
- {ivoryos-0.1.10.dist-info → ivoryos-0.1.12.dist-info}/top_level.txt +0 -0
ivoryos/__init__.py
CHANGED
ivoryos/routes/design/design.py
CHANGED
|
@@ -106,8 +106,8 @@ def experiment_builder(instrument=None):
|
|
|
106
106
|
deck_variables = list(pseudo_deck.keys()) if pseudo_deck else []
|
|
107
107
|
deck_variables.remove("deck_name") if len(deck_variables) > 0 else deck_variables
|
|
108
108
|
if instrument:
|
|
109
|
-
if instrument in ['if', 'while', 'variable', 'wait']:
|
|
110
|
-
forms = create_builtin_form(instrument)
|
|
109
|
+
if instrument in ['if', 'while', 'variable', 'wait', 'repeat']:
|
|
110
|
+
forms = create_builtin_form(instrument, autofill=autofill, script=script)
|
|
111
111
|
else:
|
|
112
112
|
if deck:
|
|
113
113
|
function_metadata = global_config.deck_snapshot.get(instrument, {})
|
|
@@ -306,6 +306,8 @@ def experiment_run():
|
|
|
306
306
|
logger=g.logger, socketio=g.socketio, repeat_count=repeat,
|
|
307
307
|
output_path=datapath
|
|
308
308
|
)
|
|
309
|
+
if utils.check_config_duplicate(config):
|
|
310
|
+
flash(f"WARNING: Duplicate in config entries.")
|
|
309
311
|
except Exception as e:
|
|
310
312
|
flash(e)
|
|
311
313
|
return render_template('experiment_run.html', script=script.script_dict, filename=filename, dot_py=exec_string,
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
<!-- <div class="rounded flex-fill" style="height: 30px;background-color: aliceblue">-->
|
|
73
73
|
<!-- <h6 style=" text-align: center; ">{{ format_name(instrument) }}</h6>-->
|
|
74
74
|
<!-- </div>-->
|
|
75
|
-
{% if instrument in ['if' , 'while' , 'variable' ,'wait'] %}
|
|
75
|
+
{% if instrument in ['if' , 'while' , 'variable' ,'wait', 'repeat'] %}
|
|
76
76
|
{# form for builtin functions #}
|
|
77
77
|
<form role="form" method='POST' name="{{instrument}}" action="{{url_for('design.experiment_builder',instrument=instrument)}}" >
|
|
78
78
|
<div class="form-group">
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
</h5>
|
|
186
186
|
<div class="accordion-collapse collapse show" id="advanced">
|
|
187
187
|
<ul class="list-group">
|
|
188
|
-
{% for instrument in ['if', 'while', 'variable', 'wait'] %}
|
|
188
|
+
{% for instrument in ['if', 'while', 'variable', 'wait', 'repeat'] %}
|
|
189
189
|
<form role="form" method='GET' name="device" action="{{url_for('design.experiment_builder',instrument=instrument)}}">
|
|
190
190
|
<div class="form-group">
|
|
191
191
|
<button class="list-group-item list-group-item-action" aria-current="true" type="submit">{{instrument}}</button>
|
|
@@ -302,7 +302,7 @@
|
|
|
302
302
|
{% for button in buttons %}
|
|
303
303
|
<li id="{{ button['id'] }}" style="list-style-type: none;">
|
|
304
304
|
<a href="{{ url_for('design.edit_action', uuid=button['uuid']) }}" type="button" class="btn btn-light" style="{{ button['style'] }}">{{ button['label'] }}</a>
|
|
305
|
-
{% if not button["instrument"] in ["if","while"] %}
|
|
305
|
+
{% if not button["instrument"] in ["if","while","repeat"] %}
|
|
306
306
|
<a href="{{ url_for('design.duplicate_action', id=button['id']) }}" type="button" class="btn btn-light"><span class="bi bi-copy"></span></a>
|
|
307
307
|
{% endif %}
|
|
308
308
|
<a href="{{ url_for('design.delete_action', id=button['id']) }}" type="button" class="btn btn-light"><span class="bi bi-trash"></span></a>
|
|
@@ -403,7 +403,7 @@
|
|
|
403
403
|
</div>
|
|
404
404
|
</div>
|
|
405
405
|
|
|
406
|
-
{% if instrument and not instrument in ['if' , 'while' , 'variable' ,'wait'] and use_llm %}
|
|
406
|
+
{% if instrument and not instrument in ['if' , 'while' , 'variable' ,'wait', 'repeat'] and use_llm %}
|
|
407
407
|
<script>
|
|
408
408
|
const buttonIds = {{ ['generate'] | tojson }};
|
|
409
409
|
</script>
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
<form role="form" method='POST' name="run" action="{{url_for('design.experiment_run')}}">
|
|
51
51
|
<div class="input-group mb-3">
|
|
52
52
|
<label class="input-group-text" for="repeat">Repeat for </label>
|
|
53
|
-
<input class="form-control" type="number" id="repeat" name="repeat" min="1" max="
|
|
53
|
+
<input class="form-control" type="number" id="repeat" name="repeat" min="1" max="1000" value="1">
|
|
54
54
|
<label class="input-group-text" for="repeat"> times</label>
|
|
55
55
|
</div>
|
|
56
56
|
{# {% if not no_deck_warning%}#}
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
<p><h5>Budget:</h5></p>
|
|
186
186
|
<div class="input-group mb-3">
|
|
187
187
|
<label class="input-group-text" for="repeat">Max iteration </label>
|
|
188
|
-
<input class="form-control" type="number" id="repeat" name="repeat" min="1" max="
|
|
188
|
+
<input class="form-control" type="number" id="repeat" name="repeat" min="1" max="1000" value="25">
|
|
189
189
|
</div>
|
|
190
190
|
{% if not no_deck_warning%}
|
|
191
191
|
<div class="input-group mb-3">
|
ivoryos/utils/db_models.py
CHANGED
|
@@ -241,6 +241,13 @@ class Script(db.Model):
|
|
|
241
241
|
"args": '0' if statement == '' else statement,
|
|
242
242
|
"return": '', "uuid": uid, "arg_types": "float"},
|
|
243
243
|
],
|
|
244
|
+
"repeat":
|
|
245
|
+
[
|
|
246
|
+
{"id": current_len + 1, "instrument": 'repeat', "action": "repeat",
|
|
247
|
+
"args": '1' if statement == '' else statement, "return": '', "uuid": uid, "arg_types": "int"},
|
|
248
|
+
{"id": current_len + 2, "instrument": 'repeat', "action": 'endrepeat',
|
|
249
|
+
"args": '', "return": '', "uuid": uid},
|
|
250
|
+
],
|
|
244
251
|
}
|
|
245
252
|
action_list = logic_dict[logic_type]
|
|
246
253
|
self.currently_editing_script.extend(action_list)
|
|
@@ -366,11 +373,14 @@ class Script(db.Model):
|
|
|
366
373
|
"""
|
|
367
374
|
Generate the function header.
|
|
368
375
|
"""
|
|
369
|
-
configure,
|
|
376
|
+
configure, config_type = self.config(stype)
|
|
377
|
+
|
|
378
|
+
configure = [param + f":{param_type}" if not param_type == "any" else "" for param, param_type in config_type.items()]
|
|
379
|
+
|
|
370
380
|
function_header = f"\n\ndef {run_name}_{stype}("
|
|
371
381
|
|
|
372
382
|
if stype == "script":
|
|
373
|
-
function_header += ",".join(configure)
|
|
383
|
+
function_header += ", ".join(configure)
|
|
374
384
|
|
|
375
385
|
function_header += "):"
|
|
376
386
|
function_header += self.indent(1) + f"global {run_name}_{stype}"
|
|
@@ -389,7 +399,6 @@ class Script(db.Model):
|
|
|
389
399
|
return_str, return_list = self.config_return()
|
|
390
400
|
if return_list and stype == "script":
|
|
391
401
|
body += self.indent(indent_unit) + return_str
|
|
392
|
-
|
|
393
402
|
return body
|
|
394
403
|
|
|
395
404
|
def _process_action(self, indent_unit, action, index, stype):
|
|
@@ -409,6 +418,9 @@ class Script(db.Model):
|
|
|
409
418
|
return self.indent(indent_unit) + f"{action_name} = {args}", indent_unit
|
|
410
419
|
elif instrument == 'wait':
|
|
411
420
|
return f"{self.indent(indent_unit)}time.sleep({args})", indent_unit
|
|
421
|
+
elif instrument == 'repeat':
|
|
422
|
+
return self._process_repeat(indent_unit, action_name, args, next_action)
|
|
423
|
+
|
|
412
424
|
else:
|
|
413
425
|
return self._process_instrument_action(indent_unit, instrument, action_name, args, save_data)
|
|
414
426
|
|
|
@@ -456,6 +468,20 @@ class Script(db.Model):
|
|
|
456
468
|
indent_unit -= 1
|
|
457
469
|
return exec_string, indent_unit
|
|
458
470
|
|
|
471
|
+
def _process_repeat(self, indent_unit, action, args, next_action):
|
|
472
|
+
"""
|
|
473
|
+
Process 'while' and 'endwhile' actions.
|
|
474
|
+
"""
|
|
475
|
+
exec_string = ""
|
|
476
|
+
if action == 'repeat':
|
|
477
|
+
exec_string += self.indent(indent_unit) + f"for _ in range({args}):"
|
|
478
|
+
indent_unit += 1
|
|
479
|
+
if next_action and next_action['instrument'] == 'repeat':
|
|
480
|
+
exec_string += self.indent(indent_unit) + "pass"
|
|
481
|
+
elif action == 'endrepeat':
|
|
482
|
+
indent_unit -= 1
|
|
483
|
+
return exec_string, indent_unit
|
|
484
|
+
|
|
459
485
|
def _process_instrument_action(self, indent_unit, instrument, action, args, save_data):
|
|
460
486
|
"""
|
|
461
487
|
Process actions related to instruments.
|
ivoryos/utils/form.py
CHANGED
|
@@ -269,17 +269,25 @@ def create_form_from_pseudo(pseudo: dict, autofill: bool, script=None, design=Tr
|
|
|
269
269
|
return method_forms
|
|
270
270
|
|
|
271
271
|
|
|
272
|
-
def create_builtin_form(logic_type):
|
|
272
|
+
def create_builtin_form(logic_type, autofill, script):
|
|
273
273
|
class BuiltinFunctionForm(FlaskForm):
|
|
274
274
|
pass
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
placeholder_text = {
|
|
276
|
+
'wait': 'Enter second',
|
|
277
|
+
'repeat': 'Enter an integer'
|
|
278
|
+
}.get(logic_type, 'Enter statement')
|
|
279
|
+
description_text = {
|
|
280
|
+
'variable': 'Your variable can be numbers, boolean (True or False) or text ("text")',
|
|
281
|
+
}.get(logic_type, '')
|
|
282
|
+
field_class = {
|
|
283
|
+
'wait': VariableOrFloatField,
|
|
284
|
+
'repeat': VariableOrIntField
|
|
285
|
+
}.get(logic_type, VariableOrStringField) # Default to StringField as a fallback
|
|
279
286
|
field_kwargs = {
|
|
280
287
|
"label": f'statement',
|
|
281
288
|
"validators": [InputRequired()] if logic_type in ['wait', "variable"] else [],
|
|
282
289
|
"description": description_text,
|
|
290
|
+
"script": script
|
|
283
291
|
}
|
|
284
292
|
render_kwargs = {"placeholder": placeholder_text}
|
|
285
293
|
field = field_class(**field_kwargs, render_kw=render_kwargs)
|
|
@@ -295,10 +303,8 @@ def create_builtin_form(logic_type):
|
|
|
295
303
|
|
|
296
304
|
|
|
297
305
|
def create_action_button(s: dict):
|
|
298
|
-
|
|
299
|
-
if s['instrument'] in ['if', 'while']:
|
|
306
|
+
if s['instrument'] in ['if', 'while', 'repeat']:
|
|
300
307
|
text = f"{s['action']} {s['args']}"
|
|
301
|
-
style = "background-color: tomato"
|
|
302
308
|
elif s['instrument'] == 'variable':
|
|
303
309
|
text = f"{s['action']} = {s['args']}"
|
|
304
310
|
else:
|
|
@@ -313,4 +319,10 @@ def create_action_button(s: dict):
|
|
|
313
319
|
arg_string = f"= {s['args']}"
|
|
314
320
|
|
|
315
321
|
text = f"{prefix}{action_text} {arg_string}"
|
|
322
|
+
style = {
|
|
323
|
+
"repeat": "background-color: lightsteelblue",
|
|
324
|
+
"if": "background-color: salmon",
|
|
325
|
+
"while": "background-color: salmon",
|
|
326
|
+
|
|
327
|
+
}.get(s['instrument'], "")
|
|
316
328
|
return dict(label=text, style=style, uuid=s["uuid"], id=s["id"], instrument=s['instrument'])
|
ivoryos/utils/script_runner.py
CHANGED
|
@@ -133,7 +133,8 @@ class ScriptRunner:
|
|
|
133
133
|
function = self.globals_dict[fname]
|
|
134
134
|
output = function(**parameters)
|
|
135
135
|
# output = eval(f"{run_name}_script(**{parameters})")
|
|
136
|
-
|
|
136
|
+
_output = output.copy()
|
|
137
|
+
ax_client.complete_trial(trial_index=trial_index, raw_data=_output)
|
|
137
138
|
output.update(parameters)
|
|
138
139
|
except Exception as e:
|
|
139
140
|
logger.info(f'Optimization error: {e}')
|
ivoryos/utils/utils.py
CHANGED
|
@@ -6,6 +6,7 @@ import os
|
|
|
6
6
|
import pickle
|
|
7
7
|
import subprocess
|
|
8
8
|
import sys
|
|
9
|
+
from collections import Counter
|
|
9
10
|
from typing import Optional, Dict, Tuple
|
|
10
11
|
|
|
11
12
|
from flask import session
|
|
@@ -317,8 +318,9 @@ def ax_wrapper(data: dict, arg_types:list):
|
|
|
317
318
|
is_min = True if value == "minimize" else False
|
|
318
319
|
|
|
319
320
|
threshold = None if f"{obj_name}_threshold" not in data else data[f"{obj_name}_threshold"]
|
|
320
|
-
properties = ObjectiveProperties(minimize=is_min
|
|
321
|
+
properties = ObjectiveProperties(minimize=is_min)
|
|
321
322
|
objectives[obj_name] = properties
|
|
323
|
+
|
|
322
324
|
return parameter, objectives
|
|
323
325
|
|
|
324
326
|
|
|
@@ -331,7 +333,7 @@ def ax_initiation(data, arg_types):
|
|
|
331
333
|
parameter, objectives = ax_wrapper(data, arg_types)
|
|
332
334
|
from ax.service.ax_client import AxClient
|
|
333
335
|
ax_client = AxClient()
|
|
334
|
-
ax_client.create_experiment(parameter, objectives)
|
|
336
|
+
ax_client.create_experiment(parameter, objectives=objectives)
|
|
335
337
|
return ax_client
|
|
336
338
|
|
|
337
339
|
|
|
@@ -423,3 +425,13 @@ def load_deck(pkl_name: str):
|
|
|
423
425
|
return pseudo_deck
|
|
424
426
|
except FileNotFoundError:
|
|
425
427
|
return None
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def check_config_duplicate(config):
|
|
431
|
+
"""
|
|
432
|
+
Checks if the config entry has any duplicate
|
|
433
|
+
:param config: [{"arg": 1}, {"arg": 1}, {"arg": 1}]
|
|
434
|
+
:return: [True, False]
|
|
435
|
+
"""
|
|
436
|
+
hashable_data = [tuple(sorted(d.items())) for d in config]
|
|
437
|
+
return any(count > 1 for count in Counter(hashable_data).values())
|
ivoryos/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.12"
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
ivoryos/__init__.py,sha256=
|
|
1
|
+
ivoryos/__init__.py,sha256=pKaEGt1aqh4U0ofAVm2jdhyoyrR1jYlEO-Qi2T7Sfp4,4743
|
|
2
2
|
ivoryos/config.py,sha256=3FPBYTIBhQTKDvsEoR8ZeTmg65D-CSFEdGmOuIL4pSI,1311
|
|
3
|
-
ivoryos/version.py,sha256=
|
|
3
|
+
ivoryos/version.py,sha256=LcIlFjHZFfiF9Rd4UHoakmombOFkxIYk00I181frGBM,23
|
|
4
4
|
ivoryos/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
ivoryos/routes/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
ivoryos/routes/auth/auth.py,sha256=7CdXjGAr1B_xsmwweakTWOoROgsOJf0MNTzlMP_5Nus,3240
|
|
7
7
|
ivoryos/routes/auth/templates/auth/login.html,sha256=WSRrKbdM_oobqSXFRTo-j9UlOgp6sYzS9tm7TqqPULI,1207
|
|
8
8
|
ivoryos/routes/auth/templates/auth/signup.html,sha256=b5LTXtpfTSkSS7X8u1ldwQbbgEFTk6UNMAediA5BwBY,1465
|
|
9
9
|
ivoryos/routes/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
ivoryos/routes/control/control.py,sha256=
|
|
10
|
+
ivoryos/routes/control/control.py,sha256=MmrcKrkjSKS589XhDdvPc7kWO0ApCNVZCtrgfzTAAN8,14163
|
|
11
11
|
ivoryos/routes/control/templates/control/controllers.html,sha256=QdZAieEA4ODC-3KlsgHmFO35q8KXjm0KT43ZNpcBgEs,4084
|
|
12
12
|
ivoryos/routes/control/templates/control/controllers_home.html,sha256=xFnBXTWMlyi2naMSsCEqFlX-Z1HJJDDtzITPvq-3nng,2733
|
|
13
13
|
ivoryos/routes/control/templates/control/controllers_new.html,sha256=uOQo9kYmwX2jk3KZDkMUF_ylfNUIs_oIWb_kk_MMVDM,4921
|
|
@@ -15,9 +15,9 @@ ivoryos/routes/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
15
15
|
ivoryos/routes/database/database.py,sha256=IOrdtdsZ28bV7R1ZQfcwAeS5JDCkX-QYsP9i8BseD38,5684
|
|
16
16
|
ivoryos/routes/database/templates/database/experiment_database.html,sha256=ABchwHYDovzwECc7UD4Mh8C_9JUl0YZpAAF9sFjNCs0,3434
|
|
17
17
|
ivoryos/routes/design/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
ivoryos/routes/design/design.py,sha256=
|
|
19
|
-
ivoryos/routes/design/templates/design/experiment_builder.html,sha256=
|
|
20
|
-
ivoryos/routes/design/templates/design/experiment_run.html,sha256=
|
|
18
|
+
ivoryos/routes/design/design.py,sha256=ZAUh-XOMhePCmY7q-hfru-4X6fDR3aKKyktrD2NC6M4,20876
|
|
19
|
+
ivoryos/routes/design/templates/design/experiment_builder.html,sha256=lF8fDMHtwQjVznbCL4klV3o1p0tkqMptPY5IXR7WSuE,27327
|
|
20
|
+
ivoryos/routes/design/templates/design/experiment_run.html,sha256=JxYEbJqeJH8vZaSVI25EtNYmI_W5GSFdc02Y8y3kZGc,22543
|
|
21
21
|
ivoryos/routes/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
ivoryos/routes/main/main.py,sha256=yuVJzXAob1kc1dfflkTBIZQ0tdf6kChfuq-uQlN1e9Q,957
|
|
23
23
|
ivoryos/routes/main/templates/main/help.html,sha256=IOktMEsOPk0SCiMBXZ4mpffClERAyX8W82fel71M3M0,9370
|
|
@@ -34,14 +34,14 @@ ivoryos/static/js/sortable_card.js,sha256=ifmlGe3yy0U_KzMphV4ClRhK2DLOvkELYMlq1v
|
|
|
34
34
|
ivoryos/static/js/sortable_design.js,sha256=1lI1I8FbL66tv6n-SX2FkbHNDYo36xVo2qDBKVLmxnQ,1120
|
|
35
35
|
ivoryos/templates/base.html,sha256=OR04eHEgmq4Wj0en3z6J2l-CdcJjZryRBjLsWyKdnCo,7800
|
|
36
36
|
ivoryos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
-
ivoryos/utils/db_models.py,sha256=
|
|
38
|
-
ivoryos/utils/form.py,sha256=
|
|
37
|
+
ivoryos/utils/db_models.py,sha256=XoReukuWiroDX4OTfyd9dHRpGIN2woWL017P7N-VZ0U,20918
|
|
38
|
+
ivoryos/utils/form.py,sha256=zpEFUyx9nMZkkTYVL0DIT3kEWd1DQsDGSBu4UysXf4s,12338
|
|
39
39
|
ivoryos/utils/global_config.py,sha256=Ojcz6xKATSbMLnTT0kiKqSnu_bNqCMyIAnZyHaKxJns,1589
|
|
40
40
|
ivoryos/utils/llm_agent.py,sha256=DTf-AF56vy1Em1fUKagl5NURKittmNoxTKIw1PlyC2o,6413
|
|
41
|
-
ivoryos/utils/script_runner.py,sha256=
|
|
42
|
-
ivoryos/utils/utils.py,sha256=
|
|
43
|
-
ivoryos-0.1.
|
|
44
|
-
ivoryos-0.1.
|
|
45
|
-
ivoryos-0.1.
|
|
46
|
-
ivoryos-0.1.
|
|
47
|
-
ivoryos-0.1.
|
|
41
|
+
ivoryos/utils/script_runner.py,sha256=sFAUGCcfsA8DEPgw7koqEAr9fnxxYNRuiOC3L3yOwwc,7079
|
|
42
|
+
ivoryos/utils/utils.py,sha256=5pNF5QJMXmImxDR0IRqaMzIy9n0fD_M1SUY1v9koEc8,15368
|
|
43
|
+
ivoryos-0.1.12.dist-info/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
|
|
44
|
+
ivoryos-0.1.12.dist-info/METADATA,sha256=-aWjCWBd57wVqDBrPxwJdUPW3picfwV-I47vgpo0xX8,6335
|
|
45
|
+
ivoryos-0.1.12.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
|
46
|
+
ivoryos-0.1.12.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
|
|
47
|
+
ivoryos-0.1.12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|