spacr 0.1.85__py3-none-any.whl → 0.2.0__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.
- spacr/__init__.py +6 -2
- spacr/app_annotate.py +6 -5
- spacr/app_make_masks.py +8 -15
- spacr/core.py +1 -1
- spacr/gui.py +62 -100
- spacr/gui_2.py +110 -113
- spacr/gui_core.py +43 -16
- spacr/gui_elements.py +109 -20
- spacr/gui_utils.py +3 -3
- spacr/icons/abort.png +0 -0
- spacr/icons/abort.svg +1 -0
- spacr/icons/download.png +0 -0
- spacr/icons/download.svg +1 -0
- spacr/icons/download_for_offline_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
- spacr/icons/download_for_offline_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +1 -0
- spacr/icons/logo_spacr.png +0 -0
- spacr/icons/make_masks.png +0 -0
- spacr/icons/make_masks.svg +1 -0
- spacr/icons/map_barcodes.png +0 -0
- spacr/icons/map_barcodes.svg +1 -0
- spacr/icons/mask.png +0 -0
- spacr/icons/mask.svg +1 -0
- spacr/icons/measure.png +0 -0
- spacr/icons/measure.svg +1 -0
- spacr/icons/play_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
- spacr/icons/play_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +1 -0
- spacr/icons/run.png +0 -0
- spacr/icons/run.svg +1 -0
- spacr/icons/sequencing.png +0 -0
- spacr/icons/sequencing.svg +1 -0
- spacr/icons/settings.png +0 -0
- spacr/icons/settings.svg +1 -0
- spacr/icons/settings_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
- spacr/icons/settings_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +1 -0
- spacr/icons/stop_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
- spacr/icons/stop_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +1 -0
- spacr/icons/theater_comedy_100dp_E8EAED_FILL0_wght100_GRAD200_opsz48.png +0 -0
- spacr/icons/theater_comedy_100dp_E8EAED_FILL0_wght100_GRAD200_opsz48.svg +1 -0
- spacr/resources/icons/abort.png +0 -0
- spacr/resources/icons/abort.svg +1 -0
- spacr/resources/icons/annotate.png +0 -0
- spacr/resources/icons/annotate.svg +1 -0
- spacr/resources/icons/cellpose.png +0 -0
- spacr/resources/icons/cellpose_masks.png +0 -0
- spacr/resources/icons/classify.png +0 -0
- spacr/resources/icons/classify.svg +1 -0
- spacr/resources/icons/default.png +0 -0
- spacr/resources/icons/download.png +0 -0
- spacr/resources/icons/download.svg +1 -0
- spacr/resources/icons/icon.psd +0 -0
- spacr/resources/icons/logo_spacr.png +0 -0
- spacr/resources/icons/make_masks.png +0 -0
- spacr/resources/icons/make_masks.svg +1 -0
- spacr/resources/icons/map_barcodes.png +0 -0
- spacr/resources/icons/map_barcodes.svg +1 -0
- spacr/resources/icons/mask.png +0 -0
- spacr/resources/icons/mask.svg +1 -0
- spacr/resources/icons/measure.png +0 -0
- spacr/resources/icons/measure.svg +1 -0
- spacr/resources/icons/regression.png +0 -0
- spacr/resources/icons/run.png +0 -0
- spacr/resources/icons/run.svg +1 -0
- spacr/resources/icons/run_2.png +0 -0
- spacr/resources/icons/run_2.svg +1 -0
- spacr/resources/icons/sequencing.png +0 -0
- spacr/resources/icons/sequencing.svg +1 -0
- spacr/resources/icons/settings.png +0 -0
- spacr/resources/icons/settings.svg +1 -0
- spacr/resources/icons/train_cellpose.png +0 -0
- spacr/resources/icons/train_cellpose.svg +1 -0
- spacr/resources/icons/umap.png +0 -0
- spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
- spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +23 -0
- spacr/resources/models/cp/toxo_pv_lumen.CP_model +0 -0
- spacr/settings.py +12 -12
- {spacr-0.1.85.dist-info → spacr-0.2.0.dist-info}/METADATA +1 -1
- spacr-0.2.0.dist-info/RECORD +126 -0
- spacr-0.1.85.dist-info/RECORD +0 -61
- {spacr-0.1.85.dist-info → spacr-0.2.0.dist-info}/LICENSE +0 -0
- {spacr-0.1.85.dist-info → spacr-0.2.0.dist-info}/WHEEL +0 -0
- {spacr-0.1.85.dist-info → spacr-0.2.0.dist-info}/entry_points.txt +0 -0
- {spacr-0.1.85.dist-info → spacr-0.2.0.dist-info}/top_level.txt +0 -0
spacr/gui_core.py
CHANGED
@@ -231,25 +231,43 @@ def import_settings(settings_type='mask'):
|
|
231
231
|
vars_dict = hide_all_settings(vars_dict, categories=None)
|
232
232
|
|
233
233
|
def convert_settings_dict_for_gui(settings):
|
234
|
+
from torchvision import models as torch_models
|
235
|
+
torchvision_models = [name for name, obj in torch_models.__dict__.items() if callable(obj)]
|
236
|
+
chans = ['0', '1', '2', '3', '4', '5', '6', '7', '8', None]
|
237
|
+
chans_v2 = [0, 1, 2, 3, None]
|
234
238
|
variables = {}
|
235
239
|
special_cases = {
|
236
240
|
'metadata_type': ('combo', ['cellvoyager', 'cq1', 'nikon', 'zeis', 'custom'], 'cellvoyager'),
|
237
241
|
'channels': ('combo', ['[0,1,2,3]', '[0,1,2]', '[0,1]', '[0]'], '[0,1,2,3]'),
|
238
|
-
'
|
239
|
-
'
|
240
|
-
'
|
241
|
-
|
242
|
+
'channel_dims': ('combo', ['[0,1,2,3]', '[0,1,2]', '[0,1]', '[0]'], '[0,1,2,3]'),
|
243
|
+
'cell_mask_dim': ('combo', chans, None),
|
244
|
+
'cell_chann_dim': ('combo', chans, None),
|
245
|
+
'nucleus_mask_dim': ('combo', chans, None),
|
246
|
+
'nucleus_chann_dim': ('combo', chans, None),
|
247
|
+
'pathogen_mask_dim': ('combo', chans, None),
|
248
|
+
'pathogen_chann_dim': ('combo', chans, None),
|
249
|
+
'crop_mode': ('combo', ['cell', 'nucleus', 'pathogen', '[cell, nucleus, pathogen]', '[cell,nucleus, pathogen]'], ['cell']),
|
242
250
|
'magnification': ('combo', [20, 40, 60], 20),
|
243
|
-
'nucleus_channel': ('combo',
|
244
|
-
'cell_channel': ('combo',
|
245
|
-
'
|
251
|
+
'nucleus_channel': ('combo', chans_v2, None),
|
252
|
+
'cell_channel': ('combo', chans_v2, None),
|
253
|
+
'channel_of_interest': ('combo', chans_v2, None),
|
254
|
+
'pathogen_channel': ('combo', chans_v2, None),
|
246
255
|
'timelapse_mode': ('combo', ['trackpy', 'btrack'], 'trackpy'),
|
256
|
+
'train_mode': ('combo', ['erm', 'irm'], 'erm'),
|
257
|
+
'clustering': ('combo', ['dbscan', 'kmean'], 'dbscan'),
|
258
|
+
'reduction_method': ('combo', ['umap', 'tsne'], 'umap'),
|
259
|
+
'model_name': ('combo', ['cyto', 'cyto_2', 'cyto_3', 'nuclei'], 'cyto'),
|
260
|
+
'regression_type': ('combo', ['ols','gls','wls','rlm','glm','mixed','quantile','logit','probit','poisson','lasso','ridge'], 'ols'),
|
247
261
|
'timelapse_objects': ('combo', ['cell', 'nucleus', 'pathogen', 'cytoplasm', None], None),
|
248
|
-
'model_type': ('combo',
|
262
|
+
'model_type': ('combo', torchvision_models, 'resnet50'),
|
249
263
|
'optimizer_type': ('combo', ['adamw', 'adam'], 'adamw'),
|
250
264
|
'schedule': ('combo', ['reduce_lr_on_plateau', 'step_lr'], 'reduce_lr_on_plateau'),
|
251
265
|
'loss_type': ('combo', ['focal_loss', 'binary_cross_entropy_with_logits'], 'focal_loss'),
|
252
266
|
'normalize_by': ('combo', ['fov', 'png'], 'png'),
|
267
|
+
'agg_type': ('combo', ['mean', 'median'], 'mean'),
|
268
|
+
'grouping': ('combo', ['mean', 'median'], 'mean'),
|
269
|
+
'min_max': ('combo', ['allq', 'all'], 'allq'),
|
270
|
+
'transform': ('combo', ['log', 'sqrt', 'square', None], None)
|
253
271
|
}
|
254
272
|
|
255
273
|
for key, value in settings.items():
|
@@ -338,9 +356,10 @@ def setup_plot_section(vertical_container):
|
|
338
356
|
plot_frame.add(canvas_widget, stretch="always")
|
339
357
|
canvas.draw()
|
340
358
|
canvas.figure = figure
|
341
|
-
|
342
|
-
|
343
|
-
|
359
|
+
style_out = set_dark_style(ttk.Style())
|
360
|
+
|
361
|
+
figure.patch.set_facecolor(style_out['bg_color'])
|
362
|
+
plot.set_facecolor(style_out['bg_color'])
|
344
363
|
containers = [plot_frame]
|
345
364
|
widgets = [canvas_widget]
|
346
365
|
style = ttk.Style(vertical_container)
|
@@ -488,25 +507,25 @@ def setup_button_section(horizontal_container, settings_type='mask', window_dime
|
|
488
507
|
btn_row = 1
|
489
508
|
|
490
509
|
if run:
|
491
|
-
run_button = spacrButton(button_scrollable_frame.scrollable_frame, text="
|
510
|
+
run_button = spacrButton(button_scrollable_frame.scrollable_frame, text="run", command=lambda: start_process(q, fig_queue, settings_type))
|
492
511
|
run_button.grid(row=btn_row, column=btn_col, pady=5, padx=5, sticky='ew')
|
493
512
|
widgets.append(run_button)
|
494
513
|
btn_row += 1
|
495
514
|
|
496
515
|
if abort and settings_type in ['mask', 'measure', 'classify', 'sequencing', 'umap']:
|
497
|
-
abort_button = spacrButton(button_scrollable_frame.scrollable_frame, text="
|
516
|
+
abort_button = spacrButton(button_scrollable_frame.scrollable_frame, text="abort", command=initiate_abort)
|
498
517
|
abort_button.grid(row=btn_row, column=btn_col, pady=5, padx=5, sticky='ew')
|
499
518
|
widgets.append(abort_button)
|
500
519
|
btn_row += 1
|
501
520
|
|
502
521
|
if download and settings_type in ['mask']:
|
503
|
-
download_dataset_button = spacrButton(button_scrollable_frame.scrollable_frame, text="
|
522
|
+
download_dataset_button = spacrButton(button_scrollable_frame.scrollable_frame, text="download", command=download_hug_dataset)
|
504
523
|
download_dataset_button.grid(row=btn_row, column=btn_col, pady=5, padx=5, sticky='ew')
|
505
524
|
widgets.append(download_dataset_button)
|
506
525
|
btn_row += 1
|
507
526
|
|
508
527
|
if import_btn:
|
509
|
-
import_button = spacrButton(button_scrollable_frame.scrollable_frame, text="
|
528
|
+
import_button = spacrButton(button_scrollable_frame.scrollable_frame, text="settings", command=lambda: import_settings(settings_type))
|
510
529
|
import_button.grid(row=btn_row, column=btn_col, pady=5, padx=5, sticky='ew')
|
511
530
|
widgets.append(import_button)
|
512
531
|
|
@@ -516,11 +535,19 @@ def setup_button_section(horizontal_container, settings_type='mask', window_dime
|
|
516
535
|
description_frame = tk.Frame(horizontal_container)
|
517
536
|
horizontal_container.add(description_frame, stretch="always", sticky="nsew")
|
518
537
|
description_frame.grid_columnconfigure(0, weight=1)
|
538
|
+
description_frame.grid_rowconfigure(0, weight=1) # Add this line to make the row expandable
|
539
|
+
|
519
540
|
description_label = tk.Label(description_frame, text="Module Description", anchor='nw', justify='left', wraplength=width - 50)
|
520
541
|
description_label.grid(row=0, column=0, pady=50, padx=20, sticky='nsew')
|
521
542
|
description_text = descriptions.get(settings_type, "No description available for this module.")
|
522
543
|
description_label.config(text=description_text)
|
523
544
|
|
545
|
+
def update_wraplength(event):
|
546
|
+
new_width = event.width - 40 # Adjust as needed
|
547
|
+
description_label.config(wraplength=new_width)
|
548
|
+
|
549
|
+
description_label.bind('<Configure>', update_wraplength)
|
550
|
+
|
524
551
|
containers = [button_frame, description_frame]
|
525
552
|
widgets.extend([description_label])
|
526
553
|
|
@@ -588,7 +615,7 @@ def toggle_settings(button_scrollable_frame):
|
|
588
615
|
category_var = tk.StringVar()
|
589
616
|
non_empty_categories = [category for category, settings in categories.items() if any(setting in vars_dict for setting in settings)]
|
590
617
|
category_dropdown = spacrDropdownMenu(button_scrollable_frame.scrollable_frame, category_var, non_empty_categories, command=on_category_select)
|
591
|
-
category_dropdown.grid(row=
|
618
|
+
category_dropdown.grid(row=5, column=0, sticky="ew", pady=2, padx=2)
|
592
619
|
vars_dict = hide_all_settings(vars_dict, categories)
|
593
620
|
|
594
621
|
def process_fig_queue():
|
spacr/gui_elements.py
CHANGED
@@ -15,17 +15,25 @@ from skimage.draw import polygon, line
|
|
15
15
|
from skimage.transform import resize
|
16
16
|
from scipy.ndimage import binary_fill_holes, label
|
17
17
|
from tkinter import ttk, scrolledtext
|
18
|
+
import platform
|
18
19
|
|
19
|
-
def set_dark_style(style, parent_frame=None, containers=None, widgets=None, font_family="Arial", font_size=12, bg_color='black', fg_color='white', active_color='
|
20
|
+
def set_dark_style(style, parent_frame=None, containers=None, widgets=None, font_family="Arial", font_size=12, bg_color='black', fg_color='white', active_color='blue', inactive_color='dark_gray'):
|
21
|
+
|
22
|
+
if platform.system() == 'Darwin':
|
23
|
+
bg_color = '#313131'
|
24
|
+
else:
|
25
|
+
bg_color = '#000000'
|
20
26
|
|
21
27
|
if active_color == 'teal':
|
22
28
|
active_color = '#008080'
|
23
|
-
if inactive_color == '
|
24
|
-
inactive_color = '#
|
29
|
+
if inactive_color == 'dark_gray':
|
30
|
+
inactive_color = '#050505'
|
25
31
|
if bg_color == 'black':
|
26
32
|
bg_color = '#000000'
|
27
33
|
if fg_color == 'white':
|
28
34
|
fg_color = '#ffffff'
|
35
|
+
if active_color == 'blue':
|
36
|
+
active_color = '#007BFF'
|
29
37
|
|
30
38
|
font_style = tkFont.Font(family=font_family, size=font_size)
|
31
39
|
style.configure('TEntry', padding='5 5 5 5', borderwidth=1, relief='solid', fieldbackground=bg_color, foreground=fg_color, font=font_style)
|
@@ -76,7 +84,7 @@ def set_dark_style(style, parent_frame=None, containers=None, widgets=None, font
|
|
76
84
|
menu = widget['menu']
|
77
85
|
menu.configure(bg=bg_color, fg=fg_color, font=(font_family, font_size))
|
78
86
|
|
79
|
-
return {'font_family':font_family, 'font_size':font_size, 'bg_color':bg_color, 'fg_color':fg_color, 'active_color':active_color, 'inactive_color':inactive_color}
|
87
|
+
return {'font_family': font_family, 'font_size': font_size, 'bg_color': bg_color, 'fg_color': fg_color, 'active_color': active_color, 'inactive_color': inactive_color}
|
80
88
|
|
81
89
|
def set_default_font(root, font_name="Arial", size=12):
|
82
90
|
default_font = (font_name, size)
|
@@ -116,7 +124,6 @@ class spacrCheckbutton(ttk.Checkbutton):
|
|
116
124
|
style = ttk.Style()
|
117
125
|
_ = set_dark_style(style, widgets=[self])
|
118
126
|
|
119
|
-
|
120
127
|
class spacrFrame(ttk.Frame):
|
121
128
|
def __init__(self, container, width=None, *args, bg='black', **kwargs):
|
122
129
|
super().__init__(container, *args, **kwargs)
|
@@ -189,25 +196,40 @@ class spacrLabel(tk.Frame):
|
|
189
196
|
self.canvas.itemconfig(self.label_text, text=text)
|
190
197
|
|
191
198
|
class spacrButton(tk.Frame):
|
192
|
-
def __init__(self, parent, text="", command=None, font=None, *args, **kwargs):
|
199
|
+
def __init__(self, parent, text="", command=None, font=None, icon_name=None, size=50, show_text=True, outline=True, *args, **kwargs):
|
193
200
|
super().__init__(parent, *args, **kwargs)
|
194
201
|
|
195
|
-
self.text = text
|
202
|
+
self.text = text.capitalize() # Capitalize only the first letter of the text
|
196
203
|
self.command = command
|
197
|
-
|
198
|
-
|
204
|
+
self.icon_name = icon_name if icon_name else text.lower()
|
205
|
+
self.size = size
|
206
|
+
self.show_text = show_text
|
207
|
+
self.outline = outline
|
208
|
+
|
199
209
|
style_out = set_dark_style(ttk.Style())
|
200
210
|
|
211
|
+
if self.show_text:
|
212
|
+
self.button_width = int(size * 3)
|
213
|
+
else:
|
214
|
+
self.button_width = self.size # Make the button width equal to the size if show_text is False
|
215
|
+
|
201
216
|
# Create the canvas first
|
202
|
-
self.canvas = tk.Canvas(self, width=button_width + 4, height=
|
217
|
+
self.canvas = tk.Canvas(self, width=self.button_width + 4, height=self.size + 4, highlightthickness=0, bg=style_out['bg_color'])
|
203
218
|
self.canvas.grid(row=0, column=0)
|
204
219
|
|
205
220
|
# Apply dark style and get color settings
|
206
221
|
color_settings = set_dark_style(ttk.Style(), containers=[self], widgets=[self.canvas])
|
207
222
|
|
208
|
-
|
209
|
-
|
210
|
-
|
223
|
+
if self.outline:
|
224
|
+
self.button_bg = self.create_rounded_rectangle(2, 2, self.button_width + 2, self.size + 2, radius=20, fill=color_settings['bg_color'], outline=color_settings['fg_color'])
|
225
|
+
else:
|
226
|
+
self.button_bg = self.create_rounded_rectangle(2, 2, self.button_width + 2, self.size + 2, radius=20, fill=color_settings['bg_color'], outline=color_settings['bg_color'])
|
227
|
+
|
228
|
+
self.load_icon()
|
229
|
+
self.font_style = font if font else ("Arial", 12) # Default font if not provided
|
230
|
+
|
231
|
+
if self.show_text:
|
232
|
+
self.button_text = self.canvas.create_text(self.size + 10, self.size // 2 + 2, text=self.text, fill=color_settings['fg_color'], font=self.font_style, anchor="w") # Align text to the left of the specified point
|
211
233
|
|
212
234
|
self.bind("<Enter>", self.on_enter)
|
213
235
|
self.bind("<Leave>", self.on_leave)
|
@@ -219,12 +241,42 @@ class spacrButton(tk.Frame):
|
|
219
241
|
self.bg_color = color_settings['bg_color']
|
220
242
|
self.active_color = color_settings['active_color']
|
221
243
|
self.fg_color = color_settings['fg_color']
|
244
|
+
self.is_zoomed_in = False # Track zoom state for smooth transitions
|
245
|
+
|
246
|
+
def load_icon(self):
|
247
|
+
icon_path = self.get_icon_path(self.icon_name)
|
248
|
+
try:
|
249
|
+
icon_image = Image.open(icon_path)
|
250
|
+
except (FileNotFoundError, Image.UnidentifiedImageError):
|
251
|
+
try:
|
252
|
+
icon_path = icon_path.replace(' ', '_')
|
253
|
+
icon_image = Image.open(icon_path)
|
254
|
+
except (FileNotFoundError, Image.UnidentifiedImageError):
|
255
|
+
icon_image = Image.open(self.get_icon_path("default"))
|
256
|
+
print(f'Icon not found: {icon_path}. Using default icon instead.')
|
257
|
+
|
258
|
+
initial_size = int(self.size * 0.9) # Make the initial size slightly smaller
|
259
|
+
self.original_icon_image = icon_image.resize((initial_size, initial_size), Image.Resampling.LANCZOS)
|
260
|
+
self.icon_photo = ImageTk.PhotoImage(self.original_icon_image)
|
261
|
+
|
262
|
+
self.button_icon = self.canvas.create_image(self.size // 2 + 2, self.size // 2 + 2, image=self.icon_photo)
|
263
|
+
self.canvas.image = self.icon_photo # Keep a reference to avoid garbage collection
|
264
|
+
|
265
|
+
def get_icon_path(self, icon_name):
|
266
|
+
icon_dir = os.path.join(os.path.dirname(__file__), 'resources', 'icons')
|
267
|
+
return os.path.join(icon_dir, f"{icon_name}.png")
|
222
268
|
|
223
269
|
def on_enter(self, event=None):
|
224
270
|
self.canvas.itemconfig(self.button_bg, fill=self.active_color)
|
271
|
+
self.update_description(event)
|
272
|
+
if not self.is_zoomed_in:
|
273
|
+
self.animate_zoom(1.1) # Zoom in the icon by 10%
|
225
274
|
|
226
275
|
def on_leave(self, event=None):
|
227
276
|
self.canvas.itemconfig(self.button_bg, fill=self.bg_color)
|
277
|
+
self.clear_description(event)
|
278
|
+
if self.is_zoomed_in:
|
279
|
+
self.animate_zoom(1.0) # Reset the icon size
|
228
280
|
|
229
281
|
def on_click(self, event=None):
|
230
282
|
if self.command:
|
@@ -232,18 +284,15 @@ class spacrButton(tk.Frame):
|
|
232
284
|
|
233
285
|
def create_rounded_rectangle(self, x1, y1, x2, y2, radius=20, **kwargs):
|
234
286
|
points = [
|
235
|
-
x1 + radius, y1,
|
236
287
|
x1 + radius, y1,
|
237
288
|
x2 - radius, y1,
|
238
289
|
x2 - radius, y1,
|
239
290
|
x2, y1,
|
240
291
|
x2, y1 + radius,
|
241
|
-
x2, y1 + radius,
|
242
292
|
x2, y2 - radius,
|
243
293
|
x2, y2 - radius,
|
244
294
|
x2, y2,
|
245
295
|
x2 - radius, y2,
|
246
|
-
x2 - radius, y2,
|
247
296
|
x1 + radius, y2,
|
248
297
|
x1 + radius, y2,
|
249
298
|
x1, y2,
|
@@ -254,6 +303,46 @@ class spacrButton(tk.Frame):
|
|
254
303
|
x1, y1
|
255
304
|
]
|
256
305
|
return self.canvas.create_polygon(points, **kwargs, smooth=True)
|
306
|
+
|
307
|
+
def update_description(self, event):
|
308
|
+
parent = self.master
|
309
|
+
while parent:
|
310
|
+
if hasattr(parent, 'show_description'):
|
311
|
+
parent.show_description(parent.main_buttons.get(self, "No description available."))
|
312
|
+
return
|
313
|
+
parent = parent.master
|
314
|
+
|
315
|
+
def clear_description(self, event):
|
316
|
+
parent = self.master
|
317
|
+
while parent:
|
318
|
+
if hasattr(parent, 'clear_description'):
|
319
|
+
parent.clear_description()
|
320
|
+
return
|
321
|
+
parent = parent.master
|
322
|
+
|
323
|
+
def animate_zoom(self, target_scale, steps=10, delay=10):
|
324
|
+
current_scale = 1.1 if self.is_zoomed_in else 1.0
|
325
|
+
step_scale = (target_scale - current_scale) / steps
|
326
|
+
self._animate_step(current_scale, step_scale, steps, delay)
|
327
|
+
|
328
|
+
def _animate_step(self, current_scale, step_scale, steps, delay):
|
329
|
+
if steps > 0:
|
330
|
+
new_scale = current_scale + step_scale
|
331
|
+
self.zoom_icon(new_scale)
|
332
|
+
self.after(delay, self._animate_step, new_scale, step_scale, steps - 1, delay)
|
333
|
+
else:
|
334
|
+
self.is_zoomed_in = not self.is_zoomed_in
|
335
|
+
|
336
|
+
def zoom_icon(self, scale_factor):
|
337
|
+
# Resize the original icon image
|
338
|
+
new_size = int(self.size * 0.9 * scale_factor)
|
339
|
+
resized_icon = self.original_icon_image.resize((new_size, new_size), Image.Resampling.LANCZOS)
|
340
|
+
self.icon_photo = ImageTk.PhotoImage(resized_icon)
|
341
|
+
|
342
|
+
# Update the icon on the canvas
|
343
|
+
self.canvas.itemconfig(self.button_icon, image=self.icon_photo)
|
344
|
+
self.canvas.image = self.icon_photo # Keep a reference to avoid garbage collection
|
345
|
+
|
257
346
|
|
258
347
|
class spacrSwitch(ttk.Frame):
|
259
348
|
def __init__(self, parent, text="", variable=None, command=None, *args, **kwargs):
|
@@ -363,7 +452,7 @@ class spacrToolTip:
|
|
363
452
|
self.tooltip_window.destroy()
|
364
453
|
self.tooltip_window = None
|
365
454
|
|
366
|
-
class
|
455
|
+
class ModifyMaskApp:
|
367
456
|
def __init__(self, root, folder_path, scale_factor):
|
368
457
|
self.root = root
|
369
458
|
self.folder_path = folder_path
|
@@ -1207,7 +1296,7 @@ class modify_masks:
|
|
1207
1296
|
self.mask[labeled_mask == i] = 0 # Remove small objects
|
1208
1297
|
self.update_display()
|
1209
1298
|
|
1210
|
-
class
|
1299
|
+
class AnnotateApp:
|
1211
1300
|
def __init__(self, root, db_path, src, image_type=None, channels=None, grid_rows=None, grid_cols=None, image_size=(200, 200), annotation_column='annotate', normalize=False, percentiles=(1,99), measurement=None, threshold=None):
|
1212
1301
|
self.root = root
|
1213
1302
|
self.db_path = db_path
|
@@ -1471,7 +1560,7 @@ class ImageApp:
|
|
1471
1560
|
break
|
1472
1561
|
|
1473
1562
|
if not self.update_queue.empty():
|
1474
|
-
|
1563
|
+
AnnotateApp.update_html("Do not exit, Updating database...")
|
1475
1564
|
self.status_label.config(text='Do not exit, Updating database...')
|
1476
1565
|
|
1477
1566
|
pending_updates = self.update_queue.get()
|
@@ -1482,7 +1571,7 @@ class ImageApp:
|
|
1482
1571
|
c.execute(f'UPDATE png_list SET {self.annotation_column} = ? WHERE png_path = ?', (new_annotation, path))
|
1483
1572
|
conn.commit()
|
1484
1573
|
|
1485
|
-
|
1574
|
+
AnnotateApp.update_html('')
|
1486
1575
|
self.status_label.config(text='')
|
1487
1576
|
self.root.update()
|
1488
1577
|
time.sleep(0.1)
|
spacr/gui_utils.py
CHANGED
@@ -3,7 +3,7 @@ import tkinter as tk
|
|
3
3
|
from tkinter import ttk
|
4
4
|
|
5
5
|
from . gui_core import initiate_root
|
6
|
-
from .gui_elements import spacrLabel, spacrCheckbutton,
|
6
|
+
from .gui_elements import spacrLabel, spacrCheckbutton, AnnotateApp
|
7
7
|
|
8
8
|
try:
|
9
9
|
ctypes.windll.shcore.SetProcessDpiAwareness(True)
|
@@ -202,7 +202,7 @@ def annotate(settings):
|
|
202
202
|
|
203
203
|
root = tk.Tk()
|
204
204
|
root.geometry(settings['geom'])
|
205
|
-
app =
|
205
|
+
app = AnnotateApp(root, db, src, image_type=settings['image_type'], channels=settings['channels'], image_size=settings['img_size'], grid_rows=settings['rows'], grid_cols=settings['columns'], annotation_column=settings['annotation_column'], normalize=settings['normalize'], percentiles=settings['percentiles'], measurement=settings['measurement'], threshold=settings['threshold'])
|
206
206
|
next_button = tk.Button(root, text="Next", command=app.next_page)
|
207
207
|
next_button.grid(row=app.grid_rows, column=app.grid_cols - 1)
|
208
208
|
back_button = tk.Button(root, text="Back", command=app.previous_page)
|
@@ -302,7 +302,7 @@ def annotate_with_image_refs(settings, root, shutdown_callback):
|
|
302
302
|
conn.commit()
|
303
303
|
conn.close()
|
304
304
|
|
305
|
-
app =
|
305
|
+
app = AnnotateApp(root, db, src, image_type=settings['image_type'], channels=settings['channels'], image_size=settings['img_size'], grid_rows=settings['rows'], grid_cols=settings['columns'], annotation_column=settings['annotation_column'], normalize=settings['normalize'], percentiles=settings['percentiles'], measurement=settings['measurement'], threshold=settings['threshold'])
|
306
306
|
|
307
307
|
# Set the canvas background to black
|
308
308
|
root.configure(bg='black')
|
spacr/icons/abort.png
ADDED
Binary file
|
spacr/icons/abort.svg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M349.5-349.5h262v-262h-262v262ZM480.57-132q-72.94 0-135.93-27.52-62.99-27.53-110.39-74.85-47.4-47.33-74.82-110.1Q132-407.25 132-480.2q0-72.03 27.52-135.59 27.53-63.56 74.85-110.71 47.33-47.15 110.1-74.32Q407.25-828 480.2-828q72.03 0 135.59 27.39 63.57 27.39 110.72 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.57q0 72.94-27.27 135.93-27.28 62.99-74.35 110.21-47.08 47.21-110.51 74.82Q552.43-132 480.57-132Zm-.14-22q135.07 0 230.32-95.18Q806-344.37 806-480.43q0-135.07-95-230.32Q616.01-806 480.07-806q-135.57 0-230.82 95Q154-616.01 154-480.07q0 135.57 95.18 230.82Q344.37-154 480.43-154ZM480-480Z"/></svg>
|
spacr/icons/download.png
ADDED
Binary file
|
spacr/icons/download.svg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M306-306h348v-22H306v22Zm173-132 124-123-16-16-97 97v-214h-22v214l-96-97-16 16 123 123Zm1.3 306q-72.21 0-135.43-27.52-63.22-27.53-110.62-74.85-47.4-47.33-74.82-110.26Q132-407.57 132-479.7q0-72.21 27.52-135.93 27.53-63.72 74.85-110.87 47.33-47.15 110.26-74.32Q407.57-828 479.7-828q72.21 0 135.94 27.39 63.72 27.39 110.87 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.3q0 72.21-27.27 135.43-27.28 63.22-74.35 110.62-47.08 47.4-110.51 74.82Q552.43-132 480.3-132Zm-.37-22q135.57 0 230.82-95.18Q806-344.37 806-479.93q0-135.57-95.18-230.82Q615.63-806 480.07-806q-135.57 0-230.82 95.18Q154-615.63 154-480.07q0 135.57 95.18 230.82Q344.37-154 479.93-154Zm.07-326Z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M306-306h348v-22H306v22Zm173-132 124-123-16-16-97 97v-214h-22v214l-96-97-16 16 123 123Zm1.3 306q-72.21 0-135.43-27.52-63.22-27.53-110.62-74.85-47.4-47.33-74.82-110.26Q132-407.57 132-479.7q0-72.21 27.52-135.93 27.53-63.72 74.85-110.87 47.33-47.15 110.26-74.32Q407.57-828 479.7-828q72.21 0 135.94 27.39 63.72 27.39 110.87 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.3q0 72.21-27.27 135.43-27.28 63.22-74.35 110.62-47.08 47.4-110.51 74.82Q552.43-132 480.3-132Zm-.37-22q135.57 0 230.82-95.18Q806-344.37 806-479.93q0-135.57-95.18-230.82Q615.63-806 480.07-806q-135.57 0-230.82 95.18Q154-615.63 154-480.07q0 135.57 95.18 230.82Q344.37-154 479.93-154Zm.07-326Z"/></svg>
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M747-671q12.55 0 23.78-10.51Q782-692.01 782-704.98q0-13.72-11.22-23.87Q759.55-739 747-739q-13.7 0-23.85 10.24Q713-718.52 713-704.68q0 12.68 10.15 23.18T747-671Zm-166.09 0q13.67 0 24.38-10.51Q616-692.01 616-704.98q0-13.72-10.71-23.87Q594.59-739 580.93-739q-12.81 0-22.87 10.24T548-704.68q0 12.68 9.84 23.18 9.83 10.5 23.07 10.5ZM570-535h188q-5-25-31.74-42.5-26.75-17.5-62.22-17.5-37.48 0-64.26 17.5Q573-560 570-535ZM296.79-116q-85.29 0-143.54-59.21Q95-234.42 95-318v-239h401v238.53q0 83.89-57.58 143.18Q380.84-116 296.79-116Zm-1.04-35q69.13 0 117.19-49T461-317.77V-522H130v204.23Q130-249 178.31-200q48.3 49 117.44 49ZM664-405q-28.58 0-57.79-8T561-434l2-38q20.4 14 45.33 23 24.94 9 55.67 9 68.65 0 117.33-47.33Q830-534.65 830-603.26V-810H497v189h-35v-224h403v241.53q0 82.89-58.62 140.68Q747.75-405 664-405Zm-449.23 19q13.37 0 23.3-9.59Q248-405.17 248-419q0-13.1-9.84-24.05Q228.33-454 215.09-454q-13.66 0-24.38 10.84Q180-432.32 180-419.39q0 14.09 10.7 23.74 10.7 9.65 24.07 9.65Zm164.9 0q13.07 0 23.2-9.59Q413-405.17 413-419q0-13.1-9.86-24.05Q393.28-454 380-454q-14.12 0-24.56 10.84T345-419.39q0 14.09 10.8 23.74 10.79 9.65 23.87 9.65Zm-82.71 140q37.48 0 64.26-17Q388-280 391-306H203q3 26 29.74 43 26.75 17 64.22 17Zm.04-92Zm367-286Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M103-221v-479h71v479h-71Zm103 0v-479h69v479h-69Zm103 0v-479h34v479h-34Zm103 0v-479h68v479h-68Zm103 0v-479h103v479H515Zm137 0v-479h34v479h-34Zm103 0v-479h103v479H755Z"/></svg>
|
spacr/icons/mask.png
ADDED
Binary file
|
spacr/icons/mask.svg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M480-309q48.46 0 84.23-29T610-414H349q9 47 45.77 76T480-309ZM301-591h129q0-27-19.08-46-19.09-19-46.5-19Q337-656 319-637.09q-18 18.92-18 46.09Zm229-1h130q0-27-18.87-45.5-18.88-18.5-46-18.5-27.83 0-46.48 18.41Q530-619.17 530-592Zm-50.2 476q-66.8 0-125.64-25.39t-103.5-70Q206-256 181-315.04 156-374.09 156-442v-402h648v402.09q0 67.91-25.2 127.04-25.21 59.12-69.5 103.5Q665-167 605.8-141.5q-59.21 25.5-126 25.5Zm-.3-35q120.5 0 205-84.59Q769-320.17 769-442v-367H191v366.78Q191-320 274.5-235.5t205 84.5Zm.5-329Z"/></svg>
|
spacr/icons/measure.png
ADDED
Binary file
|
spacr/icons/measure.svg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="m90-271-28-22 171-275 119.14 140L512-684l85 127q-7.71 3.67-16.79 6.17-9.07 2.5-16.21 6.83l-51-75-152.11 250L239-510 90-271ZM872-63 728-206q-19 14-38.33 20-19.32 6-40.67 6-54.92 0-92.96-38.06-38.04-38.06-38.04-93t38.06-93.44q38.06-38.5 93-38.5t93.44 38.33Q781-366.33 781-311q0 23-7 43t-22 37.45L897-88l-25 25ZM648.86-215q40.08 0 68.61-28.1T746-310.86q0-40.08-28.4-68.61T649.1-408q-40.1 0-68.1 28.4-28 28.4-28 68.5t28.1 68.1q28.1 28 67.76 28ZM720-555q-11-3-20.6-3.45-9.59-.46-17.4-.55l188-299 29 22-179 281Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="m407-351 202-129-202-129v258Zm73.3 219q-72.21 0-135.43-27.52-63.22-27.53-110.62-74.85-47.4-47.33-74.82-110.26Q132-407.57 132-479.7q0-72.21 27.52-135.93 27.53-63.72 74.85-110.87 47.33-47.15 110.26-74.32Q407.57-828 479.7-828q72.21 0 135.94 27.39 63.72 27.39 110.87 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.3q0 72.21-27.27 135.43-27.28 63.22-74.35 110.62-47.08 47.4-110.51 74.82Q552.43-132 480.3-132Zm-.37-22q135.57 0 230.82-95.18Q806-344.37 806-479.93q0-135.57-95.18-230.82Q615.63-806 480.07-806q-135.57 0-230.82 95.18Q154-615.63 154-480.07q0 135.57 95.18 230.82Q344.37-154 479.93-154Zm.07-326Z"/></svg>
|
spacr/icons/run.png
ADDED
Binary file
|
spacr/icons/run.svg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="m407-351 202-129-202-129v258Zm73.3 219q-72.21 0-135.43-27.52-63.22-27.53-110.62-74.85-47.4-47.33-74.82-110.26Q132-407.57 132-479.7q0-72.21 27.52-135.93 27.53-63.72 74.85-110.87 47.33-47.15 110.26-74.32Q407.57-828 479.7-828q72.21 0 135.94 27.39 63.72 27.39 110.87 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.3q0 72.21-27.27 135.43-27.28 63.22-74.35 110.62-47.08 47.4-110.51 74.82Q552.43-132 480.3-132Zm-.37-22q135.57 0 230.82-95.18Q806-344.37 806-479.93q0-135.57-95.18-230.82Q615.63-806 480.07-806q-135.57 0-230.82 95.18Q154-615.63 154-480.07q0 135.57 95.18 230.82Q344.37-154 479.93-154Zm.07-326Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M246-80v-20q0-141.45 56.5-215.72Q359-390 455-480q-97-90-153.5-164.28Q245-718.55 245-860v-21h34.66v21q0 17 1.08 33.5Q281.83-810 286-796h388.14q2.93-14 4.4-30.5Q680-843 680-860v-21h35v21q0 141.45-57 215.72Q601-570 506-480q95 89 152 163.78 57 74.77 57 216.22v20h-34.66v-20q0-17-1.58-33.5Q677.17-150 674-164H286.86q-3.93 14-4.9 30.5Q281-117 281-100v20h-35Zm99-565h269.18q18.82-25 33.32-54t23.5-62H290q7 34.65 21.25 62.86Q325.5-669.92 345-645Zm135 141q31.34-29.33 58.17-54.67Q565-584 588-610H371q22.75 26.33 50.25 51.67Q448.76-533 480-504ZM372-350h216q-23-26-49.83-51.33Q511.34-426.67 480-457q-31.34 30.33-58.17 55.67Q395-376 372-350Zm-81 151h380q-9-34.5-23.25-62.76Q633.5-290.03 614-315H346q-18.97 24.67-33.48 53.83Q298-232 291-199Z"/></svg>
|
spacr/icons/settings.png
ADDED
Binary file
|
spacr/icons/settings.svg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="m421.5-132-15-110.94Q383-249.5 355-265.5t-47.25-34l-101.25 46-59-105 90-66.5q-2.5-13.48-3.75-26.99-1.25-13.51-1.25-27.01 0-12 1.25-26t3.25-30l-89.5-68.5 59-102 101 44q21.5-17 47.5-32.5t50.5-22.5l16-111.5h118l15 112q26 9.5 49.25 23T649-661.5l106.5-44 58 102-94 70.54q3 14.96 4.5 27.96t1.5 24.75q0 10.75-1.75 23.84T719-426.42l93 67.92-59 105-104-47q-22.97 20.36-46.49 35.18Q579-250.5 554.5-244l-15 112h-118Zm17.74-22h80.79l15.69-111.5q29.86-8.07 54.11-21.69Q614.08-300.82 641-326l102.5 44 39.5-68.51L693-418q3.5-19 6-33.71t2.5-28.66q0-16.13-2.25-29.88T693-540l92-69-39.5-69-105 44q-19-20-49.75-39t-56.25-22.5L521.43-806H439l-11.5 110.07q-33 6.43-58.25 20.68T318-635l-102.5-43-40.5 69 90.5 65.5q-5 14-7 30.14t-2 33.83q0 17.03 1.75 31.78T264-418l-89 67 40.14 69 102.36-43q23.5 25.5 49.5 39.25T426.28-264l12.96 110Zm38.25-241q36.05 0 60.53-24.5Q562.5-444 562.5-480T538-540.5Q513.5-565 477.5-565T417-540.5Q392.5-516 392.5-480t24.5 60.5q24.5 24.5 60.49 24.5Zm3.01-85.5Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="m421.5-132-15-110.94Q383-249.5 355-265.5t-47.25-34l-101.25 46-59-105 90-66.5q-2.5-13.48-3.75-26.99-1.25-13.51-1.25-27.01 0-12 1.25-26t3.25-30l-89.5-68.5 59-102 101 44q21.5-17 47.5-32.5t50.5-22.5l16-111.5h118l15 112q26 9.5 49.25 23T649-661.5l106.5-44 58 102-94 70.54q3 14.96 4.5 27.96t1.5 24.75q0 10.75-1.75 23.84T719-426.42l93 67.92-59 105-104-47q-22.97 20.36-46.49 35.18Q579-250.5 554.5-244l-15 112h-118Zm17.74-22h80.79l15.69-111.5q29.86-8.07 54.11-21.69Q614.08-300.82 641-326l102.5 44 39.5-68.51L693-418q3.5-19 6-33.71t2.5-28.66q0-16.13-2.25-29.88T693-540l92-69-39.5-69-105 44q-19-20-49.75-39t-56.25-22.5L521.43-806H439l-11.5 110.07q-33 6.43-58.25 20.68T318-635l-102.5-43-40.5 69 90.5 65.5q-5 14-7 30.14t-2 33.83q0 17.03 1.75 31.78T264-418l-89 67 40.14 69 102.36-43q23.5 25.5 49.5 39.25T426.28-264l12.96 110Zm38.25-241q36.05 0 60.53-24.5Q562.5-444 562.5-480T538-540.5Q513.5-565 477.5-565T417-540.5Q392.5-516 392.5-480t24.5 60.5q24.5 24.5 60.49 24.5Zm3.01-85.5Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M349.5-349.5h262v-262h-262v262ZM480.57-132q-72.94 0-135.93-27.52-62.99-27.53-110.39-74.85-47.4-47.33-74.82-110.1Q132-407.25 132-480.2q0-72.03 27.52-135.59 27.53-63.56 74.85-110.71 47.33-47.15 110.1-74.32Q407.25-828 480.2-828q72.03 0 135.59 27.39 63.57 27.39 110.72 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.57q0 72.94-27.27 135.93-27.28 62.99-74.35 110.21-47.08 47.21-110.51 74.82Q552.43-132 480.57-132Zm-.14-22q135.07 0 230.32-95.18Q806-344.37 806-480.43q0-135.07-95-230.32Q616.01-806 480.07-806q-135.57 0-230.82 95Q154-616.01 154-480.07q0 135.57 95.18 230.82Q344.37-154 480.43-154ZM480-480Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M747-671q12.55 0 23.78-10.51Q782-692.01 782-704.98q0-13.72-11.22-23.87Q759.55-739 747-739q-13.7 0-23.85 10.24Q713-718.52 713-704.68q0 12.68 10.15 23.18T747-671Zm-166.09 0q13.67 0 24.38-10.51Q616-692.01 616-704.98q0-13.72-10.71-23.87Q594.59-739 580.93-739q-12.81 0-22.87 10.24T548-704.68q0 12.68 9.84 23.18 9.83 10.5 23.07 10.5ZM570-535h188q-5-25-31.74-42.5-26.75-17.5-62.22-17.5-37.48 0-64.26 17.5Q573-560 570-535ZM296.79-116q-85.29 0-143.54-59.21Q95-234.42 95-318v-239h401v238.53q0 83.89-57.58 143.18Q380.84-116 296.79-116Zm-1.04-35q69.13 0 117.19-49T461-317.77V-522H130v204.23Q130-249 178.31-200q48.3 49 117.44 49ZM664-405q-28.58 0-57.79-8T561-434l2-38q20.4 14 45.33 23 24.94 9 55.67 9 68.65 0 117.33-47.33Q830-534.65 830-603.26V-810H497v189h-35v-224h403v241.53q0 82.89-58.62 140.68Q747.75-405 664-405Zm-449.23 19q13.37 0 23.3-9.59Q248-405.17 248-419q0-13.1-9.84-24.05Q228.33-454 215.09-454q-13.66 0-24.38 10.84Q180-432.32 180-419.39q0 14.09 10.7 23.74 10.7 9.65 24.07 9.65Zm164.9 0q13.07 0 23.2-9.59Q413-405.17 413-419q0-13.1-9.86-24.05Q393.28-454 380-454q-14.12 0-24.56 10.84T345-419.39q0 14.09 10.8 23.74 10.79 9.65 23.87 9.65Zm-82.71 140q37.48 0 64.26-17Q388-280 391-306H203q3 26 29.74 43 26.75 17 64.22 17Zm.04-92Zm367-286Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M349.5-349.5h262v-262h-262v262ZM480.57-132q-72.94 0-135.93-27.52-62.99-27.53-110.39-74.85-47.4-47.33-74.82-110.1Q132-407.25 132-480.2q0-72.03 27.52-135.59 27.53-63.56 74.85-110.71 47.33-47.15 110.1-74.32Q407.25-828 480.2-828q72.03 0 135.59 27.39 63.57 27.39 110.72 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.57q0 72.94-27.27 135.93-27.28 62.99-74.35 110.21-47.08 47.21-110.51 74.82Q552.43-132 480.57-132Zm-.14-22q135.07 0 230.32-95.18Q806-344.37 806-480.43q0-135.07-95-230.32Q616.01-806 480.07-806q-135.57 0-230.82 95Q154-616.01 154-480.07q0 135.57 95.18 230.82Q344.37-154 480.43-154ZM480-480Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M463-132q-35.43 0-66.81-13.75Q364.82-159.5 345-187L164-430.5l9.5-9.5q4.5-5.5 11.65-7t15.35.5l141.5 66v-309.37q0-3.87 3.23-7t8-3.13q4.77 0 8.02 3.36t3.25 7.56v340.58L193-427l173.5 229q16.1 23.7 42.15 33.85Q434.69-154 463-154h153.5q45.03 0 77.27-31.65Q726-217.29 726-263.5V-402q0-29.4-19.62-48.95-19.63-19.55-47.88-19.55h-174v-22h174q36.38 0 62.94 26.4Q748-439.71 748-402v138.49q0 55.01-38.91 93.26Q670.19-132 616.5-132H463ZM233.4-620.5q-9.47-13.75-14.19-31.47-4.71-17.71-4.71-36.86 0-58.64 40.62-98.91Q295.74-828 353.15-828q57.4 0 98.37 40.5 40.98 40.5 40.98 99.13 0 19.07-5.21 36.63-5.22 17.56-13.73 31.24l-19.06-10.34q7.5-13.16 11.75-27.74 4.25-14.59 4.25-30.83 0-48.51-34.28-82.55T352.97-806q-48.97 0-82.72 33.95-33.75 33.96-33.75 83.27 0 15.82 3.75 30.3T252.5-631l-19.1 10.5Zm227.1 297Z"/></svg>
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M480.35-367Q535-367 574-406.35q39-39.36 39-94Q613-555 573.65-594q-39.36-39-94-39Q425-633 386-593.65q-39 39.36-39 94Q347-445 386.35-406q39.36 39 94 39Zm-.76-24q-45.59 0-77.09-31.91t-31.5-77.5q0-45.59 31.91-77.09t77.5-31.5q45.59 0 77.09 31.91t31.5 77.5q0 45.59-31.91 77.09t-77.5 31.5Zm.55 139Q356.5-252 253-319.25 149.5-386.5 96-500q53.5-113.5 156.86-180.75Q356.21-748 479.86-748 603.5-748 707-680.75 810.5-613.5 864-500q-53.5 113.5-156.86 180.75Q603.79-252 480.14-252ZM480-500Zm-.17 226q116.47 0 212.89-60.91Q789.14-395.81 840-500q-50.86-104.19-147.11-165.09Q596.64-726 480.17-726t-212.89 60.91Q170.86-604.19 120-500q50.86 104.19 147.11 165.09Q363.36-274 479.83-274Z"/></svg>
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M306-306h348v-22H306v22Zm173-132 124-123-16-16-97 97v-214h-22v214l-96-97-16 16 123 123Zm1.3 306q-72.21 0-135.43-27.52-63.22-27.53-110.62-74.85-47.4-47.33-74.82-110.26Q132-407.57 132-479.7q0-72.21 27.52-135.93 27.53-63.72 74.85-110.87 47.33-47.15 110.26-74.32Q407.57-828 479.7-828q72.21 0 135.94 27.39 63.72 27.39 110.87 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.3q0 72.21-27.27 135.43-27.28 63.22-74.35 110.62-47.08 47.4-110.51 74.82Q552.43-132 480.3-132Zm-.37-22q135.57 0 230.82-95.18Q806-344.37 806-479.93q0-135.57-95.18-230.82Q615.63-806 480.07-806q-135.57 0-230.82 95.18Q154-615.63 154-480.07q0 135.57 95.18 230.82Q344.37-154 479.93-154Zm.07-326Z"/></svg>
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M212-172v-66l541.92-543.42q3.08-3.08 8.08-4.83t9.25-1.75q4.3 0 9.28 1.75 4.97 1.75 7.47 4.75l33 33q3 3.5 5 7.97 2 4.48 2 9.28 0 4.25-1.75 9.25t-4.83 8.08L278-172h-66Zm22-22h35.5L716-641l-16.98-18.02L681-676 234-229.5v35.5Zm572.5-537.5-35-35 35 35Zm-107.48 72.48L681-676l35 35-16.98-18.02ZM574.5-172q64.87 0 119.18-29.25Q748-230.5 748-286.5q0-34.3-28.25-64.15Q691.5-380.5 635.5-397l-18 19q50.5 14 79.5 38.75t29 52.75q0 40.62-44.04 66.56Q637.91-194 574.5-194q-5.5 0-8.5 3.04-3 3.03-3 7.46 0 5.5 3 8.5t8.5 3Zm-320-241.5 16.5-18q-40.5-14-58.75-29.75T194-494.5q0-21.5 24.5-41t91.14-46.7q72.72-29.8 100.04-55.05Q437-662.5 437-694.5q0-39-36.75-66.25T306.5-788q-36 0-67.5 12.5T193.5-744q-2.5 4.5-2.25 8.75t3.75 6.75q2.5 2.5 7.24 2.12 4.75-.39 8.26-4.12 16.5-16.5 41.58-26t54.33-9.5q51.09 0 79.84 20.78T415-694.56q0 26.46-23.5 45.01Q368-631 300.5-602q-78 32-103.25 55.54T172-494.5q0 22.5 19.25 44t63.25 37Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M103-221v-479h71v479h-71Zm103 0v-479h69v479h-69Zm103 0v-479h34v479h-34Zm103 0v-479h68v479h-68Zm103 0v-479h103v479H515Zm137 0v-479h34v479h-34Zm103 0v-479h103v479H755Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M480-309q48.46 0 84.23-29T610-414H349q9 47 45.77 76T480-309ZM301-591h129q0-27-19.08-46-19.09-19-46.5-19Q337-656 319-637.09q-18 18.92-18 46.09Zm229-1h130q0-27-18.87-45.5-18.88-18.5-46-18.5-27.83 0-46.48 18.41Q530-619.17 530-592Zm-50.2 476q-66.8 0-125.64-25.39t-103.5-70Q206-256 181-315.04 156-374.09 156-442v-402h648v402.09q0 67.91-25.2 127.04-25.21 59.12-69.5 103.5Q665-167 605.8-141.5q-59.21 25.5-126 25.5Zm-.3-35q120.5 0 205-84.59Q769-320.17 769-442v-367H191v366.78Q191-320 274.5-235.5t205 84.5Zm.5-329Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="m90-271-28-22 171-275 119.14 140L512-684l85 127q-7.71 3.67-16.79 6.17-9.07 2.5-16.21 6.83l-51-75-152.11 250L239-510 90-271ZM872-63 728-206q-19 14-38.33 20-19.32 6-40.67 6-54.92 0-92.96-38.06-38.04-38.06-38.04-93t38.06-93.44q38.06-38.5 93-38.5t93.44 38.33Q781-366.33 781-311q0 23-7 43t-22 37.45L897-88l-25 25ZM648.86-215q40.08 0 68.61-28.1T746-310.86q0-40.08-28.4-68.61T649.1-408q-40.1 0-68.1 28.4-28 28.4-28 68.5t28.1 68.1q28.1 28 67.76 28ZM720-555q-11-3-20.6-3.45-9.59-.46-17.4-.55l188-299 29 22-179 281Z"/></svg>
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M372-295v-372l292 186-292 186Zm22-186Zm0 145 230-145-230-145v290Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="m407-351 202-129-202-129v258Zm73.3 219q-72.21 0-135.43-27.52-63.22-27.53-110.62-74.85-47.4-47.33-74.82-110.26Q132-407.57 132-479.7q0-72.21 27.52-135.93 27.53-63.72 74.85-110.87 47.33-47.15 110.26-74.32Q407.57-828 479.7-828q72.21 0 135.94 27.39 63.72 27.39 110.87 74.35 47.14 46.96 74.31 110.39Q828-552.43 828-480.3q0 72.21-27.27 135.43-27.28 63.22-74.35 110.62-47.08 47.4-110.51 74.82Q552.43-132 480.3-132Zm-.37-22q135.57 0 230.82-95.18Q806-344.37 806-479.93q0-135.57-95.18-230.82Q615.63-806 480.07-806q-135.57 0-230.82 95.18Q154-615.63 154-480.07q0 135.57 95.18 230.82Q344.37-154 479.93-154Zm.07-326Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M246-80v-20q0-141.45 56.5-215.72Q359-390 455-480q-97-90-153.5-164.28Q245-718.55 245-860v-21h34.66v21q0 17 1.08 33.5Q281.83-810 286-796h388.14q2.93-14 4.4-30.5Q680-843 680-860v-21h35v21q0 141.45-57 215.72Q601-570 506-480q95 89 152 163.78 57 74.77 57 216.22v20h-34.66v-20q0-17-1.58-33.5Q677.17-150 674-164H286.86q-3.93 14-4.9 30.5Q281-117 281-100v20h-35Zm99-565h269.18q18.82-25 33.32-54t23.5-62H290q7 34.65 21.25 62.86Q325.5-669.92 345-645Zm135 141q31.34-29.33 58.17-54.67Q565-584 588-610H371q22.75 26.33 50.25 51.67Q448.76-533 480-504ZM372-350h216q-23-26-49.83-51.33Q511.34-426.67 480-457q-31.34 30.33-58.17 55.67Q395-376 372-350Zm-81 151h380q-9-34.5-23.25-62.76Q633.5-290.03 614-315H346q-18.97 24.67-33.48 53.83Q298-232 291-199Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="m421.5-132-15-110.94Q383-249.5 355-265.5t-47.25-34l-101.25 46-59-105 90-66.5q-2.5-13.48-3.75-26.99-1.25-13.51-1.25-27.01 0-12 1.25-26t3.25-30l-89.5-68.5 59-102 101 44q21.5-17 47.5-32.5t50.5-22.5l16-111.5h118l15 112q26 9.5 49.25 23T649-661.5l106.5-44 58 102-94 70.54q3 14.96 4.5 27.96t1.5 24.75q0 10.75-1.75 23.84T719-426.42l93 67.92-59 105-104-47q-22.97 20.36-46.49 35.18Q579-250.5 554.5-244l-15 112h-118Zm17.74-22h80.79l15.69-111.5q29.86-8.07 54.11-21.69Q614.08-300.82 641-326l102.5 44 39.5-68.51L693-418q3.5-19 6-33.71t2.5-28.66q0-16.13-2.25-29.88T693-540l92-69-39.5-69-105 44q-19-20-49.75-39t-56.25-22.5L521.43-806H439l-11.5 110.07q-33 6.43-58.25 20.68T318-635l-102.5-43-40.5 69 90.5 65.5q-5 14-7 30.14t-2 33.83q0 17.03 1.75 31.78T264-418l-89 67 40.14 69 102.36-43q23.5 25.5 49.5 39.25T426.28-264l12.96 110Zm38.25-241q36.05 0 60.53-24.5Q562.5-444 562.5-480T538-540.5Q513.5-565 477.5-565T417-540.5Q392.5-516 392.5-480t24.5 60.5q24.5 24.5 60.49 24.5Zm3.01-85.5Z"/></svg>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M462.5-146v-184.5h22v81.5h330v22h-330v81h-22ZM146-227v-22h190.5v22H146Zm168.5-161.5V-469H146v-22h168.5v-81h22v183.5h-22Zm148-80.5v-22h352v22h-352ZM624-631v-183.5h22v81h168.5v22H646v80.5h-22Zm-478-80.5v-22h352v22H146Z"/></svg>
|
Binary file
|