easycoder 250406.1__py2.py3-none-any.whl → 250422.3__py2.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.
easycoder/__init__.py CHANGED
@@ -9,4 +9,4 @@ from .ec_program import *
9
9
  from .ec_timestamp import *
10
10
  from .ec_value import *
11
11
 
12
- __version__ = "250406.1"
12
+ __version__ = "250422.3"
easycoder/ec_core.py CHANGED
@@ -1597,6 +1597,13 @@ class Core(Handler):
1597
1597
  target['locked'] = False
1598
1598
  return self.nextPC()
1599
1599
 
1600
+ def k_use(self, command):
1601
+ if self.nextIs('graphics'):
1602
+ from .ec_pyside6 import Graphics
1603
+ self.program.classes.append(Graphics)
1604
+ self.program.processClasses()
1605
+ return True
1606
+
1600
1607
  # Declare a general-purpose variable
1601
1608
  def k_variable(self, command):
1602
1609
  return self.compileVariable(command, True)
@@ -0,0 +1,517 @@
1
+ import sys
2
+ from easycoder import Handler, FatalError, RuntimeError
3
+ from PySide6.QtCore import Qt, QTimer
4
+ from PySide6.QtWidgets import (
5
+ QApplication,
6
+ QCheckBox,
7
+ QComboBox,
8
+ QDateEdit,
9
+ QDateTimeEdit,
10
+ QDial,
11
+ QDoubleSpinBox,
12
+ QFontComboBox,
13
+ QLabel,
14
+ QLCDNumber,
15
+ QLineEdit,
16
+ QListWidget,
17
+ QMainWindow,
18
+ QProgressBar,
19
+ QPushButton,
20
+ QRadioButton,
21
+ QSlider,
22
+ QSpinBox,
23
+ QTimeEdit,
24
+ QVBoxLayout,
25
+ QHBoxLayout,
26
+ QGridLayout,
27
+ QStackedLayout,
28
+ QGroupBox,
29
+ QWidget,
30
+ QSpacerItem,
31
+ QSizePolicy
32
+ )
33
+
34
+ class Graphics(Handler):
35
+
36
+ class MainWindow(QMainWindow):
37
+
38
+ def __init__(self):
39
+ super().__init__()
40
+
41
+ def __init__(self, compiler):
42
+ Handler.__init__(self, compiler)
43
+
44
+ def getName(self):
45
+ return 'pyside6'
46
+
47
+ def closeEvent(self):
48
+ print('window closed')
49
+
50
+ #############################################################################
51
+ # Keyword handlers
52
+
53
+ # Add a widget to a layout
54
+ # add [stretch] {widget} to {layout}
55
+ # add stretch to {layout}
56
+ def k_add(self, command):
57
+ command['stretch'] = False
58
+ if self.nextIs('stretch'):
59
+ if self.peek() == 'to':
60
+ command['widget'] = 'stretch'
61
+ elif self.nextIsSymbol():
62
+ record = self.getSymbolRecord()
63
+ command['widget'] = record['name']
64
+ command['stretch'] = True
65
+ else: return False
66
+ elif self.isSymbol():
67
+ record = self.getSymbolRecord()
68
+ command['widget'] = record['name']
69
+ else: return False
70
+ if self.nextIs('to'):
71
+ if self.nextIsSymbol():
72
+ record = self.getSymbolRecord()
73
+ command['layout'] = record['name']
74
+ self.add(command)
75
+ return True
76
+ return False
77
+
78
+ def r_add(self, command):
79
+ layoutRecord = self.getVariable(command['layout'])
80
+ widget = command['widget']
81
+ if widget == 'stretch':
82
+ layoutRecord['widget'].addStretch()
83
+ else:
84
+ widgetRecord = self.getVariable(widget)
85
+ layoutRecord = self.getVariable(command['layout'])
86
+ widget = widgetRecord['widget']
87
+ layout = layoutRecord['widget']
88
+ stretch = command['stretch']
89
+ if widgetRecord['keyword'] == 'layout':
90
+ if layoutRecord['keyword'] == 'groupbox':
91
+ if widgetRecord['keyword'] == 'layout':
92
+ layout.setLayout(widget)
93
+ else:
94
+ RuntimeError(self.program, 'Can only add a layout to a groupbox')
95
+ else:
96
+ if stretch: layout.addLayout(widget, stretch=1)
97
+ else: layout.addLayout(widget)
98
+ else:
99
+ if stretch: layout.addWidget(widget, stretch=1)
100
+ else: layout.addWidget(widget)
101
+ return self.nextPC()
102
+
103
+ # Declare a checkbox variable
104
+ def k_checkbox(self, command):
105
+ return self.compileVariable(command, False)
106
+
107
+ def r_checkbox(self, command):
108
+ return self.nextPC()
109
+
110
+ # Close a window
111
+ def k_close(self, command):
112
+ if self.nextIsSymbol():
113
+ record = self.getSymbolRecord()
114
+ if record['keyword'] == 'window':
115
+ command['name'] = record['name']
116
+ self.add(command)
117
+ return True
118
+ return False
119
+
120
+ def r_close(self, command):
121
+ self.getVariable(command['name'])['window'].close()
122
+ return self.nextPC()
123
+
124
+ # Create a window
125
+ def k_createWindow(self, command):
126
+ command['title'] = 'Default'
127
+ command['x'] = self.compileConstant(100)
128
+ command['y'] = self.compileConstant(100)
129
+ command['w'] = self.compileConstant(640)
130
+ command['h'] = self.compileConstant(480)
131
+ while True:
132
+ token = self.peek()
133
+ if token in ['title', 'at', 'size']:
134
+ self.nextToken()
135
+ if token == 'title': command['title'] = self.nextValue()
136
+ elif token == 'at':
137
+ command['x'] = self.nextValue()
138
+ command['y'] = self.nextValue()
139
+ elif token == 'size':
140
+ command['w'] = self.nextValue()
141
+ command['h'] = self.nextValue()
142
+ else: break
143
+ self.add(command)
144
+ return True
145
+
146
+ # Create a widget
147
+ def k_createLayout(self, command):
148
+ if self.nextIs('type'):
149
+ command['type'] = self.nextToken()
150
+ self.add(command)
151
+ return True
152
+ return False
153
+
154
+ def k_createGroupBox(self, command):
155
+ if self.peek() == 'title':
156
+ self.nextToken()
157
+ title = self.nextValue()
158
+ else: title = ''
159
+ command['title'] = title
160
+ self.add(command)
161
+ return True
162
+
163
+ def k_createLabel(self, command):
164
+ text = ''
165
+ while True:
166
+ token = self.peek()
167
+ if token == 'text':
168
+ self.nextToken()
169
+ text = self.nextValue()
170
+ elif token == 'size':
171
+ self.nextToken()
172
+ command['size'] = self.nextValue()
173
+ else: break
174
+ command['text'] = text
175
+ self.add(command)
176
+ return True
177
+
178
+ def k_createPushbutton(self, command):
179
+ text = ''
180
+ while True:
181
+ token = self.peek()
182
+ if token == 'text':
183
+ self.nextToken()
184
+ text = self.nextValue()
185
+ elif token == 'size':
186
+ self.nextToken()
187
+ command['size'] = self.nextValue()
188
+ else: break
189
+ command['text'] = text
190
+ self.add(command)
191
+ return True
192
+
193
+ def k_createCheckBox(self, command):
194
+ if self.peek() == 'text':
195
+ self.nextToken()
196
+ text = self.nextValue()
197
+ else: text = ''
198
+ command['text'] = text
199
+ self.add(command)
200
+ return True
201
+
202
+ def k_createLineEdit(self, command):
203
+ if self.peek() == 'size':
204
+ self.nextToken()
205
+ size = self.nextValue()
206
+ else: size = 10
207
+ command['size'] = size
208
+ self.add(command)
209
+ return True
210
+
211
+ def k_createListWidget(self, command):
212
+ self.add(command)
213
+ return True
214
+
215
+ def k_create(self, command):
216
+ if self.nextIsSymbol():
217
+ record = self.getSymbolRecord()
218
+ command['name'] = record['name']
219
+ keyword = record['keyword']
220
+ if keyword == 'window': return self.k_createWindow(command)
221
+ elif keyword == 'layout': return self.k_createLayout(command)
222
+ elif keyword == 'groupbox': return self.k_createGroupBox(command)
223
+ elif keyword == 'label': return self.k_createLabel(command)
224
+ elif keyword == 'pushbutton': return self.k_createPushbutton(command)
225
+ elif keyword == 'checkbox': return self.k_createCheckBox(command)
226
+ elif keyword == 'lineinput': return self.k_createLineEdit(command)
227
+ elif keyword == 'listbox': return self.k_createListWidget(command)
228
+ return False
229
+
230
+ def r_createWindow(self, command, record):
231
+ window = self.MainWindow()
232
+ window.setWindowTitle(self.getRuntimeValue(command['title']))
233
+ x = self.getRuntimeValue(command['x'])
234
+ y = self.getRuntimeValue(command['y'])
235
+ w = self.getRuntimeValue(command['w'])
236
+ h = self.getRuntimeValue(command['h'])
237
+ window.setGeometry(x, y, w, h)
238
+ record['window'] = window
239
+ return self.nextPC()
240
+
241
+ def r_createLayout(self, command, record):
242
+ type = command['type']
243
+ if type == 'QHBoxLayout': layout = QHBoxLayout()
244
+ elif type == 'QGridLayout': layout = QGridLayout()
245
+ elif type == 'QStackedLayout': layout = QStackedLayout()
246
+ else: layout = QVBoxLayout()
247
+ layout.setContentsMargins(5,0,5,0)
248
+ record['widget'] = layout
249
+ return self.nextPC()
250
+
251
+ def r_createGroupBox(self, command, record):
252
+ groupbox = QGroupBox(self.getRuntimeValue(command['title']))
253
+ groupbox.setAlignment(Qt.AlignLeft)
254
+ record['widget'] = groupbox
255
+ return self.nextPC()
256
+
257
+ def r_createLabel(self, command, record):
258
+ label = QLabel(self.getRuntimeValue(command['text']))
259
+ if 'size' in command:
260
+ fm = label.fontMetrics()
261
+ c = label.contentsMargins()
262
+ w = fm.horizontalAdvance('x') * self.getRuntimeValue(command['size']) +c.left()+c.right()
263
+ label.setMaximumWidth(w)
264
+ record['widget'] = label
265
+ return self.nextPC()
266
+
267
+ def r_createPushbutton(self, command, record):
268
+ pushbutton = QPushButton(self.getRuntimeValue(command['text']))
269
+ if 'size' in command:
270
+ fm = pushbutton.fontMetrics()
271
+ c = pushbutton.contentsMargins()
272
+ w = fm.horizontalAdvance('x') * self.getRuntimeValue(command['size']) +c.left()+c.right()
273
+ pushbutton.setMaximumWidth(w)
274
+ record['widget'] = pushbutton
275
+ return self.nextPC()
276
+
277
+ def r_createCheckBox(self, command, record):
278
+ checkbox = QCheckBox(self.getRuntimeValue(command['text']))
279
+ record['widget'] = checkbox
280
+ return self.nextPC()
281
+
282
+ def r_createLineEdit(self, command, record):
283
+ lineinput = QLineEdit()
284
+ fm = lineinput.fontMetrics()
285
+ m = lineinput.textMargins()
286
+ c = lineinput.contentsMargins()
287
+ w = fm.horizontalAdvance('x') * self.getRuntimeValue(command['size']) +m.left()+m.right()+c.left()+c.right()
288
+ lineinput.setMaximumWidth(w)
289
+ record['widget'] = lineinput
290
+ return self.nextPC()
291
+
292
+ def r_createListWidget(self, command, record):
293
+ record['widget'] = QListWidget()
294
+ return self.nextPC()
295
+
296
+ def r_create(self, command):
297
+ record = self.getVariable(command['name'])
298
+ keyword = record['keyword']
299
+ if keyword == 'window': return self.r_createWindow(command, record)
300
+ elif keyword == 'layout': return self.r_createLayout(command, record)
301
+ elif keyword == 'groupbox': return self.r_createGroupBox(command, record)
302
+ elif keyword == 'label': return self.r_createLabel(command, record)
303
+ elif keyword == 'pushbutton': return self.r_createPushbutton(command, record)
304
+ elif keyword == 'checkbox': return self.r_createCheckBox(command, record)
305
+ elif keyword == 'lineinput': return self.r_createLineEdit(command, record)
306
+ elif keyword == 'listbox': return self.r_createListWidget(command, record)
307
+ return None
308
+
309
+ # Create a group box
310
+ def k_groupbox(self, command):
311
+ return self.compileVariable(command, False)
312
+
313
+ def r_groupbox(self, command):
314
+ return self.nextPC()
315
+
316
+ # Initialize the graphics environment
317
+ def k_init(self, command):
318
+ if self.nextIs('graphics'):
319
+ self.add(command)
320
+ return True
321
+ return False
322
+
323
+ def r_init(self, command):
324
+ self.app = QApplication(sys.argv)
325
+ return self.nextPC()
326
+
327
+ # Declare a label variable
328
+ def k_label(self, command):
329
+ return self.compileVariable(command, False)
330
+
331
+ def r_label(self, command):
332
+ return self.nextPC()
333
+
334
+ # Declare a layout variable
335
+ def k_layout(self, command):
336
+ return self.compileVariable(command, False)
337
+
338
+ def r_layout(self, command):
339
+ return self.nextPC()
340
+
341
+ # Declare a line input variable
342
+ def k_lineinput(self, command):
343
+ return self.compileVariable(command, False)
344
+
345
+ def r_lineinput(self, command):
346
+ return self.nextPC()
347
+
348
+ # Declare a listbox input variable
349
+ def k_listbox(self, command):
350
+ return self.compileVariable(command, False)
351
+
352
+ def r_listbox(self, command):
353
+ return self.nextPC()
354
+
355
+ # Handle events
356
+ def k_on(self, command):
357
+ if self.nextIs('click'):
358
+ if self.nextIsSymbol():
359
+ record = self.getSymbolRecord()
360
+ if record['keyword'] == 'pushbutton':
361
+ command['name'] = record['name']
362
+ command['goto'] = self.getPC() + 2
363
+ self.add(command)
364
+ self.nextToken()
365
+ # Step over the click handler
366
+ pcNext = self.getPC()
367
+ cmd = {}
368
+ cmd['domain'] = 'core'
369
+ cmd['lino'] = command['lino']
370
+ cmd['keyword'] = 'gotoPC'
371
+ cmd['goto'] = 0
372
+ cmd['debug'] = False
373
+ self.addCommand(cmd)
374
+ # This is the click handler
375
+ self.compileOne()
376
+ cmd = {}
377
+ cmd['domain'] = 'core'
378
+ cmd['lino'] = command['lino']
379
+ cmd['keyword'] = 'stop'
380
+ cmd['debug'] = False
381
+ self.addCommand(cmd)
382
+ # Fixup the link
383
+ self.getCommandAt(pcNext)['goto'] = self.getPC()
384
+ return True
385
+ return False
386
+
387
+ def r_on(self, command):
388
+ pushbutton = self.getVariable(command['name'])['widget']
389
+ pushbutton.clicked.connect(lambda: self.run(command['goto']))
390
+ return self.nextPC()
391
+
392
+ # Declare a pushbutton variable
393
+ def k_pushbutton(self, command):
394
+ return self.compileVariable(command, False)
395
+
396
+ def r_pushbutton(self, command):
397
+ return self.nextPC()
398
+
399
+ # Clean exit
400
+ def on_last_window_closed(self):
401
+ print("Last window closed! Performing cleanup...")
402
+ self.program.kill()
403
+
404
+ # This is called every 10ms to keep the main application running
405
+ def flush(self):
406
+ self.program.flushCB()
407
+
408
+ # Resume execution at the line following 'start graphics'
409
+ def resume(self):
410
+ self.program.flush(self.nextPC())
411
+
412
+ # Set something
413
+ def k_set(self, command):
414
+ token = self.nextToken()
415
+ if token == 'the': token = self.nextToken()
416
+ if token == 'height':
417
+ command['property'] = token
418
+ if self.nextToken() == 'of':
419
+ if self.nextIsSymbol():
420
+ record = self.getSymbolRecord()
421
+ keyword = record['keyword']
422
+ if keyword == 'groupbox':
423
+ command['name'] = record['name']
424
+ if self.nextIs('to'):
425
+ command['value'] = self.nextValue()
426
+ self.add(command)
427
+ return True
428
+ return False
429
+
430
+ def r_set(self, command):
431
+ property = command['property']
432
+ if property == 'height':
433
+ groupbox = self.getVariable(command['name'])['widget']
434
+ groupbox.setFixedHeight(self.getRuntimeValue(command['value']))
435
+ return self.nextPC()
436
+
437
+ # Show a window with a specified layout
438
+ # show {name} in {window}}
439
+ def k_show(self, command):
440
+ if self.nextIsSymbol():
441
+ record = self.getSymbolRecord()
442
+ if record['keyword'] == 'layout':
443
+ command['layout'] = record['name']
444
+ if self.nextIs('in'):
445
+ if self.nextIsSymbol():
446
+ record = self.getSymbolRecord()
447
+ if record['keyword'] == 'window':
448
+ command['window'] = record['name']
449
+ self.add(command)
450
+ return True
451
+ return False
452
+
453
+ def r_show(self, command):
454
+ layoutRecord = self.getVariable(command['layout'])
455
+ windowRecord = self.getVariable(command['window'])
456
+ window = windowRecord['window']
457
+ container = QWidget()
458
+ container.setLayout(layoutRecord['widget'])
459
+ window.setCentralWidget(container)
460
+ window.show()
461
+ return self.nextPC()
462
+
463
+ # Start the graphics
464
+ def k_start(self, command):
465
+ if self.nextIs('graphics'):
466
+ self.add(command)
467
+ return True
468
+ return False
469
+
470
+ def r_start(self, command):
471
+ timer = QTimer()
472
+ timer.timeout.connect(self.flush)
473
+ timer.start(10)
474
+ QTimer.singleShot(500, self.resume)
475
+ self.app.lastWindowClosed.connect(self.on_last_window_closed)
476
+ self.app.exec()
477
+
478
+ # Declare a window variable
479
+ def k_window(self, command):
480
+ return self.compileVariable(command, False)
481
+
482
+ def r_window(self, command):
483
+ return self.nextPC()
484
+
485
+ #############################################################################
486
+ # Compile a value in this domain
487
+ def compileValue(self):
488
+ value = {}
489
+ value['domain'] = 'rbr'
490
+ if self.tokenIs('the'):
491
+ self.nextToken()
492
+ token = self.getToken()
493
+ if token == 'xxxxx':
494
+ return value
495
+
496
+ return None
497
+
498
+ #############################################################################
499
+ # Modify a value or leave it unchanged.
500
+ def modifyValue(self, value):
501
+ return value
502
+
503
+ #############################################################################
504
+ # Value handlers
505
+
506
+ def v_xxxxx(self, v):
507
+ value = {}
508
+ return value
509
+
510
+ #############################################################################
511
+ # Compile a condition
512
+ def compileCondition(self):
513
+ condition = {}
514
+ return condition
515
+
516
+ #############################################################################
517
+ # Condition handlers
@@ -1,13 +1,13 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.3
2
2
  Name: easycoder
3
- Version: 250406.1
3
+ Version: 250422.3
4
4
  Summary: Rapid scripting in English
5
5
  Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
6
6
  Author-email: Graham Trott <gtanyware@gmail.com>
7
7
  Description-Content-Type: text/markdown
8
8
  Classifier: License :: OSI Approved :: MIT License
9
- License-File: LICENSE
10
9
  Requires-Dist: pytz
10
+ Requires-Dist: pyside6
11
11
  Project-URL: Home, https://github.com/easycoder/easycoder-py
12
12
 
13
13
  # Introduction
@@ -84,18 +84,7 @@ Here in the repository is a folder called `scripts` containing some sample scrip
84
84
  `benchmark.ecs` allows the performance of **_EasyCoder_** to be compared to other languages if a similar script is written for each one.
85
85
 
86
86
  ## Graphical programming
87
- **_EasyCoder_** includes a graphical programming environment that is in the early stages of development. Some demo scripts will be included in the `scripts` directory; these can be recognised by the extension`.ecg`. To run them, first install `tkinter`. On Linux this is done with
88
- ```
89
- sudo apt install python3-tk
90
- ```
91
-
92
- Next, install the Python `pySimpleGUI` graphics library; this is done with `pip install pysimplegui`. Then run your **_EasyCoder_** script using `easycoder {scriptname}.ecg`.
93
-
94
- Graphical scripts look much like any other script but their file names must use the extension `.ecg` to signal to **_EasyCoder_** that it needs to load the graphics module. Non-graphical applications can use any extension but `.ecs` is recommended. This allows the **_EasyCoder_** application to be used wherever Python is installed, in either a command-line or a graphical environment, but graphics will of course not be available in the former.
95
-
96
- Some demo graphical scripts will included in the `scripts` directory as development proceeds.
97
-
98
- `gtest.ecg` contains sample code to demonstrate and test basic features.
87
+ **_EasyCoder_** includes a graphical programming environment based on PySide6, that is in the early stages of development. Some demo scripts will be included in the `scripts` directory as development proceeds.
99
88
 
100
89
  ## Significant features
101
90
 
@@ -1,17 +1,18 @@
1
1
  easycoder/README.md,sha256=BVXmYphcTJ6q6RN_9L6HtQukgCnOjSLVIsTM3lk-9aM,587
2
- easycoder/__init__.py,sha256=CzZqrjSXsFgsbCCRQNz3RoLfvo0k76aLwK8m3pci754,262
2
+ easycoder/__init__.py,sha256=HAdBM4aowyailw2NexqgELS6KF9_8A6QEnCYy1FghmY,262
3
3
  easycoder/ec_classes.py,sha256=xnWBNak8oKydkFoxHLlq9wo3lIsB3aMnTDrqbtCfoWo,1512
4
4
  easycoder/ec_compiler.py,sha256=rtxFEWnhW0550MtWEDvYHOw9cYkeTcR0oG3t-kmgnBk,4795
5
5
  easycoder/ec_condition.py,sha256=YXvSBQKEzKGCcgUGo3Qp8iHolXmm2BpEm0NimSDszIM,785
6
- easycoder/ec_core.py,sha256=1S6NxyDSvPqeuZzWB1ry3jySafvyn8mgFnrPKImmp70,90397
6
+ easycoder/ec_core.py,sha256=-nSX_KA_VBximHI1GIuXA-FhsqcyTNp9-HFrv6Dy64M,90625
7
7
  easycoder/ec_graphics.py,sha256=ScGLNxW_sxu0WyoO-Od-9MM0bhpVvf-vGa5UmoHYRCA,16073
8
8
  easycoder/ec_gutils.py,sha256=yqu4RRQ6VdRkC5B2ADBYsXzgNu76dLnekd9aUjdEgPw,6399
9
9
  easycoder/ec_handler.py,sha256=K7nBuQTH8l0k8hX1o2b4KhTnhZHGdf2fkEuX4FJXJs8,2277
10
10
  easycoder/ec_program.py,sha256=BDwU7aGHiaw6WdbQvVFDhGVaHsvwQ1CWa4wb5MPmOe8,10013
11
+ easycoder/ec_pyside6.py,sha256=OOj7ikQbGQqi1wZ8VaNcX0yZUrN0KkVzZGPGbKlyGDo,17583
11
12
  easycoder/ec_timestamp.py,sha256=_3QFJPzIWZ9Rzk3SQOQJ-gwmvB07pg78k23SPntoZtY,288
12
13
  easycoder/ec_value.py,sha256=zgDJTJhIg3yOvmnnKIfccIizmIhGbtvL_ghLTL1T5fg,2516
13
- easycoder-250406.1.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
14
- easycoder-250406.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
15
- easycoder-250406.1.dist-info/WHEEL,sha256=Dyt6SBfaasWElUrURkknVFAZDHSTwxg3PaTza7RSbkY,100
16
- easycoder-250406.1.dist-info/METADATA,sha256=CobU9Wrd-r7tEkMS4Q3jQnltrmtK5iWWSXybW8NUyGw,6520
17
- easycoder-250406.1.dist-info/RECORD,,
14
+ easycoder-250422.3.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
15
+ easycoder-250422.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
+ easycoder-250422.3.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
17
+ easycoder-250422.3.dist-info/METADATA,sha256=40jnSopPCKhQMtl0N_9Hka9LT7CVXI-TV0q0DeyIQ0A,5617
18
+ easycoder-250422.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: flit 3.12.0
2
+ Generator: flit 3.10.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any