From 393087954d6ef8db494f687712c36de6751aa553 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 29 Jul 2025 16:28:35 +0100 Subject: [PATCH] Added larger resolutions / custom resolutions --- gui/__main__.py | 283 ++++++++++++++++-- gui/resources/images/1024x1280_button.png | Bin 1047 -> 0 bytes gui/resources/images/1024x760_button.png | Bin 1034 -> 0 bytes gui/resources/images/1152x1080_button.png | Bin 1012 -> 0 bytes gui/resources/images/1280x1024_button.png | Bin 1045 -> 0 bytes gui/resources/images/1920x1080_button.png | Bin 1000 -> 0 bytes gui/resources/images/800x600_button.png | Bin 999 -> 0 bytes gui/resources/images/resolution_template.png | Bin 0 -> 44933 bytes .../images/resolution_template_button.png | Bin 0 -> 1228 bytes 9 files changed, 259 insertions(+), 24 deletions(-) delete mode 100644 gui/resources/images/1024x1280_button.png delete mode 100644 gui/resources/images/1024x760_button.png delete mode 100644 gui/resources/images/1152x1080_button.png delete mode 100644 gui/resources/images/1280x1024_button.png delete mode 100644 gui/resources/images/1920x1080_button.png delete mode 100644 gui/resources/images/800x600_button.png create mode 100644 gui/resources/images/resolution_template.png create mode 100644 gui/resources/images/resolution_template_button.png diff --git a/gui/__main__.py b/gui/__main__.py index 00fe690..583d535 100644 --- a/gui/__main__.py +++ b/gui/__main__.py @@ -1959,7 +1959,7 @@ class ConnectionManager: self._is_synced = False self._is_profile_being_enabled = {} self.profile_button_objects = {} - + self.available_resolutions = ['800x600', '1024x760', '1152x1080', '1280x1024', '1920x1080', '2560x1440', '2560x1600', '1920x1440', '1792x1344', '2048x1152'] self._location_list = [] self._browser_list = [] @@ -1969,8 +1969,15 @@ class ConnectionManager: def set_profile_button_objects(self, profile_id, profile_button_objects): self.profile_button_objects[profile_id] = profile_button_objects - - + def get_available_resolutions(self, profile_id): + profile = ProfileController.get(profile_id) + if profile and hasattr(profile, 'resolution') and profile.resolution: + self.available_resolutions.append(profile.resolution) + return self.available_resolutions + + def add_custom_resolution(self, resolution): + self.available_resolutions.append(resolution) + def add_connected_profile(self, profile_id): self._connected_profiles.add(profile_id) @@ -3355,28 +3362,209 @@ class ScreenPage(Page): self.selected_dimentions_icon = None self.button_back.setVisible(True) self.title.setGeometry(585, 40, 200, 40); self.title.setText("Pick a Resolution") - self.display.setGeometry(QtCore.QRect(5, 50, 580, 435))#relacion 4:3 - - + self.display.setGeometry(QtCore.QRect(5, 50, 580, 435)) + self.showing_larger_resolutions = False + self.larger_resolution_buttons = [] self.create_interface_elements() + def create_interface_elements(self): self.buttonGroup = QButtonGroup(self) self.buttons = [] for j, (object_type, icon_name, geometry) in enumerate([ - (QPushButton, "800x600", (585, 90, 185, 75)), - (QPushButton, "1024x760", (585, 170, 185, 75)), - (QPushButton, "1152x1080", (585, 250, 185, 75)), - (QPushButton, "1280x1024", (585, 330, 185, 75)), - (QPushButton, "1920x1080", (585, 410, 185, 75)) + (QPushButton, "800x600", (595, 90, 180, 70)), + (QPushButton, "1024x760", (595, 170, 180, 70)), + (QPushButton, "1152x1080", (595, 250, 180, 70)), + (QPushButton, "1280x1024", (595, 330, 180, 70)), + (QPushButton, "1920x1080", (595, 410, 180, 70)) ]): boton = object_type(self) boton.setGeometry(*geometry) boton.setIconSize(boton.size()) boton.setCheckable(True) - boton.setIcon(QIcon(os.path.join(self.btn_path, f"{icon_name}_button.png"))) + boton.setIcon(QIcon(self.create_resolution_button_image(icon_name))) self.buttons.append(boton) self.buttonGroup.addButton(boton, j) - boton.clicked.connect(lambda _, dimentions=icon_name: self.show_dimentions(dimentions)) + boton.clicked.connect(lambda _, dimentions=icon_name: self.on_standard_resolution_clicked(dimentions)) + + self.larger_resolutions_button = QPushButton(self) + self.larger_resolutions_button.setGeometry(100, 450, 185, 50) + self.larger_resolutions_button.setIconSize(self.larger_resolutions_button.size()) + self.larger_resolutions_button.setIcon(QIcon(self.create_resolution_button_image("Larger Resolutions"))) + self.larger_resolutions_button.clicked.connect(self.show_larger_resolutions) + + self.custom_resolution_button = QPushButton(self) + self.custom_resolution_button.setGeometry(300, 450, 195, 50) + self.custom_resolution_button.setIconSize(self.custom_resolution_button.size()) + self.custom_resolution_button.setIcon(QIcon(self.create_resolution_button_image("Custom Resolution"))) + self.custom_resolution_button.clicked.connect(self.show_custom_resolution_dialog) + + def create_resolution_button_image(self, resolution_text): + template_path = os.path.join(self.btn_path, "resolution_template_button.png") + + if os.path.exists(template_path): + base_image = QPixmap(template_path) + if 'Resolution' in resolution_text: + base_image = base_image.scaled(195, 50) + else: + base_image = base_image.scaled(187, 75) + else: + base_image = QPixmap(185, 75) + base_image.fill(QColor(44, 62, 80)) + + painter = QPainter(base_image) + painter.setRenderHint(QPainter.RenderHint.Antialiasing) + + font = QFont() + font.setPointSize(10) + font.setBold(True) + painter.setFont(font) + + painter.setPen(QColor(0, 255, 255)) + + text_rect = base_image.rect() + painter.drawText(text_rect, Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter, resolution_text) + + painter.end() + return base_image + + def show_larger_resolutions(self): + if self.showing_larger_resolutions: + self.hide_larger_resolutions() + else: + self.hide_standard_resolutions() + self.showing_larger_resolutions = True + self.larger_resolutions_button.setIcon(QIcon(self.create_resolution_button_image("Standard Resolutions"))) + + larger_resolutions = [ + ("2560x1600", (595, 90, 180, 70)), + ("2560x1440", (595, 170, 180, 70)), + ("1920x1440", (595, 250, 180, 70)), + ("1792x1344", (595, 330, 180, 70)), + ("2048x1152", (595, 410, 180, 70)) + ] + + for i, (resolution, geometry) in enumerate(larger_resolutions): + button = QPushButton(self) + button.setGeometry(*geometry) + button.setIconSize(button.size()) + button.setCheckable(True) + button.setVisible(True) + button.setIcon(QIcon(self.create_resolution_button_image(resolution))) + button.clicked.connect(lambda _, res=resolution: self.on_larger_resolution_clicked(res)) + self.larger_resolution_buttons.append(button) + self.buttonGroup.addButton(button, len(self.buttons) + i) + + def hide_larger_resolutions(self): + for button in self.larger_resolution_buttons: + self.buttonGroup.removeButton(button) + button.deleteLater() + self.larger_resolution_buttons.clear() + self.showing_larger_resolutions = False + self.larger_resolutions_button.setIcon(QIcon(self.create_resolution_button_image("Larger Resolutions"))) + self.show_standard_resolutions() + + def hide_standard_resolutions(self): + for button in self.buttons: + button.setVisible(False) + + def show_standard_resolutions(self): + for button in self.buttons: + button.setVisible(True) + + def on_standard_resolution_clicked(self, dimentions): + self.custom_resolution_button.setChecked(False) + self.show_dimentions(dimentions) + + def on_larger_resolution_clicked(self, dimentions): + self.custom_resolution_button.setChecked(False) + self.show_dimentions(dimentions) + + def show_custom_resolution_dialog(self): + dialog = QDialog(self) + dialog.setWindowTitle("Custom Resolution") + dialog.setFixedSize(300, 150) + dialog.setModal(True) + dialog.setStyleSheet(""" + QDialog { + background-color: #2c3e50; + border: 2px solid #00ffff; + border-radius: 10px; + } + QLabel { + color: white; + font-size: 12px; + } + QLineEdit { + background-color: #34495e; + color: white; + border: 1px solid #00ffff; + border-radius: 5px; + padding: 5px; + font-size: 12px; + } + QPushButton { + background-color: #2c3e50; + color: white; + border: 2px solid #00ffff; + border-radius: 5px; + padding: 8px; + font-size: 12px; + } + QPushButton:hover { + background-color: #34495e; + } + """) + + layout = QVBoxLayout() + + input_layout = QHBoxLayout() + width_label = QLabel("Width:") + width_input = QLineEdit() + width_input.setPlaceholderText("1920") + height_label = QLabel("Height:") + height_input = QLineEdit() + height_input.setPlaceholderText("1080") + + input_layout.addWidget(width_label) + input_layout.addWidget(width_input) + input_layout.addWidget(height_label) + input_layout.addWidget(height_input) + + button_layout = QHBoxLayout() + ok_button = QPushButton("OK") + cancel_button = QPushButton("Cancel") + + button_layout.addWidget(ok_button) + button_layout.addWidget(cancel_button) + + layout.addLayout(input_layout) + layout.addLayout(button_layout) + dialog.setLayout(layout) + + def validate_and_accept(): + try: + width = int(width_input.text()) + height = int(height_input.text()) + + if width <= 0 or height <= 0: + QMessageBox.warning(dialog, "Invalid Resolution", "Width and height must be positive numbers.") + return + + if width > 10000 or height > 10000: + QMessageBox.warning(dialog, "Invalid Resolution", "Resolution too large. Maximum 10000x10000.") + return + + custom_resolution = f"{width}x{height}" + self.show_dimentions(custom_resolution) + dialog.accept() + + except ValueError: + QMessageBox.warning(dialog, "Invalid Input", "Please enter valid numbers for width and height.") + + ok_button.clicked.connect(validate_and_accept) + cancel_button.clicked.connect(dialog.reject) + + dialog.exec() def update_swarp_json(self): inserted_data = { @@ -3385,13 +3573,46 @@ class ScreenPage(Page): self.update_status.write_data(inserted_data) - - def show_dimentions(self, dimentions): - self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"{dimentions}.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio)) + try: + image_path = os.path.join(self.btn_path, f"{dimentions}.png") + if os.path.exists(image_path): + self.display.setPixmap(QPixmap(image_path).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio)) + else: + self.create_resolution_preview_image(dimentions) + except: + self.display.clear() + self.selected_dimentions_icon = dimentions self.button_next.setVisible(True) - self.update_swarp_json() + self.update_swarp_json() + + def create_resolution_preview_image(self, resolution_text): + template_path = os.path.join(self.btn_path, "resolution_template.png") + + if os.path.exists(template_path): + base_image = QPixmap(template_path) + base_image = base_image.scaled(580, 435, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation) + else: + base_image = QPixmap(580, 435) + base_image.fill(QColor(44, 62, 80)) + + painter = QPainter(base_image) + painter.setRenderHint(QPainter.RenderHint.Antialiasing) + + font = QFont() + font.setPointSize(24) + font.setBold(True) + painter.setFont(font) + + painter.setPen(QColor(0, 255, 255)) + + text_rect = base_image.rect() + painter.drawText(text_rect, Qt.AlignmentFlag.AlignCenter, resolution_text) + + painter.end() + + self.display.setPixmap(base_image) class ResumePage(Page): def __init__(self, page_stack, main_window=None, parent=None): @@ -3506,6 +3727,14 @@ class ResumePage(Page): parent_label.setPixmap(base_image) parent_label.show() self.labels_creados.append(parent_label) + elif item == 'dimentions': + base_image = ScreenPage.create_resolution_button_image(self, text) + geometry = (585, initial_y + i * label_height, 185, 75) + parent_label = QLabel(self) + parent_label.setGeometry(*geometry) + parent_label.setPixmap(base_image) + parent_label.show() + self.labels_creados.append(parent_label) else: icon_path = os.path.join(self.btn_path, f"{text}_button.png") geometry = (585, initial_y + i * label_height, 185, 75) @@ -3811,9 +4040,13 @@ class EditorPage(Page): self.profiles_data = menu_page.match_core_profiles(profiles_dict=new_profiles) self.data_profile = self.profiles_data[selected_profiles_str].copy() + profile_id = int(selected_profiles_str.split('_')[1]) + self.data_profile['id'] = profile_id + if selected_profiles_str in self.temp_changes: for key, value in self.temp_changes[selected_profiles_str].items(): self.data_profile[key] = value + self.name.textChanged.connect(self.update_name_value) self.verificate(self.data_profile, selected_profiles_str) @@ -3827,7 +4060,7 @@ class EditorPage(Page): "connection": ['browser-only', 'system-wide'], "location": self.connection_manager.get_location_list(), "browser": self.connection_manager.get_browser_list(), - "dimentions": ['800x600', '1024x760', '1152x1080', '1280x1024', '1920x1080'] + "dimentions": self.connection_manager.get_available_resolutions(data_profile.get('id', '')) }, selected_profile_str) elif protocol == "residential" or protocol == "hidetor": @@ -3836,7 +4069,7 @@ class EditorPage(Page): "connection": ['tor', 'just proxy'], "location": self.connection_manager.get_location_list(), "browser": self.connection_manager.get_browser_list(), - "dimentions": ['800x600', '1024x760', '1152x1080', '1280x1024', '1920x1080'] + "dimentions": self.connection_manager.get_available_resolutions(data_profile.get('id', '')) }, selected_profile_str) elif protocol == "lokinet": @@ -3917,9 +4150,13 @@ class EditorPage(Page): image_path = os.path.join(self.btn_path, f"button_{current_value}.png") base_image = QPixmap(image_path) if base_image.isNull(): - locations = self.connection_manager.get_location_info(current_value) fallback_path = os.path.join(self.btn_path, "default_location_button.png") - base_image = LocationPage.create_location_button_image(locations.country_name, fallback_path) + base_image = LocationPage.create_location_button_image(current_value, fallback_path) + + elif key == 'dimentions': + current_value = f"{data_profile.get(key, '')}" + if current_value != 'None': + base_image = ScreenPage.create_resolution_button_image(self, current_value) else: image_path = os.path.join(self.btn_path, f"{data_profile.get(key, '')}_button.png") current_value = data_profile.get(key, '') @@ -6230,6 +6467,4 @@ if __name__ == "__main__": app = QApplication(sys.argv) window = CustomWindow() window.show() - sys.exit(app.exec()) - - + sys.exit(app.exec()) \ No newline at end of file diff --git a/gui/resources/images/1024x1280_button.png b/gui/resources/images/1024x1280_button.png deleted file mode 100644 index 1a679ce91bed064d667875cc07a268d2521adfd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1047 zcmeAS@N?(olHy`uVBq!ia0vp^JAv4ngBeIlYhJ4XQqKc?LR|m<|IcvyHVECi#c=N) z!?R}$7cMZ|yvcCq4#UHT3_w{R11Nj^IK#AQ4C~f0T)hes0jfEDn&IhFkb=jLK_b_$ zgG92jfCe+Xc>@v$>H?Z`{yf9py$p{Yfy`gBgyGU923J>xS+f}O@)+9N8FubuICqZW z=uw7?7eOXmxx%nS*7y-l~%m_a#iWbnc|jkKc&QJwG?C_>AFk8Dv5;KXrn#H3##>rTibi8{QCj z@jL#Vu=P?&W!}rL7OeCYDt}W|wD{D)GynBe%T%jRy|MbEEAr`<{^Gg$2bsf?K# zCrLrO>b7V)ujO=~U;D&It?wq&JO{b#_vzd<-zG&*xp8D&y6ZgYes@+4L3zvSnln%I zmwuZ1+^lTHyjzRUs}%_!&tc?ulnPoImf!behr`D?htu^dpDIsE-oH+0)#JhyAK0IK zxaq#Gc%J)0smH&Wi+v?m=-SO57-TI%G-MJH;`{r@2C zrB*n*fS>hKsMey_`vW$c>=V1bq0CbDK*oHI3wp7)4FuW@CH^f5IjCiG;OoNVv|IIa z4b-pypZ11RE>i#LlwdzgB;r3qrRx-Z+d7~F+S(SyrM8_q^PfD$r z5^~*mr|#*-JoCrdn%_kYwr4k1>pr!cb6frCYLOMUS4XUWzx2-?yTD4@@cef`*18{` i!mOsbdg=esdCKyjr+r0aGs9d^hV*pxb6Mw<&;$U?3k{?I diff --git a/gui/resources/images/1024x760_button.png b/gui/resources/images/1024x760_button.png deleted file mode 100644 index 2063416e779ee79d33b336e8eb7704c0460392ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1034 zcmZ8gZA?>F7(U|6lz}o?bi=qQI2Otf78ryP#>aY75$Le6O*%B~>L_2bI+S$+mXQ{0 z3>RdO;$;ds8IWY^{&Zh-mhEw(wJnW3 zw_00K7JZPv+7si87GGT*sQP9$%NRmC^M&e$S?_Eq5^2ycEoc%KeHw&1d2qWD)tFf; z$DF^8)X_%nUKIl1!iyuuq_B4_i3~r^26;g8NqTyE`H2GdqoIG$CmlDh98M{9f8Kj~ zecwK97kN5z@p;ZJKsHI544WQhlF+SbqRigq`K(~FFJ!o z9pU2F0egI>-mk2uzgacyT{-zNodk#zLHU;L8qb?bd!WO7bl3H@C_!LiaWO=a1 zH|PF)eKwvjp_bRwH)P{iN^iSU2KX>L6!G>`vKyXr*Ld^tmNq_5JR-+%^1mz-^?Tuv0C5pq3eQ z{ac}7ozQ)~-=#lQ_3a#*Lw}g5_A5-Fo?V+P)#UX2lm}hUcYJHA(AhJe=47}`v6rn9 z*gvyzbRn|jxAdc|z?dL)ZDO|MZp$xQ*}M01!$0)xHO0eDh3?FO4Tb6+5@r35V0rMmeim*~DV>Cvw5Apy$dO_C_;Kn+5{)Y-IT*^4NCZOnC)_lF{UQqM; z3c><8ZaSgmkg!KF92r%*Q$T_M19TYw_U}$chh?#!9B>U~=Dh}`wO2Ck;ASFAOAZGw zL&0e;V7~*6t3PU{U(u#AH%w{b&sma!pF2I0n$wmY2vH!ODb^}DHTkZxx0)6snChnF z=;-f1fJx28H0=%x-nvd6s4i;M7DgaNvCS8>=P%{nX>iFsNzlPFeh@v$>H?Z`{yf9py$p{Yfy`gBgyGU923J>xS+f}0+Zpom7|xwz*twJ8 z;zfo72N;eX1sQVX3d6>YAjYp>3@t4T&!2;g0wSQY&!3^}zkeBCzGT?84WtYr`}Hfx zVXt06xj@0!uR&%)WdHxy>+YKibeL~RkY6x^`;Ozs($xMxsSr?Exh|&S>8H7U?G8en zpY}Ma{couHbaHa|ldS6|34zW>yRXbz@$pgZiU0nO{|B`Ee_-(cW9!Zh2mYUURPaIJ z3Te4}! z^Y82l^RG<%GIuvae#fji`|n+OVG~qeJo9wSGo$|-;@x-mwit*w$p00rlyBBgZ2SLz zr|7xRP$TEErER?-Klib$5$a>unR~)n?$d;JnL!KOD1~mH{(;X< z_e9h;J58pqx_x%mE|;3DnE1F@@o9%$=jV3uDqD5<^F3zP0oGcoo9dT6rXkI$#RsQi8 zfrlV0Fykk@J>S#QzU;KG&)G9)+83SH)j7LnjiiK2ZqD1bFt3f~X2lF^eV-SZ6cmdKI;Vst E0J-AyH~;_u diff --git a/gui/resources/images/1280x1024_button.png b/gui/resources/images/1280x1024_button.png deleted file mode 100644 index d50ad88f362195124ea783adedc23027acb3b0f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1045 zcmeAS@N?(olHy`uVBq!ia0vp^JAv4ngBeIlYhJ4XQqKc?LR|m<|IcvyHVECi#c=N) z!?R}$7cMZ|yvcCq4#UHT3_w{R11Nj^IK#AQ4C~f0T)hes0jfEDn&IhFkb=jLK_b_$ zgG92jfCe+Xc>@v$>H?Z`{yf9py$p{Yfy`gBgyGU923J>xS+f}O@)+9N8FubuICqZW z=uw7?7eOXmxx%ncLZHd$(l4fG~jB@Mib4o*Xr(F$=bxb;qKeVvbW~{u6Wh(+0{h!P5rC&jCH%2 z*NNrcRGi2C>9}x4+@$d4>Dz6sv?ne7^LL`pQ$LO6bBa!BA_#q-f2sR=ubN>f9!S3+b?3x7)YZU-0T_;VqT zjEe;V17=9ch%97la#Ejv=IA3mhO84$eOUX?9L)XS;j}2gk%#lPx45+7mdPQdp(k%$ za}7RwhyB2om#?pe)rcp)V}A_4u=xSw%_DHdZG6 zOyFDRdyajEW$c-QA(pmg=9b9`e2X^jJo%M5Z0lb2S2ZnL_220hzB#jS z*|)x(+$v!u-ZJ6`f2(}{m}4lYnEr15ruDxX=IfT-vH7es_1@>2>y8XE&JP4uMrovF zK2}bjZGP_#dmrc0C!Z|>m(BeBysrLv*PUP9F1OP(^WQO_6HKW&JLmIR8Q0USvc=*b zo(ZboH*ODo|9E%$JEq#>Kc6X0`aetj$nKpXUsqo;+}>dRU-0JgS^vLFd%2vsTW32sm;u?V;AqjgzW`P zOGP9KUk8w@vZGTgt<@a!4G#fuEruQTl3%P?&k!<{<}r%y9{{0L$Il^s6J;OYuA zhT-d1hR2UVg2#_DWMwgI+s1J9Do6p)kn`smfaU{@&C6q$HH)FWonhxrhI8i_jvj@Y zeB}zm#*GXI4lq131;|0ih{pC-pV>1$S5xzI%Izfk8o$JVD+ zpH4RXcTNcGKDy${$49lZ9{gTRCX|Ff=a@C^5v$iTo< z?djqeQo(rVT%eSrq5#_k!9N*HQZ7gSnP*n)ueJ4?D=H&(=*&&S_<+q%xt6UlzmoEr z;rv0KZwK4p;VjO77EjaD4kuhAuiQE61`uzuF@)s|zyEZj zqee}be$4dacbkOeBUpN5<~1HFSh~Ky@_ViD(}fF@ofWra9xv7AI&gpY`HAx8En%o;;k%_u6{m^4~H?rJwG8 z^;qY-*1JcW_q^sh;t)Qi+F4Eh&bx{KKif|UjGgrS&)5G8Ef_X3ww{;k)era?_C;^+ z)85yApT3`l9?I@s|H^*;__J!7O&3F3qe2?fznlLBJa$^_E&tbZ>9*kqu0}Uy{>yjx zHC#->)fQRYJi9j}OJ&m?W%oBCs-asi8JPUmTx;>N>egoFxke?A7S?WFJZID4P0Dkb zrpC_vSkHCZ&a-=FTGH|jZ>AmgPrS*#I`W35bh~NB42^jSb3u8|)78&qol`;+0DlVf A$^ZZW diff --git a/gui/resources/images/800x600_button.png b/gui/resources/images/800x600_button.png deleted file mode 100644 index 75fc2b857f78be54697504fde076a28155ffdf6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 999 zcmeAS@N?(olHy`uVBq!ia0vp^JAv4ngBeIlYhJ4XQcnVWLR|m<|IcvyHVECi#c=N) z!?R}$7cMZ|yvcCq4#UHT3_w{R11Nj^IK#AQ4C~f0T)hes0jfEDn&IhFkb=jLK_b_$ zgG92jfCe+Xc>@v$>H?Z`{yf9py$p{Yfy`gBgyGU923J>xygY_kvl!aj8FubuICqZW z=uw7?7eOXmxx%n zP%cpL^=pO$2jE=SiX-=duJS1f@(X5g-*Nm{n%e&-6#^JAJv}t@BjFJK+FFJ2LC^{?%Z(T|A|Kh9~3@Ly09Q& zPJrPI1_q`yPZ!6K3dTF<9OWDpMch7m|7hS+%G22JUv(Ahmpb13_x5(p&dCNdwG7jW zv$h2Yr0$Fg?mlaF+*-G7Bc$x?=}1_ zh!3(WXS`=nUit5D;qvDb|G&A`cudEThc&@LE{S2rvgL2f?)`tcE=B56>D5JD@qE)t zZvQ%R!smpu+@}fcHcu4)uZGb4l_!MvdqzDCyc_lL#MW~)ujE|kt-r6&zPB+fHAH`! z+q%+c!8Tn+@%y9eikB)aJoSC*j@l&|EYtjgrmqryo;~rWNb{_a`NuN%)vceicJVF4 zjO967d;DI$Qu?f!y?4&M_4W$xrJq_pEw*7aP+n~Pv)Q>wNj-g${8ORH%_mNBzn$*w zuDG!2i-Xfzr_J&6 zQj0uROxJ1a*E#Sc*3G5#)EeopA!VPAov{iDxtB7Pk*vw&m7;hjlSMH=Rg1SoU`)rlP6Q(=U2X5 z^fFbEz1s5m);~9_LsAqL*}lKP93RuY^2cxS@Du0NpC|$Y4Hk|d=D+pPo6M3VIu<>c zUzpN!hE>C?Gtz3`zt@JwPrmOFee>o`{H*HNyvu%;J^#(Ps8Zr*p_7T{W|`Mhk{(aD zReBX#cUPy;FSB<3Mb=}Do7%troTAO7wmW>u^I*A#6#0|KH3M#jzI}aMbNx+sz001p ppDmu6?tWb0ZJ#jp@|5+c=Y03O^^aN_cHVdGH9YHC zYp?zHsV+{2t-G~m7{+kogt2Z6qc33?-bj8+_{oaVYp27%I4j(oMl;6>x<6$YAv1C8 zsA-||UX-~O46*q}Uv8GwO=5F-&732JJ545pTyi^oQ!Fu-Nf$h-h$`!MHYM}S9aj&% zI8)Czofa6Vq+YRu^Yfg}=Z$;tDdOGZShq><7Wpk*d_D5hJFk-3_jwgB-$j<>&3;}} zJ>Z*Sx%swQoP% zQz%>`tg~l7uTH8+R8(!ONQ{Vl|M4mLFU?;nE%J=YQ|yZrg&S4TU*?C7Kfm=-*e~~_HJ(4H8*kj9;zxsscmz95)FshCNd|Lg*I+{-fia8vmbi=;C{q+}; z4~ClsR?iSc{<3HQ@?`M8wpa-nhbrG`P5l$lJ#Vk~*MB)z8g-nf-8@g5M zvlf$%bX5zU>{Wq>H~JcLoP|A@YPHCBy7~-QmSSXnYasrVTYAN`m0avvxN#=fO4s;) z6k93ea>XHQuqWkkxAFNB3*-I6@TG)Ius;5YL137nTSqNJ1;Zf^gjxrApx%1&FyjRy z&F6bQKa^Ds2N;PP-s)it-x3K3ng(yA_vG7?IM{ zkiNK-a)mK%B#H|*lDs_ulkvCk{X)o;3yM5&ohWq|8Z(aBO!nn$=;irQs*9; zR*tm2U|VCHXX8&Rb_GEuyr*a`d^1;WIM{C-?$GQ>kjYWCR33sN=!TCeXx^R@9 z>iXC^3BWR@ z^BAv}i+_u)-_0ieA}xX}!PVx=79CMVkXHk43siiZKIv4-sFM(guk37Mv4*k=CSXOI z3imkpXac@9y#Zvm>OC1%9${chh)Bi<_mBUNTT8l-se>s~GC(@tuFt(a0rxyl;f;$n zPaA_elR48h2r~DX;Z2){(rqNDB!FCri>I}wc%9Q=@`gC;1SbEK$*QjHci?{Ud;gSi zDM1~&QIMQ`jt+i=ALAtdi0Ov(IiT^>AwIiNXg}x_V3a>NKGDsw6hOUPqY5UWrtcDb zy&~}Nu8yM(DW1Uw_8TaV(#;e}o&^u0ZyNJQquu&!(_=cqcfDRNHvNItiG7jZ3X?OMGDo zX_9-zozGskQCKXUDq^yG9i)NQB<(JiuW+Ve(lGE7Vdhr2*aKT@c2U*o;k4f9+s^1B zV7ykn|JI_>qc`xG;(j3H`(cqg-28pY)Tv76n8lPQ=mNhol5oLhjKkF>w^6JjyA2Lw z#;&Xg6z#?V{W9|9lA$Om+q_E=U>`+znWG%F>l-@eBWl?qxd349n5a?hakWsr(n62K z%#(WP{_t}937Oh{sn=1_2$d_~dlS=xJ2cZ`^+EF}K9K8C1f^pOF?^Ml%a8t1{(ws=)LO_y1T1WUf3r(3VEZn_bwUlBkygW3R*(0fY$4kRBP7-$LIo`HyGn3z zMdC8bWAc3mf}f7RwH|-xQYS5))>{JY=le$eWpOnAoMpW~_J zQjlfQ77v^&`Y$Xc>;3LnT`$02?Izo0b?9Z{3BoTA_%WXX+7`kF{E)P77`g%ca8gWw z1Uyo*%(5vB(uw!2K)@*WR#ECE;iE)MO^a!>QRNVc+vz~)IFhEHb}}vKjm0~O?6EGD zQ2i0o64w&_&QJtgIp_+-%OruVxn4Mm0%nP96zGS3kEr9gz?Fx!z`u5T@wd3pYmNeD z^3K_fqF+Xu+6t@}xMMF9>1G@|O%R6psH~jTuKs7C5 z`ctx8wrc^`OG>1zrch{}w0$6Sr*J1ca*HQxB3|g^pfJ3UA!l18)FI2`1X=GYzr<=nIOt1h@ZZ~zO7?6=q+|5RJZcpQEcZ>N-9T*1N;zxQ;- zbb*nsRYx;zbHP6H>T6FP>5rS*H7H~!gyo(_A%c7~_yGgM*~zGOUmHMNWo_%k$S;fS5cCJz9igfI}k!hgxq#x38hP;k_1(4gj``b6GvoooFGE( z_I!@kHKdo}Nw>9|8HUP-?NZtb+asG%_JR6Eg*Ax7D;0yD88zgQf&+bt$nF#=XoAW0q`SM#Jt`vtA6wt=Dz7NDz zQf@l#MA=qb!JXA{$QRV1+uM=Gb1ee(iS3b-k3K-$6iwQe;P=OS)RT)x0J2$Wep`TU z%M2Y`+48Z8Y(~!b_jp3hZ@>+&`}wdG3t$}XCva@R6y~lOyQTr4tU-A0@t!9Z%JY5 z&Dw_pa3YG4rU1~LJ@M`a{5kCmG#P2%&xw_p?DJyGgG}_XS%D_F1R;U38A0Sy`K-o^nF2mPZ9-=sB6WC50(FqEjxTUU- zE_%?wp*sBAR6-<=h6v`bj|Lp*CWFiYx-@J z&-wq!AlH&EdHi(8%XAe_op-=rG8d{*3SlEow5R8D3S`+&oGeq^}Amk{n zcC$94-aBxpCP7mzvl)|z+CjVvXy54{EGgbDk7Qe#pkzoAG>>9*RT7AGAxSZ)4<#TA zfvk5CdX7e6v2+NSK;fW1L-B2H-nDc9#IKNeiH;X%;ZMoo&W8A!*(Jjix2)g}0ET&r zndoNoee3eGl*cbAp?EWxv&q`KC^OIDh5_eZy)^`H0^$wRl?Q?&NQPz-yTlHEQo$u% zPhQ~q+uiU_*JMLNUU_{trBNdlc0BKwW$w+inAXNpRre@SaTiF*X5WeS_!hqHtZ|Oj zySEjg9!;o((s0d>m$>+Q#FHK=&H0O2vr{q-WhCrdF&$TS@s|ziGA~*#L1V3SsiwuC z=-M1})O?-$fwku_39nl&*@OjeSP)p|C^vkyIdj3qyfN7miN5_o(ziTh(q=Sh1qP`z zwOmg4o8*7s>un*a@%weRC|0vy(~2C=%ZS3>^#60iVP}PeD~3~kL(G26=s;+OkM9P? z;|9**_F{rt(PFG-i$-3SQM&W80r;)*P9B2l*+9|_Tq?_$jKvxm%cbgr;`Jm#-EC^W z46Vv=xEC9A<}GOB(it^Ffyx`s$k?GRiEPiv2$(Z^_?N|v)ixlwez_d)IUAG$N%q~F z%TSAvCTlsY8E1^&qnUzyCG1<#X6Li`^Ql(rnEn{z9gm~j2b>=20q(A@QEP+caLPfI zRvb|)uC%MO+|{vTZvX`-vF4oA89?f{V_u{6 zTNw!kNya-y#>&7iZ)WPqKU6c*+?t+gKgmO!Sc*!8L9KXx#H_vyxDa zbA~5P2$$VOQ)4;HrL+WyMP4h)dasEwL{Fs{t4d2O1~0%R85jtB%31yWBXPA}2-wln z@_93@RiBvo-3Knk=dCYgVUd_LNot$%%BNP)j&`x^Sp+BLy4o8j3&dkUK5Y6IH0O3h z3kMJ1h2sPTh*GinXj2)tF5<{6c~CJpX8_$!?s&J;976Uye)@bj_N~&xI{qrCg78<< zL_1NwSt9e)IY(9hebX&as5_%0bYc2E_>&)hH(S>W@F)Ee&jPug*mt|@e_`4G&ZX4w zQO(-`&8ZBFa-C%fva@3mRqx%gVys{w+TQt=RWv3<(sF1PK?suN2zXx_tW}H z#{(G&xR4xyqptM~NJ6;~k=#ei7MF|{FZh#k{b{Rw&7m1D|K>o7)aUB*vN1osfh-TE}~$n z7hizT+gIFdEQf|aDRt9!K)RL9YxwiVj#jk>w9(+uNmO*2W7FEB7T^1lqZZK)@swiF zRnh>fJ$Cq5(S|{lshQgZpk_0o>mrJ#yMu)#%`e7do_tROGXMP&Lgw#D>4zrz9PSDr zwJH-*@g9M!7)`1czIXE8>8NlDEFn9uygv;^l#DbINP#n*@a>Kp3(WInA)XsDy4+zQ zu~;`0AO63PJ7|+NHa>zYw{rDTpi*@115OuO=3IvcUq>03L8L(_|M0WFW1d+$xiuJy z<`}j6GNNExV|L=%nyg$$&SzI&il?;AR6u9v8DsR71nd-pWY}m7Z0-zOo1|5!;m7EG zINQ&UpA7i#*s8CeCmMfv#~}$hx;==tmaeTNf}BmZ z54}p6P$G-h?efUVaX0XWkxJO)#K`p{8oT(0KaoX}HgX>7Zusol$O(Z3XVro|DZ$(q z-0aVl`$pj3xnDEfMgF(L-{FERg?^>%=ris(d`csy@>aN+PzYhR1@!t8H2p{f2zq7a zN2BT#4caE{k5H(q(lPK(8%|TesImn}(rBt5CGN6?%-Sx;<~u^CF)GFIK9n?)ZOy6P zEBYKEeBqGSDU|cH&K5v1YUe8zm2nIk#sAuEId+$p&vokXMK@m3eS_gAPWmd&m3!#D zF)^I>#(L4h9W}jw@UGe3;o-W)M&CAc!EhjgtL(k$Z}`b_9#5>mJUzG(IEF2;@Z3Kb zw;3T5#$sO6$jfG%DRk#TCgR7z`F3U}?T?ds++o}tB(hfUnyr58Nzt$X7-^xrY9y<; z5#owlb$39krW>D9I0{>L5#!)qk&c^m;2!Xx)#Z){wqGnyCp?$EGSq+EpK_8vhhtBG zGCdb$o6qkkNk4H6C8s2^#LfcAr=ywl42i2OSyDzR0!Km>t2Vtn0j=?CTD+C%Dnohd zOBtodJ8+|f3Fq(I_2+l|++WJWA#IO%$5qwL9ZqR24Q{~`Tl4YYM%qsSoFr}kqjZ;c zoL3Y@>B3+{2{6e$+V5h*Q(M^K)A^o5AvDceQnJd@8KnYb_TW%Ujbznx(%ezRp0-88 zWEUKpg0J=n6#bFGFg&uu`ES|t7kBr6F5o|Dob$k#HnPG8HWG`-j!|g+O!l$`Pkt}; z27|6AP)!yZOT2QKxA~NfegN-q!RS#azT721m(Z={K55m9GR=^l^ttF`f(O%w->KWd zJ-L)a+j0?yqY^o1Qcha@1W)_Z`vgi3qX#0=8(c=|p!IIemw7)6qjV6q?KGjK+}oH~ z|GltaQkd88Sx7m&Eh3$K-UsI35|VC$HZ0-+jlA|hY!qca^X($$Ep>JjhZDMWTsKNn zH#dzwdar(`ua^;Cv-jWf8)Co4p-Gklye3Rz+Oly9lUuT8H;S93K|G#3DA*5gxa(^K z0nRJ!_s@jzCzBD(1PnLNyQD9gSBk$Oj;u=_XXLwGVw{rqw-z!L5#P0>ysa0c@-=_7 zNVB1wFf)R8u+9};#KVQiL)Zhld=lNREKuZ={A6+BOA5#p*iMDtx!6^)u@uz&4NcAU zLCy8&pT==Nub`7aQh2MH(kR}%kr)Dz@F2}EIFtR;z>l1Bq*46aCnIV04~^pTMKb~d zQCP9KBN%q9wZ!{g_9|4*;#@>bg8zY*sB02W2aHga6FJE;+Ww0?PWCgOh5qQ*9}@~0 zudfXXD2cFMoo)Fke#&JW#OD5#xcLc6HMQ;jS!0YxWHO=4%g?-E%%835GwqkMUQHXm zQcsSkq*Os14fwKh>JemE&)SP|Js!9KjbDROCC~%uKLy1{viT4-<{Q}H9awOJTK1}{ zcp(}H`}d7$3+HHDEg%0}Swy_!{B`-L|B=Xs*6kp8$NUHJv=&G>5D>}_I$CnZH7oT6jJVpKRs`)YPA_3h#~v?)V+uN7aGIr}F)6oZN6B>e@x z*z&;0w?cx|7vXWA!?ge$SO+q>z#)o?xyDg$>r22*eHOSA))C-{)a4%5ZUQzz| zQ3L5K9VFR8TCJYHbEgqxT{_hVs?f8U=P#jZe;-C;=U&*^o#G1#h;}qNMFEqUpy~lX z_uW7#%d>S|JaAi=aknK@rt2)Sd;sx7AKx9Octu8f4wUWO#4^eRrAjShT>0W6rEn9| zMIb4fHjwh(8M?j9|J_7ZGVf#&YC(fCb^dZip5P#g6Xdy|Ppd;JAEDbVP+0&@H=yKn zFq2tk-%9lL|j=ck3BuL(WkS{oq@I?lX8wDHKhiJJRWVU&i#1 zf>wEel-og2L;*U12jR^R=2FU9ta(r%q54PYsjdxOMIkUFz!oBheM33L=-*2d?keW* zZi^OfWLH41uiUet4;a_-#Z$E1k?Sb|XKsT$`RcOWXtSOarbEha5A&agS_GWilO)Ye zIg5s{nNt90`8|As>Nn}F484218yaocK9r76-lnbt&+3nZ91--Kag{qVANo>U$#>v- z^TIhb2Ge3uC?}G)fvDXksF30xjX=oOdrni1+!nz33T@zHWVN-7%-0sJ+dIm~zbpgMqRhpiXwamyK~`3qzPB9VZN=I19FGX}7V}l-Nen_{=NF z$AU$S4UeX5%?}#xU-`qcD!gVawT7ynmnevGu}VDL<)oz(LoN{xr!ejurGFzWTL(g} z(uOc)0ZIFIDd-&B+Me9h7T~`0+x} zjs;O6V|}5YV)h^OneuYp*2$l#bt8KW)CWCpJNp|-4-CwwXR{V5%|L05jgR2VtO6=t zpyDA7k!sREBlsL@t)wAx9jjO2 z_@`@txO;J(!Xo_Vb^J6iyZf4c$OV+V;y(04=9c8fqjg;vW#pmlIG|lI^nc%RP#VB^ z-=XvyNFPE#)K;M#B3e~Vz?6fLnuCU$cPgWB%tnMOO5-_EcDX$`lJ?(MQL;D#@DWBc z*O;TaEt2zzRcQ;J8`K5Q^QZ1po|6}02_C$|wa2J|39^o85Muak!x2VkQ0LXcM3A@r z@JA&VX#H=`L1R7p-=2ei2UX9m`w#HY|Dc`&u)o{accI54rB8KCF;9J+RolxVikl#V zWa{byGn4V6V%k5TF7TlEx^rVY(EUWV9X#ZApP`*lr(*>?x|M$!o|iaV5)KPG<&y5_ z?M1;(+yp4+E%|9Yno5ZMh`W8q4SiXC{xvF=`yvQ~XSa5z6oQR)m9<^Od+%Iz%m;l; zp-3)nP+2RN+{4K!xlmIu8}-1S(!5~}bU$Qfc_%oTC=iCx#IQZ1Vrc87152B3BY%gA zNni_Nci{i(hre{-NdiPRRWJ@=(-SBsPgVm(YC=heCu$386TA51aOMf{1eIkem(j9b~=Ptmw#D!WtE)Nw>h%SPJ~RNqzXSv zEl{lodc<&gHHB(wrB1B9M2TtLqbVN^0OVG&)1{0G)I6FDK=k zfCL5JNx%mM*RfY?AC*zs0QI3#qrdhvp0n}_Izao~*6KNU%F(?)G{U!e7ECcf()z2e zT4$IQ;)XAR*0zG-rznlGu|^th-#TxSKDs&LAP7irY-Ba)13H`6lO8s!2w_+x?@GA_ zC8R;Ghs*OI4^&JZAj=tdPkN#}Qykpck??KKdQ?Beec*i#`0d((5o^-J;1&;;_}Dhb zL+N^YT-B4Q51(yAX(CRBpgE&#>XL3t>Usg9R!{;+td_;H{(3IT*fCPa0gzTKU0#Sv zNg|8YSy911;X>gPeJBA(G+Jju>yFSki!}h+xTh)e>|nqwS7|e?46PfG4l%yWVow-; z0~RkAhT}z!xowZCkT7sfgJjxReVF9yHWc^8ux-nOCXwcfWl-So{U_e0D4qwJUS75n zFK}GY?Q=MRl5?YOWTB=m$Xc(1k|i_a-SLPghf(HY1^o`nW;*<&MIZ?aAL1SEY^y(- z)}GttZC;_}mq0t<;DW7Ih*5{ZugL+?X-+EjRM%CG;@T*Z^K>xMwR9`RUdZ`5imPqPXR>#jC=Z+jNW=jjU66+UNOP;e@Pfl0~{XNKW7vup#P zvdy{_KL~UbUOF}1XB(>EgHF|1R?U<_c%eTN4oL*$jn1f~apdIy|vHZ1~!)~#V(iVGvoDOiD zIa)j%b*2CMmH<|L3Oa1q?hrZ3e7g+QY4$_HaE+ zRIE=gL;T2vG`&I9C2SFm$;mUCpfC1f!oEWvLm23%p|~=Po~}gQ1(auUC}aD`NRotw zKi~*Y0;N1Qw;7U_tI(~RP0(_T6fT03FP-6o-xcbiZ3vkWHsl%}yv))tqpKV9|K0hE6mY_!it;#t$S=f`)_tH3<*gwo zubtz5%2XJMtWXEhKSe!jjekQtq+^MDt0;|gWX>8~iN$&ovoFog!HXa`M2C1@DoaM?8#u?c}% zLfG~Aay+jjW2Q>xK|4SGsHb8nR_tG`}oh{VFslW$gw(duGS*K@DEK3D;ap(Bfir zKSckF7EzlQ|Ib8=pxZ1a&NUOfYp&T$y8dqVvu+^R-i<9nSrw7I0xqs3XF%tf;jx76 z8Bh+#*6J~3*u0*QRq4#z3$50cAA5^X|dlm_G}G*QUV3U)Ev_!y!0WO1+Epw?6_<@O+CECmsMtkQF=bx zLV{G+Oh1amoeieH8lpZH+6TOK@{SxIM5#QJc6~^}5`XSVY5y0ICjHf%c&8xh0RVtd zQ>&eErL1uc3)yyVY}<956Hzw(!?)bId-YMoik**oUfwO}U_Nt8oXetHXFt9woquO~ zs`H3nllq#Ham);D9CIAtrUd$R(jpi@oisg>joz{N@WSwhD-Q^t~r4+1914buyK zvOS)XApKmDq+lm8iVcP-Ek3Bz~3D2_I(+ib< zTQec!aEUgumBnPvwQxUByDul;*Hwr_%nQoEBDoMygvukoYxKsffp654hDI$pL202} zO|DWJYJHpHC>_Zd$TAbzK+0`G!v?|_WEOY1!VX$3qOiJb*8*HwmE$?fG~@12laj+(UXcAdcpVG%b#|-32pfeLI#|qdj znKy23b`0(Wp&d>0g`;WNH_v`SIhv+`tC}l1r&A{Do4_rD0V@Yxp`3v^qjsAxv**kS z+R*Vr_+FSqS=6+e)TMaJ!9a6`SGQDNq|WLm)xUWcX|wv{z^f)Wa9dCkI+&xP9I+)B z?aq|QR)Qhk4~zWKZQ$h2WKhY7981c=@+jb4paigSV=|+PDj8ddx}+DQU<)@i&+S5N z*CO(^iqNy&yOe?o`oacUJg}os2|naL`!hC@l4+TgrhW&gWYjW8CP{PSML_;Irn^Zn#MM3e;#k^@fXV zD+oL@u6>JQBtC0<27%8uCa-&XrHG((MX}f(b*()9QIP#S&dn~UHVR5fOA*1921Raq z_=;WNQj=qpyJXp+KAnlNtFg7x8Cd8q+qe&}Z(wAoW?4)z*tJKY|wD+Er`$y@{rH8& zU;)9DiPV7tt#ecfJC@)h={7*TGz~t{4SjaGFA0|bJkrbB;P@;Jy0Vm2;}6ohvLGvl zt}NmlJFx1?60gy@#)M|NmDe6}uW0LcSj+T6yC&wouI1*g7SGAK>EykfwH zsRNcd;!fAO1E9{30LHaj%mNh03u9o%y$>8kH(VmiC(*?;<_|o&uwAPjK)z9rd(5Bh zfj2bqwpi+HHF{P1mE$lYl-0t+en{Ng7JpdfWXPw@a6AS1G*`a1jT`0CK5eQtw+p^0 zzOw-qy?l3wa<%bN4Rj3Ld22Mj-Zi*Yrf_)(h5hmX_6v@~ds{v}K26PjB^xargD)%y zZQvWd_RXRY2*%vxmNKurh|Shsxz||08dGydB-`Bkd#8LoU23 zssB^GL-h8i2Ol;lOv%ULU%8Prg$h&0h?>w^y&J86FIetq+nIrXCXRC%du+6L&Hn*b C|En_q literal 0 HcmV?d00001 diff --git a/gui/resources/images/resolution_template_button.png b/gui/resources/images/resolution_template_button.png new file mode 100644 index 0000000000000000000000000000000000000000..9623e8bda4e40f0f1f2e45acf23c98ae4da3cbca GIT binary patch literal 1228 zcmeAS@N?(olHy`uVBq!ia0vp^JAv4ngAGXPd{^@WQjEnx?oJHr&dI!FU|?zUba4!+ zh~vNbasZ@!;?XZ!M$W6wX&o}S-! zTvI5XL#MED#iQ%yh94&{G3Hvh^3nWDQDmN zEZADQ)-3N$ptJL@zb9Y6j(>G^wY{nR|3h!4F1cLnwVZu_kInS#Yj^Hgo;@!g9($Mn zJ->;u@e*nCs;OuFX39=jxKz==;6kX-?x(A>GABkw=}mRBGyJ&v(T_b#obGJith}rI z{VcyZ5*ux#qrC$ZI`^*3?7gX-o%b#zI{NwX6Z35>S6p9TAI#C}yr z-vsa|26#6vTqu`&uV$4%C5QFY^ZeTLr$73!^w{zBD^_>^eizkLtXtjasyu&Q-HOfW zyGwt6>-pOm;j-WuQ@7i^)4eMeFW!ADIEIf=o>A$0Vfxj8h7-ISXMPe?D3UJ^<7Mr* zBQRTYREo->u}S>K-s;wMac_gwHixdfveZNIO^BWSnwUHnS=qba)RP1orMP1D?eTQ) z|F&{#Y3|2WzdQG|?Ta}TnNaXy!?yhW3!a{y+-x&#i+`X=Scgqt``0fod*0oDfBD|t z?Q{B1*)Uz@6v^|intJk0pw`qsZ|o=aX>`p~zppZJ{gf};m&lu1Yy0~BTmA1}{FJkP zq1%sa7Az3($n)=$-M#GU>f2qf(?wkO*H=w?aoAjOPTlwS-Cd8>?p>9wi}VT8pKxd1 zn;V6Wy}hd2)#t~*NPcosS#izulF8*?U+w+L>D<_Qd-At$wyReEe)R3h?TPv}r*`jp znBTK<70afZezF!9)`zYRt9kov$)*#P;pmND%vn;W9Gd2L1Yq#CA*s)v^+7g;}5{{JU-?;X)fna2Nq z4_po3J$ZkuYrj_ao-c8=@khg-cXC|uQ}}u2chaZ%)>q>`>27MM?hR6~S`RFq7(8A5 KT-G@yGywqo7(eC! literal 0 HcmV?d00001