lazylabel-gui 1.1.8__py3-none-any.whl → 1.1.9__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.
@@ -3,6 +3,7 @@
3
3
  from .adjustments_widget import AdjustmentsWidget
4
4
  from .border_crop_widget import BorderCropWidget
5
5
  from .channel_threshold_widget import ChannelThresholdWidget
6
+ from .fft_threshold_widget import FFTThresholdWidget
6
7
  from .fragment_threshold_widget import FragmentThresholdWidget
7
8
  from .model_selection_widget import ModelSelectionWidget
8
9
  from .settings_widget import SettingsWidget
@@ -12,6 +13,7 @@ __all__ = [
12
13
  "AdjustmentsWidget",
13
14
  "BorderCropWidget",
14
15
  "ChannelThresholdWidget",
16
+ "FFTThresholdWidget",
15
17
  "FragmentThresholdWidget",
16
18
  "ModelSelectionWidget",
17
19
  "SettingsWidget",
@@ -0,0 +1,392 @@
1
+ """
2
+ FFT Threshold Widget for LazyLabel.
3
+
4
+ This widget provides FFT-based thresholding for single channel images.
5
+ It includes frequency band thresholding and intensity thresholding.
6
+ Users can double-click to add threshold points for both frequency and intensity processing.
7
+ """
8
+
9
+ import numpy as np
10
+ from PyQt6.QtCore import pyqtSignal
11
+ from PyQt6.QtWidgets import (
12
+ QCheckBox,
13
+ QGroupBox,
14
+ QLabel,
15
+ QVBoxLayout,
16
+ QWidget,
17
+ )
18
+ from scipy.fft import fft2, fftshift, ifft2
19
+
20
+ # Import MultiIndicatorSlider from channel threshold widget
21
+ from .channel_threshold_widget import MultiIndicatorSlider
22
+
23
+
24
+ class FFTThresholdSlider(MultiIndicatorSlider):
25
+ """Custom slider for FFT thresholds that allows removing all indicators."""
26
+
27
+ def contextMenuEvent(self, event):
28
+ """Handle right-click to remove indicator (allows removing all indicators)."""
29
+ from PyQt6.QtCore import QRect
30
+
31
+ slider_rect = self.get_slider_rect()
32
+
33
+ # Allow removal of any indicator (no minimum constraint)
34
+ # Check if right-clicking on an indicator
35
+ for i, value in enumerate(self.indicators):
36
+ x = self.value_to_x(value)
37
+ handle_rect = QRect(
38
+ x - 6, slider_rect.top() - 3, 12, slider_rect.height() + 6
39
+ )
40
+
41
+ if handle_rect.contains(event.pos()):
42
+ self.indicators.pop(i)
43
+ self.valueChanged.emit(self.indicators[:])
44
+ self.update()
45
+ return
46
+
47
+
48
+ class FFTThresholdWidget(QWidget):
49
+ """Widget for FFT-based thresholding of single channel images."""
50
+
51
+ fft_threshold_changed = pyqtSignal() # Emitted when FFT threshold changes
52
+ dragStarted = pyqtSignal() # Emitted when slider drag starts
53
+ dragFinished = pyqtSignal() # Emitted when slider drag finishes
54
+
55
+ def __init__(self, parent=None):
56
+ super().__init__(parent)
57
+ self.current_image_channels = (
58
+ 0 # 0 = no image, 1 = grayscale, 3+ = not supported
59
+ )
60
+ self.frequency_thresholds = [] # List of frequency threshold percentages (0-100)
61
+ self.intensity_thresholds = [] # List of intensity threshold percentages (0-100)
62
+ self._setup_ui()
63
+ self._connect_signals()
64
+
65
+ def _setup_ui(self):
66
+ """Setup the UI layout."""
67
+ group = QGroupBox("FFT Frequency Band Thresholding")
68
+ layout = QVBoxLayout(group)
69
+ layout.setSpacing(8)
70
+
71
+ # Enable checkbox
72
+ self.enable_checkbox = QCheckBox("Enable FFT Frequency Thresholding")
73
+ self.enable_checkbox.setChecked(False)
74
+ layout.addWidget(self.enable_checkbox)
75
+
76
+ # Status label
77
+ self.status_label = QLabel("Load a single channel (grayscale) image")
78
+ self.status_label.setStyleSheet(
79
+ "color: #888; font-size: 9px; font-style: italic;"
80
+ )
81
+ layout.addWidget(self.status_label)
82
+
83
+ # Frequency threshold slider (percentage-based)
84
+ freq_label = QLabel("Frequency Thresholds (Double-click to add):")
85
+ freq_label.setStyleSheet("font-weight: bold; margin-top: 5px;")
86
+ layout.addWidget(freq_label)
87
+
88
+ self.frequency_slider = FFTThresholdSlider(
89
+ channel_name="Frequency Bands", minimum=0, maximum=100, parent=self
90
+ )
91
+ self.frequency_slider.setEnabled(False)
92
+ self.frequency_slider.setToolTip(
93
+ "Double-click to add frequency cutoff points. Each frequency band gets mapped to a different intensity level."
94
+ )
95
+ layout.addWidget(self.frequency_slider)
96
+
97
+ # Intensity threshold slider (percentage-based)
98
+ intensity_label = QLabel("Intensity Thresholds (Double-click to add):")
99
+ intensity_label.setStyleSheet("font-weight: bold; margin-top: 10px;")
100
+ layout.addWidget(intensity_label)
101
+
102
+ self.intensity_slider = FFTThresholdSlider(
103
+ channel_name="Intensity Levels", minimum=0, maximum=100, parent=self
104
+ )
105
+ self.intensity_slider.setEnabled(False)
106
+ self.intensity_slider.setToolTip(
107
+ "Double-click to add intensity threshold points. Applied after frequency band processing."
108
+ )
109
+ layout.addWidget(self.intensity_slider)
110
+
111
+ # Instructions
112
+ instructions = QLabel(
113
+ "1. Add frequency thresholds to create bands: low freq → dark, high freq → bright.\n"
114
+ "2. Add intensity thresholds to further process the result with quantization levels."
115
+ )
116
+ instructions.setStyleSheet("color: #888; font-size: 9px;")
117
+ instructions.setWordWrap(True)
118
+ layout.addWidget(instructions)
119
+
120
+ # Main layout
121
+ main_layout = QVBoxLayout(self)
122
+ main_layout.setContentsMargins(0, 0, 0, 0)
123
+ main_layout.addWidget(group)
124
+
125
+ def _connect_signals(self):
126
+ """Connect internal signals."""
127
+ # Enable checkbox connection
128
+ self.enable_checkbox.toggled.connect(self._on_enable_checkbox_toggled)
129
+
130
+ # Frequency threshold connections
131
+ self.frequency_slider.valueChanged.connect(self._on_frequency_slider_changed)
132
+ self.frequency_slider.dragStarted.connect(self.dragStarted.emit)
133
+ self.frequency_slider.dragFinished.connect(self.dragFinished.emit)
134
+
135
+ # Intensity threshold connections
136
+ self.intensity_slider.valueChanged.connect(self._on_intensity_slider_changed)
137
+ self.intensity_slider.dragStarted.connect(self.dragStarted.emit)
138
+ self.intensity_slider.dragFinished.connect(self.dragFinished.emit)
139
+
140
+ def _on_enable_checkbox_toggled(self, checked):
141
+ """Handle enable checkbox toggle."""
142
+ # Enable/disable controls based on checkbox state
143
+ self.frequency_slider.setEnabled(checked)
144
+ self.intensity_slider.setEnabled(checked)
145
+
146
+ # If unchecking, optionally reset the thresholds
147
+ if not checked:
148
+ self.frequency_slider.reset() # Clear frequency threshold indicators
149
+ self.intensity_slider.reset() # Clear intensity threshold indicators
150
+ self.frequency_thresholds = [] # Clear stored thresholds
151
+ self.intensity_thresholds = [] # Clear stored thresholds
152
+
153
+ # Always emit change signal when checkbox is toggled (both check and uncheck)
154
+ # This ensures the image refreshes to show/remove thresholding
155
+ self.fft_threshold_changed.emit()
156
+
157
+ def _on_frequency_slider_changed(self, indicators):
158
+ """Handle frequency threshold slider change (receives list of threshold indicators)."""
159
+ # Store the frequency threshold indicators (percentages 0-100)
160
+ self.frequency_thresholds = indicators[:] # Copy the list
161
+ self._emit_change_if_active()
162
+
163
+ def _on_intensity_slider_changed(self, indicators):
164
+ """Handle intensity threshold slider change (receives list of threshold indicators)."""
165
+ # Store the intensity threshold indicators (percentages 0-100)
166
+ self.intensity_thresholds = indicators[:] # Copy the list
167
+ self._emit_change_if_active()
168
+
169
+ def _emit_change_if_active(self):
170
+ """Emit change signal if FFT processing is active."""
171
+ if self.is_active():
172
+ self.fft_threshold_changed.emit()
173
+
174
+ def update_fft_threshold_for_image(self, image_array):
175
+ """Update widget based on loaded image."""
176
+ if image_array is None:
177
+ self.current_image_channels = 0
178
+ self.status_label.setText("Load a single channel (grayscale) image")
179
+ self.status_label.setStyleSheet(
180
+ "color: #888; font-size: 9px; font-style: italic;"
181
+ )
182
+ return
183
+
184
+ # Determine if image is grayscale (single channel or 3-channel with identical values)
185
+ if len(image_array.shape) == 2:
186
+ # True grayscale - supported
187
+ self.current_image_channels = 1
188
+ self.status_label.setText("✓ Grayscale image - FFT processing available")
189
+ self.status_label.setStyleSheet(
190
+ "color: #4CAF50; font-size: 9px; font-style: italic;"
191
+ )
192
+ elif len(image_array.shape) == 3 and image_array.shape[2] == 3:
193
+ # Check if all three channels are identical (grayscale stored as RGB)
194
+ r_channel = image_array[:, :, 0]
195
+ g_channel = image_array[:, :, 1]
196
+ b_channel = image_array[:, :, 2]
197
+ if np.array_equal(r_channel, g_channel) and np.array_equal(
198
+ g_channel, b_channel
199
+ ):
200
+ # Grayscale stored as RGB - supported
201
+ self.current_image_channels = 1
202
+ self.status_label.setText(
203
+ "✓ Grayscale image (RGB format) - FFT processing available"
204
+ )
205
+ self.status_label.setStyleSheet(
206
+ "color: #4CAF50; font-size: 9px; font-style: italic;"
207
+ )
208
+ else:
209
+ # True multi-channel - not supported
210
+ self.current_image_channels = 3
211
+ self.status_label.setText(
212
+ "❌ Multi-channel color image - not supported"
213
+ )
214
+ self.status_label.setStyleSheet(
215
+ "color: #F44336; font-size: 9px; font-style: italic;"
216
+ )
217
+ else:
218
+ # Unknown format
219
+ self.current_image_channels = 0
220
+ self.status_label.setText("❌ Unsupported image format")
221
+ self.status_label.setStyleSheet(
222
+ "color: #F44336; font-size: 9px; font-style: italic;"
223
+ )
224
+
225
+ def is_active(self):
226
+ """Check if FFT processing is active (checkbox enabled and image is grayscale)."""
227
+ return self.enable_checkbox.isChecked() and self.current_image_channels == 1
228
+
229
+ def apply_fft_thresholding(self, image_array):
230
+ """Apply frequency band thresholding to image array and return modified array."""
231
+ if not self.is_active() or image_array is None:
232
+ return image_array
233
+
234
+ # Handle both 2D grayscale and 3D grayscale (stored as RGB) images
235
+ if len(image_array.shape) == 2:
236
+ # True grayscale
237
+ processing_image = image_array
238
+ is_3channel = False
239
+ elif len(image_array.shape) == 3 and image_array.shape[2] == 3:
240
+ # Check if it's grayscale stored as RGB
241
+ r_channel = image_array[:, :, 0]
242
+ g_channel = image_array[:, :, 1]
243
+ b_channel = image_array[:, :, 2]
244
+ if np.array_equal(r_channel, g_channel) and np.array_equal(
245
+ g_channel, b_channel
246
+ ):
247
+ # Convert to 2D for processing
248
+ processing_image = image_array[:, :, 0]
249
+ is_3channel = True
250
+ else:
251
+ return image_array
252
+ else:
253
+ return image_array
254
+
255
+ try:
256
+ result_image = self._apply_frequency_band_thresholding(processing_image)
257
+
258
+ # Convert back to original format if needed
259
+ if is_3channel:
260
+ result = np.stack([result_image, result_image, result_image], axis=2)
261
+ else:
262
+ result = result_image
263
+
264
+ return result
265
+
266
+ except Exception:
267
+ # If FFT processing fails, return original image
268
+ return image_array
269
+
270
+ def _apply_frequency_band_thresholding(self, image_array):
271
+ """Apply frequency band thresholding with multiple frequency cutoffs."""
272
+ # Convert to float for processing
273
+ image_float = image_array.astype(np.float64)
274
+ height, width = image_float.shape
275
+
276
+ # Apply FFT
277
+ fft_image = fft2(image_float)
278
+ fft_shifted = fftshift(fft_image)
279
+
280
+ # Create frequency coordinate arrays (normalized 0-1)
281
+ y_coords, x_coords = np.ogrid[:height, :width]
282
+ center_y, center_x = height // 2, width // 2
283
+
284
+ # Calculate distance from center (frequency magnitude)
285
+ max_freq = np.sqrt((height / 2) ** 2 + (width / 2) ** 2)
286
+ freq_distance = (
287
+ np.sqrt((y_coords - center_y) ** 2 + (x_coords - center_x) ** 2) / max_freq
288
+ )
289
+ freq_distance = np.clip(freq_distance, 0, 1) # Normalize to 0-1
290
+
291
+ if not self.frequency_thresholds:
292
+ # No frequency thresholds - use original FFT
293
+ result_fft = fft_shifted
294
+ else:
295
+ # Create frequency bands based on thresholds
296
+ sorted_thresholds = sorted(self.frequency_thresholds)
297
+ freq_thresholds_normalized = [
298
+ t / 100.0 for t in sorted_thresholds
299
+ ] # Convert to 0-1
300
+
301
+ # Number of bands = number of thresholds + 1
302
+ num_bands = len(freq_thresholds_normalized) + 1
303
+ result_fft = np.zeros_like(fft_shifted, dtype=complex)
304
+
305
+ for band_idx in range(num_bands):
306
+ # Define frequency band
307
+ if band_idx == 0:
308
+ # First band: 0 to first threshold
309
+ band_mask = freq_distance <= freq_thresholds_normalized[0]
310
+ elif band_idx == num_bands - 1:
311
+ # Last band: last threshold to 1
312
+ band_mask = freq_distance > freq_thresholds_normalized[band_idx - 1]
313
+ else:
314
+ # Middle bands: between two thresholds
315
+ band_mask = (
316
+ freq_distance > freq_thresholds_normalized[band_idx - 1]
317
+ ) & (freq_distance <= freq_thresholds_normalized[band_idx])
318
+
319
+ # Band intensity (evenly distributed)
320
+ band_intensity = (band_idx / (num_bands - 1)) if num_bands > 1 else 1.0
321
+
322
+ # Apply band contribution
323
+ result_fft += fft_shifted * band_mask * band_intensity
324
+
325
+ # Inverse FFT
326
+ filtered_fft_unshifted = fftshift(result_fft)
327
+ filtered_image = np.real(ifft2(filtered_fft_unshifted))
328
+
329
+ # Normalize to 0-255 range
330
+ filtered_image = filtered_image - np.min(filtered_image)
331
+ if np.max(filtered_image) > 0:
332
+ filtered_image = filtered_image / np.max(filtered_image) * 255
333
+
334
+ result_image = filtered_image.astype(np.uint8)
335
+
336
+ # Apply intensity thresholding if specified
337
+ if self.intensity_thresholds:
338
+ result_image = self._apply_intensity_thresholding(result_image)
339
+
340
+ return result_image
341
+
342
+ def _apply_intensity_thresholding(self, image_array):
343
+ """Apply intensity thresholding to the image array."""
344
+ sorted_thresholds = sorted(self.intensity_thresholds)
345
+
346
+ # If no thresholds, return original
347
+ if not sorted_thresholds:
348
+ return image_array
349
+
350
+ # Convert thresholds from percentages to intensity values (0-255)
351
+ intensity_thresholds = [t * 255 / 100.0 for t in sorted_thresholds]
352
+
353
+ # Number of levels = number of thresholds + 1
354
+ num_levels = len(intensity_thresholds) + 1
355
+ result_image = np.copy(image_array)
356
+
357
+ for level_idx in range(num_levels):
358
+ # Define intensity range for this level
359
+ if level_idx == 0:
360
+ # First level: 0 to first threshold
361
+ mask = image_array <= intensity_thresholds[0]
362
+ elif level_idx == num_levels - 1:
363
+ # Last level: last threshold to 255
364
+ mask = image_array > intensity_thresholds[level_idx - 1]
365
+ else:
366
+ # Middle levels: between two thresholds
367
+ mask = (image_array > intensity_thresholds[level_idx - 1]) & (
368
+ image_array <= intensity_thresholds[level_idx]
369
+ )
370
+
371
+ # Map to quantized level (evenly distributed)
372
+ level_value = (
373
+ (level_idx / (num_levels - 1)) * 255 if num_levels > 1 else 255
374
+ )
375
+ result_image[mask] = level_value
376
+
377
+ return result_image.astype(np.uint8)
378
+
379
+ def get_settings(self):
380
+ """Get current FFT threshold settings."""
381
+ return {
382
+ "frequency_thresholds": self.frequency_thresholds,
383
+ "intensity_thresholds": self.intensity_thresholds,
384
+ "is_active": self.is_active(),
385
+ }
386
+
387
+ def reset(self):
388
+ """Reset to default values."""
389
+ self.frequency_slider.reset() # Reset the frequency slider
390
+ self.intensity_slider.reset() # Reset the intensity slider
391
+ self.frequency_thresholds = []
392
+ self.intensity_thresholds = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lazylabel-gui
3
- Version: 1.1.8
3
+ Version: 1.1.9
4
4
  Summary: An image segmentation GUI for generating ML ready mask tensors and annotations.
5
5
  Author-email: "Deniz N. Cakan" <deniz.n.cakan@gmail.com>
6
6
  License: MIT License
@@ -12,20 +12,21 @@ lazylabel/core/segment_manager.py,sha256=M6kHcYeiub3WqL01NElCvKOc2GNmf72LUM1W8Xw
12
12
  lazylabel/models/__init__.py,sha256=fIlk_0DuZfiClcm0XlZdimeHzunQwBmTMI4PcGsaymw,91
13
13
  lazylabel/models/sam_model.py,sha256=anh4XMkoX8U5MCZHV5HqN0x8iVnRYi50rcXFt6LdFCQ,8020
14
14
  lazylabel/ui/__init__.py,sha256=4qDIh9y6tABPmD8MAMGZn_G7oSRyrcHt2HkjoWgbGH4,268
15
- lazylabel/ui/control_panel.py,sha256=B8A4J2YTCNrpwLEAQx0IwteiSJgxZgbipodT1VeclTY,29571
15
+ lazylabel/ui/control_panel.py,sha256=IvGtL-Z-WOpo9q-owhwBSB-DSwXaDubec2ajLRMoyFk,31322
16
16
  lazylabel/ui/editable_vertex.py,sha256=nAFC2UuFfbvMbGBbAiLWA77cS5-Hn3a08xe1_QLz2yk,2449
17
17
  lazylabel/ui/hotkey_dialog.py,sha256=U_B76HLOxWdWkfA4d2XgRUaZTJPAAE_m5fmwf7Rh-5Y,14743
18
18
  lazylabel/ui/hoverable_pixelmap_item.py,sha256=kJFOp7WXiyHpNf7l73TZjiob85jgP30b5MZvu_z5L3c,728
19
19
  lazylabel/ui/hoverable_polygon_item.py,sha256=aclUwd0P8H8xbcep6GwhnfaVs1zSkqeZKAL-xeDyMiU,1222
20
- lazylabel/ui/main_window.py,sha256=2L1u6SUVdeKGwsaStwstGEO-vzTW5mrbJguvOzrfbos,122093
20
+ lazylabel/ui/main_window.py,sha256=R7QpEY3kEhxTm_bYYJDpmF1zUgvEwU9UxLwPkduCgkU,128160
21
21
  lazylabel/ui/numeric_table_widget_item.py,sha256=dQUlIFu9syCxTGAHVIlmbgkI7aJ3f3wmDPBz1AGK9Bg,283
22
22
  lazylabel/ui/photo_viewer.py,sha256=f93Mn9ajR2CYakJbbhhHvD5blKrwiGq3ZYgro-k2npc,4217
23
23
  lazylabel/ui/reorderable_class_table.py,sha256=sxHhQre5O_MXLDFgKnw43QnvXXoqn5xRKMGitgO7muI,2371
24
24
  lazylabel/ui/right_panel.py,sha256=-PeXcu7Lr-xhZniBMvWLDPiFb_RAHYAcILyw8fPJs6I,13139
25
- lazylabel/ui/widgets/__init__.py,sha256=h9JNrmRPqGA38-hJ_hOX7aAPWmmCTwzWtDCr18fvnr8,607
25
+ lazylabel/ui/widgets/__init__.py,sha256=6VDoMnanqVm3yjOovxie3WggPODuhUsIO75RtxOhQhI,688
26
26
  lazylabel/ui/widgets/adjustments_widget.py,sha256=hQt0LC3hOM0qJn0KKLM5zMcnn8cSl1sxNv7Mo6ON8Ow,12695
27
27
  lazylabel/ui/widgets/border_crop_widget.py,sha256=VdgSxQQOREnXsCKBOBF36UbbAtwPO7fw5M7LpQADMGs,7100
28
28
  lazylabel/ui/widgets/channel_threshold_widget.py,sha256=PNz1S8a283F_lkMi5o5leoHp99IP8Htdj_mmJZCLIYc,18726
29
+ lazylabel/ui/widgets/fft_threshold_widget.py,sha256=F1NfRVJiimuat5Wbt6NNOlBuObNC1BQPsipb86RGX6w,16730
29
30
  lazylabel/ui/widgets/fragment_threshold_widget.py,sha256=YtToua1eAUtEuJ3EwdCMvI-39TRrFnshkty4tnR4OMU,3492
30
31
  lazylabel/ui/widgets/model_selection_widget.py,sha256=7MA9L1VKjzEAA7BJl2BAbZRSCRFJeGX5xQb-_LO9_eQ,4449
31
32
  lazylabel/ui/widgets/settings_widget.py,sha256=ShTaLJeXxwrSuTV4kmtV2JiWjfREil2D1nvPUIfAgDs,4859
@@ -34,9 +35,9 @@ lazylabel/utils/__init__.py,sha256=V6IR5Gim-39HgM2NyTVT-n8gy3mjilCSFW9y0owN5nc,1
34
35
  lazylabel/utils/custom_file_system_model.py,sha256=-3EimlybvevH6bvqBE0qdFnLADVtayylmkntxPXK0Bk,4869
35
36
  lazylabel/utils/logger.py,sha256=R7z6ifgA-NY-9ZbLlNH0i19zzwXndJ_gkG2J1zpVEhg,1306
36
37
  lazylabel/utils/utils.py,sha256=sYSCoXL27OaLgOZaUkCAhgmKZ7YfhR3Cc5F8nDIa3Ig,414
37
- lazylabel_gui-1.1.8.dist-info/licenses/LICENSE,sha256=kSDEIgrWAPd1u2UFGGpC9X71dhzrlzBFs8hbDlENnGE,1092
38
- lazylabel_gui-1.1.8.dist-info/METADATA,sha256=yVq9bxi6OiInMJu4boIB326KdNXeciP4XpE9LKj-dvU,8064
39
- lazylabel_gui-1.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
- lazylabel_gui-1.1.8.dist-info/entry_points.txt,sha256=Hd0WwEG9OPTa_ziYjiD0aRh7R6Fupt-wdQ3sspdc1mM,54
41
- lazylabel_gui-1.1.8.dist-info/top_level.txt,sha256=YN4uIyrpDBq1wiJaBuZLDipIzyZY0jqJOmmXiPIOUkU,10
42
- lazylabel_gui-1.1.8.dist-info/RECORD,,
38
+ lazylabel_gui-1.1.9.dist-info/licenses/LICENSE,sha256=kSDEIgrWAPd1u2UFGGpC9X71dhzrlzBFs8hbDlENnGE,1092
39
+ lazylabel_gui-1.1.9.dist-info/METADATA,sha256=MjH3jrF3QDAOKiGUpuA3vIBJPTjAM4jax88hJdojKlw,8064
40
+ lazylabel_gui-1.1.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
+ lazylabel_gui-1.1.9.dist-info/entry_points.txt,sha256=Hd0WwEG9OPTa_ziYjiD0aRh7R6Fupt-wdQ3sspdc1mM,54
42
+ lazylabel_gui-1.1.9.dist-info/top_level.txt,sha256=YN4uIyrpDBq1wiJaBuZLDipIzyZY0jqJOmmXiPIOUkU,10
43
+ lazylabel_gui-1.1.9.dist-info/RECORD,,