From 1116f84ca00123ff3b8d16dbf2dd8e5b5ef2e070 Mon Sep 17 00:00:00 2001 From: s460930 Date: Thu, 7 Jan 2021 18:35:51 +0100 Subject: [PATCH] SMART-63 refactorize client app - views extracted into separated files --- README.md | 6 +- client/app.py | 276 +----------------------------- client/constants.py | 16 ++ client/views/abstract_view.py | 4 + client/views/login_view.py | 56 ++++++ client/views/main_view.py | 47 +++++ client/views/profile_view.py | 43 +++++ client/views/project_view.py | 50 ++++++ client/views/projects_add_view.py | 50 ++++++ client/views/projects_view.py | 44 +++++ client/views/register_view.py | 79 +++++++++ rest-app/db.sqlite3 | Bin 172032 -> 172032 bytes 12 files changed, 398 insertions(+), 273 deletions(-) create mode 100644 client/constants.py create mode 100644 client/views/abstract_view.py create mode 100644 client/views/login_view.py create mode 100644 client/views/main_view.py create mode 100644 client/views/profile_view.py create mode 100644 client/views/project_view.py create mode 100644 client/views/projects_add_view.py create mode 100644 client/views/projects_view.py create mode 100644 client/views/register_view.py diff --git a/README.md b/README.md index 603b2f3..e4ecb93 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,9 @@ To run tests: ### Gestures module -`pip install opencv-python ` +`cd gestures` -`pip install mediapipe ` +`pip install -r requirements.txt` -`python3 gesture_recognition.py ` +`python gesture_recognition.py ` diff --git a/client/app.py b/client/app.py index 941edb5..57adbfc 100644 --- a/client/app.py +++ b/client/app.py @@ -1,14 +1,9 @@ import tkinter as tk -import requests - -FONT = ("Verdana", 12) -FONT_B = ("Verdana", 12, 'bold') -FONT_LARGE = ("Verdana", 20) -URL = "http://localhost:8000/api/authenticate" -URL_REGISTER = "http://localhost:8000/api/register" -URL_PROFILE = "http://localhost:8000/api/profile" -URL_PROJECTS = "http://localhost:8000/api/projects" +from constants import LOGIN_VIEW_NAME +from views.login_view import LoginView +from views.main_view import MainView +from views.register_view import RegisterView class SmartPicasso(tk.Tk): @@ -29,11 +24,11 @@ class SmartPicasso(tk.Tk): for F in (LoginView, MainView, RegisterView): frame = F(container, self) - self.frames[F] = frame + self.frames[F.get_view_name()] = frame frame.grid(row=0, column=0, sticky="nsew") - self.show_frame(LoginView) + self.show_frame(LOGIN_VIEW_NAME) def show_frame(self, view, token=None): frame = self.frames[view] @@ -43,264 +38,5 @@ class SmartPicasso(tk.Tk): frame.token = token -class LoginView(tk.Frame): - - def __init__(self, parent, controller): - tk.Frame.__init__(self, parent) - label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) - label.pack(pady=10, padx=10) - - label1 = tk.Label(self, text='Login:', font=FONT) - label1.pack() - - input1 = tk.Entry(self) - input1.pack() - - label2 = tk.Label(self, text='Password:', font=FONT) - label2.pack() - - input2 = tk.Entry(self, show="*") - input2.pack() - - button = tk.Button(self, text="Login", font=FONT, - command=lambda: self.login(controller, input1.get(), input2.get())) - button.pack() - - button2 = tk.Button(self, text="Register", font=FONT, command=lambda: controller.show_frame(RegisterView)) - button2.pack() - - def login(self, controller, login, password): - print(login) - print(password) - data = { - "email": str(login), - "password": str(password) - } - resp = requests.post(URL, json=data) - print(resp) - if resp.status_code == 200: - response = resp.json() - token = response['token'] - - controller.show_frame(MainView, token) - else: - print("bad pass") - bad_pass_label = tk.Label(self, text='Wrong login/password!', font=FONT) - bad_pass_label.pack() - return () - - -class MainView(tk.Frame): - - def __init__(self, parent, controller): - tk.Frame.__init__(self, parent) - self.frames = {} - self.token = '' - for F in (ProfileView, ProjectsView, ProjectsAddView): - frame = F(parent, controller, self) - - self.frames[F] = frame - - frame.grid(row=0, column=0, sticky="nsew") - label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) - label.pack(pady=10, padx=10) - label_u = tk.Label(self, text="Main menu", font=FONT) - label_u.pack(pady=10, padx=10) - - button_projects = tk.Button(self, text="Projects", font=FONT, - command=lambda: self.show_frame(ProjectsView)) - button_projects.pack() - - button_profile = tk.Button(self, text="My profile", font=FONT, - command=lambda: self.show_frame(ProfileView)) - button_profile.pack() - - def show_frame(self, view): - frame = self.frames[view] - frame.tkraise() - - if self.token: - print(self.token) - frame.token = self.token - frame.start() - - -class RegisterView(tk.Frame): - - def __init__(self, parent, controller): - tk.Frame.__init__(self, parent) - label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) - label.pack(pady=10, padx=10) - label_u = tk.Label(self, text="Register", font=FONT) - label_u.pack(pady=10, padx=10) - - label0 = tk.Label(self, text='Email:', font=FONT) - label0.pack() - - input0 = tk.Entry(self) - input0.pack() - - label1 = tk.Label(self, text='Login:', font=FONT) - label1.pack() - - input1 = tk.Entry(self) - input1.pack() - - label2 = tk.Label(self, text='Password:', font=FONT) - label2.pack() - - input2 = tk.Entry(self, show="*") - input2.pack() - - label3 = tk.Label(self, text='First name:', font=FONT) - label3.pack() - - input3 = tk.Entry(self) - input3.pack() - - label4 = tk.Label(self, text='Last name:', font=FONT) - label4.pack() - - input4 = tk.Entry(self) - input4.pack() - - button1 = tk.Button(self, text="Register", font=FONT, - command=lambda: self.register(controller, input0.get(), input1.get(), input2.get(), - input3.get(), input4.get())) - button1.pack() - - button2 = tk.Button(self, text="Cancel", font=FONT, command=lambda: controller.show_frame(LoginView)) - button2.pack() - - def register(self, controller, email, login, passw, name, lastname): - data = { - "email": str(email), - "password": str(passw), - "profile": { - "username": str(login), - "first_name": str(name), - "last_name": str(lastname) - } - } - print(data) - response = requests.post(URL_REGISTER, json=data) - print(response) - if response.status_code == 201: - response = response.json() - controller.show_frame(LoginView) - else: - print("sth wrong") - bad_pass_label = tk.Label(self, text='Something went wrong!', font=FONT) - bad_pass_label.pack() - return () - - -class ProfileView(tk.Frame): - - def __init__(self, parent, controller, main_view_controller): - tk.Frame.__init__(self, parent) - self.token = '' - label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) - label.pack(pady=10, padx=10) - label_l1 = tk.Label(self, text="Login:", font=FONT_B) - label_l1.pack(pady=10, padx=10) - self.label_username = tk.Label(self, text='', font=FONT) - self.label_username.pack(pady=10, padx=10) - label_n1 = tk.Label(self, text="Name:", font=FONT_B) - label_n1.pack(pady=10, padx=10) - self.label_first_name = tk.Label(self, text='', font=FONT) - self.label_first_name.pack(pady=10, padx=10) - label_ln1 = tk.Label(self, text="Last name", font=FONT_B) - label_ln1.pack(pady=10, padx=10) - self.label_last_name = tk.Label(self, text='', font=FONT) - self.label_last_name.pack(pady=10, padx=10) - - button_profile = tk.Button(self, text="Back", font=FONT, - command=lambda: controller.show_frame(MainView, self.token)) - button_profile.pack() - - def start(self): - headers = {'Authorization': 'Bearer ' + self.token} - resp = requests.get(URL_PROFILE, headers=headers) - response = resp.json() - print(response) - self.label_username['text'] = response['profile']['username'] - self.label_first_name['text'] = response['profile']['first_name'] - self.label_last_name['text'] = response['profile']['last_name'] - - -class ProjectsView(tk.Frame): - - def __init__(self, parent, controller, main_view_controller): - tk.Frame.__init__(self, parent) - self.token = '' - self.projects_buttons = [] - label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) - label.pack(pady=10, padx=10) - button_add = tk.Button(self, text="Add project", font=FONT, - command=lambda: main_view_controller.show_frame(ProjectsAddView)) - button_add.pack() - - button_back = tk.Button(self, text="Back", font=FONT, - command=lambda: controller.show_frame(MainView, self.token)) - button_back.pack() - label0 = tk.Label(self, text='Projects:', font=FONT) - label0.pack() - - def start(self): - for button in self.projects_buttons: - button.destroy() - self.projects_buttons = [] - headers = {'Authorization': 'Bearer ' + self.token} - resp = requests.get(URL_PROJECTS, headers=headers) - response = resp.json() - print(response) - for projects in response: - button_proj = tk.Button(self, text=projects['name'], font=FONT) - button_proj.pack() - self.projects_buttons.append(button_proj) - - -class ProjectsAddView(tk.Frame): - - def __init__(self, parent, controller, main_view_controller): - tk.Frame.__init__(self, parent) - self.token = '' - - label0 = tk.Label(self, text='Project name:', font=FONT) - label0.pack() - - input0 = tk.Entry(self) - input0.pack() - - button_add = tk.Button(self, text="Confirm and add", font=FONT, - command=lambda: self.add_project(main_view_controller, input0.get())) - button_add.pack() - - button_back = tk.Button(self, text="Back", font=FONT, - command=lambda: main_view_controller.show_frame(ProjectsView)) - button_back.pack() - - def start(self): - print("ok") - - def add_project(self, controller, project_name): - headers = {'Authorization': 'Bearer ' + self.token} - data = { - "name": str(project_name) - } - print(data) - response = requests.post(URL_PROJECTS, json=data, headers=headers) - print(response) - if response.status_code == 201: - response = response.json() - controller.show_frame(ProjectsView) - else: - print("sth wrong") - bad_pass_label = tk.Label(self, text='Something went wrong!', font=FONT) - bad_pass_label.pack() - return () - - app = SmartPicasso() app.mainloop() diff --git a/client/constants.py b/client/constants.py new file mode 100644 index 0000000..115dd99 --- /dev/null +++ b/client/constants.py @@ -0,0 +1,16 @@ +FONT = ("Verdana", 12) +FONT_B = ("Verdana", 12, 'bold') +FONT_LARGE = ("Verdana", 20) + +URL_LOGIN = "http://localhost:8000/api/authenticate" +URL_REGISTER = "http://localhost:8000/api/register" +URL_PROFILE = "http://localhost:8000/api/profile" +URL_PROJECTS = "http://localhost:8000/api/projects" + +LOGIN_VIEW_NAME = 'login_view' +MAIN_VIEW_NAME = 'main_view' +REGISTER_VIEW_NAME = 'register_view' +PROFILE_VIEW_NAME = 'profile_view' +PROJECT_VIEW_NAME = 'project_view' +PROJECTS_ADD_VIEW_NAME = 'projects_add_view' +PROJECTS_VIEW_NAME = 'projects_view' diff --git a/client/views/abstract_view.py b/client/views/abstract_view.py new file mode 100644 index 0000000..00f70c6 --- /dev/null +++ b/client/views/abstract_view.py @@ -0,0 +1,4 @@ +class AbstractView: + @staticmethod + def get_view_name() -> str: + pass diff --git a/client/views/login_view.py b/client/views/login_view.py new file mode 100644 index 0000000..a633612 --- /dev/null +++ b/client/views/login_view.py @@ -0,0 +1,56 @@ +import requests +import tkinter as tk + +from constants import FONT, FONT_LARGE, URL_LOGIN, LOGIN_VIEW_NAME, REGISTER_VIEW_NAME, MAIN_VIEW_NAME +from views.abstract_view import AbstractView + + +class LoginView(tk.Frame, AbstractView): + + def __init__(self, parent, controller): + tk.Frame.__init__(self, parent) + label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) + label.pack(pady=10, padx=10) + + label1 = tk.Label(self, text='Login:', font=FONT) + label1.pack() + + input1 = tk.Entry(self) + input1.pack() + + label2 = tk.Label(self, text='Password:', font=FONT) + label2.pack() + + input2 = tk.Entry(self, show="*") + input2.pack() + + button = tk.Button(self, text="Login", font=FONT, + command=lambda: self.login(controller, input1.get(), input2.get())) + button.pack() + + button2 = tk.Button(self, text="Register", font=FONT, command=lambda: controller.show_frame(REGISTER_VIEW_NAME)) + button2.pack() + + @staticmethod + def get_view_name() -> str: + return LOGIN_VIEW_NAME + + def login(self, controller, login, password): + print(login) + print(password) + data = { + "email": str(login), + "password": str(password) + } + resp = requests.post(URL_LOGIN, json=data) + print(resp) + if resp.status_code == 200: + response = resp.json() + token = response['token'] + + controller.show_frame(MAIN_VIEW_NAME, token) + else: + print("bad pass") + bad_pass_label = tk.Label(self, text='Wrong login/password!', font=FONT) + bad_pass_label.pack() + return () diff --git a/client/views/main_view.py b/client/views/main_view.py new file mode 100644 index 0000000..421000c --- /dev/null +++ b/client/views/main_view.py @@ -0,0 +1,47 @@ +import tkinter as tk + +from constants import FONT, FONT_LARGE, MAIN_VIEW_NAME, PROJECTS_VIEW_NAME, PROFILE_VIEW_NAME +from views.profile_view import ProfileView +from views.project_view import ProjectView +from views.projects_add_view import ProjectsAddView +from views.projects_view import ProjectsView +from views.abstract_view import AbstractView + + +class MainView(tk.Frame, AbstractView): + + def __init__(self, parent, controller): + tk.Frame.__init__(self, parent) + self.frames = {} + self.token = '' + for F in (ProfileView, ProjectsView, ProjectsAddView, ProjectView): + frame = F(parent, controller, self) + + self.frames[F.get_view_name()] = frame + + frame.grid(row=0, column=0, sticky="nsew") + label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) + label.pack(pady=10, padx=10) + label_u = tk.Label(self, text="Main menu", font=FONT) + label_u.pack(pady=10, padx=10) + + button_projects = tk.Button(self, text="Projects", font=FONT, + command=lambda: self.show_frame(PROJECTS_VIEW_NAME)) + button_projects.pack() + + button_profile = tk.Button(self, text="My profile", font=FONT, + command=lambda: self.show_frame(PROFILE_VIEW_NAME)) + button_profile.pack() + + @staticmethod + def get_view_name() -> str: + return MAIN_VIEW_NAME + + def show_frame(self, view): + frame = self.frames[view] + frame.tkraise() + + if self.token: + print(self.token) + frame.token = self.token + frame.start() diff --git a/client/views/profile_view.py b/client/views/profile_view.py new file mode 100644 index 0000000..172ddb9 --- /dev/null +++ b/client/views/profile_view.py @@ -0,0 +1,43 @@ +import requests +import tkinter as tk + +from constants import FONT, FONT_B, FONT_LARGE, URL_PROFILE, PROFILE_VIEW_NAME, MAIN_VIEW_NAME +from views.abstract_view import AbstractView + + +class ProfileView(tk.Frame, AbstractView): + + def __init__(self, parent, controller, main_view_controller): + tk.Frame.__init__(self, parent) + self.token = '' + label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) + label.pack(pady=10, padx=10) + label_l1 = tk.Label(self, text="Login:", font=FONT_B) + label_l1.pack(pady=10, padx=10) + self.label_username = tk.Label(self, text='', font=FONT) + self.label_username.pack(pady=10, padx=10) + label_n1 = tk.Label(self, text="Name:", font=FONT_B) + label_n1.pack(pady=10, padx=10) + self.label_first_name = tk.Label(self, text='', font=FONT) + self.label_first_name.pack(pady=10, padx=10) + label_ln1 = tk.Label(self, text="Last name", font=FONT_B) + label_ln1.pack(pady=10, padx=10) + self.label_last_name = tk.Label(self, text='', font=FONT) + self.label_last_name.pack(pady=10, padx=10) + + button_profile = tk.Button(self, text="Back", font=FONT, + command=lambda: controller.show_frame(MAIN_VIEW_NAME, self.token)) + button_profile.pack() + + @staticmethod + def get_view_name() -> str: + return PROFILE_VIEW_NAME + + def start(self): + headers = {'Authorization': 'Bearer ' + self.token} + resp = requests.get(URL_PROFILE, headers=headers) + response = resp.json() + print(response) + self.label_username['text'] = response['profile']['username'] + self.label_first_name['text'] = response['profile']['first_name'] + self.label_last_name['text'] = response['profile']['last_name'] diff --git a/client/views/project_view.py b/client/views/project_view.py new file mode 100644 index 0000000..91d9ce1 --- /dev/null +++ b/client/views/project_view.py @@ -0,0 +1,50 @@ +import tkinter as tk + +from constants import PROJECT_VIEW_NAME +from views.abstract_view import AbstractView + + +class ProjectView(tk.Frame, AbstractView): + + def __init__(self, parent, controller, main_view_controller): + tk.Frame.__init__(self, parent) + self.token = '' + + # label0 = tk.Label(self, text='Project name:', font=FONT) + # label0.pack() + # + # input0 = tk.Entry(self) + # input0.pack() + # + # button_add = tk.Button(self, text="Confirm and add", font=FONT, + # command=lambda: self.add_project(main_view_controller, input0.get())) + # button_add.pack() + # + # button_back = tk.Button(self, text="Back", font=FONT, + # command=lambda: main_view_controller.show_frame(ProjectsView)) + # button_back.pack() + + @staticmethod + def get_view_name() -> str: + return PROJECT_VIEW_NAME + + def start(self): + # tutaj pobieranie info o projekcie + print("ok") + + # def add_project(self, controller, project_name): + # headers = {'Authorization': 'Bearer ' + self.token} + # data = { + # "name": str(project_name) + # } + # print(data) + # response = requests.post(URL_PROJECTS, json=data, headers=headers) + # print(response) + # if response.status_code == 201: + # response = response.json() + # controller.show_frame(ProjectsView) + # else: + # print("sth wrong") + # bad_pass_label = tk.Label(self, text='Something went wrong!', font=FONT) + # bad_pass_label.pack() + # return () diff --git a/client/views/projects_add_view.py b/client/views/projects_add_view.py new file mode 100644 index 0000000..21c23cd --- /dev/null +++ b/client/views/projects_add_view.py @@ -0,0 +1,50 @@ +import requests +import tkinter as tk + +from constants import FONT, URL_PROJECTS, PROJECTS_ADD_VIEW_NAME, PROJECTS_VIEW_NAME +from views.abstract_view import AbstractView + + +class ProjectsAddView(tk.Frame, AbstractView): + + def __init__(self, parent, controller, main_view_controller): + tk.Frame.__init__(self, parent) + self.token = '' + + label0 = tk.Label(self, text='Project name:', font=FONT) + label0.pack() + + input0 = tk.Entry(self) + input0.pack() + + button_add = tk.Button(self, text="Confirm and add", font=FONT, + command=lambda: self.add_project(main_view_controller, input0.get())) + button_add.pack() + + button_back = tk.Button(self, text="Back", font=FONT, + command=lambda: main_view_controller.show_frame(PROJECTS_VIEW_NAME)) + button_back.pack() + + @staticmethod + def get_view_name() -> str: + return PROJECTS_ADD_VIEW_NAME + + def start(self): + print("ok") + + def add_project(self, controller, project_name): + headers = {'Authorization': 'Bearer ' + self.token} + data = { + "name": str(project_name) + } + print(data) + response = requests.post(URL_PROJECTS, json=data, headers=headers) + print(response) + if response.status_code == 201: + response = response.json() + controller.show_frame(PROJECTS_VIEW_NAME) + else: + print("sth wrong") + bad_pass_label = tk.Label(self, text='Something went wrong!', font=FONT) + bad_pass_label.pack() + return () diff --git a/client/views/projects_view.py b/client/views/projects_view.py new file mode 100644 index 0000000..458bf79 --- /dev/null +++ b/client/views/projects_view.py @@ -0,0 +1,44 @@ +import requests +import tkinter as tk + +from constants import FONT, FONT_LARGE, URL_PROJECTS, PROJECTS_VIEW_NAME, PROJECTS_ADD_VIEW_NAME, PROJECT_VIEW_NAME, \ + MAIN_VIEW_NAME +from views.abstract_view import AbstractView + + +class ProjectsView(tk.Frame, AbstractView): + + def __init__(self, parent, controller, main_view_controller): + tk.Frame.__init__(self, parent) + self.token = '' + self.projects_buttons = [] + self.main_view_controller = main_view_controller + label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) + label.pack(pady=10, padx=10) + button_add = tk.Button(self, text="Add project", font=FONT, + command=lambda: self.main_view_controller.show_frame(PROJECTS_ADD_VIEW_NAME)) + button_add.pack() + + button_back = tk.Button(self, text="Back", font=FONT, + command=lambda: controller.show_frame(MAIN_VIEW_NAME, self.token)) + button_back.pack() + label0 = tk.Label(self, text='Projects:', font=FONT) + label0.pack() + + @staticmethod + def get_view_name() -> str: + return PROJECTS_VIEW_NAME + + def start(self): + for button in self.projects_buttons: + button.destroy() + self.projects_buttons = [] + headers = {'Authorization': 'Bearer ' + self.token} + resp = requests.get(URL_PROJECTS, headers=headers) + response = resp.json() + print(response) + for projects in response: + button_proj = tk.Button(self, text=projects['name'], font=FONT, + command=lambda: self.main_view_controller.show_frame(PROJECT_VIEW_NAME)) + button_proj.pack() + self.projects_buttons.append(button_proj) diff --git a/client/views/register_view.py b/client/views/register_view.py new file mode 100644 index 0000000..27c2bb6 --- /dev/null +++ b/client/views/register_view.py @@ -0,0 +1,79 @@ +import requests +import tkinter as tk + +from constants import FONT, FONT_LARGE, URL_REGISTER, REGISTER_VIEW_NAME, LOGIN_VIEW_NAME +from views.abstract_view import AbstractView + + +class RegisterView(tk.Frame, AbstractView): + + def __init__(self, parent, controller): + tk.Frame.__init__(self, parent) + label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE) + label.pack(pady=10, padx=10) + label_u = tk.Label(self, text="Register", font=FONT) + label_u.pack(pady=10, padx=10) + + label0 = tk.Label(self, text='Email:', font=FONT) + label0.pack() + + input0 = tk.Entry(self) + input0.pack() + + label1 = tk.Label(self, text='Login:', font=FONT) + label1.pack() + + input1 = tk.Entry(self) + input1.pack() + + label2 = tk.Label(self, text='Password:', font=FONT) + label2.pack() + + input2 = tk.Entry(self, show="*") + input2.pack() + + label3 = tk.Label(self, text='First name:', font=FONT) + label3.pack() + + input3 = tk.Entry(self) + input3.pack() + + label4 = tk.Label(self, text='Last name:', font=FONT) + label4.pack() + + input4 = tk.Entry(self) + input4.pack() + + button1 = tk.Button(self, text="Register", font=FONT, + command=lambda: self.register(controller, input0.get(), input1.get(), input2.get(), + input3.get(), input4.get())) + button1.pack() + + button2 = tk.Button(self, text="Cancel", font=FONT, command=lambda: controller.show_frame(LOGIN_VIEW_NAME)) + button2.pack() + + @staticmethod + def get_view_name() -> str: + return REGISTER_VIEW_NAME + + def register(self, controller, email, login, passw, name, lastname): + data = { + "email": str(email), + "password": str(passw), + "profile": { + "username": str(login), + "first_name": str(name), + "last_name": str(lastname) + } + } + print(data) + response = requests.post(URL_REGISTER, json=data) + print(response) + if response.status_code == 201: + response = response.json() + controller.show_frame(LOGIN_VIEW_NAME) + else: + print("sth wrong") + bad_pass_label = tk.Label(self, text='Something went wrong!', font=FONT) + bad_pass_label.pack() + return () diff --git a/rest-app/db.sqlite3 b/rest-app/db.sqlite3 index 0c273407f25adc6af25848c97f8a4658143c6f8c..769e01bd5416e14375f94f1a9c22820a5e31111a 100644 GIT binary patch delta 298 zcmZoTz}0YoYl1Xm%0wAw))WRk?+J}5ttpIKQ<#c)#SL{0fXH0I(A>({)XLCY&(Ol$ z*vx2pp*)kqc3wWF?}1{R+#U@4ReWFg@_1kHCh^?n3Fbb{?Xj^@k2|@Mfs@Tw($Ud3 z$sjGoz|zDtInB__#KOSBA~`87$-vCe$lS~{(I_#wB(=CC-q6Uv2-Q9#Gd*JqGgAvw z95QAGmJpYm&StV?;p61n!oc^Be>=Z2{~f+9+XV`k7V)X7F#9qRvYvDM%{nG+MmDek eTefpFFs2h%z^+FFHfNW delta 151 zcmV;I0BHY!zzTrC3XmHCVv!s}1!4d$N2q~hg=7J>WCC&x7cea`GA%JQATcsJGBP?a zHZC?eFfubZmvJ8gAh!(;0{2lA2n)*q4|)#t4sH$T4Pp%23{wlsv4OJ-x65k+IRq34 z4%q+>{tvegBM;mUNDkQ#k`HaMfx!;9*?s~m0R#vR*#Nf+fC8!xk&q{s{*D49xBZR+ F0})E%FKz$;