coralnet-toolbox 0.0.71__py2.py3-none-any.whl → 0.0.72__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.
- coralnet_toolbox/Annotations/QtRectangleAnnotation.py +31 -2
- coralnet_toolbox/Explorer/QtDataItem.py +52 -20
- coralnet_toolbox/Explorer/QtExplorer.py +439 -274
- coralnet_toolbox/Explorer/QtFeatureStore.py +15 -0
- coralnet_toolbox/Explorer/QtSettingsWidgets.py +3 -3
- coralnet_toolbox/QtAnnotationWindow.py +10 -2
- coralnet_toolbox/QtMainWindow.py +60 -0
- coralnet_toolbox/Tools/QtResizeSubTool.py +6 -1
- coralnet_toolbox/Tools/QtSelectTool.py +48 -6
- coralnet_toolbox/__init__.py +1 -1
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.72.dist-info}/METADATA +1 -1
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.72.dist-info}/RECORD +16 -16
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.72.dist-info}/WHEEL +0 -0
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.72.dist-info}/entry_points.txt +0 -0
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.72.dist-info}/licenses/LICENSE.txt +0 -0
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.72.dist-info}/top_level.txt +0 -0
@@ -149,6 +149,21 @@ class FeatureStore:
|
|
149
149
|
index_path = f"{self.index_path_base}_{model_key}.faiss"
|
150
150
|
print(f"Saving FAISS index for '{model_key}' to {index_path}")
|
151
151
|
faiss.write_index(index_to_save, index_path)
|
152
|
+
|
153
|
+
def remove_features_for_annotation(self, annotation_id):
|
154
|
+
"""
|
155
|
+
Removes an annotation's feature metadata from the SQLite database.
|
156
|
+
This effectively orphans the vector in the FAISS index, invalidating it.
|
157
|
+
"""
|
158
|
+
try:
|
159
|
+
self.cursor.execute(
|
160
|
+
"DELETE FROM features WHERE annotation_id = ?",
|
161
|
+
(annotation_id,)
|
162
|
+
)
|
163
|
+
self.conn.commit()
|
164
|
+
print(f"Invalidated features for annotation_id: {annotation_id}")
|
165
|
+
except sqlite3.Error as e:
|
166
|
+
print(f"Error removing feature for annotation {annotation_id}: {e}")
|
152
167
|
|
153
168
|
def close(self):
|
154
169
|
"""Closes the database connection."""
|
@@ -670,8 +670,8 @@ class EmbeddingSettingsWidget(QGroupBox):
|
|
670
670
|
|
671
671
|
def apply_embedding(self):
|
672
672
|
if self.explorer_window and hasattr(self.explorer_window, 'run_embedding_pipeline'):
|
673
|
-
# Clear all selections before running embedding pipeline
|
674
|
-
if hasattr(self.explorer_window, '
|
675
|
-
self.explorer_window.
|
673
|
+
# Clear all selections before running a new embedding pipeline.
|
674
|
+
if hasattr(self.explorer_window, '_clear_selections'):
|
675
|
+
self.explorer_window._clear_selections()
|
676
676
|
|
677
677
|
self.explorer_window.run_embedding_pipeline()
|
@@ -48,6 +48,7 @@ class AnnotationWindow(QGraphicsView):
|
|
48
48
|
annotationSelected = pyqtSignal(int) # Signal to emit when annotation is selected
|
49
49
|
annotationDeleted = pyqtSignal(str) # Signal to emit when annotation is deleted
|
50
50
|
annotationCreated = pyqtSignal(str) # Signal to emit when annotation is created
|
51
|
+
annotationModified = pyqtSignal(str) # Signal to emit when annotation is modified
|
51
52
|
|
52
53
|
def __init__(self, main_window, parent=None):
|
53
54
|
"""Initialize the annotation window with the main window and parent widget."""
|
@@ -374,6 +375,9 @@ class AnnotationWindow(QGraphicsView):
|
|
374
375
|
|
375
376
|
def set_image(self, image_path):
|
376
377
|
"""Set and display an image at the given path."""
|
378
|
+
# Calculate GDIs for Windows if needed
|
379
|
+
self.main_window.check_windows_gdi_count()
|
380
|
+
|
377
381
|
# Clean up
|
378
382
|
self.clear_scene()
|
379
383
|
|
@@ -543,7 +547,7 @@ class AnnotationWindow(QGraphicsView):
|
|
543
547
|
return type(self.selected_annotations[0])
|
544
548
|
return None
|
545
549
|
|
546
|
-
def select_annotation(self, annotation, multi_select=False):
|
550
|
+
def select_annotation(self, annotation, multi_select=False, quiet_mode=False):
|
547
551
|
"""Select an annotation and update the UI accordingly."""
|
548
552
|
# If the annotation is already selected and Ctrl is pressed, unselect it
|
549
553
|
if annotation in self.selected_annotations and multi_select:
|
@@ -569,7 +573,11 @@ class AnnotationWindow(QGraphicsView):
|
|
569
573
|
|
570
574
|
# If this is the only selected annotation, update label window and confidence window
|
571
575
|
if len(self.selected_annotations) == 1:
|
572
|
-
|
576
|
+
|
577
|
+
if not quiet_mode:
|
578
|
+
# Emit the label selected signal, unless in quiet mode.
|
579
|
+
# This is in Explorer to avoid overwriting preview label.
|
580
|
+
self.labelSelected.emit(annotation.label.id)
|
573
581
|
|
574
582
|
# Make sure we have a cropped image
|
575
583
|
if not annotation.cropped_image:
|
coralnet_toolbox/QtMainWindow.py
CHANGED
@@ -4,6 +4,7 @@ warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
4
4
|
|
5
5
|
import os
|
6
6
|
import re
|
7
|
+
import ctypes
|
7
8
|
import requests
|
8
9
|
|
9
10
|
from packaging import version
|
@@ -130,6 +131,9 @@ class MainWindow(QMainWindow):
|
|
130
131
|
|
131
132
|
def __init__(self, __version__):
|
132
133
|
super().__init__()
|
134
|
+
|
135
|
+
# Get the process ID
|
136
|
+
self.pid = os.getpid()
|
133
137
|
|
134
138
|
# Define icons
|
135
139
|
self.coral_icon = get_icon("coral.png")
|
@@ -2329,6 +2333,62 @@ class MainWindow(QMainWindow):
|
|
2329
2333
|
msg.exec_()
|
2330
2334
|
except Exception as e:
|
2331
2335
|
QMessageBox.critical(self, "Critical Error", f"{e}")
|
2336
|
+
|
2337
|
+
def check_windows_gdi_count(self):
|
2338
|
+
"""Calculate and print the number of GDI objects for the current process on Windows."""
|
2339
|
+
# 1. Check if the OS is Windows. If not, return early.
|
2340
|
+
if os.name != 'nt':
|
2341
|
+
return
|
2342
|
+
|
2343
|
+
# Load necessary libraries
|
2344
|
+
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
|
2345
|
+
user32 = ctypes.WinDLL('user32', use_last_error=True)
|
2346
|
+
|
2347
|
+
# Define constants
|
2348
|
+
PROCESS_QUERY_INFORMATION = 0x0400
|
2349
|
+
GR_GDIOBJECTS = 0
|
2350
|
+
|
2351
|
+
process_handle = None
|
2352
|
+
try:
|
2353
|
+
# 2. Get a handle to the process from its PID
|
2354
|
+
process_handle = kernel32.OpenProcess(PROCESS_QUERY_INFORMATION, False, self.pid)
|
2355
|
+
|
2356
|
+
if not process_handle:
|
2357
|
+
error_code = ctypes.get_last_error()
|
2358
|
+
raise RuntimeError(f"Failed to open PID {self.pid}. Error code: {error_code}")
|
2359
|
+
|
2360
|
+
# 3. Use the handle to get the GDI object count
|
2361
|
+
gdi_count = user32.GetGuiResources(process_handle, GR_GDIOBJECTS)
|
2362
|
+
|
2363
|
+
if gdi_count >= 9500: # GDI limit
|
2364
|
+
self.show_gdi_limit_warning()
|
2365
|
+
|
2366
|
+
except Exception as e:
|
2367
|
+
pass
|
2368
|
+
|
2369
|
+
finally:
|
2370
|
+
# 4. CRITICAL: Always close the handle when you're done
|
2371
|
+
if process_handle:
|
2372
|
+
kernel32.CloseHandle(process_handle)
|
2373
|
+
|
2374
|
+
return
|
2375
|
+
|
2376
|
+
def show_gdi_limit_warning(self):
|
2377
|
+
"""
|
2378
|
+
Show a warning dialog if the GDI limit is reached.
|
2379
|
+
"""
|
2380
|
+
try:
|
2381
|
+
self.untoggle_all_tools()
|
2382
|
+
msg = QMessageBox()
|
2383
|
+
msg.setWindowIcon(self.coral_icon)
|
2384
|
+
msg.setWindowTitle("GDI Limit Reached")
|
2385
|
+
msg.setText(
|
2386
|
+
"The GDI limit has been reached! Please immediately save your work, close, and reopen the application!"
|
2387
|
+
)
|
2388
|
+
msg.setStandardButtons(QMessageBox.Ok)
|
2389
|
+
msg.exec_()
|
2390
|
+
except Exception as e:
|
2391
|
+
QMessageBox.critical(self, "Critical Error", f"{e}")
|
2332
2392
|
|
2333
2393
|
def open_snake_game_dialog(self):
|
2334
2394
|
"""
|
@@ -59,9 +59,14 @@ class ResizeSubTool(SubTool):
|
|
59
59
|
def mouseReleaseEvent(self, event):
|
60
60
|
"""Finalize the resize, update related windows, and deactivate."""
|
61
61
|
if self.target_annotation:
|
62
|
+
# Normalize the coordinates after resize is complete
|
63
|
+
if hasattr(self.target_annotation, 'normalize_coordinates'):
|
64
|
+
self.target_annotation.normalize_coordinates()
|
65
|
+
|
62
66
|
self.target_annotation.create_cropped_image(self.annotation_window.rasterio_image)
|
63
67
|
self.parent_tool.main_window.confidence_window.display_cropped_image(self.target_annotation)
|
64
|
-
|
68
|
+
self.annotation_window.annotationModified.emit(self.target_annotation.id) # Emit modified signal
|
69
|
+
|
65
70
|
self.parent_tool.deactivate_subtool()
|
66
71
|
|
67
72
|
# --- Handle Management Logic (moved from original class) ---
|
@@ -49,6 +49,7 @@ class SelectTool(Tool):
|
|
49
49
|
|
50
50
|
# --- State for transient UI (like resize handles) ---
|
51
51
|
self.resize_handles_visible = False
|
52
|
+
self.selection_locked = False
|
52
53
|
|
53
54
|
self._connect_signals()
|
54
55
|
|
@@ -81,16 +82,36 @@ class SelectTool(Tool):
|
|
81
82
|
self.deactivate_subtool()
|
82
83
|
self._hide_resize_handles()
|
83
84
|
self.annotation_window.viewport().setCursor(self.cursor)
|
85
|
+
self.selection_locked = False
|
84
86
|
|
85
87
|
def deactivate(self):
|
86
88
|
self.deactivate_subtool()
|
87
89
|
self._hide_resize_handles()
|
88
90
|
self.annotation_window.viewport().setCursor(self.default_cursor)
|
91
|
+
self.selection_locked = False
|
89
92
|
super().deactivate()
|
90
93
|
|
91
94
|
# --- Event Handlers (Dispatcher Logic) ---
|
92
95
|
|
93
96
|
def mousePressEvent(self, event: QMouseEvent):
|
97
|
+
if self.selection_locked:
|
98
|
+
# If selection is locked, only allow interaction with resize handles.
|
99
|
+
# Check if a handle was clicked to start a resize operation.
|
100
|
+
position = self.annotation_window.mapToScene(event.pos())
|
101
|
+
items = self.annotation_window.scene.items(position)
|
102
|
+
if self.resize_handles_visible:
|
103
|
+
for item in items:
|
104
|
+
if item in self.resize_subtool.resize_handles_items:
|
105
|
+
handle_name = item.data(1)
|
106
|
+
if handle_name and len(self.selected_annotations) == 1:
|
107
|
+
self.set_active_subtool(
|
108
|
+
self.resize_subtool, event,
|
109
|
+
annotation=self.selected_annotations[0],
|
110
|
+
handle_name=handle_name
|
111
|
+
)
|
112
|
+
return # Exit after starting resize
|
113
|
+
return # Otherwise, ignore the click entirely
|
114
|
+
|
94
115
|
# Ignore right mouse button events (used for panning)
|
95
116
|
if event.button() == Qt.RightButton:
|
96
117
|
return
|
@@ -215,14 +236,35 @@ class SelectTool(Tool):
|
|
215
236
|
return self.annotation_window.annotations_dict.get(annotation_id) if annotation_id else None
|
216
237
|
|
217
238
|
def _get_annotation_from_items(self, items, position):
|
218
|
-
"""
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
239
|
+
"""
|
240
|
+
Finds the first valid annotation at a position from a list of items.
|
241
|
+
First prioritizes annotations where the center graphic contains the point,
|
242
|
+
then falls back to any annotation that contains the point.
|
243
|
+
"""
|
244
|
+
# Filter out resize handles
|
245
|
+
valid_items = [item for item in items if item not in self.resize_subtool.resize_handles_items]
|
246
|
+
|
247
|
+
center_threshold = 10.0 # Distance threshold in pixels to consider a click "on center"
|
248
|
+
center_candidates = []
|
249
|
+
general_candidates = []
|
250
|
+
|
251
|
+
# Gather all potential candidates
|
252
|
+
for item in valid_items:
|
223
253
|
annotation = self._get_annotation_from_item(item)
|
224
254
|
if annotation and annotation.contains_point(position):
|
225
|
-
|
255
|
+
# Calculate distance to center
|
256
|
+
center_distance = (position - annotation.center_xy).manhattanLength()
|
257
|
+
if center_distance <= center_threshold:
|
258
|
+
center_candidates.append(annotation)
|
259
|
+
else:
|
260
|
+
general_candidates.append(annotation)
|
261
|
+
|
262
|
+
# Return priority: center candidates first, then general candidates
|
263
|
+
if center_candidates:
|
264
|
+
return center_candidates[0]
|
265
|
+
elif general_candidates:
|
266
|
+
return general_candidates[0]
|
267
|
+
|
226
268
|
return None
|
227
269
|
|
228
270
|
def _handle_annotation_selection(self, position, items, modifiers):
|
coralnet_toolbox/__init__.py
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
coralnet_toolbox/QtAnnotationWindow.py,sha256=
|
1
|
+
coralnet_toolbox/QtAnnotationWindow.py,sha256=ZlaYYAMNqu95SJhduQxH1K0YP7mOkMv3BzGQwemfByg,39518
|
2
2
|
coralnet_toolbox/QtConfidenceWindow.py,sha256=L5hR23uW91GpqnsNS9R1XF3zCTe2aU7w0iDoQMV0oyE,16190
|
3
3
|
coralnet_toolbox/QtEventFilter.py,sha256=KKC9de3e66PvGVgiML8P7MZ9-r7vvHidPJJYpcbTwyM,6696
|
4
4
|
coralnet_toolbox/QtImageWindow.py,sha256=vLziMSEWFfVRSBN0nUNkosgk3LiNxZDqPwbinz9ZivQ,49356
|
5
5
|
coralnet_toolbox/QtLabelWindow.py,sha256=-4GCk4pTY9g4ADH1iE__4xwqT-7UR_7VCT8v-bJzerk,50869
|
6
|
-
coralnet_toolbox/QtMainWindow.py,sha256=
|
6
|
+
coralnet_toolbox/QtMainWindow.py,sha256=z_Erak0fJC4x962rsFgK3IwjLQYVUe6rayzQzfJtkhw,114372
|
7
7
|
coralnet_toolbox/QtPatchSampling.py,sha256=Ehj06auBGfQwIruLNYQjF8eFOCpl8G72p42UXXb2mUo,29013
|
8
8
|
coralnet_toolbox/QtProgressBar.py,sha256=pnozUOcVjfO_yTS9z8wOMPcrrrOtG_FeCknTcdI6eyk,6250
|
9
9
|
coralnet_toolbox/QtWorkArea.py,sha256=YXRvHQKpWUtWyv_o9lZ8rmxfm28dUOG9pmMUeimDhQ4,13578
|
10
|
-
coralnet_toolbox/__init__.py,sha256
|
10
|
+
coralnet_toolbox/__init__.py,sha256=-OIPFY1gy8COaSsB29_2bWyVd3ro4BAdKgI2eIvHhPY,207
|
11
11
|
coralnet_toolbox/main.py,sha256=6j2B_1reC_KDmqvq1C0fB-UeSEm8eeJOozp2f4XXMLQ,1573
|
12
12
|
coralnet_toolbox/utilities.py,sha256=eUkxXuWaNFH83LSW-KniwujkXKJ2rK04czx3k3OPiAY,27115
|
13
13
|
coralnet_toolbox/Annotations/QtAnnotation.py,sha256=-3ASbjl1dXw9U731vyCgwyiyZT9zOD5Mvp1jt-7bCnA,29242
|
14
14
|
coralnet_toolbox/Annotations/QtMultiPolygonAnnotation.py,sha256=ErAT31gw-zhEVNxkPRpyB9uw-NSpPh-ShCBxpscXdRw,15579
|
15
15
|
coralnet_toolbox/Annotations/QtPatchAnnotation.py,sha256=67fNnK_-muyhGZdGB0kBDx-JGuflv1TM6q5ikfW_zOk,20076
|
16
16
|
coralnet_toolbox/Annotations/QtPolygonAnnotation.py,sha256=1EkZEJlO4VZ4so01Sat2T8LeO1LNs7HbGJLO-G2_73Q,26886
|
17
|
-
coralnet_toolbox/Annotations/QtRectangleAnnotation.py,sha256=
|
17
|
+
coralnet_toolbox/Annotations/QtRectangleAnnotation.py,sha256=TgeawekA3jNBlCmZBRqXYRHoZqch7pWM-NSBBPG6S60,21404
|
18
18
|
coralnet_toolbox/Annotations/__init__.py,sha256=bpMldC70tT_lzMrOdBNDkEhG9dCX3tXEBd48IrcUg3E,419
|
19
19
|
coralnet_toolbox/AutoDistill/QtBatchInference.py,sha256=k871aW3XRX8kc4BDaS1aipbPh9WOZxgmilF2c4KOdVA,5646
|
20
20
|
coralnet_toolbox/AutoDistill/QtDeployModel.py,sha256=6alhzvA3KYEeLaQj-Qhs9GicjNQyVoQbnvgZ3lxGnCU,25162
|
@@ -35,10 +35,10 @@ coralnet_toolbox/Common/QtUpdateImagePaths.py,sha256=_hJYx6hXdAOfH_m77f75AQduQ0W
|
|
35
35
|
coralnet_toolbox/CoralNet/QtAuthenticate.py,sha256=Y__iY0Kcosz6AOV7dlJBwiB6Hte40wHahHe-OmRngZA,13267
|
36
36
|
coralnet_toolbox/CoralNet/QtDownload.py,sha256=HBb8TpZRIEFirGIaIAV1v8qg3fL4cP6Bf-hUiqXoiLE,48516
|
37
37
|
coralnet_toolbox/CoralNet/__init__.py,sha256=ILkAZh6mlAK1UaCCZjCB9JZxd-oY4cIgfnIC8UgjjIU,188
|
38
|
-
coralnet_toolbox/Explorer/QtDataItem.py,sha256
|
39
|
-
coralnet_toolbox/Explorer/QtExplorer.py,sha256=
|
40
|
-
coralnet_toolbox/Explorer/QtFeatureStore.py,sha256=
|
41
|
-
coralnet_toolbox/Explorer/QtSettingsWidgets.py,sha256=
|
38
|
+
coralnet_toolbox/Explorer/QtDataItem.py,sha256=fNpCHJSxMzHL2XpBXtPwKchSbmY7H0HWzL1Kbs4W1Ts,14920
|
39
|
+
coralnet_toolbox/Explorer/QtExplorer.py,sha256=vAtGTNsEUcy14-_XJuOocH7xdAlesHm5faN9AINaEvg,131591
|
40
|
+
coralnet_toolbox/Explorer/QtFeatureStore.py,sha256=3VwGezs1stmu65Z4ZQpvY27rGEIJq_prERWkFwMATBo,7378
|
41
|
+
coralnet_toolbox/Explorer/QtSettingsWidgets.py,sha256=unm23yP329cVL84aOvy20DBt3YBHVLU85rnfN9VUF8A,27649
|
42
42
|
coralnet_toolbox/Explorer/__init__.py,sha256=wZPhf2oaUUyIQ2WK48Aj-4q1ENIZG2dGl1HF_mjhI6w,116
|
43
43
|
coralnet_toolbox/IO/QtExportAnnotations.py,sha256=xeaS0BukC3cpkBIGT9DXRqHmvHhp-vOU47h6EoANpNg,4474
|
44
44
|
coralnet_toolbox/IO/QtExportCoralNetAnnotations.py,sha256=4royhF63EmeOlSIBX389EUjjvE-SF44_maW6qm52mdA,2778
|
@@ -206,19 +206,19 @@ coralnet_toolbox/Tools/QtPanTool.py,sha256=q0g5Ryse6mIZ_Ss4qJw5NNwgoLuQQBIyQTXNF
|
|
206
206
|
coralnet_toolbox/Tools/QtPatchTool.py,sha256=57vFeR2jQ_VQRlMEIC_mH8NigUqOlVvmhaVkXDvd_Gw,5574
|
207
207
|
coralnet_toolbox/Tools/QtPolygonTool.py,sha256=yxnkwK3rb52pWCq7a3iAABhHUSS_a3vkL7G7Ev0uLDA,9174
|
208
208
|
coralnet_toolbox/Tools/QtRectangleTool.py,sha256=gYOOsn1WRHLG0YzkKmmM7OzLpuLNh8GWIZ4MloXoLDc,7218
|
209
|
-
coralnet_toolbox/Tools/QtResizeSubTool.py,sha256
|
209
|
+
coralnet_toolbox/Tools/QtResizeSubTool.py,sha256=derPy4adRj758-xYtjL-_35yGBOjoSe_DRE48HpdQpA,5836
|
210
210
|
coralnet_toolbox/Tools/QtSAMTool.py,sha256=TQ--xcR76lymFS0YVo5Gi4ay_tIsIEecYpLDMRBPLWQ,26174
|
211
211
|
coralnet_toolbox/Tools/QtSeeAnythingTool.py,sha256=2uxyX_chOIXcmW6oBlb6XlgbRmSwSaQXmkmgOtFrqI4,30606
|
212
212
|
coralnet_toolbox/Tools/QtSelectSubTool.py,sha256=xKtXYCwezLq3YZQLsSTG3mxs_ZRjLiPrYl-0ebgq-GA,3125
|
213
|
-
coralnet_toolbox/Tools/QtSelectTool.py,sha256=
|
213
|
+
coralnet_toolbox/Tools/QtSelectTool.py,sha256=rSzM9s7pMxrLqvcWgIcEnpEQhYHU6TbGUna8ZaamakA,19957
|
214
214
|
coralnet_toolbox/Tools/QtSubTool.py,sha256=H25FoFqywdi6Bl35MfpEXGrr48ZTgdRRvHMxUy1tqN4,1601
|
215
215
|
coralnet_toolbox/Tools/QtTool.py,sha256=2MCjT151gYBN8KbsK0GX4WOrEg1uw3oeSkp7Elw1AUA,2531
|
216
216
|
coralnet_toolbox/Tools/QtWorkAreaTool.py,sha256=-CDrEPenOdSI3sf5wn19Cip4alE1ef7WsRDxQFDkHlc,22162
|
217
217
|
coralnet_toolbox/Tools/QtZoomTool.py,sha256=F9CAoABv1jxcUS7dyIh1FYjgjOXYRI1xtBPNIR1g62o,4041
|
218
218
|
coralnet_toolbox/Tools/__init__.py,sha256=218iQ8IFXIkKXiUDVYtXk9e08UY9-LhHjcryaJAanQ0,797
|
219
|
-
coralnet_toolbox-0.0.
|
220
|
-
coralnet_toolbox-0.0.
|
221
|
-
coralnet_toolbox-0.0.
|
222
|
-
coralnet_toolbox-0.0.
|
223
|
-
coralnet_toolbox-0.0.
|
224
|
-
coralnet_toolbox-0.0.
|
219
|
+
coralnet_toolbox-0.0.72.dist-info/licenses/LICENSE.txt,sha256=AURacZ_G_PZKqqPQ9VB9Sqegblk67RNgWSGAYKwXXMY,521
|
220
|
+
coralnet_toolbox-0.0.72.dist-info/METADATA,sha256=cOB6wtxUBZcPWkW0L9v3LCWIsI_NOaaiKo9RyQJl15M,18152
|
221
|
+
coralnet_toolbox-0.0.72.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
|
222
|
+
coralnet_toolbox-0.0.72.dist-info/entry_points.txt,sha256=oEeMoDlJ_2lq95quOeDHIx9hZpubUlSo80OLtgbcrbM,63
|
223
|
+
coralnet_toolbox-0.0.72.dist-info/top_level.txt,sha256=SMWPh4_9JfB8zVpPOOvjucV2_B_hvWW7bNWmMjG0LsY,17
|
224
|
+
coralnet_toolbox-0.0.72.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.72.dist-info}/licenses/LICENSE.txt
RENAMED
File without changes
|
File without changes
|