diff --git a/DemoPrograms old/ButtonClick.wav b/DemoPrograms old/ButtonClick.wav
deleted file mode 100644
index f774f70e..00000000
Binary files a/DemoPrograms old/ButtonClick.wav and /dev/null differ
diff --git a/DemoPrograms old/Color-Guide.png b/DemoPrograms old/Color-Guide.png
deleted file mode 100644
index bd9edbe4..00000000
Binary files a/DemoPrograms old/Color-Guide.png and /dev/null differ
diff --git a/DemoPrograms old/Color-names.png b/DemoPrograms old/Color-names.png
deleted file mode 100644
index f81654f7..00000000
Binary files a/DemoPrograms old/Color-names.png and /dev/null differ
diff --git a/DemoPrograms old/Demo_All_Widgets.py b/DemoPrograms old/Demo_All_Widgets.py
deleted file mode 100644
index 51d70237..00000000
--- a/DemoPrograms old/Demo_All_Widgets.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-sg.ChangeLookAndFeel('GreenTan')
-
-# ------ Menu Definition ------ #
-menu_def = [['&File', ['&Open', '&Save', 'E&xit', 'Properties']],
- ['&Edit', ['Paste', ['Special', 'Normal', ], 'Undo'], ],
- ['&Help', '&About...'], ]
-
-# ------ Column Definition ------ #
-column1 = [[sg.Text('Column 1', background_color='lightblue', justification='center', size=(10, 1))],
- [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')],
- [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2')],
- [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3')]]
-
-layout = [
- [sg.Menu(menu_def, tearoff=True)],
- [sg.Text('(Almost) All widgets in one Window!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)],
- [sg.Text('Here is some text.... and a place to enter text')],
- [sg.InputText('This is my text')],
- [sg.Frame(layout=[
- [sg.Checkbox('Checkbox', size=(10,1)), sg.Checkbox('My second checkbox!', default=True)],
- [sg.Radio('My first Radio! ', "RADIO1", default=True, size=(10,1)), sg.Radio('My second Radio!', "RADIO1")]], title='Options',title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='Use these to set flags')],
- [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)),
- sg.Multiline(default_text='A second multi-line', size=(35, 3))],
- [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 1)),
- sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)],
- [sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))],
- [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)),
- sg.Frame('Labelled Group',[[
- sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25, tick_interval=25),
- sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75),
- sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10),
- sg.Column(column1, background_color='lightblue')]])],
- [sg.Text('_' * 80)],
- [sg.Text('Choose A Folder', size=(35, 1))],
- [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'),
- sg.InputText('Default Folder'), sg.FolderBrowse()],
- [sg.Submit(tooltip='Click to submit this form'), sg.Cancel()]]
-
-window = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False).Layout(layout)
-event, values = window.Read()
-
-sg.Popup('Title',
- 'The results of the window.',
- 'The button clicked was "{}"'.format(event),
- 'The values are', values)
-
-
diff --git a/DemoPrograms old/Demo_Animated_GIFs.py b/DemoPrograms old/Demo_Animated_GIFs.py
deleted file mode 100644
index e6f02868..00000000
--- a/DemoPrograms old/Demo_Animated_GIFs.py
+++ /dev/null
@@ -1,65 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Demo_Animated_GIFs.py
-
- Shows how to:
- * Use PopupAnimated
- * Use animated GIF in a custom window layout
- * Store your GIFs in base64 format inside this source file (copy and paste into your source file)
-
- The first image that uses PopupAnimated will stop after a few seconds on its own.
- The remaining images are shown 1 at a time. To move on to the next image, click the current image.
- If you want to exit before reaching the final image, right click the image and choose 'exit'
-"""
-
-# ---------------------------- Base 64 GIFs ----------------------------
-
-line_boxes = b'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'
-
-
-line_bubbles = b'R0lGODlhoAAUAOMAAHx+fNTS1KSipKyqrPz6/KSmpKyurPz+/P7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCQAIACwAAAAAoAAUAAAE/hDJSau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru/jERiGwEFD+AWHmSJQSDQyk04kRnlsLqUX6nMatVanBYAYMCCAx2RzNjwun9tqC4Etdq/Rdjk9/a7HK3N4fxSBcBgBaGIBh4kAixeIiY8WkWiTFZVjlxSZioySn5ahmqOeF3tiAhioAKqnja4WrLEVs6uwt4m0FLavurlouxOsAxgCjcUXx4nJFst4xsjRzNPQytLX1NnWlI2bE52OpeKQ3uPfEuHoCOrn7uWgWQOCGAfzYwaDEwT3YvlT/QD8k4dmoJyABgEh1CeBX0GGCBzigyjRH0QEPq542XIh45d6KF0yeORoYSSWkiFBahSZsmNLHjBjypxJs6bNmzhz6tzJs6fPn0BBRAAAIfkECQkAFgAsAAAAAKAAFACEBAIEhIaETEpM1NbU9Pb0NDI0dHJ0rK6s3N7cFBYU/P78PD48fH58tLa0XFpc3Nrc/Pr8NDY0dHZ0tLK05OLkHBoc/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf6gJY5kaZ5oqq5s675wLM90bd94ru9879OIQKEQoPyOyKSNUAA4nw6IckqtjiCJpxaQkFq/YJ2iudUWTpBBo/HwohRqtvsEX7dVdTk+fk/l+298cyZ/gyWFJghlZQglEAcBDJIThiIQE5KTlRaXmQyUKJ2ZoGiYo5uimqGmqqWepCapn4MGi1sGJQOekg8ougyRvL6SwQy9J7/FxybJmcu5xM7DwNLI0cLW1NgjC7ZaESUH158o4rsT5bvkJ+av6efv7uzq6PPw9vLc3k/gJKzB9UyYixQpYLhoBd8RXCcQIcOD1BLaW2iQxEBqFUdclDii1j4AuEj80vZM5LiSI3yabYOmzdg0ZS+rMTsZc6XJliUVfSwpC5YjVrNWvUIF1CeJnkSHCj21tFWsooPG7CtgSMGDCRMGbLI0ACsgNF0nfI0Vdqyjsls5oVWRxmvatmLfrjVBIMuiBATC6N1Lg0kZAXn5Ch7c4oGBIRJQEl7MuLHjx5AjS55M+UsIACH5BAkJAB0ALAAAAACgABQAhAQCBISChERGRMTCxCwuLOTi5LSytBQWFGRmZDw6PPT29Ly6vAwODNza3DQ2NHx6fPz+/AQGBIyOjFRWVDQyNOTm5LS2tBwaHDw+PPz6/Ly+vNze3Hx+fP7+/gAAAAAAAAX+YCeOZGmeaKqubOu+cCzPdG3feK7vfO//pYKEQpFUgMikcgQZCCIRwQByUlAA2Cwis+x6bxlCNkvgkhSH8fhg/rrfKohYjSVQRZArnXyCNDQaDXcofoCCcX+Bg32JhymFioiGiyaQjoSNlCIDe1kDIxudYxslEAscARwcC22lFqmoFq0kEK+qAbKEtrGzTLu4vXi/uX3DwR21sMAmGKIAGCMPzlgPJQ2qqKoNKNfZqNsn3crgJuK35Na359zq3+zeAegk5u4lEc4RI83TDiUW2akCGEDxL6CqgScKPoCF0IRChgRRLTwYMcBEDg39SYSYcCNFe84Y6JsGoB+JVwvHH3x0qAxVxpPwMBK0CPDliILqbIpAWbNizpkqA9pM4CxBNJLV5mELKG+EOJUcmoowl0pqB3pR3xm0ipWruqpasTXV4EwDKJKkSGSwlYqYibUGWaGAG9TAMbjZ5J6g6/Iu21V+aQoMnLeXnE52mMxBrMnPAguX9jZYsKDBMTyTK2tSm9myigydN48ATdlzCtKaP3e+u5jMLDSdDiiAQ7t2KQ0CsGDQsFlBaywTLtseTrzEBg4UCHBIW7y58+fQo0ufTr26dR4hAAAh+QQJCQAhACwAAAAAoAAUAIUEAgSEgoREQkTEwsQsLizk4uSkpqRsbmwUEhRUUlT09vTc2tw0NjS0trQMDgyUkpRMTkwcGhz8/vy8vrwEBgSEhoRERkTExsQ0MjTk5uR8fnwUFhRcXlz8+vzc3tw8Ojy8urz+/v4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG/sCQcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/VwoPBeGTA6HRWoVhKLhAKBXKRHDsEgH5/6Kj/gG4TCHoIE3ZGHRh7ewR+RAobjIwbj4GXgRIJkwAJiEMSeZwABJ8Si6N6BEcSHhMDC5+srrCyRq2vsUq4tbu0ukm8wEjCtkMTqSBFF6l6F0MFzXseRRIgARrZIMZCHSAa2BrbSN7g2twh5eHjd9/r6Orn5O7y1YSjCLIW0hZDGtJ6NBRZkA0btgVICBoEh/CIQnMBGhp5aFDiQIgME2KMqHEhxyIKpLUZQkEahSH7AH4o0mAhuAZIvpnLBvOIzJk1jdwMl7PI406aMbPhDFoQKEiRREo2c4ASIICVRFoW1dCTCD1wAaoOkbpQq5Cr2LyGAEs1aLiwZotqlXCPkwNZAqQJ8OdUIBGKGR1O1WDx7syDGjH2HUJQcOCFg4UURnzEQCoDRQZIGzDEg1NqRKzNBGGpmkxsnIldDc1qdOfMpkVvPg0q9a2UjCzYCpWqFChRtY1JWAACxALWmXn7Bg5K+O9dxokL2d37eLDkyJsrl9DgnoMG3PBwcgRSEr6RmMIHYrOkwwAIeiwMAK4A9x4OysXLn+/EQwAyATDT38+/v///AAYo4IAE0hcEACH5BAkJACEALAAAAACgABQAhQQCBISChERCRMTCxCwuLOTi5KSmpGxubBQSFFRSVPT29Nza3DQ2NLS2tAwODJSSlExOTBwaHPz+/Ly+vAQGBISGhERGRMTGxDQyNOTm5Hx+fBQWFFxeXPz6/Nze3Dw6PLy6vP7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb+wJBwSCwaj8ikcslsOp/QqHRKrVqv2Kx2y+16v+Bi4cFgPDLhtNqqUCwlFwiFArlIjh0CYM8/dNaAgUgSEwh7CBN3Rh0YfHwEf0QKG46OG5GCmVYSHhMDC4pGEgmVAAmhQhJ6pQAEoRKNrHsER5yeoEq2n6iinbu5vrhJusKDwbxEEiAaARoaIMghILIgRReyexdDBdh8HkXKzc7QSB3L4uR45+PRIebM7OXrz+3v6O0L8M0BC6KGrAhQWehmYYiGbns0FMmnT0O/I/n2MXtoJKI+igsb8kNicR9GIh0nIlkGz1kDIwq6uRlCoRuFIQMRfijSQCKzk0dIitOA0wjpyZI9i/wUF5TIUJMjnQFFUtPZvqLuVBJpic0BTIQAZhJpujRnyQABoAppKlGstK88k4prZnYeW44aP7pzIMsBKgHdBBjEqhBkXLglHcJdKxiiU3hyhTCUmDjEYsSD5oHARMSALANFBnQbMMQD1m/JJFMOfXhy5JKma4k+jW70EGWoXb9eAALEAtkhJMR0ZIGXKlmuXq8CjkwCbdu4Ux2/nWt58tzOm9dmPiw6FgkN/jloEC1PKUhFJslCsFKT+TVtlnQYAGGPhQGyFQznw+H5+fv4lXgIUCYA6PwABijggAQWaOCBCCYoRRAAIfkECQkAIQAsAAAAAKAAFACFBAIEhIKEREJExMLELC4s5OLkpKakbG5sFBIUVFJU9Pb03NrcNDY0tLa0DA4MlJKUTE5MHBoc/P78vL68BAYEhIaEREZExMbENDI05ObkfH58FBYUXF5c/Pr83N7cPDo8vLq8/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABv7AkHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4GrhwWA8MuG02qpQLCUXCIUCuUiOHQJgzz901oCBSBITCHsIE3dGHRh8fAR/RAobjo4bkYKZRhIeEwMLioOdn6FFEgmVAAmlIRJ6qQAEoRKNsHsER5yeoEq6pL2jvEm+wqK7rEQSIBoBGhogyEIdy83P0SC2IEUXtnsXQwXdfB6mINXWSNPMztDp1OzRIerV7Xjv6EcL680BC0j6/Jj5M2UIFoJSFsRZGKJB3B4NRfTt0zDQCMB9FSNO7PdvY0YiF/l9HLJsnbMGSEqaRFlEgTg3QyiIozAkocMPRRoEZMbSSOvJcz2LqKwWlMjQkymdrUSi0xm/oiRNNoPa4SURmd0c1HQIACeRpkuP3AsQAKqQpgHNhhirQS1btSEFdpw4soMDWw5KCRAngCFXiCA9zj03UsjFdYVDSAyYeDHiQfdAYCoyj93kIQZsGSgyQNyAIR64kksW+fIQZU6fmRaCmt7qVqUhm5Q8bAEIEAtes7aN+7UEm44ssHJlS9bpV8WRSeCduxdz3a2eO7/dvDZ16F8kNCjooEG0PKkgtaRkEKam82vaLOkwAMIeCwNWK0DOhwN29PjzJ/EQoEyA0foFKOCABBZo4IEIJqigEEEAACH5BAkJACEALAAAAACgABQAhQQCBISChERCRMTCxCwuLOTi5KSmpGxubBQSFFRSVPT29Nza3DQ2NLS2tAwODJSSlExOTBwaHPz+/Ly+vAQGBISGhERGRMTGxDQyNOTm5Hx+fBQWFFxeXPz6/Nze3Dw6PLy6vP7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb+wJBwSCwaj8ikcslsOp/QqHRKrVqv2Kx2y+16v+AwsfBgMB4ZsXo9VSiWkguEQoFcJMcOAcDvHzpsgYJFEhMIfAgTeEYdGH19BIBEChuPjxuSg10SHhMDC4tInJ6gSqOfoYQJlgAJqSESe6wABKESjrN8BEenpUm9r4SdqKbDvrwgGgEaGiDBQh3Jy83PIdHKzM5HILkgRRe5fBdDBeF9HoQg09RI19PaedLZ1e7zSAvYywEL9/nK/Efw6ftnRMKhWQhSWTBnYYgGc3w0FMHnD6ARgfksTvS3r9/AjtuYrWuAJJlIZiRDntSQcpK5N0MomKMwZCHED0UaDFTWsojnyZElmWFjGXRlTyI6TwY4OkQeNqZCnC5j2uElEZnhHNSECAAn0mnToIaQuhRJ0oFipRINyFEjEYoD3Q6Bi01uBwe5HKQSYE6AQ64S37btN1SDXCEY6xKOK8opiExF6jWDTESCY8pCDOQyUGSAuQFDPHBFV/ly45OPT7/DLMTy0NSiFoAAsYD1EAmyadtunbu2KJuPLLyKlavWbVnFg+Ge7ftX792wnpuSrumJhAYHHTR4podVpCKUciGAWb28GDdLOgyAwMfCANYKkPfhAN28/ftHPAQwE4A0/v8ABijggAQWaOCBYAQBACH5BAkJACEALAAAAACgABQAhQQCBISChERCRMTCxCwuLOTi5KSmpGxubBQSFFRSVPT29Nza3DQ2NLS2tAwODJSSlExOTBwaHPz+/Ly+vAQGBISGhERGRMTGxDQyNOTm5Hx+fBQWFFxeXPz6/Nze3Dw6PLy6vP7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb+wJBwSCwaj8ikcslsOp/QqHRKrVqv2Kx2y+16v+AwtfBgMB4ZsXo9VSiWkguEQoFcJMcOAcDvHzpsgYJFEhMIfAgTeEYdGH19BIBEChuPjxuSg00SHhMDC4tInJ6gSqOfoUenpaoJlgAJqSESe68ABKESjrZ8BKqdqKbArKLDskQSIBoBGhogx0IdyszO0CHSy83PSNjU20YgvCBFF7x8F0MF5n0ehCDU1dzT2tbd9EgL2cwBC/j6y/2O5NsH0B9BfkYkHLKFIJWFdRaGaFjHR0ORfP8CGhmoT+PFfwiPKMvWrAGSkSRNimyW8iRLaionrXszhMI6CkMeUvxQpAHuwWUxi4yEF5QISphIfDbbV3TIvGxNhTxlFjXEVA1NO8wkYtOcg5wUAfAkorTlSmoBAlRVSrAqx30eiWAkGHfI3Gx1hdxlVreDA14OUglYJ0BiWItyQeYNcbfZYo54RT0FkamIPWeVkU3OPCQZScpHDPAyUGTAugFDPIRtp/kzZyGes4FWtTmJhAUgQCx43Rm3bt6wfe82JZy3BJ2PLMiixQtX51rNj93OPdx2ceLUgWu6IqHBQgcNoOl5FakIJV4IaG5fL8bNkg4DIPCxMOC1Auh9OGhnz7//EQ8BmBEAa/4VaOCBCCao4IIMNghFEAAh+QQJCQAhACwAAAAAoAAUAIUEAgSEgoREQkTEwsQsLizk4uSkpqRsbmwUEhRUUlT09vTc2tw0NjS0trQMDgyUkpRMTkwcGhz8/vy8vrwEBgSEhoRERkTExsQ0MjTk5uR8fnwUFhRcXlz8+vzc3tw8Ojy8urz+/v4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG/sCQcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/gsFhYeDAYj8x4zYYqFEvJBUKhQC6SY4cA6PsPHW2Cg0ISEwh9CBN5Rh0Yfn4EgUQKG5CQG5NsEh4TAwuMSJyeoEqjn6FHp6VJq6lEEgmXAAmvEnyzAAShEo+5fQSqnaimw6yqIBoBGhogr0MdycvNz0LRyszOSNfT2nrS2dUgvyBFF799F0MF6H4eRRIg09Tb4PRHC9jLAQtI+fvK+uHTF9AfQX4GASKEhygXglQW2lkYoqFdHw1F8hEUaOSfPo5FkmFj1gCJyJElj5ycltLISpImmaE0oqAdnCEU2lEYEtHi6IciDQAqaxmS2TyiRIIaHRpz2jKkQ+w9bboUqhCpGqB2sEkkJzoHPC0C+JnUKUyVIwMEsBrC4z6QRDQChDtELja6Quwuw9t26d5GDn45SCWgnQCKYjHGPcjXLjO+8UaC0FSEWzbKsOxNFqUZ85DI3TyHMPDLQJEB7QYM8SD2XWbJokNExrZZ1AIQIBbELnQ7927ZvXWbCv5bAnFRPSFZsIVr1q7PzXM9h3e8VXVC2GE1aOigQbU9zjFX+oXgZvbzYN4s6TAAQh8LA0QriN6Hw2/0+PMT8RDgTADX+gUo4IAEFmjggQjmFwQAIfkECQkAIQAsAAAAAKAAFACFBAIEhIKEREJExMLELC4s5OLkpKakbG5sFBIUVFJU9Pb03NrcNDY0tLa0DA4MlJKUTE5MHBoc/P78vL68BAYEhIaEREZExMbENDI05ObkfH58FBYUXF5c/Pr83N7cPDo8vLq8/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABv7AkHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4LBYWngwGI/MeM2GKhRLyQVCoUAukmOHAOj7Dx1tgoNCEhMIfQgTeUYdGH5+BIFEChuQkBuTVRIeEwMLjEicnqBKo5+hR6elSaupRq6iCZcACa8SfLQABKESj7p9BKqdqK0gGgEaGiCvQx3HycvNQs/IysxI1dHYetDX0yHa30cgwCBFF8B9F0MF6n4eRRIg0dJIC9bJAQv3+cj8R/Dp+9dv4L6C+QAaEZgQFiJdCFJZeGdhiIZ3fTQUwedPYZFj1pQ1QAIy5EhyykySTBntpJGSLVcqi1lEwTs4Qyi8ozBkIuHGD0UaDETmMmg0fUWJeLOWdMjSZE2FPNUQNcTUqlcb3SSiU52DnhgBACUidKZIhPo8EuE4UO0QttbcCoGbTG4Iuhrs4nXbwQEwB6kEvBNgMazGtf4OqloKQlMRccscE5kXsrEoxpKHUN6WuRDmIwaAGSgy4N2AIR7Cxpv8WdQCECAWdNb8OvbsQrVlm8p9O4QE3rth61blE5KFW7lo8dKcXNdyecAJSd/U4KGDBtP2KJdcCRgCnNPDg3mzpMMACH0sDOisoHkfDr3Fy59PxEOAMwFW09/Pv7///wAGKOAXQQAAIfkECQkAIQAsAAAAAKAAFACFBAIEhIKEREJExMLELC4s5OLkpKakbG5sFBIUVFJU9Pb03NrcNDY0tLa0DA4MlJKUTE5MHBoc/P78vL68BAYEhIaEREZExMbENDI05ObkfH58FBYUXF5c/Pr83N7cPDo8vLq8/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABv7AkHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4LBYXHgwGI/MeM2GKhRLyQVCoUAukmOHAOj7Dx1tgoNCEhMIfQgTeUYdGH5+BIFEChuQkBuTRRIeEwMLjEicnqBKo5+hR6elSaupRq6mnaiiCZcACa8SfLcABKESj719BLAgGgEaGiCvQx3HycvNQs/IysxI1dHYetDX0yHa39ne0kcgwyBFF8N9F0MF7X4eRQvWyQELSPb4yPpH/O79MxIQ38B69/ztS5hvYb+GmxD1QpDKgjwLQzTI66OhyDFryhog+QhS5DllJUeijGbSCEmWKpXBPCkzpBEF8uAMoSCPwuEQixs/FGkQDV9LjyCTHSVSTqnKohqWDmka9WlNqUKoSu2QkwjPdg5+bgQglEhBhQBrJjtoVq0GtkPsJYQrRG4/uiHsWsOrd20jB8McpBIgT0DGsR2JSCgHQlMRccscK2YsechikI1FUdaMuXKhzUYMDDNQZIC8AUM8jKW3aQEIEAs8W3YNW3Yh2rFN4bYdQsJu3a9zt/qtCigkC7p43fplWXkv5oSih5HQQKKDBtP2LJdcaRgCndLDg3mzpMMACH0sDPCswHkfDrzFy59PxEOAMwFY09/Pv7///wAGKOATQQAAIfkECQkAFwAsAAAAAKAAFACEBAIEnJ6c1NbUREJELC4stLK09PL0vL68DA4MPDo8/Pr8vLq8BAYErK6s3NrcfH58NDI0tLa09Pb0xMLEFBIUPD48/P78/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf7gJY5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqFEsPKMqkwGIOD5UitwiwLCgBAiUxNCsJ2DCAoUBbHYuH4otVs9ym9bqvo8TvcnsLz33VyJn6CIxYDZFsDghZiiVsEhRYFD5UPEWcnChGWl5lgnJaYKJudo5qhlaegpp8lpaKuJLCqsiIRj1sRJRO5YwcmAp2VDijCw8Unx53JwcMPzSXLltEk08TGz9Uj19BgWrkUcgm+WwkmqZYFKJTD6yftne8m8ersz/Ml9ZX5JPsP/Ub8CyihHAAJJBgYZEAP3z13D+VFtAfPYUWIFyVmpEiiYDmEIxSWQ2DCgTYUJoSRoTx5IiWzlSpbsiw5s4RLaoPAPUIwzuC5V+kW2BJB64FQUkGHXih6FFWnpqwsQQX6VCnToQF8BShxwCCwQXsKkSCkJ1DZPH3Cnv0zR21as3PIJUrAyNGjSFby6i0xCcEWBAXEhrmrdK/hIwaU3FlQwdyBwocjS55MubLly5gza95cIgQAIfkECQkAEAAsAAAAAKAAFACEBAIElJaU1NLU9PL0REJEpKak/Pr8rK6sPD48FBIU1NbU9Pb0fH58rKqs/P78tLK0/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf4gJI5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqPq8EAyWwCHY8EAJA4OFIOweOhMKiy2+5Xy/ViyeJz2IwCl8dr+Fs9NzkI0zyAcDUZDgyBDAdsJX+Cg4Ukh4KEKIyBjieQiY+AjYojlJJ+l5GZIpugB3p6BycCiIECKKmqrKiqDLAmroi0JbaCuCS6q62yvCO+s8CvdlKlUwl9JA2yDSjPqtEn04jVJteC2SXbgd3O0NLj1uXa5yMLynoL6NTk8Oby79jx9vP49dz3/Pn+JNaxm+IulywFxhAhjKVqYa2DCQU5NNgwYqCJvSAyVOgnmTJmnQIFYPAAFAQDD2VEkjSJUmXJRykZjHw5KeZMljZXwnSJk+dOmTpNBBgYoI2CBw0EmAx1NOnSk02VqjAQ9SlVpFJTXHU6tWpXrFa9TkKgDMFTJ2jTYimQLEGBZmrjyk2yZK7du3jz6t3Lt6/fv3hDAAA7RUdlR1FOTnV1MlpNRXJFRUNTWTFTTXc3U0diYnV4ejl0aW9mRGhaUW5WNitjVHJwQTNTYytvb2xUZTdLS2RJQg=='
-
-ring_black_dots = b'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'
-
-ring_gray_segments = b'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'
-
-
-ring_lines = b'R0lGODlh2ADYAKIHAPj4+ODg4MnJyaysrIuLi2NjYzk5Of///yH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Q0NFQTZFMUU5QzBDMTFFMkFFNDdDRTVDRTJCRUM3RTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6Q0NFQTZFMUY5QzBDMTFFMkFFNDdDRTVDRTJCRUM3RTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDQ0VBNkUxQzlDMEMxMUUyQUU0N0NFNUNFMkJFQzdFMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDQ0VBNkUxRDlDMEMxMUUyQUU0N0NFNUNFMkJFQzdFMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDP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'
-
-
-red_dots_ring = b'R0lGODlhkAHIALMPAM0/QMQfIdRcXtpxc9+EhOahofbf3/vv7+KTlOy4ucIYGv/+/vHNze/Dw8MbHf///yH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjMzOEMxNzM2RTAzMTFFNjg4Mzk5NzdDMkE1QzlDRjIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjMzOEMxNzQ2RTAzMTFFNjg4Mzk5NzdDMkE1QzlDRjIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MzM4QzE3MTZFMDMxMUU2ODgzOTk3N0MyQTVDOUNGMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MzM4QzE3MjZFMDMxMUU2ODgzOTk3N0MyQTVDOUNGMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t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'
-
-blue_dots = b'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'
-
-ring_blue = b'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HGieCTBLWavP5OjocYKR////HI/jXLPc////PJTMVG6EdLTsRJrMBEF1rNb4VK33////+vz8////NFp8NpjaVF5oVJ7EJE9mBHDIdLLE////////OH60O2FxPJLcFCAnHFqBeb/5PKboJEBMHILU////4O/8VLTuDI70lJyh////////RKrkPHKM////////DEJopKq0////rLrMvMjQbK7EfKbMVIiYfKTEVIKMfJKsv8LEhNDlxNLgpMLcpNL8VHaU////PHaXXGZs////lLXR////////PEJM////JDI6vNLkFFaMfIeRHDhGfHp8vNvxNIzJpKKkXI60KYDAi9/5PFhgPGd4lM78j5OUVFhYZK7MVI68XJWmfH+H1ODwXJ7U1NLUaLrc////HE5wHG6oT2Z8dLrRdK7gVJjYBE6E////aLrsb3qE8vb4////V67gLH6sFEJk////GmKYaJq0ebrsPI68////////KEhk////LHKo////////LGKQTKbUOKb4PGKEBFaYrLK8XLrkfLLcVLr4lKKspLLEXIKkfI6cHD5MDIjqDEp0FGaglMjwbLLIbMnxTGqENFhkLI7ZDDxcrMbc1NfcHFR9DFycHIfWbMLp////THyMXKbkLDhIVJOsPE5cHDE6HEhkJGiWXGp0fLTkTJe/XJ+8LFFiDHHBHCAkLEBI////zNHUrM7sXHKE/v7+CP4A/wkcSLCgwYFztrjh4qyBw4cxuAzbMuegxYsYMXrp5KaBM2rfRIka8q3kt0RDEn2j0yAMh05eMsqcKXBXAmcEQn4j0KBOgJ9Af2qb8kZaonRv1rjZRbNpwV0dJ4ia0DOAz6A/c2QNoDXHlF5FeoUYxtTpTC+lGkglcBVrUK1c4+bomiMGkSchusU0e3HOR1EE3GLtKpcr3blz17zKsqYiX4OMGgyZ0BZrnRh0YJxMxJlIrmYx0CFGPKK0Am+hUDwe6MWNM1ENBNchUGQIjDxhprx4oe3FlDBvnhQh0kx06TIjypSJg8pTrb1md3GhNqTyzwYwEkmbMoVDgk5zdv558aJiTqdu7OKgU0AElRXl8Mvgs1fPVtmm0jVbr5OuSJ4pWFRAUwVYxOEJKqigA98DZTxQTw8k3CeTF1zAMIFbeSTyXykS0rRLNxp44k09+DxgoonEQAhdRrnQ8c1b2qSTzhTDrMjXLvTgMwYFGpz4gAvEyGDETIw4kwhQWk2hYRgCrlYQK6EQQ0EoLvz4ozvJLJJRBQ0k4hNcSsbQTIdO1lSPBhT4UqULVbrTBBQXefFGETHINUURLtlYJmtGyMIjm2xyQ0gaegrUDRfSwJWDNnhysGdGfarSBKDQPJKEJAftoqQ2hgXwSh7skPkoQV6kkowqLkCjKjSEBKOCQf7DSJPHXFwp8EoIoo5K0C7JyCADNBcAG4wehTx1J10vFBFHk7pilMI5hshzwbQX6NHGqwO5QUUMo1GRxTDNzlRIMIZMe8sAbSRhAmtrFDHaFLTEkWu4uwazjjwDnDsABszs1UkYT4z2hBXd0DuTJG1goO8AM7ShiEBYQBDCXCPEEe+8Bg+0SyZ6zDDAxwOogYRA4hBx3AhWZFFLxjMJswEpWsSshRoz/DOHJ83Eh0oozLJ8UQrbYDBACVqUsAETUKCgwHvKjWBGHD7PZI4asZRgNROxAELPE3HAF8oYrUQt0zUbbGC11fcgYYs3JTLYAzGYio2RCUyYXYITJfjQiP4ngjBoYg+hYCI3RpiMM8rdd98DRigU+GiPLI4NfhAPJYziBN5OwBHP1ye6QAE+GMutghPh3H35L+No0IOVD1BwQKGS/+NFCQt0cLkT2XSAjztWuiDMObBL7oUTC9yOwCZOaOAOoC6ockDoYo9evBMIINBBB8oz704wcMZuECtO6EN99ZvAkQaqbEIjQxOCe19QIJlXX70Sx6SyfKqVXup+QdU4gUP1RzgCPGYxCBkEY1XyeAQo9kcQfyhBCQFEwBGUoIlFPEIewLoAtILBwIFkAx4nkGAEozGHYDyCWrdYxwpS0EF+IAAeAYzhEVjxjySs4xYXOJc8SCGMDkYBAf4nCKAFAggHgQhDDyvQ1wowkAnoGcwLSgjhEYY4RF0IRBEzwBfISGGOuHnPDkcIogXGGEAHCMQLzBDax7RgDi46sVm7gAcb2DBFMioBOiZghjlkNrNYHMJ7mgjjGIMwRguYgiAqWAHMilYCJqihDywcXDmOQMdBEvII2BrIITZQtbOR4R4zeGOZdtGOI4jAAkEg5BitWBAVmCMcfThbCcLxi0YEb1ReEIMF2EDIVF4ykwQxARmqhrlx+KADGYjaBwqJSl8GwQ4W8cIz7jGO2znBmMi85Wq8oAsqOjOVlQgeD35xD8RdrgPFu4IoZ7ILMfTSlwAIAgAsUI6MWAOd1v68nD7oV89RuaIdqkxlPAFA0GrMJAPZyMb4EHA5HGwCAdhYp0F2sQpUNpOgGA3CB2jiBXBsogPyk58S/peNakj0H7uwwwlSiUqMurQA2tzVLD4KwJCCEAFKiAI/aMKPD+QjoC516Tti+pRZKAEeIpQhEIMowHnYARE8UMF4VMADRNgBEitVZVCDCtPHeOGHSkgqFQM4RzrW8Z3OtORWXfoBol7ED0BEwFgLWccp2pWZal2rSw36KB744AgSxGsvm9lMZ+o1qEvoJy5VKkSLsvSb8pTnYTNqCrc6RQWrkOsUIRvZyQaVE91jmQpMAQ9mClSyngVAPgQQWrF5ARG6gCRHPDs72Xx8ABGWpRcU/KALMbQjHxYgqAVE0I4CcOITPHhUQAAAIfkECQkA/wAsAAAAAEAAQACHBBEdFIzkBFCNjI6UTE5UVI2fCm66Bi9MXLLUJE5klMr0////JDE5RKPcVKLEdMnnNIq8DD5gBB8zzNTYRHB8BH/hJF6EBFmfbLjUbKLMb3V8JHS43Ov3jLLUFCAmNJXcBHDIbIykBDBWRH+cbL7c////BEBxrK+3HFqBJEBKOmBqKZfpLHqs////BBYkBGSyBCI8bLPqTK/nRJrMzODw9PX4FC9CZKrBlL/h////HE9xZL/p////////XG58FIHRJILEOUFJJIzY////NG+MbK3AbJe4HG6pxMzURoyxHEFXFicrPJvXB3bLFBocFDZMZLXZJGiSVIWW////////////////ZKC0gtHqTHefdIGP6/T5FjpU////JEZUfLXnKZLfjKK0OGqQBChG////Gne6SHeIfIyYBTZb////JFd3FSo2XLrpDCY0pLLEfMDUWK7cPGd3DBggHDA7pMLcTKj0GYbZJIbRPHakfK3UwNvvRJ3W////VGFs////JDhAvMbOpKSkrMzoRGZ0VHqcPH2fjJqskrjZ////vNbslKe3XJ7U3NrcfKbITIKsNldi+vz8hMrkJ2KR7O7vdKrYfJevLHapPJLE////////////ZJqsVGp8VIKofL70HEZk////LFZkXKbE1NrkBF6nbKa8TIac////NIKsdLr0TJ7E1Ob0LIbENEZUPHaURJK4////3Ob0fIaUxOL8qNL0WLXoLHKoNI3JbMLpGVyP////////////////VJbU////OJ7qBDllVKr0DIbkbHqEJ3q3RKrsWKbMDDZMrLbEfLrvfJKkpLrQVIq0DBIULFBeTKTXXKG/fMjfFEBeDB8pTHJ8dLnNlK7EPJbUdIqcTICS////NHykdLPp////1N7pHILNLIC8LI3XPG+KHDdF////fICGLEhRlKCpDCg+LFhxLITMXHiQTFZcZLrcZKa4LF54xMbIlJqcDF6cTJKs5ObnHIrcPIu31NbUDIHeDFqcdKDELHa05O75dMDY/v7+CP4A/wkcSLCgwYH9aCkT9gGMkIdCxH1Y1E1Qv4MYM2rUCGlWtxXAZLiTJs0fBgQIoGCwdnIGq3WU9EDaSLOmwC0KVhjbgQUBMDD5KjQR2qQJCBBNwEFQVUQUhHCHtticWnCLpxW1sNQCU6GrUKJFkR4da6DMq3evNuSRSrUmpJw8jXntOrSoXaNjQRgA8YLvi3DRkmw4NLNtRg4hscid+7Wu3bxHXxh4QZkyKRabuKGKZfggrRUPdgxj/DUfGGhwoHSzxrKIg1cQyvStbJlUoQJH6HQeCCkVMCzASFf40QDDGwQzxIH70aRM83WX6N24kkT2C1LYL1w4IiXKvsJtIf7VqfUgwOjRXYUgkAZNCLhFChJxqAEJUg0OiXAsKlPm3iZ6lmBHinYX6DMCEc2AZxMkxrCByzDodWVHLf4wYUc3NNhEAyVHWEIPPVEQeIEAF7hChCMKbiSeg6Q1IM0eQihQg2E14HCELQWMoB2JAghAxIkpZhRDLbhUEGE+O0BhhzIz7vZPDXnMM0IBufRopRiSGFETLcA8EGEF9jwAjTirOFnQKrZE0Z2VApgwDgrMbLTKClgEMFcA0nwATZNmElRDM7loI0mbPZpAgQ5lYgTJbytEaI80YHQTZJ//QGJELmZY0KYJPcYhxqT/KCBDLXPl488HMVCqkREomKHDpv4mqKHGNQdtQeeXUEADDaiqVtqJBRRwasKwKujAFkHK1NKAV03sAYU4fPZ6UA2SwBPHsMN+okYlVa0gDbN2PABOotJmRIMAg+gwbDDBPPLJJAR5oixdTdQyQzfl0lSJDiqYwG4wESQQBm8ffFuXPdbYEW2+0+oATwL/BvNMAoXNwgSpdcGBjQIM03TNJ4+wi4YISkyDhEAxuCMEUfm8AQ6vHQtUgw6hfILGzWicE4JAYETi2B6qpBrzRiF88owISIvgxTP/9AMGHI9BcUeGQ2s0QQSPJC0CF0/EQgs0TNiVjzXgVE3TJ+dMg/QYyJDjxhcI2IOXONEsYvZGhHihxP4YIowxhhJnQPPGYzNgg8PdGinCRQp9+/0HJx9YIxYIDrCiB+IZAYLMOX77Tc4z4mCQ1w1lcIA5RrGMkULnY8zBxR035FVEGceeTtAWY3DuNww22ACOKGO9UIQBMN8NierpjAEDDGukA84xevU1fPFmH/+H8hJIsEYbQIgyGV+lGLCw7f9sAcMfy8OgfTrrvDPbC9EcYTr5BDEyBvrqS7AEObfEXhk9xUgE/QgCiHQwIHvZ88A5fPGOyVAmCag4xAAHgo50zCF7LpCAB/qQB1UcoTIsSIIvJigQHyxhCRLIoAs8kA1B3CMclTnCJo5Awn+QY3sYlIAcTtCPDSThOv4Dws0oJogEGKDQBUikhgvq8Q/MCMg2eMjABLXQhiWo0AXU+INAMkCPI1xgQPMoQBTGd7ca2GAJSkSiC+RADIHowRKFGJB2TBEFCZIPHdSwYgqRKId4CAQSliiAiKKgjVxQr1w1mIMH0ugCAMiBAeDpQCFCNCIBjCAKjbCdLFxgRSQCwAXOWMbtuFNJAQRKAN/AHD40mEYAOFIO8CJII1wRBTaNYxySIGO+apACD3jgk650pTkMsoVcmIJNAqCABTpxSCdBog9y8EAjg+kMD8SyIIcQQy0JpYNDaWloGlihJ4MJAHkoCg9mQIGwTICCdBmhmVSBBDFWSA1yAsAZrf7gVSxQQAFCDQsFKviENnS5mxr0YYVysKcjGbERZqDgWtgyAb8cNoFe4eMP0UyoQgNREyPAQxIRNcE0HhGKCFSCoDWpgSx06AGN2lMDC8qCCiyALXaZ4BmPmMYnFIFSjNQAHXOIpjQV6gwCwBMSWVCHOiIWDDRw4Rnn4MI0slHRmkxAC1b0pUvtGYSeGqQGWUhAKPyFs5Ep4RzneMIBlMAOdAAiFpOoTw0YAQh0+GAOWNTqNBVKAK8eBBJFe0QERDCypI3hCSlIwR/IcYA2LA+B2aNGHvW615f6NSNumMYzlGDYxvntCTZgwB/+wIA5mPaES1ikGhV6T2eYk1LfiInDWUfGN9alT335w6AaV6vQPzC0VzVQxCcSiwzbpg+BV0wuUV17WapMYhlcIEcKnqC8x0JWjSkEJjmd4UhzXLNjkzCEFyx4wzEgN4efbGQjncFdBgzgu1WDBBK04IU2rOG+qW2DHKixXzn4t73EiEdz81UPN8iiD+cgRxskS401BKEPWjgBZ/oUEAAh+QQJCQD/ACwAAAAAQABAAIcEER0UjOQEUI2MjpRMTlRUjZ8KbroGL0xUtOgsT1mUyvT///8kMTlEo9xUosQMPmR0yecEHzM0irxEb3zM1NgEf+EkXoRsuNQEWZ5woMRsdXwkeLTc6/eMstQUICYEcMgEMFY0lNpEf5xsjqxsvtRUoeIEQHGsr7ckP0g0XmwUXJD///8seqwEFyQkl+kEZLIUL0JMr+cEIjzM4PBss+n09fj///88lsQUeMgcUHJkv+k8pegUgdFsrb8kgsSMwvQ0PkxUmrw0b4xcqsxccHwWJytRgakUOEwcbqnEzNQHdss8m9cUGhwkjdhktdgcQVckaJIWOVT///////////8bZZ////9UlKxkn7GC0epGjLH////r8/krR1CMorQsV2partc4apAEKEZ8tOj///8VKjYad7pEdowFNltUhZZ8wdf///9EndYpkt5UYWxcuumkucx8jZy8xc48aHgMGCAcMDtMqPQbhtt8q9T///88dqTB2+////8MEhT///8kOECkpKSkwtyszOhEaHRUepx8oLw8fZ+MmqyTuNn///+81uyUp7fc2tz///98gYY2V2L6/PyEyuQnYpHs7u////98lqxUqvQsdqlapsj///////////9Uanx8vvQcRmR8psz///9IdoTU2uQEXqdsprxMhpw0gqzU5vRwuvQkWn////80RlQ8dpRMhrT////c5vREkrjE4vyo0vQscqg0jclswukkQlj///////9UltT///83nekEOWYMhuRveoQsfrREquwMNkystsRkprh8hpT///9MpNdcob8UQF58yOAMIClMcnx0uc2UrsRMgJJ0ipxcoNgcXIw0fKT////U3ul0s+ccgs2Uwec8b4ocN0Qsjdf///9clKeUoKkMKD3////ExshceJBMVlxkutx8uulMnsQsXniUmpwMXpx0pswsWnjk5ugcitxctug8i7fU1tQMgd4MWpwseLjk7vk8ltR0wNj///88YWpEmswcesREpeQshMI8QkhclsRkq8f+/v4I/gD/CRxIsKDBgfNkjSkRQpsPa9Z87KOVq1qgeQczaty4EdKeam3aGANTj9kFf0MwYfLX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qqz///8Eedbc3eBMlLQ0UFx3v9f///8YXIwUMEH///83NzkHDxT///8caJ6E1+0LHylso88sZpQcj+MUSWwJMEtcrdF8yOHc6PRkmqxxe4T///88oPT///88lMx4s+ZMl78EQXWs1vhUtOxUnsR0ssT///////98v/b///8kQFBUXmgkT2YEcMj///////9UboQ4frQ7YXEUICZEquT6/Pw0Wnz////g7/x8e38MjvSUnKH///////////+kqrQMQmj///8slOI8pulUgoxUrdwEgORclaasusy8ytRsrsR8psxUiJh8pMT///+/wsSE0OXE0uA8coykwtyk0vz///88dpdcZmyUtc7///88QkwwcJr///8kMjcUVowcN0a82vFUuvdcntQ0jMmkoqRcjrQpgMCL3/n///88WGA8Z3hUmryUzvx8ipePk5RUWFhUjrzU4PBUq/fU0tRoutz///9kuuQcbqgcTnD///90utBPZnx0ruQEToT////y9vkcWoQsfqz///8UQmT///8aYppxgpH///9cuuQ8jrz///////8oSGT///////////8sYpQscqhMptQpjtk3mtxcxvw4pvg8YoRUpswEVpissrx8stx8goyUoqykssRcgqS80uQcPkxsuvxUmNAMiOwMSXQUZqCUyPBssshsyfM0WGQMPFysxtzU19wch9cMXJxswuccVX0sOEj///9MfIxUk6w8TlwcMTokaJYcSGTk6vBctOBcn7wsQEgsUWIMccFcanQcICRMretcruwMftzM0dSszuz+/v4I/gD/CRxIsKDBgXD8Xdm2yZMGDfcepkE1aBGcgxgzatTYBtOVZcuwQAMHLgkXLO3a/fnTzoYjI0osJGqzsaZNgbfA6GEGwQc0K+buORjqoIVRo97gOeKjCBmyQrduSi2YE4aTJ04+jCjDtQzRoUdbRLtANoYSDGrSFZI39WabbzDmPdnDb4SOrVwdeC3agm+0vxdqDRicTk0HWJBots0IhYo+RGx0SL5bBi/RvkcBkxU8OEsWWGqIPUu1+CAjGIiAcdPhR7Jdrvc2BcNCz4LtP4RcwjtX68LgAZ5PnCBjb5e10gPbaNtzpIGf56zt8iMBARyXYLk0HNh+IGmypeyU/sQAngWP8BPjenDIoLjtLVWZEMl53trPCHNOZClwyOUbtgq3tNEGC1BgA8kfQADhBgaipJPFeU00cQID2aAR1VS36ONCOAHQ15oK88gCFC2Y3JSCBemkI4oaTEAYYTbZzHKhTW2oMkE4fnRInwJPWPHBNzNKdQsksIBGxgkRItkEB+/M0t5G2mTCYYcdqsAKBCr4EORitxQyjj09jBNhEwg0EUQQvtjECBtHBODmc0s8wcYypCFXUAo0xGOPmGQigMAlCNyxERwNfCLHmwHEyYwyW9qJExq7MMBBn36+g8AOGbXhTHOHdrgEInps8KSjBLWRAQcMUIoEAkG4M+pA/qRk0oybHXKDyAwbkLpRBk2kigASwAJbzUG3FNqpm+iwocqrupaKRhAy+BnsGkGwVRAYE+hDqx9soKNHo81SRcwlQQQbLDVUGUurHEcsUUG4NZXz569IUEABEmuwQFACzThzbLJgwGtTKQi8U+/BFJiSnLpuorYEuAJTdYnB9RJxbyWKVeDMBMe64Mw3EdtUDRJB3EuBxRQcIpA2za3bLsQhlxrEGvWebK8IAhVKawD67KNNzDZJgcAa9hJhcSX/wLHxseHo8S7QG/WDLxIWG01EKlpkkonLy0Bt08wnW00EDmCE0wCtVLiyj9c14QOs2ERIoY+hb27BBshsazTH/r1wj+HMJzu7MEOJeWd0CN9GAwDAEA20+eYTS1xUOEapEEF14kSs0cCUHSKiAsyFs2C51YpTsPmbfiDCDbOT/9NG0UQorvjpOabOD+uTt1F17LJvXnvqn7d+EAv2AsA7AKYjoqMfT6ggufAE7VC17ADkQ8URtevgih6EQz/QIRZTD0AlqihPXx8KJOA9QaaQLnsBZS9B3wxOrL2+QI8kTn0cjOizB3Tm8IE57ieQEpxMfJyAwwyAQR8dCPBp3utH+MSHqQY8oTWSUYYCrnA/KehPdvkQyBXQIT/JBPB23rvFGj6oOJz9AxN7UAYGRwCBTeBNeHNwn+xU5jo9XPAu/iNYhiDMAbqQsaAELKxee77RB2aM4IllEMQmpiE8ahABBOIDgAAIwoIl+OA1I/CEIO4BQbatImxZtNZArtDEynAFC1zwRBGbdQt1THB/BrnFB1iBF65YYBOowF2z2jCG6VGPCGokyDcUoICuOEADFtBAErwmgqJlUWEHaYMVhqiXoXjCAq9IgiCR0wYpwO54i8NdBT4wxq/kIgqvQMUcMVRIS4qvHBtBwSa4sBejaCAKk0hGCsJVDnXULImcsAktgsGDy7TgFbk5B1QcdYtS1ItoOgSAC2vSBixgIRiYMco5bEAIePQCErOkSjUMRrOwobIAoyTILUjAA3CGJRrw/mAHBoBgiSjg0ib98EW51mDAUxoPAK5qSxu2kYZ2+IUs0VACO9BAg26k4xrVCAQUAtSGW+wgENVAgxj8VIIStNOdvINnadqQhGS0wxt/GQtncCEKtNAAFuYZ05jO9I6enhSlxhNBPDWyCCMQwhFjCQxnPAOLDohDHKHogT0YwIB6iEEGlqLXMd1JgWHpCgppmAQhetGb3wQHQieYVISkRS97Fa1okvjnICFhBEVgABedOauSxuSnvgLLZG69lynSORUWFAIIZ6EBcNAqIb5qtWZ/RYIvEhmyW1QDHrhQg2HMs1dK0etX9AqCKSgLtTYkIgo0YAJx7GEPYmSDA5fgJMCZzgQsGUjhAUONmTwAEQU0uCEe45gUB8RADHxQwxpQ0FVAAAAh+QQJCQD/ACwAAAAAQABAAIcEBQgEhOqMiowMRGg8rvRMVFwPY6REgpwEIz4knO+EzuRsr8YkQ1QEZLFEm8wkJiTIztQkhswEMlRkx/cETIYqerIEEhpku+EQdMRkm6nc7flEbXk0YnwMkPZ8hIwkUmwUIywki9ZZwPwppvwENFysxtwEVpQYGBx0vdJUsur///8UhNiUqrwUUnxMouwEdM9sbmwscpwEGiTE4vx00/wcRFs0mtyE3Pc0ksw8TlwcMjn09fU0U1wUV4cEKkQkSlxMeIccLDMUa680grR0yuhpp7x0uvRUuOwEetQEDBMEivVEZmx0tsxUpswWPlxUkagcO06MmqQKSnocbqREhqQEFSZkwew0boQ0ldcEWKCsqqw0eqTc3txMtPD///8UUoQ0fqwcjuc8p+r///8citlEpuT///80ovFUfoQMiuxUhJIpovpsr+YEbcFcmqwkOD/U1NgEUpQofcEcdLTr9fv///+s2vz///+M4/w0XXAEK07///8MDg9UlrCkpKgMg+GsusyQvNz///+80OD///88PkT////AwMQ0MjT///8kWITE2uwkluyk0PCUttTU5PSUlpyUprSUy/c8doz6/PwcSnDs7uz///9Usvx0tuxUirRUpux8enz///////85irxUosS83vxkorhEtvxQWmQkisxswuT///94ipxMlrzM5vw4ouT///98zud8wvwEXqff5uwkPkR8lqyUwuz///+Myvz///8kTGf///80hsRckrz///8EPG1YfJz///8UHiTc2twUesRcxvxsdnz///9stvREsfcMJDUsne8sRlYshcZsyPRsutk8ZXQUkOwsU2IcJjEMV4z///8cUXdUoODM3ux80/R8xtx8vPRct+R8stxsvvw8e5z///8sOkw8XmzM1twcluw0cp88ovQMUogMXpxUUlT///8MNVEMToQMFBnk7vQsjtcchNQMdswMGyM8nNiM3PY8kccMK0EsS1QcbKw8hrAMe89cp8ZckqSUnagkcKI8bIA8ktzk4uT+/v4I/gD/CRxIsKDBgetKFNEkrp6iHi2mKeLQSxYgWAczaty4kdKiIhX2bTmgRg2QSfw48GvWLM+zGk5uoRpEiaPNmwLpBJIDRpcbKjEM9IhDoagUXkh5Dajxgx4DdPSiWMJJtSAdbXLkFflU4dWrLGDjEKXAi2xSEiT0oIMSSwc6VFOr3qQ0KwKorUIaNPgadmxRXkd5oUWrp/C8N0Hm+akpV6OGfg6Y4GjTRu9evib8lk0qOK0EPQhCzwtyLAewxgclhWAGyh3lynq9GphyhRuQ2xs2tPxQQ/DnwqFDHwNxzA/qgZQywUOB40Ub57CFgHmS70AMReXIpaMgRUqlSs94/rxEBzy4DBkg3g1jLJeSizIoVryYT7lBsD5u7E2pp8vRIFh0UELJDlwMwoIalTgBBT2xoGMeAlXI8M47pOzQXhnZMPPHfNBhAIooYMxRRDU4gYOKE+jE8sY8CJwnQxVVTFiAhTi5l80FSCDB4QvyLPDJHLPQWNUOkThxGIsyQAijOhYUwB5HxRxhSgA56ngPPvgEo82Tje0ggB5BBKEkjFUwOcxNjYhBBJVUIrECCg4o88hxBoGTzDGkkZlEEuokYdxGGiRgTRhtIkEGcw4ISSdBOyxxDDQvwrgnn6dlRMk4rZwRwKZIpHENO2xwuShynCAAwosWWDBpIaIKJEkX/lZwGsAf1+DAxqgcDfPOL1WoquqekBxEBzI3dLAplRe4QE2ruCJHyq6p7glAEifERRA2ExhzbABlMMMOs80OtAMUv/Q5KQAAcGJVAjcocWwaCqygSrg2wRFjFecCoI61/9QiTBfbXlAGNvTe5IEF5iaBLgACILdGPB24GwAjrZABbsHiQpOwwgA8wNgMxggTgMRWiCEJxjfpg7C0Cx8i0DY0rKGEu84oEMbFKAu0Q7kKcwwADAKdgcfM7nZxhBE53zRMEnz0jO4D/6xDwAREB0BEAvMmzREEfE67MABc2CHCKEQ7E08YWt8ETdNfA+CHKzETfYYVKaRtEyl9eo3u/jBd4BHxzEd0MYvdHOnD8sLmjDP0zAFMcEYohG90yOHoIjLC4u5aw4gGkWvERb7onrAGDUQrcYMzinZOkCWUA8DHCKQTHU8aONtNCejowl767LWnfbvPC49edTyoq34Q65S/3i7j1oTDufEFfc5H2ycoXvoyj0Nf0OTAA4AIJn4TnY0xJ2s/ECS4mwO3zDMTcAEm5g9ECttfDyM2AUSHM2j8Aj1g7tda0AABhFE1zWVNexCwAP0WxoV/rAFzAThCCpBmPk4kQVVfg9o/YJYAxiVAAbTT3g5A8L+FAe0fIBMB46y2ivIZDxIr0xsAXPYPSjxshWeoWOrstoMgJGxh/tBgj78IMLJNEQEeBFPdwZjkNIYRhA7s2hYj4nVAu8FBQj/UF7/+gS0iHisb2WDHDlG2A2+844cKU9e6brCtP5gCHsvyHSlkwKtf7WlfqTHasZAQAgWAKm3DMBUTzxWsg1zKGgmQFTuuEYFQoYwSgXzAO3qFrz2xyjEUSwObXmADRlJjjHTawQZ+kR5J/UodldJImqaEBCq9AAcokIcyqrgoOCQDBKSJlKrw9ScopSAbAXhBjl4QASaAAgNbWtQOUOGD0ZyKTBaoAh/ONBcXZCMFVZqPO0CxAGXMIRC9KwiRjPQGHRwDQrpUh5OoYiNsCpM+yiiCG+QghBGV6ETo/nhDLMSETjKpE5QacU+3dEQfynxCFG4AgxD44x8ACWgHsDBQL25BAicwIBk6AE2L0HkMdVQINcmxAQraUVDYVOAJGVADN/bRg2gYBTADqMQtwkMPKJQnNBECQRXWs6hGrMYB0IHNXsqxD26QRA1oAEJuNvANl9QAHWnRgw/MMw/i9HJRj4DMAiJQn9jwRSzkIMcXyCGFAQygMyT4jUYRQBrT0IsudhGFHCyzF7Bkpijc4Uxn1OoDHehgHvoIZ1WuEoxU4GMIQsDMXY0SGKSgRQISSJFbUAHQZu1gJ0N4Qh/AsI9yiAWvm0mKE5zwg6dEZYta8whI9iEOKqjhAJO4IgIHZsuBPLjkBzFBBQQEi7GELEQcihDKF1rQA4pYBCOjCggAIfkECQkA/wAsAAAAAEAAQACHBAkO////BEiAjIqM////TFBUTIac////CSc7jMr8RKDXJCYoK0hR////xMbMJJ71bLTJ////ZMf5KonK0eb5ZqCyJHe3BBYjBFiabImc////DDNLB3bLNFdfbLXsKI3YNGqEFBka////bHB0SJLI////pMrsBDxpFCcvzNrk7vDxBHnXFFmMF0lqBBktKFh+ZMDvJJfqKXapJDhD////dNL8////UpSyNJ/nrKqs3N3gZKrESHqMNzc5FIffUKzc////dMnpHDM6VKfsBw8UVLTnhNjyBG/EdMDXOJPK4efpBF2mZJmnKmiUcXuEFCw/FHjCd7Pm////NFp8NJjc////R2Z3rNb4////BCA3JEFOPKL3XLrkVIeXWZ+8JE9nfLLcNIa8dKbUVG6ETJbAHC40////BX7b4O/8HGaXBC5MDB4kFCAnHCgx+vz8F094////HJDk////////FHC0JG6kfHt/lJuf////////OH60DBgdMmByPJLcSq7upKq0rLrMvMrUNHigVH6M////VF5ofL/4v8LEhNHmxNLgpMLcpNL8////LH60PHCIlLXOGWCZPEJMbKLQbKrcJDI4XJanvNrxXI60////pKKk////VJjQFILUNHGYlM78fIqXj5OUVFdZVI/BXKvOBHLN1ODw1NLU////ZLrn////GX7MWKbMF26s////HDpKBDZgDF6cKJLiDEJo8vb5////PKbp////TIKcit75////cYKR////dLrMPH6c////RIqwKEhk////////////////////XJ7U////BIHm////LGKUXIKk////DI70LI7Mb3Z8ebrpOGKArLK8fIKMlKKspLLEvNLkbLr5HDNFDEh4lMjwTKDQLJ/2bMjwDFmUFDNFPGZ0TKr0rMbcDDxf1NfcHFaEbMLnLJbkLDhIfNTy////bKu8HIfZPE5cfMjhXKbkXLLcDG64HHe6PJrYDCEuLEJMLFFhPIi0fKXHXGp0HCAkLHCkPHaUzNHUrM7s/v7+CP4A/wkcSLCgwYFKAGUYNAXYuA0bvrlqZ+WTNCUHM2rcuNFNogzKWnyx16EdAwZaZrhSSekJijUznDhww7GmTYEq8IEoBw7ciy+yXr1SQ5RoFgRZjqJAwQbmABU3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LCcwLHxWmdCAwmhNe1oZkEMYwpiCNxJhUkxJohbVmIEuDuALaDhgD80Qww+w4QNYeEAYZ/CGNzzAB9jySgO2yMMPdHGPLdRjC0c4wjGwUQ1BmO5JAQEAIfkECQkA/wAsAAAAAEAAQACHBAkO////jIqMBEiA////TFBQDGisRIuvBCdEhM7lK0hRRJ/XJCYsBGi4xMbMKJ72arLIZMj8BzZb////0eb5JHe3CxcbBFCPLFdsZKCybIacRG55BHbMbLPpJIzaFBkaFCczcXR3NGeCUJSy////BDllpMrsRKbkBHnX7vDyJlh9zNrkJJjqHFJsdNL4BB40BFyiZMHz////FJL0JDdE////THyMLHWprKqs////NJ7mFDZJ3N3g////FEhsdMHZ////Z6vC////////hNPq////BxAU4efpCx8pHGCSFD9ZWbPgVK7cN5PMOGFxdLTs////VKfsODg8////JFBpGHK0dLbMbJKsVGyA////rNb4BX7cPGKEOZnZVJrBdsns////O4e0fKXHOJLYBj9r+vz8KGCA////4O/8V730lJyjVF5oVJ68////OH60////HHe3////////XJWkBGGu////////////bLrWKZLfpKq0er/5PHSP////GU5x////rLrMvMjQVIugVIKMfJKsv8LEJDE6////pMLc////////bKPPdK7clMjwXGZsKH60////lLXOvNLkFFaMfIaRfHp8vNvxNIrHpKKk////VFdXPFhgFEJkj5OUPEJEbKrc1ODwNDI01NLUZLrkFFqERJrM////hNr3////VGZ8VKbMGX7ICE6EDC5ETKbY////////b3qETK7s8vb4////DGKkPKbs////fM7kerrqdLrMaJq0JG6kPI68////jMr8KEhk////GVWCTJPPFInl////FGKk////////BEF1LGKQTGJ8////////DI70LI7MNqb2////rLK8lKKsXJ7UXJqspLLEPHqcXIKklM78fI6cbLr4VJjQDEd0FGehDCg5TKDMbMfuNFpsTGqELI7cHCkxPGd3rMbcTKrv1Nfc////fNX0DFyYbMLoHJPoLDhINHOcPE5c////HDdFHElkfMDUjNXmHDE6HD5RXKvPfLLkXKrkLFBgfLLcXGp0/v7+CP4A/wkcSLCgwYFHcMTSJAXJBwAAjHyQoikW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aYlTtOQUVDhDAuJRjGfY057P4AMtzqYRawYhHsqop0SV8YxiHOEF+tDHLhIhCgzgwDE4wIAoErELfZzhBUcohjXOIFGJ8iEI8OwKJ6iQCnKMo6US7UY8pmHMbiSACBL9AhGS0I0gHGEaR3gGUHFKhCOkggrjNIgjEoANdLT0CxIlAiL4cNRpePWr0yBHB15w03piFasBeAE2EuBLFmGgG+goBiIC8IW61pWuZ+3DOBKQgHEs4ayAvesXEuAFdHTjlE/iRCISUAsvzNWukLWrBjQQ2com4Ai1WIY4OWUGNCyjFvZAx18jS1nJfqG0de0DAeyRWTSkEVhmmFQEKQgwA3vYABFLKC1lJ2vXPpjABjPwAgGWMYnX1osTLkADKRABXB7YwxgPqEUtHmAMe/BgBrclBRpEEdUxmYEOaAgCIhBhgvKaYLlBQAMdECuggAAAIfkECQkA/wAsAAAAAEAAQACHBAkOBIfvjIqMBEZ8////TFBQR42xBGasBCZDhMvfRJ7UJCYsKkhS////xMbMZ7PQKZ/1////ZMb4KInK0eb5Z6GxJHe3BBYjRG16bIecBFicJFZ0bLPpFCcxBnbLJI3cbHV8JGaMSJLERKTkFBkZkazBpMrsBDll7vDxzNrkKVd/BHjX////dNL8ZMHyF0lqRHuRKXapFJL0////ZKzE////BCpMBBktrKqsJDhCNJ7kGzA43N3gVbPjTJK0dMfhBw8Ub7/cGzhIGYfZh9ToVKzc////4efp////JGeUVKfsVIiYBl6jdLTsdIKR////rNb4F4LUNzc5VLv0CXC6PJbMLIC4VGyATJi+Bj9rPGKENJjcFD5UBEyHfLLcfKXHNFZcPJLc+vz8////KV+ABn/bBCA3NKH3////////4O/8TGJ8FGagDDBEV6HBKVBjPIasFHbEJ5LhFCAmGU5wGY7olJyhHCkxfHp8pKq0er/5VICQZK7M////////////rLrMvMjQPGZxfJKsOHic////v8LE////M3GYpMLclMjw////////PHCIbKPPVFhalLXROWBxJDE8vNLkfIaRWI6wvNrxXGZs////pKKkSazuHGGSPEJEFHK0VJjQFEJkj5OUjMr8VI68XJSk1ODwdK7c1NLURHKCZLrkZ5qx////dLrIGG6q////F37KfL7UbLrY////DB4kcHqE8vb4TIKc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2uTu8PEEXKQ5WWEkl+kEHjQcUmz///900vhkwfP///8UlPQkN0QUNkksdan///////9Eeoysqqzc3eD///90wdlnq8L///8UP1n///+E0+p0x+cFftwcYJIHDxQUSGzh5ukLHypZs+AkUGlUrtw3k8xkmqwmWH1xe4Ss1vj///84ODz///8YcrR0tsx4s+ZcrOg5mdkUgdccaJ40hrxUboR8pcc4ktj///8GP2v///9UmsD////////g7/xXvfRUXmhUnsAEcMcsfrT///8cd7cUICZclaRMrun6/Pz///80XHQkQUz///8pYIJ8e3+Um59sutYqkt8cKTGkqrR8v/Y8dZGsusy8xsxUi6BUgoz///////84frS/wsQkMTf///+kwtz///////90rtxcZmyUtc680NwUVoxso8y82vE0isekoqT///9UWFgUQmR8ipePk5Q8QkRsqtzU4PDU0tREdoxkuuQXWoREmsz///8ajuKE2vcZTnFPZnxUpsz///80MjQIToQMLkRMptz////////y9vk8Xmz///88puz///////9xgpF0usz///8kbqQ8jrz///84YniUzvz///8nSWT///9EcIgZVYJMk88UieX///////////////8EQXX///8YesgMjvAsjsw2pvaEzuSssrxcntRcmqxQrvh8goyUoqykssQ8epxcgqRsuvxUmNAMRnQUZ6EMKDlMoMxsx+4sjtw8Z3esxtxUqO7U19wMXJz///981fNswugckuQsOEgcN0U0c5w8Tlz///9MfIx8wNQcMTocPlGM1OZ8yOQcSGQsUGBcq898stwkaJg8h7JcanQMcMAcICQsQkz+/v4I/gD/CRxIsKDBgUnEfRlmqEIuN24qsAGjDUuJMwczaty4UQ4kSfnysdMBpySJk2p+/IBwT1QzcFgmyeFIs6ZAFV9E3Ak26E8uLiuCrmhAlOiaZU5Q3QKlZU8CWDajFsRpilcwEaEuaL0gNGjRBmvCht3SBF6WPX5USLUp51E9DeGgDJi7lSvXoUOLiuXAAQUKLUSWtOg1c61GHrx+xXqRLNncAXW74tUblq9fFEW0PDsxC6Nhg9Yw2WMiZkTjx5AjcRkpCI60DRvUkNFFaVnly0VyLyHSQsrngXIyBGmHKYJpMadX3dHRkx0Xbgaic7PCRhcZCBC8bVnjN3fuFudm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pdaq1OQMTmyhHeAzFg3ekUD2pbB7lTWrwg5wL80qwRnD0mgGNHo6lUtAQot6xCtlxaba1f5KCSRYRgLSdQmrXWIADGCB7/4QuuYGTmocS2sTBlsCTFw0VpMAxDAq4bskouG7aKCbHYxQCSMYIV/TAAJt+zUPOUACDrdgwDk2JgMjLMMTc1jHPDYVEAAh+QQJCQD/ACwAAAAAQABAAIcEER0MiuQEToSMjpRMTlRMiqQEb8NMsuwGL0wkTmQnb5yUyvQkMThMn8xstM4MP2EEHzMEXqQEf+HM1NgyjckkXoBsorREcYFsxuwkgMBvdXwsmuSMstRsjKTf7PgEMFdywNlUoeIUICb///////9EgpwEQHGsr7c0UF4kQEwEFyQsdagcYJA8YGpss+osjdlMkrxhtNgUL0Jcqs8bgMkEcszM4PAEIjyUv+H09fg5QUk0fqw8m9lcu+pamK4sV2psq7tsl7gXOlQUOEwcTm/EzNRcorwcQFdcbnwYKCsUGhwMZqQHN1n///////////////8qSFP///8ahtj///98yN50gY8aeLr///84dqQ0aoh8tec8pOckl+qMorQ0cZE8jLgkZozr9Pn///8EeNZcipx8usxEepR8jJgEWJw0WGQkerQZZ6AWgNcEKEYaWIAWKTf///8MEhVsutYkhsykssR8wdQESH+8xc4MGB86Z3lctegcMD2kwtx0qtjB2+9UYWykpKQijdqszOhEanRUepx8pshcpOBclsSMmqySuNm81uyUp7f////c2txUgpT///9cntRJeIp90Otcrtz6/PwkOEAsYpTs7u88nuxklqR8l698vvRUg6xUkqT///9Mptz///////9EkrwcRmAMdsRMptQMJjTU2uRMhpx0uvTU5vQ0RlRkprzc5vR8hpTE4vwkkuSo0vRUanz///8kUG8EYa3///8kdbf///9UltT///8nWHb///////9QqvQkSGAUecf///8MhuRseoQMNkystsR8uu98kqSkutD///88XnwMcbxUoMZ0tcQMHygsX3h0x+QsgsiUrsR0ipxMgZf///90s+lkrszU3uk8gKREnNJkvOb///9knrR8gIZEptyUoKc8coxEirD///8Md8xMd58MWpQ8WmQMJzwMSXfExsh8rdRceJBMVlxckqQ0mtw8apQserB0uswshsKUmpzk5ugMT4FUjqJUs+osT18UP2AMYKAMgdzU1tT+/v4I/gD/CRxIsKDBgR4GXQtB4YWgh4Ji8QihSpaYgxgzatRY6Y8fehS2zZgHYl6Mk3NAVKnC7QC8DapgVdpIs6ZAMYqk0TPioAGFDOVqCCVDlGg/QZn2VMHAZQOOizajEhTDDtcoCzBoGNhqQKjXokQlSCAjQVC+ST26cIIqlWYlRbjGedthwFZdrluH1gBLVqxfLlV6bFgws21GV9p2aNphy67ju3i97gU71q8ELpMOZPJg+GAfNvjGNR7duC4zaaOatXIwr7WDGKbgTQlrWcKwfNE2yOo8sJIFBfgUpEkTgTQzbUaAwABDj0awUsGC0aDAYwYIEJRm15bQZRIXVYXb/lbq9KXaueER0keI623clSuRcCzyIKZSJTEe/uA4NIUOODtzwNOXbRIEgEE+v4RnUw4liHPGcBCmwc8478iDCxA22GTDNW3Ak1IX2/XQQ4JRjfeFOGkIEOEK72ShwFOGVbLAFDxUQYllw0ggIok1BQGNOHcIIKSK1VTDDztsdVbJFm3EEI0gtfWQjws1JfPGBUOqeE4hCqyQDW8GrSLINlXAUxtTu2mUzZXqBCnklmHgkwOYB+XwywtV8IBjNF1whlEl8ehBxB2E3nGPOSwEoSCdBFXigiBlWtZFNJksOtA0vPByhwmFXlBBEIxu5AKeUPp1wC8LHCQGES08YAKn/nfocUknlobaaAg8gNCGZXwmKdAm+hDx6qu86BHGnLZqlMMLe1BCFlkbxMBJQZiog86wJqijhzqoJEvTKv2AIKBfGMSSpBfAkMIEEyYwwUstm3hb0zHwgNBPWBtQMq1AldSixrrtmtACEbXKW1AONDjAQ1hkRBNLYUXsA8wHTHxgwg9ETGNwTQu8AEJREoDDAywCdRBFMRSvi446yG6sbMICEjUFN1T+A0wUH+TMBCnAdOByTdeIBNYcsfxjzxAp5JyzPg9M8DNNNrRhRj+TmfKCGHUMMYQbSqNAxNM1BeMABZO9AI4saFiCANduCAFMO2DTdEgDDQzVTwxbzJKC/ht8fzDEEeHEvREOFGAj2Tyg6GMJ33wfMQQegmv0R8J51RADBUJYcgPjKRTjSOQZecCMM6XU0NUML8jAx+Z8790y6AWJYQAQV3RlQDN0pCPDDbzfsHfBoFcyu1ZdNUDDKXD07sbiwEdeiS20c2U8HHBAAAHvi78O+0BiLAEEM3c1kIEl1VsPweKfb1+QB94z41gz0kSRhPkQyHAK5OoTtAgu3jxmBAWASIIKzAeHUwQufwNRxBr65xgj6OIbp4CACgaIPCQgcCCI0IZoGsMMH/jhBHl4xgAHyIchXFAgbPCBPEZzBTAMwh4qEOEIC1iEC2aDH5pgw2i0sQbOWEIE/hOc4ClEYIULGmIFBSBOY3ywBoFoQIYThAD1tOc8fqQiC8QpjicsIJB15CEPQVSBCE6RiPwpggVliAB6VrCCP/CLAXkAgArkCAER8IGKYMsBC86AIggVYAXhGUAcwyiCZ6Bhe4ZgwSPOMxw2aIMDBMHEFwFAyQmKAAL+AB0qBCCJL6hIRWdgg6++EcdKxlAEKcCjwXJwCS1IYkhpOMcZDGEQTIiglJVUwjMA0bxQjecNkniDmzgpyoPUg5LItKQKiAG2IKjjAppy0yUUUIc/6UAOyKwkEInRSyUhQx2EgEahBHCPM2QBeI7IAzazmQcgAkKVvMlBIdTRAmi8qlDx/njDlzQSDgCsM5m3TEEmbYUKXrDqB8Mi1DJYkIyaaCCbAAUjGuBZkxxsggm1QIewsMWLT9mkEgT4JztvyYdwUBQjOWAEEYTwAxQ8gF3sMgERoGGObg4kBwSAKECBCAcr1LAmE6DGPoYADBSoa10wrQUvatoWnPpTpwBoZyFVwAckhAMPjsiBfXLgCDwwoh1HQMAQohCFzqUMqbWoRSFO+qeHQjWIIkhCEp7xDPpdj28ykIElUpCCISBAaTq7GCk6YNOMBEIOIs0mXOEgVz44lg+WYABkZbA2xgF2H/rYRzVD5Q9LIBaqcoziACFQ1+ttjnV941oxgHGEZezTVjmoccdnIRpG0Zqvd7xjnBuKcYQUHIERhZUKJjSghNlWMrRBtN5oTbs5BFjCEkNABibAholXMMCf65xjbZd7PThMFhiJmK7z1qGB634xhCGs4xCpR70bAIMYRQiuwexxAisAQgdwmGo6+BAFQFDjBPYIVUAAACH5BAkJAP8ALAAAAABAAEAAhwQJDgSH74yKjARIgESy/ExRVP///0yGnAknO4zK/ESf1StIUSQmLP///8TGzCSe9Gy0yf///2TH+SqJyiR3t9Hm+WagsgQWIwRYmmyKnP///wwzSjRXXwd2y2yz6SiN2DRqhBQZG////290d////0mSyaTK7AQ8aRQnL8za5O7w8f///xdJav///yhYfmTA7yl2qQQZLSSX6////yQ4QXTS/P///1KUsjSe5qyqrNzd4BSH32SqxEh6jITY8lCs3P///3TI6DqTyihplFSn7Dc3OQcPFARvxHPA1wRdpv///xwzPv///zRafOTo6HSz6XGCkf///6zW+DeZ2f///////1Sz6BR4wv///xaC1AQgN0dmd1SHl1mfvCRPZzSGvHylx1RuhP////r8/BRPeP///yRBTiRupFy65JScoxxmlwQuTHyy3Dh+tAweJBQgJ0SazBwuNASA5Hm/+RyQ5P///////xRwtODv/P///wwYHjJgcjyS3KSqtBwpMRRgnKy6zLzI0Dx2kFR+jHySrFReaL/CxITR5sTS4HSu3KTC3KTS/P///2qkzFSX1Cx+tDxwiJS1zjxCTCQyPLzS5HyHkXx6fFyWp7za8VyOtP///6SipP///zRxmJTO/I+TlFRYWFSOvFyrzgRyzXx/h9Tg8NTS1P///2S63P///2iatBh+zFimzBdurDx+nP///xw6SgQ2YAxenGa66ieS4v///296hAxCaPL2+P///zym6f///0yCnIre9////3m67P///3S6zP///0SKsChIZP///////////////1ye1ChikP///////zR6pFyCpP///wyO9CyOzDhigDym/KyyvJSirKSyxHyOnAxIeJTI8Eyi1Cyf9WzI8AxZlBQzRTxmdEyq9KzG3Aw8X9TX3GzC5////yw4SHzT8Tyg5ByI3GyrvDxOXHzJ5Fym5AxuuHy05Fyy3Bx3uAwhLixRYTyItFxqdBxRfCxCTCxxoRwgJEyWwAx+3BxhlMzR1KzO7P7+/gj+AP8JHEiwoMGBeKTMIbINx4OHD7ZNszJnEZ6DGDNq1DgG0y8ZOKxI8OHjUBBu3GqQ9FEDzbRtczCN2UizpkBcc6agI3doli4ZO+QEGEo0ALQHBCT0qkFgWwJcNqMWxPWOFjx2P2jJ2cpVaACvRYc+eNFLwoM5UKXWHJPtww8kcPZ1nbv1a9ii0Kb5kLDN00y1GfHwgQO3gxzDiOnOvTsUWgACPlxeBGzQxCoIrDpo3rx53xRt8IKwO0T63AsruugwNoqmxrZFlAeOSTQBwoQjo3J3GNVhHzok7ODpmkJnR5YAO+jg0DXr0DkrDxg/8EFg1l+1uByV4HHniPfco9L+iUKibUKWdtkw4cE1ZgwuPJiywaNDy4rJbXehtQSXNiouffp04d2AR1zBCgR8rJJIBTZV4AE06LDDzjZgDfWCBPxFNYYjw+iThDvuJOEdPRAIsYoi/fnnCR3oHIKGY0Wh8QI4123UCD03iCjiEe500cUd76QIGE47vMCOVnYF8AIas9SkCAyXfChlK13Q80gpsRlUAS26HIKDUF5xMw1sGlVwxiWyJKFmEndY8IgjQmZ5ExG0HIIOV1+dI8NkB43RBhdnrJlEK5dQ0EiNchI0xhO0sPMlVzIEgQ6iA0XSiSsYYLDmJWc0kuhGHtSpFVfggJPNQSqowUWmrB7QTCj+lH6qKBERysUVOzLECYYgQwyQ6QD48HJGnLJO9QE8qBy2FQ7w/FKQCvz04Kuv3XDxB4PFblTKPkhMoWwH5NCSIhggKDPAtLyCkW1NvwiBRGL1nSrQGMqEce653fTAD7HrTpUFBOgkhsQHfyHiwh73DgCJMpH0W1M2E7y7GTpTYCKQKnuQcS8ZPdjDr8ME4XKZEJtlgYoHArmwxS23DHCLCy6oAnJNTwghim6jeBDNP06wMM8AJ5wwwDdkpDAzTRVcEcxuvCkQDR6AeMFC0Cfc8o09R9e0ijq34TYBHP4QMs8tVLPggjNZ05QMgAN2IMo7PXAQy9wneOFFNWlvlM3+I6wQyIMjTawz99xSB5K3RpjEo86OSfAQDQsLrBGL5OucoMPhgbmjTojeOfIILMSsIfka84ijAuYYqZCEBXdwfkM8G5ghuuiCx4r6GKu3ouMwsMMy+xqR24457hbo/iE98XgDCwJraAH8Gh8fjksSlxifxDBnwEJD86LLjiXqBjkhC5prDkPBOks4r4UWsHhjOPgFUfJHJpqqmUkbW9CwvvPeeIM3/ASJxBAOwCoMHCAUlUABAva3hjiEAYAEyUQnBFHAA4CBGgiQx/4QMAlYQHAg0eoVBgaghmYowgnyQEEM9hcHBPTjgynoxiC64SsMDIEfF6GBClcYAxSgAAr+H1SFMiCRsB7gQyC2eIMWYsBELcTBG9Gb2RjIAAmE1RASMvuHA2LgBiYyEQXySAMAI2EPSGDjXi5QBiLmNYk3XOACXkTBEqLYL1zYYw9NaNm5FnadT+jhjYB8gxsqAT5C2GNlQBsAC/agroGowA16MMIFjBCDCyjRFJhLwS324IWgAU0aZDgdQaAgyVJewA0hMAcdP4ULF3iBA1Q7ATZcQIjw5SOSpoRkIYQnqzEMQhwcEEcsOWAPURYkDaU0gjIv8EdbZC0DG1gHCwYXCxZ4oWF9koQRAKDMZf5xBLyMzRgysIZ1mGFyg+NAE4Q3jkhys5tG+GMhVumfMGzgHrL+m10sFnCLy2lkE9wEgEC7GUlzvFBW4yCGN+7hu9+xABbWqMkIBErRgUbyAqSgJ0ZwcQ0ELIEG3mDe7GABiwzYZAwFqGhAlRlJP6RBowPBRTVo4NHtaWGBzVNeGMIZspSqdKDxNMIbbHFQmvQDCmD0xiRQsD6cakF5W4DpP3Dh059uE55+qMcnDKED9oxBBTowRBrqsYQYyMMPfmDq/vbXv6hSZgwT/SlQg7rMbgISjnp4AwreoEE4rnB/S0AAFHiqEWTKtaIEjaceFhuCELjhDX8EpBeZmMI19AGhRTgsRa8KT1NK8q6VXCEY1+HPXn5im5pVKWft+tk3PhYF1SBJrFpUYInUInal8HyjHh4LBWOCTAUCyIdtN5vbSE7iE77N2hgMUQ8GaPaq7zTCJEbgANk6TAc5GEEBihAC1ObVHKCAQh9Km6WAAAA7MGJrRXo5Y2lXNnVmU0JEVzFsWjk4YnBTejVFT1Mvbm5iRHBCSDJBNE5ONjFRSXU2QzdKNElOS3RHaFgwemlKbg=='
-
-
-
-bar_striped = b'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'
-
-# list of all of the base64 GIFs
-gifs = [ring_blue, red_dots_ring, ring_black_dots, ring_gray_segments, ring_lines, blue_dots, red_dots_ring, bar_striped, line_boxes, line_bubbles]
-
-# first show how to use PopupAnimated using built-in GIF image
-for i in range(100000):
- sg.PopupAnimated(sg.DEFAULT_BASE64_LOADING_GIF, background_color='white', time_between_frames=100)
-sg.PopupAnimated(None) # close all Animated Popups
-
-# Next demo is to show how to create custom windows with animations
-layout = [[sg.Image(data=gifs[0], enable_events=True, background_color='white', key='_IMAGE_', right_click_menu=['UNUSED', 'Exit'])],]
-
-window = sg.Window('My new window', no_titlebar=True, grab_anywhere=True, keep_on_top=True, background_color='white', alpha_channel=.8, margins=(0,0)).Layout(layout)
-
-offset = 0
-gif = gifs[0]
-while True: # Event Loop
- event, values = window.Read(timeout=10) # loop every 10 ms to show that the 100 ms value below is used for animation
- if event in (None, 'Exit', 'Cancel'):
- break
-
- elif event == '_IMAGE_': # if clicked on the image
- offset += (offset < len(gifs)-1) # add 1 until the last one
- gif = gifs[offset] # get a new gif image
- # update the animation in the window
- window.Element('_IMAGE_').UpdateAnimation(gif, time_between_frames=100)
diff --git a/DemoPrograms old/Demo_Bar_Chart.py b/DemoPrograms old/Demo_Bar_Chart.py
deleted file mode 100644
index 276e4471..00000000
--- a/DemoPrograms old/Demo_Bar_Chart.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import PySimpleGUI as sg
-import random
-
-BAR_WIDTH = 50
-BAR_SPACING = 75
-EDGE_OFFSET = 3
-GRAPH_SIZE = (500,500)
-DATA_SIZE = (500,500)
-
-graph = sg.Graph(GRAPH_SIZE, (0,0), DATA_SIZE)
-
-layout = [[sg.Text('Bar graphs using PySimpleGUI')],
- [graph],
- [sg.Button('OK')]]
-
-window = sg.Window('Window Title', layout)
-
-while True:
- event, values = window.Read()
- graph.Erase()
- if event is None:
- break
-
- for i in range(7):
- graph_value = random.randint(0, 400)
- graph.DrawRectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
- bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='blue')
- graph.DrawText(text=graph_value, location=(i*BAR_SPACING+EDGE_OFFSET+25, graph_value+10))
-window.Close()
diff --git a/DemoPrograms old/Demo_Base64_Image_Encoder.py b/DemoPrograms old/Demo_Base64_Image_Encoder.py
deleted file mode 100644
index bf7a6b44..00000000
--- a/DemoPrograms old/Demo_Base64_Image_Encoder.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import PySimpleGUI as sg
-import os
-import base64
-
-'''
- Base64 Encoder - encodes a folder of PNG files and creates a .py file with definitions
-'''
-
-OUTPUT_FILENAME = 'output.py'
-
-def main():
- # folder = r'C:\Python\PycharmProjects\GooeyGUI\Uno Cards'
- folder=''
- folder = sg.PopupGetFolder('Source folder for images\nImages will be encoded and results saved to %s'%OUTPUT_FILENAME,
- title='Base64 Encoder',
- default_path=folder, initial_folder=folder )
-
- if folder is None or folder == '':
- sg.PopupCancel('Cancelled - No valid folder entered')
- return
- try:
- namesonly = [f for f in os.listdir(folder) if f.endswith('.png') or f.endswith('.ico') or f.endswith('.gif')]
- except:
- sg.PopupCancel('Cancelled - No valid folder entered')
- return
-
- outfile = open(os.path.join(folder, OUTPUT_FILENAME), 'w')
-
- for i, file in enumerate(namesonly):
- contents = open(os.path.join(folder, file), 'rb').read()
- encoded = base64.b64encode(contents)
- outfile.write('\n{} = {}\n\n'.format(file[:file.index(".")], encoded))
- sg.OneLineProgressMeter('Base64 Encoding', i+1, len(namesonly),key='_METER_')
-
- outfile.close()
- sg.Popup('Completed!', 'Encoded %s files'%(i+1))
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Borderless_Window.py b/DemoPrograms old/Demo_Borderless_Window.py
deleted file mode 100644
index 38a4a287..00000000
--- a/DemoPrograms old/Demo_Borderless_Window.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-"""
-Turn off padding in order to get a really tight looking layout.
-"""
-
-sg.ChangeLookAndFeel('Dark')
-sg.SetOptions(element_padding=(0, 0))
-
-layout = [[sg.T('User:', pad=((3, 0), 0)), sg.OptionMenu(values=('User 1', 'User 2'), size=(20, 1)),
- sg.T('0', size=(8, 1))],
- [sg.T('Customer:', pad=((3, 0), 0)), sg.OptionMenu(values=('Customer 1', 'Customer 2'), size=(20, 1)),
- sg.T('1', size=(8, 1))],
- [sg.T('Notes:', pad=((3, 0), 0)), sg.In(size=(44, 1), background_color='white', text_color='black')],
- [sg.Button('Start', button_color=('white', 'black')),
- sg.Button('Stop', button_color=('gray50', 'black')),
- sg.Button('Reset', button_color=('white', '#9B0023')),
- sg.Button('Submit', button_color=('gray60', 'springgreen4')),
- sg.Button('Exit', button_color=('white', '#00406B'))]]
-
-window = sg.Window("Borderless Window",
- default_element_size=(12, 1),
- text_justification='r',
- auto_size_text=False,
- auto_size_buttons=False,
- no_titlebar=True,
- grab_anywhere=True,
- default_button_element_size=(12, 1))
-
-window.Layout(layout)
-
-while True:
- event, values = window.Read()
- if event is None or event == 'Exit':
- break
-
-
diff --git a/DemoPrograms old/Demo_Button_Click.py b/DemoPrograms old/Demo_Button_Click.py
deleted file mode 100644
index 84f16376..00000000
--- a/DemoPrograms old/Demo_Button_Click.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-if not sys.platform.startswith('win'):
- sg.PopupError('Sorry, you gotta be on Windows')
- sys.exit()
-import winsound
-
-
-# sg.ChangeLookAndFeel('Dark')
-# sg.SetOptions(element_padding=(0,0))
-
-layout = [
- [sg.Button('Start', button_color=('white', 'black'), key='start'),
- sg.Button('Stop', button_color=('white', 'black'), key='stop'),
- sg.Button('Reset', button_color=('white', 'firebrick3'), key='reset'),
- sg.Button('Submit', button_color=('white', 'springgreen4'), key='submit')]
- ]
-
-window = sg.Window("Button Click", default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False, default_button_element_size=(12,1), use_default_focus=False).Layout(layout).Finalize()
-
-window.FindElement('submit').Update(disabled=True)
-
-recording = have_data = False
-while True:
- event, values = window.Read(timeout=100)
- if event is None:
- sys.exit(69)
- winsound.PlaySound("ButtonClick.wav", 1) if event != sg.TIMEOUT_KEY else None
diff --git a/DemoPrograms old/Demo_Button_Func_Calls.py b/DemoPrograms old/Demo_Button_Func_Calls.py
deleted file mode 100644
index c4d62a71..00000000
--- a/DemoPrograms old/Demo_Button_Func_Calls.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-
-"""
-Demo Button Function Calls
-Typically GUI packages in Python (tkinter, Qt, WxPython, etc) will call a user's function
-when a button is clicked. This "Callback" model versus "Message Passing" model is a fundamental
-difference between PySimpleGUI and all other GUI.
-
-There are NO BUTTON CALLBACKS in the PySimpleGUI Architecture
-
-It is quite easy to simulate these callbacks however. The way to do this is to add the calls
-to your Event Loop
-"""
-
-def callback_function1():
- sg.Popup('In Callback Function 1')
- print('In the callback function 1')
-
-def callback_function2():
- sg.Popup('In Callback Function 2')
- print('In the callback function 2')
-
-layout = [ [sg.Text('Demo of Button Callbacks')],
- [sg.Button('Button 1'), sg.Button('Button 2')] ]
-
-window = sg.Window('Button Callback Simulation').Layout(layout)
-
-while True: # Event Loop
- event, values = window.Read()
- if event is None:
- break
- elif event == 'Button 1':
- callback_function1() # call the "Callback" function
- elif event == 'Button 2':
- callback_function2() # call the "Callback" function
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Button_States.py b/DemoPrograms old/Demo_Button_States.py
deleted file mode 100644
index 0b442699..00000000
--- a/DemoPrograms old/Demo_Button_States.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-"""
-Demonstrates using a "tight" layout with a Dark theme.
-Shows how button states can be controlled by a user application. The program manages the disabled/enabled
-states for buttons and changes the text color to show greyed-out (disabled) buttons
-"""
-
-sg.ChangeLookAndFeel('Dark')
-sg.SetOptions(element_padding=(0,0))
-
-layout = [[sg.T('User:', pad=((3,0),0)), sg.OptionMenu(values = ('User 1', 'User 2'), size=(20,1)), sg.T('0', size=(8,1))],
- [sg.T('Customer:', pad=((3,0),0)), sg.OptionMenu(values=('Customer 1', 'Customer 2'), size=(20,1)), sg.T('1', size=(8,1))],
- [sg.T('Notes:', pad=((3,0),0)), sg.In(size=(44,1), background_color='white', text_color='black')],
- [sg.Button('Start', button_color=('white', 'black'), key='_Start_'),
- sg.Button('Stop', button_color=('white', 'black'), key='_Stop_'),
- sg.Button('Reset', button_color=('white', 'firebrick3'), key='_Reset_'),
- sg.Button('Submit', button_color=('white', 'springgreen4'), key='_Submit_')]]
-
-window = sg.Window("Time Tracker", default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False,
- default_button_element_size=(12,1)).Layout(layout).Finalize()
-
-
-for key, state in {'_Start_': False, '_Stop_': True, '_Reset_': True, '_Submit_': True}.items():
- window.FindElement(key).Update(disabled=state)
-
-recording = have_data = False
-while True:
- event, values = window.Read()
- print(event)
- if event is None:
- sys.exit(69)
- if event == '_Start_':
- for key, state in {'_Start_':True, '_Stop_':False, '_Reset_':False, '_Submit_':True}.items():
- window.FindElement(key).Update(disabled=state)
- recording = True
- elif event == '_Stop_' and recording:
- [window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':False, '_Submit_':False}.items()]
- recording = False
- have_data = True
- elif event == '_Reset_':
- [window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':True, '_Submit_':True}.items()]
- recording = False
- have_data = False
- elif event == '_Submit_' and have_data:
- [window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':True, '_Submit_':False}.items()]
- recording = False
diff --git a/DemoPrograms old/Demo_Button_Toggle.py b/DemoPrograms old/Demo_Button_Toggle.py
deleted file mode 100644
index 0d923be6..00000000
--- a/DemoPrograms old/Demo_Button_Toggle.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Toggle Button Demo
- The background color of the button toggles between on and off
- Two versions are present... a simple button that changes text and a graphical one
- A HUGE thank you to the PySimpleGUI community memeber that donated his time and skill in creating the buttons!
- The text of the button toggles between Off and On
-"""
-def main():
- layout = [[sg.Text('A toggle button example')],
- [sg.T('A graphical version'), sg.B('', image_data=toggle_btn_off, key='_TOGGLE_GRAPHIC_', button_color=sg.COLOR_SYSTEM_DEFAULT,border_width=0),],
- [sg.Button('On', size=(3,1), button_color=('white', 'green'), key='_B_'), sg.Button('Exit')]]
-
- window = sg.Window('Toggle Button Example', layout)
-
- down = True
- graphic_off = True
- while True: # Event Loop
- event, values = window.Read()
- print(event, values)
- if event in (None, 'Exit'):
- break
- elif event == '_B_': # if the normal button that changes color and text
- down = not down
- window.Element('_B_').Update(('Off','On')[down], button_color=(('white', ('red', 'green')[down])))
- elif event == '_TOGGLE_GRAPHIC_': # if the graphical button that changes images
- graphic_off = not graphic_off
- window.Element('_TOGGLE_GRAPHIC_').Update(image_data=(toggle_btn_on, toggle_btn_off)[graphic_off])
-
- window.Close()
-
-
-toggle_btn_off = b'iVBORw0KGgoAAAANSUhEUgAAAGQAAAAoCAYAAAAIeF9DAAAPpElEQVRoge1b63MUVRY//Zo3eQHyMBEU5LVYpbxdKosQIbAqoFBraclatZ922Q9bW5b/gvpBa10+6K6WftFyxSpfaAmCEUIEFRTRAkQFFQkkJJghmcm8uqd763e6b+dOZyYJktoiskeb9OP2ne7zu+d3Hve2smvXLhqpKIpCmqaRruu1hmGsCoVCdxiGMc8wjNmapiUURalGm2tQeh3HSTuO802xWDxhmmaraZotpmkmC4UCWZZFxWKRHMcZVjMjAkQAEQqFmiORyJ+j0ei6UCgUNgyDz6uqym3Edi0KlC0227YBQN40zV2FQuHZbDa7O5fLOQBnOGCGBQTKNgzj9lgs9s9EIrE4EomQAOJaVf5IBYoHAKZpHs7lcn9rbm7+OAjGCy+8UHKsD9W3ruuRSCTyVCKR+Es8HlfC4bAPRF9fHx0/fpx+/PFH6unp4WOYJkbHtWApwhowYHVdp6qqKqqrq6Pp06fTvHnzqLq6mnWAa5qmLTYM48DevXuf7e/vf+Suu+7KVep3kIWsXbuW/7a0tDREo9Ed1dXVt8bjcbYK/MB3331HbW1t1N7eTgAIFoMfxSZTF3lU92sUMcplisJgxJbL5Sifz1N9fT01NjbSzTffXAKiaZpH+/v7169Zs+Yszr344oslFFbWQlpaWubGYrH3a2pqGmKxGCv74sWL9Pbbb1NnZyclEgmaNGmST13kUVsJ0h4wOB8EaixLkHIEKKAmAQx8BRhj+/btNHnyZNqwYQNNnDiR398wjFsTicSBDz74oPnOO+/8Gro1TbOyhWiaVh+Pxz+ura3FXwbj8OHDtHv3bgI448aNYyCg5Ouvv55mzJjBf2traykajXIf2WyWaQxWdOrUKTp//rww3V+N75GtRBaA4lkCA5NKpSiTydDq1atpyZIlfkvLstr7+/tvTyaT+MuAUhAQVVUjsVgMYABFVvzOnTvp888/Z34EIDgHjly6dCmfc3vBk4leFPd/jBwo3nHo559/pgMfHaATX59ApFZCb2NJKkVH5cARwAAUKBwDdOHChbRu3Tq/DegrnU4DlBxAwz3aQw895KpRUaCsp6urq9fDQUHxsIojR47QhAkTCNYCAO677z5acNttFI3FyCGHilaRUqk0myi2/nSaRwRMV9c1UhWFYrEozZo9mx3eyW9OMscGqexq3IJS7hlJOk+S3xTnvLyNB+L333/P4MycOVMYwGRN02pt234PwHFAJCxE1/Vl48aNO1hXV6fAEj777DPCteuuu44d9w033EDr16/3aQlKv3TpEv8tHS6exXiCvmpqaigWj5NCDqXT/bT9tdfoYnc39yWs5WqXcr6j0rHwK/I+KAy66u7upubmZlq8eLG47mQymeU9PT0fg95UD00lFAptSyQSHNrCgcM6xo8fz2DceOONtHnTJt4v2kXq7LxAHR0d7CvYccujRlNIwchX3WO06ejopM6ODrKsIgP0xy1bGGhhSRgZV7sELaNcRBnclzcwDt4dLAPdAhih+3A4/A8wEKyIAdE0bU0kEuGkDyaGaAo3YwMod999NyvZtCx20JlMf8lDkaK6ICgq8X/sRrxj1QUMwJw/D1BMvu8P99/PYTPCRAHI1Uxf5aLESvQ1FChQPPQKHQvRNG1pNBpdDf2rHl2hHMI3nD592g9tcdy8ppl03eCR3N3VxT5D5n9331U6/2XLUEv2Fe9vsWjRha5uKloWhUMGbdiwnjkVPkVEGWPNUoLnKJB/BdvACqBb6Bg5nbhmGMZWpnBVVWpDodDvw+EQO+H9+/fzDbhx9uzZTC2OU6Te3l5Wms/3AV9R8tCOe9FRSps4pJBdtCh56RKHyfX1DTRnzhx2dgAf/mQ0Iy9ky0jMFi1aVHL+k08+YWWAs4WibrnlFlq+fPmQ/bW2ttJPP/1EW7ZsGbLdiRMn2P/KdT74EfFbYAboGAn2rFlu4qjrGjCoVVVVawqFQiHDCHG0hNwBSKGjhYsWckf5XJ5yHBkJK3AtwPcVgq48y1A0lVRN8Y5Vv72GB1I1DgXzuRw5tsPZLHwJnJ5cdrnSbdq0afTAAw8MAgOybNkyVuqUKVN8yxxJJRa0i204wful0+lBVEwD1sA6hq77+lI8eBVFBQZNqqZpvxMZ97Fjxxg9HONhq6uq2IlnsjkXaU/xLlVppLHCNRck35m759FO0zyHrwpwNB8kvJjt2DS+bjxn/fAloMWRKGY4gWXI8X4luffee5kJ8LsjEQyakVArgEBbYRWyyNQFXUPnQoCFrmnafFwEICgUohEU1tDQQLbtlQXsImmqihyPFMWjI4bbIdUBFam8r5CbCJLi0pU79AjunRzVvU/1ruPFsOHhkO0fOnRoIFu9QtpasGCBv//DDz/Qu+++S2fOnOF3RMSIeh1yIggS3D179pQMhMcee4yTWVEWEgI9wfKEwDHv27dvUPUBx3DecjgvrguQ0Aa6xvMJqgQWuqqqMwXP4SHA4xCMWlGbwYh3exXde0onDwQSICnAhc+riuIn74yh15oR5HMqjyIEDPUN9cynIgS+0rxEKBuOc9u2bczXSG5h+QgiXn31VXrwwQc5t4KffOutt0pCb7QTpaCgUhEJyccoJUH5QfBEqUi0C1q+qBIjg5f6m6Fjlk84H/AekjgcV1VXk+Ol/6Cjih5ciOfkub2iuqA4A5Yi4GMsaaCtYxdpwvgJPh1cKWWBrjCSIaADhJg4J49YKB/hOwCBgnFdBuTRRx8d1O/JkyfZksSAhSBRxiYLAoXnn3/eD1AqvY+okCeTSd96VFWtASBVgtegFNFJyNDdhwTlqKXoO/6oH8BpiKDLvY5+yjSwHcdNOD0KG80kEX5KTBHIIxj7YAMhSNaG+12E5hiwsJyhBP0gIsXAFgOjkgidCwEWuhzNyOk+/Af8BUdRnqpLaojSUen5YSTQGC8gttFw6HIfsI5KRUxQspCuri6aOnXqkP1isCB6Gu4ZOSq9zLxKfj7dcZw+x3Gq0BG4U/wgRhfMXCR//s3Sv25hl52GDw1T0zAIKS5zMSUWbZsLkqMlGJ1QCCwD1dUDBw6UHf1w7hBEdwBEVsrjjz8+yKmDXuCL5HZw6shNhFMXDhu+J+hTyonQuRBgoXsrJqpwDlVesUIC3BaJRlh7hqaxB/B8OXk+2hvtiqi4+2gzpqoHkIi6PJ5TvAQRlFfwKOpCV9eoluORaM6dO5dp4+GHH+aKNWpvUBIsA5EVSkLkRWHBAieOca/s1EVkFHTyACno1L11CEM+o5hhRFAgRWCXdNu2TxWLxQaghYdEZIJ9/J00eTKRbZIaCZPDilcGrMJz0H6465kEY6EKvDwa5PkRhfy4S3HbF7MWJ4ciJA2+8C8RvBzmbwAIBGGqHKoGZceOHX6oLysa5wTlyRIsi4iioezsg/Mj5WhORLCYUZTuO606jnNMOFPkAzB37KNE4BRdSsEmlKX5SR6SQdU77yaFqtfGTQA1r6blZvAaZ/AaX1M4D7FdJ+7Y9O2335aMUnlJzS/ZEOm8+eabw8KJFR9ggmB4e7kSLL3L7yCfl6/h3aHrm266yffhtm0fV23b3i8mR+bPn8+NgBx4NZnsYZ7PZtxMHQBwJq55ZRKpNKJ5inYVrvrZO498v42bteNcNpsjx7G5DI0QFCNytOZG8Bznzp2j5557jvbu3TvoOsrfTzzxBE8vI+TFCB8pXVZSMlUAo9IcPJeP8nmuoQmxbbsVlNViWVbBsqwQHg4ZOhwjlHPkiy9oxR13kJ3P880iKWKK4mxcJHkeiSkDeYbrLRQ/ifTDAcWhXD5Hhby7EqZ1XyuHh6JaUO4lfomgLzwz1gOgYArnLSIfXMO7iOQPx0ePHuUAALOeGBTwIeWeBZNyTz75pF9shd8dDozgOYS6CJqga+l3gEELoiwsd3wvn89vxMOtXLmSXn75ZR6xKKXM6ezkim9vX68/Hy78uVISbXl+Y8C1uDgEEhVMUvVe6iWbHDrXfo6OHT/GeYBY8zVagJBUwkDfcp1M8dZLydVlgCCmIMjL1is9B/oT+YjwfZXAKAeMyGk2btzotykWi8Agyfxgmua/gBiQmzVrFq8iwTFuRljHcTXTWDfPaah+kVHMhahSAdGt6mr+vIjq+ReVR1R3dxf3hQryG2+84U+EyRYyWiJCdvSN3wA4YoKIZ+ekyE6uwoqp5XI0JqItWJhYxXk5YIhKMPIelG1owGqegc4ZENu2d+fz+cNi9m7Tpk0MiEASnGuaFs/2dXRcoGwmw5EUNkVUc0maPfRnEL3pTkXhEjumcTHraBaLXE/CbyBslOP2K3Xo/4tNVra8lQNA3jDgUUuDLjZv3iw780PZbHYP9K0hTvc6OKYoyp9CoZDCixJiMfrqq694FKATOF6Ej7AAHMMpozDII01xfUq5OQwoHY4bnIsySSFf4AVkyAvgs8DBQ43Iq0VGa5EDEk5MiUvW4eTz+ft7e3vP4roMSLvjOBN1XV8CM4TyoUxM6YIzAQJm2VA1TcQTbDHpVIp9S8Es8LFYHIb7+nr7qKu7i3r7+tgqIOfOtdMrr/yHHaMMxtW6eC44+iu1Ce4PBQYWyzU1NfnXsTo+lUr9G8EE1xI//PBDv0NVVaPxePwgFsqJFYrvvPMOT3lCeeBcOEdUSRcvXkS1NdJCOZIrjAOFeeyjxNzW9hFXTGF5oClBVWNlGRCNwkI5VAjuuecevw0WyqVSqd8mk8ks2vCMqQwIuWUDfykplAaFARAAA/qCtXhL7KmurpamT5tOU6ZiKalbagAUuWyOkj1JOtt+1l80IRxr0ImPFTCCUinPKLeUFMoGTWHqWAiWknqrFnkpqZi1HATIqlWrMFk0Nx6P82Jrsb4XieLrr7/O88CinO0MfP8wqGKrDHzk409Xim2sLiWly1hsDdoW0RSCJFFdRlvLss729/c3NzY2fo3gRi7Bl139joZtbW3LHcfZYds2f46AXGTr1q1MO8h+kaNAsZVWi/gZvLeUUvGmbRFJ4IHHsgR9RPBzBGzwwcgzsKpGBq9QKOBzhI0rVqw4Q16RUZaKH+w0Njae3b9//+22bT9lWZb/wQ6iA/wIoqYvv/ySK6siivLXp5aJtsYqNVUSAYao7MLHYmEIyvooQckTWZ4F4ZO2Z9Pp9CNNTU05+ZosZSkrKAcPHsQnbU/H4/ElYgX8/z9pG14kSj+UyWT+vnLlyoNBAF566aWS4xEBIuTTTz/Fcse/RqPRteFwOCy+ExHglFtuea2IHCJ7/qRgmubOfD7/jPfRpz+TOFQYPQiQoUQ4asMw8Fk0FtitCIVCv9F1nT+LVlW16hoFJOU4Tsq2bXwWfdyyrNZCodBSKBSScNgjXsBBRP8FGptkKVwR+ZoAAAAASUVORK5CYII='
-
-
-toggle_btn_on = b'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'
-
-main()
diff --git a/DemoPrograms old/Demo_Buttons_Mac.py b/DemoPrograms old/Demo_Buttons_Mac.py
deleted file mode 100644
index b605923b..00000000
--- a/DemoPrograms old/Demo_Buttons_Mac.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-import sys
-import time
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-def show_win():
- sg.SetOptions(border_width=0, margins=(0,0), element_padding=(5,3))
-
-
- frame_layout = [ [sg.Button('', image_data=mac_red, button_color=('white', sg.COLOR_SYSTEM_DEFAULT), key='_exit_'),
- sg.Button('', image_data=mac_orange, button_color=('white', sg.COLOR_SYSTEM_DEFAULT)),
- sg.Button('', image_data=mac_green, button_color=('white', sg.COLOR_SYSTEM_DEFAULT), key='_minimize_'),
- sg.Text(' '*40)],]
-
- layout = [[sg.Frame('',frame_layout)],
- [sg.T('')],
- [ sg.Text(' My Mac-alike window', size=(25,2)) ],]
-
- window = sg.Window('My new window',
- no_titlebar=True,
- grab_anywhere=True,
- alpha_channel=0,
- ).Layout(layout).Finalize()
-
- for i in range(100):
- window.SetAlpha(i/100)
- time.sleep(.01)
-
- while True: # Event Loop
- event, values = window.Read()
- if event is None or event == '_exit_':
- break
- if event == '_minimize_':
- # window.Minimize() # cannot minimize a window with no titlebar
- pass
- print(event, values)
-
-
-
-mac_red = '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'
-
-mac_green = 'iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjFjKpxLAAAHAElEQVR42o1WaVBUVxZ+CvmbmuhEoUyMJMaJWCQGUNawLwINFEtkp4GGprsBW2Vp6O639M4iLVAzjomaURKNCCONsimKogwko6IwgnEJOEaBTCpJZRaTorvvmXtfwIAmVf746p5733fOd8/prnsOxXEctQCWZfmVYWhHjtVQ5toGSq1XyhMLBD3uca72V31ftq3zc4a1vqttb0W42LdlhfSUM7t3mGv3UizNUTTxWxRnAb9sWG5egHHQafQUyzErU4oSO92iNjzGQZGT90totd+L4ByMEfgiOPn8Dr3iswq5hr/xY3xeVKfGyPrpdQbeH8dZtljoaQFHvdZAFVVIpO6xrg+cvV+CteEr4G2RM8Sa3EF6JBZ2tiSB/FgCpDb5god8Dbwev5IIgnvcRpCWi6XEX62ml2bypEQs42jQGSlhcYZkfcgaWBe6Crx2rLNG/PE1pOhNRGe/bEafP+yCGzP9cG26DwYfnERcfyaKOeCCgrg3rOtjV1ldApwhT55Vuaduz+/VtPpJRgsCDlpcIpFcKHEJcoKN8Wus2+o22NJb3CDz+GZ0/LoZrjzogy++vgpffX8PJr8dh5szQ9A5cQiyPvVA6S1vQ9JHrsij8JU5l5DVUKQS9xrxhXFllvOZkAw0nJZS6RRit5j14Jb66lzSQVd7TpsHpB99B0naAqD3djOMzw7DN/99BHZkh8dz/4H7303A36ZOQYklHNKOuiHhCQ+U3fouCqRdfno91GkutyRLRkqH/0QOFE3TDgaDfkV0XvDsxgRn2/uH3Gyi9i0gbPEkjpDTtgUs4x/AxOxnMPPv+/CT9TH88OO3vMiFeycg/68+IDzhDjknPHmIOjyRf7mLzSPxLWD0aj+WYZdRRl01JVfLmE2CtRBrdp0rPO0Nea1bUf5JLyg46Q3C1nfB0J8LQ//sgjv/GoEH39+GKVyusZlBMF8uxgKbeR7hi9q2ImLntHpaN2evQcni2FMkPlVfY14uyA275lPyml122s8mtfgjqcUPZB3+TyCx+IDyTCL85aoWOnBWLaP1oO/PBkm7D0gX8YiftN0PlXS/Z4+q2WAPTPO8X1tT60Tpa7nS4GzPx0n73GBHdyCSWfyh6NR7z6DQ4g0F7Vt5W4JtcbvXr/KIWPHpAMg9vsXqlfMmlCl2v0ml5Sdy/uI/gAzfYldXEMg7A2EnXpciGH/D6A7h97u6f7GfBu/fGYR29gTZfYvX2bU17F4qs3B7Q7hiEyo9GwJlvWGorDcUys+EPQHZl86fVZwNh6q+SKjsi4CKM+FQ3hsGpT0hsNiH2GU9oaA4Hw4R9AbQmKuAKtidfSbe8A6oLm7jAxAoz2H73M82czEGqoeTof5KKjRcS4em65k8iE3OTEPJPIf3PTfvezYS6EvRSGByBbm6YI5KFSUp4vWbkXogClTnopDqPF4xmAsx0HA1HfaP5sIHY3nPYOH8wzERbzdcycA+AlCe5+MAe1kAAv0m0NbjTPKKMw1xKg8gIuxALL6VALiBONh/IwcO3RTDARzkwD/yfxtj+TyHcP+MfTSX4oG+IEDaoTgUzbnaG/fVfkM1NppLkxVB/9t1OhiZhpOQ5lIc+tOIED6ZkMHhm4VwZFwCRyak8+u8/fQe24T7MfbZd10IussJWCjGmkB7A6dhfKk6Y/2ygsrUGzkHvaB+JMVG6v/xRBF8+sUOOHarhF+fBwvc5nEZMl9Ls8stQbbtZWGPak17VlLk3dJVs/KEKi8rezHW2jiSgY7fkqO2O7uh9fYuIOvzYJ6LWm7JoWk0Yy5t7xYoqhBVajkdRbrZC8SQKrP60vGHxtEMKyF23C1H7XfLoONe+XOh/W4pstzB/KlyW0V3hC1TGTmr0+pWkB6FOyC7HL/5Dhod5yxUCr4u+MjfdvhO4VzvpAq6vqxEGNA9WYWh/A1UQSfh3auE8w9Zm/nzlDlhdSjoa1gxx3AkvsNCb1/O4oO6BpM4j40G8eEAOHq7yHrxoQb1T3Gob5JGfVM0/Ar4bwNfadHAtMZqHkwDkTkCOKNSQmYEFvcp0nWJ0rwQg7sYRxmrdYHZFdEjWWZfqO5PsZ6aLLcOTuvtwzMmNDRtRMPTJsDAqxE+mzWhS9M627GxEmvp0UjIVEWOaHVsIPmdcTy+YZH4S6YUkhpDs5RGy60s04u70lQBkNPkB4rWaGgaFNoOXS20fTJaDM3XZfYP/55vM/a8by8+GAapWvyoMpldHB4+SEX4DBbFfWYc4rAQyYi0Y41B5S9ns7tzlNGPUmk/SGF9IFntBdsZH0jFEDIRINdlDxnr2RINq+MHEnLRp8eiJVMFSY3lJxcWl45x5MVYA2UwGBxprcKd1ii2Nnc0gXm/bl8VXeZeU2dw02tMFMke+zrypf9ZaEnc/wNvUH/BVaIfLQAAAABJRU5ErkJggg=='
-
-mac_orange = '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'
-
-
-show_win()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Buttons_Nice_Graphics.py b/DemoPrograms old/Demo_Buttons_Nice_Graphics.py
deleted file mode 100644
index 2a53a919..00000000
--- a/DemoPrograms old/Demo_Buttons_Nice_Graphics.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/env python
-import PySimpleGUI as sg
-import io
-from PIL import Image
-import base64
-
-"""
-Shows some fancy button graphics with the help of PIL
-
-Usually when you create Base64 buttons to embed in your PySimpleGUI code, you make the exactly the correct size. Resizing isn't an option when
- using the tkinter version of PySimpleGUI (except for crude "Scaling")
-
-The PIL code resizes the button images prior to creating the sg.Button
-"""
-
-
-DEF_BUTTON_COLOR =('white', 'black')
-
-def resize_base64_image(image64, size):
- '''
- May not be the original purpose, but this code is being used to resize an image for use with PySimpleGUI (tkinter) button graphics
- :param image64: (str) The Base64 image
- :param size: Tuple[int, int] Size to make the image in pixels (width, height)
- :return: (str) A new Base64 image
- '''
- image_file = io.BytesIO(base64.b64decode(image64))
- img = Image.open(image_file)
- img.thumbnail(size, Image.ANTIALIAS)
- bio = io.BytesIO()
- img.save(bio, format='PNG')
- imgbytes = bio.getvalue()
- return imgbytes
-
-
-def GraphicButton(text, key, image_data, color=DEF_BUTTON_COLOR, size=(100,50)):
- '''
- A user defined element. Use this function inside of your layouts as if it were a Button element (it IS a Button Element)
- Only 3 parameters are required.
-
- :param text: (str) Text you want to display on the button
- :param key: (Any) The key for the button
- :param image_data: (str) The Base64 image to use on the button
- :param color: Tuple[str, str] Button color
- :param size: Tuple[int, int] Size of the button to display in pixels (width, height)
- :return: (PySimpleGUI.Button) A button with a resized Base64 image applied to it
- '''
- return sg.Button(text, image_data=resize_base64_image(image_data, size), button_color=color, font='Any 15', pad=(0, 0), key=key, border_width=0)
-
-def ShowMeTheButtons():
-
- sg.ChangeLookAndFeel('Black')
-
- frame_layout = [ [sg.Text('Who says Windows have to be ugly when using tkinter?', size=(45,3))],
- [sg.Text('All of these buttons are part of the code itself', size=(45,2))],
- [GraphicButton('Next', '-NEXT-', button64),
- GraphicButton('Submit', '-SUBMIT-', red_pill64),
- GraphicButton('OK', '-OK-', green_pill64),
- GraphicButton('Exit', '-EXIT-', orange64)],]
-
- layout = [[sg.Frame('Nice Buttons', frame_layout, font=('any 18'), background_color='black')]]
-
- window = sg.Window('Demo of Nice Looking Buttons', layout,
- grab_anywhere=True,
- keep_on_top=True,
- no_titlebar=True,
- use_default_focus=False,
- font='any 15',
- background_color='black')
-
- # ---===--- The event loop --- #
- while True:
- event, values = window.Read()
- print(event)
- if event in ('-EXIT-', None): # Exit button or X
- break
-
-if __name__ == '__main__':
-
- # To convert your images, use the PySimpleGUI program - Demo_Base64_Image_Encoder.py located on the GitHub (http://www.PySimpleGUI.com)
-
- orange64 = 'iVBORw0KGgoAAAANSUhEUgAAAiIAAADLCAMAAABkvgh7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAANtvJ99sId5tIt5uI91tJNxuJNxuJttvKN90NN91Ntt3PN52ONx3Otx3PNt4Pdp4Ptx4PepfD+pfEOtgD+piD+tkD+ttD+dnFOdoE+doFOVoFuNqG+JrHOFrHuFsHuRpGORpGuRqGORqGupgEOpiEOpkEOlmEOhnEupoEOpoEupqFettEetsF+tuFOxqFetrGOtsGetvHOxrGOxsGOxtGuxuG+xuHexxFutwH+xxGOxyGOxyGuxxHuBsIOJvJ+NvKORvKONwKeNwKuJxLONyLeJyLuRwKeRwKuRxLOtxIexyIexzJOx0JOx1Ju11KOx2KOx2Kux5Iux4Kux5Le1/LeFyMOFzMuB0NOB1Nux7MOx8MOx8Mu19NO1+NO1+Ntd7RdV8RtN+S9J/TdF/TtV9SNR9Stl5QNl6Qdh6Qth7RK+Tfa+Tfq6Ufr+JZb+JZr+KZ7uMbr6KaL6LaryMbLyNb7yOb7WPdLuNcLqOcLmOcrmPdLOQd7SQdrKReLKRerGSerCTfLCTfrmQde2AN+2AOO2BOu2COu6DPO6EPe6EPsWDV8OFXcOFXsOGXcOGXsaDWMSEWsqCVs+AUM2AUs6CU82CVMqDWMmEWtCAT9CAUMKHYMCIYsCIZMCKZu6FQO6GQe6GQu6HRO6IRe6JRu6KR+6KSO+LSu+MS++MTO+OTe+OTu+OUO+RUu+TVfCNTvCOTvCPUPCQUfCQUvCSU/CRVPCSVPCSVvCUV/CUWPCVWvGWWvGXXPGYXvCWYPGaYfGcYvGcZPKdZvKeZ/GdavKeaPKebfKebvKgavKhbPKibfGibvKjcPGkcfKmdPKiePOod/OpePSpePSqevSrfPSsfPSsfvSqg/SugfWwgvWwhPWyhfWyhvWxi/Wyj/W0ifW2jfa4j/a1kPW2kva2lfW2lvW4kPa6kfa7kva5lvW7lPa8lPW8lve+l/a4mva5nPa6nPa7nva+mPa+mva/nPa8oPa9ovbAm/bAnfXAnvbCofbEo/XGp/bGqPbIqQAAAC/NnaUAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjFjKpxLAAAJXElEQVR4Xu3de3zVdR3H8Xb9/sJh60LlOTtubdIZEyckSdedMzkdZyRGIePmZdqki8s0KllJmtGCTAXRlUAyrireUeZga2JRkooYRWR0JbXMLsIqZ5fT7/L5nRvj9/md0/fhw/Px/fyHP+D33fb4vPj+LvsxXpMA8IREgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgJF7Ih1Xf3bVsuu/AYXu+mUrL+u8iqbqIcdErvhme0V8SjQCIpwWe+0nli+k2R5NTolc0jYzqpQBcigV+UDltZ57SQ6JfLqyRRXRyiCIis7u7qAhj8B3Ip1tLdg/pFLR0Z+hOR/JbyIrWxGIZCp289E2Ep+J3HzEFqLKy0qhUJUfeUkZnf8lGnYWX4l0tDfTOg5VEqoJNNTXh6EgmaMLBKuaymmcJFLRSfPO5CuRtgitYisPBehDQUFrqC3O2EtUxRdo4Bn8JHJhlNawlNZh85Aj2JQeiRp9JY08nY9Euk+nFUwq1ECLgww1ZTRaS+R8mnk6PpEF8dTDkNIgLQxiHFdNw7U0d9PU07CJdLw+tRUVpy5Cxo19+bz9lYI+n5cNfdhcjWGZf2jsCTTJcDiUmnBR/HKaewqbSHfqQqSJrkLGvuuctZu3jOgBD1u99B7Fg6a+Vwrrk8kNfRX+0XE2+qg527adsc38M723d01yK3lbqhH1SZp7CpfIolnJw4udQk44ddPOn/3q6b+M6K8+/c2vF+jXVw29X/ALI7N+Z3jome+f/QZ7pOG6VCMtl9Dkk7hElifvd0uPs1cb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'
-
- green_pill64 = 'iVBORw0KGgoAAAANSUhEUgAAAYEAAACCCAYAAACgunQ+AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAl2cEFnAAABgQAAAIIAb/yLCQAAGGZJREFUeNrt3XuUXWV9N/Dvb+99bnPOZK7JTBIIF3MBAgElEiIBjEWwVl/f6iIKWhRae9GFlxaKttQQQWyL0db61sWqS1kWqw2vdlWrVqzINZogQtKQGHIDcs/cMnOu++y9n1//mImNM3ufOWdu5yT5ftaKK5x9e05c6/me57KfR1QVRER0ZrLqXQAiIqofhgAR0RmMIUBEdAZz6l2AevrIbkkM+sggQBo2kvUuDxHNrMBBIeYg99C5GFScmQOkcroODP/pAUkN5LDQsrAQgoWqWAjFYgg6IGiBQSsEAgCOJBKOxOP1LjMRzSzX5PMKY0b+swQgD8UggIMAdquF3ZZitwmwO17Ayw9erl69yzzVTpsQeP+vpMOxcI0BVoniGgCLIZCk1dxc77IR0amtZLJZKDwItgB4SgVPB0Vs/Poyzde7bJN1yoaAQOTW3bhGDK43wHUCXMhf9EQ0E0ZCwUDwSwgesw2++09LdGu9yzURp1wIfHCnLAuANQq8SwTz+UufiOqtZLJZVeywBBvUxoavvkb317tM1TolQmDNdok3O7hdgdsBtLPiJ6JGVQqyQ7DwM6P4znmL8ZW1UDP5u06fhg6B23bLbBj8CRQfBNDCyp+IThUjXUb7AXwxl8HXN5ylxXqXKUxDhsBt2+Rs4+CjorglbqfbLVj2RO+lBnCH9H//DCqCssL4gPGAwBv5u1/vb01EM812ACsGWDGBHQMsB7ATgmSrIDFr+E88IxieRzgxJZPNAuiH4stw8eDXLtPj9f7eJ2uoELhlq6SdGD6pij9J2s3tE7lHOavIHTHIHVWU+g1Kxxvn+xHRqSnVLmjqtJDutpCZK3AStaeCa/J5o2ZAgfuKF+ErG6BBvb8X0CAhIBB5/3bcCOBeAHNr6fZRAwztN8gfMxjYG8CcdrN4iajRJFoEzfMsNM+3kOmyamoplEw2qwbbRHDnQ0v1mXp/l7qHwG0vykVG8WUIXlt15a9A7qjB4MsGg/tZ8RNR/TgpQes5FlrOtZFqrz4NSiY7BMW3RfAXX1uqR+pV/rqFwDqItXc7PgaDv6y268d4wLH/9tH/UjAl4+0igq6WBYg5ccTtBGJOAnEngbiTxKQ6AYmoQSn8wEPZd+EFLsq+i7JfwmChDwU3O+m7J1oEHUtstJ5vQ6pcma1ksgcE+PBDS/W79fgXqUsI3PqidBuDByFYXc2vf6+g6N9pMLAnmNAAbiKWwrmzL8S5sy9Ea7oTbenZaE13Ip1sYVVPRACAwATozR7G8XwPBvI9ONi/Bwf79qJn6CAUtdWTTkrQsdhC20IbVmz880smm1Xga6UsPrFh5czOIprxELjlRbkBBl9OWpnzxjvX+EDPtgD9uwxq+f8gFU/jorOuwDmdS7CgcwlamiY0xkxEBGMCvNq3C4cHXsaLBzbhUP++qkNBbKDjAgudF47fMiiZXA7ADsvg1ocu1Rdn6vvNWAgIRG7Zgs+q4MNJK5OpdK4aoH+XQe+O6n/5d7WcjQvnL8fC7mXoajkb7M4houngegX86tAvsffoNuw49AtUU4c6KUHXMguzzh6/j6gU5IYg+KOvL9NvzcT3mZEQWLNd4kkP/wjg3eMFQP6o4uiWAOXc+OVKxFK4aP7rccmCq9DdsmAm/r2IiH6tUM7ixf2bsHX/M+jLjj+229Qp6LrURqKl8o9UN8hlVbDu65fq+un+DtMeAu/bJLOsBL6hwBsrBYDxgSPPB8geHH/EN51owdVL3oYL5i+HVDv6QkQ0jV4+th1bXn0Ge49tG/fcttdYmHOxXbHDomRyOQG+UtqFOzbcOH3vFExrCPz+8zKvrPg2BBdXCoDSgOLwcwG8QuWytKe7sPz8N2FR92Ws/ImoIfVmD+HZvf+FvUe3VRw7SLULui+3EUtFJ8FIEHw/ZXDbg5drYTrKO20h8P7N0hE4eCppZS6MPEmBgb0Gfb8KKu7pk4w1YdWSt+M1c5ZB2NVPRKeA/twxPLb9EfRmD0WeY8WArmU2MnOjf9SOBMHmtll46xcXqjvV5ZyWEHj/ZukIbPzIkcQljsRC1/fXADj0nI9ib/TzLbFw4fwr8Lpz34i4nZjychIRTScFsPfYNmze8ygK5ej3EFoWWJh9cfQSaSWTy4niR02Cm6Z6d7MpD4F3PCPN6Ti+H7MSK6ICICgDh5/z4Q5GP7sjMxfXLX03krH0lJaPiGimGfXx/CtPYtuBn0Wek+m2MGdZ9FTSksnlFNiwZDk+OJXLU09pCKz5maTiDr6jglVRYwBefvz+/wvmLcdlC66BJRNePJSIqOEcHNiDn+/+IVw//H2wVLug+7VO5AtmJwaLH16uH5+qMk1ZCAhEbn4Wj0BxQ9IODwB3SHH4F37k3P+Ek8IVr7ke3S3nTtX3IyJqKMVyDpv2/Cd6sgdDjztJwfwVNuyIlUpLQS4nwL0PX6F/OxXlmbIQuHmTfAzAvVEBUM4pDj/nRy721pxswxsW/Q6a4tw3hohOb6qKLa8+iX2920OPx9KCecsrtAiC3JBl4Z0Pv15/MtmyTEkI3LxJVsHge0kn0xp23C8qDv/SRxAxrt2e7sLrz3szYg4Hf4nozLHr6AvYefi50GOJWYKu1zqRW2qV/NwrloVVD6/QA5Mpw6RD4OZN0qUGTyftzMKw44GrOPJ8AL8U/pzO5vm4/JzVnPdPRGekQwN7sPVA+LYCyVbBnGVO5GCxa3I/9WfhLRsu0vJEn+9MpvBrHhHbmo8NKTuzMOydCDXAsa0BAldD5/d3ZuZh2dmrEGiABtlkh4hoRs1pWYCl6mP7oU1jjrmDit4Xfcy+OLyqVoPXO4O4D8CfT/T5k2oJ3LRRPqKKz0SNA/TtDFDoCZ/J1JLqxLKzVsGa+PbBRESnjQP9u7CnZ2vosdZzbTSfFd4cKPm5rNh4yzdX6saJPHfCIXDTk3I2bDybsDJdYcdzRwyO7w0PgKZ480gATKohQkR0Wnm1bwcODOwee0CA2UttJGZFzBgyuefnDGHlF3+79jeKJ1wLq2B9QtJdYSFSzikGXzahiyPZloNFXZfBwMCYCXdjERGddua2no+sexyDxd4xx/p3BZhzScQmNQaLj2bwZwDur/WZE2oJrHlS/o8F/EvCTo95nVcNcHRrEDkT6LzOi9HaNHv6/zWJiE5BgfHwq8PPohxSicabBbMviugWMvn+QHHl/79Gd9XyvJpbAjc8Kum2BL6UsNPpsMHgoVcNTBmRA8HNyVYE3BmeiCjSOZ0XYM+xrWNWIfVyikKPoqlzbAWblHS7q/l/APCWWp5Vcwi0JPAhBdrD2g9eXpHv0dBuoJidQGfzPPgTn8lERHRGiDkJtGe60Zc/PObY0AGDRKuNsCFVVaxa84S8ecO1+uNqn1VTCKx5XDIC3B7aClBg6BWNXOp5dvN8BOrXtFcwEdGZqi09G0OlXvijek40ALIHDFrOGdstlLDS6ZLJfwLA9IQAFH+oQHvYMEKhR+GVwlsBTfFmJGKpMV+GiIiitaW70JMb+0JwsV+R6lDE0iEVrsGKNY/Jmza8SR+r5hlVh8Atj0pabXwk6YxtBWgA5I+ayFZAS6oDAWcCERHVJBlLIeEkUQ5KY47lDinaFo6tdBNWOu2a/CcBTG0IFGz8gQCdoa2APh1e3TokBJJOE1QUHscCiIhq1pRoRrk4NgS8osIdUsSbx1a8arByzY/l2g1v1ifGu39VIbBunVi4Ch8OGwtQAxT7TOSGyYl4E2cDERFNkG3HYNsOgpA1+As9ingmvDVQ0vyHAExNCGy9Etdainlhg7ql/uFWQFhXkGPFIALOCCIimoSEk0TRy4353C8pyjlFPHxs4Pp3PipzvnO9Hqt076pCQATvi1vptIbMCCoORLcCbNvhYDAR0SSJZUXWs8U+RawppDVgN7WUgsK7AfxDpXuPGwLv+K40Owm8PawVUM4qNIgsG6AKnwPCRESTZosFE7K1sF9UBGXAHrOchIgo3ovJhoATx7ugaAobEHazGpkAAoGvHt8LICKaAirRx9whg1T72PcGVHHx7/5ALvu3t+oLUddW0x30nrA1gow/nEAS3QyAgnsEEBFNlaj61sspUu1jP0/Y6bQr+fcAeCHqnhVD4IZHJd1ksEJD1isq57RCPxAREc0UEwBeQeGkxlbKxuC3Kl1bMQSaPawKBLGwLh0vzxAgImoUXl7hJMdWymJwwZofSPeGt+qRsOsqhoAPrE5aTenRy01rMNwdJMIUICJqBL4LhG0NELebMsWg8EYA3wq7rmIIiGJ1WCvAd8FWABFRA1EDGA+hq4taBqtRawis+aHMhmJpWAgYt9KAMBER1UPgAqHbtiveGHVNZAi4Hq5IWMlU2NRQ3wNbAkREDcYvhw8OK3DW2/9D5n/vbXpw9LFK3UFLBJYVtmIoAmYAEVGj0TJC381KWE1NRa+wBEANIWCwJOzlhMAHE4CIqAEphqeLSsi0fhEsQcjy0pEhoIrFYYmiATgeQETUoCLraIPFYedHtwQUi8PGA9Tw/QAiokZlAkBCBodVsSTs/NAQeOe/yRwArWHHojaPISKi+lOjiKikF4V9GBoCgcH8uJ0KnRmkyu4gIqJGpWa4nh7zuWLuunVirV37m0uRhoaAH6A5ZlWo6hkCRESNK3z1Ztm0EBkAQyd/GBoCImiOWgKarQAiosYlQHgIKGDH0YxqQsAEyIStHIrIriYiImoEKuHdQXGrqalgCpnRn9fWEuB4ABFR44voybECNI/+LDQE1FRoCRARUUPTiLraANW1BKBIRFb4bAkQETW2iPrbNkiM/iw0BCyEr0sNcA8BIqJGF1V/Gx0bD07EiYXQJBGwJUBE1OhM+MeWojj6s6gxgSzs8JuwIUBE1NiievPVQnb0Z+HdQYKsRswOqrwXGRER1ZVGDQyrqldlCGiALMJmB4EtASKiRqa//p/fVA5KpaDalkBgI6ecHUREdOrRyLWDEC8hN/rz8BDwcLxsFYtxO5UKu5FEtBKIiKi+VIGIvWDK3/tDLYz+PDQEbAevqA8NfWHMMASIiBpW1Cqign1hp4eGwI9+T/Nv+aocgI7diYb7CRARNS4NNLQlIAYvhZ0fOdfHKHZqaAgoXxgjImpQJghvCRhgZ9j5lbaXfCksTUwAtgSIiBqUCRD+okCtLQFV7AwdXPA4TZSIqBFpgNC3hV2/WJxIS2BHySsWE85vzhBSBYwPWLF6f10iIjpZ4EW8KGag8UyNIeDH8QunjCKAMdNEAw+w4/X+ukREdLKgHLWRAJ7/wXt1KOxQZAj89ANauu5B2aiKt40+5ruKeIZ9QkREjcR3w1sCgcFPo66puBKQpXgcISEQuCN/YQ4QETWEwBsZExjF9YtFW/B41HUVQ0CBx1y/WIrbyeToA4ErcFJMASKiRhAUNXwfAQO31cXGqOsqvvu76ii2iGIAJ15DPulPOc+9JomIGkU5bxBWVwP4+YaPazHquootgbVr1Vz3j/JDKG4bfczLK9DBJSSIiOrNLylMeeznqsYo8P1K1467O4AafMPV0s1hXULlvCIxi11CRET1VM5p6IBw2SvnPeBfK107bghc04fHn2rHflhYNOYBQ4pkC0OAiKheVIFyVqO2E/vRk7drT6Xrxw2BtWvVrP6SfMNR3DP6mFdU+K7CSTIIiIjqwR3U4aUiRikHpRIM/nm866vaLNJSPFz2SnfFneSYF8eKvYrmsxkCREQzToFin4laK6iv8zj+c7xbiGp1s3xW/708GneSbw471na+xdYAEdEMKx1XZA+Z0GOeX3rgsY/qn493j6q3jRdgfdkvXT1mgBhAoUcxawFDgIhoxihQ6AlvBbhBaUgsfLGa21TdEgCA1X8nT8fs5FVhxzoW23CSVd+KiIgmoTigGNof3gpw/dKXnvi43l7NfapuCQCAGNxfNqVvx52xrYHsQYO2hXxpgIhoumkA5A6HtwLKfinrKD5X7b1qagkIRK5dj2fiTnJl2PGWBRZSHewWIiKaTkP7DQq94XV3OSh9+fE/1Q9Ve6+aWgIK1dUi97te6ZGw1sDQQYNEqw2rprsSEVG1vLwi3xMeAK5fKgjwQC33q6klcMK1n5P/iNvJ3wk7luoQtJ7PbiEioimnQO92A68wtt4u+6USBOufuEPvruWWE/rN7is+ql7pDXEn2Tb6WKFXkWpXJNvYLURENJWGDprIxTsN8HLrLNxf6z0n1BIAgKv/Vu4SxT1h3UKWA8y+hLOFiIimintc0bsjfDZQ2S+V1MLvPnWnjvty2GgT7r2fW8QXDifxHlW9bPSxwAP6dwaYs8zhKqNERJMUuIq+XUHoInFe4LoKfGciAQBMoiUAANd8Vq6C4CcxO5EIO57uttC+yK7TPxsR0alPFTi2xR9eJC6EF7hHEoILfnyXDk7k/pMKAQC4+rNyNwR3RwVB+yIbzXPZHCAimoieHcHwm8EhPM8twcaap+7S7030/pOezHldGff/OIYrjZjftsQaU9v3vxTAsoF0F4OAiKgWA3sCFI5FBMBwN9AXnp5EAADjbC9ZjbVr1ZQ8fCAIvH2hW5sp0LcjQLGP21ESEVVr8BWDoVcjtowc/vN0zMOnJvucSXcHnbDyXllhC/4r5iQyoQ+ygO7LHE4dJSIax9ABg76dQeRxz3dfLftYsfkePTLZZ01ZCADA1Z+RG1Xxz1HjA5YNzFnmINXJICAiCjP4ikH/S9EBUA7cbEzxW4//lT47Fc+b0hAAgDfcK3cIcF9UEIgAnUttzJrPMQIiol9ToHdngMFXTOQpnu/m1MKNG++e2HTQMFMeAgBw1Tq5D4I7ooIAGJ41xFVHiYgANcCxLQFyRyoEQOAWBbj16U/pv9Zw63FNSwgIRK5chy+J4vdjTnQQNM+z0HWpzRfKiOiMZXzg4GYfpYHoutjzXVcVt/9snf7TVD9/WkIAGA6CFffgIUvx7kpBEG8WdL/ORmIWxwmI6MySP6o4+oKPoBx9jue7LoCPblynD05HGaYtBICRFsFa3CuKOyoFgdjA7KU2Ws9jk4CITn9qgN7tAQb2mIrneb6bBfDHGz+t/zJdZZnWEDhh5afkjxVYH3cSTZXOy3QL5i53uB8BEZ22/BJw8Oc+Sscr172e7/aI4KaN6/Qn01meGQkBALhyrbwDBg/FnURrpfMsB+hYYqNtkcWxAiI6bQTl4V//x/eFbwt5Mi9wXzbA/930ad0y3eWasRAAgBV3y3IRfFdgdTp2LFbp3HhG0HWpjUw3xwqI6BSmwPGXDY5tCyr2/QNA2XddAfYZ4PrN9+n+mSjejIYAAFz9SWkrC/4fBO+MVxgnOCHdJei8wEbTHIYBEZ1CdHgv4N4dBu7Q+PWs57tFCNb7Pfj0Lx5Ub6aKOeMhcMLKv5Q/MMADMTveWs35qQ4LnReMvGTGPCCiBqUBMLAvQN/OAOVcFZV/UC4DOAKDWzd9Vh+b6fLWLQQA4HV3ybyYjX8HsCxmx+PVXJOYJWhbaKPtfBtWrJoriIimn19S9O0I0L8rgAmqu2YkAB6VBN7787U6VI9y1zUEAGD1OnHyRXwQgrWOFZsjIlX9zhcBMnMttJ5rYdbZNmcUEdGM80uKwVcMBvbVtlLySOW/D4o7N//15JaCnqy6h8AJ1/yFzC4G+LQl+IBjx2vbnXgkEJrnWkh3WUi1C7uMiGjKqQEKPQa5Iwb5I4r8MVPT9UaDIAiCrACfa0ph/U/v0VK9v1PDhMAJr7tDznEsPATBG6rtIhrzpezhJSlSHRYSrYLELEGiRTjllIiqpgFQGlC4Qwp30CB/TFE4ajDRKtMLyi4Uj4iDj226X/vq/f1OaLgQOOHKT8iqwOBOADfE7Pi4s4iqEc8Mh4EdA6yYwIoBtjPyd3YnEZ1xAg8wnsL4v/n3Yr/CL05N3ej55ZwC3xQL65/9G91Z7+88WsOGwAlX3inLAsUdELwrZsebJn9HIqLpFRjfN8YMieCr5QB/98Ln9WC9yxSl4UPghOUfkwXq4H0iuBXAgol2FRERTRcvKLuq2CTAN+MGGzZ+XvvrXabxnDIhcLLL75DLBbhJFDeqoJuBQET1MjLT5yUFvmkbfGvz53VvvctUi1MyBE624k5Z6StWW4prVbASQIKhQETTZaTSHxLgSVU8oRYef+4B3Vrvck3UKR8CJ1u9TpxCHitNgBsUOA/AJSJYpIDFYCCiWnlBuQyFr4IXBdgOxS8tG08++wC26GlSeZ5WIRD6BdeJdXke56mPRSK4WIBWBWYBaIYgA6AZQFoUtb2bQESnPCMoWIKcKnJQZC0gbwTHLeCgJ3hJA+za8gUcOl0q/DCnfQgQEVE0vj5FRHQGYwgQEZ3BGAJERGcwhgAR0RnsfwCReA5ROFftiwAAADt0RVh0Y29tbWVudABFZGl0ZWQgYnkgUGF1bCBTaGVybWFuIGZvciBXUENsaXBhcnQsIFB1YmxpYyBEb21haW40zfqqAAAAJXRFWHRjcmVhdGUtZGF0ZQAyMDA4LTEwLTE0VDE2OjQwOjIxLTA0OjAwPdgB9gAAACV0RVh0bW9kaWZ5LWRhdGUAMjAwOC0xMC0xNFQxNjo0MDoyMS0wNDowMGJpd8IAAAAASUVORK5CYII='
-
- red_pill64 = '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'
-
- button64 = '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'
-
- ShowMeTheButtons()
-
diff --git a/DemoPrograms old/Demo_Calendar.py b/DemoPrograms old/Demo_Calendar.py
deleted file mode 100644
index 79a5533c..00000000
--- a/DemoPrograms old/Demo_Calendar.py
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [[sg.T('Calendar Test')],
- [sg.In('', size=(20,1), key='input')],
- [sg.CalendarButton('Choose Date', target='input', key='date')],
- [sg.Ok(key=1)]]
-
-window = sg.Window('Calendar', grab_anywhere=False).Layout(layout)
-event,values = window.Read()
-sg.Popup(values['input'])
diff --git a/DemoPrograms old/Demo_Canvas.py b/DemoPrograms old/Demo_Canvas.py
deleted file mode 100644
index 60773758..00000000
--- a/DemoPrograms old/Demo_Canvas.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [
- [sg.Canvas(size=(150, 150), background_color='red', key='canvas')],
- [sg.T('Change circle color to:'), sg.Button('Red'), sg.Button('Blue')]
- ]
-
-window = sg.Window('Canvas test').Layout(layout).Finalize()
-
-cir = window.FindElement('canvas').TKCanvas.create_oval(50, 50, 100, 100)
-
-while True:
- event, values = window.Read()
- if event is None:
- break
- if event in ('Blue', 'Red'):
- window.FindElement('canvas').TKCanvas.itemconfig(cir, fill=event)
diff --git a/DemoPrograms old/Demo_Change_Look_And_Feel_Browser.py b/DemoPrograms old/Demo_Change_Look_And_Feel_Browser.py
deleted file mode 100644
index 823e66f5..00000000
--- a/DemoPrograms old/Demo_Change_Look_And_Feel_Browser.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Allows you to "browse" through the look and feel settings. Click on one and you'll see a
- Popup window using the color scheme you chose. It's a simply little program that demonstrates
- how snappy a GUI can feel if you enable an element's events rather than waiting on a button click.
- In this program, as soon as a listbox entry is clicked, the read returns.
-"""
-
-sg.ChangeLookAndFeel('GreenTan')
-
-layout = [ [sg.Text('Look and Feel Browser')],
- [sg.Text('Click a look and feel color to see demo window')],
- [sg.Listbox(values=sg.list_of_look_and_feel_values(), size=(20,12), key='-LIST-', enable_events=True)],
- [sg.Button('Show Window'), sg.Button('Exit')] ]
-
-window = sg.Window('Look and Feel Browser', layout)
-
-while True: # Event Loop
- event, values = window.read()
- if event in (None, 'Exit'):
- break
- sg.change_look_and_feel(values['-LIST-'][0])
- sg.popup_get_text('This is {}'.format(values['-LIST-'][0]))
-window.close()
diff --git a/DemoPrograms old/Demo_Change_Submits_InputText.py b/DemoPrograms old/Demo_Change_Submits_InputText.py
deleted file mode 100644
index 215b46b2..00000000
--- a/DemoPrograms old/Demo_Change_Submits_InputText.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-"""
- Demonstrates the new change_submits parameter for inputtext elements
- It ONLY submits when a button changes the field, not normal user input
- Be careful on persistent forms to not clear the input
-"""
-layout = [[ sg.Text('Test of reading input field') ],
- [sg.T('This input is normal'), sg.In()],
- [sg.T('This input change submits'), sg.In(change_submits=True)],
- [sg.T('This multiline input change submits'), sg.Multiline(change_submits=True, do_not_clear=True)],
- [sg.T('This input is normal'), sg.In(), sg.FileBrowse()],
- [sg.T('File Browse submits'), sg.In(change_submits=True,
- do_not_clear=True,
- key='_in1_'), sg.FileBrowse()],
- [sg.T('Color Chooser submits'), sg.In(change_submits=True,
- do_not_clear=True,
- key='_in2_'), sg.ColorChooserButton('Color...', target=(sg.ThisRow, -1))],
- [sg.T('Folder Browse submits'), sg.In(change_submits=True,
- do_not_clear=True,
- key='_in3_'), sg.FolderBrowse()],
- [sg.T('Calendar Chooser submits'), sg.In(change_submits=True,
- do_not_clear=True,
- key='_in4_'), sg.CalendarButton('Date...', target=(sg.ThisRow, -1))],
- [sg.T('Disabled input submits'), sg.In(change_submits=True,
- do_not_clear=True,
- disabled=True,
- key='_in5'), sg.FileBrowse()],
- [sg.T('This input clears after submit'),sg.In(change_submits=True,
- key='_in6_'), sg.FileBrowse()],
- [ sg.Button('Read')]]
-
-window = sg.Window('Demonstration of InputText with change_submits',
- auto_size_text=False,
- default_element_size=(22,1),
- text_justification='right',
- ).Layout(layout)
-
-while True: # Event Loop
- event, values = window.Read()
- print(event, values)
- if event is None:
- break
diff --git a/DemoPrograms old/Demo_Chat.py b/DemoPrograms old/Demo_Chat.py
deleted file mode 100644
index c4ab0dd3..00000000
--- a/DemoPrograms old/Demo_Chat.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-'''
-A chat window. Add call to your send-routine, print the response and you're done
-
-To see this program RUN on the web go here:
-https://repl.it/@PySimpleGUI/Chat-Application-Demo
-
-Note that the size of the display on repl.it is smaller than most, so the sizes of the
-Multiline and Output text areas were reduced in the online version. Nothing else was changed
-'''
-
-sg.ChangeLookAndFeel('GreenTan') # give our window a spiffy set of colors
-
-layout = [ [sg.Text('Your output will go here', size=(40, 1))],
- [sg.Output(size=(127, 30), font=('Helvetica 10'))],
- [sg.Multiline(size=(85, 5), enter_submits=True, key='query'),
- sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
- sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]
-
-window = sg.Window('Chat window',
- default_element_size=(30, 2),
- font=('Helvetica',' 13'),
- default_button_element_size=(8,2)).Layout(layout)
-
-# ---===--- Loop taking in user input and using it --- #
-while True:
- event, value = window.Read()
- if event == 'SEND':
- query = value['query'].rstrip()
- # EXECUTE YOUR COMMAND HERE
- print('The command you entered was {}'.format(query))
- elif event in (None, 'EXIT'): # quit if exit button or X
- break
-sys.exit(69)
-
diff --git a/DemoPrograms old/Demo_Chat_With_History.py b/DemoPrograms old/Demo_Chat_With_History.py
deleted file mode 100644
index 1330caa1..00000000
--- a/DemoPrograms old/Demo_Chat_With_History.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-'''
-A chatbot with history
-Scroll up and down through prior commands using the arrow keys
-Special keyboard keys:
- Up arrow - scroll up in commands
- Down arrow - scroll down in commands
- Escape - clear current command
- Control C - exit form
-'''
-
-def ChatBotWithHistory():
- # ------- Make a new Window ------- #
- sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors
-
- layout = [[sg.Text('Your output will go here', size=(40, 1))],
- [sg.Output(size=(127, 30), font=('Helvetica 10'))],
- [sg.T('Command History'), sg.T('', size=(20,3), key='history')],
- [sg.Multiline(size=(85, 5), enter_submits=True, key='query', do_not_clear=False),
- sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
- sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]
-
- window = sg.Window('Chat window with history', default_element_size=(30, 2), font=('Helvetica',' 13'), default_button_element_size=(8,2), return_keyboard_events=True).Layout(layout)
-
- # ---===--- Loop taking in user input and using it --- #
- command_history = []
- history_offset = 0
- while True:
- (event, value) = window.Read()
- if event == 'SEND':
- query = value['query'].rstrip()
- # EXECUTE YOUR COMMAND HERE
- print('The command you entered was {}'.format(query))
- command_history.append(query)
- history_offset = len(command_history)-1
- window.FindElement('query').Update('') # manually clear input because keyboard events blocks clear
- window.FindElement('history').Update('\n'.join(command_history[-3:]))
- elif event in (None, 'EXIT'): # quit if exit event or X
- break
- elif 'Up' in event and len(command_history):
- command = command_history[history_offset]
- history_offset -= 1 * (history_offset > 0) # decrement is not zero
- window.FindElement('query').Update(command)
- elif 'Down' in event and len(command_history):
- history_offset += 1 * (history_offset < len(command_history)-1) # increment up to end of list
- command = command_history[history_offset]
- window.FindElement('query').Update(command)
- elif 'Escape' in event:
- window.FindElement('query').Update('')
-
- sys.exit(69)
-
-
-ChatBotWithHistory()
diff --git a/DemoPrograms old/Demo_Chatterbot.py b/DemoPrograms old/Demo_Chatterbot.py
deleted file mode 100644
index a80d08c3..00000000
--- a/DemoPrograms old/Demo_Chatterbot.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-from chatterbot import ChatBot
-import chatterbot.utils
-
-
-'''
-Demo_Chatterbot.py
-A GUI wrapped arouind the Chatterbot package.
-The GUI is used to show progress bars during the training process and
-to collect user input that is sent to the chatbot. The reply is displayed in the GUI window
-'''
-
-# Create the 'Trainer GUI'
-# The Trainer GUI consists of a lot of progress bars stacked on top of each other
-sg.ChangeLookAndFeel('GreenTan')
-# sg.DebugWin()
-MAX_PROG_BARS = 20 # number of training sessions
-bars = []
-texts = []
-training_layout = [[sg.T('TRAINING PROGRESS', size=(20, 1), font=('Helvetica', 17))], ]
-for i in range(MAX_PROG_BARS):
- bars.append(sg.ProgressBar(100, size=(30, 4)))
- texts.append(sg.T(' ' * 20, size=(20, 1), justification='right'))
- training_layout += [[texts[i], bars[i]],] # add a single row
-
-training_window = sg.Window('Training').Layout(training_layout)
-current_bar = 0
-
-# callback function for training runs
-def print_progress_bar(description, iteration_counter, total_items, progress_bar_length=20):
- global current_bar
- global bars
- global texts
- global training_window
- # update the window and the bars
- button, values = training_window.Read(timeout=0)
- if button is None: # if user closed the window on us, exit
- sys.exit(69)
- if bars[current_bar].UpdateBar(iteration_counter, max=total_items) is False:
- sys.exit(69)
- texts[current_bar].Update(description) # show the training dataset name
- if iteration_counter == total_items:
- current_bar += 1
-
-# redefine the chatbot text based progress bar with a graphical one
-chatterbot.utils.print_progress_bar = print_progress_bar
-
-chatbot = ChatBot('Ron Obvious', trainer='chatterbot.trainers.ChatterBotCorpusTrainer')
-
-# Train based on the english corpus
-chatbot.train("chatterbot.corpus.english")
-
-################# GUI #################
-
-layout = [[sg.Output(size=(80, 20))],
- [sg.Multiline(size=(70, 5), enter_submits=True),
- sg.Button('SEND', bind_return_key=True), sg.Button('EXIT')]]
-
-window = sg.Window('Chat Window', auto_size_text=True, default_element_size=(30, 2)).Layout(layout)
-
-# ---===--- Loop taking in user input and using it to query HowDoI web oracle --- #
-while True:
- event, (value,) = window.Read()
- if event != 'SEND':
- break
- string = value.rstrip()
- print(' '+string)
- # send the user input to chatbot to get a response
- response = chatbot.get_response(value.rstrip())
- print(response)
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Chatterbot_With_TTS.py b/DemoPrograms old/Demo_Chatterbot_With_TTS.py
deleted file mode 100644
index 565c89c1..00000000
--- a/DemoPrograms old/Demo_Chatterbot_With_TTS.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-from chatterbot import ChatBot
-import chatterbot.utils
-
-from gtts import gTTS
-from pygame import mixer
-import time
-import os
-
-'''
-Demo_Chatterbot.py
-A GUI wrapped arouind the Chatterbot package.
-The GUI is used to show progress bars during the training process and
-to collect user input that is sent to the chatbot. The reply is displayed in the GUI window
-'''
-
-# Create the 'Trainer GUI'
-# The Trainer GUI consists of a lot of progress bars stacked on top of each other
-sg.ChangeLookAndFeel('NeutralBlue')
-# sg.DebugWin()
-MAX_PROG_BARS = 20 # number of training sessions
-bars = []
-texts = []
-training_layout = [[sg.T('TRAINING PROGRESS', size=(20, 1), font=('Helvetica', 17))], ]
-for i in range(MAX_PROG_BARS):
- bars.append(sg.ProgressBar(100, size=(30, 4)))
- texts.append(sg.T(' ' * 20, size=(20, 1), justification='right'))
- training_layout += [[texts[i], bars[i]],] # add a single row
-
-training_window = sg.Window('Training').Layout(training_layout)
-current_bar = 0
-
-# callback function for training runs
-def print_progress_bar(description, iteration_counter, total_items, progress_bar_length=20):
- global current_bar
- global bars
- global texts
- global training_window
- # update the window and the bars
- button, values = training_window.Read(timeout=0)
- if button is None: # if user closed the window on us, exit
- sys.exit(69)
- if bars[current_bar].UpdateBar(iteration_counter, max=total_items) is False:
- sys.exit(69)
- texts[current_bar].Update(description) # show the training dataset name
- if iteration_counter == total_items:
- current_bar += 1
-
-def speak(text):
- global i
- tts = gTTS(text=text, lang='en',slow=False)
- tts.save('speech{}.mp3'.format(i%2))
- # playback the speech
- mixer.music.load('speech{}.mp3'.format(i%2))
- mixer.music.play()
- # wait for playback to end
- while mixer.music.get_busy():
- time.sleep(.1)
- mixer.stop()
- i += 1
-
-i = 0
-mixer.init()
-
-# redefine the chatbot text based progress bar with a graphical one
-chatterbot.utils.print_progress_bar = print_progress_bar
-
-chatbot = ChatBot('Ron Obvious', trainer='chatterbot.trainers.ChatterBotCorpusTrainer')
-
-# Train based on the english corpus
-chatbot.train("chatterbot.corpus.english")
-
-################# GUI #################
-
-layout = [[sg.Output(size=(80, 20))],
- [sg.Multiline(size=(70, 5), enter_submits=True),
- sg.Button('SEND', bind_return_key=True), sg.Button('EXIT')]]
-
-window = sg.Window('Chat Window', auto_size_text=True, default_element_size=(30, 2)).Layout(layout)
-
-# ---===--- Loop taking in user input and using it to query HowDoI web oracle --- #
-while True:
- event, (value,) = window.Read()
- if event != 'SEND':
- break
- string = value.rstrip()
- print(' '+string)
- # send the user input to chatbot to get a response
- response = chatbot.get_response(value.rstrip())
- print(response)
- speak(str(response))
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Color.py b/DemoPrograms old/Demo_Color.py
deleted file mode 100644
index ead1245f..00000000
--- a/DemoPrograms old/Demo_Color.py
+++ /dev/null
@@ -1,1728 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-MY_WINDOW_ICON = 'E:\\TheRealMyDocs\\Icons\\The Planets\\jupiter.ico'
-reverse = {}
-colorhex = {}
-
-colors = {
- "abbey" : ( 76, 79, 86),
- "acadia" : ( 27, 20, 4),
- "acapulco" : (124, 176, 161),
- "aero blue" : (201, 255, 229),
- "affair" : (113, 70, 147),
- "akaroa" : (212, 196, 168),
- "alabaster" : (250, 250, 250),
- "albescent white" : (245, 233, 211),
- "algae green" : (147, 223, 184),
- "alice blue" : (240, 248, 255),
- "alizarin crimson" : (227, 38, 54),
- "allports" : ( 0, 118, 163),
- "almond" : (238, 217, 196),
- "almond frost" : (144, 123, 113),
- "alpine" : (175, 143, 44),
- "alto" : (219, 219, 219),
- "aluminium" : (169, 172, 182),
- "amaranth" : (229, 43, 80),
- "amazon" : ( 59, 122, 87),
- "amber" : (255, 191, 0),
- "americano" : (135, 117, 110),
- "amethyst" : (153, 102, 204),
- "amethyst smoke" : (163, 151, 180),
- "amour" : (249, 234, 243),
- "amulet" : (123, 159, 128),
- "anakiwa" : (157, 229, 255),
- "antique brass" : (200, 138, 101),
- "antique bronze" : (112, 74, 7),
- "anzac" : (224, 182, 70),
- "apache" : (223, 190, 111),
- "apple" : ( 79, 168, 61),
- "apple blossom" : (175, 77, 67),
- "apple green" : (226, 243, 236),
- "apricot" : (235, 147, 115),
- "apricot peach" : (251, 206, 177),
- "apricot white" : (255, 254, 236),
- "aqua deep" : ( 1, 75, 67),
- "aqua forest" : ( 95, 167, 119),
- "aqua haze" : (237, 245, 245),
- "aqua island" : (161, 218, 215),
- "aqua spring" : (234, 249, 245),
- "aqua squeeze" : (232, 245, 242),
- "aquamarine" : (127, 255, 212),
- "aquamarine blue" : (113, 217, 226),
- "arapawa" : ( 17, 12, 108),
- "armadillo" : ( 67, 62, 55),
- "arrowtown" : (148, 135, 113),
- "ash" : (198, 195, 181),
- "asparagus" : (123, 160, 91),
- "asphalt" : ( 19, 10, 6),
- "astra" : (250, 234, 185),
- "astral" : ( 50, 125, 160),
- "astronaut" : ( 40, 58, 119),
- "astronaut blue" : ( 1, 62, 98),
- "athens gray" : (238, 240, 243),
- "aths special" : (236, 235, 206),
- "atlantis" : (151, 205, 45),
- "atoll" : ( 10, 111, 117),
- "atomic tangerine" : (255, 153, 102),
- "au chico" : (151, 96, 93),
- "aubergine" : ( 59, 9, 16),
- "australian mint" : (245, 255, 190),
- "avocado" : (136, 141, 101),
- "axolotl" : ( 78, 102, 73),
- "azalea" : (247, 200, 218),
- "aztec" : ( 13, 28, 25),
- "azure" : ( 49, 91, 161),
- "azure radiance" : ( 0, 127, 255),
- "baby blue" : (224, 255, 255),
- "bahama blue" : ( 2, 99, 149),
- "bahia" : (165, 203, 12),
- "baja white" : (255, 248, 209),
- "bali hai" : (133, 159, 175),
- "baltic sea" : ( 42, 38, 48),
- "bamboo" : (218, 99, 4),
- "banana mania" : (251, 231, 178),
- "bandicoot" : (133, 132, 112),
- "barberry" : (222, 215, 23),
- "barley corn" : (166, 139, 91),
- "barley white" : (255, 244, 206),
- "barossa" : ( 68, 1, 45),
- "bastille" : ( 41, 33, 48),
- "battleship gray" : (130, 143, 114),
- "bay leaf" : (125, 169, 141),
- "bay of many" : ( 39, 58, 129),
- "bazaar" : (152, 119, 123),
- "bean " : ( 61, 12, 2),
- "beauty bush" : (238, 193, 190),
- "beaver" : (146, 111, 91),
- "beeswax" : (254, 242, 199),
- "beige" : (245, 245, 220),
- "bermuda" : (125, 216, 198),
- "bermuda gray" : (107, 139, 162),
- "beryl green" : (222, 229, 192),
- "bianca" : (252, 251, 243),
- "big stone" : ( 22, 42, 64),
- "bilbao" : ( 50, 124, 20),
- "biloba flower" : (178, 161, 234),
- "birch" : ( 55, 48, 33),
- "bird flower" : (212, 205, 22),
- "biscay" : ( 27, 49, 98),
- "bismark" : ( 73, 113, 131),
- "bison hide" : (193, 183, 164),
- "bistre" : ( 61, 43, 31),
- "bitter" : (134, 137, 116),
- "bitter lemon" : (202, 224, 13),
- "bittersweet" : (254, 111, 94),
- "bizarre" : (238, 222, 218),
- "black" : ( 0, 0, 0),
- "black bean" : ( 8, 25, 16),
- "black forest" : ( 11, 19, 4),
- "black haze" : (246, 247, 247),
- "black marlin" : ( 62, 44, 28),
- "black olive" : ( 36, 46, 22),
- "black pearl" : ( 4, 19, 34),
- "black rock" : ( 13, 3, 50),
- "black rose" : (103, 3, 45),
- "black russian" : ( 10, 0, 28),
- "black squeeze" : (242, 250, 250),
- "black white" : (255, 254, 246),
- "blackberry" : ( 77, 1, 53),
- "blackcurrant" : ( 50, 41, 58),
- "blaze orange" : (255, 102, 0),
- "bleach white" : (254, 243, 216),
- "bleached cedar" : ( 44, 33, 51),
- "blizzard blue" : (163, 227, 237),
- "blossom" : (220, 180, 188),
- "blue" : ( 0, 0, 255),
- "blue bayoux" : ( 73, 102, 121),
- "blue bell" : (153, 153, 204),
- "blue chalk" : (241, 233, 255),
- "blue charcoal" : ( 1, 13, 26),
- "blue chill" : ( 12, 137, 144),
- "blue diamond" : ( 56, 4, 116),
- "blue dianne" : ( 32, 72, 82),
- "blue gem" : ( 44, 14, 140),
- "blue haze" : (191, 190, 216),
- "blue lagoon" : ( 1, 121, 135),
- "blue marguerite" : (118, 102, 198),
- "blue ribbon" : ( 0, 102, 255),
- "blue romance" : (210, 246, 222),
- "blue smoke" : (116, 136, 129),
- "blue stone" : ( 1, 97, 98),
- "blue violet" : (100, 86, 183),
- "blue whale" : ( 4, 46, 76),
- "blue zodiac" : ( 19, 38, 77),
- "blumine" : ( 24, 88, 122),
- "blush" : (180, 70, 104),
- "blush pink" : (255, 111, 255),
- "bombay" : (175, 177, 184),
- "bon jour" : (229, 224, 225),
- "bondi blue" : ( 0, 149, 182),
- "bone" : (228, 209, 192),
- "bordeaux" : ( 92, 1, 32),
- "bossanova" : ( 78, 42, 90),
- "boston blue" : ( 59, 145, 180),
- "botticelli" : (199, 221, 229),
- "bottle green" : ( 9, 54, 36),
- "boulder" : (122, 122, 122),
- "bouquet" : (174, 128, 158),
- "bourbon" : (186, 111, 30),
- "bracken" : ( 74, 42, 4),
- "brandy" : (222, 193, 150),
- "brandy punch" : (205, 132, 41),
- "brandy rose" : (187, 137, 131),
- "breaker bay" : ( 93, 161, 159),
- "brick red" : (198, 45, 66),
- "bridal heath" : (255, 250, 244),
- "bridesmaid" : (254, 240, 236),
- "bright gray" : ( 60, 65, 81),
- "bright green" : (102, 255, 0),
- "bright red" : (177, 0, 0),
- "bright sun" : (254, 211, 60),
- "bright turquoise" : ( 8, 232, 222),
- "brilliant rose" : (246, 83, 166),
- "brink pink" : (251, 96, 127),
- "bronco" : (171, 161, 150),
- "bronze" : ( 63, 33, 9),
- "bronze olive" : ( 78, 66, 12),
- "bronzetone" : ( 77, 64, 15),
- "broom" : (255, 236, 19),
- "brown" : (150, 75, 0),
- "brown bramble" : ( 89, 40, 4),
- "brown derby" : ( 73, 38, 21),
- "brown pod" : ( 64, 24, 1),
- "brown rust" : (175, 89, 62),
- "brown tumbleweed" : ( 55, 41, 14),
- "bubbles" : (231, 254, 255),
- "buccaneer" : ( 98, 47, 48),
- "bud" : (168, 174, 156),
- "buddha gold" : (193, 160, 4),
- "buff" : (240, 220, 130),
- "bulgarian rose" : ( 72, 6, 7),
- "bull shot" : (134, 77, 30),
- "bunker" : ( 13, 17, 23),
- "bunting" : ( 21, 31, 76),
- "burgundy" : (144, 0, 32),
- "burnham" : ( 0, 46, 32),
- "burning orange" : (255, 112, 52),
- "burning sand" : (217, 147, 118),
- "burnt maroon" : ( 66, 3, 3),
- "burnt orange" : (204, 85, 0),
- "burnt sienna" : (233, 116, 81),
- "burnt umber" : (138, 51, 36),
- "bush" : ( 13, 46, 28),
- "buttercup" : (243, 173, 22),
- "buttered rum" : (161, 117, 13),
- "butterfly bush" : ( 98, 78, 154),
- "buttermilk" : (255, 241, 181),
- "buttery white" : (255, 252, 234),
- "cab sav" : ( 77, 10, 24),
- "cabaret" : (217, 73, 114),
- "cabbage pont" : ( 63, 76, 58),
- "cactus" : ( 88, 113, 86),
- "cadet blue" : (169, 178, 195),
- "cadillac" : (176, 76, 106),
- "cafe royale" : (111, 68, 12),
- "calico" : (224, 192, 149),
- "california" : (254, 157, 4),
- "calypso" : ( 49, 114, 141),
- "camarone" : ( 0, 88, 26),
- "camelot" : (137, 52, 86),
- "cameo" : (217, 185, 155),
- "camouflage" : ( 60, 57, 16),
- "camouflage green" : (120, 134, 107),
- "can can" : (213, 145, 164),
- "canary" : (243, 251, 98),
- "candlelight" : (252, 217, 23),
- "candy corn" : (251, 236, 93),
- "cannon black" : ( 37, 23, 6),
- "cannon pink" : (137, 67, 103),
- "cape cod" : ( 60, 68, 67),
- "cape honey" : (254, 229, 172),
- "cape palliser" : (162, 102, 69),
- "caper" : (220, 237, 180),
- "caramel" : (255, 221, 175),
- "cararra" : (238, 238, 232),
- "cardin green" : ( 1, 54, 28),
- "cardinal" : (196, 30, 58),
- "cardinal pink" : (140, 5, 94),
- "careys pink" : (210, 158, 170),
- "caribbean green" : ( 0, 204, 153),
- "carissma" : (234, 136, 168),
- "carla" : (243, 255, 216),
- "carmine" : (150, 0, 24),
- "carnaby tan" : ( 92, 46, 1),
- "carnation" : (249, 90, 97),
- "carnation pink" : (255, 166, 201),
- "carousel pink" : (249, 224, 237),
- "carrot orange" : (237, 145, 33),
- "casablanca" : (248, 184, 83),
- "casal" : ( 47, 97, 104),
- "cascade" : (139, 169, 165),
- "cashmere" : (230, 190, 165),
- "casper" : (173, 190, 209),
- "castro" : ( 82, 0, 31),
- "catalina blue" : ( 6, 42, 120),
- "catskill white" : (238, 246, 247),
- "cavern pink" : (227, 190, 190),
- "cedar" : ( 62, 28, 20),
- "cedar wood finish" : (113, 26, 0),
- "celadon" : (172, 225, 175),
- "celery" : (184, 194, 93),
- "celeste" : (209, 210, 202),
- "cello" : ( 30, 56, 91),
- "celtic" : ( 22, 50, 34),
- "cement" : (141, 118, 98),
- "ceramic" : (252, 255, 249),
- "cerise" : (218, 50, 135),
- "cerise red" : (222, 49, 99),
- "cerulean" : ( 2, 164, 211),
- "cerulean blue" : ( 42, 82, 190),
- "chablis" : (255, 244, 243),
- "chalet green" : ( 81, 110, 61),
- "chalky" : (238, 215, 148),
- "chambray" : ( 53, 78, 140),
- "chamois" : (237, 220, 177),
- "champagne" : (250, 236, 204),
- "chantilly" : (248, 195, 223),
- "charade" : ( 41, 41, 55),
- "chardon" : (255, 243, 241),
- "chardonnay" : (255, 205, 140),
- "charlotte" : (186, 238, 249),
- "charm" : (212, 116, 148),
- "chartreuse" : (127, 255, 0),
- "chartreuse yellow" : (223, 255, 0),
- "chateau green" : ( 64, 168, 96),
- "chatelle" : (189, 179, 199),
- "chathams blue" : ( 23, 85, 121),
- "chelsea cucumber" : (131, 170, 93),
- "chelsea gem" : (158, 83, 2),
- "chenin" : (223, 205, 111),
- "cherokee" : (252, 218, 152),
- "cherry pie" : ( 42, 3, 89),
- "cherrywood" : (101, 26, 20),
- "cherub" : (248, 217, 233),
- "chestnut" : (185, 78, 72),
- "chestnut rose" : (205, 92, 92),
- "chetwode blue" : (133, 129, 217),
- "chicago" : ( 93, 92, 88),
- "chiffon" : (241, 255, 200),
- "chilean fire" : (247, 119, 3),
- "chilean heath" : (255, 253, 230),
- "china ivory" : (252, 255, 231),
- "chino" : (206, 199, 167),
- "chinook" : (168, 227, 189),
- "chocolate" : ( 55, 2, 2),
- "christalle" : ( 51, 3, 107),
- "christi" : (103, 167, 18),
- "christine" : (231, 115, 10),
- "chrome white" : (232, 241, 212),
- "cinder" : ( 14, 14, 24),
- "cinderella" : (253, 225, 220),
- "cinnabar" : (227, 66, 52),
- "cinnamon" : (123, 63, 0),
- "cioccolato" : ( 85, 40, 12),
- "citrine white" : (250, 247, 214),
- "citron" : (158, 169, 31),
- "citrus" : (161, 197, 10),
- "clairvoyant" : ( 72, 6, 86),
- "clam shell" : (212, 182, 175),
- "claret" : (127, 23, 52),
- "classic rose" : (251, 204, 231),
- "clay ash" : (189, 200, 179),
- "clay creek" : (138, 131, 96),
- "clear day" : (233, 255, 253),
- "clementine" : (233, 110, 0),
- "clinker" : ( 55, 29, 9),
- "cloud" : (199, 196, 191),
- "cloud burst" : ( 32, 46, 84),
- "cloudy" : (172, 165, 159),
- "clover" : ( 56, 73, 16),
- "cobalt" : ( 0, 71, 171),
- "cocoa bean" : ( 72, 28, 28),
- "cocoa brown" : ( 48, 31, 30),
- "coconut cream" : (248, 247, 220),
- "cod gray" : ( 11, 11, 11),
- "coffee" : (112, 101, 85),
- "coffee bean" : ( 42, 20, 14),
- "cognac" : (159, 56, 29),
- "cola" : ( 63, 37, 0),
- "cold purple" : (171, 160, 217),
- "cold turkey" : (206, 186, 186),
- "colonial white" : (255, 237, 188),
- "comet" : ( 92, 93, 117),
- "como" : ( 81, 124, 102),
- "conch" : (201, 217, 210),
- "concord" : (124, 123, 122),
- "concrete" : (242, 242, 242),
- "confetti" : (233, 215, 90),
- "congo brown" : ( 89, 55, 55),
- "congress blue" : ( 2, 71, 142),
- "conifer" : (172, 221, 77),
- "contessa" : (198, 114, 107),
- "copper" : (184, 115, 51),
- "copper canyon" : (126, 58, 21),
- "copper rose" : (153, 102, 102),
- "copper rust" : (148, 71, 71),
- "copperfield" : (218, 138, 103),
- "coral" : (255, 127, 80),
- "coral red" : (255, 64, 64),
- "coral reef" : (199, 188, 162),
- "coral tree" : (168, 107, 107),
- "corduroy" : ( 96, 110, 104),
- "coriander" : (196, 208, 176),
- "cork" : ( 64, 41, 29),
- "corn" : (231, 191, 5),
- "corn field" : (248, 250, 205),
- "corn harvest" : (139, 107, 11),
- "cornflower" : (147, 204, 234),
- "cornflower blue" : (100, 149, 237),
- "cornflower lilac" : (255, 176, 172),
- "corvette" : (250, 211, 162),
- "cosmic" : (118, 57, 93),
- "cosmos" : (255, 216, 217),
- "costa del sol" : ( 97, 93, 48),
- "cotton candy" : (255, 183, 213),
- "cotton seed" : (194, 189, 182),
- "county green" : ( 1, 55, 26),
- "cowboy" : ( 77, 40, 45),
- "crail" : (185, 81, 64),
- "cranberry" : (219, 80, 121),
- "crater brown" : ( 70, 36, 37),
- "cream" : (255, 253, 208),
- "cream brulee" : (255, 229, 160),
- "cream can" : (245, 200, 92),
- "creole" : ( 30, 15, 4),
- "crete" : (115, 120, 41),
- "crimson" : (220, 20, 60),
- "crocodile" : (115, 109, 88),
- "crown of thorns" : (119, 31, 31),
- "crowshead" : ( 28, 18, 8),
- "cruise" : (181, 236, 223),
- "crusoe" : ( 0, 72, 22),
- "crusta" : (253, 123, 51),
- "cumin" : (146, 67, 33),
- "cumulus" : (253, 255, 213),
- "cupid" : (251, 190, 218),
- "curious blue" : ( 37, 150, 209),
- "cutty sark" : ( 80, 118, 114),
- "cyan / aqua" : ( 0, 255, 255),
- "cyprus" : ( 0, 62, 64),
- "daintree" : ( 1, 39, 49),
- "dairy cream" : (249, 228, 188),
- "daisy bush" : ( 79, 35, 152),
- "dallas" : (110, 75, 38),
- "dandelion" : (254, 216, 93),
- "danube" : ( 96, 147, 209),
- "dark blue" : ( 0, 0, 200),
- "dark burgundy" : (119, 15, 5),
- "dark ebony" : ( 60, 32, 5),
- "dark fern" : ( 10, 72, 13),
- "dark tan" : (102, 16, 16),
- "dawn" : (166, 162, 154),
- "dawn pink" : (243, 233, 229),
- "de york" : (122, 196, 136),
- "deco" : (210, 218, 151),
- "deep blue" : ( 34, 8, 120),
- "deep blush" : (228, 118, 152),
- "deep bronze" : ( 74, 48, 4),
- "deep cerulean" : ( 0, 123, 167),
- "deep cove" : ( 5, 16, 64),
- "deep fir" : ( 0, 41, 0),
- "deep forest green" : ( 24, 45, 9),
- "deep koamaru" : ( 27, 18, 123),
- "deep oak" : ( 65, 32, 16),
- "deep sapphire" : ( 8, 37, 103),
- "deep sea" : ( 1, 130, 107),
- "deep sea green" : ( 9, 88, 89),
- "deep teal" : ( 0, 53, 50),
- "del rio" : (176, 154, 149),
- "dell" : ( 57, 100, 19),
- "delta" : (164, 164, 157),
- "deluge" : (117, 99, 168),
- "denim" : ( 21, 96, 189),
- "derby" : (255, 238, 216),
- "desert" : (174, 96, 32),
- "desert sand" : (237, 201, 175),
- "desert storm" : (248, 248, 247),
- "dew" : (234, 255, 254),
- "di serria" : (219, 153, 94),
- "diesel" : ( 19, 0, 0),
- "dingley" : ( 93, 119, 71),
- "disco" : (135, 21, 80),
- "dixie" : (226, 148, 24),
- "dodger blue" : ( 30, 144, 255),
- "dolly" : (249, 255, 139),
- "dolphin" : (100, 96, 119),
- "domino" : (142, 119, 94),
- "don juan" : ( 93, 76, 81),
- "donkey brown" : (166, 146, 121),
- "dorado" : (107, 87, 85),
- "double colonial white" : (238, 227, 173),
- "double pearl lusta" : (252, 244, 208),
- "double spanish white" : (230, 215, 185),
- "dove gray" : (109, 108, 108),
- "downriver" : ( 9, 34, 86),
- "downy" : (111, 208, 197),
- "driftwood" : (175, 135, 81),
- "drover" : (253, 247, 173),
- "dull lavender" : (168, 153, 230),
- "dune" : ( 56, 53, 51),
- "dust storm" : (229, 204, 201),
- "dusty gray" : (168, 152, 155),
- "eagle" : (182, 186, 164),
- "earls green" : (201, 185, 59),
- "early dawn" : (255, 249, 230),
- "east bay" : ( 65, 76, 125),
- "east side" : (172, 145, 206),
- "eastern blue" : ( 30, 154, 176),
- "ebb" : (233, 227, 227),
- "ebony" : ( 12, 11, 29),
- "ebony clay" : ( 38, 40, 59),
- "eclipse" : ( 49, 28, 23),
- "ecru white" : (245, 243, 229),
- "ecstasy" : (250, 120, 20),
- "eden" : ( 16, 88, 82),
- "edgewater" : (200, 227, 215),
- "edward" : (162, 174, 171),
- "egg sour" : (255, 244, 221),
- "egg white" : (255, 239, 193),
- "eggplant" : ( 97, 64, 81),
- "el paso" : ( 30, 23, 8),
- "el salva" : (143, 62, 51),
- "electric lime" : (204, 255, 0),
- "electric violet" : (139, 0, 255),
- "elephant" : ( 18, 52, 71),
- "elf green" : ( 8, 131, 112),
- "elm" : ( 28, 124, 125),
- "emerald" : ( 80, 200, 120),
- "eminence" : (108, 48, 130),
- "emperor" : ( 81, 70, 73),
- "empress" : (129, 115, 119),
- "endeavour" : ( 0, 86, 167),
- "energy yellow" : (248, 221, 92),
- "english holly" : ( 2, 45, 21),
- "english walnut" : ( 62, 43, 35),
- "envy" : (139, 166, 144),
- "equator" : (225, 188, 100),
- "espresso" : ( 97, 39, 24),
- "eternity" : ( 33, 26, 14),
- "eucalyptus" : ( 39, 138, 91),
- "eunry" : (207, 163, 157),
- "evening sea" : ( 2, 78, 70),
- "everglade" : ( 28, 64, 46),
- "faded jade" : ( 66, 121, 119),
- "fair pink" : (255, 239, 236),
- "falcon" : (127, 98, 109),
- "fall green" : (236, 235, 189),
- "falu red" : (128, 24, 24),
- "fantasy" : (250, 243, 240),
- "fedora" : (121, 106, 120),
- "feijoa" : (159, 221, 140),
- "fern" : ( 99, 183, 108),
- "fern frond" : (101, 114, 32),
- "fern green" : ( 79, 121, 66),
- "ferra" : (112, 79, 80),
- "festival" : (251, 233, 108),
- "feta" : (240, 252, 234),
- "fiery orange" : (179, 82, 19),
- "finch" : ( 98, 102, 73),
- "finlandia" : ( 85, 109, 86),
- "finn" : (105, 45, 84),
- "fiord" : ( 64, 81, 105),
- "fire" : (170, 66, 3),
- "fire bush" : (232, 153, 40),
- "firefly" : ( 14, 42, 48),
- "flame pea" : (218, 91, 56),
- "flamenco" : (255, 125, 7),
- "flamingo" : (242, 85, 42),
- "flax" : (238, 220, 130),
- "flax smoke" : (123, 130, 101),
- "flesh" : (255, 203, 164),
- "flint" : (111, 106, 97),
- "flirt" : (162, 0, 109),
- "flush mahogany" : (202, 52, 53),
- "flush orange" : (255, 127, 0),
- "foam" : (216, 252, 250),
- "fog" : (215, 208, 255),
- "foggy gray" : (203, 202, 182),
- "forest green" : ( 34, 139, 34),
- "forget me not" : (255, 241, 238),
- "fountain blue" : ( 86, 180, 190),
- "frangipani" : (255, 222, 179),
- "french gray" : (189, 189, 198),
- "french lilac" : (236, 199, 238),
- "french pass" : (189, 237, 253),
- "french rose" : (246, 74, 138),
- "fresh eggplant" : (153, 0, 102),
- "friar gray" : (128, 126, 121),
- "fringy flower" : (177, 226, 193),
- "froly" : (245, 117, 132),
- "frost" : (237, 245, 221),
- "frosted mint" : (219, 255, 248),
- "frostee" : (228, 246, 231),
- "fruit salad" : ( 79, 157, 93),
- "fuchsia blue" : (122, 88, 193),
- "fuchsia pink" : (193, 84, 193),
- "fuego" : (190, 222, 13),
- "fuel yellow" : (236, 169, 39),
- "fun blue" : ( 25, 89, 168),
- "fun green" : ( 1, 109, 57),
- "fuscous gray" : ( 84, 83, 77),
- "fuzzy wuzzy brown" : (196, 86, 85),
- "gable green" : ( 22, 53, 49),
- "gallery" : (239, 239, 239),
- "galliano" : (220, 178, 12),
- "gamboge" : (228, 155, 15),
- "geebung" : (209, 143, 27),
- "genoa" : ( 21, 115, 107),
- "geraldine" : (251, 137, 137),
- "geyser" : (212, 223, 226),
- "ghost" : (199, 201, 213),
- "gigas" : ( 82, 60, 148),
- "gimblet" : (184, 181, 106),
- "gin" : (232, 242, 235),
- "gin fizz" : (255, 249, 226),
- "givry" : (248, 228, 191),
- "glacier" : (128, 179, 196),
- "glade green" : ( 97, 132, 95),
- "go ben" : (114, 109, 78),
- "goblin" : ( 61, 125, 82),
- "gold" : (255, 215, 0),
- "gold drop" : (241, 130, 0),
- "gold sand" : (230, 190, 138),
- "gold tips" : (222, 186, 19),
- "golden bell" : (226, 137, 19),
- "golden dream" : (240, 213, 45),
- "golden fizz" : (245, 251, 61),
- "golden glow" : (253, 226, 149),
- "golden grass" : (218, 165, 32),
- "golden sand" : (240, 219, 125),
- "golden tainoi" : (255, 204, 92),
- "goldenrod" : (252, 214, 103),
- "gondola" : ( 38, 20, 20),
- "gordons green" : ( 11, 17, 7),
- "gorse" : (255, 241, 79),
- "gossamer" : ( 6, 155, 129),
- "gossip" : (210, 248, 176),
- "gothic" : (109, 146, 161),
- "governor bay" : ( 47, 60, 179),
- "grain brown" : (228, 213, 183),
- "grandis" : (255, 211, 140),
- "granite green" : (141, 137, 116),
- "granny apple" : (213, 246, 227),
- "granny smith" : (132, 160, 160),
- "granny smith apple" : (157, 224, 147),
- "grape" : ( 56, 26, 81),
- "graphite" : ( 37, 22, 7),
- "gravel" : ( 74, 68, 75),
- "gray" : (128, 128, 128),
- "gray asparagus" : ( 70, 89, 69),
- "gray chateau" : (162, 170, 179),
- "gray nickel" : (195, 195, 189),
- "gray nurse" : (231, 236, 230),
- "gray olive" : (169, 164, 145),
- "gray suit" : (193, 190, 205),
- "green" : ( 0, 255, 0),
- "green haze" : ( 1, 163, 104),
- "green house" : ( 36, 80, 15),
- "green kelp" : ( 37, 49, 28),
- "green leaf" : ( 67, 106, 13),
- "green mist" : (203, 211, 176),
- "green pea" : ( 29, 97, 66),
- "green smoke" : (164, 175, 110),
- "green spring" : (184, 193, 177),
- "green vogue" : ( 3, 43, 82),
- "green waterloo" : ( 16, 20, 5),
- "green white" : (232, 235, 224),
- "green yellow" : (173, 255, 47),
- "grenadier" : (213, 70, 0),
- "guardsman red" : (186, 1, 1),
- "gulf blue" : ( 5, 22, 87),
- "gulf stream" : (128, 179, 174),
- "gull gray" : (157, 172, 183),
- "gum leaf" : (182, 211, 191),
- "gumbo" : (124, 161, 166),
- "gun powder" : ( 65, 66, 87),
- "gunsmoke" : (130, 134, 133),
- "gurkha" : (154, 149, 119),
- "hacienda" : (152, 129, 27),
- "hairy heath" : (107, 42, 20),
- "haiti" : ( 27, 16, 53),
- "half baked" : (133, 196, 204),
- "half colonial white" : (253, 246, 211),
- "half dutch white" : (254, 247, 222),
- "half spanish white" : (254, 244, 219),
- "half and half" : (255, 254, 225),
- "hampton" : (229, 216, 175),
- "harlequin" : ( 63, 255, 0),
- "harp" : (230, 242, 234),
- "harvest gold" : (224, 185, 116),
- "havelock blue" : ( 85, 144, 217),
- "hawaiian tan" : (157, 86, 22),
- "hawkes blue" : (212, 226, 252),
- "heath" : ( 84, 16, 18),
- "heather" : (183, 195, 208),
- "heathered gray" : (182, 176, 149),
- "heavy metal" : ( 43, 50, 40),
- "heliotrope" : (223, 115, 255),
- "hemlock" : ( 94, 93, 59),
- "hemp" : (144, 120, 116),
- "hibiscus" : (182, 49, 108),
- "highland" : (111, 142, 99),
- "hillary" : (172, 165, 134),
- "himalaya" : (106, 93, 27),
- "hint of green" : (230, 255, 233),
- "hint of red" : (251, 249, 249),
- "hint of yellow" : (250, 253, 228),
- "hippie blue" : ( 88, 154, 175),
- "hippie green" : ( 83, 130, 75),
- "hippie pink" : (174, 69, 96),
- "hit gray" : (161, 173, 181),
- "hit pink" : (255, 171, 129),
- "hokey pokey" : (200, 165, 40),
- "hoki" : (101, 134, 159),
- "holly" : ( 1, 29, 19),
- "hollywood cerise" : (244, 0, 161),
- "honey flower" : ( 79, 28, 112),
- "honeysuckle" : (237, 252, 132),
- "hopbush" : (208, 109, 161),
- "horizon" : ( 90, 135, 160),
- "horses neck" : ( 96, 73, 19),
- "hot cinnamon" : (210, 105, 30),
- "hot pink" : (255, 105, 180),
- "hot toddy" : (179, 128, 7),
- "humming bird" : (207, 249, 243),
- "hunter green" : ( 22, 29, 16),
- "hurricane" : (135, 124, 123),
- "husk" : (183, 164, 88),
- "ice cold" : (177, 244, 231),
- "iceberg" : (218, 244, 240),
- "illusion" : (246, 164, 201),
- "inch worm" : (176, 227, 19),
- "indian khaki" : (195, 176, 145),
- "indian tan" : ( 77, 30, 1),
- "indigo" : ( 79, 105, 198),
- "indochine" : (194, 107, 3),
- "international klein blue" : ( 0, 47, 167),
- "international orange" : (255, 79, 0),
- "irish coffee" : ( 95, 61, 38),
- "iroko" : ( 67, 49, 32),
- "iron" : (212, 215, 217),
- "ironside gray" : (103, 102, 98),
- "ironstone" : (134, 72, 60),
- "island spice" : (255, 252, 238),
- "ivory" : (255, 255, 240),
- "jacaranda" : ( 46, 3, 41),
- "jacarta" : ( 58, 42, 106),
- "jacko bean" : ( 46, 25, 5),
- "jacksons purple" : ( 32, 32, 141),
- "jade" : ( 0, 168, 107),
- "jaffa" : (239, 134, 63),
- "jagged ice" : (194, 232, 229),
- "jagger" : ( 53, 14, 87),
- "jaguar" : ( 8, 1, 16),
- "jambalaya" : ( 91, 48, 19),
- "janna" : (244, 235, 211),
- "japanese laurel" : ( 10, 105, 6),
- "japanese maple" : (120, 1, 9),
- "japonica" : (216, 124, 99),
- "java" : ( 31, 194, 194),
- "jazzberry jam" : (165, 11, 94),
- "jelly bean" : ( 41, 123, 154),
- "jet stream" : (181, 210, 206),
- "jewel" : ( 18, 107, 64),
- "jon" : ( 59, 31, 31),
- "jonquil" : (238, 255, 154),
- "jordy blue" : (138, 185, 241),
- "judge gray" : ( 84, 67, 51),
- "jumbo" : (124, 123, 130),
- "jungle green" : ( 41, 171, 135),
- "jungle mist" : (180, 207, 211),
- "juniper" : (109, 146, 146),
- "just right" : (236, 205, 185),
- "kabul" : ( 94, 72, 62),
- "kaitoke green" : ( 0, 70, 32),
- "kangaroo" : (198, 200, 189),
- "karaka" : ( 30, 22, 9),
- "karry" : (255, 234, 212),
- "kashmir blue" : ( 80, 112, 150),
- "kelp" : ( 69, 73, 54),
- "kenyan copper" : (124, 28, 5),
- "keppel" : ( 58, 176, 158),
- "key lime pie" : (191, 201, 33),
- "khaki" : (240, 230, 140),
- "kidnapper" : (225, 234, 212),
- "kilamanjaro" : ( 36, 12, 2),
- "killarney" : ( 58, 106, 71),
- "kimberly" : (115, 108, 159),
- "kingfisher daisy" : ( 62, 4, 128),
- "kobi" : (231, 159, 196),
- "kokoda" : (110, 109, 87),
- "korma" : (143, 75, 14),
- "koromiko" : (255, 189, 95),
- "kournikova" : (255, 231, 114),
- "kumera" : (136, 98, 33),
- "la palma" : ( 54, 135, 22),
- "la rioja" : (179, 193, 16),
- "las palmas" : (198, 230, 16),
- "laser" : (200, 181, 104),
- "laser lemon" : (255, 255, 102),
- "laurel" : (116, 147, 120),
- "lavender" : (181, 126, 220),
- "lavender gray" : (189, 187, 215),
- "lavender magenta" : (238, 130, 238),
- "lavender pink" : (251, 174, 210),
- "lavender purple" : (150, 123, 182),
- "lavender rose" : (251, 160, 227),
- "lavender blush" : (255, 240, 245),
- "leather" : (150, 112, 89),
- "lemon" : (253, 233, 16),
- "lemon chiffon" : (255, 250, 205),
- "lemon ginger" : (172, 158, 34),
- "lemon grass" : (155, 158, 143),
- "light apricot" : (253, 213, 177),
- "light orchid" : (226, 156, 210),
- "light wisteria" : (201, 160, 220),
- "lightning yellow" : (252, 192, 30),
- "lilac" : (200, 162, 200),
- "lilac bush" : (152, 116, 211),
- "lily" : (200, 170, 191),
- "lily white" : (231, 248, 255),
- "lima" : (118, 189, 23),
- "lime" : (191, 255, 0),
- "limeade" : (111, 157, 2),
- "limed ash" : (116, 125, 99),
- "limed oak" : (172, 138, 86),
- "limed spruce" : ( 57, 72, 81),
- "linen" : (250, 240, 230),
- "link water" : (217, 228, 245),
- "lipstick" : (171, 5, 99),
- "lisbon brown" : ( 66, 57, 33),
- "livid brown" : ( 77, 40, 46),
- "loafer" : (238, 244, 222),
- "loblolly" : (189, 201, 206),
- "lochinvar" : ( 44, 140, 132),
- "lochmara" : ( 0, 126, 199),
- "locust" : (168, 175, 142),
- "log cabin" : ( 36, 42, 29),
- "logan" : (170, 169, 205),
- "lola" : (223, 207, 219),
- "london hue" : (190, 166, 195),
- "lonestar" : (109, 1, 1),
- "lotus" : (134, 60, 60),
- "loulou" : ( 70, 11, 65),
- "lucky" : (175, 159, 28),
- "lucky point" : ( 26, 26, 104),
- "lunar green" : ( 60, 73, 58),
- "luxor gold" : (167, 136, 44),
- "lynch" : (105, 126, 154),
- "mabel" : (217, 247, 255),
- "macaroni and cheese" : (255, 185, 123),
- "madang" : (183, 240, 190),
- "madison" : ( 9, 37, 93),
- "madras" : ( 63, 48, 2),
- "magenta / fuchsia" : (255, 0, 255),
- "magic mint" : (170, 240, 209),
- "magnolia" : (248, 244, 255),
- "mahogany" : ( 78, 6, 6),
- "mai tai" : (176, 102, 8),
- "maize" : (245, 213, 160),
- "makara" : (137, 125, 109),
- "mako" : ( 68, 73, 84),
- "malachite" : ( 11, 218, 81),
- "malibu" : (125, 200, 247),
- "mallard" : ( 35, 52, 24),
- "malta" : (189, 178, 161),
- "mamba" : (142, 129, 144),
- "manatee" : (141, 144, 161),
- "mandalay" : (173, 120, 27),
- "mandy" : (226, 84, 101),
- "mandys pink" : (242, 195, 178),
- "mango tango" : (231, 114, 0),
- "manhattan" : (245, 201, 153),
- "mantis" : (116, 195, 101),
- "mantle" : (139, 156, 144),
- "manz" : (238, 239, 120),
- "mardi gras" : ( 53, 0, 54),
- "marigold" : (185, 141, 40),
- "marigold yellow" : (251, 232, 112),
- "mariner" : ( 40, 106, 205),
- "maroon" : (128, 0, 0),
- "maroon flush" : (195, 33, 72),
- "maroon oak" : ( 82, 12, 23),
- "marshland" : ( 11, 15, 8),
- "martini" : (175, 160, 158),
- "martinique" : ( 54, 48, 80),
- "marzipan" : (248, 219, 157),
- "masala" : ( 64, 59, 56),
- "matisse" : ( 27, 101, 157),
- "matrix" : (176, 93, 84),
- "matterhorn" : ( 78, 59, 65),
- "mauve" : (224, 176, 255),
- "mauvelous" : (240, 145, 169),
- "maverick" : (216, 194, 213),
- "medium carmine" : (175, 64, 53),
- "medium purple" : (147, 112, 219),
- "medium red violet" : (187, 51, 133),
- "melanie" : (228, 194, 213),
- "melanzane" : ( 48, 5, 41),
- "melon" : (254, 186, 173),
- "melrose" : (199, 193, 255),
- "mercury" : (229, 229, 229),
- "merino" : (246, 240, 230),
- "merlin" : ( 65, 60, 55),
- "merlot" : (131, 25, 35),
- "metallic bronze" : ( 73, 55, 27),
- "metallic copper" : (113, 41, 29),
- "meteor" : (208, 125, 18),
- "meteorite" : ( 60, 31, 118),
- "mexican red" : (167, 37, 37),
- "mid gray" : ( 95, 95, 110),
- "midnight" : ( 1, 22, 53),
- "midnight blue" : ( 0, 51, 102),
- "midnight moss" : ( 4, 16, 4),
- "mikado" : ( 45, 37, 16),
- "milan" : (250, 255, 164),
- "milano red" : (184, 17, 4),
- "milk punch" : (255, 246, 212),
- "millbrook" : ( 89, 68, 51),
- "mimosa" : (248, 253, 211),
- "mindaro" : (227, 249, 136),
- "mine shaft" : ( 50, 50, 50),
- "mineral green" : ( 63, 93, 83),
- "ming" : ( 54, 116, 125),
- "minsk" : ( 63, 48, 127),
- "mint green" : (152, 255, 152),
- "mint julep" : (241, 238, 193),
- "mint tulip" : (196, 244, 235),
- "mirage" : ( 22, 25, 40),
- "mischka" : (209, 210, 221),
- "mist gray" : (196, 196, 188),
- "mobster" : (127, 117, 137),
- "moccaccino" : (110, 29, 20),
- "mocha" : (120, 45, 25),
- "mojo" : (192, 71, 55),
- "mona lisa" : (255, 161, 148),
- "monarch" : (139, 7, 35),
- "mondo" : ( 74, 60, 48),
- "mongoose" : (181, 162, 127),
- "monsoon" : (138, 131, 137),
- "monte carlo" : (131, 208, 198),
- "monza" : (199, 3, 30),
- "moody blue" : (127, 118, 211),
- "moon glow" : (252, 254, 218),
- "moon mist" : (220, 221, 204),
- "moon raker" : (214, 206, 246),
- "morning glory" : (158, 222, 224),
- "morocco brown" : ( 68, 29, 0),
- "mortar" : ( 80, 67, 81),
- "mosque" : ( 3, 106, 110),
- "moss green" : (173, 223, 173),
- "mountain meadow" : ( 26, 179, 133),
- "mountain mist" : (149, 147, 150),
- "mountbatten pink" : (153, 122, 141),
- "muddy waters" : (183, 142, 92),
- "muesli" : (170, 139, 91),
- "mulberry" : (197, 75, 140),
- "mulberry wood" : ( 92, 5, 54),
- "mule fawn" : (140, 71, 47),
- "mulled wine" : ( 78, 69, 98),
- "mustard" : (255, 219, 88),
- "my pink" : (214, 145, 136),
- "my sin" : (255, 179, 31),
- "mystic" : (226, 235, 237),
- "nandor" : ( 75, 93, 82),
- "napa" : (172, 164, 148),
- "narvik" : (237, 249, 241),
- "natural gray" : (139, 134, 128),
- "navajo white" : (255, 222, 173),
- "navy blue" : ( 0, 0, 128),
- "nebula" : (203, 219, 214),
- "negroni" : (255, 226, 197),
- "neon carrot" : (255, 153, 51),
- "nepal" : (142, 171, 193),
- "neptune" : (124, 183, 187),
- "nero" : ( 20, 6, 0),
- "nevada" : (100, 110, 117),
- "new orleans" : (243, 214, 157),
- "new york pink" : (215, 131, 127),
- "niagara" : ( 6, 161, 137),
- "night rider" : ( 31, 18, 15),
- "night shadz" : (170, 55, 90),
- "nile blue" : ( 25, 55, 81),
- "nobel" : (183, 177, 177),
- "nomad" : (186, 177, 162),
- "norway" : (168, 189, 159),
- "nugget" : (197, 153, 34),
- "nutmeg" : (129, 66, 44),
- "nutmeg wood finish" : (104, 54, 0),
- "oasis" : (254, 239, 206),
- "observatory" : ( 2, 134, 111),
- "ocean green" : ( 65, 170, 120),
- "ochre" : (204, 119, 34),
- "off green" : (230, 248, 243),
- "off yellow" : (254, 249, 227),
- "oil" : ( 40, 30, 21),
- "old brick" : (144, 30, 30),
- "old copper" : (114, 74, 47),
- "old gold" : (207, 181, 59),
- "old lace" : (253, 245, 230),
- "old lavender" : (121, 104, 120),
- "old rose" : (192, 128, 129),
- "olive" : (128, 128, 0),
- "olive drab" : (107, 142, 35),
- "olive green" : (181, 179, 92),
- "olive haze" : (139, 132, 112),
- "olivetone" : (113, 110, 16),
- "olivine" : (154, 185, 115),
- "onahau" : (205, 244, 255),
- "onion" : ( 47, 39, 14),
- "opal" : (169, 198, 194),
- "opium" : (142, 111, 112),
- "oracle" : ( 55, 116, 117),
- "orange" : (255, 104, 31),
- "orange peel" : (255, 160, 0),
- "orange roughy" : (196, 87, 25),
- "orange white" : (254, 252, 237),
- "orchid" : (218, 112, 214),
- "orchid white" : (255, 253, 243),
- "oregon" : (155, 71, 3),
- "orient" : ( 1, 94, 133),
- "oriental pink" : (198, 145, 145),
- "orinoco" : (243, 251, 212),
- "oslo gray" : (135, 141, 145),
- "ottoman" : (233, 248, 237),
- "outer space" : ( 45, 56, 58),
- "outrageous orange" : (255, 96, 55),
- "oxford blue" : ( 56, 69, 85),
- "oxley" : (119, 158, 134),
- "oyster bay" : (218, 250, 255),
- "oyster pink" : (233, 206, 205),
- "paarl" : (166, 85, 41),
- "pablo" : (119, 111, 97),
- "pacific blue" : ( 0, 157, 196),
- "pacifika" : (119, 129, 32),
- "paco" : ( 65, 31, 16),
- "padua" : (173, 230, 196),
- "pale canary" : (255, 255, 153),
- "pale leaf" : (192, 211, 185),
- "pale oyster" : (152, 141, 119),
- "pale prim" : (253, 254, 184),
- "pale rose" : (255, 225, 242),
- "pale sky" : (110, 119, 131),
- "pale slate" : (195, 191, 193),
- "palm green" : ( 9, 35, 15),
- "palm leaf" : ( 25, 51, 14),
- "pampas" : (244, 242, 238),
- "panache" : (234, 246, 238),
- "pancho" : (237, 205, 171),
- "papaya whip" : (255, 239, 213),
- "paprika" : (141, 2, 38),
- "paradiso" : ( 49, 125, 130),
- "parchment" : (241, 233, 210),
- "paris daisy" : (255, 244, 110),
- "paris m" : ( 38, 5, 106),
- "paris white" : (202, 220, 212),
- "parsley" : ( 19, 79, 25),
- "pastel green" : (119, 221, 119),
- "pastel pink" : (255, 209, 220),
- "patina" : ( 99, 154, 143),
- "pattens blue" : (222, 245, 255),
- "paua" : ( 38, 3, 104),
- "pavlova" : (215, 196, 152),
- "peach" : (255, 229, 180),
- "peach cream" : (255, 240, 219),
- "peach orange" : (255, 204, 153),
- "peach schnapps" : (255, 220, 214),
- "peach yellow" : (250, 223, 173),
- "peanut" : (120, 47, 22),
- "pear" : (209, 226, 49),
- "pearl bush" : (232, 224, 213),
- "pearl lusta" : (252, 244, 220),
- "peat" : (113, 107, 86),
- "pelorous" : ( 62, 171, 191),
- "peppermint" : (227, 245, 225),
- "perano" : (169, 190, 242),
- "perfume" : (208, 190, 248),
- "periglacial blue" : (225, 230, 214),
- "periwinkle" : (204, 204, 255),
- "periwinkle gray" : (195, 205, 230),
- "persian blue" : ( 28, 57, 187),
- "persian green" : ( 0, 166, 147),
- "persian indigo" : ( 50, 18, 122),
- "persian pink" : (247, 127, 190),
- "persian plum" : (112, 28, 28),
- "persian red" : (204, 51, 51),
- "persian rose" : (254, 40, 162),
- "persimmon" : (255, 107, 83),
- "peru tan" : (127, 58, 2),
- "pesto" : (124, 118, 49),
- "petite orchid" : (219, 150, 144),
- "pewter" : (150, 168, 161),
- "pharlap" : (163, 128, 123),
- "picasso" : (255, 243, 157),
- "pickled bean" : (110, 72, 38),
- "pickled bluewood" : ( 49, 68, 89),
- "picton blue" : ( 69, 177, 232),
- "pig pink" : (253, 215, 228),
- "pigeon post" : (175, 189, 217),
- "pigment indigo" : ( 75, 0, 130),
- "pine cone" : (109, 94, 84),
- "pine glade" : (199, 205, 144),
- "pine green" : ( 1, 121, 111),
- "pine tree" : ( 23, 31, 4),
- "pink" : (255, 192, 203),
- "pink flamingo" : (255, 102, 255),
- "pink flare" : (225, 192, 200),
- "pink lace" : (255, 221, 244),
- "pink lady" : (255, 241, 216),
- "pink salmon" : (255, 145, 164),
- "pink swan" : (190, 181, 183),
- "piper" : (201, 99, 35),
- "pipi" : (254, 244, 204),
- "pippin" : (255, 225, 223),
- "pirate gold" : (186, 127, 3),
- "pistachio" : (157, 194, 9),
- "pixie green" : (192, 216, 182),
- "pizazz" : (255, 144, 0),
- "pizza" : (201, 148, 21),
- "plantation" : ( 39, 80, 75),
- "plum" : (132, 49, 121),
- "pohutukawa" : (143, 2, 28),
- "polar" : (229, 249, 246),
- "polo blue" : (141, 168, 204),
- "pomegranate" : (243, 71, 35),
- "pompadour" : (102, 0, 69),
- "porcelain" : (239, 242, 243),
- "porsche" : (234, 174, 105),
- "port gore" : ( 37, 31, 79),
- "portafino" : (255, 255, 180),
- "portage" : (139, 159, 238),
- "portica" : (249, 230, 99),
- "pot pourri" : (245, 231, 226),
- "potters clay" : (140, 87, 56),
- "powder ash" : (188, 201, 194),
- "powder blue" : (176, 224, 230),
- "prairie sand" : (154, 56, 32),
- "prelude" : (208, 192, 229),
- "prim" : (240, 226, 236),
- "primrose" : (237, 234, 153),
- "provincial pink" : (254, 245, 241),
- "prussian blue" : ( 0, 49, 83),
- "puce" : (204, 136, 153),
- "pueblo" : (125, 44, 20),
- "puerto rico" : ( 63, 193, 170),
- "pumice" : (194, 202, 196),
- "pumpkin" : (255, 117, 24),
- "pumpkin skin" : (177, 97, 11),
- "punch" : (220, 67, 51),
- "punga" : ( 77, 61, 20),
- "purple" : (102, 0, 153),
- "purple heart" : (101, 45, 193),
- "purple mountain's majesty" : (150, 120, 182),
- "purple pizzazz" : (255, 0, 204),
- "putty" : (231, 205, 140),
- "quarter pearl lusta" : (255, 253, 244),
- "quarter spanish white" : (247, 242, 225),
- "quicksand" : (189, 151, 142),
- "quill gray" : (214, 214, 209),
- "quincy" : ( 98, 63, 45),
- "racing green" : ( 12, 25, 17),
- "radical red" : (255, 53, 94),
- "raffia" : (234, 218, 184),
- "rainee" : (185, 200, 172),
- "rajah" : (247, 182, 104),
- "rangitoto" : ( 46, 50, 34),
- "rangoon green" : ( 28, 30, 19),
- "raven" : (114, 123, 137),
- "raw sienna" : (210, 125, 70),
- "raw umber" : (115, 74, 18),
- "razzle dazzle rose" : (255, 51, 204),
- "razzmatazz" : (227, 11, 92),
- "rebel" : ( 60, 18, 6),
- "red" : (255, 0, 0),
- "red beech" : (123, 56, 1),
- "red berry" : (142, 0, 0),
- "red damask" : (218, 106, 65),
- "red devil" : (134, 1, 17),
- "red orange" : (255, 63, 52),
- "red oxide" : (110, 9, 2),
- "red ribbon" : (237, 10, 63),
- "red robin" : (128, 52, 31),
- "red stage" : (208, 95, 4),
- "red violet" : (199, 21, 133),
- "redwood" : ( 93, 30, 15),
- "reef" : (201, 255, 162),
- "reef gold" : (159, 130, 28),
- "regal blue" : ( 1, 63, 106),
- "regent gray" : (134, 148, 159),
- "regent st blue" : (170, 214, 230),
- "remy" : (254, 235, 243),
- "reno sand" : (168, 101, 21),
- "resolution blue" : ( 0, 35, 135),
- "revolver" : ( 44, 22, 50),
- "rhino" : ( 46, 63, 98),
- "rice cake" : (255, 254, 240),
- "rice flower" : (238, 255, 226),
- "rich gold" : (168, 83, 7),
- "rio grande" : (187, 208, 9),
- "ripe lemon" : (244, 216, 28),
- "ripe plum" : ( 65, 0, 86),
- "riptide" : (139, 230, 216),
- "river bed" : ( 67, 76, 89),
- "rob roy" : (234, 198, 116),
- "robin's egg blue" : ( 0, 204, 204),
- "rock" : ( 77, 56, 51),
- "rock blue" : (158, 177, 205),
- "rock spray" : (186, 69, 12),
- "rodeo dust" : (201, 178, 155),
- "rolling stone" : (116, 125, 131),
- "roman" : (222, 99, 96),
- "roman coffee" : (121, 93, 76),
- "romance" : (255, 254, 253),
- "romantic" : (255, 210, 183),
- "ronchi" : (236, 197, 78),
- "roof terracotta" : (166, 47, 32),
- "rope" : (142, 77, 30),
- "rose" : (255, 0, 127),
- "rose bud" : (251, 178, 163),
- "rose bud cherry" : (128, 11, 71),
- "rose fog" : (231, 188, 180),
- "rose white" : (255, 246, 245),
- "rose of sharon" : (191, 85, 0),
- "rosewood" : (101, 0, 11),
- "roti" : (198, 168, 75),
- "rouge" : (162, 59, 108),
- "royal blue" : ( 65, 105, 225),
- "royal heath" : (171, 52, 114),
- "royal purple" : (107, 63, 160),
- "rum" : (121, 105, 137),
- "rum swizzle" : (249, 248, 228),
- "russet" : (128, 70, 27),
- "russett" : (117, 90, 87),
- "rust" : (183, 65, 14),
- "rustic red" : ( 72, 4, 4),
- "rusty nail" : (134, 86, 10),
- "saddle" : ( 76, 48, 36),
- "saddle brown" : ( 88, 52, 1),
- "saffron" : (244, 196, 48),
- "saffron mango" : (249, 191, 88),
- "sage" : (158, 165, 135),
- "sahara" : (183, 162, 20),
- "sahara sand" : (241, 231, 136),
- "sail" : (184, 224, 249),
- "salem" : ( 9, 127, 75),
- "salmon" : (255, 140, 105),
- "salomie" : (254, 219, 141),
- "salt box" : (104, 94, 110),
- "saltpan" : (241, 247, 242),
- "sambuca" : ( 58, 32, 16),
- "san felix" : ( 11, 98, 7),
- "san juan" : ( 48, 75, 106),
- "san marino" : ( 69, 108, 172),
- "sand dune" : (130, 111, 101),
- "sandal" : (170, 141, 111),
- "sandrift" : (171, 145, 122),
- "sandstone" : (121, 109, 98),
- "sandwisp" : (245, 231, 162),
- "sandy beach" : (255, 234, 200),
- "sandy brown" : (244, 164, 96),
- "sangria" : (146, 0, 10),
- "sanguine brown" : (141, 61, 56),
- "santa fe" : (177, 109, 82),
- "santas gray" : (159, 160, 177),
- "sapling" : (222, 212, 164),
- "sapphire" : ( 47, 81, 158),
- "saratoga" : ( 85, 91, 16),
- "satin linen" : (230, 228, 212),
- "sauvignon" : (255, 245, 243),
- "sazerac" : (255, 244, 224),
- "scampi" : (103, 95, 166),
- "scandal" : (207, 250, 244),
- "scarlet" : (255, 36, 0),
- "scarlet gum" : ( 67, 21, 96),
- "scarlett" : (149, 0, 21),
- "scarpa flow" : ( 88, 85, 98),
- "schist" : (169, 180, 151),
- "school bus yellow" : (255, 216, 0),
- "schooner" : (139, 132, 126),
- "science blue" : ( 0, 102, 204),
- "scooter" : ( 46, 191, 212),
- "scorpion" : (105, 95, 98),
- "scotch mist" : (255, 251, 220),
- "screamin' green" : (102, 255, 102),
- "sea buckthorn" : (251, 161, 41),
- "sea green" : ( 46, 139, 87),
- "sea mist" : (197, 219, 202),
- "sea nymph" : (120, 163, 156),
- "sea pink" : (237, 152, 158),
- "seagull" : (128, 204, 234),
- "seance" : (115, 30, 143),
- "seashell" : (241, 241, 241),
- "seashell peach" : (255, 245, 238),
- "seaweed" : ( 27, 47, 17),
- "selago" : (240, 238, 253),
- "selective yellow" : (255, 186, 0),
- "sepia" : (112, 66, 20),
- "sepia black" : ( 43, 2, 2),
- "sepia skin" : (158, 91, 64),
- "serenade" : (255, 244, 232),
- "shadow" : (131, 112, 80),
- "shadow green" : (154, 194, 184),
- "shady lady" : (170, 165, 169),
- "shakespeare" : ( 78, 171, 209),
- "shalimar" : (251, 255, 186),
- "shamrock" : ( 51, 204, 153),
- "shark" : ( 37, 39, 44),
- "sherpa blue" : ( 0, 73, 80),
- "sherwood green" : ( 2, 64, 44),
- "shilo" : (232, 185, 179),
- "shingle fawn" : (107, 78, 49),
- "ship cove" : (120, 139, 186),
- "ship gray" : ( 62, 58, 68),
- "shiraz" : (178, 9, 49),
- "shocking" : (226, 146, 192),
- "shocking pink" : (252, 15, 192),
- "shuttle gray" : ( 95, 102, 114),
- "siam" : (100, 106, 84),
- "sidecar" : (243, 231, 187),
- "silk" : (189, 177, 168),
- "silver" : (192, 192, 192),
- "silver chalice" : (172, 172, 172),
- "silver rust" : (201, 192, 187),
- "silver sand" : (191, 193, 194),
- "silver tree" : (102, 181, 143),
- "sinbad" : (159, 215, 211),
- "siren" : (122, 1, 58),
- "sirocco" : (113, 128, 128),
- "sisal" : (211, 203, 186),
- "skeptic" : (202, 230, 218),
- "sky blue" : (118, 215, 234),
- "slate gray" : (112, 128, 144),
- "smalt" : ( 0, 51, 153),
- "smalt blue" : ( 81, 128, 143),
- "smoky" : ( 96, 91, 115),
- "snow drift" : (247, 250, 247),
- "snow flurry" : (228, 255, 209),
- "snowy mint" : (214, 255, 219),
- "snuff" : (226, 216, 237),
- "soapstone" : (255, 251, 249),
- "soft amber" : (209, 198, 180),
- "soft peach" : (245, 237, 239),
- "solid pink" : (137, 56, 67),
- "solitaire" : (254, 248, 226),
- "solitude" : (234, 246, 255),
- "sorbus" : (253, 124, 7),
- "sorrell brown" : (206, 185, 143),
- "soya bean" : (106, 96, 81),
- "spanish green" : (129, 152, 133),
- "spectra" : ( 47, 90, 87),
- "spice" : (106, 68, 46),
- "spicy mix" : (136, 83, 66),
- "spicy mustard" : (116, 100, 13),
- "spicy pink" : (129, 110, 113),
- "spindle" : (182, 209, 234),
- "spray" : (121, 222, 236),
- "spring green" : ( 0, 255, 127),
- "spring leaves" : ( 87, 131, 99),
- "spring rain" : (172, 203, 177),
- "spring sun" : (246, 255, 220),
- "spring wood" : (248, 246, 241),
- "sprout" : (193, 215, 176),
- "spun pearl" : (170, 171, 183),
- "squirrel" : (143, 129, 118),
- "st tropaz" : ( 45, 86, 155),
- "stack" : (138, 143, 138),
- "star dust" : (159, 159, 156),
- "stark white" : (229, 215, 189),
- "starship" : (236, 242, 69),
- "steel blue" : ( 70, 130, 180),
- "steel gray" : ( 38, 35, 53),
- "stiletto" : (156, 51, 54),
- "stonewall" : (146, 133, 115),
- "storm dust" : (100, 100, 99),
- "storm gray" : (113, 116, 134),
- "stratos" : ( 0, 7, 65),
- "straw" : (212, 191, 141),
- "strikemaster" : (149, 99, 135),
- "stromboli" : ( 50, 93, 82),
- "studio" : (113, 74, 178),
- "submarine" : (186, 199, 201),
- "sugar cane" : (249, 255, 246),
- "sulu" : (193, 240, 124),
- "summer green" : (150, 187, 171),
- "sun" : (251, 172, 19),
- "sundance" : (201, 179, 91),
- "sundown" : (255, 177, 179),
- "sunflower" : (228, 212, 34),
- "sunglo" : (225, 104, 101),
- "sunglow" : (255, 204, 51),
- "sunset orange" : (254, 76, 64),
- "sunshade" : (255, 158, 44),
- "supernova" : (255, 201, 1),
- "surf" : (187, 215, 193),
- "surf crest" : (207, 229, 210),
- "surfie green" : ( 12, 122, 121),
- "sushi" : (135, 171, 57),
- "suva gray" : (136, 131, 135),
- "swamp" : ( 0, 27, 28),
- "swamp green" : (172, 183, 142),
- "swans down" : (220, 240, 234),
- "sweet corn" : (251, 234, 140),
- "sweet pink" : (253, 159, 162),
- "swirl" : (211, 205, 197),
- "swiss coffee" : (221, 214, 213),
- "sycamore" : (144, 141, 57),
- "tabasco" : (160, 39, 18),
- "tacao" : (237, 179, 129),
- "tacha" : (214, 197, 98),
- "tahiti gold" : (233, 124, 7),
- "tahuna sands" : (238, 240, 200),
- "tall poppy" : (179, 45, 41),
- "tallow" : (168, 165, 137),
- "tamarillo" : (153, 22, 19),
- "tamarind" : ( 52, 21, 21),
- "tan" : (210, 180, 140),
- "tan hide" : (250, 157, 90),
- "tana" : (217, 220, 193),
- "tangaroa" : ( 3, 22, 60),
- "tangerine" : (242, 133, 0),
- "tango" : (237, 122, 28),
- "tapa" : (123, 120, 116),
- "tapestry" : (176, 94, 129),
- "tara" : (225, 246, 232),
- "tarawera" : ( 7, 58, 80),
- "tasman" : (207, 220, 207),
- "taupe" : ( 72, 60, 50),
- "taupe gray" : (179, 175, 149),
- "tawny port" : (105, 37, 69),
- "te papa green" : ( 30, 67, 60),
- "tea" : (193, 186, 176),
- "tea green" : (208, 240, 192),
- "teak" : (177, 148, 97),
- "teal" : ( 0, 128, 128),
- "teal blue" : ( 4, 66, 89),
- "temptress" : ( 59, 0, 11),
- "tenn" : (205, 87, 0),
- "tequila" : (255, 230, 199),
- "terracotta" : (226, 114, 91),
- "texas" : (248, 249, 156),
- "texas rose" : (255, 181, 85),
- "thatch" : (182, 157, 152),
- "thatch green" : ( 64, 61, 25),
- "thistle" : (216, 191, 216),
- "thistle green" : (204, 202, 168),
- "thunder" : ( 51, 41, 47),
- "thunderbird" : (192, 43, 24),
- "tia maria" : (193, 68, 14),
- "tiara" : (195, 209, 209),
- "tiber" : ( 6, 53, 55),
- "tickle me pink" : (252, 128, 165),
- "tidal" : (241, 255, 173),
- "tide" : (191, 184, 176),
- "timber green" : ( 22, 50, 44),
- "timberwolf" : (217, 214, 207),
- "titan white" : (240, 238, 255),
- "toast" : (154, 110, 97),
- "tobacco brown" : (113, 93, 71),
- "toledo" : ( 58, 0, 32),
- "tolopea" : ( 27, 2, 69),
- "tom thumb" : ( 63, 88, 59),
- "tonys pink" : (231, 159, 140),
- "topaz" : (124, 119, 138),
- "torch red" : (253, 14, 53),
- "torea bay" : ( 15, 45, 158),
- "tory blue" : ( 20, 80, 170),
- "tosca" : (141, 63, 63),
- "totem pole" : (153, 27, 7),
- "tower gray" : (169, 189, 191),
- "tradewind" : ( 95, 179, 172),
- "tranquil" : (230, 255, 255),
- "travertine" : (255, 253, 232),
- "tree poppy" : (252, 156, 29),
- "treehouse" : ( 59, 40, 32),
- "trendy green" : (124, 136, 26),
- "trendy pink" : (140, 100, 149),
- "trinidad" : (230, 78, 3),
- "tropical blue" : (195, 221, 249),
- "tropical rain forest" : ( 0, 117, 94),
- "trout" : ( 74, 78, 90),
- "true v" : (138, 115, 214),
- "tuatara" : ( 54, 53, 52),
- "tuft bush" : (255, 221, 205),
- "tulip tree" : (234, 179, 59),
- "tumbleweed" : (222, 166, 129),
- "tuna" : ( 53, 53, 66),
- "tundora" : ( 74, 66, 68),
- "turbo" : (250, 230, 0),
- "turkish rose" : (181, 114, 129),
- "turmeric" : (202, 187, 72),
- "turquoise" : ( 48, 213, 200),
- "turquoise blue" : (108, 218, 231),
- "turtle green" : ( 42, 56, 11),
- "tuscany" : (189, 94, 46),
- "tusk" : (238, 243, 195),
- "tussock" : (197, 153, 75),
- "tutu" : (255, 241, 249),
- "twilight" : (228, 207, 222),
- "twilight blue" : (238, 253, 255),
- "twine" : (194, 149, 93),
- "tyrian purple" : (102, 2, 60),
- "ultramarine" : ( 18, 10, 143),
- "valencia" : (216, 68, 55),
- "valentino" : ( 53, 14, 66),
- "valhalla" : ( 43, 25, 79),
- "van cleef" : ( 73, 23, 12),
- "vanilla" : (209, 190, 168),
- "vanilla ice" : (243, 217, 223),
- "varden" : (255, 246, 223),
- "venetian red" : (114, 1, 15),
- "venice blue" : ( 5, 89, 137),
- "venus" : (146, 133, 144),
- "verdigris" : ( 93, 94, 55),
- "verdun green" : ( 73, 84, 0),
- "vermilion" : (255, 77, 0),
- "vesuvius" : (177, 74, 11),
- "victoria" : ( 83, 68, 145),
- "vida loca" : ( 84, 144, 25),
- "viking" : (100, 204, 219),
- "vin rouge" : (152, 61, 97),
- "viola" : (203, 143, 169),
- "violent violet" : ( 41, 12, 94),
- "violet" : ( 36, 10, 64),
- "violet eggplant" : (153, 17, 153),
- "violet red" : (247, 70, 138),
- "viridian" : ( 64, 130, 109),
- "viridian green" : (103, 137, 117),
- "vis vis" : (255, 239, 161),
- "vista blue" : (143, 214, 180),
- "vista white" : (252, 248, 247),
- "vivid tangerine" : (255, 153, 128),
- "vivid violet" : (128, 55, 144),
- "voodoo" : ( 83, 52, 85),
- "vulcan" : ( 16, 18, 29),
- "wafer" : (222, 203, 198),
- "waikawa gray" : ( 90, 110, 156),
- "waiouru" : ( 54, 60, 13),
- "walnut" : (119, 63, 26),
- "wasabi" : (120, 138, 37),
- "water leaf" : (161, 233, 222),
- "watercourse" : ( 5, 111, 87),
- "waterloo " : (123, 124, 148),
- "wattle" : (220, 215, 71),
- "watusi" : (255, 221, 207),
- "wax flower" : (255, 192, 168),
- "we peep" : (247, 219, 230),
- "web orange" : (255, 165, 0),
- "wedgewood" : ( 78, 127, 158),
- "well read" : (180, 51, 50),
- "west coast" : ( 98, 81, 25),
- "west side" : (255, 145, 15),
- "westar" : (220, 217, 210),
- "wewak" : (241, 155, 171),
- "wheat" : (245, 222, 179),
- "wheatfield" : (243, 237, 207),
- "whiskey" : (213, 154, 111),
- "whisper" : (247, 245, 250),
- "white" : (255, 255, 255),
- "white ice" : (221, 249, 241),
- "white lilac" : (248, 247, 252),
- "white linen" : (248, 240, 232),
- "white pointer" : (254, 248, 255),
- "white rock" : (234, 232, 212),
- "wild blue yonder" : (122, 137, 184),
- "wild rice" : (236, 224, 144),
- "wild sand" : (244, 244, 244),
- "wild strawberry" : (255, 51, 153),
- "wild watermelon" : (253, 91, 120),
- "wild willow" : (185, 196, 106),
- "william" : ( 58, 104, 108),
- "willow brook" : (223, 236, 218),
- "willow grove" : (101, 116, 93),
- "windsor" : ( 60, 8, 120),
- "wine berry" : ( 89, 29, 53),
- "winter hazel" : (213, 209, 149),
- "wisp pink" : (254, 244, 248),
- "wisteria" : (151, 113, 181),
- "wistful" : (164, 166, 211),
- "witch haze" : (255, 252, 153),
- "wood bark" : ( 38, 17, 5),
- "woodland" : ( 77, 83, 40),
- "woodrush" : ( 48, 42, 15),
- "woodsmoke" : ( 12, 13, 15),
- "woody brown" : ( 72, 49, 49),
- "xanadu" : (115, 134, 120),
- "yellow" : (255, 255, 0),
- "yellow green" : (197, 225, 122),
- "yellow metal" : (113, 99, 56),
- "yellow orange" : (255, 174, 66),
- "yellow sea" : (254, 169, 4),
- "your pink" : (255, 195, 192),
- "yukon gold" : (123, 102, 8),
- "yuma" : (206, 194, 145),
- "zambezi" : (104, 85, 88),
- "zanah" : (218, 236, 214),
- "zest" : (229, 132, 27),
- "zeus" : ( 41, 35, 25),
- "ziggurat" : (191, 219, 226),
- "zinnwaldite" : (235, 194, 175),
- "zircon" : (244, 248, 255),
- "zombie" : (228, 214, 155),
- "zorba" : (165, 155, 145),
- "zuccini" : ( 4, 64, 34),
- "zumthor" : (237, 246, 255)}
-
-def build_reverse_dict():
- global reverse
- global colorhex
- global colors
- for color in colors:
- rgb = colors[color]
- hex = '#%02X%02X%02X' % (rgb)
- reverse[hex] = color
- colorhex[color] = hex
- return
-
-
-def get_complementary_hex(color):
- # strip the # from the beginning
- color = color[1:]
- # convert the string into hex
- color = int(color, 16)
- # invert the three bytes
- # as good as substracting each of RGB component by 255(FF)
- comp_color = 0xFFFFFF ^ color
- # convert the color back to hex by prefixing a #
- comp_color = "#%06X" % comp_color
- # return the result
- return comp_color
-
-def get_complementary_rgb(red, green, blue):
- color_string = '#%02X%02X%02X' % (red, green, blue)
- # strip the # from the beginning
- color = color_string[1:]
- # convert the string into hex
- color = int(color, 16)
- # invert the three bytes
- # as good as substracting each of RGB component by 255(FF)
- comp_color = 0xFFFFFF ^ color
- # convert the color back to hex by prefixing a #
- comp_color = "#%06X" % comp_color
- # return the result
- return comp_color
-
-def get_name_from_hex(hex):
- global reverse
- global colorhex
- global colors
-
- hex = hex.upper()
- try:
- name = reverse[hex]
- except:
- name = 'No Hex For Name'
- return name
-
-def get_hex_from_name(name):
- global reverse
- global colorhex
- global colors
-
- name = name.lower()
- try:
- hex = colorhex[name]
- except:
- hex = '#000000'
- return hex
-
-def show_all_colors_on_buttons():
- global reverse
- global colorhex
- global colors
- window = sg.Window('Colors on Buttons Demo', default_element_size=(3, 1), location=(0, 0), icon=MY_WINDOW_ICON, font=("Helvetica", 7))
- row = []
- row_len = 20
- for i, c in enumerate(colors):
- hex = get_hex_from_name(c)
- button1 = sg.CButton(button_text=c, button_color=(get_complementary_hex(hex), hex), size=(8, 1))
- button2 = sg.CButton(button_text=c, button_color=(hex, get_complementary_hex(hex)), size=(8, 1))
- row.append(button1)
- row.append(button2)
- if (i+1) % row_len == 0:
- window.AddRow(*row)
- row = []
- if row != []:
- window.AddRow(*row)
- window.Show()
-
-
-GoodColors = [('#0e6251', sg.RGB(255, 246, 122)),
- ('white', sg.RGB(0, 74, 60)),
- (sg.RGB(0, 210, 124), sg.RGB(0, 74, 60)),
- (sg.RGB(0, 210, 87), sg.RGB(0, 74, 60)),
- (sg.RGB(0, 164, 73), sg.RGB(0, 74, 60)),
- (sg.RGB(0, 74, 60), sg.RGB(0, 74, 60)),
- ]
-
-
-def main():
- global colors
- global reverse
-
- build_reverse_dict()
- list_of_colors = [c for c in colors]
- printable = '\n'.join(map(str, list_of_colors))
- # show_all_colors_on_buttons()
- sg.SetOptions(element_padding=(0,0))
- while True:
- # ------- Form show ------- #
- layout = [[sg.Text('Find color')],
- [sg.Text('Demonstration of colors')],
- [sg.Text('Enter a color name in text or hex #RRGGBB format')],
- [sg.InputText(key='hex')],
- [sg.Listbox(list_of_colors, size=(20, 30), bind_return_key=True, key='listbox'), sg.T('Or choose from list')],
- [sg.Submit(), sg.Button('Many buttons', button_color=('white', '#0e6251'), key='Many buttons'), sg.ColorChooserButton( 'Chooser', target=(3,0), key='Chooser'), sg.Quit(),],
- ]
- # [g.Multiline(DefaultText=str(printable), Size=(30,20))]]
- event, values = sg.Window('Color Demo', auto_size_buttons=False).Layout(layout).Read()
-
- # ------- OUTPUT results portion ------- #
- if event == 'Quit' or event is None:
- exit(0)
- elif event == 'Many buttons':
- show_all_colors_on_buttons()
-
- drop_down_value = values['listbox']
- hex_input = values['hex']
- if hex_input == '' and len(drop_down_value) == 0:
- continue
-
- if len(hex_input) != 0:
- if hex_input[0] == '#':
- color_hex = hex_input.upper()
- color_name = get_name_from_hex(hex_input)
- else:
- color_name = hex_input
- color_hex = get_hex_from_name(color_name)
- elif drop_down_value is not None and len(drop_down_value) != 0:
- color_name = drop_down_value[0]
- color_hex = get_hex_from_name(color_name)
-
- complementary_hex = get_complementary_hex(color_hex)
- complementary_color = get_name_from_hex(complementary_hex)
-
- layout = [[sg.Text('That color and it\'s compliment are shown on these buttons. This form auto-closes')],
- [sg.CloseButton(button_text=color_name, button_color=(color_hex, complementary_hex))],
- [sg.CloseButton(button_text=complementary_hex + ' ' + complementary_color, button_color=(complementary_hex , color_hex), size=(30, 1))],
- ]
- sg.Window('Color demo', default_element_size=(100, 1), auto_size_text=True, auto_close=True, auto_close_duration=5, icon=MY_WINDOW_ICON).Layout(layout).Read()
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Color_Names.py b/DemoPrograms old/Demo_Color_Names.py
deleted file mode 100644
index aa080f30..00000000
--- a/DemoPrograms old/Demo_Color_Names.py
+++ /dev/null
@@ -1,709 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-
-"""
-
- Shows a big chart of colors... give it a few seconds to create it
- Once large window is shown, you can click on any color and another window will popup
- showing both white and black text on that color
- Uses TOOLTIPS to show the hex values for the colors. Hover over a color and a tooltip will show you the RGB
- You will find the list of tkinter colors here:
- http://www.tcl.tk/man/tcl8.5/TkCmd/colors.htm
-
-"""
-
-color_map = {
- 'alice blue': '#F0F8FF',
- 'AliceBlue': '#F0F8FF',
- 'antique white': '#FAEBD7',
- 'AntiqueWhite': '#FAEBD7',
- 'AntiqueWhite1': '#FFEFDB',
- 'AntiqueWhite2': '#EEDFCC',
- 'AntiqueWhite3': '#CDC0B0',
- 'AntiqueWhite4': '#8B8378',
- 'aquamarine': '#7FFFD4',
- 'aquamarine1': '#7FFFD4',
- 'aquamarine2': '#76EEC6',
- 'aquamarine3': '#66CDAA',
- 'aquamarine4': '#458B74',
- 'azure': '#F0FFFF',
- 'azure1': '#F0FFFF',
- 'azure2': '#E0EEEE',
- 'azure3': '#C1CDCD',
- 'azure4': '#838B8B',
- 'beige': '#F5F5DC',
- 'bisque': '#FFE4C4',
- 'bisque1': '#FFE4C4',
- 'bisque2': '#EED5B7',
- 'bisque3': '#CDB79E',
- 'bisque4': '#8B7D6B',
- 'black': '#000000',
- 'blanched almond': '#FFEBCD',
- 'BlanchedAlmond': '#FFEBCD',
- 'blue': '#0000FF',
- 'blue violet': '#8A2BE2',
- 'blue1': '#0000FF',
- 'blue2': '#0000EE',
- 'blue3': '#0000CD',
- 'blue4': '#00008B',
- 'BlueViolet': '#8A2BE2',
- 'brown': '#A52A2A',
- 'brown1': '#FF4040',
- 'brown2': '#EE3B3B',
- 'brown3': '#CD3333',
- 'brown4': '#8B2323',
- 'burlywood': '#DEB887',
- 'burlywood1': '#FFD39B',
- 'burlywood2': '#EEC591',
- 'burlywood3': '#CDAA7D',
- 'burlywood4': '#8B7355',
- 'cadet blue': '#5F9EA0',
- 'CadetBlue': '#5F9EA0',
- 'CadetBlue1': '#98F5FF',
- 'CadetBlue2': '#8EE5EE',
- 'CadetBlue3': '#7AC5CD',
- 'CadetBlue4': '#53868B',
- 'chartreuse': '#7FFF00',
- 'chartreuse1': '#7FFF00',
- 'chartreuse2': '#76EE00',
- 'chartreuse3': '#66CD00',
- 'chartreuse4': '#458B00',
- 'chocolate': '#D2691E',
- 'chocolate1': '#FF7F24',
- 'chocolate2': '#EE7621',
- 'chocolate3': '#CD661D',
- 'chocolate4': '#8B4513',
- 'coral': '#FF7F50',
- 'coral1': '#FF7256',
- 'coral2': '#EE6A50',
- 'coral3': '#CD5B45',
- 'coral4': '#8B3E2F',
- 'cornflower blue': '#6495ED',
- 'CornflowerBlue': '#6495ED',
- 'cornsilk': '#FFF8DC',
- 'cornsilk1': '#FFF8DC',
- 'cornsilk2': '#EEE8CD',
- 'cornsilk3': '#CDC8B1',
- 'cornsilk4': '#8B8878',
- 'cyan': '#00FFFF',
- 'cyan1': '#00FFFF',
- 'cyan2': '#00EEEE',
- 'cyan3': '#00CDCD',
- 'cyan4': '#008B8B',
- 'dark blue': '#00008B',
- 'dark cyan': '#008B8B',
- 'dark goldenrod': '#B8860B',
- 'dark gray': '#A9A9A9',
- 'dark green': '#006400',
- 'dark grey': '#A9A9A9',
- 'dark khaki': '#BDB76B',
- 'dark magenta': '#8B008B',
- 'dark olive green': '#556B2F',
- 'dark orange': '#FF8C00',
- 'dark orchid': '#9932CC',
- 'dark red': '#8B0000',
- 'dark salmon': '#E9967A',
- 'dark sea green': '#8FBC8F',
- 'dark slate blue': '#483D8B',
- 'dark slate gray': '#2F4F4F',
- 'dark slate grey': '#2F4F4F',
- 'dark turquoise': '#00CED1',
- 'dark violet': '#9400D3',
- 'DarkBlue': '#00008B',
- 'DarkCyan': '#008B8B',
- 'DarkGoldenrod': '#B8860B',
- 'DarkGoldenrod1': '#FFB90F',
- 'DarkGoldenrod2': '#EEAD0E',
- 'DarkGoldenrod3': '#CD950C',
- 'DarkGoldenrod4': '#8B6508',
- 'DarkGray': '#A9A9A9',
- 'DarkGreen': '#006400',
- 'DarkGrey': '#A9A9A9',
- 'DarkKhaki': '#BDB76B',
- 'DarkMagenta': '#8B008B',
- 'DarkOliveGreen': '#556B2F',
- 'DarkOliveGreen1': '#CAFF70',
- 'DarkOliveGreen2': '#BCEE68',
- 'DarkOliveGreen3': '#A2CD5A',
- 'DarkOliveGreen4': '#6E8B3D',
- 'DarkOrange': '#FF8C00',
- 'DarkOrange1': '#FF7F00',
- 'DarkOrange2': '#EE7600',
- 'DarkOrange3': '#CD6600',
- 'DarkOrange4': '#8B4500',
- 'DarkOrchid': '#9932CC',
- 'DarkOrchid1': '#BF3EFF',
- 'DarkOrchid2': '#B23AEE',
- 'DarkOrchid3': '#9A32CD',
- 'DarkOrchid4': '#68228B',
- 'DarkRed': '#8B0000',
- 'DarkSalmon': '#E9967A',
- 'DarkSeaGreen': '#8FBC8F',
- 'DarkSeaGreen1': '#C1FFC1',
- 'DarkSeaGreen2': '#B4EEB4',
- 'DarkSeaGreen3': '#9BCD9B',
- 'DarkSeaGreen4': '#698B69',
- 'DarkSlateBlue': '#483D8B',
- 'DarkSlateGray': '#2F4F4F',
- 'DarkSlateGray1': '#97FFFF',
- 'DarkSlateGray2': '#8DEEEE',
- 'DarkSlateGray3': '#79CDCD',
- 'DarkSlateGray4': '#528B8B',
- 'DarkSlateGrey': '#2F4F4F',
- 'DarkTurquoise': '#00CED1',
- 'DarkViolet': '#9400D3',
- 'deep pink': '#FF1493',
- 'deep sky blue': '#00BFFF',
- 'DeepPink': '#FF1493',
- 'DeepPink1': '#FF1493',
- 'DeepPink2': '#EE1289',
- 'DeepPink3': '#CD1076',
- 'DeepPink4': '#8B0A50',
- 'DeepSkyBlue': '#00BFFF',
- 'DeepSkyBlue1': '#00BFFF',
- 'DeepSkyBlue2': '#00B2EE',
- 'DeepSkyBlue3': '#009ACD',
- 'DeepSkyBlue4': '#00688B',
- 'dim gray': '#696969',
- 'dim grey': '#696969',
- 'DimGray': '#696969',
- 'DimGrey': '#696969',
- 'dodger blue': '#1E90FF',
- 'DodgerBlue': '#1E90FF',
- 'DodgerBlue1': '#1E90FF',
- 'DodgerBlue2': '#1C86EE',
- 'DodgerBlue3': '#1874CD',
- 'DodgerBlue4': '#104E8B',
- 'firebrick': '#B22222',
- 'firebrick1': '#FF3030',
- 'firebrick2': '#EE2C2C',
- 'firebrick3': '#CD2626',
- 'firebrick4': '#8B1A1A',
- 'floral white': '#FFFAF0',
- 'FloralWhite': '#FFFAF0',
- 'forest green': '#228B22',
- 'ForestGreen': '#228B22',
- 'gainsboro': '#DCDCDC',
- 'ghost white': '#F8F8FF',
- 'GhostWhite': '#F8F8FF',
- 'gold': '#FFD700',
- 'gold1': '#FFD700',
- 'gold2': '#EEC900',
- 'gold3': '#CDAD00',
- 'gold4': '#8B7500',
- 'goldenrod': '#DAA520',
- 'goldenrod1': '#FFC125',
- 'goldenrod2': '#EEB422',
- 'goldenrod3': '#CD9B1D',
- 'goldenrod4': '#8B6914',
- 'green': '#00FF00',
- 'green yellow': '#ADFF2F',
- 'green1': '#00FF00',
- 'green2': '#00EE00',
- 'green3': '#00CD00',
- 'green4': '#008B00',
- 'GreenYellow': '#ADFF2F',
- 'grey': '#BEBEBE',
- 'grey0': '#000000',
- 'grey1': '#030303',
- 'grey2': '#050505',
- 'grey3': '#080808',
- 'grey4': '#0A0A0A',
- 'grey5': '#0D0D0D',
- 'grey6': '#0F0F0F',
- 'grey7': '#121212',
- 'grey8': '#141414',
- 'grey9': '#171717',
- 'grey10': '#1A1A1A',
- 'grey11': '#1C1C1C',
- 'grey12': '#1F1F1F',
- 'grey13': '#212121',
- 'grey14': '#242424',
- 'grey15': '#262626',
- 'grey16': '#292929',
- 'grey17': '#2B2B2B',
- 'grey18': '#2E2E2E',
- 'grey19': '#303030',
- 'grey20': '#333333',
- 'grey21': '#363636',
- 'grey22': '#383838',
- 'grey23': '#3B3B3B',
- 'grey24': '#3D3D3D',
- 'grey25': '#404040',
- 'grey26': '#424242',
- 'grey27': '#454545',
- 'grey28': '#474747',
- 'grey29': '#4A4A4A',
- 'grey30': '#4D4D4D',
- 'grey31': '#4F4F4F',
- 'grey32': '#525252',
- 'grey33': '#545454',
- 'grey34': '#575757',
- 'grey35': '#595959',
- 'grey36': '#5C5C5C',
- 'grey37': '#5E5E5E',
- 'grey38': '#616161',
- 'grey39': '#636363',
- 'grey40': '#666666',
- 'grey41': '#696969',
- 'grey42': '#6B6B6B',
- 'grey43': '#6E6E6E',
- 'grey44': '#707070',
- 'grey45': '#737373',
- 'grey46': '#757575',
- 'grey47': '#787878',
- 'grey48': '#7A7A7A',
- 'grey49': '#7D7D7D',
- 'grey50': '#7F7F7F',
- 'grey51': '#828282',
- 'grey52': '#858585',
- 'grey53': '#878787',
- 'grey54': '#8A8A8A',
- 'grey55': '#8C8C8C',
- 'grey56': '#8F8F8F',
- 'grey57': '#919191',
- 'grey58': '#949494',
- 'grey59': '#969696',
- 'grey60': '#999999',
- 'grey61': '#9C9C9C',
- 'grey62': '#9E9E9E',
- 'grey63': '#A1A1A1',
- 'grey64': '#A3A3A3',
- 'grey65': '#A6A6A6',
- 'grey66': '#A8A8A8',
- 'grey67': '#ABABAB',
- 'grey68': '#ADADAD',
- 'grey69': '#B0B0B0',
- 'grey70': '#B3B3B3',
- 'grey71': '#B5B5B5',
- 'grey72': '#B8B8B8',
- 'grey73': '#BABABA',
- 'grey74': '#BDBDBD',
- 'grey75': '#BFBFBF',
- 'grey76': '#C2C2C2',
- 'grey77': '#C4C4C4',
- 'grey78': '#C7C7C7',
- 'grey79': '#C9C9C9',
- 'grey80': '#CCCCCC',
- 'grey81': '#CFCFCF',
- 'grey82': '#D1D1D1',
- 'grey83': '#D4D4D4',
- 'grey84': '#D6D6D6',
- 'grey85': '#D9D9D9',
- 'grey86': '#DBDBDB',
- 'grey87': '#DEDEDE',
- 'grey88': '#E0E0E0',
- 'grey89': '#E3E3E3',
- 'grey90': '#E5E5E5',
- 'grey91': '#E8E8E8',
- 'grey92': '#EBEBEB',
- 'grey93': '#EDEDED',
- 'grey94': '#F0F0F0',
- 'grey95': '#F2F2F2',
- 'grey96': '#F5F5F5',
- 'grey97': '#F7F7F7',
- 'grey98': '#FAFAFA',
- 'grey99': '#FCFCFC',
- 'grey100': '#FFFFFF',
- 'honeydew': '#F0FFF0',
- 'honeydew1': '#F0FFF0',
- 'honeydew2': '#E0EEE0',
- 'honeydew3': '#C1CDC1',
- 'honeydew4': '#838B83',
- 'hot pink': '#FF69B4',
- 'HotPink': '#FF69B4',
- 'HotPink1': '#FF6EB4',
- 'HotPink2': '#EE6AA7',
- 'HotPink3': '#CD6090',
- 'HotPink4': '#8B3A62',
- 'indian red': '#CD5C5C',
- 'IndianRed': '#CD5C5C',
- 'IndianRed1': '#FF6A6A',
- 'IndianRed2': '#EE6363',
- 'IndianRed3': '#CD5555',
- 'IndianRed4': '#8B3A3A',
- 'ivory': '#FFFFF0',
- 'ivory1': '#FFFFF0',
- 'ivory2': '#EEEEE0',
- 'ivory3': '#CDCDC1',
- 'ivory4': '#8B8B83',
- 'khaki': '#F0E68C',
- 'khaki1': '#FFF68F',
- 'khaki2': '#EEE685',
- 'khaki3': '#CDC673',
- 'khaki4': '#8B864E',
- 'lavender': '#E6E6FA',
- 'lavender blush': '#FFF0F5',
- 'LavenderBlush': '#FFF0F5',
- 'LavenderBlush1': '#FFF0F5',
- 'LavenderBlush2': '#EEE0E5',
- 'LavenderBlush3': '#CDC1C5',
- 'LavenderBlush4': '#8B8386',
- 'lawn green': '#7CFC00',
- 'LawnGreen': '#7CFC00',
- 'lemon chiffon': '#FFFACD',
- 'LemonChiffon': '#FFFACD',
- 'LemonChiffon1': '#FFFACD',
- 'LemonChiffon2': '#EEE9BF',
- 'LemonChiffon3': '#CDC9A5',
- 'LemonChiffon4': '#8B8970',
- 'light blue': '#ADD8E6',
- 'light coral': '#F08080',
- 'light cyan': '#E0FFFF',
- 'light goldenrod': '#EEDD82',
- 'light goldenrod yellow': '#FAFAD2',
- 'light gray': '#D3D3D3',
- 'light green': '#90EE90',
- 'light grey': '#D3D3D3',
- 'light pink': '#FFB6C1',
- 'light salmon': '#FFA07A',
- 'light sea green': '#20B2AA',
- 'light sky blue': '#87CEFA',
- 'light slate blue': '#8470FF',
- 'light slate gray': '#778899',
- 'light slate grey': '#778899',
- 'light steel blue': '#B0C4DE',
- 'light yellow': '#FFFFE0',
- 'LightBlue': '#ADD8E6',
- 'LightBlue1': '#BFEFFF',
- 'LightBlue2': '#B2DFEE',
- 'LightBlue3': '#9AC0CD',
- 'LightBlue4': '#68838B',
- 'LightCoral': '#F08080',
- 'LightCyan': '#E0FFFF',
- 'LightCyan1': '#E0FFFF',
- 'LightCyan2': '#D1EEEE',
- 'LightCyan3': '#B4CDCD',
- 'LightCyan4': '#7A8B8B',
- 'LightGoldenrod': '#EEDD82',
- 'LightGoldenrod1': '#FFEC8B',
- 'LightGoldenrod2': '#EEDC82',
- 'LightGoldenrod3': '#CDBE70',
- 'LightGoldenrod4': '#8B814C',
- 'LightGoldenrodYellow': '#FAFAD2',
- 'LightGray': '#D3D3D3',
- 'LightGreen': '#90EE90',
- 'LightGrey': '#D3D3D3',
- 'LightPink': '#FFB6C1',
- 'LightPink1': '#FFAEB9',
- 'LightPink2': '#EEA2AD',
- 'LightPink3': '#CD8C95',
- 'LightPink4': '#8B5F65',
- 'LightSalmon': '#FFA07A',
- 'LightSalmon1': '#FFA07A',
- 'LightSalmon2': '#EE9572',
- 'LightSalmon3': '#CD8162',
- 'LightSalmon4': '#8B5742',
- 'LightSeaGreen': '#20B2AA',
- 'LightSkyBlue': '#87CEFA',
- 'LightSkyBlue1': '#B0E2FF',
- 'LightSkyBlue2': '#A4D3EE',
- 'LightSkyBlue3': '#8DB6CD',
- 'LightSkyBlue4': '#607B8B',
- 'LightSlateBlue': '#8470FF',
- 'LightSlateGray': '#778899',
- 'LightSlateGrey': '#778899',
- 'LightSteelBlue': '#B0C4DE',
- 'LightSteelBlue1': '#CAE1FF',
- 'LightSteelBlue2': '#BCD2EE',
- 'LightSteelBlue3': '#A2B5CD',
- 'LightSteelBlue4': '#6E7B8B',
- 'LightYellow': '#FFFFE0',
- 'LightYellow1': '#FFFFE0',
- 'LightYellow2': '#EEEED1',
- 'LightYellow3': '#CDCDB4',
- 'LightYellow4': '#8B8B7A',
- 'lime green': '#32CD32',
- 'LimeGreen': '#32CD32',
- 'linen': '#FAF0E6',
- 'magenta': '#FF00FF',
- 'magenta1': '#FF00FF',
- 'magenta2': '#EE00EE',
- 'magenta3': '#CD00CD',
- 'magenta4': '#8B008B',
- 'maroon': '#B03060',
- 'maroon1': '#FF34B3',
- 'maroon2': '#EE30A7',
- 'maroon3': '#CD2990',
- 'maroon4': '#8B1C62',
- 'medium aquamarine': '#66CDAA',
- 'medium blue': '#0000CD',
- 'medium orchid': '#BA55D3',
- 'medium purple': '#9370DB',
- 'medium sea green': '#3CB371',
- 'medium slate blue': '#7B68EE',
- 'medium spring green': '#00FA9A',
- 'medium turquoise': '#48D1CC',
- 'medium violet red': '#C71585',
- 'MediumAquamarine': '#66CDAA',
- 'MediumBlue': '#0000CD',
- 'MediumOrchid': '#BA55D3',
- 'MediumOrchid1': '#E066FF',
- 'MediumOrchid2': '#D15FEE',
- 'MediumOrchid3': '#B452CD',
- 'MediumOrchid4': '#7A378B',
- 'MediumPurple': '#9370DB',
- 'MediumPurple1': '#AB82FF',
- 'MediumPurple2': '#9F79EE',
- 'MediumPurple3': '#8968CD',
- 'MediumPurple4': '#5D478B',
- 'MediumSeaGreen': '#3CB371',
- 'MediumSlateBlue': '#7B68EE',
- 'MediumSpringGreen': '#00FA9A',
- 'MediumTurquoise': '#48D1CC',
- 'MediumVioletRed': '#C71585',
- 'midnight blue': '#191970',
- 'MidnightBlue': '#191970',
- 'mint cream': '#F5FFFA',
- 'MintCream': '#F5FFFA',
- 'misty rose': '#FFE4E1',
- 'MistyRose': '#FFE4E1',
- 'MistyRose1': '#FFE4E1',
- 'MistyRose2': '#EED5D2',
- 'MistyRose3': '#CDB7B5',
- 'MistyRose4': '#8B7D7B',
- 'moccasin': '#FFE4B5',
- 'navajo white': '#FFDEAD',
- 'NavajoWhite': '#FFDEAD',
- 'NavajoWhite1': '#FFDEAD',
- 'NavajoWhite2': '#EECFA1',
- 'NavajoWhite3': '#CDB38B',
- 'NavajoWhite4': '#8B795E',
- 'navy': '#000080',
- 'navy blue': '#000080',
- 'NavyBlue': '#000080',
- 'old lace': '#FDF5E6',
- 'OldLace': '#FDF5E6',
- 'olive drab': '#6B8E23',
- 'OliveDrab': '#6B8E23',
- 'OliveDrab1': '#C0FF3E',
- 'OliveDrab2': '#B3EE3A',
- 'OliveDrab3': '#9ACD32',
- 'OliveDrab4': '#698B22',
- 'orange': '#FFA500',
- 'orange red': '#FF4500',
- 'orange1': '#FFA500',
- 'orange2': '#EE9A00',
- 'orange3': '#CD8500',
- 'orange4': '#8B5A00',
- 'OrangeRed': '#FF4500',
- 'OrangeRed1': '#FF4500',
- 'OrangeRed2': '#EE4000',
- 'OrangeRed3': '#CD3700',
- 'OrangeRed4': '#8B2500',
- 'orchid': '#DA70D6',
- 'orchid1': '#FF83FA',
- 'orchid2': '#EE7AE9',
- 'orchid3': '#CD69C9',
- 'orchid4': '#8B4789',
- 'pale goldenrod': '#EEE8AA',
- 'pale green': '#98FB98',
- 'pale turquoise': '#AFEEEE',
- 'pale violet red': '#DB7093',
- 'PaleGoldenrod': '#EEE8AA',
- 'PaleGreen': '#98FB98',
- 'PaleGreen1': '#9AFF9A',
- 'PaleGreen2': '#90EE90',
- 'PaleGreen3': '#7CCD7C',
- 'PaleGreen4': '#548B54',
- 'PaleTurquoise': '#AFEEEE',
- 'PaleTurquoise1': '#BBFFFF',
- 'PaleTurquoise2': '#AEEEEE',
- 'PaleTurquoise3': '#96CDCD',
- 'PaleTurquoise4': '#668B8B',
- 'PaleVioletRed': '#DB7093',
- 'PaleVioletRed1': '#FF82AB',
- 'PaleVioletRed2': '#EE799F',
- 'PaleVioletRed3': '#CD687F',
- 'PaleVioletRed4': '#8B475D',
- 'papaya whip': '#FFEFD5',
- 'PapayaWhip': '#FFEFD5',
- 'peach puff': '#FFDAB9',
- 'PeachPuff': '#FFDAB9',
- 'PeachPuff1': '#FFDAB9',
- 'PeachPuff2': '#EECBAD',
- 'PeachPuff3': '#CDAF95',
- 'PeachPuff4': '#8B7765',
- 'peru': '#CD853F',
- 'pink': '#FFC0CB',
- 'pink1': '#FFB5C5',
- 'pink2': '#EEA9B8',
- 'pink3': '#CD919E',
- 'pink4': '#8B636C',
- 'plum': '#DDA0DD',
- 'plum1': '#FFBBFF',
- 'plum2': '#EEAEEE',
- 'plum3': '#CD96CD',
- 'plum4': '#8B668B',
- 'powder blue': '#B0E0E6',
- 'PowderBlue': '#B0E0E6',
- 'purple': '#A020F0',
- 'purple1': '#9B30FF',
- 'purple2': '#912CEE',
- 'purple3': '#7D26CD',
- 'purple4': '#551A8B',
- 'red': '#FF0000',
- 'red1': '#FF0000',
- 'red2': '#EE0000',
- 'red3': '#CD0000',
- 'red4': '#8B0000',
- 'rosy brown': '#BC8F8F',
- 'RosyBrown': '#BC8F8F',
- 'RosyBrown1': '#FFC1C1',
- 'RosyBrown2': '#EEB4B4',
- 'RosyBrown3': '#CD9B9B',
- 'RosyBrown4': '#8B6969',
- 'royal blue': '#4169E1',
- 'RoyalBlue': '#4169E1',
- 'RoyalBlue1': '#4876FF',
- 'RoyalBlue2': '#436EEE',
- 'RoyalBlue3': '#3A5FCD',
- 'RoyalBlue4': '#27408B',
- 'saddle brown': '#8B4513',
- 'SaddleBrown': '#8B4513',
- 'salmon': '#FA8072',
- 'salmon1': '#FF8C69',
- 'salmon2': '#EE8262',
- 'salmon3': '#CD7054',
- 'salmon4': '#8B4C39',
- 'sandy brown': '#F4A460',
- 'SandyBrown': '#F4A460',
- 'sea green': '#2E8B57',
- 'SeaGreen': '#2E8B57',
- 'SeaGreen1': '#54FF9F',
- 'SeaGreen2': '#4EEE94',
- 'SeaGreen3': '#43CD80',
- 'SeaGreen4': '#2E8B57',
- 'seashell': '#FFF5EE',
- 'seashell1': '#FFF5EE',
- 'seashell2': '#EEE5DE',
- 'seashell3': '#CDC5BF',
- 'seashell4': '#8B8682',
- 'sienna': '#A0522D',
- 'sienna1': '#FF8247',
- 'sienna2': '#EE7942',
- 'sienna3': '#CD6839',
- 'sienna4': '#8B4726',
- 'sky blue': '#87CEEB',
- 'SkyBlue': '#87CEEB',
- 'SkyBlue1': '#87CEFF',
- 'SkyBlue2': '#7EC0EE',
- 'SkyBlue3': '#6CA6CD',
- 'SkyBlue4': '#4A708B',
- 'slate blue': '#6A5ACD',
- 'slate gray': '#708090',
- 'slate grey': '#708090',
- 'SlateBlue': '#6A5ACD',
- 'SlateBlue1': '#836FFF',
- 'SlateBlue2': '#7A67EE',
- 'SlateBlue3': '#6959CD',
- 'SlateBlue4': '#473C8B',
- 'SlateGray': '#708090',
- 'SlateGray1': '#C6E2FF',
- 'SlateGray2': '#B9D3EE',
- 'SlateGray3': '#9FB6CD',
- 'SlateGray4': '#6C7B8B',
- 'SlateGrey': '#708090',
- 'snow': '#FFFAFA',
- 'snow1': '#FFFAFA',
- 'snow2': '#EEE9E9',
- 'snow3': '#CDC9C9',
- 'snow4': '#8B8989',
- 'spring green': '#00FF7F',
- 'SpringGreen': '#00FF7F',
- 'SpringGreen1': '#00FF7F',
- 'SpringGreen2': '#00EE76',
- 'SpringGreen3': '#00CD66',
- 'SpringGreen4': '#008B45',
- 'steel blue': '#4682B4',
- 'SteelBlue': '#4682B4',
- 'SteelBlue1': '#63B8FF',
- 'SteelBlue2': '#5CACEE',
- 'SteelBlue3': '#4F94CD',
- 'SteelBlue4': '#36648B',
- 'tan': '#D2B48C',
- 'tan1': '#FFA54F',
- 'tan2': '#EE9A49',
- 'tan3': '#CD853F',
- 'tan4': '#8B5A2B',
- 'thistle': '#D8BFD8',
- 'thistle1': '#FFE1FF',
- 'thistle2': '#EED2EE',
- 'thistle3': '#CDB5CD',
- 'thistle4': '#8B7B8B',
- 'tomato': '#FF6347',
- 'tomato1': '#FF6347',
- 'tomato2': '#EE5C42',
- 'tomato3': '#CD4F39',
- 'tomato4': '#8B3626',
- 'turquoise': '#40E0D0',
- 'turquoise1': '#00F5FF',
- 'turquoise2': '#00E5EE',
- 'turquoise3': '#00C5CD',
- 'turquoise4': '#00868B',
- 'violet': '#EE82EE',
- 'violet red': '#D02090',
- 'VioletRed': '#D02090',
- 'VioletRed1': '#FF3E96',
- 'VioletRed2': '#EE3A8C',
- 'VioletRed3': '#CD3278',
- 'VioletRed4': '#8B2252',
- 'wheat': '#F5DEB3',
- 'wheat1': '#FFE7BA',
- 'wheat2': '#EED8AE',
- 'wheat3': '#CDBA96',
- 'wheat4': '#8B7E66',
- 'white': '#FFFFFF',
- 'white smoke': '#F5F5F5',
- 'WhiteSmoke': '#F5F5F5',
- 'yellow': '#FFFF00',
- 'yellow green': '#9ACD32',
- 'yellow1': '#FFFF00',
- 'yellow2': '#EEEE00',
- 'yellow3': '#CDCD00',
- 'yellow4': '#8B8B00',
- 'YellowGreen': '#9ACD32',
-}
-
-
-sg.SetOptions(button_element_size=(12,1), element_padding=(0,0), auto_size_buttons=False, border_width=1, tooltip_time=100)
-
-#start layout with the tittle
-layout = [[sg.Text('Hover mouse to see RGB value, click for white & black text',
- text_color='blue',
- font='Any 15',
- relief=sg.RELIEF_SUNKEN,
- justification='center',
- size=(100,1),
- background_color='light green',
- pad=(0,(0,20))),]]
-
-# -- Create primary color viewer window --
-color_list = [key for key in color_map]
-for rows in range(40):
-
- row = []
- for i in range(12):
- try:
- color = color_list[rows+40*i]
- row.append(sg.Button(color, button_color=('black', color), key=color, tooltip=color_map[color]))
- except:
- pass
- layout.append(row)
-
-
-window = sg.Window('Color Viewer', grab_anywhere=False, font=('any 9')).Layout(layout)
-
-# -- Event loop --
-while True:
- event, values = window.Read()
- if event is None:
- break
- # -- Create a secondary window that shows white and black text on chosen color
- layout2 =[[sg.DummyButton(event, button_color=('white', event), tooltip=color_map[event]), sg.DummyButton(event, button_color=('black', event), tooltip=color_map[event])] ]
- sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read(timeout=0)
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Color_Names_Smaller_List.py b/DemoPrograms old/Demo_Color_Names_Smaller_List.py
deleted file mode 100644
index e6911dcd..00000000
--- a/DemoPrograms old/Demo_Color_Names_Smaller_List.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-"""
- Color names courtesy of Big Daddy's Wiki-Python
- http://www.wikipython.com/tkinter-ttk-tix/summary-information/colors/
-
- Shows a big chart of colors... give it a few seconds to create it
- Once large window is shown, you can click on any color and another window will popup
- showing both white and black text on that color
-"""
-
-
-
-COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'old lace',
- 'linen', 'antique white', 'papaya whip', 'blanched almond', 'bisque', 'peach puff',
- 'navajo white', 'lemon chiffon', 'mint cream', 'azure', 'alice blue', 'lavender',
- 'lavender blush', 'misty rose', 'dark slate gray', 'dim gray', 'slate gray',
- 'light slate gray', 'gray', 'light gray', 'midnight blue', 'navy', 'cornflower blue', 'dark slate blue',
- 'slate blue', 'medium slate blue', 'light slate blue', 'medium blue', 'royal blue', 'blue',
- 'dodger blue', 'deep sky blue', 'sky blue', 'light sky blue', 'steel blue', 'light steel blue',
- 'light blue', 'powder blue', 'pale turquoise', 'dark turquoise', 'medium turquoise', 'turquoise',
- 'cyan', 'light cyan', 'cadet blue', 'medium aquamarine', 'aquamarine', 'dark green', 'dark olive green',
- 'dark sea green', 'sea green', 'medium sea green', 'light sea green', 'pale green', 'spring green',
- 'lawn green', 'medium spring green', 'green yellow', 'lime green', 'yellow green',
- 'forest green', 'olive drab', 'dark khaki', 'khaki', 'pale goldenrod', 'light goldenrod yellow',
- 'light yellow', 'yellow', 'gold', 'light goldenrod', 'goldenrod', 'dark goldenrod', 'rosy brown',
- 'indian red', 'saddle brown', 'sandy brown',
- 'dark salmon', 'salmon', 'light salmon', 'orange', 'dark orange',
- 'coral', 'light coral', 'tomato', 'orange red', 'red', 'hot pink', 'deep pink', 'pink', 'light pink',
- 'pale violet red', 'maroon', 'medium violet red', 'violet red',
- 'medium orchid', 'dark orchid', 'dark violet', 'blue violet', 'purple', 'medium purple',
- 'thistle', 'snow2', 'snow3',
- 'snow4', 'seashell2', 'seashell3', 'seashell4', 'AntiqueWhite1', 'AntiqueWhite2',
- 'AntiqueWhite3', 'AntiqueWhite4', 'bisque2', 'bisque3', 'bisque4', 'PeachPuff2',
- 'PeachPuff3', 'PeachPuff4', 'NavajoWhite2', 'NavajoWhite3', 'NavajoWhite4',
- 'LemonChiffon2', 'LemonChiffon3', 'LemonChiffon4', 'cornsilk2', 'cornsilk3',
- 'cornsilk4', 'ivory2', 'ivory3', 'ivory4', 'honeydew2', 'honeydew3', 'honeydew4',
- 'LavenderBlush2', 'LavenderBlush3', 'LavenderBlush4', 'MistyRose2', 'MistyRose3',
- 'MistyRose4', 'azure2', 'azure3', 'azure4', 'SlateBlue1', 'SlateBlue2', 'SlateBlue3',
- 'SlateBlue4', 'RoyalBlue1', 'RoyalBlue2', 'RoyalBlue3', 'RoyalBlue4', 'blue2', 'blue4',
- 'DodgerBlue2', 'DodgerBlue3', 'DodgerBlue4', 'SteelBlue1', 'SteelBlue2',
- 'SteelBlue3', 'SteelBlue4', 'DeepSkyBlue2', 'DeepSkyBlue3', 'DeepSkyBlue4',
- 'SkyBlue1', 'SkyBlue2', 'SkyBlue3', 'SkyBlue4', 'LightSkyBlue1', 'LightSkyBlue2',
- 'LightSkyBlue3', 'LightSkyBlue4', 'Slategray1', 'Slategray2', 'Slategray3',
- 'Slategray4', 'LightSteelBlue1', 'LightSteelBlue2', 'LightSteelBlue3',
- 'LightSteelBlue4', 'LightBlue1', 'LightBlue2', 'LightBlue3', 'LightBlue4',
- 'LightCyan2', 'LightCyan3', 'LightCyan4', 'PaleTurquoise1', 'PaleTurquoise2',
- 'PaleTurquoise3', 'PaleTurquoise4', 'CadetBlue1', 'CadetBlue2', 'CadetBlue3',
- 'CadetBlue4', 'turquoise1', 'turquoise2', 'turquoise3', 'turquoise4', 'cyan2', 'cyan3',
- 'cyan4', 'DarkSlategray1', 'DarkSlategray2', 'DarkSlategray3', 'DarkSlategray4',
- 'aquamarine2', 'aquamarine4', 'DarkSeaGreen1', 'DarkSeaGreen2', 'DarkSeaGreen3',
- 'DarkSeaGreen4', 'SeaGreen1', 'SeaGreen2', 'SeaGreen3', 'PaleGreen1', 'PaleGreen2',
- 'PaleGreen3', 'PaleGreen4', 'SpringGreen2', 'SpringGreen3', 'SpringGreen4',
- 'green2', 'green3', 'green4', 'chartreuse2', 'chartreuse3', 'chartreuse4',
- 'OliveDrab1', 'OliveDrab2', 'OliveDrab4', 'DarkOliveGreen1', 'DarkOliveGreen2',
- 'DarkOliveGreen3', 'DarkOliveGreen4', 'khaki1', 'khaki2', 'khaki3', 'khaki4',
- 'LightGoldenrod1', 'LightGoldenrod2', 'LightGoldenrod3', 'LightGoldenrod4',
- 'LightYellow2', 'LightYellow3', 'LightYellow4', 'yellow2', 'yellow3', 'yellow4',
- 'gold2', 'gold3', 'gold4', 'goldenrod1', 'goldenrod2', 'goldenrod3', 'goldenrod4',
- 'DarkGoldenrod1', 'DarkGoldenrod2', 'DarkGoldenrod3', 'DarkGoldenrod4',
- 'RosyBrown1', 'RosyBrown2', 'RosyBrown3', 'RosyBrown4', 'IndianRed1', 'IndianRed2',
- 'IndianRed3', 'IndianRed4', 'sienna1', 'sienna2', 'sienna3', 'sienna4', 'burlywood1',
- 'burlywood2', 'burlywood3', 'burlywood4', 'wheat1', 'wheat2', 'wheat3', 'wheat4', 'tan1',
- 'tan2', 'tan4', 'chocolate1', 'chocolate2', 'chocolate3', 'firebrick1', 'firebrick2',
- 'firebrick3', 'firebrick4', 'brown1', 'brown2', 'brown3', 'brown4', 'salmon1', 'salmon2',
- 'salmon3', 'salmon4', 'LightSalmon2', 'LightSalmon3', 'LightSalmon4', 'orange2',
- 'orange3', 'orange4', 'DarkOrange1', 'DarkOrange2', 'DarkOrange3', 'DarkOrange4',
- 'coral1', 'coral2', 'coral3', 'coral4', 'tomato2', 'tomato3', 'tomato4', 'OrangeRed2',
- 'OrangeRed3', 'OrangeRed4', 'red2', 'red3', 'red4', 'DeepPink2', 'DeepPink3', 'DeepPink4',
- 'HotPink1', 'HotPink2', 'HotPink3', 'HotPink4', 'pink1', 'pink2', 'pink3', 'pink4',
- 'LightPink1', 'LightPink2', 'LightPink3', 'LightPink4', 'PaleVioletRed1',
- 'PaleVioletRed2', 'PaleVioletRed3', 'PaleVioletRed4', 'maroon1', 'maroon2',
- 'maroon3', 'maroon4', 'VioletRed1', 'VioletRed2', 'VioletRed3', 'VioletRed4',
- 'magenta2', 'magenta3', 'magenta4', 'orchid1', 'orchid2', 'orchid3', 'orchid4', 'plum1',
- 'plum2', 'plum3', 'plum4', 'MediumOrchid1', 'MediumOrchid2', 'MediumOrchid3',
- 'MediumOrchid4', 'DarkOrchid1', 'DarkOrchid2', 'DarkOrchid3', 'DarkOrchid4',
- 'purple1', 'purple2', 'purple3', 'purple4', 'MediumPurple1', 'MediumPurple2',
- 'MediumPurple3', 'MediumPurple4', 'thistle1', 'thistle2', 'thistle3', 'thistle4',
- 'grey1', 'grey2', 'grey3', 'grey4', 'grey5', 'grey6', 'grey7', 'grey8', 'grey9', 'grey10',
- 'grey11', 'grey12', 'grey13', 'grey14', 'grey15', 'grey16', 'grey17', 'grey18', 'grey19',
- 'grey20', 'grey21', 'grey22', 'grey23', 'grey24', 'grey25', 'grey26', 'grey27', 'grey28',
- 'grey29', 'grey30', 'grey31', 'grey32', 'grey33', 'grey34', 'grey35', 'grey36', 'grey37',
- 'grey38', 'grey39', 'grey40', 'grey42', 'grey43', 'grey44', 'grey45', 'grey46', 'grey47',
- 'grey48', 'grey49', 'grey50', 'grey51', 'grey52', 'grey53', 'grey54', 'grey55', 'grey56',
- 'grey57', 'grey58', 'grey59', 'grey60', 'grey61', 'grey62', 'grey63', 'grey64', 'grey65',
- 'grey66', 'grey67', 'grey68', 'grey69', 'grey70', 'grey71', 'grey72', 'grey73', 'grey74',
- 'grey75', 'grey76', 'grey77', 'grey78', 'grey79', 'grey80', 'grey81', 'grey82', 'grey83',
- 'grey84', 'grey85', 'grey86', 'grey87', 'grey88', 'grey89', 'grey90', 'grey91', 'grey92',
- 'grey93', 'grey94', 'grey95', 'grey97', 'grey98', 'grey99']
-
-
-
-
-sg.SetOptions(button_element_size=(12,1), element_padding=(0,0), auto_size_buttons=False, border_width=0)
-
-layout = [[sg.Text('Click on a color square to see both white and black text on that color', text_color='blue', font='Any 15')]]
-row = []
-layout = []
-# -- Create primary color viewer window --
-for rows in range(40):
-
- row = []
- for i in range(12):
- try:
- color = COLORS[rows+40*i]
- row.append(sg.Button(color, button_color=('black', color), key=color))
- except:
- pass
- layout.append(row)
-
-
-# for i, color in enumerate(COLORS):
-# row.append(sg.Button(color, button_color=('black', color), key=color))
-# if (i+1) % 12 == 0:
-# layout.append(row)
-# row = []
-
-window = sg.Window('Color Viewer', grab_anywhere=False, font=('any 9')).Layout(layout)
-
-# -- Event loop --
-while True:
- event, values = window.Read()
- if event is None:
- break
- # -- Create a secondary window that shows white and black text on chosen color
- layout2 =[[sg.DummyButton(event, button_color=('white', event)), sg.DummyButton(event, button_color=('black', event))]]
- sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read(timeout=0)
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Column_And_Frames.py b/DemoPrograms old/Demo_Column_And_Frames.py
deleted file mode 100644
index 2c6f64ea..00000000
--- a/DemoPrograms old/Demo_Column_And_Frames.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import PySimpleGUI as sg
-# this one long import has the effect of making the code more compact as there is no 'sg.' prefix required for Elements
-from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, Check, Button, B, Btn, ButtonMenu, Canvas, Column, Col, Combo, Frame, Graph, Image, InputText, Input, In, Listbox, LBox, Menu, Multiline, ML, MLine, OptionMenu, Output, Pane, ProgressBar, Radio, Slider, Spin, StatusBar, Tab, TabGroup, Table, Text, Txt, T, Tree, TreeData, VerticalSeparator, Window, Sizer
-
-"""
- Demo Columns and Frames
- Demonstrates using mixture of Column and Frame elements to create a nice window layout.
- A couple of the concepts shown here include:
- * Using Columns and Frames with specific sizes on them
- * Importing all required classes so that "sg." is not required on any objects. This makes the code more compact and readable
-
- There are 3 columns. Two are side by side at the top and the third is along the bottom
-"""
-
-sg.change_look_and_feel('GreenTan')
-
-col2 = Column([[Frame('Accounts:', [[Column([[Listbox(['Account '+str(i) for i in range(1,16)], key='-ACCT-LIST-', size=(15,20)),]],size=(150,400))]])]], pad=(0,0))
-
-col1 = Column([
- # Categories frame
- [Frame('Categories:', [[Radio('Websites', 'radio1', default=True, key='-WEBSITES-', size=(10, 1)),
- Radio('Software', 'radio1',key='-SOFTWARE-', size=(10, 1))]],)],
- # Information frame
- [Frame('Information:', [[Column([[Text('Account:')],
- [Input(key='-ACCOUNT-IN-', size=(19, 1))],
- [Text('User Id:')],
- [Input(key='-USERID-IN-', size=(19, 1)), Button('Copy', key='-USERID-')],
- [Text('Password:')],
- [Input(key='-PW-IN-', size=(19, 1)), Button('Copy', key='-PASS-')],
- [Text('Location:')],
- [Input(key='-LOC-IN-', size=(19, 1)), Button('Copy', key='-LOC')],
- [Text('Notes:')],
- [Multiline(key='-NOTES-', size=(25, 5))],
- ], size=(235,350),pad=(0,0))]])],], pad=(0,0))
-
-col3 = Column([[Frame('Actions:', [[Column([[Button('Save'), Button('Clear'), Button('Delete'),]], size=(450,45), pad=(0,0))]])]], pad=(0,0))
-
-layout = [ [col1, col2],
- [col3]]
-
-window = Window('Passwords', layout)
-
-while True:
- event, values = window.read()
- print(event, values)
- if event is None:
- break
-window.close()
diff --git a/DemoPrograms old/Demo_Columns.py b/DemoPrograms old/Demo_Columns.py
deleted file mode 100644
index 481751cb..00000000
--- a/DemoPrograms old/Demo_Columns.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-sg.ChangeLookAndFeel('BlueMono')
-
-# Column layout
-col = [[sg.Text('col Row 1', text_color='white', background_color='blue')],
- [sg.Text('col Row 2', text_color='white', background_color='blue'), sg.Input('col input 1')],
- [sg.Text('col Row 3', text_color='white', background_color='blue'), sg.Input('col input 2')]]
-# Window layout
-layout = [[sg.Listbox(values=('Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'),
- select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, size=(20, 3)),
- sg.Column(col, background_color='blue')],
- [sg.Input('Last input')],
- [sg.OK()]]
-
-# Display the window and get values
-event, values = sg.Window('Compact 1-line form with column').Layout(layout).Read()
-
-sg.Popup(event, values, line_width=200)
-
diff --git a/DemoPrograms old/Demo_Compact_Layouts_Element_Renaming.py b/DemoPrograms old/Demo_Compact_Layouts_Element_Renaming.py
deleted file mode 100644
index 589375a3..00000000
--- a/DemoPrograms old/Demo_Compact_Layouts_Element_Renaming.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import PySimpleGUI as sg
-# Import the elements individually to save space
-from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, Check, Button, B, Btn, ButtonMenu,BMenu, Canvas, Column, Col, Combo, DropDown, Drop, DD, Frame, Graph, Image, InputText, Input, In, I, Listbox, LBox, LB, Menu, Multiline, ML, MLine, OptionMenu, Output, Pane, ProgressBar, Prog, PBar, Radio, R, Rad, Sizer, Slider, Spin, StatusBar, Tab, TabGroup, Table, Text, Txt, T, Tree, TreeData, VerticalSeparator, Window, Print
-
-
-"""
- Demo - Compact Layouts and Element Renaming
-
- Some layouts contain many many elements such that space becomes a premium. For experienced PySimpleGUI
- programmers, there is little additional knowledge to be gained by writing
- sg.Text('My text')
- rather than using one of the shortcuts such as
- sg.T('My text')
- However, even with shortcut usage, you continue to have the package prefix of
- sg.
- That's 3 characters per element that are added to your layout!
- The very long import statement st the top can be copied into your code to give you the ability to write
- T('My text')
-
- If you don't want to use that very-long import or perhaps want to use your own shortcut names, you can easily
- create your shortcut by simple assignment:
- T = sg.Text
- This enables you to use T just as if you imported the Class T from PySimpleGUI. You could develop your own
- template that you copy and paste at the top of all of your PySimpleGUI programs. Or perhaps perform an import
- of those assignments from a .py file you create.
-
- Note that you may lose docstrings in PyCharm using these shortcuts. You can still see the parameters when pressing
- Control+P, but the Control+Q doesn't bring up the full list of parms and their descriptions. Looking for a fix
- for this.
-
- PLEASE OH PLEASE OH PLEASE NEVER EVER EVER do this:
- from PySimpleGUI import *
- There is a bot scanning GitHub for this statement. If found in your code, a squad of assassins will be dispatched
- from the PySimpleGUI headquarters and you will be hunted down and forced to change your code.
-"""
-
-# A user created shortcut....
-# Suppose this user's layout contains many Multiline Elements. It could be advantageous to have a single letter
-# shortcut version for Multiline
-M = sg.Multiline
-
-# This layout uses the user defined "M" element as well as the PySimpleGUI Button shortcut, B.
-layout = [[M(size=(30,3))],
- [B('OK')]]
-
-event, values = Window('Shortcuts', layout).read()
-sg.popup_scrolled(event, values)
diff --git a/DemoPrograms old/Demo_Compare_Files.py b/DemoPrograms old/Demo_Compare_Files.py
deleted file mode 100644
index 77ab262d..00000000
--- a/DemoPrograms old/Demo_Compare_Files.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-# sg.SetOptions(button_color=sg.COLOR_SYSTEM_DEFAULT)
-
-def GetFilesToCompare():
- form_rows = [[sg.Text('Enter 2 files to comare')],
- [sg.Text('File 1', size=(15, 1)), sg.InputText(key='file1'), sg.FileBrowse()],
- [sg.Text('File 2', size=(15, 1)), sg.InputText(key='file2'), sg.FileBrowse(target='file2')],
- [sg.Submit(), sg.Cancel()]]
-
- window = sg.Window('File Compare')
- event, values = window.Layout(form_rows).Read()
- return event, values
-
-def main():
- button, values = GetFilesToCompare()
- f1 = values['file1']
- f2 = values['file2']
-
- if any((button != 'Submit', f1 =='', f2 == '')):
- sg.PopupError('Operation cancelled')
- sys.exit(69)
-
- # --- This portion of the code is not GUI related ---
- with open(f1, 'rb') as file1:
- with open(f2, 'rb') as file2:
- a = file1.read()
- b = file2.read()
-
- for i, x in enumerate(a):
- if x != b[i]:
- sg.Popup('Compare results for files', f1, f2, '**** Mismatch at offset {} ****'.format(i))
- break
- else:
- if len(a) == len(b):
- sg.Popup('**** The files are IDENTICAL ****')
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Conways_Game_of_Life.py b/DemoPrograms old/Demo_Conways_Game_of_Life.py
deleted file mode 100644
index ece57f65..00000000
--- a/DemoPrograms old/Demo_Conways_Game_of_Life.py
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/env python
-
-# John Conway's "Game of Life" using a GUI.
-# Copyright (C) 2018 PySimpleGUI.org
-# GUI provided by PySimpleGUI.
-# Core game engine provied by Christian Jacobs
-
-# An implementation of Conway's Game of Life in Python.
-
-# Copyright (C) 2013 Christian Jacobs.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-import numpy
-import PySimpleGUI as sg # Take your pick! Tkinter
-# import PySimpleGUIWeb as sg # Or the Web! (Remi!)
-
-BOX_SIZE = 15
-
-class GameOfLife:
-
- def __init__(self, N=20, T=200):
- """ Set up Conway's Game of Life. """
- # Here we create two grids to hold the old and new configurations.
- # This assumes an N*N grid of points.
- # Each point is either alive or dead, represented by integer values of 1 and 0, respectively.
- self.N = N
- self.old_grid = numpy.zeros(N * N, dtype='i').reshape(N, N)
- self.new_grid = numpy.zeros(N * N, dtype='i').reshape(N, N)
- self.T = T # The maximum number of generations
-
- # Set up a random initial configuration for the grid.
- for i in range(0, self.N):
- for j in range(0, self.N):
- self.old_grid[i][j] = 0
- self.init_graphics()
- self.manual_board_setup()
-
- def live_neighbours(self, i, j):
- """ Count the number of live neighbours around point (i, j). """
- s = 0 # The total number of live neighbours.
- # Loop over all the neighbours.
- for x in [i - 1, i, i + 1]:
- for y in [j - 1, j, j + 1]:
- if (x == i and y == j):
- continue # Skip the current point itself - we only want to count the neighbours!
- if (x != self.N and y != self.N):
- s += self.old_grid[x][y]
- # The remaining branches handle the case where the neighbour is off the end of the grid.
- # In this case, we loop back round such that the grid becomes a "toroidal array".
- elif (x == self.N and y != self.N):
- s += self.old_grid[0][y]
- elif (x != self.N and y == self.N):
- s += self.old_grid[x][0]
- else:
- s += self.old_grid[0][0]
- return s
-
- def play(self):
- """ Play Conway's Game of Life. """
-
- # Write the initial configuration to file.
-
- self.t = 1 # Current time level
- while self.t <= self.T: # Evolve!
- # print( "At time level %d" % t)
-
- # Loop over each cell of the grid and apply Conway's rules.
- for i in range(self.N):
- for j in range(self.N):
- live = self.live_neighbours(i, j)
- if (self.old_grid[i][j] == 1 and live < 2):
- self.new_grid[i][j] = 0 # Dead from starvation.
- elif (self.old_grid[i][j] == 1 and (live == 2 or live == 3)):
- self.new_grid[i][j] = 1 # Continue living.
- elif (self.old_grid[i][j] == 1 and live > 3):
- self.new_grid[i][j] = 0 # Dead from overcrowding.
- elif (self.old_grid[i][j] == 0 and live == 3):
- self.new_grid[i][j] = 1 # Alive from reproduction.
-
- # Output the new configuration.
-
- # The new configuration becomes the old configuration for the next generation.
- self.old_grid = self.new_grid.copy()
- self.draw_board()
- # Move on to the next time level
- self.t += 1
-
- def init_graphics(self):
- self.graph = sg.Graph((600, 600), (0, 0), (450, 450), key='_GRAPH_', change_submits=True, drag_submits=False, background_color='lightblue')
- layout = [
- [sg.Text('Game of Life ', font='ANY 15'), sg.Text('', key='_OUTPUT_', size=(30,1), font='ANY 15')],
- [self.graph],
- [sg.Button('Go!', key='_DONE_'),
- sg.Text(' Delay (ms)') , sg.Slider([0,800], orientation='h', key='_SLIDER_', enable_events=True, size=(15,15)), sg.T('', size=(3,1), key='_S1_OUT_'),
- sg.Text(' Num Generations'), sg.Slider([0, 20000],default_value=4000, orientation='h',size=(15,15),enable_events=True, key='_SLIDER2_'), sg.T('', size=(3,1), key='_S2_OUT_')]
- ]
-
- self.window = sg.Window('Window Title', ).Layout(layout).Finalize()
- event, values = self.window.Read(timeout=0)
- self.delay = values['_SLIDER_']
- self.window.Element('_S1_OUT_').Update(values['_SLIDER_'])
- self.window.Element('_S2_OUT_').Update(values['_SLIDER2_'])
-
-
- def draw_board(self):
- BOX_SIZE = 15
- self.graph.Erase()
- for i in range(self.N):
- for j in range(self.N):
- if self.old_grid[i][j]:
- self.graph.DrawRectangle((i * BOX_SIZE, j * BOX_SIZE),
- (i * BOX_SIZE + BOX_SIZE, j * (BOX_SIZE) + BOX_SIZE),
- line_color='black', fill_color='yellow')
- event, values = self.window.Read(timeout=self.delay)
- if event in (None, '_DONE_'):
- exit()
- self.delay = values['_SLIDER_']
- self.T = int(values['_SLIDER2_'])
- self.window.Element('_S1_OUT_').Update(values['_SLIDER_'])
- self.window.Element('_S2_OUT_').Update(values['_SLIDER2_'])
- self.window.Element('_OUTPUT_').Update('Generation {}'.format(self.t))
-
-
- def manual_board_setup(self):
- ids = []
- for i in range(self.N):
- ids.append([])
- for j in range(self.N):
- ids[i].append(0)
- while True: # Event Loop
- event, values = self.window.Read()
- if event is None or event == '_DONE_':
- break
- self.window.Element('_S1_OUT_').Update(values['_SLIDER_'])
- self.window.Element('_S2_OUT_').Update(values['_SLIDER2_'])
- mouse = values['_GRAPH_']
-
- if event == '_GRAPH_':
- if mouse == (None, None):
- continue
- box_x = mouse[0] // BOX_SIZE
- box_y = mouse[1] // BOX_SIZE
- if self.old_grid[box_x][box_y] == 1:
- id = ids[box_x][box_y]
- self.graph.DeleteFigure(id)
- self.old_grid[box_x][box_y] = 0
- else:
- id = self.graph.DrawRectangle((box_x * BOX_SIZE, box_y * BOX_SIZE),
- (box_x * BOX_SIZE + BOX_SIZE, box_y * (BOX_SIZE) + BOX_SIZE),
- line_color='black', fill_color='yellow')
- ids[box_x][box_y] = id
- self.old_grid[box_x][box_y] = 1
- self.window.Element('_DONE_').Update(text='Exit')
-
-if (__name__ == "__main__"):
- game = GameOfLife(N=35, T=200)
- game.play()
- game.window.Close()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Crossword_Puzzle.py b/DemoPrograms old/Demo_Crossword_Puzzle.py
deleted file mode 100644
index 62dd7b4e..00000000
--- a/DemoPrograms old/Demo_Crossword_Puzzle.py
+++ /dev/null
@@ -1,54 +0,0 @@
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
- # import PySimpleGUIWeb as sg # take your pick of ports. Runs on both
-else:
- import PySimpleGUI27 as sg
-import random
-import string
-
-"""
- Demo application to show how to draw rectangles and letters on a Graph Element
- This demo mocks up a crossword puzzle board
- It will place a letter where you click on the puzzle
-"""
-
-
-BOX_SIZE = 25
-
-layout = [
- [sg.Text('Crossword Puzzle Using PySimpleGUI'), sg.Text('', key='_OUTPUT_')],
- [sg.Graph((800,800), (0,450), (450,0), key='_GRAPH_', change_submits=True, drag_submits=False)],
- [sg.Button('Show'), sg.Button('Exit')]
- ]
-
-window = sg.Window('Window Title', ).Layout(layout).Finalize()
-
-g = window.FindElement('_GRAPH_')
-
-for row in range(16):
- for col in range(16):
- if random.randint(0,100) > 10:
- g.DrawRectangle((col * BOX_SIZE + 5, row * BOX_SIZE + 3), (col * BOX_SIZE + BOX_SIZE + 5, row * BOX_SIZE + BOX_SIZE + 3), line_color='black')
- else:
- g.DrawRectangle((col * BOX_SIZE + 5, row * BOX_SIZE + 3), (col * BOX_SIZE + BOX_SIZE + 5, row * BOX_SIZE + BOX_SIZE + 3), line_color='black', fill_color='black')
-
- g.DrawText('{}'.format(row * 6 + col + 1), (col * BOX_SIZE + 10, row * BOX_SIZE + 8))
-
-while True: # Event Loop
- event, values = window.Read()
- print(event, values)
- if event is None or event == 'Exit':
- break
- mouse = values['_GRAPH_']
-
- if event == '_GRAPH_':
- if mouse == (None, None):
- continue
- box_x = mouse[0]//BOX_SIZE
- box_y = mouse[1]//BOX_SIZE
- letter_location = (box_x * BOX_SIZE + 18, box_y * BOX_SIZE + 17)
- print(box_x, box_y)
- g.DrawText('{}'.format(random.choice(string.ascii_uppercase)), letter_location, font='Courier 25')
-
-window.Close()
diff --git a/DemoPrograms old/Demo_DOC_Viewer_PIL.py b/DemoPrograms old/Demo_DOC_Viewer_PIL.py
deleted file mode 100644
index 50c6f0c8..00000000
--- a/DemoPrograms old/Demo_DOC_Viewer_PIL.py
+++ /dev/null
@@ -1,242 +0,0 @@
-"""
-@created: 2018-08-19 18:00:00
-@author: (c) 2018 Jorj X. McKie
-Display a PyMuPDF Document using Tkinter
--------------------------------------------------------------------------------
-Dependencies:
--------------
-PyMuPDF, PySimpleGUI (requires Python 3), Tkinter, PIL
-License:
---------
-GNU GPL V3+
-Description
-------------
-Get filename and start displaying page 1. Please note that all file types
-of MuPDF are supported (including EPUB e-books and HTML files for example).
-Pages can be directly jumped to, or buttons can be used for paging.
-
-This version contains enhancements:
-* Use of PIL improves response times by a factor 3 or more.
-* Zooming is now flexible: only one button serves as a toggle. Arrow keys can
- be used for moving the window when zooming.
-
-We also interpret keyboard events (PageDown / PageUp) and mouse wheel actions
-to support paging as if a button was clicked. Similarly, we do not include
-a 'Quit' button. Instead, the ESCAPE key can be used, or cancelling the window.
-To improve paging performance, we are not directly creating pixmaps from
-pages, but instead from the fitz.DisplayList of the page. A display list
-will be stored in a list and looked up by page number. This way, zooming
-pixmaps and page re-visits will re-use a once-created display list.
-
-"""
-import sys
-import fitz
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import tkinter as tk
-from PIL import Image, ImageTk
-import time
-
-if len(sys.argv) == 1:
- fname = sg.PopupGetFile('Document Browser', 'Document file to open', no_window=True,
- file_types = (
- ("PDF Files", "*.pdf"),
- ("XPS Files", "*.*xps"),
- ("Epub Files", "*.epub"),
- ("Fiction Books", "*.fb2"),
- ("Comic Books", "*.cbz"),
- ("HTML", "*.htm*")
- # add more document types here
- )
- )
-else:
- fname = sys.argv[1]
-
-if not fname:
- sg.Popup("Cancelling:", "No filename supplied")
- raise SystemExit("Cancelled: no filename supplied")
-
-doc = fitz.open(fname)
-page_count = len(doc)
-
-# used for response time statistics only
-fitz_img_time = 0.0
-tk_img_time = 0.0
-img_count = 1
-
-# allocate storage for page display lists
-dlist_tab = [None] * page_count
-
-title = "PyMuPDF display of '%s', pages: %i" % (fname, page_count)
-
-def get_page(pno, zoom = False, max_size = None, first = False):
- """Return a PNG image for a document page number.
- """
- dlist = dlist_tab[pno] # get display list of page number
- if not dlist: # create if not yet there
- dlist_tab[pno] = doc[pno].getDisplayList()
- dlist = dlist_tab[pno]
- r = dlist.rect # the page rectangle
- clip = r
- # ensure image fits screen:
- # exploit, but do not exceed width or height
- zoom_0 = 1
- if max_size:
- zoom_0 = min(1, max_size[0] / r.width, max_size[1] / r.height)
- if zoom_0 == 1:
- zoom_0 = min(max_size[0] / r.width, max_size[1] / r.height)
- mat_0 = fitz.Matrix(zoom_0, zoom_0)
-
- if not zoom: # show total page
- pix = dlist.getPixmap(matrix = mat_0, alpha=False)
- else:
- mp = r.tl + (r.br - r.tl) * 0.5 # page rect center
- w2 = r.width / 2
- h2 = r.height / 2
- clip = r * 0.5
- tl = zoom[0] # old top-left
- tl.x += zoom[1] * (w2 / 2)
- tl.x = max(0, tl.x)
- tl.x = min(w2, tl.x)
- tl.y += zoom[2] * (h2 / 2)
- tl.y = max(0, tl.y)
- tl.y = min(h2, tl.y)
- clip = fitz.Rect(tl, tl.x + w2, tl.y + h2)
-
- mat = mat_0 * fitz.Matrix(2, 2) # zoom matrix
- pix = dlist.getPixmap(alpha=False, matrix=mat, clip=clip)
-
- if first: # first call: tkinter still inactive
- img = pix.getPNGData() # so use fitz png output
- else: # else take tk photo image
- pilimg = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
- img = ImageTk.PhotoImage(pilimg)
-
- return img, clip.tl # return image, clip position
-
-
-root = tk.Tk()
-max_width = root.winfo_screenwidth() - 20
-max_height = root.winfo_screenheight() - 135
-max_size = (max_width, max_height)
-root.destroy()
-del root
-
-window = sg.Window(title, return_keyboard_events = True,
- location = (0,0), use_default_focus = False, no_titlebar=False)
-
-cur_page = 0
-data, clip_pos = get_page(cur_page,
- zoom = False,
- max_size = max_size,
- first = True)
-
-image_elem = sg.Image(data = data)
-
-goto = sg.InputText(str(cur_page + 1), size=(5, 1), do_not_clear=True,
- key = "PageNumber")
-
-layout = [
- [
- sg.ReadButton('Next'),
- sg.ReadButton('Prev'),
- sg.Text('Page:'),
- goto,
- sg.Text('(%i)' % page_count),
- sg.ReadButton('Zoom'),
- sg.Text('(toggle on/off, use arrows to navigate while zooming)'),
- ],
- [image_elem],
-]
-
-window.Layout(layout)
-
-# now define the buttons / events we want to handle
-enter_buttons = [chr(13), "Return:13"]
-quit_buttons = ["Escape:27", chr(27)]
-next_buttons = ["Next", "Next:34", "MouseWheel:Down"]
-prev_buttons = ["Prev", "Prior:33", "MouseWheel:Up"]
-Up = "Up:38"
-Left = "Left:37"
-Right = "Right:39"
-Down = "Down:40"
-zoom_buttons = ["Zoom", Up, Down, Left, Right]
-
-# all the buttons we will handle
-my_keys = enter_buttons + next_buttons + prev_buttons + zoom_buttons
-
-# old page store and zoom toggle
-old_page = 0
-old_zoom = False
-
-while True:
- event, value = window.Read()
- if event is None and (value is None or value['PageNumber'] is None):
- break
- if event in quit_buttons:
- break
-
- zoom_pressed = False
- zoom = False
-
- if event in enter_buttons:
- try:
- cur_page = int(value['PageNumber']) - 1 # check if valid
- while cur_page < 0:
- cur_page += page_count
- except:
- cur_page = 0 # this guy's trying to fool me
-
- elif event in next_buttons:
- cur_page += 1
- elif event in prev_buttons:
- cur_page -= 1
- elif event == Up:
- zoom = (clip_pos, 0, -1)
- elif event == Down:
- zoom = (clip_pos, 0, 1)
- elif event == Left:
- zoom = (clip_pos, -1, 0)
- elif event == Right:
- zoom = (clip_pos, 1, 0)
- elif event == "Zoom":
- zoom_pressed = True
- zoom = (clip_pos, 0, 0)
-
- # sanitize page number
- if cur_page >= page_count: # wrap around
- cur_page = 0
- while cur_page < 0: # pages > 0 look nicer
- cur_page += page_count
-
- if zoom_pressed and old_zoom:
- zoom = zoom_pressed = old_zoom = False
-
- t0 = time.perf_counter()
- data, clip_pos = get_page(cur_page, zoom = zoom, max_size = max_size,
- first = False)
- t1 = time.perf_counter()
- image_elem.Update(data = data)
- t2 = time.perf_counter()
- fitz_img_time += t1 - t0
- tk_img_time += t2 - t1
- img_count += 1
- old_page = cur_page
- old_zoom = zoom_pressed or zoom
-
- # update page number field
- if event in my_keys:
- goto.Update(str(cur_page + 1))
-
-
-# print some response time statistics
-if img_count > 0:
- print("response times for '%s'" % doc.name)
- print("%.4f" % (fitz_img_time/img_count), "sec fitz avg. image time")
- print("%.4f" % (tk_img_time/img_count), "sec tk avg. image time")
- print("%.4f" % ((fitz_img_time + tk_img_time)/img_count), "sec avg. total time")
- print(img_count, "images read")
- print(page_count, "pages")
diff --git a/DemoPrograms old/Demo_Debugger_Built_Into_PSG.py b/DemoPrograms old/Demo_Debugger_Built_Into_PSG.py
deleted file mode 100644
index 22e4b9ae..00000000
--- a/DemoPrograms old/Demo_Debugger_Built_Into_PSG.py
+++ /dev/null
@@ -1,55 +0,0 @@
-import PySimpleGUI as sg
-# import imwatchingyou # Not needed because using the one inside PySimpleGUI.py code itself
-
-"""
- Demo program that shows you how to integrate the PySimpleGUI Debugger
- into your program.
- This particular program is a GUI based program simply to make it easier for you to interact and change
- things.
-
- In this example, the debugger is not started initiallly. You click the "Debug" button to launch it
- There are THREE steps, and they are copy and pastes.
- 1. At the top of your app to debug add
- import imwatchingyou
- 2. When you want to show a debug window, call one of two functions:
- imwatchingyou.show_debug_window()
- imwatchingyou.show_popout_window()
- 3. You must find a location in your code to "refresh" the debugger. Some loop that's executed often.
- In this loop add this call:
- imwatchingyou.refresh()
-"""
-
-layout = [
- [sg.T('A typical PSG application')],
- [sg.In(key='_IN_')],
- [sg.T(' ', key='_OUT_', size=(45,1))],
- [sg.CBox('Checkbox 1'), sg.CBox('Checkbox 2')],
- [sg.Radio('a',1, key='_R1_'), sg.Radio('b',1, key='_R2_'), sg.Radio('c',1, key='_R3_')],
- [sg.Combo(['c1', 'c2', 'c3'], size=(6,3), key='_COMBO_')],
- [sg.Output(size=(50,6))],
- [sg.Ok(), sg.Exit(), sg.Button('Enable'), sg.Button('Popout'), sg.Button('Debugger'), sg.Debug(key='Debug')],
- ]
-
-window = sg.Window('This is your Application Window', layout, debugger_enabled=False)
-
-counter = 0
-timeout = 100
-
-# Note that you can launch the debugger windows right away, without waiting for user input
-sg.show_debugger_popout_window()
-
-while True: # Your Event Loop
- event, values = window.Read(timeout=timeout)
- if event in (None, 'Exit'):
- break
- elif event == 'Enable':
- window.EnableDebugger()
- elif event == 'Popout':
- sg.show_debugger_popout_window() # replaces old popout with a new one, possibly with new variables`
- elif event == 'Debugger':
- sg.show_debugger_window()
- counter += 1
- # to prove window is operating, show the input in another area in the window.
- window.Element('_OUT_').Update(values['_IN_'])
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Debugger_Button.py b/DemoPrograms old/Demo_Debugger_Button.py
deleted file mode 100644
index b2b482d6..00000000
--- a/DemoPrograms old/Demo_Debugger_Button.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import PySimpleGUI as sg
-# import imwatchingyou # STEP 1
-
-"""
- Demo program that shows you how to integrate the PySimpleGUI Debugger
- into your program.
- This particular program is a GUI based program simply to make it easier for you to interact and change
- things.
-
- In this example, the debugger is not started initiallly. You click the "Debug" button to launch it
- There are THREE steps, and they are copy and pastes.
- 1. At the top of your app to debug add
- import imwatchingyou
- 2. When you want to show a debug window, call one of two functions:
- imwatchingyou.show_debug_window()
- imwatchingyou.show_popout_window()
- 3. You must find a location in your code to "refresh" the debugger. Some loop that's executed often.
- In this loop add this call:
- imwatchingyou.refresh()
-"""
-
-layout = [
- [sg.T('A typical PSG application')],
- [sg.In(key='_IN_')],
- [sg.T(' ', key='_OUT_', size=(45,1))],
- [sg.CBox('Checkbox 1'), sg.CBox('Checkbox 2')],
- [sg.Radio('a',1, key='_R1_'), sg.Radio('b',1, key='_R2_'), sg.Radio('c',1, key='_R3_')],
- [sg.Combo(['c1', 'c2', 'c3'], size=(6,3), key='_COMBO_')],
- [sg.Output(size=(50,6))],
- [sg.Ok(), sg.Exit(), sg.Button('Enable'), sg.Debug(key='Debug')],
- ]
-
-window = sg.Window('This is your Application Window', layout, debugger_enabled=False)
-
-counter = 0
-timeout = 100
-
-while True: # Your Event Loop
- event, values = window.Read(timeout=timeout)
- if event in (None, 'Exit'):
- break
- elif event == 'Enable':
- window.EnableDebugger()
- counter += 1
- # to prove window is operating, show the input in another area in the window.
- window.Element('_OUT_').Update(values['_IN_'])
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Debugger_ImWatchingYou.py b/DemoPrograms old/Demo_Debugger_ImWatchingYou.py
deleted file mode 100644
index 12239a7e..00000000
--- a/DemoPrograms old/Demo_Debugger_ImWatchingYou.py
+++ /dev/null
@@ -1,54 +0,0 @@
-import PySimpleGUI as sg
-import imwatchingyou # STEP 1
-
-"""
- Demo program that shows you how to integrate the PySimpleGUI Debugger
- into your program.
- This particular program is a GUI based program simply to make it easier for you to interact and change
- things.
-
- In this example, the debugger is not started initiallly. You click the "Debug" button to launch it
- There are THREE steps, and they are copy and pastes.
- 1. At the top of your app to debug add
- import imwatchingyou
- 2. When you want to show a debug window, call one of two functions:
- imwatchingyou.show_debug_window()
- imwatchingyou.show_popout_window()
- 3. You must find a location in your code to "refresh" the debugger. Some loop that's executed often.
- In this loop add this call:
- imwatchingyou.refresh()
-"""
-
-layout = [
- [sg.T('A typical PSG application')],
- [sg.In(key='_IN_')],
- [sg.T(' ', key='_OUT_', size=(30, 1))],
- [sg.Radio('a', 1, key='_R1_'), sg.Radio('b', 1, key='_R2_'), sg.Radio('c', 1, key='_R3_')],
- [sg.Combo(['c1', 'c2', 'c3'], size=(6, 3), key='_COMBO_')],
- [sg.Output(size=(50, 6))],
- [sg.Ok(), sg.Exit(), sg.Button('Debug'), sg.Button('Popout')],
-]
-
-window = sg.Window('This is your Application Window', layout)
-
-counter = 0
-timeout = 100
-
-while True: # Your Event Loop
- event, values = window.Read(timeout=timeout)
- if event in (None, 'Exit'):
- break
- elif event == 'Ok':
- print('You clicked Ok.... this is where print output goes')
- elif event == 'Debug':
- imwatchingyou.show_debugger_window() # STEP 2
- elif event == 'Popout':
- imwatchingyou.show_debugger_popout_window() # STEP 2
- counter += 1
- # to prove window is operating, show the input in another area in the window.
- window.Element('_OUT_').Update(values['_IN_'])
-
- # don't worry about the "state" of things, just call this function "frequently"
- imwatchingyou.refresh_debugger() # STEP 3 - refresh debugger
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows.py b/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows.py
deleted file mode 100644
index 22b8cf55..00000000
--- a/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-"""
- Demo - Running 2 windows with both being active at the same time
- Three important things to note about this design patter:
- 1. The layout for window 2 is inside of the while loop, just before the call to window2=sg.Window
- 2. The read calls have timeout values of 100 and 0. You can change the 100 to whatever interval you wish
- but must keep the second window's timeout at 0
- 3. There is a safeguard to stop from launching multiple copies of window2. Only 1 window2 is visible at a time
-"""
-
-# Window 1 layout
-layout = [
- [sg.Text('This is the FIRST WINDOW'), sg.Text(' ', key='_OUTPUT_')],
- [sg.Text('')],
- [sg.Button('Launch 2nd Window'),sg.Button('Popup'), sg.Button('Exit')]
- ]
-
-window = sg.Window('Window Title', location=(800,600)).Layout(layout)
-win2_active = False
-i=0
-while True: # Event Loop
- event, values = window.Read(timeout=100)
- if event != sg.TIMEOUT_KEY:
- print(i, event, values)
-
- if event is None or event == 'Exit':
- break
- elif event == 'Popup':
- sg.Popup('This is a BLOCKING popup','all windows remain inactive while popup active')
- i+=1
- if event == 'Launch 2nd Window' and not win2_active: # only run if not already showing a window2
- win2_active = True
- # window 2 layout - note - must be "new" every time a window is created
- layout2 = [
- [sg.Text('The second window'), sg.Text('', key='_OUTPUT_')],
- [sg.Input(do_not_clear=True, key='_IN_')],
- [sg.Button('Show'), sg.Button('Exit')]
- ]
- window2 = sg.Window('Second Window').Layout(layout2)
- # Read window 2's events. Must use timeout of 0
- if win2_active:
- # print("reading 2")
- event, values = window2.Read(timeout=100)
- # print("win2 ", event)
- if event != sg.TIMEOUT_KEY:
- print("win2 ", event)
- if event == 'Exit' or event is None:
- # print("Closing window 2", event)
- win2_active = False
- window2.Close()
- if event == 'Show':
- sg.Popup('You entered ', values['_IN_'])
-
-window.Close()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows1.py b/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows1.py
deleted file mode 100644
index f2328e33..00000000
--- a/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows1.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""
- PySimpleGUI The Complete Course
- Lesson 7 - Multiple Windows
-"""
-import PySimpleGUI as sg
-
-# Design pattern 1 - First window does not remain active
-
-layout = [[ sg.Text('Window 1'),],
- [sg.Input(do_not_clear=True)],
- [sg.Text('', size=(20,1), key='_OUTPUT_')],
- [sg.Button('Launch 2')]]
-
-win1 = sg.Window('Window 1').Layout(layout)
-win2_active=False
-while True:
- ev1, vals1 = win1.Read(timeout=100)
- if ev1 is None:
- break
- win1.FindElement('_OUTPUT_').Update(vals1[0])
-
- if ev1 == 'Launch 2' and not win2_active:
- win2_active = True
- win1.Hide()
- layout2 = [[sg.Text('Window 2')],
- [sg.Button('Exit')]]
-
- win2 = sg.Window('Window 2').Layout(layout2)
- while True:
- ev2, vals2 = win2.Read()
- if ev2 is None or ev2 == 'Exit':
- win2.Close()
- win2_active = False
- win1.UnHide()
- break
diff --git a/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows2.py b/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows2.py
deleted file mode 100644
index 41bdad76..00000000
--- a/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows2.py
+++ /dev/null
@@ -1,34 +0,0 @@
-"""
- PySimpleGUI The Complete Course
- Lesson 7 - Multiple Windows
-"""
-import PySimpleGUI as sg
-
-# Design pattern 2 - First window remains active
-
-layout = [[ sg.Text('Window 1'),],
- [sg.Input(do_not_clear=True)],
- [sg.Text('', size=(20,1), key='_OUTPUT_')],
- [sg.Button('Launch 2'), sg.Button('Exit')]]
-
-win1 = sg.Window('Window 1').Layout(layout)
-
-win2_active = False
-while True:
- ev1, vals1 = win1.Read(timeout=100)
- win1.FindElement('_OUTPUT_').Update(vals1[0])
- if ev1 is None or ev1 == 'Exit':
- break
-
- if not win2_active and ev1 == 'Launch 2':
- win2_active = True
- layout2 = [[sg.Text('Window 2')],
- [sg.Button('Exit')]]
-
- win2 = sg.Window('Window 2').Layout(layout2)
-
- if win2_active:
- ev2, vals2 = win2.Read(timeout=100)
- if ev2 is None or ev2 == 'Exit':
- win2_active = False
- win2.Close()
diff --git a/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows3.py b/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows3.py
deleted file mode 100644
index b5500cec..00000000
--- a/DemoPrograms old/Demo_Design_Pattern_Multiple_Windows3.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import PySimpleGUI as sg
-
-layout = [[sg.Text('Window 1'), ],
- [sg.Input(do_not_clear=True)],
- [sg.Text('',size=(20,1), key='_OUTPUT_')],
- [sg.Button('Next >'), sg.Button('Exit')]]
-
-win1 = sg.Window('Window 1').Layout(layout)
-
-win3_active = win2_active = False
-while True:
- if not win2_active:
- ev1, vals1 = win1.Read()
- if ev1 is None or ev1 == 'Exit':
- break
- win1.FindElement('_OUTPUT_').Update(vals1[0])
-
- if not win2_active and ev1 == 'Next >':
- win2_active = True
- win1.Hide()
- layout2 = [[sg.Text('Window 2')],
- [sg.Button('< Prev'), sg.Button('Next >')]]
-
- win2 = sg.Window('Window 2').Layout(layout2)
-
- if win2_active:
- ev2, vals2 = win2.Read()
- if ev2 in (None, 'Exit', '< Prev'):
- win2_active = False
- win2.Close()
- win1.UnHide()
- elif ev2 == 'Next >':
- win3_active = True
- win2_active = False
- win2.Hide()
- layout3 = [[sg.Text('Window 3')],
- [sg.Button('< Prev'), sg.Button('Exit')]]
- win3 = sg.Window('Window 3').Layout(layout3)
-
- if win3_active:
- ev3, vals3 = win3.Read()
- if ev3 == '< Prev':
- win3.Close()
- win3_active = False
- win2_active = True
- win2.UnHide()
- elif ev3 in (None, 'Exit'):
- break
diff --git a/DemoPrograms old/Demo_Design_Pattern_Persistent_Window.py b/DemoPrograms old/Demo_Design_Pattern_Persistent_Window.py
deleted file mode 100644
index 7d137458..00000000
--- a/DemoPrograms old/Demo_Design_Pattern_Persistent_Window.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [
- [sg.Text('Your typed chars appear here:'), sg.Text('', size=(20,1), key='-OUTPUT-')],
- [sg.Input(do_not_clear=True, key='-IN-')],
- [sg.Button('Show'), sg.Button('Exit')]
- ]
-
-window = sg.Window('Window Title').Layout(layout)
-
-while True: # Event Loop
- event, values = window.Read()
- print(event, values)
- if event is None or event == 'Exit':
- break
- if event == 'Show':
- # change the "output" element to be the value of "input" element
- window.FindElement('-OUTPUT-').Update(values['-IN-'])
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Design_Patterns.py b/DemoPrograms old/Demo_Design_Patterns.py
deleted file mode 100644
index 64b39661..00000000
--- a/DemoPrograms old/Demo_Design_Patterns.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""
-When creating a new PySimpleGUI program from scratch, start here.
-These are the accepted design patterns that cover the two primary use cases
-
-1. A "One Shot" window
-2. A persistent window that stays open after button clicks (uses an event loop)
-3. A persistent window that need to perform Update of an element before the window.read
-"""
-# ---------------------------------#
-# DESIGN PATTERN 1 - Simple Window #
-# ---------------------------------#
-import PySimpleGUI as sg
-
-layout = [[ sg.Text('My Oneshot') ],
- [ sg.Button('OK') ]]
-
-window = sg.Window('My Oneshot', layout)
-event, values = window.read()
-window.close()
-
-
-# -------------------------------------#
-# DESIGN PATTERN 2 - Persistent Window #
-# -------------------------------------#
-import PySimpleGUI as sg
-
-layout = [[ sg.Text('My layout') ],
- [ sg.Button('OK'), sg.Button('Cancel') ]]
-
-window = sg.Window('Design Pattern 2', layout)
-
-while True: # Event Loop
- event, values = window.read()
- if event in (None, 'Cancel'):
- break
-window.close()
-
-# ------------------------------------------------------------------#
-# DESIGN PATTERN 3 - Persistent Window with "early update" required #
-# ------------------------------------------------------------------#
-import PySimpleGUI as sg
-
-layout = [[ sg.Text('My layout', key='-TEXT-KEY-') ],
- [ sg.Button('OK'), sg.Button('Cancel') ]]
-
-window = sg.Window('Design Pattern 3', layout, finalize=True)
-
-window['-TEXT-KEY-'].Update('NEW Text') # Change the text field. Finalize allows us to do this
-
-while True: # Event Loop
- event, values = window.read()
- if event in (None, 'Cancel'):
- break
-window.close()
diff --git a/DemoPrograms old/Demo_Desktop_Floating_Toolbar.py b/DemoPrograms old/Demo_Desktop_Floating_Toolbar.py
deleted file mode 100644
index 785ae428..00000000
--- a/DemoPrograms old/Demo_Desktop_Floating_Toolbar.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-import subprocess
-import os
-
-
-"""
- Demo_Toolbar - A floating toolbar with quick launcher
-
- One cool PySimpleGUI demo. Shows borderless windows, grab_anywhere, tight button layout
- You can setup a specific program to launch when a button is clicked, or use the
- Combobox to select a .py file found in the root folder, and run that file.
-
-"""
-
-ROOT_PATH = './'
-
-def Launcher():
-
- # def print(line):
- # window.FindElement('output').Update(line)
-
- sg.ChangeLookAndFeel('Dark')
-
- namesonly = [f for f in os.listdir(ROOT_PATH) if f.endswith('.py') ]
-
- if len(namesonly) == 0:
- namesonly = ['test 1', 'test 2', 'test 3']
-
- sg.SetOptions(element_padding=(0,0), button_element_size=(12,1), auto_size_buttons=False)
-
- layout = [[sg.Combo(values=namesonly, size=(35,30), key='demofile'),
- sg.Button('Run', button_color=('white', '#00168B')),
- sg.Button('Program 1'),
- sg.Button('Program 2'),
- sg.Button('Program 3', button_color=('white', '#35008B')),
- sg.Button('EXIT', button_color=('white','firebrick3'))],
- [sg.T('', text_color='white', size=(50,1), key='output')]]
-
- window = sg.Window('Floating Toolbar', no_titlebar=True, grab_anywhere=True, keep_on_top=True).Layout(layout)
-
-
- # ---===--- Loop taking in user input and executing appropriate program --- #
- while True:
- (event, values) = window.Read()
- if event == 'EXIT' or event is None:
- break # exit button clicked
- if event == 'Program 1':
- print('Run your program 1 here!')
- elif event == 'Program 2':
- print('Run your program 2 here!')
- elif event == 'Run':
- file = values['demofile']
- print('Launching %s'%file)
- ExecuteCommandSubprocess('python', os.path.join(ROOT_PATH, file))
- else:
- print(event)
-
-def ExecuteCommandSubprocess(command, *args, wait=False):
- try:
- if sys.platform == 'linux':
- arg_string = ''
- arg_string = ' '.join([str(arg) for arg in args])
- # for arg in args:
- # arg_string += ' ' + str(arg)
- print('python3 ' + arg_string)
- sp = subprocess.Popen(['python3 ', arg_string ], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- else:
- arg_string = ' '.join([str(arg) for arg in args])
- sp = subprocess.Popen([command, arg_string], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- # sp = subprocess.Popen([command, list(args)], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
- if wait:
- out, err = sp.communicate()
- if out:
- print(out.decode("utf-8"))
- if err:
- print(err.decode("utf-8"))
- except: pass
-
-
-
-if __name__ == '__main__':
- Launcher()
-
diff --git a/DemoPrograms old/Demo_Desktop_Widget_CPU_Dashboard.py b/DemoPrograms old/Demo_Desktop_Widget_CPU_Dashboard.py
deleted file mode 100644
index 0512f4d6..00000000
--- a/DemoPrograms old/Demo_Desktop_Widget_CPU_Dashboard.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import psutil
-
-"""
- Desktop floating widget - CPU Cores
- Uses psutil to display:
- CPU usage on each individual core
- Information is updated once a second and is shown as an area graph that scrolls
-"""
-
-GRAPH_WIDTH = 120 # each individual graph size in pixels
-GRAPH_HEIGHT = 40
-TRANSPARENCY = .8 # how transparent the window looks. 0 = invisible, 1 = normal window
-NUM_COLS = 4
-POLL_FREQUENCY = 500 # how often to update graphs in milliseconds
-
-colors = ('#23a0a0', '#56d856', '#be45be', '#5681d8', '#d34545', '#BE7C29')
-
-# DashGraph does the drawing of each graph
-class DashGraph(object):
- def __init__(self, graph_elem, text_elem, starting_count, color):
- self.graph_current_item = 0
- self.graph_elem = graph_elem
- self.text_elem = text_elem
- self.prev_value = starting_count
- self.max_sent = 1
- self.color = color
-
- def graph_percentage_abs(self, value):
- self.graph_elem.DrawLine((self.graph_current_item, 0), (self.graph_current_item, value), color=self.color)
- if self.graph_current_item >= GRAPH_WIDTH:
- self.graph_elem.Move(-1,0)
- else:
- self.graph_current_item += 1
-
- def text_display(self, text):
- self.text_elem.Update(text)
-
-def main():
- # A couple of "Uber Elements" that combine several elements and enable bulk edits
- def Txt(text, **kwargs):
- return(sg.Text(text, font=('Helvetica 8'), **kwargs))
-
- def GraphColumn(name, key):
- col = sg.Column([[Txt(name, key=key+'_TXT_'), ],
- [sg.Graph((GRAPH_WIDTH, GRAPH_HEIGHT), (0, 0), (GRAPH_WIDTH, 100), background_color='black',
- key=key+'_GRAPH_')]], pad=(2, 2))
- return col
-
-
- num_cores = len(psutil.cpu_percent(percpu=True)) # get the number of cores in the CPU
-
- sg.ChangeLookAndFeel('Black')
- sg.SetOptions(element_padding=(0,0), margins=(1,1), border_width=0)
-
- # ---------------- Create Layout ----------------
- layout = [[ sg.Button('', image_data=red_x, button_color=('black', 'black'), key='Exit', tooltip='Closes window'),
- sg.Text(' CPU Core Usage')] ]
-
- # add on the graphs
- for rows in range(num_cores//NUM_COLS+1):
- row = []
- for cols in range(min(num_cores-rows*NUM_COLS, NUM_COLS)):
- row.append(GraphColumn('CPU '+str(rows*NUM_COLS+cols), '_CPU_'+str(rows*NUM_COLS+cols)))
- layout.append(row)
-
- # ---------------- Create Window ----------------
- window = sg.Window('PSG System Dashboard',
- keep_on_top=True,
- auto_size_buttons=False,
- grab_anywhere=True,
- no_titlebar=True,
- default_button_element_size=(12, 1),
- return_keyboard_events=True,
- alpha_channel=TRANSPARENCY,
- use_default_focus=False,
- ).Layout(layout).Finalize()
-
- # setup graphs & initial values
- graphs = []
- for i in range(num_cores):
- graphs.append(DashGraph(window.FindElement('_CPU_'+str(i)+'_GRAPH_'),
- window.FindElement('_CPU_'+str(i) + '_TXT_'),
- 0, colors[i%6]))
-
- # ---------------- main loop ----------------
- while (True):
- # --------- Read and update window once every Polling Frequency --------
- event, values = window.Read(timeout=POLL_FREQUENCY)
- if event in (None, 'Exit'): # Be nice and give an exit
- break
- # read CPU for each core
- stats = psutil.cpu_percent(percpu=True)
- # Update each graph
- for i in range(num_cores):
- graphs[i].graph_percentage_abs(stats[i])
- graphs[i].text_display('{} CPU {:2.0f}'.format(i, stats[i]))
- window.Close()
-
-if __name__ == "__main__":
- # the clever Red X graphic
- red_x = "R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
-
- main()
- sys.exit(69)
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Desktop_Widget_CPU_Graph.py b/DemoPrograms old/Demo_Desktop_Widget_CPU_Graph.py
deleted file mode 100644
index 801cd61e..00000000
--- a/DemoPrograms old/Demo_Desktop_Widget_CPU_Graph.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-import sys
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import time
-import random
-import psutil
-from threading import Thread
-
-
-STEP_SIZE=3
-SAMPLES = 300
-SAMPLE_MAX = 500
-CANVAS_SIZE = (300,200)
-
-
-g_interval = .25
-g_cpu_percent = 0
-g_procs = None
-g_exit = False
-
-def CPU_thread(args):
- global g_interval, g_cpu_percent, g_procs, g_exit
-
- while not g_exit:
- try:
- g_cpu_percent = psutil.cpu_percent(interval=g_interval)
- g_procs = psutil.process_iter()
- except:
- pass
-
-def main():
- global g_exit, g_response_time
- # start ping measurement thread
-
- sg.ChangeLookAndFeel('Black')
- sg.SetOptions(element_padding=(0,0))
-
- layout = [ [sg.Quit( button_color=('white','black')), sg.T('', pad=((100,0),0), font='Any 15', key='output')],
- [sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,SAMPLE_MAX),background_color='black', key='graph')],]
-
- window = sg.Window('CPU Graph', grab_anywhere=True, keep_on_top=True, background_color='black', no_titlebar=True, use_default_focus=False).Layout(layout)
-
- graph = window.FindElement('graph')
- output = window.FindElement('output')
- # start cpu measurement thread
- thread = Thread(target=CPU_thread,args=(None,))
- thread.start()
-
- last_cpu = i = 0
- prev_x, prev_y = 0, 0
- while True: # the Event Loop
- time.sleep(.5)
- event, values = window.Read(timeout=0)
- if event == 'Quit' or event is None: # always give ths user a way out
- break
- # do CPU measurement and graph it
- current_cpu = int(g_cpu_percent*10)
- if current_cpu == last_cpu:
- continue
- output.Update(current_cpu/10) # show current cpu usage at top
- if current_cpu > SAMPLE_MAX:
- current_cpu = SAMPLE_MAX
- new_x, new_y = i, current_cpu
- if i >= SAMPLES:
- graph.Move(-STEP_SIZE,0) # shift graph over if full of data
- prev_x = prev_x - STEP_SIZE
- graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white')
- prev_x, prev_y = new_x, new_y
- i += STEP_SIZE if i < SAMPLES else 0
- last_cpu = current_cpu
-
- g_exit = True
- window.Close()
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Desktop_Widget_CPU_Utilization.py b/DemoPrograms old/Demo_Desktop_Widget_CPU_Utilization.py
deleted file mode 100644
index 39aefb5d..00000000
--- a/DemoPrograms old/Demo_Desktop_Widget_CPU_Utilization.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env python
-import sys
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import psutil
-import time
-from threading import Thread
-import operator
-
-
-"""
- PSUTIL Desktop Widget
- Creates a floating CPU utilization window that is always on top of other windows
- You move it by grabbing anywhere on the window
- Good example of how to do a non-blocking, polling program using PySimpleGUI
- Use the spinner to adjust the number of seconds between readings of the CPU utilizaiton
-
- NOTE - you will get a warning message printed when you exit using exit button.
- It will look something like:
- invalid command name "1616802625480StopMove"
-"""
-
-# globale used to communicate with thread.. yea yea... it's working fine
-g_interval = 1
-g_cpu_percent = 0
-g_procs = None
-g_exit = False
-
-def CPU_thread(args):
- global g_interval, g_cpu_percent, g_procs, g_exit
-
- while not g_exit:
- try:
- g_cpu_percent = psutil.cpu_percent(interval=g_interval)
- g_procs = psutil.process_iter()
- except:
- pass
-
-
-def main():
- global g_interval, g_procs, g_exit
-
- # ---------------- Create Form ----------------
- sg.ChangeLookAndFeel('Black')
- layout = [[sg.Text('', size=(8,1), font=('Helvetica', 20),text_color=sg.YELLOWS[0],
- justification='center', key='text')],
- [sg.Text('', size=(30, 8), font=('Courier New', 12),text_color='white', justification='left', key='processes')],
- [sg.Exit(button_color=('white', 'firebrick4'), pad=((15,0), 0), size=(9,1)),
- sg.Spin([x+1 for x in range(10)], 3, key='spin')],]
-
- window = sg.Window('CPU Utilization',
- no_titlebar=True,
- keep_on_top=True,
- alpha_channel=.8,
- grab_anywhere=True).Layout(layout)
-
- # start cpu measurement thread
- thread = Thread(target=CPU_thread,args=(None,))
- thread.start()
- timeout_value = 1 # make first read really quick
- g_interval = 1
- # ---------------- main loop ----------------
- while (True):
- # --------- Read and update window --------
- event, values = window.Read(timeout=timeout_value, timeout_key='Timeout')
- # --------- Do Button Operations --------
- if event is None or event == 'Exit':
- break
-
- timeout_value = int(values['spin']) * 1000
-
- cpu_percent = g_cpu_percent
- display_string = ''
- if g_procs:
- # --------- Create list of top % CPU porocesses --------
- try:
- top = {proc.name() : proc.cpu_percent() for proc in g_procs}
- except: pass
-
-
- top_sorted = sorted(top.items(), key=operator.itemgetter(1), reverse=True)
- if top_sorted:
- top_sorted.pop(0)
- display_string = ''
- for proc, cpu in top_sorted:
- display_string += '{:2.2f} {}\n'.format(cpu/10, proc)
-
- # --------- Display timer and proceses in window --------
- window.FindElement('text').Update('CPU {}'.format(cpu_percent))
- window.FindElement('processes').Update(display_string)
-
- g_exit = True
- thread.join()
-
-if __name__ == "__main__":
- main()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Desktop_Widget_CPU_Utilization_Simple.py b/DemoPrograms old/Demo_Desktop_Widget_CPU_Utilization_Simple.py
deleted file mode 100644
index f5c61b32..00000000
--- a/DemoPrograms old/Demo_Desktop_Widget_CPU_Utilization_Simple.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-import sys
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-import psutil
-
-# ---------------- Create Form ----------------
-sg.ChangeLookAndFeel('Black')
-
-layout = [[sg.Text('CPU Utilization')],
- [sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='_text_')],
- [sg.Exit(button_color=('white', 'firebrick4'), pad=((15, 0), 0), size=(9,1)),
- sg.Spin([x + 1 for x in range(10)], 3, key='_spin_')]]
-
-# Layout the rows of the Window
-window = sg.Window('CPU Meter',
- no_titlebar=True,
- keep_on_top=True,
- grab_anywhere=True).Layout(layout).Finalize()
-
-# ---------------- main loop ----------------
-interval = 10 # For the first one, make it quick
-while (True):
- # --------- Read and update window --------
- event, values = window.Read(timeout=interval)
- # --------- Do Button Operations --------
- if event is None or event == 'Exit':
- break
-
- interval = int(values['_spin_'])*1000
-
-
-
- cpu_percent = psutil.cpu_percent(interval=1)
-
- # --------- Display timer in window --------
-
- window.FindElement('_text_').Update(f'CPU {cpu_percent:02.0f}%')
-
-# Broke out of main loop. Close the window.
-window.CloseNonBlocking()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Desktop_Widget_Email_Notification.py b/DemoPrograms old/Demo_Desktop_Widget_Email_Notification.py
deleted file mode 100644
index de4264d8..00000000
--- a/DemoPrograms old/Demo_Desktop_Widget_Email_Notification.py
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env python
-import sys
-
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
- sg.PopupError('Sorry, at the moment this program only runs on Python 3')
- sys.exit()
-
-import email
-import imaplib
-from datetime import datetime
-import calendar
-
-IMAP_SERVER_GMAIL = 'imap.gmail.com' # gmail server address
-IMAP_SERVER_HOTMAIL = 'imap-mail.outlook.com' # hotmail server address
-
-################# Change these to match your email setup ################
-LOGIN_EMAIL = 'you@mail.com'
-LOGIN_PASSWORD = 'your email password'
-IMAP_SERVER = IMAP_SERVER_GMAIL # change to match your email service
-
-MAX_EMAILS = 10
-
-
-def gui():
- sg.ChangeLookAndFeel('Topanga')
-
- sg.SetOptions(border_width=0, margins=(0, 0), element_padding=(4, 0))
-
- layout = [[sg.T('Email New Mail Notification' + 48 * ' '),
- sg.Button('', image_data=refresh, button_color=('#282923', '#282923'), key='_refresh_',
- tooltip='Refreshes Email'),
- sg.Button('', image_data=red_x, button_color=('#282923', '#282923'), key='_quit_',
- tooltip='Closes window')],
- [sg.T('', key='_status_', size=(25, 1))], ]
-
- for i in range(MAX_EMAILS):
- layout.append([sg.T('', size=(20, 1), key='{}date'.format(i), font='Sans 8'),
- sg.T('', size=(45, 1), font='Sans 8', key='{}from'.format(i))])
-
- window = sg.Window('',
- no_titlebar=True,
- grab_anywhere=True,
- keep_on_top=True,
- alpha_channel=0,
- ).Layout(layout).Finalize()
-
- # move the window to the upper right corner of the screen
- w, h = window.GetScreenDimensions()
- window.Move(w - 410, 0)
- window.SetAlpha(.9)
- window.Refresh()
- status_elem = window.FindElement('_status_')
- # The Event Loop
- while True:
- status_elem.Update('Reading...')
- window.Refresh()
- read_mail(window)
- status_elem.Update('')
- event, values = window.Read(timeout=30 * 1000) # return every 30 seconds
- if event == '_quit_':
- break
-
-
-def read_mail(window):
- """
- Reads late emails from IMAP server and displays them in the Window
- :param window: window to display emails in
- :return:
- """
- mail = imaplib.IMAP4_SSL(IMAP_SERVER)
-
- (retcode, capabilities) = mail.login(LOGIN_EMAIL, LOGIN_PASSWORD)
- mail.list()
- typ, data = mail.select('Inbox')
- n = 0
- now = datetime.now()
- # get messages from today
- search_string = '(SENTON {}-{}-{})'.format(now.day, calendar.month_abbr[now.month], now.year)
- (retcode, messages) = mail.search(None, search_string)
- if retcode == 'OK':
- msg_list = messages[0].split() # message numbers are separated by spaces, turn into list
- msg_list.sort(reverse=True) # sort messages descending
- for n, message in enumerate(msg_list):
- if n >= MAX_EMAILS:
- break
- from_elem = window.FindElement('{}from'.format(n))
- date_elem = window.FindElement('{}date'.format(n))
- from_elem.Update('') # erase them so you know they're changing
- date_elem.Update('')
- window.Refresh()
- typ, data = mail.fetch(message, '(RFC822)')
- for response_part in data:
- if isinstance(response_part, tuple):
- original = email.message_from_bytes(response_part[1])
- date_str = original['Date'][:22]
- from_elem.Update(original['From'])
- date_elem.Update(date_str)
- window.Refresh() # make the window changes show up right away
-
-
-red_x = "R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
-
-refresh = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACb0lEQVR4XpVTXUiTbxT/vePdFuF0BTFW9ufVvMlu+iACka6CQY1gQVdtEmTMpSKzzJT/RTdCRHhT4F0Us8LGVqlo1lZaFslWQWBkN+tDkpSpbfNz797T8zy6DbUbf/Dbec7vfOycMwa0DBJjM7Ko72mBtz+KplCS6Ronf3NNxNZBt2qv4dJzL0uKwGRqU/6zHDqyd1dBk32/xMnfXOMxkVPXXYlVSLjykk4fKIb/4zgUSxEO7zRBKd4Bjm/jU9ys8f2fJoCFhRiWl6pw6+Qw0BymhlfT5Lg/xmycHA++ktL+nsRqrUOrdpBpH6hhKC7yhObti0CgKUTu0KTgcd8X4j4aB2bYvj7UPqkQrO/1cU25ESV3eJJO8LzLIQ11/CYXn5Grf4KqGF19E3Ts9iixe2QPm0dtt5PtP6NcHxF5ZVfDhIbeqMQ6E0hcI4ec327jah513T4YDM5TR/dh8vc0hkfHUxI2gwuPKyDLb2wV5cIdePuZZGwWmQxSSyqICFBVyKgJJkFaQW4Hna4THQ4X/gUiD2+QXEwjNZsASJvTgWgMqoY95WWw7raAJdjheeTEeniCTqgZu2IxswnSmGI3gEZjMiQpAMocTC2nJcm4hU9gRjp9E+6Ajb07wKFpHqRVOzKqedFUhOX4HyRnEwSjMQCB8/4IqnxU2DYiaGnsIe7n2UlK61MWe0dbW18Ijdfk/wuy7IXeEEvEvmM+kcRM4XYYSkohW62ChtIS/NKbWGwO8z9+Anp9TNSsQU2wEtVdEZy5o7Gfi7Z5ewj/vxbkPs51kYhVP4zAw3I3IN+ohSVFcfZeEs67Gid/c03E1uEv5QpTFzvZK5EAAAAASUVORK5CYII='
-
-gui()
diff --git a/DemoPrograms old/Demo_Desktop_Widget_Timer.py b/DemoPrograms old/Demo_Desktop_Widget_Timer.py
deleted file mode 100644
index 31b24875..00000000
--- a/DemoPrograms old/Demo_Desktop_Widget_Timer.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-import PySimpleGUI as sg
-import time
-
-"""
- Timer Desktop Widget Creates a floating timer that is always on top of other windows You move it by grabbing anywhere on the window Good example of how to do a non-blocking, polling program using PySimpleGUI
- Something like this can be used to poll hardware when running on a Pi
-
- While the timer ticks are being generated by PySimpleGUI's "timeout" mechanism, the actual value
- of the timer that is displayed comes from the system timer, time.time(). This guarantees an
- accurate time value is displayed regardless of the accuracy of the PySimpleGUI timer tick. If
- this design were not used, then the time value displayed would slowly drift by the amount of time
- it takes to execute the PySimpleGUI read and update calls (not good!)
-
-"""
-
-def time_as_int():
- return int(round(time.time() * 100))
-
-# ---------------- Create Form ----------------
-sg.ChangeLookAndFeel('Black')
-
-layout = [[sg.Text('')],
- [sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
- [sg.Button('Pause', key='-RUN-PAUSE-', button_color=('white', '#001480')),
- sg.Button('Reset', button_color=('white', '#007339'), key='-RESET-'),
- sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]]
-
-window = sg.Window('Running Timer', layout, no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True, element_padding=(0,0))
-
-# ---------------- main loop ----------------
-current_time, paused_time, paused = 0, 0, False
-start_time = time_as_int()
-while (True):
- # --------- Read and update window --------
- if not paused:
- event, values = window.Read(timeout=10)
- current_time = time_as_int() - start_time
- else:
- event, values = window.Read()
- # --------- Do Button Operations --------
- if event in (None, 'Exit'): # ALWAYS give a way out of program
- break
- if event == '-RESET-':
- paused_time = start_time = time_as_int()
- current_time = 0
- elif event == '-RUN-PAUSE-':
- paused = not paused
- if paused:
- paused_time = time_as_int()
- else:
- start_time = start_time + time_as_int() - paused_time
- window['-RUN-PAUSE-'].Update('Run' if paused else 'Pause') # Change button's text
-
- # --------- Display timer in window --------
- window['text'].Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
- (current_time // 100) % 60,
- current_time % 100))
-window.close()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Desktop_Widget_psutil_Dashboard.py b/DemoPrograms old/Demo_Desktop_Widget_psutil_Dashboard.py
deleted file mode 100644
index 3d1df605..00000000
--- a/DemoPrograms old/Demo_Desktop_Widget_psutil_Dashboard.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import psutil
-
-"""
- Desktop floating widget - System status dashboard
- Uses psutil to display:
- Network I/O
- Disk I/O
- CPU Used
- Mem Used
- Information is updated once a second and is shown as an area graph that scrolls
-"""
-
-GRAPH_WIDTH = 120 # each individual graph size in pixels
-GRAPH_HEIGHT = 40
-ALPHA = .7
-
-class DashGraph(object):
- def __init__(self, graph_elem, starting_count, color):
- self.graph_current_item = 0
- self.graph_elem = graph_elem
- self.prev_value = starting_count
- self.max_sent = 1
- self.color = color
-
- def graph_value(self, current_value):
- delta = current_value - self.prev_value
- self.prev_value = current_value
- self.max_sent = max(self.max_sent, delta)
- percent_sent = 100 * delta / self.max_sent
- self.graph_elem.DrawLine((self.graph_current_item, 0), (self.graph_current_item, percent_sent), color=self.color)
- if self.graph_current_item >= GRAPH_WIDTH:
- self.graph_elem.Move(-1,0)
- else:
- self.graph_current_item += 1
- return delta
-
- def graph_percentage_abs(self, value):
- self.graph_elem.DrawLine((self.graph_current_item, 0), (self.graph_current_item, value), color=self.color)
- if self.graph_current_item >= GRAPH_WIDTH:
- self.graph_elem.Move(-1,0)
- else:
- self.graph_current_item += 1
-
-
-def human_size(bytes, units=[' bytes','KB','MB','GB','TB', 'PB', 'EB']):
- """ Returns a human readable string reprentation of bytes"""
- return str(bytes) + units[0] if bytes < 1024 else human_size(bytes>>10, units[1:])
-
-def main():
- # Make the layout less cluttered and allow bulk-changes to text formatting
- def Txt(text, **kwargs):
- return(sg.Text(text, font=('Helvetica 8'), **kwargs))
- # Update a Text Element
- def Txt_Update(window, key, value):
- window.FindElement(key).Update(value)
-
- # ---------------- Create Window ----------------
- sg.ChangeLookAndFeel('Black')
- sg.SetOptions(element_padding=(0,0), margins=(1,1), border_width=0)
-
- def GraphColumn(name, key):
- col = sg.Column([[Txt(name, key=key+'TXT_'), ],
- [sg.Graph((GRAPH_WIDTH, GRAPH_HEIGHT), (0, 0), (GRAPH_WIDTH, 100), background_color='black',
- key=key+'GRAPH_')]], pad=(2, 2))
- return col
-
- layout = [[sg.Text('System Status Dashboard'+' '*18), sg.Button('', image_data=red_x, button_color=('black', 'black'), key='Exit', tooltip='Closes window')],
- [GraphColumn('Net Out', '_NET_OUT_'),
- GraphColumn('Net In', '_NET_IN_')],
- [GraphColumn('Disk Read', '_DISK_READ_'),
- GraphColumn('Disk Write', '_DISK_WRITE_')],
- [GraphColumn('CPU Usage', '_CPU_'),
- GraphColumn('Memory Usage', '_MEM_')],]
-
- window = sg.Window('PSG System Dashboard',
- keep_on_top=True,
- auto_size_buttons=False,
- grab_anywhere=True,
- no_titlebar=True,
- default_button_element_size=(12, 1),
- return_keyboard_events=True,
- alpha_channel=ALPHA,
- use_default_focus=False,
- ).Layout(layout).Finalize()
-
- # setup graphs & initial values
- netio = psutil.net_io_counters()
- net_graph_in = DashGraph(window.FindElement('_NET_IN_GRAPH_'), netio.bytes_recv, '#23a0a0')
- net_graph_out = DashGraph(window.FindElement('_NET_OUT_GRAPH_'), netio.bytes_sent, '#56d856')
-
-
- diskio = psutil.disk_io_counters()
- disk_graph_write = DashGraph(window.FindElement('_DISK_WRITE_GRAPH_'), diskio.write_bytes, '#be45be')
- disk_graph_read = DashGraph(window.FindElement('_DISK_READ_GRAPH_'), diskio.read_bytes, '#5681d8')
-
- cpu_usage_graph = DashGraph(window.FindElement('_CPU_GRAPH_'), 0, '#d34545')
- mem_usage_graph = DashGraph(window.FindElement('_MEM_GRAPH_'), 0, '#BE7C29')
-
- print(psutil.cpu_percent(percpu=True))
- # ---------------- main loop ----------------
- while (True):
- # --------- Read and update window once a second--------
- event, values = window.Read(timeout=1000)
- if event in (None, 'Exit'): # Be nice and give an exit, expecially since there is no titlebar
- break
- # ----- Network Graphs -----
- netio = psutil.net_io_counters()
- write_bytes = net_graph_out.graph_value(netio.bytes_sent)
- read_bytes = net_graph_in.graph_value(netio.bytes_recv)
- Txt_Update(window, '_NET_OUT_TXT_', 'Net out {}'.format(human_size(write_bytes)))
- Txt_Update(window, '_NET_IN_TXT_', 'Net In {}'.format(human_size(read_bytes)))
- # ----- Disk Graphs -----
- diskio = psutil.disk_io_counters()
- write_bytes = disk_graph_write.graph_value(diskio.write_bytes)
- read_bytes = disk_graph_read.graph_value(diskio.read_bytes)
- Txt_Update(window, '_DISK_WRITE_TXT_', 'Disk Write {}'.format(human_size(write_bytes)))
- Txt_Update(window, '_DISK_READ_TXT_', 'Disk Read {}'.format(human_size(read_bytes)))
- # ----- CPU Graph -----
- cpu = psutil.cpu_percent(0)
- cpu_usage_graph.graph_percentage_abs(cpu)
- Txt_Update(window, '_CPU_TXT_', '{0:2.0f}% CPU Used'.format(cpu))
- # ----- Memory Graph -----
- mem_used = psutil.virtual_memory().percent
- mem_usage_graph.graph_percentage_abs(mem_used)
- Txt_Update(window, '_MEM_TXT_', '{}% Memory Used'.format(mem_used))
-
-if __name__ == "__main__":
- # the clever Red X graphic
- red_x = "R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
-
- main()
- sys.exit(69)
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Disable_Elements.py b/DemoPrograms old/Demo_Disable_Elements.py
deleted file mode 100644
index 4f4f7778..00000000
--- a/DemoPrograms old/Demo_Disable_Elements.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-import sys
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-sg.ChangeLookAndFeel('Dark')
-sg.SetOptions(element_padding=(0, 0))
-
-layout = [
- [sg.T('Notes:', pad=((3, 0), 0)), sg.In(size=(44, 1), background_color='white', text_color='black', key='notes')],
- [sg.T('Output:', pad=((3, 0), 0)), sg.T('', size=(44, 1), text_color='white', key='output')],
- [sg.CBox('Checkbox:', default=True, pad=((3, 0), 0), disabled=True, key='cbox'), sg.Listbox((1,2,3,4),size=(8,3),disabled=True, key='listbox'),
- sg.Radio('Radio 1', default=True, group_id='1', disabled=True, key='radio1'), sg.Radio('Radio 2', default=False, group_id='1', disabled=True, key='radio2')],
- [sg.Spin((1,2,3,4),1,disabled=True, key='spin'), sg.OptionMenu((1,2,3,4),disabled=True, key='option'), sg.Combo(values=(1,2,3,4),disabled=True,key='combo')],
- [sg.Multiline('Multiline', size=(20,3),disabled=True, key='multi')],
- [sg.Slider((1,10), size=(20,20), orientation='h', disabled=True, key='slider')],
- [sg.Button('Enable', button_color=('white', 'black')),
- sg.Button('Disable', button_color=('white', 'black')),
- sg.Button('Reset', button_color=('white', '#9B0023'), key='reset'),
- sg.Button('Values', button_color=('white', 'springgreen4')),
- sg.Button('Exit', disabled=True, button_color=('white', '#00406B'), key='exit')]]
-
-window = sg.Window("Disable Elements Demo", default_element_size=(12, 1), text_justification='r', auto_size_text=False,
- auto_size_buttons=False, keep_on_top=True, grab_anywhere=False,
- default_button_element_size=(12, 1)).Layout(layout).Finalize()
-
-key_list = 'cbox', 'listbox', 'radio1', 'radio2', 'spin', 'option', 'combo', 'reset', 'notes', 'multi', 'slider', 'exit'
-
-for key in key_list: window.FindElement(key).Update(disabled=True) # don't do this kind of for-loop
-
-while True:
- event, values = window.Read()
- if event in (None, 'exit'):
- break
- elif event == 'Disable':
- for key in key_list: window.FindElement(key).Update(disabled=True)
- elif event == 'Enable':
- for key in key_list: window.FindElement(key).Update(disabled=False)
- elif event == 'Values':
- sg.Popup(values, keep_on_top=True)
-
-sys.exit(0)
diff --git a/DemoPrograms old/Demo_DuplicateFileFinder.py b/DemoPrograms old/Demo_DuplicateFileFinder.py
deleted file mode 100644
index 7e7045c6..00000000
--- a/DemoPrograms old/Demo_DuplicateFileFinder.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-import sys
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import hashlib
-import os
-
-
-# ====____====____==== FUNCTION DeDuplicate_folder(path) ====____====____==== #
-# Function to de-duplicate the folder passed in #
-# --------------------------------------------------------------------------- #
-def FindDuplicatesFilesInFolder(path):
- shatab = []
- total = 0
- small_count, dup_count, error_count = 0,0,0
- pngdir = path
- if not os.path.exists(path):
- sg.Popup('Duplicate Finder', '** Folder doesn\'t exist***', path)
- return
- pngfiles = os.listdir(pngdir)
- total_files = len(pngfiles)
- for idx, f in enumerate(pngfiles):
- if not sg.OneLineProgressMeter('Counting Duplicates', idx + 1, total_files, 'Counting Duplicate Files'):
- break
- total += 1
- fname = os.path.join(pngdir, f)
- if os.path.isdir(fname):
- continue
- x = open(fname, "rb").read()
-
- m = hashlib.sha256()
- m.update(x)
- f_sha = m.digest()
- if f_sha in shatab:
- # uncomment next line to remove duplicate files
- # os.remove(fname)
- dup_count += 1
- # sg.Print(f'Duplicate file - {f}') # cannot current use sg.Print with Progress Meter
- continue
- shatab.append(f_sha)
-
- msg = '{} Files processed\n {} Duplicates found'.format(total_files, dup_count)
- sg.Popup('Duplicate Finder Ended', msg)
-
-# ====____====____==== Pseudo-MAIN program ====____====____==== #
-# This is our main-alike piece of code #
-# + Starts up the GUI #
-# + Gets values from GUI #
-# + Runs DeDupe_folder based on GUI inputs #
-# ------------------------------------------------------------- #
-if __name__ == '__main__':
-
- source_folder = None
- source_folder = sg.PopupGetFolder('Duplicate Finder - Count number of duplicate files', 'Enter path to folder you wish to find duplicates in')
- if source_folder is not None:
- FindDuplicatesFilesInFolder(source_folder)
- else:
- sg.PopupCancel('Cancelling', '*** Cancelling ***')
- exit(0)
diff --git a/DemoPrograms old/Demo_EXE_Maker.py b/DemoPrograms old/Demo_EXE_Maker.py
deleted file mode 100644
index 9d751c6f..00000000
--- a/DemoPrograms old/Demo_EXE_Maker.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import PySimpleGUI as sg
-import subprocess
-from shutil import copyfile
-import shutil
-import os
-
-def Launcher():
- sg.ChangeLookAndFeel('LightGreen')
-
- layout = [[sg.T('PyInstaller EXE Creator', font='Any 15')],
- [sg.T('Source Python File'), sg.In(key='_sourcefile_', size=(45,1)), sg.FileBrowse(file_types=(("Python Files", "*.py"),))],
- [sg.T('Icon File'), sg.In(key='_iconfile_', size=(45,1)), sg.FileBrowse(file_types=(("Icon Files", "*.ico"),))],
- [sg.Frame('Output', font='Any 15',layout= [[sg.Output(size=(65, 15), font='Courier 10')]])],
- [sg.ReadFormButton('Make EXE',bind_return_key=True),
- sg.SimpleButton('Quit', button_color=('white','firebrick3')),]]
-
- window = sg.Window('PySimpleGUI EXE Maker',
- auto_size_text=False,
- auto_size_buttons=False,
- default_element_size=(20,1,),
- text_justification='right')
-
- window.Layout(layout)
-
- # ---===--- Loop taking in user input --- #
- while True:
- (button, values) = window.Read()
- if button in ('Quit', None):
- break # exit button clicked
-
- source_file = values['_sourcefile_']
- icon_file = values['_iconfile_']
-
- icon_option = '-i "{}"'.format(icon_file) if icon_file else ''
- source_path, source_filename = os.path.split(source_file)
- workpath_option = '--workpath "{}"'.format(source_path)
- dispath_option = '--distpath "{}"'.format(source_path)
- specpath_option = '--specpath "{}"'.format(source_path)
- folder_to_remove = os.path.join(source_path,source_filename[:-3])
- file_to_remove = os.path.join(source_path, source_filename[:-3]+'.spec')
- command_line = 'pyinstaller -wF "{}" {} {} {} {}'.format(source_file, icon_option, workpath_option, dispath_option, specpath_option)
-
- if button == 'Make EXE':
- try:
- print(command_line)
- print('Making EXE... this will take a while.. the program has NOT locked up...')
- window.Refresh()
- # print('Running command {}'.format(command_line))
- runCommand(command_line)
- shutil.rmtree(folder_to_remove)
- os.remove(file_to_remove)
- print('**** DONE ****')
- except:
- sg.PopupError('Something went wrong')
-
-
-def runCommand(cmd, timeout=None):
- """ run shell command
-
- @param cmd: command to execute
- @param timeout: timeout for command execution
-
- @return: (return code from command, command output)
- """
- p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- output = ''
-
- out, err = p.communicate()
- p.wait(timeout)
-
- return (out, err)
-
-if __name__ == '__main__':
- Launcher()
-
diff --git a/DemoPrograms old/Demo_Event_Callback_Simulation.py b/DemoPrograms old/Demo_Event_Callback_Simulation.py
deleted file mode 100644
index d3642368..00000000
--- a/DemoPrograms old/Demo_Event_Callback_Simulation.py
+++ /dev/null
@@ -1,53 +0,0 @@
-import PySimpleGUI as sg
-# import PySimpleGUIQt as sg
-# import PySimpleGUIWx as sg
-
-'''
- Event Callback Simulation
-
- This design pattern simulates callbacks for events.
- This is NOT the "normal" way things work in PySimpleGUI and is an architecture that is actively discouraged
- Unlike tkinter, Qt, etc, PySimpleGUI does not utilize callback
- functions as a mechanism for communicating when button presses or other events happen.
- BUT, should you want to quickly convert some existing code that does use callback functions, then this
- is one way to do a "quick and dirty" port to PySimpleGUI.
-'''
-
-# The callback functions
-# These callbacks all display a message in a non-blocking way and immediately return
-def button1(event, values):
- sg.popup_quick_message('Button 1 callback', background_color='red', text_color='white')
-
-def button2(event, values):
- sg.popup_quick_message('Button 2 callback', background_color='green', text_color='white')
-
-def catch_all(event, values):
- sg.popup_quick_message(f'An unplanned event = "{event}" happend', background_color='blue', text_color='white', auto_close_duration=6)
-
-# Lookup dictionary that maps event to function to call. In this case, only 2 event have defined callbacks
-func_dict = {'1':button1, '2':button2}
-
-# Layout the design of the GUI
-layout = [[sg.Text('Please click a button')],
- [sg.Button('1'), sg.Button('2'), sg.Button('Not defined', key='-MY-KEY-'), sg.Quit()]]
-
-# Show the Window to the user
-window = sg.Window('Button callback example', layout)
-
-# Event loop. Read buttons, make callbacks
-while True:
- # Read the Window
- event, values = window.read()
- # Lookup event in function dictionary and call the function, passing in the event and values variables
- try:
- func_dict[event](event, values) # Call function with event and values
- except:
- catch_all(event, values)
- # See if should close the window
- if event in ('Quit', None): # normally this is done IMMEDIATELY after the read
- break
-
-window.close()
-
-# All done!
-sg.popup_auto_close('Done... this window auto closes')
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Fill_Form.py b/DemoPrograms old/Demo_Fill_Form.py
deleted file mode 100644
index 08e24929..00000000
--- a/DemoPrograms old/Demo_Fill_Form.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-import sys
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-def Everything():
- sg.ChangeLookAndFeel('TanBlue')
-
- column1 = [
- [sg.Text('Column 1', background_color=sg.DEFAULT_BACKGROUND_COLOR, justification='center', size=(10, 1))],
- [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1', key='spin1')],
- [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
- [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3', key='spin3')]]
-
- layout = [
- [sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25))],
- [sg.Text('Here is some text.... and a place to enter text')],
- [sg.InputText('This is my text', key='in1', do_not_clear=True)],
- [sg.Checkbox('Checkbox', key='cb1'), sg.Checkbox('My second checkbox!', key='cb2', default=True)],
- [sg.Radio('My first Radio! ', "RADIO1", key='rad1', default=True),
- sg.Radio('My second Radio!', "RADIO1", key='rad2')],
- [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3),
- key='multi1', do_not_clear=True),
- sg.Multiline(default_text='A second multi-line', size=(35, 3), key='multi2', do_not_clear=True)],
- [sg.InputCombo(('Combobox 1', 'Combobox 2'), key='combo', size=(20, 1)),
- sg.Slider(range=(1, 100), orientation='h', size=(34, 20), key='slide1', default_value=85)],
- [sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'), key='optionmenu')],
- [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3), key='listbox'),
- sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25, key='slide2', ),
- sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75, key='slide3', ),
- sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10, key='slide4'),
- sg.Column(column1, background_color='gray34')],
- [sg.Text('_' * 80)],
- [sg.Text('Choose A Folder', size=(35, 1))],
- [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'),
- sg.InputText('Default Folder', key='folder', do_not_clear=True), sg.FolderBrowse()],
- [sg.Button('Exit'),
- sg.Text(' ' * 40), sg.Button('SaveSettings'), sg.Button('LoadSettings')]
- ]
-
- window = sg.Window('Form Fill Demonstration', default_element_size=(40, 1), grab_anywhere=False)
- # button, values = window.LayoutAndRead(layout, non_blocking=True)
- window.Layout(layout)
-
- while True:
- event, values = window.Read()
-
- if event == 'SaveSettings':
- filename = sg.PopupGetFile('Save Settings', save_as=True, no_window=True)
- window.SaveToDisk(filename)
- # save(values)
- elif event == 'LoadSettings':
- filename = sg.PopupGetFile('Load Settings', no_window=True)
- window.LoadFromDisk(filename)
- # load(form)
- elif event in ('Exit', None):
- break
-
- # window.CloseNonBlocking()
-
-
-if __name__ == '__main__':
- Everything()
diff --git a/DemoPrograms old/Demo_Floating_Toolbar.py b/DemoPrograms old/Demo_Floating_Toolbar.py
deleted file mode 100644
index 14312f6a..00000000
--- a/DemoPrograms old/Demo_Floating_Toolbar.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import PySimpleGUI as sg
-import sys
-
-button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer')
-
-house64='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'
-
-cpu64='iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAAFzElEQVRYhc1XX2wTdRz/lLv+uV7btbTbXdeyAHZX2g0uTiADM5SbhGgfwOiDIip7MUFf9EEU45MmgJj4gPLAgwHFaGJMTIybIYYRIhH5E93JuuHqssGutKNd73psd2vXrj7QQoO0yOa/T3LJ3fff53P5fe/3+x5wD3Act0cQhGi1LRKJXA8EAj2V52AwuCsSiVyvjhEEIcpx3Ov3qr/kXgH/NOoKcDgcrQ6HgydJ0uX1ersBwO/3PwGAamhoWEfTdAtN0y12u309AKrsA8uy3SRJuhoaGniHw9G6YAEMw2xnGGaH0Wj0hkKhQwDA8/wxADaWZXe7XC7B5XIJDMPsBmAr+xAOhw8ZjUZvU1PTcyzLbq/HYajnpChqmdVqfQAAisXijKIoF9xu98MAjAAwPT19GQBsNtuqckp+amrqR6fTuY4gCBoANE0b1XV9YkECnE5nyOPxPGIwGCz14mqhVCrNptPp04qiDN+3gHA4/MaKFSv2YfGNOj82NvbW0NDQe3UFOByOAMMwT09OTn5BkqRzw4YNv+Tz+YnR0dF38/l8GgDsdnvrypUrDy5AROns2bMPFgoFhWGYZycnJ79SVfV3ACBbW1vfBACn07m6qalph6Zp561WawcAw+Dg4AuJROI0ABgMBsP69es/WwA5ABjcbvcWTdN+5jhuv9PpXK0oyiUAIJctW/YiAJAk6bwVXV7z6rVrb29/x+Px7FigAFT3kcvlEux2ewcAkP39/SEA8Hq9QigUOlwsFrWqvBIABAKBnpaWlrcXSl5BsVjUdF2/PDQ09HIymTwFAGTFmUgk+hOJRAgAHA7HYxV7c3NzdzAYPLJYcgBIJpM/JZPJULWNqNz4/f6tXV1dZzRNO2cymZa73W6hVCqlgsHgR0uWLLEuljyTyZyyWCzzmzZtOqfr+qCqqqMAQEYikUQ5xgrAAcBUSbqj43OZTKbPZDJ5bDZbl67r45qmjVssFhtN0w/Nzc1NAABBEM65ublxs9m85i46TABYnue/5HleAwBSFMW9AODxeNb6fL5Xar3B4OBgj6qq0VwuN9nW1nYgm82Op9PpPoIgKI/Hs65QKBAA5t1u9+OxWOy1zs5OsVateDx+PJ1OXwQAUpKkYwAgy/LJdDp9UZblYZqmN96ZlEqlfli7du2nJEk2z8/P57PZ7DjDMBtomm69du1aH03Tq2sRViDL8rAoij2ZTOakpmkTwH3scgaDAaVSCajavOLx+HeZTGYgHA5/ULbPl6+/XJf0+/27gNtLMDAw0H23QI/H0xWNRl+dnZ1NtbW17QMAhmG2chz3IQA0NjZuHhgY2JlKpb5lWXbb3Wq4XK4Qz/NH4/H44VtLwPP8/rK/bqe3t7cfrW5Cu90+DmCuqvjWjRs3ns3n81Pl+aAmfD7f8z6f7ykAIHt7e73Azc+wfJ7na+SZly5d+mTlgaKo5X8KMJsDZrM5UIc7DyApiuIuSZJOAFUbkSRJJyRJ8gIAx3GP1nuDhSIej5+Jx+PeatutZvF6vYIgCMMsy3b+E+QAwLJsZ5ljc8VGCoIwDNw8jIxGI0sQxKJ3vVogCMJKUdSqNWvWfB4OhxUAICcmJj4Bbh/HwM1J5u8mr64py3L/reM4FosdAG4OJIqiXLpx48aopmlTHMeVcI+R7X740+n098ViURkZGdlbPZD8f0ayu+HfGErJWg4AyOVy07IsXwYWPpbncrnpehx1Bfj9/mc4jjsIALquD/X397d1dnZ+DaARAERR7AEAnuePllNSvb29TR0dHccoigoDQCwW2zMyMvJ+LQ6ilgMACoVCiqKopSaTqTEajb40PT09put6lGXZbYlE4mNJko7Pzs6OWSwWi81mC4miuFNV1Ziu6781NjZumZqa+ubKlStHcrlcphZH3QZTVTWmKIpYKBTkRCJxEgAkSeoDoGez2fMzMzNXZ2Zmrmaz2QsA9LIPyWTyZKFQkBVF+VVV1Vg9jv/87/gP2fZ5DF1CS4UAAAAASUVORK5CYII='
-
-timer64='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'
-
-close64 = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEQ0lEQVR42r2XW2wbRRSG/1177TgkdkyoS4shaaWogVIKRAXUVn4BgRBEIRBSkSK1lAakPhTxABJSK6BEtAoXCUHEWwWi4oEXUAVvRUASSBuJliAh5QJp6hrspoGQi69r73LO7Npu6kvsBGek0ezOrvf79szsmbG0D2iwAN8DaMQaFA0YHQFaLwCX6TQuHQAuNtjR2PawD05LZeFzKeC7b/txPoLxU8Aj1BVkAf1wqw/uejeU9RsASaqYQGp+Dv8EAvjgdD9OAg9S14gQOPKED1XNWyv7+lT0VArxiVH0fCUEOqjr3JoKcImN/pYW2EOnQyUJTESBJkdpgGkV8Cj/owDDdx59A8Mf92FT+GpR+KSlBrt6ehE6+hL0pLp6AYbvfusE5FontFgUZ989UVAiDU+X0OsvQ0/EVy4g4MeOQ3a6Mn38wKHet3MkrofzZJMsFlzpeRVaeLF8ASPsb8Javy7nDXRVxdA7x7FpIZQXnrlP0yDJMoKvHVpZBKq23Qv3M8/nzQt6PIah93qhRxaLwvPNhbLmgGP7Drg694mHlVqKwcsWEBItD8DVvleM6WrhRQXUwBSsnpthvclDY++BZLdnflS9YxecrZ2QFGVZePDIYcq5yWuGK47k39NIzlCdDkHxNuYXiJzrz/xIrr4BFpdbfAFyTS1CSi1uf7IDrqeeheyoLihxubsD2sI8UuEFaItUKfen5mahRcLZl7nft7xAvjIQs+GFP2cLCmjRCL5p3oDN6nzR56xIYDl4ORJlCwyqDnT7Z5aFL5G4w4vN8dnVCwymatA9daVkeCkSJQv8qDtxcDKYF86AwKEuSDYbvB+doq/DlnMPJ6uvmzfmSJQk0E9D+OLVcEG4f38bwgNnxLmz9Wl4+z6HZLXm3JuYHMfE7i0ri8Ck3Y3Hx4L0lvYl8Et7H0Xk7NJ7Xe1d8H74GX2/2YyZmv8XY3euo4SUXJkAFyvtEbdc+CsDn2r3Ifrrz3nHvW7Pftzy/kmxdhSCly2Qlmj66Xf88dB2qP6LRme+jauuo67rIDyvHMN4i1esmvlK6QIUTrEISbKxDnDlPkk2BK6VIDhXXaddP6Vk0H6A9wSUn0WKFn2lCgiYbDEmFVXJYjWOuU1LcHudgAASSLS0FnD4dV4TksYxNEOqsMDwgAAxELToSFZFfGaiVWzGNV6MWM4Uyc5OE8wQCr2AqwmxIuoJowX3k5CjZSd6vvxhqcBj921Fc2g8C2Mwzf5sax7zNZZjSdkcCg6/EEgacAYzlLZvRk1kW7rm39iELwZHsgLPATN311rqb7trG+65dT2FXTEg4o1NoDinZKOYQ8ICFo4ADwMJpEwBDrnKIU+YMqZQ0pAbC4QwODwCf0Rd/BQ4IATagM46oI+CeiNPPVS40EDF6M/pJ78Ap+n0PL8Cp7sGs9asgQSFDLxBmKJ6STKBVSbcZsa10gKcJHi/Hv0PWqbBbaFH/AEAAAAASUVORK5CYII='
-
-
-def main():
-
- toolbar_buttons = [[sg.Button('', image_data=close64,button_color=('white', 'black'), pad=(0,0), key='-CLOSE-'),
- sg.Button('', image_data=timer64, button_color=('white', 'black'), pad=(0, 0), key='-TIMER-'),
- sg.Button('', image_data=house64, button_color=('white', 'black'), pad=(0, 0), key='-HOUSE-'),
- sg.Button('', image_data=cpu64, button_color=('white', 'black'), pad=(0,0), key='-CPU-'),]]
-
- # layout = toolbar_buttons
- layout = [[sg.Column( toolbar_buttons, background_color='black')]]
-
- window = sg.Window('Toolbar', layout, no_titlebar=True, grab_anywhere=True, background_color='black', margins=(0,0))
-
- # ---===--- Loop taking in user input --- #
- while True:
- button, value = window.read()
- print(button)
- if button == '-CLOSE-' or button is None:
- break # exit button clicked
- elif button == '-TIMER-':
- print('Timer Button') # add your call to launch a timer program
- elif button == '-CPU-':
- print('CPU Button') # add your call to launch a CPU measuring utility
- elif button == '-HOUSE-':
- print('Home Button')
-
- window.close()
-
-if __name__ == '__main__':
- main()
-
diff --git a/DemoPrograms old/Demo_Font_Previewer.py b/DemoPrograms old/Demo_Font_Previewer.py
deleted file mode 100644
index 1c7eeb63..00000000
--- a/DemoPrograms old/Demo_Font_Previewer.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-from tkinter import font
-import tkinter
-root = tkinter.Tk()
-fonts = list(font.families())
-fonts.sort()
-root.destroy()
-
-sg.ChangeLookAndFeel('Black')
-
-layout = [[ sg.Text('My Text Element',
- size=(20,1),
- auto_size_text=False,
- click_submits=True,
- relief=sg.RELIEF_GROOVE,
- font = 'Courier` 25',
- text_color='#FF0000',
- background_color='white',
- justification='center',
- pad=(5,3),
- key='_text_',
- tooltip='This is a text element',
- ) ],
- [sg.Listbox(fonts, size=(30,20), change_submits=True, key='_list_')],
- [sg.Input(key='_in_')],
- [ sg.Button('Read', bind_return_key=True), sg.Exit()]]
-
-window = sg.Window('My new window',
- # grab_anywhere=True,
- # force_toplevel=True,
- ).Layout(layout)
-
-
-while True: # Event Loop
- event, values = window.Read()
- if event is None or event == 'Exit':
- break
- text_elem = window.FindElement('_text_')
- print(event, values)
- if values['_in_'] != '':
- text_elem.Update(font=values['_in_'])
- else:
- text_elem.Update(font=(values['_list_'][0], 25))
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Font_Sizer.py b/DemoPrograms old/Demo_Font_Sizer.py
deleted file mode 100644
index 7050160e..00000000
--- a/DemoPrograms old/Demo_Font_Sizer.py
+++ /dev/null
@@ -1,30 +0,0 @@
-
-# Testing async form, see if can have a slider
-# that adjusts the size of text displayed
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-fontSize = 12
-layout = [[sg.Spin([sz for sz in range(6, 172)], font=('Helvetica 20'), initial_value=fontSize, change_submits=True, key='spin'),
- sg.Slider(range=(6,172), orientation='h', size=(10,20), change_submits=True, key='slider', font=('Helvetica 20')), sg.Text("Aa", size=(2, 1), font="Helvetica " + str(fontSize), key='text')]]
-sz = fontSize
-window = sg.Window("Font size selector", grab_anywhere=False)
-window.Layout(layout)
-while True:
- event, values= window.Read()
- if event is None or event == 'Quit':
- break
- sz_spin = int(values['spin'])
- sz_slider = int(values['slider'])
- sz = sz_spin if sz_spin != fontSize else sz_slider
- if sz != fontSize:
- fontSize = sz
- font = "Helvetica " + str(fontSize)
- window.FindElement('text').Update(font=font)
- window.FindElement('slider').Update(sz)
- window.FindElement('spin').Update(sz)
-
-print("Done.")
diff --git a/DemoPrograms old/Demo_Font_String.py b/DemoPrograms old/Demo_Font_String.py
deleted file mode 100644
index b97c0f67..00000000
--- a/DemoPrograms old/Demo_Font_String.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [[sg.Text('This is my sample text',size=(20,1), key='_text_') ],
- [sg.CB('Bold', key='_bold_', change_submits=True),
- sg.CB('Italics', key='_italics_', change_submits=True),
- sg.CB('Underline', key='_underline_', change_submits=True)],
- [sg.Slider((6,50), default_value=12, size=(14,20), orientation='h', key='_slider_', change_submits=True),
- sg.Text('Font size')],
- [sg.Text('Font string = '), sg.Text('', size=(25,1), key='_fontstring_')],
- [ sg.Button('Exit')]]
-
-window = sg.Window('Font string builder').Layout(layout)
-
-text_elem = window.FindElement('_text_')
-while True: # Event Loop
- event, values = window.Read()
- if event in (None, 'Exit'):
- break
- font_string = 'Helvitica '
- font_string += str(values['_slider_'])
- if values['_bold_']:
- font_string += ' bold'
- if values['_italics_']:
- font_string += ' italic'
- if values['_underline_']:
- font_string += ' underline'
- text_elem.Update(font=font_string)
- window.FindElement('_fontstring_').Update('"'+font_string+'"')
- print(event, values)
diff --git a/DemoPrograms old/Demo_GoodColors.py b/DemoPrograms old/Demo_GoodColors.py
deleted file mode 100644
index 8ea1ba9c..00000000
--- a/DemoPrograms old/Demo_GoodColors.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-def main():
- # ------- Make a new Window ------- #
- window = sg.Window('GoodColors', auto_size_text=True, default_element_size=(30,2))
- window.AddRow(sg.Text('Having trouble picking good colors? Try one of the colors defined by PySimpleGUI'))
- window.AddRow(sg.Text('Here come the good colors as defined by PySimpleGUI'))
-
- #===== Show some nice BLUE colors with yellow text ===== ===== ===== ===== ===== ===== =====#
- text_color = sg.YELLOWS[0]
- buttons = (sg.Button('BLUES[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.BLUES))
- window.AddRow(sg.T('Button Colors Using PySimpleGUI.BLUES'))
- window.AddRow(*buttons)
- window.AddRow(sg.Text('_' * 100, size=(65, 1)))
-
- #===== Show some nice PURPLE colors with yellow text ===== ===== ===== ===== ===== ===== =====#
- buttons = (sg.Button('PURPLES[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.PURPLES))
- window.AddRow(sg.T('Button Colors Using PySimpleGUI.PURPLES'))
- window.AddRow(*buttons)
- window.AddRow(sg.Text('_' * 100, size=(65, 1)))
-
- #===== Show some nice GREEN colors with yellow text ===== ===== ===== ===== ===== ===== =====#
- buttons = (sg.Button('GREENS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.GREENS))
- window.AddRow(sg.T('Button Colors Using PySimpleGUI.GREENS'))
- window.AddRow(*buttons)
- window.AddRow(sg.Text('_' * 100, size=(65, 1)))
-
- #===== Show some nice TAN colors with yellow text ===== ===== ===== ===== ===== ===== =====#
- text_color = sg.GREENS[0] # let's use GREEN text on the tan
- buttons = (sg.Button('TANS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.TANS))
- window.AddRow(sg.T('Button Colors Using PySimpleGUI.TANS'))
- window.AddRow(*buttons)
- window.AddRow(sg.Text('_' * 100, size=(65, 1)))
-
- #===== Show some nice YELLOWS colors with black text ===== ===== ===== ===== ===== ===== =====#
- text_color = 'black' # let's use black text on the tan
- buttons = (sg.Button('YELLOWS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.YELLOWS))
- window.AddRow(sg.T('Button Colors Using PySimpleGUI.YELLOWS'))
- window.AddRow(*buttons)
- window.AddRow(sg.Text('_' * 100, size=(65, 1)))
-
-
- #===== Add a click me button for fun and SHOW the window ===== ===== ===== ===== ===== ===== =====#
- window.AddRow(sg.Button('Click ME!'))
- event, values = window.Read() # show it!
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Google_TTS.py b/DemoPrograms old/Demo_Google_TTS.py
deleted file mode 100644
index ee8557bb..00000000
--- a/DemoPrograms old/Demo_Google_TTS.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-from gtts import gTTS
-from pygame import mixer
-import time
-import os
-
-'''
- Simple demonstration of using Google Text to Speech
- Get a multi-line string
- Convert to speech
- Play back the speech
-
- Note that there are 2 temp files created. The program tries to delete them but will fail on one of them
-'''
-
-layout = [[sg.Text('What would you like me to say?')],
- [sg.Multiline(size=(60,10), enter_submits=True)],
- [sg.Button('Speak', bind_return_key=True), sg.Exit()]]
-
-window = sg.Window('Google Text to Speech').Layout(layout)
-
-i = 0
-mixer.init()
-while True:
- event, values = window.Read()
- if event is None or event == 'Exit':
- break
- # Get the text and convert to mp3 file
- tts = gTTS(text=values[0], lang='en',slow=False)
- tts.save('speech{}.mp3'.format(i%2))
- # playback the speech
- mixer.music.load('speech{}.mp3'.format(i%2))
- mixer.music.play()
- # wait for playback to end
- while mixer.music.get_busy():
- time.sleep(.1)
- mixer.stop()
- i += 1
-
-# try to remove the temp files. You'll likely be left with 1 to clean up
-try:
- os.remove('speech0.mp3')
-except:
- pass
-try:
- os.remove('speech1.mp3')
-except:
- pass
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Graph_Ball_Game.py b/DemoPrograms old/Demo_Graph_Ball_Game.py
deleted file mode 100644
index e1c3c642..00000000
--- a/DemoPrograms old/Demo_Graph_Ball_Game.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# import PySimpleGUIWeb as sg
-import PySimpleGUI as sg
-import pymunk
-import random
-import socket
-
-"""
- Demo that shows integrating PySimpleGUI with the pymunk library. This combination
- of PySimpleGUI and pymunk could be used to build games.
- Note this exact same demo runs with PySimpleGUIWeb by changing the import statement
-"""
-
-class Ball():
- def __init__(self, x, y, r, graph_elem, *args, **kwargs):
- mass = 10
- self.body = pymunk.Body(mass,
- pymunk.moment_for_circle(mass, 0, r, (0, 0))) # Create a Body with mass and moment
- self.body.position = x, y
- self.shape = pymunk.Circle(self.body, r, offset=(0, 0)) # Create a box shape and attach to body
- self.shape.elasticity = 0.99999
- self.shape.friction = 0.8
- self.gui_circle_figure = None
- self.graph_elem = graph_elem
-
- def move(self):
- self.graph_elem.RelocateFigure(self.gui_circle_figure, self.body.position[0], ball.body.position[1])
-
-
-
-class Playfield():
- def __init__(self, graph_elem):
- self.space = pymunk.Space()
- self.space.gravity = 0, 200
- self.add_wall((0, 400), (600, 400)) # ground
- self.add_wall((0, 0), (0, 600)) # Left side
- self.add_wall((600, 0), (600, 400)) # right side
- self.arena_balls = [] # type: [] Ball
- self.graph_elem = graph_elem # type: sg.Graph
-
-
- def add_wall(self, pt_from, pt_to):
- body = pymunk.Body(body_type=pymunk.Body.STATIC)
- ground_shape = pymunk.Segment(body, pt_from, pt_to, 0.0)
- ground_shape.friction = 0.8
- ground_shape.elasticity = .99
- self.space.add(ground_shape)
-
- def add_random_balls(self):
- for i in range(1, 200):
- x = random.randint(0, 600)
- y = random.randint(0, 400)
- r = random.randint(1, 10)
- self.add_ball(x,y,r)
-
- def add_ball(self, x, y, r, fill_color='black', line_color='red'):
- ball = Ball(x, y, r, self.graph_elem)
- self.arena_balls.append(ball)
- area.space.add(ball.body, ball.shape)
- ball.gui_circle_figure = self.graph_elem.DrawCircle((x, y), r, fill_color=fill_color, line_color=line_color)
- return ball
-
- def shoot_a_ball(self, x, y, r, vector=(-10, 0), fill_color='black', line_color='red'):
- ball = self.add_ball(x,y,r, fill_color=fill_color, line_color=line_color )
- # ball.shape.surface_velocity=10
- ball.body.apply_impulse_at_local_point(100*pymunk.Vec2d(vector))
-
-# ------------------- Build and show the GUI Window -------------------
-graph_elem = sg.Graph((600, 400), (0, 400), (600, 0), enable_events=True, key='_GRAPH_', background_color='lightblue')
-
-layout = [[sg.Text('Ball Test'), sg.T('My IP {}'.format(socket.gethostbyname(socket.gethostname())))],
- [graph_elem],
- [sg.B('Kick'), sg.B('Player 1 Shoot', size=(15,2)),sg.B('Player 2 Shoot', size=(15,2)), sg.Button('Exit')]]
-
-window = sg.Window('Window Title', layout, disable_close=True)
-
-area = Playfield(graph_elem)
-# area.add_random_balls()
-
-# ------------------- GUI Event Loop -------------------
-while True: # Event Loop
- event, values = window.Read(timeout=10)
- # print(event, values)
- if event in (None, 'Exit'):
- break
- area.space.step(0.01)
-
- if event == 'Player 2 Shoot':
- area.shoot_a_ball(555, 200, 5, (-10,0), fill_color='green', line_color='green')
- elif event == 'Player 1 Shoot':
- area.shoot_a_ball(10, 200, 5, (10,0))
-
- for ball in area.arena_balls:
- if event == 'Kick':
- ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(1,200)
- ball.move()
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Graph_Drag_Rectangle.py b/DemoPrograms old/Demo_Graph_Drag_Rectangle.py
deleted file mode 100644
index b23a795f..00000000
--- a/DemoPrograms old/Demo_Graph_Drag_Rectangle.py
+++ /dev/null
@@ -1,53 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Demo - Drag a rectangle to draw it
-
- This demo shows how to use a Graph Element to (optionally) display an image and then use the
- mouse to "drag a rectangle". This is sometimes called a rubber band and is an operation you
- see in things like editors
-"""
-
-
-# image_file = r'Color-names.png'
-image_file = None # image is optional
-
-layout = [[sg.Graph(
- canvas_size=(400, 400),
- graph_bottom_left=(0, 400),
- graph_top_right=(400, 0),
- key="-GRAPH-",
- change_submits=True, # mouse click events
- drag_submits=True),],
- [sg.Text("", key="info", size=(60, 1))]]
-
-window = sg.Window("draw rect on image", layout, finalize=True)
-# get the graph element for ease of use later
-graph = window["-GRAPH-"] # type: sg.Graph
-
-graph.DrawImage(image_file, location=(0,0)) if image_file else None
-dragging = False
-start_point = end_point = prior_rect = None
-
-while True:
- event, values = window.Read()
- if event is None:
- break # exit
- if event == "-GRAPH-": # if there's a "Graph" event, then it's a mouse
- x, y = values["-GRAPH-"]
- if not dragging:
- start_point = (x, y)
- dragging = True
- else:
- end_point = (x, y)
- if prior_rect:
- graph.DeleteFigure(prior_rect)
- if None not in (start_point, end_point):
- prior_rect = graph.DrawRectangle(start_point, end_point, line_color='red')
- elif event.endswith('+UP'): # The drawing has ended because mouse up
- info = window.Element("info")
- info.Update(value=f"grabbed rectangle from {start_point} to {end_point}")
- start_point, end_point = None, None # enable grabbing a new rect
- dragging = False
- else:
- print("unhandled event", event, values)
diff --git a/DemoPrograms old/Demo_Graph_Drawing.py b/DemoPrograms old/Demo_Graph_Drawing.py
deleted file mode 100644
index 8c11ced1..00000000
--- a/DemoPrograms old/Demo_Graph_Drawing.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(0,0), graph_top_right=(400, 400), background_color='red', key='graph')],
- [sg.T('Change circle color to:'), sg.Button('Red'), sg.Button('Blue'), sg.Button('Move')]]
-
-window = sg.Window('Graph test').Layout(layout).Finalize()
-
-graph = window.FindElement('graph')
-circle =graph .DrawCircle((75,75), 25, fill_color='black',line_color='white')
-point = graph.DrawPoint((75,75), 10, color='green')
-oval = graph.DrawOval((25,300), (100,280), fill_color='purple', line_color='purple' )
-rectangle = graph.DrawRectangle((25,300), (100,280), line_color='purple' )
-line = graph.DrawLine((0,0), (100,100))
-arc = graph.DrawArc((0,0), (400,400), 160, 10, style='arc' ,arc_color='blue')
-while True:
- event, values = window.Read()
- if event is None:
- break
- if event in ('Blue', 'Red'):
- graph.TKCanvas.itemconfig(circle, fill=event)
- elif event == 'Move':
- graph.MoveFigure(point, 10,10)
- graph.MoveFigure(circle, 10,10)
- graph.MoveFigure(oval, 10,10)
- graph.MoveFigure(rectangle, 10,10)
- graph.MoveFigure(arc, 10,10)
diff --git a/DemoPrograms old/Demo_Graph_Element.py b/DemoPrograms old/Demo_Graph_Element.py
deleted file mode 100644
index 67f28ac5..00000000
--- a/DemoPrograms old/Demo_Graph_Element.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-import ping
-from threading import Thread
-import time
-
-
-STEP_SIZE=1
-SAMPLES = 1000
-CANVAS_SIZE = (1000,500)
-
-# globale used to communicate with thread.. yea yea... it's working fine
-g_exit = False
-g_response_time = None
-def ping_thread(args):
- global g_exit, g_response_time
- while not g_exit:
- g_response_time = ping.quiet_ping('google.com', timeout=1000)
-
-def main():
- global g_exit, g_response_time
-
- # start ping measurement thread
- thread = Thread(target=ping_thread, args=(None,))
- thread.start()
-
- sg.ChangeLookAndFeel('Black')
- sg.SetOptions(element_padding=(0,0))
-
- layout = [ [sg.T('Ping times to Google.com', font='Any 12'), sg.Quit(pad=((100,0), 0), button_color=('white', 'black'))],
- [sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,500),background_color='black', key='graph')],]
-
- window = sg.Window('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False).Layout(layout)
-
- graph = window.FindElement('graph')
-
- prev_response_time = None
- i=0
- prev_x, prev_y = 0, 0
- while True:
- event, values = window.Read(timeout=200)
- if event == 'Quit' or event is None:
- break
- if g_response_time is None or prev_response_time == g_response_time:
- continue
- new_x, new_y = i, g_response_time[0]
- prev_response_time = g_response_time
- if i >= SAMPLES:
- graph.Move(-STEP_SIZE,0)
- prev_x = prev_x - STEP_SIZE
- graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white')
- # window.FindElement('graph').DrawPoint((new_x, new_y), color='red')
- prev_x, prev_y = new_x, new_y
- i += STEP_SIZE if i < SAMPLES else 0
-
- # tell thread we're done. wait for thread to exit
- g_exit = True
- thread.join()
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Graph_Element_Bar_Chart.py b/DemoPrograms old/Demo_Graph_Element_Bar_Chart.py
deleted file mode 100644
index 276e4471..00000000
--- a/DemoPrograms old/Demo_Graph_Element_Bar_Chart.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import PySimpleGUI as sg
-import random
-
-BAR_WIDTH = 50
-BAR_SPACING = 75
-EDGE_OFFSET = 3
-GRAPH_SIZE = (500,500)
-DATA_SIZE = (500,500)
-
-graph = sg.Graph(GRAPH_SIZE, (0,0), DATA_SIZE)
-
-layout = [[sg.Text('Bar graphs using PySimpleGUI')],
- [graph],
- [sg.Button('OK')]]
-
-window = sg.Window('Window Title', layout)
-
-while True:
- event, values = window.Read()
- graph.Erase()
- if event is None:
- break
-
- for i in range(7):
- graph_value = random.randint(0, 400)
- graph.DrawRectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
- bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='blue')
- graph.DrawText(text=graph_value, location=(i*BAR_SPACING+EDGE_OFFSET+25, graph_value+10))
-window.Close()
diff --git a/DemoPrograms old/Demo_Graph_Element_Sine_Wave.py b/DemoPrograms old/Demo_Graph_Element_Sine_Wave.py
deleted file mode 100644
index dc2b7305..00000000
--- a/DemoPrograms old/Demo_Graph_Element_Sine_Wave.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# import PySimpleGUIWeb as sg
-# import PySimpleGUIQt as sg
-import PySimpleGUI as sg
-import math
-
-SIZE_X = 200
-SIZE_Y = 100
-NUMBER_MARKER_FREQUENCY = 25
-
-def draw_axis():
- graph.draw_line((-SIZE_X,0), (SIZE_X, 0)) # axis lines
- graph.draw_line((0,-SIZE_Y), (0,SIZE_Y))
-
- for x in range(-SIZE_X, SIZE_X+1, NUMBER_MARKER_FREQUENCY):
- graph.draw_line((x,-3), (x,3)) # tick marks
- if x != 0:
- graph.draw_text( str(x), (x,-10), color='green', font='Algerian 15') # numeric labels
-
- for y in range(-SIZE_Y, SIZE_Y+1, NUMBER_MARKER_FREQUENCY):
- graph.draw_line((-3,y), (3,y))
- if y != 0:
- graph.draw_text( str(y), (-10,y), color='blue')
-
-# Create the graph that will be put into the window
-graph = sg.Graph(canvas_size=(400, 400),
- graph_bottom_left=(-(SIZE_X+5), -(SIZE_Y+5)),
- graph_top_right=(SIZE_X+5, SIZE_Y+5),
- background_color='white',
- key='graph')
-# Window layout
-layout = [[sg.Text('Example of Using Math with a Graph', justification='center', size=(50,1), relief=sg.RELIEF_SUNKEN)],
- [graph],
- [sg.Text('y = sin(x / x2 * x1)', font='Algerian 18')],
- [sg.Text('x1'),sg.Slider((0,200), orientation='h', enable_events=True,key='_SLIDER_')],
- [sg.Text('x2'),sg.Slider((1,200), orientation='h', enable_events=True,key='_SLIDER2_')]]
-
-window = sg.Window('Graph of Sine Function', layout)
-
-while True:
- event, values = window.read()
- if event is None:
- break
- graph.erase()
- draw_axis()
- prev_x = prev_y = None
- for x in range(-SIZE_X,SIZE_X):
- y = math.sin(x/int(values['_SLIDER2_']))*int(values['_SLIDER_'])
- if prev_x is not None:
- graph.draw_line((prev_x, prev_y), (x,y), color='red')
- prev_x, prev_y = x, y
-
diff --git a/DemoPrograms old/Demo_Graph_Noise.py b/DemoPrograms old/Demo_Graph_Noise.py
deleted file mode 100644
index c1893514..00000000
--- a/DemoPrograms old/Demo_Graph_Noise.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-import random
-import sys
-
-STEP_SIZE=1
-SAMPLES = 300
-SAMPLE_MAX = 300
-CANVAS_SIZE = (300,300)
-
-
-def main():
- global g_exit, g_response_time
-
- layout = [[sg.T('Enter width, height of graph')],
- [sg.In(size=(6, 1)), sg.In(size=(6, 1))],
- [sg.Ok(), sg.Cancel()]]
-
- window = sg.Window('Enter graph size').Layout(layout)
- b,v = window.Read()
- if b is None or b == 'Cancel':
- sys.exit(69)
- w, h = int(v[0]), int(v[1])
- CANVAS_SIZE = (w,h)
-
- # start ping measurement thread
-
- sg.ChangeLookAndFeel('Black')
- sg.SetOptions(element_padding=(0,0))
-
- layout = [ [sg.Button('Quit', button_color=('white','black'))],
- [sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,SAMPLE_MAX),background_color='black', key='graph')],]
-
- window = sg.Window('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False).Layout(layout).Finalize()
- graph = window.FindElement('graph')
-
- prev_response_time = None
- i=0
- prev_x, prev_y = 0, 0
- graph_value = 250
- while True:
- # time.sleep(.2)
- event, values = window.Read(timeout=0)
- if event == 'Quit' or event is None:
- break
- graph_offset = random.randint(-10, 10)
- graph_value = graph_value + graph_offset
- if graph_value > SAMPLE_MAX:
- graph_value = SAMPLE_MAX
- if graph_value < 0:
- graph_value = 0
- new_x, new_y = i, graph_value
- prev_value = graph_value
- if i >= SAMPLES:
- graph.Move(-STEP_SIZE,0)
- prev_x = prev_x - STEP_SIZE
- graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white')
- # window.FindElement('graph').DrawPoint((new_x, new_y), color='red')
- prev_x, prev_y = new_x, new_y
- i += STEP_SIZE if i < SAMPLES else 0
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Graph__Element.py b/DemoPrograms old/Demo_Graph__Element.py
deleted file mode 100644
index 174ce1fb..00000000
--- a/DemoPrograms old/Demo_Graph__Element.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import ping
-from threading import Thread
-import time
-import PySimpleGUI as sg
-
-
-STEP_SIZE=1
-SAMPLES = 6000
-CANVAS_SIZE = (6000,500)
-
-# globale used to communicate with thread.. yea yea... it's working fine
-g_exit = False
-g_response_time = None
-def ping_thread(args):
- global g_exit, g_response_time
- while not g_exit:
- g_response_time = ping.quiet_ping('google.com', timeout=1000)
-
-def main():
- global g_exit, g_response_time
-
- # start ping measurement thread
- thread = Thread(target=ping_thread, args=(None,))
- thread.start()
-
- sg.ChangeLookAndFeel('Black')
- sg.SetOptions(element_padding=(0,0))
-
- layout = [ [sg.T('Ping times to Google.com', font='Any 12'), sg.Quit(pad=((100,0), 0), button_color=('white', 'black'))],
- [sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,500),background_color='black', key='graph')],]
-
- form = sg.FlexForm('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False)
- form.Layout(layout)
-
- form.Finalize()
- graph = form.FindElement('graph')
-
- prev_response_time = None
- i=0
- prev_x, prev_y = 0, 0
- while True:
- time.sleep(.2)
-
- button, values = form.ReadNonBlocking()
- if button == 'Quit' or values is None:
- break
- if g_response_time is None or prev_response_time == g_response_time:
- continue
- new_x, new_y = i, g_response_time[0]
- prev_response_time = g_response_time
- if i >= SAMPLES:
- graph.Move(-STEP_SIZE,0)
- prev_x = prev_x - STEP_SIZE
- graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white')
- # form.FindElement('graph').DrawPoint((new_x, new_y), color='red')
- prev_x, prev_y = new_x, new_y
- i += STEP_SIZE if i < SAMPLES else 0
-
- # tell thread we're done. wait for thread to exit
- g_exit = True
- thread.join()
-
-
-if __name__ == '__main__':
- main()
- exit(69)
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Graph_pymunk_2D_Graphics.py b/DemoPrograms old/Demo_Graph_pymunk_2D_Graphics.py
deleted file mode 100644
index 9dcd8e9c..00000000
--- a/DemoPrograms old/Demo_Graph_pymunk_2D_Graphics.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import PySimpleGUIWeb as sg
-# import PySimpleGUI as sg
-import pymunk
-import random
-import socket
-
-"""
- Demo that shows integrating PySimpleGUI with the pymunk library. This combination
- of PySimpleGUI and pymunk could be used to build games.
- Note this exact same demo runs with PySimpleGUIWeb by changing the import statement
-"""
-
-class Ball():
- def __init__(self, x, y, r, *args, **kwargs):
- mass = 10
- self.body = pymunk.Body(mass,
- pymunk.moment_for_circle(mass, 0, r, (0, 0))) # Create a Body with mass and moment
- self.body.position = x, y
- self.shape = pymunk.Circle(self.body, r, offset=(0, 0)) # Create a box shape and attach to body
- self.shape.elasticity = 0.99999
- self.shape.friction = 0.8
- self.gui_circle_figure = None
-
-class Playfield():
- def __init__(self):
- self.space = pymunk.Space()
- self.space.gravity = 0, 200
- self.add_wall((0, 400), (600, 400)) # ground
- self.add_wall((0, 0), (0, 600)) # Left side
- self.add_wall((600, 0), (600, 400)) # right side
-
- def add_wall(self, pt_from, pt_to):
- body = pymunk.Body(body_type=pymunk.Body.STATIC)
- ground_shape = pymunk.Segment(body, pt_from, pt_to, 0.0)
- ground_shape.friction = 0.8
- ground_shape.elasticity = .99
- self.space.add(ground_shape)
-
- def add_balls(self):
- self.arena_balls = []
- for i in range(1, 200):
- x = random.randint(0, 600)
- y = random.randint(0, 400)
- r = random.randint(1, 10)
- ball = Ball(x, y, r)
- self.arena_balls.append(ball)
- area.space.add(ball.body, ball.shape)
- ball.gui_circle_figure = graph_elem.DrawCircle((x, y), r, fill_color='black', line_color='red')
-
-
-# ------------------- Build and show the GUI Window -------------------
-graph_elem = sg.Graph((600, 400), (0, 400), (600, 0), enable_events=True, key='_GRAPH_', background_color='lightblue')
-
-layout = [[sg.Text('Ball Test'), sg.T('My IP {}'.format(socket.gethostbyname(socket.gethostname())))],
- [graph_elem],
- # [sg.Up(), sg.Down()],
- [sg.B('Kick'), sg.Button('Exit')]]
-
-window = sg.Window('Window Title', layout, ).Finalize()
-
-area = Playfield()
-area.add_balls()
-
-# ------------------- GUI Event Loop -------------------
-while True: # Event Loop
- event, values = window.Read(timeout=0)
- # print(event, values)
- if event in (None, 'Exit'):
- break
- area.space.step(0.02)
-
- for ball in area.arena_balls:
- if event == 'Kick':
- ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(1,200)
- graph_elem.RelocateFigure(ball.gui_circle_figure, ball.body.position[0], ball.body.position[1])
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Hello_World.py b/DemoPrograms old/Demo_Hello_World.py
deleted file mode 100644
index eb7ee429..00000000
--- a/DemoPrograms old/Demo_Hello_World.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Oh yes, the classic "Hello World". The problem is that you
- can do it so many ways using PySimpleGUI
-"""
-
-sg.PopupNoButtons('Hello World') # the single line
-
-sg.Window('Hello world', [[sg.Text('Hello World')]]).Read() # single line using a real window
-
-# This is a "Traditional" PySimpleGUI window code. First make a layout, then a window, the read it
-layout = [[sg.Text('Hello World')]]
-window = sg.Window('Hello world', layout)
-event, values = window.Read()
diff --git a/DemoPrograms old/Demo_HowDoI.py b/DemoPrograms old/Demo_HowDoI.py
deleted file mode 100644
index 38d73bc0..00000000
--- a/DemoPrograms old/Demo_HowDoI.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUIQt as sg
-else:
- import PySimpleGUI27 as sg
-import subprocess
-
-
-# Test this command in a dos window if you are having trouble.
-HOW_DO_I_COMMAND = 'python -m howdoi.howdoi'
-
-# if you want an icon on your taskbar for this gui, then change this line of code to point to the ICO file
-DEFAULT_ICON = 'E:\\TheRealMyDocs\\Icons\\QuestionMark.ico'
-
-def HowDoI():
- '''
- Make and show a window (PySimpleGUI form) that takes user input and sends to the HowDoI web oracle
- Excellent example of 2 GUI concepts
- 1. Output Element that will show text in a scrolled window
- 2. Non-Window-Closing Buttons - These buttons will cause the form to return with the form's values, but doesn't close the form
- :return: never returns
- '''
- # ------- Make a new Window ------- #
- sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors
-
- layout = [
- [sg.Text('Ask and your answer will appear here....', size=(40, 1))],
- [sg.Output(size=(120, 30), font=('Helvetica 10'))],
- [ sg.Spin(values=(1, 2, 3, 4), initial_value=1, size=(2, 1), key='Num Answers', font='Helvetica 15'),
- sg.Text('Num Answers',font='Helvetica 15'), sg.Checkbox('Display Full Text', key='full text', font='Helvetica 15'),
- sg.T('Command History', font='Helvetica 15'), sg.T('', size=(40,3), text_color=sg.BLUES[0], key='history')],
- [sg.Multiline(size=(85, 5), enter_submits=True, key='query', do_not_clear=False),
- sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
- sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]
- ]
-
- window = sg.Window('How Do I ??', default_element_size=(30, 2), icon=DEFAULT_ICON, font=('Helvetica',' 13'), default_button_element_size=(8,2), return_keyboard_events=True, no_titlebar=True, grab_anywhere=True)
- window.Layout(layout)
- # ---===--- Loop taking in user input and using it to query HowDoI --- #
- command_history = []
- history_offset = 0
- while True:
- event, values = window.Read()
- if event == 'SEND':
- query = values['query'].rstrip()
- # print(query)
- QueryHowDoI(query, values['Num Answers'], values['full text']) # send the string to HowDoI
- command_history.append(query)
- history_offset = len(command_history)-1
- window.FindElement('query').Update('') # manually clear input because keyboard events blocks clear
- window.FindElement('history').Update('\n'.join(command_history[-3:]))
- elif event == None or event == 'EXIT': # if exit button or closed using X
- break
- elif 'Up' in event and len(command_history): # scroll back in history
- command = command_history[history_offset]
- history_offset -= 1 * (history_offset > 0) # decrement is not zero
- window.FindElement('query').Update(command)
- elif 'Down' in event and len(command_history): # scroll forward in history
- history_offset += 1 * (history_offset < len(command_history)-1) # increment up to end of list
- command = command_history[history_offset]
- window.FindElement('query').Update(command)
- elif 'Escape' in event: # clear currently line
- window.FindElement('query').Update('')
-
-
-def QueryHowDoI(Query, num_answers, full_text):
- '''
- Kicks off a subprocess to send the 'Query' to HowDoI
- Prints the result, which in this program will route to a gooeyGUI window
- :param Query: text english question to ask the HowDoI web engine
- :return: nothing
- '''
- howdoi_command = HOW_DO_I_COMMAND
- full_text_option = ' -a' if full_text else ''
- t = subprocess.Popen(howdoi_command + ' \"'+ Query + '\" -n ' + str(num_answers)+full_text_option, stdout=subprocess.PIPE)
- (output, err) = t.communicate()
- print('{:^88}'.format(Query.rstrip()))
- print('_'*60)
- print(output.decode("utf-8") )
- exit_code = t.wait()
-
-if __name__ == '__main__':
- HowDoI()
-
diff --git a/DemoPrograms old/Demo_IP_Address_Entry.py b/DemoPrograms old/Demo_IP_Address_Entry.py
deleted file mode 100644
index 7b92fff8..00000000
--- a/DemoPrograms old/Demo_IP_Address_Entry.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import PySimpleGUI as sg
-
-'''
- IP Address entry window with digit validation and auto advance
- If not a digit or ., the ignored
- . will advance the focus to the next entry
- On the last input, once it's complete the focus moves to the OK button
- Pressing spacebar with focus on OK generates an _OK_ event
-'''
-
-# create a short-cut element so don't have to type this in over and over
-InIp = lambda key: sg.Input(do_not_clear=True, size=(3, 1), key=key, pad=(0, 2))
-
-layout = [[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_')],
- [InIp(0), sg.T('.'), InIp(1), sg.T('.'), InIp(2), sg.T('.'), InIp(3)],
- [sg.Button('Ok', key='_OK_', bind_return_key=True), sg.Button('Exit')]]
-
-window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout)
-
-while True: # Event Loop
- event, values = window.Read()
- print(event)
- if event is None or event == 'Exit':
- break
- elem = window.FindElementWithFocus()
- if elem is not None:
- key = elem.Key
- value = values[key] # get value of input field that has focus
- if event == '.' and key!= '_OK_': # if a ., then advance to next field
- elem.Update(value[:-1])
- value = value[:-1]
- next_elem = window.Element(key+1)
- next_elem.SetFocus()
- elif event not in '0123456789':
- elem.Update(value[:-1])
- elif len(value) > 2 and key < 3: # if 2 digits typed in, move on to next input
- next_elem = window.Element(key+1)
- next_elem.SetFocus()
- elif len(value)> 2 and key == 3:
- window.Element('_OK_').SetFocus()
- print('You entered IP Address {}.{}.{}.{}'.format(*values.values()))
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Img_Viewer.py b/DemoPrograms old/Demo_Img_Viewer.py
deleted file mode 100644
index c4fa408c..00000000
--- a/DemoPrograms old/Demo_Img_Viewer.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import os
-from PIL import Image, ImageTk
-import io
-"""
-Simple Image Browser based on PySimpleGUI
---------------------------------------------
-There are some improvements compared to the PNG browser of the repository:
-1. Paging is cyclic, i.e. automatically wraps around if file index is outside
-2. Supports all file types that are valid PIL images
-3. Limits the maximum form size to the physical screen
-4. When selecting an image from the listbox, subsequent paging uses its index
-5. Paging performance improved significantly because of using PIL
-
-Dependecies
-------------
-Python v3
-PIL
-"""
-# Get the folder containin:g the images from the user
-folder = sg.PopupGetFolder('Image folder to open', default_path='')
-if not folder:
- sg.PopupCancel('Cancelling')
- raise SystemExit()
-
-# PIL supported image types
-img_types = (".png", ".jpg", "jpeg", ".tiff", ".bmp")
-
-# get list of files in folder
-flist0 = os.listdir(folder)
-
-# create sub list of image files (no sub folders, no wrong file types)
-fnames = [f for f in flist0 if os.path.isfile(os.path.join(folder,f)) and f.lower().endswith(img_types)]
-
-num_files = len(fnames) # number of iamges found
-if num_files == 0:
- sg.Popup('No files in folder')
- raise SystemExit()
-
-del flist0 # no longer needed
-
-#------------------------------------------------------------------------------
-# use PIL to read data of one image
-#------------------------------------------------------------------------------
-def get_img_data(f, maxsize = (1200, 850), first = False):
- """Generate image data using PIL
- """
- img = Image.open(f)
- img.thumbnail(maxsize)
- if first: # tkinter is inactive the first time
- bio = io.BytesIO()
- img.save(bio, format = "PNG")
- del img
- return bio.getvalue()
- return ImageTk.PhotoImage(img)
-#------------------------------------------------------------------------------
-
-
-# create the form that also returns keyboard events
-window = sg.Window('Image Browser', return_keyboard_events=True,
- location=(0, 0), use_default_focus=False)
-
-# make these 2 elements outside the layout as we want to "update" them later
-# initialize to the first file in the list
-filename = os.path.join(folder, fnames[0]) # name of first file in list
-image_elem = sg.Image(data = get_img_data(filename, first = True))
-filename_display_elem = sg.Text(filename, size=(80, 3))
-file_num_display_elem = sg.Text('File 1 of {}'.format(num_files), size=(15,1))
-
-# define layout, show and read the form
-col = [[filename_display_elem],
- [image_elem]]
-
-col_files = [[sg.Listbox(values = fnames, change_submits=True, size=(60, 30), key='listbox')],
- [sg.Button('Next', size=(8,2)), sg.Button('Prev',
- size=(8,2)), file_num_display_elem]]
-
-layout = [[sg.Column(col_files), sg.Column(col)]]
-
-window.Layout(layout) # Shows form on screen
-
-# loop reading the user input and displaying image, filename
-i=0
-while True:
- # read the form
- event, values = window.Read()
- print(event, values)
- # perform button and keyboard operations
- if event is None:
- break
- elif event in ('Next', 'MouseWheel:Down', 'Down:40', 'Next:34'):
- i += 1
- if i >= num_files:
- i -= num_files
- filename = os.path.join(folder, fnames[i])
- elif event in ('Prev', 'MouseWheel:Up', 'Up:38', 'Prior:33'):
- i -= 1
- if i < 0:
- i = num_files + i
- filename = os.path.join(folder, fnames[i])
- elif event == 'listbox': # something from the listbox
- f = values["listbox"][0] # selected filename
- filename = os.path.join(folder, f) # read this file
- i = fnames.index(f) # update running index
- else:
- filename = os.path.join(folder, fnames[i])
-
- # update window with new image
- image_elem.Update(data=get_img_data(filename))
- # update window with filename
- filename_display_elem.Update(filename)
- # update page display
- file_num_display_elem.Update('File {} of {}'.format(i+1, num_files))
-
-
diff --git a/DemoPrograms old/Demo_Input_Auto_Complete.py b/DemoPrograms old/Demo_Input_Auto_Complete.py
deleted file mode 100644
index e963dad0..00000000
--- a/DemoPrograms old/Demo_Input_Auto_Complete.py
+++ /dev/null
@@ -1,90 +0,0 @@
-import sys
-import re
-QT = True
-if QT:
- import PySimpleGUIQt as sg
-else:
- import PySimpleGUI as sg
-
-def autocomplete_popup_show(text_list ):
- autocomplete_popup_layout = [[sg.Listbox(values=text_list,
- size=(100,20*len(text_list)) if QT else (15, len(text_list)),
- change_submits=True,
- bind_return_key=True,
- auto_size_text=True,
- key='_FLOATING_LISTBOX_', enable_events=True)]]
-
- autocomplete_popup = sg.Window("Borderless Window",
- default_element_size=(12, 1),
- auto_size_text=False,
- auto_size_buttons=False,
- no_titlebar=True,
- grab_anywhere=True,
- return_keyboard_events=True,
- keep_on_top=True,
- background_color='black',
- location=(1320,622),
- default_button_element_size=(12, 1))
-
- window = autocomplete_popup.Layout(autocomplete_popup_layout).Finalize()
- return window
-
-
-def predict_text(input, lista):
- pattern = re.compile('.*' + input + '.*')
- return [w for w in lista if re.match(pattern, w)]
-
-choices = ['ABC' + str(i) for i in range(30)] # dummy data
-
-layout = [ [sg.Text('Your typed chars appear here:')],
- [sg.In(key='_INPUT_', size=(10,1), do_not_clear=True)],
- [sg.Button('Show'), sg.Button('Exit')],]
-
-window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout)
-
-sel_item = -1
-skip_event = False
-while True: # Event Loop
- event, values = window.Read(timeout=500)
- if event is None or event == 'Exit':
- break
- if event != sg.TIMEOUT_KEY:
- # print(f'ev1 {event}')
- in_val = values['_INPUT_']
- prediction_list = predict_text(str(in_val), choices)
- if prediction_list:
- try:
- fwindow.Close()
- except: pass
- fwindow = autocomplete_popup_show(prediction_list)
- list_elem = fwindow.Element('_FLOATING_LISTBOX_')
- if event == '_COMBO_':
- sg.Popup('Chose', values['_COMBO_'])
- if event.startswith('Down') or event.startswith('special 16777237'):
- sel_item = sel_item + (sel_item0)
- list_elem.Update(set_to_index=sel_item)
- skip_event = True
- if event == '\r' or event.startswith('special 16777220'):
- chosen = vals2['_FLOATING_LISTBOX_']
- window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'][0], select=True)
- fwindow.Close()
- sel_item = -1
- if event.startswith('Escape') or event.startswith('special 16777216'):
- window.Element('_INPUT_').Update('')
-
- try:
- ev2, vals2 = fwindow.Read(timeout=10)
- if ev2 == '_FLOATING_LISTBOX_' and skip_event and QT:
- skip_event = False
- elif ev2 != sg.TIMEOUT_KEY and ev2 is not None:
- # print(f'ev2 {ev2}')
- fwindow.Close()
- window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'][0], select=True)
- sel_item = -1
- fwindow = None
- except: pass
-window.Close()
diff --git a/DemoPrograms old/Demo_Input_Validation.py b/DemoPrograms old/Demo_Input_Validation.py
deleted file mode 100644
index 0a963f0b..00000000
--- a/DemoPrograms old/Demo_Input_Validation.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-"""
- Simple field validation
- Input field should only accept digits.
- If non-digit entered, it is deleted from the field
-"""
-
-layout = [[sg.Text('Enter digits:')],
- [sg.Input(do_not_clear=True, enable_events=True, key='_INPUT_')],
- [sg.Button('Ok', key='_OK_'),sg.Button('Exit')]]
-
-window = sg.Window('Window Title').Layout(layout)
-
-while True: # Event Loop
- event, values = window.Read()
- if event in (None, 'Exit'):
- break
- if len(values['_INPUT_']) and values['_INPUT_'][-1] not in ('0123456789'): # if last char entered not a digit
- window.Element('_INPUT_').Update(values['_INPUT_'][:-1]) # delete last char from input
-window.Close()
diff --git a/DemoPrograms old/Demo_Invisible_Elements.py b/DemoPrograms old/Demo_Invisible_Elements.py
deleted file mode 100644
index df98d4bd..00000000
--- a/DemoPrograms old/Demo_Invisible_Elements.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Demonstrates that using a Column Element to make groups of Elements appear and disappear
- will cause the layout of the elements in the column to remain as they were. If each individual element
- were made invisible and then visible, then tkinter puts EACH ELEMENT on a separate row when it is made
- visible again. This means a row of 6 elements will become a column of 6 elements if you make each of them
- visible one at a time.
-
-"""
-
-layout = [[sg.Column([[sg.Text('My Window')],[sg.Input(key='_IN_'), sg.B('My button', key='_OUT_')]], key='_COL_')],
- [sg.Button('Invisible'), sg.B('Visible'), sg.Button('Exit')]]
-
-window = sg.Window('Window Title', layout)
-
-while True: # Event Loop
- event, values = window.Read()
- print(event, values)
- if event in (None, 'Exit'):
- break
- if event == 'Invisible':
- window.Elem('_COL_').Update(visible=False)
- elif event == 'Visible':
- window.Elem('_COL_').Update(visible=True)
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Keyboard.py b/DemoPrograms old/Demo_Keyboard.py
deleted file mode 100644
index 6fd21931..00000000
--- a/DemoPrograms old/Demo_Keyboard.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-# Recipe for getting keys, one at a time as they are released
-# If want to use the space bar, then be sure and disable the "default focus"
-
-layout = [[sg.Text("Press a key or scroll mouse")],
- [sg.Text("", size=(18,1), key='text')],
- [sg.Button("OK", key='OK')]]
-
-window = sg.Window("Keyboard Test", return_keyboard_events=True, use_default_focus=False).Layout(layout)
-
-# ---===--- Loop taking in user input --- #
-while True:
- event, values = window.Read()
- text_elem = window.FindElement('text')
- if event in ("OK", None):
- print(event, "exiting")
- break
- if len(event) == 1:
- text_elem.Update(value='%s - %s' % (event, ord(event)))
- if event is not None:
- text_elem.Update(event)
-
-
diff --git a/DemoPrograms old/Demo_Keyboard_ENTER_Presses_Button.py b/DemoPrograms old/Demo_Keyboard_ENTER_Presses_Button.py
deleted file mode 100644
index de2c2a6b..00000000
--- a/DemoPrograms old/Demo_Keyboard_ENTER_Presses_Button.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import PySimpleGUI as sg
-# import PySimpleGUIQt as sg
-
-"""
- tkinter and Qt do not "activate" buttons by pressing the ENTER key with the button highlighted / in focus
- This demo will enable the application to click on a button if the button has focus (is highlighted) and the
- user presses the ENTER key.
- NOTE that the SPACE BAR works correctly out of the box with both tkinter and Qt. If a button has focus and
- you press the space bar, then tkinter and Qt will both consider that a button click. But not so with the ENTER
- key.
-
- The solution is for your program to read the keyboard presses and act upon those directly. It's trivial logic
- in the end:
- 1. Get a key press
- 2. See if the key is the ENTER key
- 3. Find the Element that currently has focus
- 4. Click the Button if the Element with focus is a button
-
-"""
-
-QT_ENTER_KEY1 = 'special 16777220'
-QT_ENTER_KEY2 = 'special 16777221'
-
-layout = [ [sg.T('Test of Enter Key use')],
- [sg.In(key='_IN_')],
- [sg.Button('Button 1', key='_1_')],
- [sg.Button('Button 2', key='_2_')],
- [sg.Button('Button 3', key='_3_')], ]
-
-window = sg.Window('My new window', layout,
- return_keyboard_events=True)
-while True: # Event Loop
- event, values = window.Read()
- if event is None:
- break
- if event in ('\r', QT_ENTER_KEY1, QT_ENTER_KEY2): # Check for ENTER key
- elem = window.FindElementWithFocus() # go find element with Focus
- if elem is not None and elem.Type == sg.ELEM_TYPE_BUTTON: # if it's a button element, click it
- elem.Click()
- # check for buttons that have been clicked
- elif event == '_1_':
- print('Button 1 clicked')
- elif event == '_2_':
- print('Button 2 clicked')
- elif event == '_3_':
- print('Button 3 clicked')
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Keyboard_Realtime.py b/DemoPrograms old/Demo_Keyboard_Realtime.py
deleted file mode 100644
index cc50054e..00000000
--- a/DemoPrograms old/Demo_Keyboard_Realtime.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [[sg.Text("Hold down a key")],
- [sg.Button("OK")]]
-
-window = sg.Window("Realtime Keyboard Test", return_keyboard_events=True, use_default_focus=False).Layout(layout)
-
-while True:
- event, values = window.Read(timeout=0)
-
- if event == "OK":
- print(event, values, "exiting")
- break
- if event is not sg.TIMEOUT_KEY:
- if len(event) == 1:
- print('%s - %s' % (event, ord(event)))
- else:
- print(event)
- elif event is None:
- break
diff --git a/DemoPrograms old/Demo_Keypad.py b/DemoPrograms old/Demo_Keypad.py
deleted file mode 100644
index 31194fbc..00000000
--- a/DemoPrograms old/Demo_Keypad.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-# Demonstrates a number of PySimpleGUI features including:
-# Default element size
-# auto_size_buttons
-# Button
-# Dictionary return values
-# Update of elements in form (Text, Input)
-# do_not_clear of Input elements
-
-
-
-layout = [[sg.Text('Enter Your Passcode')],
- [sg.Input(size=(10, 1), do_not_clear=True, key='input')],
- [sg.Button('1'), sg.Button('2'), sg.Button('3')],
- [sg.Button('4'), sg.Button('5'), sg.Button('6')],
- [sg.Button('7'), sg.Button('8'), sg.Button('9')],
- [sg.Button('Submit'), sg.Button('0'), sg.Button('Clear')],
- [sg.Text('', size=(15, 1), font=('Helvetica', 18), text_color='red', key='out')],
- ]
-
-window = sg.Window('Keypad', default_button_element_size=(5, 2), auto_size_buttons=False, grab_anywhere=False).Layout(layout)
-
-# Loop forever reading the form's values, updating the Input field
-keys_entered = ''
-while True:
- event, values = window.Read() # read the form
- if event is None: # if the X button clicked, just exit
- break
- if event == 'Clear': # clear keys if clear button
- keys_entered = ''
- elif event in '1234567890':
- keys_entered = values['input'] # get what's been entered so far
- keys_entered += event # add the new digit
- elif event == 'Submit':
- keys_entered = values['input']
- window.FindElement('out').Update(keys_entered) # output the final string
-
- window.FindElement('input').Update(keys_entered) # change the form to reflect current key string
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_LED_Clock_Weather.py b/DemoPrograms old/Demo_LED_Clock_Weather.py
deleted file mode 100644
index cde7115e..00000000
--- a/DemoPrograms old/Demo_LED_Clock_Weather.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
- sg.PopupError('This program uses Base64 images which are not supported in Python 2.7')
- sys.exit()
-import datetime
-import calendar
-import forecastio
-
-##### CHANGE these settings to match your location... check Google Maps #####
-MY_LOCATION_LAT = 35.000000
-MY_LOCATION_LON = -79.000000
-##### You need a free dark-sky key. You get 1000 calls a month for free #####
-DARKSKY_KEY = "INSERT YOUR DARKSKY KEY HERE!" # *** INSERT YOUR DARKSKY KEY HERE **
-
-NUM_COLS = 5 # Changes number of days in forecast
-
-
-class GUI():
- def __init__(self):
- self.api_key = DARKSKY_KEY
- self.lat = MY_LOCATION_LAT
- self.lng = MY_LOCATION_LON
- self.blink_count = 0
-
- sg.SetOptions(border_width=0, text_color='white', background_color='black', text_element_background_color='black')
-
- # Create clock layout
- clock = [
- [sg.T('', pad=((120,0),0)),
- sg.Image(data=ledblank[22:], key='_hour1_'),
- sg.Image(data=ledblank[22:], key='_hour2_'),
- sg.Image(data=ledblank[22:], key='_colon_'),
- sg.Image(data=ledblank[22:], key='_min1_'),
- sg.Image(data=ledblank[22:], key='_min2_')], ]
-
- # Create the weather columns layout
- weather_cols = []
- for i in range(NUM_COLS):
- weather_cols.append(
- [[sg.T('', size=(4, 1), font='Any 20', justification='center', key='_DAY_' + str(i)), ],
- [sg.Image(data=w1[22:], background_color='black', key='_icon_'+str(i), pad=((4, 0), 3)), ],
- [sg.T('--', size=(3, 1), justification='center', font='Any 20', key='_high_' + str(i), pad=((10, 0), 3))],
- [sg.T('--', size=(3, 1), justification='center', font='Any 20', key='_low_' + str(i), pad=((10, 0), 3))]])
-
- # Create the overall layout
- layout = [[sg.Column(clock, background_color='black')],
- [sg.Column(weather_cols[x], background_color='black') for x in range(NUM_COLS)],
-
- [sg.Button('Exit', button_color=('black', 'black'),
- image_data=orangeround[22:], tooltip='close window', pad=((450,0),(10,0)))]]
-
- # Create the window
- self.window = sg.Window('My new window',
- background_color='black',
- grab_anywhere=True,
- use_default_focus=False,
- no_titlebar=True,
- alpha_channel=.8, # set an alpha channel if want transparent
- ).Layout(layout).Finalize()
-
- self.colon_elem = self.window.FindElement('_colon_')
- self.hour1 = self.window.FindElement('_hour1_')
- self.hour2 = self.window.FindElement('_hour2_')
- self.min1 = self.window.FindElement('_min1_')
- self.min2 = self.window.FindElement('_min2_')
-
-
- def update_clock(self):
- # update the clock
- now = datetime.datetime.now()
- real_hour = now.hour - 12 if now.hour > 12 else now.hour
- hour1_digit = led_digits[real_hour // 10]
- self.hour1.Update(data=hour1_digit[22:])
- self.hour2.Update(data=led_digits[real_hour % 10][22:])
- self.min2.Update(data=led_digits[int(now.minute) % 10][22:])
- self.min1.Update(data=led_digits[int(now.minute) // 10][22:])
- # Blink the :
- if self.blink_count % 2:
- self.colon_elem.Update(data=ledcolon[22:])
- else:
- self.colon_elem.Update(data=ledblank[22:])
- self.blink_count += 1
-
- def update_weather(self):
- forecast = forecastio.load_forecast(self.api_key, self.lat, self.lng)
- daily = forecast.daily()
- today_weekday = datetime.datetime.today().weekday()
-
- max_temps = []
- min_temps = []
- daily_icons = []
- for daily_data in daily.data:
- daily_icons.append(daily_data.d['icon'])
- max_temps.append(int(daily_data.d['temperatureMax']))
- min_temps.append(int(daily_data.d['temperatureMin']))
-
- for i in range(NUM_COLS):
- day_element = self.window.FindElement('_DAY_' + str(i))
- max_element = self.window.FindElement('_high_' + str(i))
- min_element = self.window.FindElement('_low_' + str(i))
- icon_element = self.window.FindElement('_icon_' + str(i))
- day_element.Update(calendar.day_abbr[(today_weekday + i) % 7])
- max_element.Update(max_temps[i])
- min_element.Update(min_temps[i])
- icon_element.Update(data=weather_icon_dict[daily_icons[i]][22:])
-
-
-def led_clock():
-
- # Get the GUI object that is used to update the window
- gui = GUI()
-
- # ---------- EVENT LOOP ----------
- last_update_time = 0
- while True:
- # Wake up once a second to update the clock and weather
- event, values = gui.window.Read(timeout=1000)
- if event in (None, 'Exit'):
- break
- # update clock
- gui.update_clock()
- # update weather once ever 6 hours
- now = datetime.datetime.now()
- if last_update_time == 0 or (now-last_update_time).seconds >= 60*60*6:
- print('*** Updating Weather ***')
- last_update_time = now
- gui.update_weather()
-
-
-led0 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAAEb0lEQVRoge2Zz4scRRTHP/WqunsDSQjiBvFHSBC8eRJRFAXFgCIYRVBPgrkoiBgU9U/w4iEgHjwEBT2IKHiIiBfBg4oB8SJ4CgHjIXpSE5Ls9HR9PUz1ZGa6dnZ2dmdnlXzh0TPV1a+/9erVq/eqHSB2GWzZBHK4TmpW7EpSIdfokuwE4jrv12QDk40LhNElNmapluFNZtws8bdEsQCCrb69zvEL0FP3DQLk0nUf6P6y1A8hSKAeKG6jNEmnQG8Xhe5cWZE5p5ZHy3mM1GHQz2Z6YGVF33ovgeqkZDukn65vVpVeDUFfr6wIM9k0UgdBa6DfvNc9VaWvErFeGuW80h8Z3Imi0PGqkkCny1KYyY+Q6qw+A64AtzUNn0k8GwI9M56oayLzxxABzjleCgFvxqleb3DDddd5NiT4dL01Rr6oa54pS9aKgqMSl+YgFoG9wFtm7JE42evRkyjJh54sqRZ9YFXi07rmLjMuJEWbXY0B+Ac4Dpysa2qmD6xDavSFnsEoVyVWm4bzEg35gLcRKYA7wuDXRsE561M28R8GVptFYQ5t/yYTj6aSagPnJKlJDNfsJtD2n3Uw3fdnVsNOo0PKwdKJ/YcstSDM71ObeHhR6FpqN04fsHS/2lGfmhU76lNbcvRF5eez7pkbOnpcr+McaPe03KCV6TdsvApccY4KqIESOGvG7yOb6bzT+6MEZvgYqRlkIRdTojypc5iGtnnysbLUFTMJ9Kv3OhLCIGV1Tm5O8c4JMz1fluon3WdC0KrZWDre2kc5Yk+GoJ+KQoeKQjg3mdjPJQGE9zpeFPq+KHRDCDlC6hSjMJjT6BzmPcSIYqSZc8omUQDRDOccagZaJ3V3/NcYJHT3ec8nzrHfORqzbXP02jke854PzSicoyHvo52pu9d7/ZlKq++81w1FIcw6Zt6MeBBmejQEXUw+ddp7VdN8qm280XtdSISupjrtTAja5/3At+Zw8uCccE5Hi0I9M8UR3aeqSjg3VvcNZ6U14T7nOJCWf8lgvu9uGm4fqXO1SWmfe9iMIkb6XItFtwA4N+bYHVfRxBy3NeCsSf809JOOUf2tk4+2zey/25HSWEZHTuvST/Jy9l86qRyWTuq6pWaFMqt6+aQybUsnlcPSSf3/LLUdxUTOqXN6px4vAsPD17bjVg7NQtpmRvfX4YY9K6kmdTjrPefSg3FiR58FbUV0JkZwDpOm6lj3g5HSzfPe82JR8EFdc8iMNTZvqQjsBz4GXi5L3kunw7C+W4xlnYdDGFYyfzinB8tS36Skr2H614Rp0j77elXpRDrYF+jzVJhkk7xRhgG45BzPlSWvNQ0PNQ29dK+ZU8Qg939nbY3LMfJGOinuzxLRA3DZjKfKkhdi5FjTcJVryd5WUQPv1zXnvOfdEDiwTr+xHP1ICHp6zx59lKasv4UpmyrO6ZWq0uNV1Skcxuq+9s9BMx6Jkb+20UKjiAzy/55zfAmdkJAtRrONC8KGX0ZHsQgL5ZCrvHfSKDNjV27I/wIpihClbBNQxAAAAABJRU5ErkJggg=='
-
-led1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAACD0lEQVRoge2Yv27UQBCHv9kkRCAhXgAkSh6AmoKCFFBENLwBFQ0PQIPES0BJky4NDR0lJT28A4ICQc7nH4V3FccZ+9zcrAv/pJVP3jntp525+XMGiIUp1QbwtELN1Qo1V1WhLK+hqkEVIC8fVYFKdDB3gLvW3ZUN9qsAmRlnKfEoQ6WBTShQCxybcW7Gk7blt2N3GAVkGegmcA6ctC0AB45tyE2VgL5txifgROLfhH0YFMBH4DGwYdpFIVBtft5XlwA8l/UVGujtbhMgGMrL3p7W2rcrlor2DtV32dHM7+wdSiOfp7TG1FytUHO1Qnllpko7bL3n3N4pJE+VFvhLftf09n/Kz16KXO/NJJBAr8wEKF23i4GxvDDTh5T0OqUxII2NXntRiavGDJM4pOtChwqfZhrgDfDCjA3jnUOY+zDT2xxTf0Gnea9KTJVD36UkgS5ALWgDeugEe+jg8DTPegnY0k009/JetbF92wMoEFu73rmHB/oVOUCuXbS2zrvqUF6RrgIlLmPKy9zrTXlaJNQi3bc8KGmBUCwgphYzOPRVeqdd/1OFQJVDvuVa1y8tcgaHEKhy7EvgsxlHXE401dxXysqFxHO6UevGhH1YTCkf9kfiFPiaXdk4tuG/vgT8Ap4B31PilmMXOmIVHdAF+wMzGuCHdAWkClQ5mJHDq2X0/q0MVe2mplS99nlaJNR/DW4BrSasyZkAAAAASUVORK5CYII='
-
-led2 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAADmElEQVRoge2Zz4scRRiGn7d6NlHJQaKoKHgwxGgiIpiTegrI4kEUkdwEQcRF8pdI0INIrorkoqB48SB4EhQUvSoIIkjixaiExdnNTtfrYaqyPZmamZ6e7GQC88JHM71dVU999ev7tgSYFVO41QAlraHaaiWheqWXSrYMxQnt39LVVwLolT64T+Jem22gOgAQM5w3hyV+8bhPisN3GPhU4qTNf5M+WgBIwCFgS+KqxKU4Oohj3ssvHpL4UuLJGKm5OR7LDQl4NQQeBp4A3oiRCqjT38dWX3btJZszwA8SFbCXCnW1AfteerGqOCLxboz00/A1F1ZxS4gMPXMlRjaB7yQ2UsGqgwWGU0DACxKPxMiHdT0GkzVxutSpsn9sNiU+riqetulP6skM9YA303Q4b7MD3DEvFAw9JmDb5pU07l3UA/rAOeC8zd6MhmcurDwPSJV1UZ7gpwrzpxNUrvQ6XAflcqXdu6S5tqCuW39zK2ijlTyQ11BttYZqq6VCSe3W39pTbbWSUK139EWSidzz0jFTOiVaQYVUuO3ZdaNyuRxlNM/RuUOXDBSBu4GjDOOseT3WA/4CvgbeSnA5fPl3QhlPspCexyX/KjmC++DdOa0PNnhL8supHoM/l3xIMmCNtl0GqtLz8RD8u2SD61RZF8sgWyH4tRB8MQRXZaAyVAaS5O8T0G6quKvVqQ6DXwrBgDfKQONQecjOSH5P8mnJlxue6go1SEDvSw6pnQlAo1AZ6JkQfCVV8kEIfqyqfDkEW3KU7DmtTs93koemwBjw9dWXV9mDEl/YHAV2gbdj5M4QOC1xXOoUpwu4BvwUY+uVO+KlU8kb2e0Gb4MfyPNsRi+n2YwhG/dUVt7omvl8c2+qGu/nVT37E6CweZaOkyZIvQBUW63kgbyGaqvbG+qgJ3dTt7enlqk1VFu1guoam3dVq8Qh/wMW9pOILhLtzr+pUANgA/hR4k8Am7gAFOyHSJ2g6gbQuRD4LEbuSfHUvNlMBI4AH0lciJEeww5P00g8dVLyIIW/P4NPhOBvQlg4ccj2eoo+e9NjqlGoEyl0/U3yoyH4q0biMFjA9nKnJJ9NWcwUsFGopyT/EYKPVZU/SUA7qcJFbS8BXgNvJo+FaVA5TD0m+bmq8sU0ZDkLuVmWQ+wdyc9PABu5xco/7geeZZhSH8R9Xw3cBfwt8a09dpVWvFrjxpdLVvG6Vizn/DEreodc0koeyP8DbP/uIBO2okgAAAAASUVORK5CYII='
-
-led3 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAADoUlEQVRoge2ZzascRRTFf6d7TCLBaALiImAIRoObJzqu3JiVCzH/QEACLlyI4sdCiArqwp2gG/8BcavgB7gRsgquRRBc+lwEBTExEMzLdB8XVTWv01090zPznPcgc6FopvtO1al7q+qee0uAOWBS7DeAnGxADZUDCWrU92EdaE1+l6nn/dokB2CUUzguccLmJlD+D0Aq4BBQS/zurk267pM4AnwFbAH/ZJVWB1QB54GbwF/cabGO9UqJSuJUXfMDcAao2Zs15jjgBHgWeA44DFwiTHwS9TpjVTalzW8S54Cfo9JOnN2y7XYEdAN4WuIJ4H2CJ/omMG2KzxKM5OOSr4ANruJz0VbH5zXwGcmvN769G8cbNTB0lksycQWUNn9LvAB8ATwK/Jsz7wxx1K+AF4ELwIexnyNxrLmWarcCXEgzdea1ZIV3onV2YjP4vYyl5k66js9VFnraSY8r2EX0WwgG7va+k3eoJACTmVq7stbYV2YOypwcyIB894Jqho8hcvdaalHZgBoqG1BDpRNmJOHWyZuYw9At3ZaSwBLqzLfcGT8o9pXxz7lOh0g1Y7BcDpAF1bRWmuWx2JYBNgL+BL6XuGBP+RrA1dz4ZCyoRDFsaomzwNc2pwm0eBE3JtePgOcljgLfxAl/ArzVAyJLzErJFIXH4KstWrssHTb4PPhl8Gct+t1q3ZdJ8RD4p9jZrdj5sm3SaFux/8M9oLJHggmp1k5R8ApwjZCrrUr0SuAl4KTEm8At+s+krqUkSwoulPwM+PoKLkz/uQg+1+Dnr0XuX3Q9lV/o090nUQEPAw8SKO2i59UI+APYsvmOsIMr4B7gIvA5u7s86fcCgpicxpx/e0EwTVAT4CMJ7OngAKfTuC39uVKz2ome1k1KHJr93M7oD65dLHuaN/+bW9RD3+27bEANlQ2oobJWUEPD1MZSQ2XjvlxUyL0bFGYSF1qWT5WEuJcb7Ebm3VxLNYPpsuXqFIh/zBTNFk6xSqCSeMTmYylcXbA4W6iB+4APbN4APiVUh2cN3mGdsFtHPwn+lb2po++An5J8SZp+e5UhdXQ71L0l7ge+BR4jpFYFy1MYE5jmZZuxxAPA2+SLsx1QhUQtcW9d8yXwZAS0F5dGE0JCe8VmDJwCTsyYxG5qVRQ+Kvnyii6b58pt8FjyWe5M62gnDunHQ8AYuM7e3/eJQIGPAdvAL3Qz5H29GU27uA0gX+BgfXfIuY2z73fIOTmQLOE/hw5ngBNVOEQAAAAASUVORK5CYII='
-
-led4 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAADdElEQVRoge2Zu4tkRRSHv3OqukdFxd0FUQRdxESMFgQDBWFBQ/P1LzBREHSNzAwNRPwbVkMDQUMVdIKNfIAYimAgsivjY3fsufUzmKrZftSdvn3t7tvC/OBw+z6q6runHufUbQPEjsmHBqjpDKqrzqC6qgq1TdJaW9X21XZjzXIgtVyf0f3uXAyBBIQtAF0ajYhmC/cFyPLxwRD0/Xisp0MQoJivr9MiCDO9HqO+Go+F2Un72WahHghBN0PQgbueyWCjNQKVul4JQTLT5zEKM/lpUOdD0K8xSqDfzfScmQCFNQCF7KHX3CWQQF+MRsuhLoSgGxlKoD/MdDlGAfMFVzLPQFdz3Ye5/i+7eOpCCLoRggSa5IIH7nrcvTdY8fKV3GWTqbprUAuzz7gzJQPHM+S+lDif0sn9VVXKPJL9ryX1VKFq5+vIb8qatOzFqlC1Qn081LeOzlDbVDWabAqqa71xoaA2mB1XwklN/5/UZWgtQm2y+zqq7qkNgfVeEnZBOwm1sCQox6Y2TcfGrirP1+qtXVuAcmb7vqTF0zGwllefpvJ8Sa81BeqVtWsB6hbwpxn3SkyAMfCDGb+Z8URKOKsH5wAcANeBf8wYSxwCe8DNlkk1m4iBLrvrwEwCfWemSzHq63w+ATUrWsmd3nPXCyHo73z+jbseypltNUefB3vRXfsx6vnRSPs56WtyZX2slH0/Rr0co/Zj1MM5cZwDWoQqYA7CXZ9loNug9B/tVgZ7KwThrj3quX91IiXyQEyJqynxszt7QFN7g47WAHcB10LgW+AaMDKjob6onp7sg550108xSu5q3KUVrZT5MEY9Ox7rl7yb+dRdd1e60Eoftinkt3w0BJ5yZ9LyZqfJgb8Al/g4Jc6lxO3suY9i5ErT4NLMUtNpe1QZjJ2t7LLfyB46nBr4+3k3Y7PPL1cZY31jUgCOuLOITq91TT5Od1knqALWVzZ3XKbBA3KnT0Hbliqxb3ioyrXBoXaz+yrXzqBq2kmoszFVU80rg0PVdjXlt1We26hKwz+agdlMQB7MU01u6JOUeNXsJEcbFAry/lHig5R40529HPMGH1MNx7nSuxJvx+Os6aiy7+ucT61LDRAl3jk64mIIPNbyda93mtvXSup7D+il/DfI3P21fCLvpc7/921TagEY1FNtGjz21bSTUP8C1hqqTm9IJgsAAAAASUVORK5CYII='
-
-led5 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAADyUlEQVRoge2Zv4tcVRTHP99zZ6NEggg2iYgWpghKEGNlYaGNYifBgAGbNFaCkCJ/haAiiGDAgOkFKxtttrGKFlaCbJFlwVVEo+5m5t2vxdy3+3bmzcybmXVnA/uFw5v35r37Pu/cX+fcK8AcM8WqAdp0AtVVxxKqN+mPo6I14z1NLdfaLx6hWj0VwLMS/9iYIeRhawCcAbYkfrXHHFF70CrHsxG+npIN3gX3wYNDtB2wwXcifDalA+8uv/cBE1ABNyXuSPwlcbOqyMVbh+GxqrznB4nXgC2bkMje99OB9ly/dAB8mDODnHlHIoBcCsxLWL8ArUfwisSWTYIDQGNQo3C3bE5LvJUSSSKV/2IBA1gDvpV4Hfg9572aGa2BiQ0dYBf4NGfeS4nLEXxs829LIbOUgdPA9zZXgb9zJgoQjPf0ieNUDdcHPqoqrqXEuVL4YE6oWgPApaflKfdNhWr2gvMSVBX3l4Cqa2DWGNgKJWnYaWk0/sb5or2wbfTuDNWm5lf+36P91N63Kh3LKOHBgTqpvhaNQ0lDW6FOqq+rjqWnOo/o9QTaDEXm1ULTTP2AGscaJjXgps3w0xQjZXaCEoDNn+V8wDAwQ2IdeBx4jP04qKvM8KO2Jf6w9yLZWc8cCN7PSP4mwgbfB7+Rkm+U8zqRmMd2S6Lwk+SnSqIQjfe22MELNdjDEf46wlcjfEOywVUpfBGrn/05whckA+51harB1sBIfrukWjvgvKTVHluXjGRN9lg7bUhOkk9F+PMC1i9fvIj1C9AG+MUIf5KSX4qYVJXtUCpfApgIfxZhS64ke07L5XhX8nOSb5fmsBnhF1rA2tcSJDwSDq9JXIqg1/ZAB/WAX2w+sHnTZhd4CNiUuAj8NpK6T+sFe20slca5iNVeOM8wbW+2sz74mZH7Oo3oZjiupFk3TlA9Lpn9tN3s18Jced+o5h00azWrZHSKaptnH5woYdU6geqqlUNVjK9NrByqLT5bOVSbTqC66sihDn19atF1qXru63Usp5On6kXTRZeq6zlzA/hRQkyfR2d6KgGVxPUIruTMva5f0pCBU8AmcC2CL3PmQtlimfZMq/VKnP5+yWQyyycO30m+mJI3SvR5D/zkSDzVDiXtAb1bgOp0aZk9mTpx+CrCz0d4G7wr+VwJIKdCpQJ0OSVn6VCARjeLvpB8KcJ3I/z0LKgoQFfqwH/JamuzQTneivDLvZ6fKFB1ojJxv/FV4BFgh8XD4GmqgEcZ7tVsjyQNq94E3Ru3mhBT95CPYp2qTiiaWrmn2nQsJ+T/AHYfURS2h8j3AAAAAElFTkSuQmCC'
-
-led6 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAAEBUlEQVRoge2ZP4gdVRTGf9+Z3c1qZJFUChJWLBQigmLQiJYhIkQLwcLWwkYrGy1s0sRC0gQUIljYWCRaaKONJoKNIoJKwEgaBcEuJuwmu/vefBZz7+68P/N23p91X7EfHGbmzsy935x777nfuSPAzBlivwkMwwGptphLUgvDCv8vpmVDueibfQMF+4BtT2UyhyUeBP61Kfao0RK4B7gO3Gl4xtkOgY8WhT+RbPAaeGPGtg42+EKEkVxvv2ZY6WJJ8jcRfjrCFxKxTqpkFpbr+qAojGTV2m4kheRrEb4l+VhR+FyEnb6wM6VtJkLnJCM5mgn1kpLk3xKRG5KPR/i95LHuFB4q0/Fs6rJiNCEPhIQ8uFdsrticjGBD4nXgJuOHizyoz0ucLUsWbLrZHQ1Q8hQGQuKqxMNlSYdqaq5LHAeuAodoji27YQsIu9X7g8HT1TcE0AHutllNpDpAd0JSxRjvDpBS7Tx3Vad2T0yGcTzcQ2q3Rrenxh5jLhfkHlKyJ+6eWWLQU97v5XgIqbnz1DSza5aY/4E+Lzgg1RY9EX23iB273B+FcVaDgWWmft5NRPJDJZOrhNwlbYj1kNoCbkpgs0klVf4Erkk8YLPYstJ+CPhbYiOtGG3qMOBIx2OS/0pK8XfJj0T4UlKft0ckBE12O9X1qeQiJQp1pQsNcrif2GMpgXiiKHwxyeNp5HB+91KElyNcgKOZUC8pKn3sJaok4sOah8opLXvsTNLpi6N1+qCnjkr+WPLjki/XUq1JCeXU6mKEn4zwR5KP9HXlUFL55n0R/il12ffg1Qh/G2FL7kr2mJbf+SzCq0XhX9NHXpa80kBsYDJ8J/GczR1gGfhR4hWJ+6WJ4pSoZvUtmy9tHqrV/XkEL9tDE4qdDBl8nZ1cbSudP5/uF81jYFQOZ8CvJu9v1gb+D2l89XuqJ07Vg6PZCXi5bJINj4Iq8cgernu7KRAPRPRRi2GX8VMs9R09pKwfc7kg7yuppklzQKotDjzVFgeeaou58FR/EG1Faha7C3lJaZOBD/0NUq8ogKV0PYlKyF+dG6ovM2OTKtPNfyR+AUgbqONmM3kX8GdgDThMJWUKmj+wkdQCcEPixQjeKkueklhjst3hFeAL4KUIvirLVnVs65lF8B9J66yDT0T4fNJB0/x5yPrp3Qifiti+vpL0VJbh2XpI1/v7lMRp4I2yZDOVdSc0U3XZmbLkUZvTRaXM3LBBF/0XAl4oCk4A75QlG1RdqSktgE3gfZsjNq9FcJe07YyB7st2L/jZovDbM8j1mqwEW/KbEX4mokrndkscliVOJnHfZvqOC1PNvAL4muFKdoBUMPkmxrhoamvofsNe/RHtR5Pen4dfxgOYS5XwH7eZhqnTFNxUAAAAAElFTkSuQmCC'
-
-led7 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAACtElEQVRoge2ZwWoUQRCGv+ruFRPx4iOIGPEuETyLGDH4AqII4tN49KQg+AB6jAjiOeBFg5gHEA+KHiQmJpme38P0hN3ZSZysm949zA9NQ2/t9LfdtV1V0waIOZObNUCbeqiumkuocNgHuWjF+D/NWsayylI/DHHoSi2ZUUgUTH/VDNgHzgK/zPgijazOGJQDSmDZjOdAlIhTBiuARWATuG/GjsQPRrdNzeZSfy8ERTMJVII0hRZTv2mmJee0Brqe5vNDLjYGBSikftVMuwlqPz100raXgDa81+XBQK+9l0BXukIBGqT+pnPadu6/VqxeoXXQee/1Lj1PoKsNqEMdHSpnDMBaWXInBJ46R6DyOTvqiw2VwAKwIfGwLHkRI9fS8wct9kdCAQf/vjdFwUXvCUx2hhjwR+ItHAAdNvk/oaD6pQ7Yi5HdCYEEnAEupDF/hH0nqBrMON62NaFKIHaw7wwF0zn6u/youQzIPVRX9VBd1UN1VQ/VVVmh6lDTNj6srFCO0UCsofGm3YlLVDFvG1i3KvoVaUxm/E5janznxJul/pSZXqU0OIIemAmzg7qgZssCNQLmnF6GoEdmI4XKkF3eYtSlFp0DiSCx32KTTXUuVQCPgVWqtLgtC822fYAw05NUS26Z6XYIbVuY0Z/M9Cw5+S5VebXjnC41fOtY6fCkqh13UeJGrLL0ulQ7XZacG7KDzD7VLBxqiGYxkd3R2yZsFhN9QO6qHqqreqiu6qG6aj6gbPT4zF44dEneshcOYxPa+Bur7IXDR1dNORKEZ7l9AHfNeO89A6oMtE3ZoJQm+xkjKxIfzFpfV2eFgiqf8sD3smRF4nMaj7PevpjAvgK3nOOb9yw0bGZ23+epAJdDYAv4VBQHN2gzvYRsu4CEGZ/o9VHRPKlmfl3bpvmIfQ3NJdRfFS/ZxKoPEs0AAAAASUVORK5CYII='
-
-led8 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAAEi0lEQVRoge2ZT4gcRRTGf+9Vd/VkIRjxIqggJF5E8JSDF/EQjKAICflDQjAnUdGD6EEQDHrRmwdBD6IIweQkiiIevOTgKSAiiiAiBDxpomhiJLvTVf08TPVkZqdmMz272Z2FfPCoobrr1dev/r1vSgBjwaBbTSCHW6RmxUKSKnKVkuxmw8ivMlld35LZjCU5ra8JUgD3qyJNQ5+bM74R2AGsqPJL02RJGGCSyru9t5NVZf+JmIEFsGYDrQYzsL9U7diOHXavc2P9AzYMhEvlURH2x8iBsuSaKi69KRtgxmAS/y3CwbLkZAg8FuNY/5AZncvAsRA41DQ86T1XRFAgAM06LKTOflflibLkuRjZX9f8I/klZYAVqXy2qsxSiM+UpT3ivV1KQ9mk+q7WtvvNOXuoquwL54bPToiM9Z9+57EMHK9ryqLgcFnyoRlLZkS6bRcGlMCfwDPO8XoIPBojy0BvSpsJUjLyoAYOh0C/LNltxs5EqisUuAp8mQjVieg0TI0UXJ9896lCCFyNsfP+1U5wBfaM+G26kBodmpZAYzbxrCuxBmaO8pqRGnUK04+FWTHrR01sCZtx5t0IC5klbI9ILSSpjYZM+b0WNi1Syvihe6N3Fw6bOqcWbvi6YKYdvT2nlO47envEqMjAj417yPmbIJWbZC4lYs2cpNrjKec7NzITpK6YgQiNGcJgxZwz43Yz7mSQQXZFAfwhwjlV9oRw/WAW4V8RMMsLh6GJ2HtFYZayzTe9tyPeDwVEAIsdLKQM85qqPV5V9s5I1vmW94bImGhgICImdZ+J8EFR0Ae+UeVMv4+kr5lnIbTtVkQ4WhQcEuFi0/ByjEO/uTajLM2DoWoPem8rqhY2QGq17a+o2p6qMkTMr5JWUyOlQCPCKeeIqlw04/0QhonePGgnuQAnvOcBMy4Bb4eAmmWz0LEoIWKnynIw7iL2Qlna096bqVqjatbRRtsc895e837gW9WeL8tWfOYj5Rikq8erijN1TZ3kdAG8UpZ8JcI9ZvTprmYq4IIZJ0R4NQTqtLILVfaL8HWMw/7HItXqrpeS7qtHVs557w3nsuN/I5OR8ufkL3Jdvj+VZPuaui83d9ovaCX8PDDye1yuv0k1k5HR7U4c10Fq1M8YMqS2R+qy2YiLFKl2kuQE6pZHKre9zERqs68ktjxSOdwiNSu2L6mNmuhr/VE2ipnUjKajZ56sc6hmpnRmKUcf628th+2XnY8RzBARrKM1IgN5pcq3xYDW6hRlNaZGKjD49/Z0UXBOle+ahmWRucWqA153jiXgQAgspzoykZpKqgd8UpacLQo+XVlhqWnWLRxO9/scLAp2Ose+GEFktki1Oc/nzvGuCJ8tL7NkRpiTUIsGuMOMszFy1Hs88HCMBJ2cQRM1twHfO8cbzvFxXbPLjHqdhNqO+sBdTcNHdc2LZcmvRcHOKe+PJe/7ej070uvZhSQa5736mGYxlT+q2sFez/YWxYR4GJNYrRDdC+w24zIz7hkdIAxuMnYBP6nyQ+a+b/vcjLbC8WbDyO/yWVJbjYU8kP8HKX/sOnQ6GT4AAAAASUVORK5CYII='
-
-led9 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAAEYklEQVRoge2ZT2gkRRTGf+91VXeQJcp6kAVBEFn/ggh7ET0IggjBGBNW1+Bpc1E8uDfPIgqC4OLNu6IL4oJ48+RR0LMXvQgii4d1E4PZdFc9D1M9yWRqJjPpbGbAfFBM0l3d7+tXr+q9r0oAY86gsyaQwympSTGXpFzuoqR2p2HkZ5kcvN6SOYkpOcrWECmAh1XxMbIDFHeATAQqIKjyS4zZPgaYpN9zInapquymqhlYDRaPsTVgBrYlYm+UpT1YlgP2AesHeuuRJTPWQ2CtLLklgks95RiaJTvbqqyWJa/EyEXVAfuQmX03gZeaho0QWPaev0RQoEluP2prkrFbIiyXJZdCYLVp+Nvy0WuAufT7WnKvgV0vCnumLO2PojBL7rcjtPa5G6r2bFnaV973771dVQP209957AArIbAAvO49n4lwFqiZbrkweuvOlggbIlwJgbUQ2AEWRjwzRKp1pk8EXgyBWoRHzThDbyimRQFsAdeAtRCoc4bHkWqDrA1KgIdiRMz4xyy/hkwCVc471yc57uOGSDmR3mjvQ2BvBsL0q70kEmFEUB9KKmew6yrfPjdpoh3uJyeR9cZjiNTsKZ16anLMZZE37Kl5HL55wGlMTYrhvJiJqTZPdfmCtq46iFyWGJmQc50iI4r6CZGrDDTjhH6/1tAmgAhmRkgkf1DlbIzcZ0ZzRDI3gO9FeJJegifZ2RwnHGiLdxH7uCzNRMzArjpny2VpO0lINGBhitakyrMWsVXv7aOy7FWdIvap94bIgGhIPIZ1n6nySVGwKMJ3wLW6xpsNlC/ToH0uAutVxfNmRDPeDAGJMRsOB1n26+XHqsq2i6IvjbpKqwD2r6o9UVWGqpUHpNVIT7XecqrUIrxTFFyta+IxeEpF2PCe+4EmRj5sGpTRs3KgFUVhImIKhnP2lvdmqhZVzTq0y1VlV1olI2LvOme0dsZ5SpM4jGlWFCIEVS6IcK8IzZTeMqAEfhfhZeCD3V3qdM+LcNF7vt7dpWBvVmZFRdw3TYMZzoyfY8QmrLGzUOXzJBw0kcWMc8kJ+z90nNLZI0a31VzoKeQmfdT+4cmJiYlItdO56/bQ0YXDHGAiUp1i6bB3Z67N3FNzSSqHmZOaS0/NjNTYDJCZRP9fT/UxoaY8UVIxM1QTCYccNNXsXVFkPHWk4VMgivRyn8iRWrsV8GP6sLDfwKQJuc3iDmhUWSoK3gd20p7ntDB6xx7vqbLoPet1zU56/yj/D1R9qrq3r61qz3lv20nJdN1H31K1FxYW7Bvn+vcuO3f4PrrR24xtRLjgHNebhrtinLrizL33TIx8efs2K95TqrIUY78K3Y8hUgXQiPCIc3wbAvfEyC7dT7ME2AXOmvFF07DiPQ80DYvjjkFo5Y6qPe6c/dlxyA4byt+Kwl5dWLCnve+FzSjh0P7zlCrnY2ST3snDcVZTQu8k427gVxF+yhwYdNmv6IxR+/PZJUE5mc0zIy9EZ+qpUZh5lZDDfw9J5SDpQQEIAAAAAElFTkSuQmCC'
-
-ledcolon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAA8CAYAAADhR3NQAAAACXBIWXMAADBKAAAwSgHCONjjAAABdklEQVRoge2YQU7DMBBFn9MEVVBYcADEmiVH4BScD3EL7gIcAYEEFSQdFrZRCJGYeBa1qnlSZSuVJz8/k/EkARAqo9m3gDlclBYXpcVFaXFRWlyUFhelpUpRrWVxAFaTYwIMlqApbnX9VJFT+UpOgRugA3ZE195C4EHE7JYs/TVpvAJ5BxGQPo1PTSObEASQUBA7xS/nE/hI8+yMEJ20YBK1G81zwnfWoKXr85MxAF9p3o/+24tT45N2k/EYOLIoovDpy069AvfAOdGxDngR+cmzUg6nTv0XoJ85toQqnapyQ3ZRWlyUFhelpUpR5oo+1xFYq3GVFd3Uo18Cd8CGuN+tgcem4VaErUjxFZtErYFr4ITY8K2AM2ILsy0JnDD36Pnk49a4mh49B2qtQUvX5zzZ8TdnVqVBR5jWD/x2C6Ko6av8UkwloQUuiImd32J64Bnb94TDqVNj5u7/9JYupUqnqtyQXZQWF6XFRWlxUVpclBYXpeUbS+1qOYf8HRgAAAAASUVORK5CYII='
-
-ledblank = 'data:image/png;base64,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/GMzLdsAADpEaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0NSA3OS4xNjIzMTksIDIwMTgvMDIvMTUtMjA6Mjk6NDMgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBFbGVtZW50cyAxNy4wIChXaW5kb3dzKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxOC0xMC0yMFQxNjowOToyNS0wNDowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE4LTEwLTIwVDE2OjM2OjMyLTA0OjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxOC0xMC0yMFQxNjozNjozMi0wNDowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHBob3Rvc2hvcDpJQ0NQcm9maWxlPnNSR0IgSUVDNjE5NjYtMi4xPC9waG90b3Nob3A6SUNDUHJvZmlsZT4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDoxYTc5NDQ5ZC05ZmM0LWZiNGItOTNjYy0xNTcyMjU1MGU5OTk8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPmFkb2JlOmRvY2lkOnBob3Rvc2hvcDpkMGIzZGFmNS1kNGE3LTExZTgtOGI3ZC1jYmQxMWFlODBkMGE8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+eG1wLmRpZDowZDlkYjE1OS1lYThmLWQxNDEtYWE4MS04YTY4NzFkNTI4YTc8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jcmVhdGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6MGQ5ZGIxNTktZWE4Zi1kMTQxLWFhODEtOGE2ODcxZDUyOGE3PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE4LTEwLTIwVDE2OjA5OjI1LTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgRWxlbWVudHMgMTcuMCAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjFhNzk0NDlkLTlmYzQtZmI0Yi05M2NjLTE1NzIyNTUwZTk5OTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxOC0xMC0yMFQxNjozNjozMi0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIEVsZW1lbnRzIDE3LjAgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjMxNDAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjMxNDAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+Mzc8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NjA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PvnJsBAAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAEZJREFUeNrszkEBACAMAKHT/p1nDPeABJxqWua2kJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSU1G8PAAD//wMAGdkBdyV2S1QAAAAASUVORK5CYII='
-
-w1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAABGCAYAAABxLuKEAAAACXBIWXMAAAsSAAALEgHS3X78AAAUjklEQVR4nO2ceZhddXnHP+/vnHO3mTt7MknIQhYSAhgSaAuGLaDYggqiVlyKLQ8V96WWAlJNQ6ViK23R1gcLPlpRXEr1AQOUnTYoQVlCICEbIRCTTGYyy52Zu57l9/aPc2ZJyDJDJsE/eJ/nPHfOuef83t/ve979/d0RVeVNei2ZN3oCv6/0JjAHoDcSGEmO30ty30DeBzNuMoZ7jigdBYnR/UuF+g5qnf0/YxWNDgCKygHHnEB6A1RJY5619ZcTbj8juZYAlCy4tulCgm3nx9f2BU80Po4sHVlgtJpGo30Wliw+2PVW/M1/nFxzR8ABKk9fiR2YmZzJXp+23IYdaN9rrCNARwiYRCr8l9+q5dVXxteG3rzGdk1rBa2sPxNwQHwglgRbaaa2+QxVwuT+oefij/Jj1xINTk0Y/b4Do/v3ME5rhxQfuoqwayGYKF6k8eNHwpL4L51N1D0fRIl2ngqAv+k8DTvbIJoSDyJRDKoolWc/otVNy/COeS7mKXafOUwYTQAwKqg1gI68XVFQg9u2XTG7tfDjb8XXI6PBCxdBUI9GU4l6obb5NGznWVR/8b9obTK1zWeLLSNqBwA0WPduMBG23KoDP/973PZ1Cd9RHlUNiKLRhIFzuMAIiGrl6XcRds8ZebtDcu9UJD3vWSk9/nZKqy8HN5Lqw3dRW3UTdmA2CFr+7efwn7oBreWo3HcP1RcvAgfCnjZqD3xHar/+BoQNOnDPCvFfnSOpWasT1lH8GXkgVv1Nb1N/8znxNT3sF+6sWLHiMB6PRVyi/nZ6//NmMic8hqnvi+fbPQ8xGWzNpfzUewk7jsdrrkc7zsJ2naa271j8QRHjT8XVmZAC7T0Gv6sJVSVll6I9pyNpS9Cfk+KDn0RSHg3vuQYJm9FqFskOgLFU1lzM4L03SP15tyHpwkSYnsNE1kQQOWROXIXTuJ2O657Af/UPY2C2L6P0g1XQfRGmPsDfMZ/i3TcguGikkmo2kpsD2emKySpiBFNvyU5X6mYJbiaDYlG/lfLD1xIO5tTUdxO9dAWl29diu08GoPzbP6fn5rskd9pPMQ3bIHKZgMBQxp9dDxnaIcOnBsQS7FqgOz+3FpMbkMnXXopXl6J4x/1IGiIfKq8qmWmQbhdUQWvxEZXA+slwBkwGTBYkq4gnIFDbbfF7DbnpiqiCNdR/7GxKa99C323f1tTcTdK+/Ewk1T08HxCwJn55RweYmOewLTF2eDK9P/w7+m5fgTdtpzac95SYwgWo7yGewaTBVpVgl+DvgqiMqiB4YNzELChoAASxz3Hq0dQ0JDUVxANbA40iTEoJnHWUnnoLGjm0fvLj1C29NTb+YhMVjxInIK8nIBwPMAIopSfPx20skl64ehiQqPM4/PWXoVKl5/vX4vfWk2qChiWC8cAGUNkA1VdQ0og7BZxm1GQQceOhdQhyC0SoLSNRHxp2IkRoZg6Smw84oFUY3KBENSE9q5OWD60g3DWf7Bk3Ivk98XStS2n1RzF1vyO7+KFRkjTRwFgDxuJvX6KdN35P0nN/S/OHb8KbtgUNm3Xg289g+2YjuYigz6BWyc4wVLYgg8+C5CA9F5wGwIJGQCLlOiSFCjJkOB0YAi3qQ2tbEUK04Y+Q1Ay0tjNCPIPXaLH9jjgzV9NwxbmgSmX9BfT/7HpM6w4mffpSJF0ar+SMU5WSwWvbTmbHpx8F69Jw4Y9p+sBXCbdcTfWRzyPZCHEdxIXCY2jld0jmBEi1JqoQMlJxGAKEff4eOk8+xQNJQdAJ1U1o3fFI41vBVsHaEK265C5YDvUrtf8XN0npibeRXfIkU5afj6SL45WW1wEMxFbfCam9dDo7Pnc3Yddk3Kk7qV/STypzAph4hT3/A1ENcicBYWJghdgRjpVnApTa+BmTARQtvYCk2qD1bWADRUSoFDqpbW3QaCBLdsmvZcpXLsXU7xyW9HHSGIBJIlsRHWagQQrxMlr69SWy+4bvojUHEJrOBjcDXSvjxWTmgi3HC5yImHRI5UwWKhtRtwlpuwDCPhhcH3/pTe2m/W/fi9f+PEoFcf1YYjT2huKMyUuNV5WILb5RBu/8KeH2i7FlsJUUYHEajPY+CkE3kp0NYQkYFQgfNg2ha8HJQnkr5OZA0+kQDlhEDU5zBTSFd8L3qX/3x8C6YMJxczowMIk9CXa3a2XN2yV70rN4MzYkLjEi2rNIC//+f6htQlzFyQr9a5D+p+PJ2gpHvNxjPLS8DVrPhbq5ENUUrQmm8RVp/sxZSN0OQLCVFiprT9eoPyP5ZSuRtH+ooQ9S2kzejtM0KEHPdO268uuCCTR36iOSmfcCmcW/ktTiX1L9zUfBjajtcel7EjJtEBYmaOUHozhPFS+Pdq9CUu0gjqIquMetovT0H1Jd/yVqL59CdeNJpGZslNYrvhyDcmgPNTYbgyj+9hPZ/Q9f18Jd74oj07pI3KaAhsUZMtNVd98nUtmKZtvjuOWo1LkVHA8p7ULzpyKTzkKrO5DiRotWBVsSTH2F1ituovnD/4hJlxhxhwelsdmYYeMryuCq89h9438S9czAySl1CwWTg23fh7pWMN5Y+E4ciYGwDLUazP4LCHqh1mmJykazJz4uk/76ClLHbBmpFY/NQ42tSyAmjkujwhRM7VyazzJE3eDUK05K6FwFYQXESeKUo0gaxTFObRcMbIbmReC1CraKeLObCTZejNPwHZx8aSSHip882LAHAWaoAJVUz0RCTF2RqLedcOdUTD1EZYMG6MDWOA6zo6LZo0aCqkCk0L8ZaVwItiaIq/gbTiI1G5x8EbVunICKxgAdXNUPZnw19vmj/L6YCg2XXokzaQOD9/4LTlrx+0QqXTH+4ZBtOZqqJPELsQLlDjQoqjhpUB/q3/tZ6pbdivo5xCsnXlJAU3G2emADvB8bM+SmO46j/4F3am3LDKLByULUrjaoii05aotToLJEGpaIDryMbLsrDttzdZDKJoHY0SCNbUytDJUiGIG5l8aecXBdoHgv4qRdJFMSpAAu6rYYqTv95zRd9B0kLfFkXys9+5GYBEW3dQf1S+8Twot04NEztPzMIqntzCKpODTPzAQNEb8fohBcDyolME48waOBjYBGAVJNouvQR/0BJNMMtuhJ0H0ytgbGQdPzt0rd0pWSX/YomROeQDyIkd3/0GNw1wnT7kmUfnsmfT/5KsaeSGqKYlxh1yroeBLcHNgIXBfNZeO86IhKTqyyUi5DGIExEFZh5tth8ikQ+VZrHUa8OY/S/JGryBy3DvGCsY5+CK80nCcJbuseleAU8eoXIgaiiiBZiMI4x7NJQcUPISoh2XQ82SMBjgCRhaqP2sT7JnOQyI/jqKgm4jUDhbMJX7kQWbgGjVxE7Fi6mYcARhQxNu4xh65kFv4PtthC9YVLscVWUEVjVjEwQ9IVQbECKRe8JC2YCHyGpD6wUAtHXUrWaYf5xBMxTV2aXXKHZE58YKRPPrbA81DuOo5hxAnBCKn5T6CpPQw8u4TglbdSP08xKUHZp9cuMVAVH/UN4pnYIZgEHR3LBHVkHZrYrCgBxY4uaCU3KXH9y0khGirVbaLenJ3ScPwPcY9Zizjjas4dyl2DLTdSfWkhg6v+mMKD79bKC4slKgpOC2SmG03lh8X4tWojECgaRHGS7ShiSCR5aNGjMHqNg0yGjEwMih0Z9rW8FMRBvDo0KhrKLyP2uSVaWPks6XkbyJ91n+TPeYzMwmfw2ncfCpgDu2u/czKFey6hcN9lFJ9eStAtiAFTr5pqQxpPFrxGKO5GN6w8FJ+9F74XOLoPMMnbV1ArI5bgkAKm4KaREy6GTBPUetDyxkhsxWKrHhqB29Sn2YWbaH7/LdL8p7eDEWT/Sn5grxQV8wS7WtCoDshj/QCtpSk9dQ2VJy7GrQ+xgYsqun4lUukFxxu7sR214KFHJMFkzGAMryJx1Y3HIAsvjI2vuKhGBWl836fJnrQByZSQVCdabUK8Mm7rnoMxOLAqOfWDOPMHk1XEUqS1POVH26AKkXEwGfBcyLdjB3sSvT80MHtNZ9TtQwDpqO/GBrPEDduGaXEcZS2ob8UONuFv/hMa3vHjOG5RAekf04gHj2NGW1RRbLku9kZSR/cPvqL9D3yQ7DGWwR6j6+/fxyAeRVIF4yCL3g2ZrKXaYcgve1AmffyLiNOHZAqYbGXvhw7urg9RYhuq84qi1mDqipimDrp/uZSOH54mhTVIpUNonAL1k5EwRJDhKOGoHBgkjJCWmVDXAuWdIoMvwp47F9P90/cgmUFMroxaE2ebY9uRNcaabzyglp5fzLar/43Cg2cirkrdfKHxZHActNCJvvAQOEnr+KikBEOpjoNZ/A7INkEUQOl5qGxXtCaaP32DzLjxc+TPeHg8vaUxqJIoQWc7O26+il3/+kUVE5F7yybSM6qSkiU4GbC+g5fGbv4NumMzpLxYz4+0ZomAH2LmLEaOXQRBBUwKrB1AWu6ntm0W5XULCAtNOukjP5ZpVy8nfezWMQ19kGI4cRRbSLHjpmsJumbTdO7jZOevJTPnZQYfvoruW67D5CNMvYMBIp9ozSMw2Aeel/SDjgQ6GqcbtQBpm4ZZdE4c44iBcFCxZdGp131K8ufeQnXzCfg7ZzGweilYmPwXt5Gavv1Q0nNoVVLfIarkcBsHR100DDzyCSCHDdrYvuIawoJq8yKhWsE++yj4VXCPVK4kEERQ34hZch4YixRfAicfMv3L38Kk9iBuH/llt8VFqQQEW8mAgMlUD8lizH0ljZxhBpJUwVQ93fLJf5fO26/UdLulZYkRN4UO9hKt/RVUq0jKjSVndIT7ekgZ9nrqR0i+CXPyUiRbB0EVBl6ICPocWt//E+bdcjni1eKQWUi2whGnNoedK+1Dwx08lTgkNY6+/FfflV23fhRxrKQbwclEBCWR+ibjnLIMu+43aF8fpEySEb9O6RGSIM5CoMjkdpyTTotjqKBmcXKqXoPB77J0fe9DGLcmc79zJUqEiCLuRDbc9kejKu2vrvgaL13/JbLtgzr5w/8l7uA51DbOw8kr6gkSoRjs1o3oq1tjY+wJMjr+PxjroZhIQK3GgKRSyOy5mFkL4l44HkhoCfuM1i1dDU2P0/WDyylumcTMq74ls7/x+bjmOZR7HClgNDKIY3X7P31RXl7+T0y7/A6mf/6fSbd3s/2LD5GetUXDalZ23PYOUq2W5hMMxqCFHuy2zWh3V5wdG5LDjOQBw9l04oKtTZJTIOUg7dMwx85DGpogCGFgoyUcMEy9bDXG9BP2TWXmzcsIelvp/N6ndOe/fYwpH7tVZn/tb3gdwcN49scIGKX77g9p18/fJbOuuYm6E9cAEPXXY8tNeFN3sO4Dd9B154epnxvRvNDBWovnGsRF+3uwHTvQnh60XIIgGJny6PxIgFQaqatD2towU6bHgISBEllF1NC/PqLa4WjLBffLiXe9E3/nApyGDpx83Ab1O+bojm9cR+NZD0nrJT8bTwwzTmAADV2qr84jfcyrmEwlNmqJeokb0n3Phax73z1ghfzx/TTOyxL2pZA0VHviACyVR/0qlEtouYJWyxD4cdnCSAxINofkckgmB14aagUISpBqAfVRtzGg+LuCDG6YhCh6/I8+IG3vvROsGZY+cSxqDf7uVlLt3YgzLqkZX9dd3JDs3I2I58clT2MRJ0JMhAYuO2/9OFVfaHvfj3TWdV/S2quO5k7erKVCiZ41aKUQqV8FtSr5RjWTWjCzZmGOOx6z4HjM/IU4M2dg2logl1fVCA1qSqU3ovc5tNrfr+k5W6ht92TuN7/A5A/djl9BOv7jUxC5xPVEjYtS1oAV0tP2jBeU8QMDwBAgQ3tlonhbSO9j5+nulRfpzMv+ixN/8peSnraF9s8ul/a/eSfVvm5FoNphBBOJ9dFqj7D7aSi8ogSRpVoGP7D0vqTa+RzUCiIaxKa61mNQg5Q7y3LM9Rcy6S9vxGnYxILb/lxnfuEWuh5cxp5fXoIYHflRh7GIG42lWrc/eh07qkbTSOatvzn1GZrOXC0LvvkZQLBVF5MJ6H34XJ5/z71E5SyzPv8w4brz8Fq3aLE3TfdDx5JqVmleIHh5S1A09G5Uwj6hdVk3ubomxOvA+4OH2Pa1P0OiFCc/eAFNZ9+PBl68eCdi2/Vf1+67z5dTHj8Hp644XnuyPzq8DSxD2eruH13C5Et+Lgu++Rk0MonNie+pbJtHpZSl5U/uZ/YN7yN93H8zbflHJLvoXokAt22Xtrz/TsIeZfKV12tq5gYNgbo/+qFOW3EZ3pynmHXdJ2g5/zGqNSiuPT6Zeiy1Ghpm/921TLviDrrvvmBkXodJqnp4hw08LW+dq1E1FV+zJrnuqir64idu1QdQLT6/WFXRoDerquiWq1fovai+8MEfadg3WXd+/R9VFfviFbfpvai+dM1fqyrq7zlWVdHy5pPsI00lu/6jP4vHD51kDqI2MqpWtLq9XTWSw16T6gRseRI3IDtna6zPQzvGEy+ltTrtfeY05qxYTt1bnkMjB6ch3s3ktMbV1knvWYnT1MWUv/oKAM1vfwQAUxfPzW3egQYu2ePWybzlN1B48g8AJ7ZxmnTdkr/TMzpHWhGHRxOzF0xVEmOsw+cAxQ0LyLX9jmO/cDMAYkaMoclFmsoXaTpjdfJdXApvfceDZHIVJJWJB48M4kaowozP/gv5RWso/PrUpHg2SmWGgZoQmphf0co+hm743Pgy+8v/gNs4OOzeh4yiyA5pPudXpKdvRyMHcQPUGryWXprPfELR/NBm1jhxVQG3JvNuvJqoqvvlO4G/lTxCPy9OJphftG4kABzayZR85+TQSec9luTLe9fHJ196B1E5F5+ZUWOqkJ338sidE6M2+6Mj/LtrlaRcMGoB8d+19ElryWWKaWB4+1dyX9jwtgfU72hKxd9Fez+7vzEnng4zjnn9ZOM+t5j9NLxUQVHMG9V14A0EBvbuP76WDj9IOxx6I4H5vaY3/xvIAehNYA5AbwJzAHoTmAPQm8AcgN4E5gD0/1bxlgNoWAgGAAAAAElFTkSuQmCC'
-
-w2 = 'data:image/png;base64,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'
-
-w3 = 'data:image/png;base64,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'
-
-w4 = 'data:image/png;base64,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'
-
-w5 = 'data:image/png;base64,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'
-
-orangeround = 'data:image/png;base64,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'
-
-weather_icon_dict = {'clear-day': w1, 'clear-night': w1, 'rain': w3, 'snow': w3, 'sleet': w3, 'wind': w3, 'fog': w3,
- 'cloudy': w4, 'partly-cloudy-day': w5, 'partly-cloudy-night': w5}
-
-led_digits = [led0, led1, led2, led3, led4, led5, led6, led7, led8, led9]
-
-if __name__ == '__main__':
- led_clock()
diff --git a/DemoPrograms old/Demo_LED_Indicators.py b/DemoPrograms old/Demo_LED_Indicators.py
deleted file mode 100644
index 790b3cb8..00000000
--- a/DemoPrograms old/Demo_LED_Indicators.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-import sys
-
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import time
-import random
-
-"""
- Demo program showing how to create your own "LED Indicators"
- The LEDIndicator function acts like a new Element that is directly placed in a window's layout
- After the Window is created, use the SetLED function to access the LED and set the color
-
-"""
-
-
-def LEDIndicator(key=None, radius=30):
- return sg.Graph(canvas_size=(radius, radius),
- graph_bottom_left=(-radius, -radius),
- graph_top_right=(radius, radius),
- pad=(0, 0), key=key)
-
-def SetLED(window, key, color):
- graph = window.FindElement(key)
- graph.Erase()
- graph.DrawCircle((0, 0), 12, fill_color=color, line_color=color)
-
-
-layout = [[sg.Text('My LED Status Indicators', size=(20,1))],
- [sg.Text('CPU Use'), LEDIndicator('_cpu_')],
- [sg.Text('RAM'), LEDIndicator('_ram_')],
- [sg.Text('Temperature'), LEDIndicator('_temp_')],
- [sg.Text('Server 1'), LEDIndicator('_server1_')],
- [sg.Button('Exit')]]
-
-window = sg.Window('My new window', default_element_size=(12, 1), auto_size_text=False).Layout(layout).Finalize()
-
-i = 0
-while True: # Event Loop
- event, value = window.Read(timeout=400)
- if event == 'Exit' or event is None:
- break
- if value is None:
- break
- i += 1
- SetLED(window, '_cpu_', 'green' if random.randint(1, 10) > 5 else 'red')
- SetLED(window, '_ram_', 'green' if random.randint(1, 10) > 5 else 'red')
- SetLED(window, '_temp_', 'green' if random.randint(1, 10) > 5 else 'red')
- SetLED(window, '_server1_', 'green' if random.randint(1, 10) > 5 else 'red')
diff --git a/DemoPrograms old/Demo_Layout_Generation.py b/DemoPrograms old/Demo_Layout_Generation.py
deleted file mode 100644
index 201a0ce0..00000000
--- a/DemoPrograms old/Demo_Layout_Generation.py
+++ /dev/null
@@ -1,289 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- PySimpleGUI is designed & authored in Python to take full advantage the awesome Python constructs & capabilities.
- Layouts are represented as lists to PySimpleGUI. Lists are fundamental in Python and have a number of powerful
- capabilities that PySimpleGUI exploits.
-
- Many times PySimpleGUI programs can benefit from using CODE to GENERATE your layouts. This Demo illustrates
- a number of ways of "building" a layout. Some work on 3.5 and up. Some are basic and show concatenation of rows
- to build up a layout. Some utilize generators.
-
- These 8 "Constructs" or Design Patterns demonstrate numerous ways of "generating" or building your layouts
- 0 - A simple list comprehension to build a row of buttons
- 1 - A simple list comprehension to build a column of buttons
- 2 - Concatenation of rows within a layout
- 3 - Concatenation of 2 complete layouts [[ ]] + [[ ]] = [[ ]]
- 4 - Concatenation of elements to form a single row [ [] + [] + [] ] = [[ ]]
- 5 - Questionnaire - Using a double list comprehension to build both rows and columns in a single line of code
- 6 - Questionnaire - Unwinding the comprehensions into 2 for loops instead
- 7 - Using the * operator to unpack generated items onto a single row
- 8 - Multiple Choice Test - a practical use showing list comprehension and concatenated layout
-"""
-
-"""
- Construct #0 - List comprehension to generate a row of Buttons
-
- Comprehensions are super-powers of Python. In this example we're using a comprehension to create 4 buttons that
- are all on the same row.
-"""
-
-
-def layout0():
- layout = [[sg.Button(i) for i in range(4)]] # A list of buttons is created
-
- window = sg.Window('Generated Layouts', layout)
-
- event, values = window.Read()
-
- print(event, values)
- window.Close()
-
-"""
- Construct #1 - List comprehension to generate a Column of Buttons
-
- More list super-power, this time used to build a series of buttons doing DOWN the window instead of across
-
-"""
-
-def layout1():
- layout = [[sg.Button(i)] for i in range(4)] # a List of lists of buttons. Notice the ] after Button
-
- window = sg.Window('Generated Layouts', layout)
-
- event, values = window.Read()
-
- print(event, values)
- window.Close()
-
-
-"""
- Construct #2 - List comprehension to generate a row of Buttons and concatenation of more lines of elements
-
- Comprehensions are super-powers of Python. In this example we're using a comprehension to create 4 buttons that
- are all on the same row, just like the previous example.
- However, here, we want to not just have a row of buttons, we want have an OK button at the bottom.
- To do this, you "add" the rest of the GUI layout onto the end of the generated part.
-
- Note - you can't end the layout line after the +. If you wanted to put the OK button on the next line, you need
- to add a \ at the end of the first line.
- See next Construct on how to not use a \ that also results in a VISUALLY similar to a norma layout
-"""
-
-def layout2():
- layout = [[sg.Button(i) for i in range(4)]] + [[sg.OK()]] # if want to split, can't add newline after + to do it
-
- window = sg.Window('Generated Layouts', layout)
-
- event, values = window.Read()
-
- print(event, values)
- window.Close()
-
-
-"""
- Construct # 3 - Adding together what appears to be 2 layouts
-
- Same as layout2, except that the OK button is put on another line without using a \ so that the layout appears to
- look like a normal, multiline layout without a \ at the end
-
- Also shown is the OLD tried and true way, using layout.append. You will see the append technique in many of the
- Demo programs and probably elsewhere. Hoping to remove these and instead use this more explicit method of +=.
-
- Using the + operator, as you've already seen, can be used in the middle of the layout. A call to append you cannot
- use this way because it modifies the layout list directly.
-"""
-
-def layout3():
- # in terms of formatting, the layout to the RIGHT of the = sign looks like a 2-line GUI (ignore the layout +=
- layout = [[sg.Button(i) for i in range(4)]]
- layout += [[sg.OK()]] # this row is better than, but is the same as
- layout.append([sg.Cancel()]) # .. this row in that they both add a new ROW with a button on it
-
- window = sg.Window('Generated Layouts', layout)
-
- event, values = window.Read()
-
- print(event, values)
- window.Close()
-
-
-"""
- Construct 4 - Using + to place Elements on the same row
-
- If you want to put elements on the same row, you can simply add them together. All that is happening is that the
- items in one list are added to the items in another. That's true for all these contructs using +
-"""
-
-def layout4():
- layout = [[sg.Text('Enter some info')] + [sg.Input()] + [sg.Exit()]]
-
- window = sg.Window('Generated Layouts', layout)
-
- event, values = window.Read()
-
- print(event, values)
- window.Close()
-
-
-"""
- Construct #5 - Simple "concatenation" of layouts
- Layouts are lists of lists. Some of the examples and demo programs use a .append method to add rows to layouts.
- These will soono be replaced with this new technique. It's so simple that I don't know why it took so long to
- find it.
- This layout uses list comprehensions heavily, and even uses 2 of them. So, if you find them confusing, skip down
- to the next Construct and you'll see the same layout built except for loops are used rather than comprehensions
-
- The next 3 examples all use this same window that is layed out like this:
- Each row is:
- Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
- Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
- ...
-
- It shows, in particular, this handy bit of layout building, a += to add on additional rows.
- layout = [[stuff on row 1], [stuff on row 2]]
- layout += [[stuff on row 3]]
-
- Works as long as the things you are adding together look like this [[ ]] (the famous double bracket layouts of PSG)
-"""
-
-def layout5():
- questions = ('Managing your day-to-day life', 'Coping with problems in your life?', 'Concentrating?',
- 'Get along with people in your family?', 'Get along with people outside your family?',
- 'Get along well in social situations?', 'Feel close to another person',
- 'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
-
- layout = [[sg.T(qnum + 1, size=(2, 2)), sg.T(q, size=(30, 2))] + [sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, col)) for col in range(5)] for qnum, q in enumerate(questions)]
- layout += [[sg.OK()]]
-
- window = sg.Window('Computed Layout Questionnaire', layout)
- event, values = window.Read()
-
- print(event, values)
- window.Close()
-
-
-"""
- Construct #6 - Computed layout without using list comprehensions
- This layout is identical to Contruct #5. The difference is that rather than use list comprehensions, this code
- uses for loops. Perhaps if you're a beginner this version makes more sense?
-
- In this example we start with a "blank layout" [[ ]] and add onto it.
-
- Works as long as the things you are adding together look like this [[ ]] (the famous double bracket layouts of PSG)
-"""
-
-
-def layout6():
- questions = ('Managing your day-to-day life', 'Coping with problems in your life?', 'Concentrating?',
- 'Get along with people in your family?', 'Get along with people outside your family?',
- 'Get along well in social situations?', 'Feel close to another person',
- 'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
-
- layout = [[]]
- for qnum, question in enumerate(questions): # loop through questions
- row_layout = [sg.T(qnum + 1, size=(2, 2)), sg.T(question, size=(30, 2))] # rows start with # and question
- for radio_num in range(5): # loop through 5 radio buttons and add to row
- row_layout += [sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, radio_num))]
- layout += [row_layout] # after row is completed layout, tack it onto the end of final layout
-
- layout += [[sg.OK()]] # and finally, add a row to the bottom that has an OK button
-
- window = sg.Window('Computed Layout Questionnaire', layout)
- event, values = window.Read()
-
- print(event, values)
- window.Close()
-
-
-
-"""
- Construct #7 - * operator and list comprehensions
- Using the * operator from inside the layout
- List comprehension inside the layout
- Addition of rows to layouts
- All in a single variable assignment
-
- NOTE - this particular code, using the * operator, will not work on Python 2 and think it was added in Python 3.5
-
- This code shows a bunch of questions with Radio Button choices
-
- There is a double-loop comprehension used. One that loops through the questions (rows) and the other loops through
- the Radio Button choices.
- Thus each row is:
- Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
- Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
- Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
-
- What the * operator is doing in these cases is expanding the list they are in front of into a SERIES of items
- from the list... one after another, as if they are separated with comma. It's a way of "unpacking" from within
- a statement.
-
- The result is a beautifully compact way to make a layout, still using a layout variable, that consists of a
- variable number of rows and a variable number of columns in each row.
-"""
-
-def layout7():
- questions = ('Managing your day-to-day life', 'Coping with problems in your life?', 'Concentrating?',
- 'Get along with people in your family?', 'Get along with people outside your family?',
- 'Get along well in social situations?', 'Feel close to another person',
- 'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
-
- layout = [[*[sg.T(qnum + 1, size=(2, 2)), sg.T(q, size=(30, 2))], # These are the question # and the question text
- *[sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, col)) for col in range(5)]] for qnum, q in enumerate(questions)] + [[sg.OK()]] # finally add an OK button at the very bottom by using the '+' operator
-
- window = sg.Window('Questionnaire', layout)
-
- event, values = window.Read()
-
- print(event, values)
- window.Close()
-
-
-"""
- Construct #8 - Computed layout using list comprehension and concatenation
- This layout shows one practical use, a multiple choice test. It's been left parse as to focus on the generation
- part of the program. For example, default keys are used on the Radio elements. In reality you would likely
- use a tuple of the question number and the answer number.
-
- In this example we start with a "Header" Text element and build from there.
-"""
-
-def layout8():
- # The questions and answers
- q_and_a = [
- ['1. What is the thing that makes light in our solar system', ['A. The Moon', 'B. Jupiter', 'C. I dunno']],
- ['2. What is Pluto', ['A. The 9th planet', 'B. A dwarf-planet', 'C. The 8th planet', 'D. Goofies pet dog']],
- ['3. When did man step foot on the moon', ['A. 1969', 'B. 1960', 'C. 1970', 'D. 1869']], ]
-
- layout = [[sg.Text('Astronomy Quiz #1', font='ANY 15', size=(30, 2))]] # make Header larger
-
- # "generate" the layout for the window based on the Question and Answer information
- for qa in q_and_a:
- q = qa[0]
- a_list = qa[1]
- layout += [[sg.Text(q)]] + [[sg.Radio(a, group_id=q)] for a in a_list] + [[sg.Text('_' * 50)]]
-
- layout += [[sg.Button('Submit Answers', key='SUBMIT')]]
-
- window = sg.Window('Multiple Choice Test', layout)
-
- while True: # Event Loop
- event, values = window.read()
- if event in (None, 'SUBMIT'):
- break
- sg.popup('The answers submitted were', values)
- window.close()
-
-
-# ------------------------- Call each of the Constructs -------------------------
-
-layout0()
-layout1()
-layout2()
-layout3()
-layout4()
-layout5()
-layout6()
-layout7()
-layout8()
diff --git a/DemoPrograms old/Demo_Listbox_Search_Filter.py b/DemoPrograms old/Demo_Listbox_Search_Filter.py
deleted file mode 100644
index 88f4ce45..00000000
--- a/DemoPrograms old/Demo_Listbox_Search_Filter.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import PySimpleGUI as sg
-
-names = ['Roberta', 'Kylie', 'Jenny', 'Helen',
- 'Andrea', 'Meredith','Deborah','Pauline',
- 'Belinda', 'Wendy']
-
-layout = [ [sg.Text('Listbox with search')],
- [sg.Input(do_not_clear=True, size=(20,1),enable_events=True, key='_INPUT_')],
- [sg.Listbox(names, size=(20,4), enable_events=True, key='_LIST_')],
- [sg.Button('Chrome'), sg.Button('Exit')]]
-
-window = sg.Window('Listbox with Search').Layout(layout)
-# Event Loop
-while True:
- event, values = window.Read()
- if event is None or event == 'Exit': # always check for closed window
- break
- if values['_INPUT_'] != '': # if a keystroke entered in search field
- search = values['_INPUT_']
- new_values = [x for x in names if search in x] # do the filtering
- window.Element('_LIST_').Update(new_values) # display in the listbox
- else:
- window.Element('_LIST_').Update(names) # display original unfiltered list
- if event == '_LIST_' and len(values['_LIST_']): # if a list item is chosen
- sg.Popup('Selected ', values['_LIST_'])
-
-window.Close()
diff --git a/DemoPrograms old/Demo_MIDI_Player.py b/DemoPrograms old/Demo_MIDI_Player.py
deleted file mode 100644
index 11b4445c..00000000
--- a/DemoPrograms old/Demo_MIDI_Player.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import os
-import mido
-import time
-import sys
-
-PLAYER_COMMAND_NONE = 0
-PLAYER_COMMAND_EXIT = 1
-PLAYER_COMMAND_PAUSE = 2
-PLAYER_COMMAND_NEXT = 3
-PLAYER_COMMAND_RESTART_SONG = 4
-
-# ---------------------------------------------------------------------- #
-# PlayerGUI CLASS #
-# ---------------------------------------------------------------------- #
-class PlayerGUI():
- '''
- Class implementing GUI for both initial screen but the player itself
- '''
-
- def __init__(self):
- self.Window = None
- self.TextElem = None
- self.PortList = mido.get_output_names() # use to get the list of midi ports
- self.PortList = self.PortList[::-1] # reverse the list so the last one is first
-
- # ---------------------------------------------------------------------- #
- # PlayerChooseSongGUI #
- # Show a GUI get to the file to playback #
- # ---------------------------------------------------------------------- #
- def PlayerChooseSongGUI(self):
-
- # ---------------------- DEFINION OF CHOOSE WHAT TO PLAY GUI ----------------------------
-
- layout = [[sg.Text('MIDI File Player', font=("Helvetica", 15), size=(20, 1), text_color='green')],
- [sg.Text('File Selection', font=("Helvetica", 15), size=(20, 1))],
- [sg.Text('Single File Playback', justification='right'), sg.InputText(size=(65, 1), key='midifile'), sg.FileBrowse(size=(10, 1), file_types=(("MIDI files", "*.mid"),))],
- [sg.Text('Or Batch Play From This Folder', auto_size_text=False, justification='right'), sg.InputText(size=(65, 1), key='folder'), sg.FolderBrowse(size=(10, 1))],
- [sg.Text('_' * 250, auto_size_text=False, size=(100, 1))],
- [sg.Text('Choose MIDI Output Device', size=(22, 1)),
- sg.Listbox(values=self.PortList, size=(30, len(self.PortList) + 1), key='device')],
- [sg.Text('_' * 250, auto_size_text=False, size=(100, 1))],
- [sg.SimpleButton('PLAY', size=(12, 2), button_color=('red', 'white'), font=("Helvetica", 15), bind_return_key=True), sg.Text(' ' * 2, size=(4, 1)), sg.Cancel(size=(8, 2), font=("Helvetica", 15))]]
-
- window = sg.Window('MIDI File Player', auto_size_text=False, default_element_size=(30, 1), font=("Helvetica", 12)).Layout(layout)
- self.Window = window
- return window.Read()
-
-
- def PlayerPlaybackGUIStart(self, NumFiles=1):
- # ------- Make a new FlexForm ------- #
-
- image_pause = './ButtonGraphics/Pause.png'
- image_restart = './ButtonGraphics/Restart.png'
- image_next = './ButtonGraphics/Next.png'
- image_exit = './ButtonGraphics/Exit.png'
-
- self.TextElem = sg.T('Song loading....', size=(70, 5 + NumFiles), font=("Helvetica", 14), auto_size_text=False)
- self.SliderElem = sg.Slider(range=(1, 100), size=(50, 8), orientation='h', text_color='#f0f0f0')
- layout = [
- [sg.T('MIDI File Player', size=(30, 1), font=("Helvetica", 25))],
- [self.TextElem],
- [self.SliderElem],
- [sg.Button('', button_color=sg.TRANSPARENT_BUTTON,
- image_filename=image_pause, image_size=(50,50), image_subsample=2, border_width=0, key='PAUSE'), sg.T(' '),
- sg.Button('', button_color=sg.TRANSPARENT_BUTTON,
- image_filename=image_next, image_size=(50,50), image_subsample=2, border_width=0, key='NEXT'), sg.T(' '),
- sg.Button('', button_color=sg.TRANSPARENT_BUTTON,
- image_filename=image_restart, image_size=(50,50), image_subsample=2, border_width=0, key='Restart Song'), sg.T(' '),
- sg.Button('', button_color=sg.TRANSPARENT_BUTTON,
- image_filename=image_exit, image_size=(50,50), image_subsample=2, border_width=0,key='EXIT')]
- ]
-
- window = sg.Window('MIDI File Player', default_element_size=(30, 1), font=("Helvetica", 25)).Layout(layout).Finalize()
- self.Window = window
-
-
-
- # ------------------------------------------------------------------------- #
- # PlayerPlaybackGUIUpdate #
- # Refresh the GUI for the main playback interface (must call periodically #
- # ------------------------------------------------------------------------- #
- def PlayerPlaybackGUIUpdate(self, DisplayString):
- window = self.Window
- if 'window' not in locals() or window is None: # if the widnow has been destoyed don't mess with it
- return PLAYER_COMMAND_EXIT
- self.TextElem.Update(DisplayString)
- event, (values) = window.Read(timeout=0)
- if event is None:
- return PLAYER_COMMAND_EXIT
- if event == 'PAUSE':
- return PLAYER_COMMAND_PAUSE
- elif event == 'EXIT':
- return PLAYER_COMMAND_EXIT
- elif event == 'NEXT':
- return PLAYER_COMMAND_NEXT
- elif event == 'Restart Song':
- return PLAYER_COMMAND_RESTART_SONG
- return PLAYER_COMMAND_NONE
-
-
-# ---------------------------------------------------------------------- #
-# MAIN - our main program... this is it #
-# Runs the GUI to get the file / path to play #
-# Decodes the MIDI-Video into a MID file #
-# Plays the decoded MIDI file #
-# ---------------------------------------------------------------------- #
-def main():
- def GetCurrentTime():
- '''
- Get the current system time in milliseconds
- :return: milliseconds
- '''
- return int(round(time.time() * 1000))
-
-
- pback = PlayerGUI()
-
- button, values = pback.PlayerChooseSongGUI()
- if button != 'PLAY':
- sg.PopupCancel('Cancelled...\nAutoclose in 2 sec...', auto_close=True, auto_close_duration=2)
- sys.exit(69)
- if values['device']:
- midi_port = values['device'][0]
- else:
- sg.PopupCancel('No devices found\nAutoclose in 2 sec...', auto_close=True, auto_close_duration=2)
-
- batch_folder = values['folder']
- midi_filename = values['midifile']
- # ------ Build list of files to play --------------------------------------------------------- #
- if batch_folder:
- filelist = os.listdir(batch_folder)
- filelist = [batch_folder+'/'+f for f in filelist if f.endswith(('.mid', '.MID'))]
- filetitles = [os.path.basename(f) for f in filelist]
- elif midi_filename: # an individual filename
- filelist = [midi_filename,]
- filetitles = [os.path.basename(midi_filename),]
- else:
- sg.PopupError('*** Error - No MIDI files specified ***')
- sys.exit(666)
-
- # ------ LOOP THROUGH MULTIPLE FILES --------------------------------------------------------- #
- pback.PlayerPlaybackGUIStart(NumFiles=len(filelist) if len(filelist) <=10 else 10)
- port = None
- # Loop through the files in the filelist
- for now_playing_number, current_midi_filename in enumerate(filelist):
- display_string = 'Playing Local File...\n{} of {}\n{}'.format(now_playing_number+1, len(filelist), current_midi_filename)
- midi_title = filetitles[now_playing_number]
- # --------------------------------- REFRESH THE GUI ----------------------------------------- #
- pback.PlayerPlaybackGUIUpdate(display_string)
-
- # ---===--- Output Filename is .MID --- #
- midi_filename = current_midi_filename
-
- # --------------------------------- MIDI - STARTS HERE ----------------------------------------- #
- if not port: # if the midi output port not opened yet, then open it
- port = mido.open_output(midi_port if midi_port else None)
-
- try:
- mid = mido.MidiFile(filename=midi_filename)
- except:
- print('****** Exception trying to play MidiFile filename = {}***************'.format(midi_filename))
- sg.PopupError('Exception trying to play MIDI file:', midi_filename, 'Skipping file')
- continue
-
- # Build list of data contained in MIDI File using only track 0
- midi_length_in_seconds = mid.length
- display_file_list = '>> ' + '\n'.join([f for i, f in enumerate(filetitles[now_playing_number:]) if i < 10])
- paused = cancelled = next_file = False
- ######################### Loop through MIDI Messages ###########################
- while(True):
- start_playback_time = GetCurrentTime()
- port.reset()
-
- for midi_msg_number, msg in enumerate(mid.play()):
- #################### GUI - read values ##################
- if not midi_msg_number % 4: # update the GUI every 4 MIDI messages
- t = (GetCurrentTime() - start_playback_time)//1000
- display_midi_len = '{:02d}:{:02d}'.format(*divmod(int(midi_length_in_seconds),60))
- display_string = 'Now Playing {} of {}\n{}\n {:02d}:{:02d} of {}\nPlaylist:'.\
- format(now_playing_number+1, len(filelist), midi_title, *divmod(t, 60), display_midi_len)
- # display list of next 10 files to be played.
- pback.SliderElem.Update(t, range=(1,midi_length_in_seconds))
- rc = pback.PlayerPlaybackGUIUpdate(display_string + '\n' + display_file_list)
- else: # fake rest of code as if GUI did nothing
- rc = PLAYER_COMMAND_NONE
- if paused:
- rc = PLAYER_COMMAND_NONE
- while rc == PLAYER_COMMAND_NONE: # TIGHT-ASS loop waiting on a GUI command
- rc = pback.PlayerPlaybackGUIUpdate(display_string)
- time.sleep(.25)
-
- ####################################### MIDI send data ##################################
- port.send(msg)
-
- # ------- Execute GUI Commands after sending MIDI data ------- #
- if rc == PLAYER_COMMAND_EXIT:
- cancelled = True
- break
- elif rc == PLAYER_COMMAND_PAUSE:
- paused = not paused
- port.reset()
- elif rc == PLAYER_COMMAND_NEXT:
- next_file = True
- break
- elif rc == PLAYER_COMMAND_RESTART_SONG:
- break
-
- if cancelled or next_file:
- break
- #------- DONE playing the song ------- #
- port.reset() # reset the midi port when done with the song
-
- if cancelled:
- break
-
-# ---------------------------------------------------------------------- #
-# LAUNCH POINT -- program starts and ends here #
-# ---------------------------------------------------------------------- #
-if __name__ == '__main__':
- main()
-
diff --git a/DemoPrograms old/Demo_Machine_Learning.py b/DemoPrograms old/Demo_Machine_Learning.py
deleted file mode 100644
index 0b5881f1..00000000
--- a/DemoPrograms old/Demo_Machine_Learning.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-def MachineLearningGUI():
- sg.SetOptions(text_justification='right')
-
- flags = [[sg.Checkbox('Normalize', size=(12, 1), default=True), sg.Checkbox('Verbose', size=(20, 1))],
- [sg.Checkbox('Cluster', size=(12, 1)), sg.Checkbox('Flush Output', size=(20, 1), default=True)],
- [sg.Checkbox('Write Results', size=(12, 1)), sg.Checkbox('Keep Intermediate Data', size=(20, 1))],
- [sg.Checkbox('Normalize', size=(12, 1), default=True), sg.Checkbox('Verbose', size=(20, 1))],
- [sg.Checkbox('Cluster', size=(12, 1)), sg.Checkbox('Flush Output', size=(20, 1), default=True)],
- [sg.Checkbox('Write Results', size=(12, 1)), sg.Checkbox('Keep Intermediate Data', size=(20, 1))],]
-
- loss_functions = [[sg.Radio('Cross-Entropy', 'loss', size=(12, 1)), sg.Radio('Logistic', 'loss', default=True, size=(12, 1))],
- [sg.Radio('Hinge', 'loss', size=(12, 1)), sg.Radio('Huber', 'loss', size=(12, 1))],
- [sg.Radio('Kullerback', 'loss', size=(12, 1)), sg.Radio('MAE(L1)', 'loss', size=(12, 1))],
- [sg.Radio('MSE(L2)', 'loss', size=(12, 1)), sg.Radio('MB(L0)', 'loss', size=(12, 1))],]
-
- command_line_parms = [[sg.Text('Passes', size=(8, 1)), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1)),
- sg.Text('Steps', size=(8, 1), pad=((7,3))), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1))],
- [sg.Text('ooa', size=(8, 1)), sg.In(default_text='6', size=(8, 1)), sg.Text('nn', size=(8, 1)),
- sg.In(default_text='10', size=(10, 1))],
- [sg.Text('q', size=(8, 1)), sg.In(default_text='ff', size=(8, 1)), sg.Text('ngram', size=(8, 1)),
- sg.In(default_text='5', size=(10, 1))],
- [sg.Text('l', size=(8, 1)), sg.In(default_text='0.4', size=(8, 1)), sg.Text('Layers', size=(8, 1)),
- sg.Drop(values=('BatchNorm', 'other'), auto_size_text=True)],]
-
- layout = [[sg.Frame('Command Line Parameteres', command_line_parms, title_color='green', font='Any 12')],
- [sg.Frame('Flags', flags, font='Any 12', title_color='blue')],
- [sg.Frame('Loss Functions', loss_functions, font='Any 12', title_color='red')],
- [sg.Submit(), sg.Cancel()]]
-
- window = sg.Window('Machine Learning Front End', font=("Helvetica", 12)).Layout(layout)
- button, values = window.Read()
- sg.SetOptions(text_justification='left')
-
- print(button, values)
-
-def CustomMeter():
- # layout the form
- layout = [[sg.Text('A custom progress meter')],
- [sg.ProgressBar(1000, orientation='h', size=(20,20), key='progress')],
- [sg.Cancel()]]
-
- # create the form`
- window = sg.Window('Custom Progress Meter').Layout(layout)
- progress_bar = window.FindElement('progress')
- # loop that would normally do something useful
- for i in range(1000):
- # check to see if the cancel button was clicked and exit loop if clicked
- event, values = window.Read(timeout=0, timeout_key='timeout')
- if event == 'Cancel' or event == None:
- break
- # update bar with loop value +1 so that bar eventually reaches the maximum
- progress_bar.UpdateBar(i+1)
- # done with loop... need to destroy the window as it's still open
- window.CloseNonBlocking()
-
-if __name__ == '__main__':
- CustomMeter()
- MachineLearningGUI()
diff --git a/DemoPrograms old/Demo_Matplotlib.py b/DemoPrograms old/Demo_Matplotlib.py
deleted file mode 100644
index 63164465..00000000
--- a/DemoPrograms old/Demo_Matplotlib.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python
-import PySimpleGUI as sg
-
-import matplotlib
-matplotlib.use('TkAgg')
-
-from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
-
-"""
-Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window.
-
-Basic steps are:
- * Create a Canvas Element
- * Layout form
- * Display form (NON BLOCKING)
- * Draw plots onto convas
- * Display form (BLOCKING)
-
- Based on information from: https://matplotlib.org/3.1.0/gallery/user_interfaces/embedding_in_tk_sgskip.html
- (Thank you Em-Bo & dirck)
-"""
-
-
-#------------------------------- PASTE YOUR MATPLOTLIB CODE HERE -------------------------------
-
-import numpy as np
-import matplotlib.pyplot as plt
-
-from matplotlib.ticker import NullFormatter # useful for `logit` scale
-
-# Fixing random state for reproducibility
-np.random.seed(19680801)
-
-# make up some data in the interval ]0, 1[
-y = np.random.normal(loc=0.5, scale=0.4, size=1000)
-y = y[(y > 0) & (y < 1)]
-y.sort()
-x = np.arange(len(y))
-
-# plot with various axes scales
-plt.figure(1)
-
-# linear
-plt.subplot(221)
-plt.plot(x, y)
-plt.yscale('linear')
-plt.title('linear')
-plt.grid(True)
-
-
-# log
-plt.subplot(222)
-plt.plot(x, y)
-plt.yscale('log')
-plt.title('log')
-plt.grid(True)
-
-
-# symmetric log
-plt.subplot(223)
-plt.plot(x, y - y.mean())
-plt.yscale('symlog', linthreshy=0.01)
-plt.title('symlog')
-plt.grid(True)
-
-# logit
-plt.subplot(224)
-plt.plot(x, y)
-plt.yscale('logit')
-plt.title('logit')
-plt.grid(True)
-plt.gca().yaxis.set_minor_formatter(NullFormatter())
-plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
- wspace=0.35)
-fig = plt.gcf() # if using Pyplot then get the figure from the plot
-figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
-
-#------------------------------- END OF YOUR MATPLOTLIB CODE -------------------------------
-
-#------------------------------- Beginning of Matplotlib helper code -----------------------
-
-
-def draw_figure(canvas, figure, loc=(0, 0)):
- figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
- figure_canvas_agg.draw()
- figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
- return figure_canvas_agg
-#------------------------------- Beginning of GUI CODE -------------------------------
-
-# define the window layout
-layout = [[sg.Text('Plot test', font='Any 18')],
- [sg.Canvas(size=(figure_w, figure_h), key='canvas')],
- [sg.OK(pad=((figure_w / 2, 0), 3), size=(4, 2))]]
-
-# create the form and show it without the plot
-window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True)
-
-# add the plot to the window
-fig_canvas_agg = draw_figure(window['canvas'].TKCanvas, fig)
-
-event, values = window.read()
diff --git a/DemoPrograms old/Demo_Matplotlib_Animated.py b/DemoPrograms old/Demo_Matplotlib_Animated.py
deleted file mode 100644
index da28c03c..00000000
--- a/DemoPrograms old/Demo_Matplotlib_Animated.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-import PySimpleGUI as sg
-
-from random import randint
-from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureCanvasAgg
-from matplotlib.figure import Figure
-
-def draw_figure(canvas, figure, loc=(0, 0)):
- figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
- figure_canvas_agg.draw()
- figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
- return figure_canvas_agg
-
-def main():
-
- NUM_DATAPOINTS = 10000
- # define the form layout
- layout = [[sg.Text('Animated Matplotlib', size=(40, 1), justification='center', font='Helvetica 20')],
- [sg.Canvas(size=(640, 480), key='-CANVAS-')],
- [sg.Text('Progress through the data')],
- [sg.Slider(range=(0, NUM_DATAPOINTS), size=(60, 10), orientation='h', key='-SLIDER-')],
- [sg.Text('Number of data points to display on screen')],
- [sg.Slider(range=(10, 500), default_value=40, size=(40, 10), orientation='h', key='-SLIDER-DATAPOINTS-')],
- [sg.Button('Exit', size=(10, 1), pad=((280, 0), 3), font='Helvetica 14')]]
-
- # create the form and show it without the plot
- window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True)
-
- canvas_elem = window.FindElement('-CANVAS-')
- slider_elem = window.FindElement('-SLIDER-')
- canvas = canvas_elem.TKCanvas
-
- # draw the initial plot in the window
- fig = Figure()
- ax = fig.add_subplot(111)
- ax.set_xlabel("X axis")
- ax.set_ylabel("Y axis")
- ax.grid()
- fig_agg = draw_figure(canvas, fig)
- # make a bunch of random data points
- dpts = [randint(0, 10) for x in range(NUM_DATAPOINTS)]
-
- for i in range(len(dpts)):
- event, values = window.Read(timeout=10)
- if event in ('Exit', None):
- exit(69)
- slider_elem.Update(i) # slider shows "progress" through the data points
- ax.cla() # clear the subplot
- ax.grid() # draw the grid
- data_points = int(values['-SLIDER-DATAPOINTS-']) # draw this many data points (on next line)
- ax.plot(range(data_points), dpts[i:i+data_points], color='purple')
- fig_agg.draw()
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Matplotlib_Animated_Scatter.py b/DemoPrograms old/Demo_Matplotlib_Animated_Scatter.py
deleted file mode 100644
index 21df8cdf..00000000
--- a/DemoPrograms old/Demo_Matplotlib_Animated_Scatter.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-import PySimpleGUI as sg
-
-import PySimpleGUI as sg
-from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
-import matplotlib.pyplot as plt
-from numpy.random import rand
-
-def draw_figure(canvas, figure):
- figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
- figure_canvas_agg.draw()
- figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
- return figure_canvas_agg
-
-
-
-
-def main():
- # define the form layout
- layout = [[sg.Text('Animated Matplotlib', size=(40, 1), justification='center', font='Helvetica 20')],
- [sg.Canvas(size=(640, 480), key='-CANVAS-')],
- [sg.Button('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]]
-
- # create the form and show it without the plot
- window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True)
-
- canvas_elem = window.FindElement('-CANVAS-')
- canvas = canvas_elem.TKCanvas
- # draw the intitial scatter plot
- fig, ax = plt.subplots()
- ax.grid(True)
- fig_agg = draw_figure(canvas, fig)
-
- while True:
- event, values = window.Read(timeout=10)
- if event in ('Exit', None):
- exit(69)
-
- ax.cla()
- ax.grid(True)
- for color in ['red', 'green', 'blue']:
- n = 750
- x, y = rand(2, n)
- scale = 200.0 * rand(n)
- ax.scatter(x, y, c=color, s=scale, label=color, alpha=0.3, edgecolors='none')
- ax.legend()
- fig_agg.draw()
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Matplotlib_Browser.py b/DemoPrograms old/Demo_Matplotlib_Browser.py
deleted file mode 100644
index a05242b0..00000000
--- a/DemoPrograms old/Demo_Matplotlib_Browser.py
+++ /dev/null
@@ -1,878 +0,0 @@
-#!/usr/bin/env python
-import PySimpleGUI as sg
-import matplotlib
-matplotlib.use('TkAgg')
-import inspect
-
-from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
-
-"""
-Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window.
-
-Basic steps are:
- * Create a Canvas Element
- * Layout form
- * Display form (NON BLOCKING)
- * Draw plots onto convas
- * Display form (BLOCKING)
-
-Each plotting function, complete with imports, was copied directly from Matplot examples page
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-
-
-def PyplotSimple():
- import numpy as np
- import matplotlib.pyplot as plt
-
- # evenly sampled time .2 intervals
- t = np.arange(0., 5., 0.2) # go from 0 to 5 using .2 intervals
-
- # red dashes, blue squares and green triangles
- plt.plot(t, t, 'r--', t, t ** 2, 'bs', t, t ** 3, 'g^')
-
- fig = plt.gcf() # get the figure to show
- return fig
-
-def PyplotHistogram():
- """
- =============================================================
- Demo of the histogram (hist) function with multiple data sets
- =============================================================
-
- Plot histogram with multiple sample sets and demonstrate:
-
- * Use of legend with multiple sample sets
- * Stacked bars
- * Step curve with no fill
- * Data sets of different sample sizes
-
- Selecting different bin counts and sizes can significantly affect the
- shape of a histogram. The Astropy docs have a great section on how to
- select these parameters:
- http://docs.astropy.org/en/stable/visualization/histogram.html
- """
-
- import numpy as np
- import matplotlib.pyplot as plt
-
- np.random.seed(0)
-
- n_bins = 10
- x = np.random.randn(1000, 3)
-
- fig, axes = plt.subplots(nrows=2, ncols=2)
- ax0, ax1, ax2, ax3 = axes.flatten()
-
- colors = ['red', 'tan', 'lime']
- ax0.hist(x, n_bins, normed=1, histtype='bar', color=colors, label=colors)
- ax0.legend(prop={'size': 10})
- ax0.set_title('bars with legend')
-
- ax1.hist(x, n_bins, normed=1, histtype='bar', stacked=True)
- ax1.set_title('stacked bar')
-
- ax2.hist(x, n_bins, histtype='step', stacked=True, fill=False)
- ax2.set_title('stack step (unfilled)')
-
- # Make a multiple-histogram of data-sets with different length.
- x_multi = [np.random.randn(n) for n in [10000, 5000, 2000]]
- ax3.hist(x_multi, n_bins, histtype='bar')
- ax3.set_title('different sample sizes')
-
- fig.tight_layout()
- return fig
-
-def PyplotArtistBoxPlots():
- """
- =========================================
- Demo of artist customization in box plots
- =========================================
-
- This example demonstrates how to use the various kwargs
- to fully customize box plots. The first figure demonstrates
- how to remove and add individual components (note that the
- mean is the only value not shown by default). The second
- figure demonstrates how the styles of the artists can
- be customized. It also demonstrates how to set the limit
- of the whiskers to specific percentiles (lower right axes)
-
- A good general reference on boxplots and their history can be found
- here: http://vita.had.co.nz/papers/boxplots.pdf
-
- """
-
- import numpy as np
- import matplotlib.pyplot as plt
-
- # fake data
- np.random.seed(937)
- data = np.random.lognormal(size=(37, 4), mean=1.5, sigma=1.75)
- labels = list('ABCD')
- fs = 10 # fontsize
-
- # demonstrate how to toggle the display of different elements:
- fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(6, 6), sharey=True)
- axes[0, 0].boxplot(data, labels=labels)
- axes[0, 0].set_title('Default', fontsize=fs)
-
- axes[0, 1].boxplot(data, labels=labels, showmeans=True)
- axes[0, 1].set_title('showmeans=True', fontsize=fs)
-
- axes[0, 2].boxplot(data, labels=labels, showmeans=True, meanline=True)
- axes[0, 2].set_title('showmeans=True,\nmeanline=True', fontsize=fs)
-
- axes[1, 0].boxplot(data, labels=labels, showbox=False, showcaps=False)
- tufte_title = 'Tufte Style \n(showbox=False,\nshowcaps=False)'
- axes[1, 0].set_title(tufte_title, fontsize=fs)
-
- axes[1, 1].boxplot(data, labels=labels, notch=True, bootstrap=10000)
- axes[1, 1].set_title('notch=True,\nbootstrap=10000', fontsize=fs)
-
- axes[1, 2].boxplot(data, labels=labels, showfliers=False)
- axes[1, 2].set_title('showfliers=False', fontsize=fs)
-
- for ax in axes.flatten():
- ax.set_yscale('log')
- ax.set_yticklabels([])
-
- fig.subplots_adjust(hspace=0.4)
- return fig
-
-def ArtistBoxplot2():
-
- # fake data
- np.random.seed(937)
- data = np.random.lognormal(size=(37, 4), mean=1.5, sigma=1.75)
- labels = list('ABCD')
- fs = 10 # fontsize
-
- # demonstrate how to customize the display different elements:
- boxprops = dict(linestyle='--', linewidth=3, color='darkgoldenrod')
- flierprops = dict(marker='o', markerfacecolor='green', markersize=12,
- linestyle='none')
- medianprops = dict(linestyle='-.', linewidth=2.5, color='firebrick')
- meanpointprops = dict(marker='D', markeredgecolor='black',
- markerfacecolor='firebrick')
- meanlineprops = dict(linestyle='--', linewidth=2.5, color='purple')
-
- fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(6, 6), sharey=True)
- axes[0, 0].boxplot(data, boxprops=boxprops)
- axes[0, 0].set_title('Custom boxprops', fontsize=fs)
-
- axes[0, 1].boxplot(data, flierprops=flierprops, medianprops=medianprops)
- axes[0, 1].set_title('Custom medianprops\nand flierprops', fontsize=fs)
-
- axes[0, 2].boxplot(data, whis='range')
- axes[0, 2].set_title('whis="range"', fontsize=fs)
-
- axes[1, 0].boxplot(data, meanprops=meanpointprops, meanline=False,
- showmeans=True)
- axes[1, 0].set_title('Custom mean\nas point', fontsize=fs)
-
- axes[1, 1].boxplot(data, meanprops=meanlineprops, meanline=True,
- showmeans=True)
- axes[1, 1].set_title('Custom mean\nas line', fontsize=fs)
-
- axes[1, 2].boxplot(data, whis=[15, 85])
- axes[1, 2].set_title('whis=[15, 85]\n#percentiles', fontsize=fs)
-
- for ax in axes.flatten():
- ax.set_yscale('log')
- ax.set_yticklabels([])
-
- fig.suptitle("I never said they'd be pretty")
- fig.subplots_adjust(hspace=0.4)
- return fig
-
-def PyplotScatterWithLegend():
- import matplotlib.pyplot as plt
- from numpy.random import rand
-
- fig, ax = plt.subplots()
- for color in ['red', 'green', 'blue']:
- n = 750
- x, y = rand(2, n)
- scale = 200.0 * rand(n)
- ax.scatter(x, y, c=color, s=scale, label=color,
- alpha=0.3, edgecolors='none')
-
- ax.legend()
- ax.grid(True)
- return fig
-
-def PyplotLineStyles():
- """
- ==========
- Linestyles
- ==========
-
- This examples showcases different linestyles copying those of Tikz/PGF.
- """
- import numpy as np
- import matplotlib.pyplot as plt
- from collections import OrderedDict
- from matplotlib.transforms import blended_transform_factory
-
- linestyles = OrderedDict(
- [('solid', (0, ())),
- ('loosely dotted', (0, (1, 10))),
- ('dotted', (0, (1, 5))),
- ('densely dotted', (0, (1, 1))),
-
- ('loosely dashed', (0, (5, 10))),
- ('dashed', (0, (5, 5))),
- ('densely dashed', (0, (5, 1))),
-
- ('loosely dashdotted', (0, (3, 10, 1, 10))),
- ('dashdotted', (0, (3, 5, 1, 5))),
- ('densely dashdotted', (0, (3, 1, 1, 1))),
-
- ('loosely dashdotdotted', (0, (3, 10, 1, 10, 1, 10))),
- ('dashdotdotted', (0, (3, 5, 1, 5, 1, 5))),
- ('densely dashdotdotted', (0, (3, 1, 1, 1, 1, 1)))])
-
- plt.figure(figsize=(10, 6))
- ax = plt.subplot(1, 1, 1)
-
- X, Y = np.linspace(0, 100, 10), np.zeros(10)
- for i, (name, linestyle) in enumerate(linestyles.items()):
- ax.plot(X, Y + i, linestyle=linestyle, linewidth=1.5, color='black')
-
- ax.set_ylim(-0.5, len(linestyles) - 0.5)
- plt.yticks(np.arange(len(linestyles)), linestyles.keys())
- plt.xticks([])
-
- # For each line style, add a text annotation with a small offset from
- # the reference point (0 in Axes coords, y tick value in Data coords).
- reference_transform = blended_transform_factory(ax.transAxes, ax.transData)
- for i, (name, linestyle) in enumerate(linestyles.items()):
- ax.annotate(str(linestyle), xy=(0.0, i), xycoords=reference_transform,
- xytext=(-6, -12), textcoords='offset points', color="blue",
- fontsize=8, ha="right", family="monospace")
-
- plt.tight_layout()
- return plt.gcf()
-
-def PyplotLinePolyCollection():
- import matplotlib.pyplot as plt
- from matplotlib import collections, colors, transforms
- import numpy as np
-
- nverts = 50
- npts = 100
-
- # Make some spirals
- r = np.arange(nverts)
- theta = np.linspace(0, 2 * np.pi, nverts)
- xx = r * np.sin(theta)
- yy = r * np.cos(theta)
- spiral = np.column_stack([xx, yy])
-
- # Fixing random state for reproducibility
- rs = np.random.RandomState(19680801)
-
- # Make some offsets
- xyo = rs.randn(npts, 2)
-
- # Make a list of colors cycling through the default series.
- colors = [colors.to_rgba(c)
- for c in plt.rcParams['axes.prop_cycle'].by_key()['color']]
-
- fig, axes = plt.subplots(2, 2)
- fig.subplots_adjust(top=0.92, left=0.07, right=0.97,
- hspace=0.3, wspace=0.3)
- ((ax1, ax2), (ax3, ax4)) = axes # unpack the axes
-
- col = collections.LineCollection([spiral], offsets=xyo,
- transOffset=ax1.transData)
- trans = fig.dpi_scale_trans + transforms.Affine2D().scale(1.0 / 72.0)
- col.set_transform(trans) # the points to pixels transform
- # Note: the first argument to the collection initializer
- # must be a list of sequences of x,y tuples; we have only
- # one sequence, but we still have to put it in a list.
- ax1.add_collection(col, autolim=True)
- # autolim=True enables autoscaling. For collections with
- # offsets like this, it is neither efficient nor accurate,
- # but it is good enough to generate a plot that you can use
- # as a starting point. If you know beforehand the range of
- # x and y that you want to show, it is better to set them
- # explicitly, leave out the autolim kwarg (or set it to False),
- # and omit the 'ax1.autoscale_view()' call below.
-
- # Make a transform for the line segments such that their size is
- # given in points:
- col.set_color(colors)
-
- ax1.autoscale_view() # See comment above, after ax1.add_collection.
- ax1.set_title('LineCollection using offsets')
-
- # The same data as above, but fill the curves.
- col = collections.PolyCollection([spiral], offsets=xyo,
- transOffset=ax2.transData)
- trans = transforms.Affine2D().scale(fig.dpi / 72.0)
- col.set_transform(trans) # the points to pixels transform
- ax2.add_collection(col, autolim=True)
- col.set_color(colors)
-
- ax2.autoscale_view()
- ax2.set_title('PolyCollection using offsets')
-
- # 7-sided regular polygons
-
- col = collections.RegularPolyCollection(
- 7, sizes=np.abs(xx) * 10.0, offsets=xyo, transOffset=ax3.transData)
- trans = transforms.Affine2D().scale(fig.dpi / 72.0)
- col.set_transform(trans) # the points to pixels transform
- ax3.add_collection(col, autolim=True)
- col.set_color(colors)
- ax3.autoscale_view()
- ax3.set_title('RegularPolyCollection using offsets')
-
- # Simulate a series of ocean current profiles, successively
- # offset by 0.1 m/s so that they form what is sometimes called
- # a "waterfall" plot or a "stagger" plot.
-
- nverts = 60
- ncurves = 20
- offs = (0.1, 0.0)
-
- yy = np.linspace(0, 2 * np.pi, nverts)
- ym = np.max(yy)
- xx = (0.2 + (ym - yy) / ym) ** 2 * np.cos(yy - 0.4) * 0.5
- segs = []
- for i in range(ncurves):
- xxx = xx + 0.02 * rs.randn(nverts)
- curve = np.column_stack([xxx, yy * 100])
- segs.append(curve)
-
- col = collections.LineCollection(segs, offsets=offs)
- ax4.add_collection(col, autolim=True)
- col.set_color(colors)
- ax4.autoscale_view()
- ax4.set_title('Successive data offsets')
- ax4.set_xlabel('Zonal velocity component (m/s)')
- ax4.set_ylabel('Depth (m)')
- # Reverse the y-axis so depth increases downward
- ax4.set_ylim(ax4.get_ylim()[::-1])
- return fig
-
-def PyplotGGPlotSytleSheet():
- import numpy as np
- import matplotlib.pyplot as plt
-
- plt.style.use('ggplot')
-
- # Fixing random state for reproducibility
- np.random.seed(19680801)
-
- fig, axes = plt.subplots(ncols=2, nrows=2)
- ax1, ax2, ax3, ax4 = axes.ravel()
-
- # scatter plot (Note: `plt.scatter` doesn't use default colors)
- x, y = np.random.normal(size=(2, 200))
- ax1.plot(x, y, 'o')
-
- # sinusoidal lines with colors from default color cycle
- L = 2 * np.pi
- x = np.linspace(0, L)
- ncolors = len(plt.rcParams['axes.prop_cycle'])
- shift = np.linspace(0, L, ncolors, endpoint=False)
- for s in shift:
- ax2.plot(x, np.sin(x + s), '-')
- ax2.margins(0)
-
- # bar graphs
- x = np.arange(5)
- y1, y2 = np.random.randint(1, 25, size=(2, 5))
- width = 0.25
- ax3.bar(x, y1, width)
- ax3.bar(x + width, y2, width,
- color=list(plt.rcParams['axes.prop_cycle'])[2]['color'])
- ax3.set_xticks(x + width)
- ax3.set_xticklabels(['a', 'b', 'c', 'd', 'e'])
-
- # circles with colors from default color cycle
- for i, color in enumerate(plt.rcParams['axes.prop_cycle']):
- xy = np.random.normal(size=2)
- ax4.add_patch(plt.Circle(xy, radius=0.3, color=color['color']))
- ax4.axis('equal')
- ax4.margins(0)
- fig = plt.gcf() # get the figure to show
- return fig
-
-def PyplotBoxPlot():
- import numpy as np
- import matplotlib.pyplot as plt
-
- # Fixing random state for reproducibility
- np.random.seed(19680801)
-
- # fake up some data
- spread = np.random.rand(50) * 100
- center = np.ones(25) * 50
- flier_high = np.random.rand(10) * 100 + 100
- flier_low = np.random.rand(10) * -100
- data = np.concatenate((spread, center, flier_high, flier_low), 0)
- fig1, ax1 = plt.subplots()
- ax1.set_title('Basic Plot')
- ax1.boxplot(data)
- return fig1
-
-def PyplotRadarChart():
- import numpy as np
-
- import matplotlib.pyplot as plt
- from matplotlib.path import Path
- from matplotlib.spines import Spine
- from matplotlib.projections.polar import PolarAxes
- from matplotlib.projections import register_projection
-
- def radar_factory(num_vars, frame='circle'):
- """Create a radar chart with `num_vars` axes.
-
- This function creates a RadarAxes projection and registers it.
-
- Parameters
- ----------
- num_vars : int
- Number of variables for radar chart.
- frame : {'circle' | 'polygon'}
- Shape of frame surrounding axes.
-
- """
- # calculate evenly-spaced axis angles
- theta = np.linspace(0, 2 * np.pi, num_vars, endpoint=False)
-
- def draw_poly_patch(self):
- # rotate theta such that the first axis is at the top
- verts = unit_poly_verts(theta + np.pi / 2)
- return plt.Polygon(verts, closed=True, edgecolor='k')
-
- def draw_circle_patch(self):
- # unit circle centered on (0.5, 0.5)
- return plt.Circle((0.5, 0.5), 0.5)
-
- patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch}
- if frame not in patch_dict:
- raise ValueError('unknown value for `frame`: %s' % frame)
-
- class RadarAxes(PolarAxes):
-
- name = 'radar'
- # use 1 line segment to connect specified points
- RESOLUTION = 1
- # define draw_frame method
- draw_patch = patch_dict[frame]
-
- def __init__(self, *args, **kwargs):
- super(RadarAxes, self).__init__(*args, **kwargs)
- # rotate plot such that the first axis is at the top
- self.set_theta_zero_location('N')
-
- def fill(self, *args, **kwargs):
- """Override fill so that line is closed by default"""
- closed = kwargs.pop('closed', True)
- return super(RadarAxes, self).fill(closed=closed, *args, **kwargs)
-
- def plot(self, *args, **kwargs):
- """Override plot so that line is closed by default"""
- lines = super(RadarAxes, self).plot(*args, **kwargs)
- for line in lines:
- self._close_line(line)
-
- def _close_line(self, line):
- x, y = line.get_data()
- # FIXME: markers at x[0], y[0] get doubled-up
- if x[0] != x[-1]:
- x = np.concatenate((x, [x[0]]))
- y = np.concatenate((y, [y[0]]))
- line.set_data(x, y)
-
- def set_varlabels(self, labels):
- self.set_thetagrids(np.degrees(theta), labels)
-
- def _gen_axes_patch(self):
- return self.draw_patch()
-
- def _gen_axes_spines(self):
- if frame == 'circle':
- return PolarAxes._gen_axes_spines(self)
- # The following is a hack to get the spines (i.e. the axes frame)
- # to draw correctly for a polygon frame.
-
- # spine_type must be 'left', 'right', 'top', 'bottom', or `circle`.
- spine_type = 'circle'
- verts = unit_poly_verts(theta + np.pi / 2)
- # close off polygon by repeating first vertex
- verts.append(verts[0])
- path = Path(verts)
-
- spine = Spine(self, spine_type, path)
- spine.set_transform(self.transAxes)
- return {'polar': spine}
-
- register_projection(RadarAxes)
- return theta
-
- def unit_poly_verts(theta):
- """Return vertices of polygon for subplot axes.
-
- This polygon is circumscribed by a unit circle centered at (0.5, 0.5)
- """
- x0, y0, r = [0.5] * 3
- verts = [(r * np.cos(t) + x0, r * np.sin(t) + y0) for t in theta]
- return verts
-
- def example_data():
- # The following data is from the Denver Aerosol Sources and Health study.
- # See doi:10.1016/j.atmosenv.2008.12.017
- #
- # The data are pollution source profile estimates for five modeled
- # pollution sources (e.g., cars, wood-burning, etc) that emit 7-9 chemical
- # species. The radar charts are experimented with here to see if we can
- # nicely visualize how the modeled source profiles change across four
- # scenarios:
- # 1) No gas-phase species present, just seven particulate counts on
- # Sulfate
- # Nitrate
- # Elemental Carbon (EC)
- # Organic Carbon fraction 1 (OC)
- # Organic Carbon fraction 2 (OC2)
- # Organic Carbon fraction 3 (OC3)
- # Pyrolized Organic Carbon (OP)
- # 2)Inclusion of gas-phase specie carbon monoxide (CO)
- # 3)Inclusion of gas-phase specie ozone (O3).
- # 4)Inclusion of both gas-phase species is present...
- data = [
- ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', 'O3'],
- ('Basecase', [
- [0.88, 0.01, 0.03, 0.03, 0.00, 0.06, 0.01, 0.00, 0.00],
- [0.07, 0.95, 0.04, 0.05, 0.00, 0.02, 0.01, 0.00, 0.00],
- [0.01, 0.02, 0.85, 0.19, 0.05, 0.10, 0.00, 0.00, 0.00],
- [0.02, 0.01, 0.07, 0.01, 0.21, 0.12, 0.98, 0.00, 0.00],
- [0.01, 0.01, 0.02, 0.71, 0.74, 0.70, 0.00, 0.00, 0.00]]),
- ('With CO', [
- [0.88, 0.02, 0.02, 0.02, 0.00, 0.05, 0.00, 0.05, 0.00],
- [0.08, 0.94, 0.04, 0.02, 0.00, 0.01, 0.12, 0.04, 0.00],
- [0.01, 0.01, 0.79, 0.10, 0.00, 0.05, 0.00, 0.31, 0.00],
- [0.00, 0.02, 0.03, 0.38, 0.31, 0.31, 0.00, 0.59, 0.00],
- [0.02, 0.02, 0.11, 0.47, 0.69, 0.58, 0.88, 0.00, 0.00]]),
- ('With O3', [
- [0.89, 0.01, 0.07, 0.00, 0.00, 0.05, 0.00, 0.00, 0.03],
- [0.07, 0.95, 0.05, 0.04, 0.00, 0.02, 0.12, 0.00, 0.00],
- [0.01, 0.02, 0.86, 0.27, 0.16, 0.19, 0.00, 0.00, 0.00],
- [0.01, 0.03, 0.00, 0.32, 0.29, 0.27, 0.00, 0.00, 0.95],
- [0.02, 0.00, 0.03, 0.37, 0.56, 0.47, 0.87, 0.00, 0.00]]),
- ('CO & O3', [
- [0.87, 0.01, 0.08, 0.00, 0.00, 0.04, 0.00, 0.00, 0.01],
- [0.09, 0.95, 0.02, 0.03, 0.00, 0.01, 0.13, 0.06, 0.00],
- [0.01, 0.02, 0.71, 0.24, 0.13, 0.16, 0.00, 0.50, 0.00],
- [0.01, 0.03, 0.00, 0.28, 0.24, 0.23, 0.00, 0.44, 0.88],
- [0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]])
- ]
- return data
-
- N = 9
- theta = radar_factory(N, frame='polygon')
-
- data = example_data()
- spoke_labels = data.pop(0)
-
- fig, axes = plt.subplots(figsize=(9, 9), nrows=2, ncols=2,
- subplot_kw=dict(projection='radar'))
- fig.subplots_adjust(wspace=0.25, hspace=0.20, top=0.85, bottom=0.05)
-
- colors = ['b', 'r', 'g', 'm', 'y']
- # Plot the four cases from the example data on separate axes
- for ax, (title, case_data) in zip(axes.flatten(), data):
- ax.set_rgrids([0.2, 0.4, 0.6, 0.8])
- ax.set_title(title, weight='bold', size='medium', position=(0.5, 1.1),
- horizontalalignment='center', verticalalignment='center')
- for d, color in zip(case_data, colors):
- ax.plot(theta, d, color=color)
- ax.fill(theta, d, facecolor=color, alpha=0.25)
- ax.set_varlabels(spoke_labels)
-
- # add legend relative to top-left plot
- ax = axes[0, 0]
- labels = ('Factor 1', 'Factor 2', 'Factor 3', 'Factor 4', 'Factor 5')
- legend = ax.legend(labels, loc=(0.9, .95),
- labelspacing=0.1, fontsize='small')
-
- fig.text(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios',
- horizontalalignment='center', color='black', weight='bold',
- size='large')
- return fig
-
-def DifferentScales():
- import numpy as np
- import matplotlib.pyplot as plt
-
- # Create some mock data
- t = np.arange(0.01, 10.0, 0.01)
- data1 = np.exp(t)
- data2 = np.sin(2 * np.pi * t)
-
- fig, ax1 = plt.subplots()
-
- color = 'tab:red'
- ax1.set_xlabel('time (s)')
- ax1.set_ylabel('exp', color=color)
- ax1.plot(t, data1, color=color)
- ax1.tick_params(axis='y', labelcolor=color)
-
- ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
-
- color = 'tab:blue'
- ax2.set_ylabel('sin', color=color) # we already handled the x-label with ax1
- ax2.plot(t, data2, color=color)
- ax2.tick_params(axis='y', labelcolor=color)
-
- fig.tight_layout() # otherwise the right y-label is slightly clipped
- return fig
-
-def ExploringNormalizations():
- import matplotlib.pyplot as plt
- import matplotlib.colors as mcolors
- import numpy as np
- from numpy.random import multivariate_normal
-
- data = np.vstack([
- multivariate_normal([10, 10], [[3, 2], [2, 3]], size=100000),
- multivariate_normal([30, 20], [[2, 3], [1, 3]], size=1000)
- ])
-
- gammas = [0.8, 0.5, 0.3]
-
- fig, axes = plt.subplots(nrows=2, ncols=2)
-
- axes[0, 0].set_title('Linear normalization')
- axes[0, 0].hist2d(data[:, 0], data[:, 1], bins=100)
-
- for ax, gamma in zip(axes.flat[1:], gammas):
- ax.set_title(r'Power law $(\gamma=%1.1f)$' % gamma)
- ax.hist2d(data[:, 0], data[:, 1],
- bins=100, norm=mcolors.PowerNorm(gamma))
-
- fig.tight_layout()
- return fig
-
-def PyplotFormatstr():
-
- def f(t):
- return np.exp(-t) * np.cos(2*np.pi*t)
-
- t1 = np.arange(0.0, 5.0, 0.1)
- t2 = np.arange(0.0, 5.0, 0.02)
-
- plt.figure(1)
- plt.subplot(211)
- plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
-
- plt.subplot(212)
- plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
- fig = plt.gcf() # get the figure to show
- return fig
-
-def UnicodeMinus():
- import numpy as np
- import matplotlib
- import matplotlib.pyplot as plt
-
- # Fixing random state for reproducibility
- np.random.seed(19680801)
-
- matplotlib.rcParams['axes.unicode_minus'] = False
- fig, ax = plt.subplots()
- ax.plot(10 * np.random.randn(100), 10 * np.random.randn(100), 'o')
- ax.set_title('Using hyphen instead of Unicode minus')
- return fig
-
-def Subplot3d():
- from mpl_toolkits.mplot3d.axes3d import Axes3D
- from matplotlib import cm
- # from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatter
- import matplotlib.pyplot as plt
- import numpy as np
-
- fig = plt.figure()
-
- ax = fig.add_subplot(1, 2, 1, projection='3d')
- X = np.arange(-5, 5, 0.25)
- Y = np.arange(-5, 5, 0.25)
- X, Y = np.meshgrid(X, Y)
- R = np.sqrt(X ** 2 + Y ** 2)
- Z = np.sin(R)
- surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet,
- linewidth=0, antialiased=False)
- ax.set_zlim3d(-1.01, 1.01)
-
- # ax.w_zaxis.set_major_locator(LinearLocator(10))
- # ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))
-
- fig.colorbar(surf, shrink=0.5, aspect=5)
-
- from mpl_toolkits.mplot3d.axes3d import get_test_data
- ax = fig.add_subplot(1, 2, 2, projection='3d')
- X, Y, Z = get_test_data(0.05)
- ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
- return fig
-
-def PyplotScales():
- import numpy as np
- import matplotlib.pyplot as plt
-
- from matplotlib.ticker import NullFormatter # useful for `logit` scale
-
- # Fixing random state for reproducibility
- np.random.seed(19680801)
-
- # make up some data in the interval ]0, 1[
- y = np.random.normal(loc=0.5, scale=0.4, size=1000)
- y = y[(y > 0) & (y < 1)]
- y.sort()
- x = np.arange(len(y))
-
- # plot with various axes scales
- plt.figure(1)
-
- # linear
- plt.subplot(221)
- plt.plot(x, y)
- plt.yscale('linear')
- plt.title('linear')
- plt.grid(True)
-
- # log
- plt.subplot(222)
- plt.plot(x, y)
- plt.yscale('log')
- plt.title('log')
- plt.grid(True)
-
- # symmetric log
- plt.subplot(223)
- plt.plot(x, y - y.mean())
- plt.yscale('symlog', linthreshy=0.01)
- plt.title('symlog')
- plt.grid(True)
-
- # logit
- plt.subplot(224)
- plt.plot(x, y)
- plt.yscale('logit')
- plt.title('logit')
- plt.grid(True)
- # Format the minor tick labels of the y-axis into empty strings with
- # `NullFormatter`, to avoid cumbering the axis with too many labels.
- plt.gca().yaxis.set_minor_formatter(NullFormatter())
- # Adjust the subplot layout, because the logit one may take more space
- # than usual, due to y-tick labels like "1 - 10^{-3}"
- plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
- wspace=0.35)
- return plt.gcf()
-
-
-def AxesGrid():
- import numpy as np
- import matplotlib.pyplot as plt
- from mpl_toolkits.axes_grid1.axes_rgb import RGBAxes
-
- def get_demo_image():
- # prepare image
- delta = 0.5
-
- extent = (-3, 4, -4, 3)
- x = np.arange(-3.0, 4.001, delta)
- y = np.arange(-4.0, 3.001, delta)
- X, Y = np.meshgrid(x, y)
- Z1 = np.exp(-X ** 2 - Y ** 2)
- Z2 = np.exp(-(X - 1) ** 2 - (Y - 1) ** 2)
- Z = (Z1 - Z2) * 2
-
- return Z, extent
-
- def get_rgb():
- Z, extent = get_demo_image()
-
- Z[Z < 0] = 0.
- Z = Z / Z.max()
-
- R = Z[:13, :13]
- G = Z[2:, 2:]
- B = Z[:13, 2:]
-
- return R, G, B
-
- fig = plt.figure(1)
- ax = RGBAxes(fig, [0.1, 0.1, 0.8, 0.8])
-
- r, g, b = get_rgb()
- kwargs = dict(origin="lower", interpolation="nearest")
- ax.imshow_rgb(r, g, b, **kwargs)
-
- ax.RGB.set_xlim(0., 9.5)
- ax.RGB.set_ylim(0.9, 10.6)
-
- plt.draw()
- return plt.gcf()
-
-
-
-# The magic function that makes it possible.... glues together tkinter and pyplot using Canvas Widget
-def draw_figure(canvas, figure):
- figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
- figure_canvas_agg.draw()
- figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
- return figure_canvas_agg
-
-def delete_figure_agg(figure_agg):
- figure_agg.get_tk_widget().forget()
- plt.close('all')
-
-# -------------------------------- GUI Starts Here -------------------------------#
-# fig = your figure you want to display. Assumption is that 'fig' holds the #
-# information to display. #
-# --------------------------------------------------------------------------------#
-
-fig_dict = {'Pyplot Simple':PyplotSimple, 'Pyplot Formatstr':PyplotFormatstr,'PyPlot Three':Subplot3d,
- 'Unicode Minus': UnicodeMinus, 'Pyplot Scales' : PyplotScales, 'Axes Grid' : AxesGrid,
- 'Exploring Normalizations' : ExploringNormalizations, 'Different Scales' : DifferentScales,
- 'Pyplot Box Plot' : PyplotBoxPlot, 'Pyplot ggplot Style Sheet' : PyplotGGPlotSytleSheet,
- 'Pyplot Line Poly Collection' : PyplotLinePolyCollection, 'Pyplot Line Styles' : PyplotLineStyles,
- 'Pyplot Scatter With Legend' :PyplotScatterWithLegend, 'Artist Customized Box Plots' : PyplotArtistBoxPlots,
- 'Artist Customized Box Plots 2' : ArtistBoxplot2, 'Pyplot Histogram' : PyplotHistogram}
-
-sg.ChangeLookAndFeel('LightGreen')
-
-figure_w, figure_h = 650, 650
-# define the form layout
-listbox_values = list(fig_dict)
-col_listbox = [[sg.Listbox(values=listbox_values, enable_events=True, size=(28, len(listbox_values)), key='-LISTBOX-')],
- [sg.T(' ' * 12), sg.Exit(size=(5, 2))]]
-
-layout = [[sg.Text('Matplotlib Plot Test', font=('current 18'))],
- [sg.Column(col_listbox, pad=(5, (3, 330))), sg.Canvas(size=(figure_w, figure_h), key='-CANVAS-') ,
- sg.Multiline(size=(70, 35), pad=(5, (3, 90)), key='-MULTILINE-')],]
-
-# create the form and show it without the plot
-window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, grab_anywhere=False, finalize=True)
-figure_agg = None
-# The GUI Event Loop
-while True:
- event, values = window.read()
- # print(event, values) # helps greatly when debugging
- if event in (None, 'Exit'): # if user closed window or clicked Exit button
- break
- if figure_agg:
- # ** IMPORTANT ** Clean up previous drawing before drawing again
- delete_figure_agg(figure_agg)
- choice = values['-LISTBOX-'][0] # get first listbox item chosen (returned as a list)
- func = fig_dict[choice] # get function to call from the dictionary
- window['-MULTILINE-'].Update(inspect.getsource(func)) # show source code to function in multiline
- fig = func() # call function to get the figure
- figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig) # draw the figure
-window.close()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Matplotlib_Browser_Paned.py b/DemoPrograms old/Demo_Matplotlib_Browser_Paned.py
deleted file mode 100644
index 3a61374d..00000000
--- a/DemoPrograms old/Demo_Matplotlib_Browser_Paned.py
+++ /dev/null
@@ -1,889 +0,0 @@
-#!/usr/bin/env python
-#!/usr/bin/env python
-import PySimpleGUI as sg
-import matplotlib
-matplotlib.use('TkAgg')
-import inspect
-import numpy as np
-import matplotlib.pyplot as plt
-from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
-
-"""
-Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window.
-
-Basic steps are:
- * Create a Canvas Element
- * Layout form
- * Display form (NON BLOCKING)
- * Draw plots onto convas
- * Display form (BLOCKING)
-"""
-
-
-
-import numpy as np
-import matplotlib.pyplot as plt
-
-
-def PyplotSimple():
- import numpy as np
- import matplotlib.pyplot as plt
-
- # evenly sampled time at 200ms intervals
- t = np.arange(0., 5., 0.2)
-
- # red dashes, blue squares and green triangles
- plt.plot(t, t, 'r--', t, t ** 2, 'bs', t, t ** 3, 'g^')
-
- fig = plt.gcf() # get the figure to show
- return fig
-
-def PyplotHistogram():
- """
- =============================================================
- Demo of the histogram (hist) function with multiple data sets
- =============================================================
-
- Plot histogram with multiple sample sets and demonstrate:
-
- * Use of legend with multiple sample sets
- * Stacked bars
- * Step curve with no fill
- * Data sets of different sample sizes
-
- Selecting different bin counts and sizes can significantly affect the
- shape of a histogram. The Astropy docs have a great section on how to
- select these parameters:
- http://docs.astropy.org/en/stable/visualization/histogram.html
- """
-
- import numpy as np
- import matplotlib.pyplot as plt
-
- np.random.seed(0)
-
- n_bins = 10
- x = np.random.randn(1000, 3)
-
- fig, axes = plt.subplots(nrows=2, ncols=2)
- ax0, ax1, ax2, ax3 = axes.flatten()
-
- colors = ['red', 'tan', 'lime']
- ax0.hist(x, n_bins, normed=1, histtype='bar', color=colors, label=colors)
- ax0.legend(prop={'size': 10})
- ax0.set_title('bars with legend')
-
- ax1.hist(x, n_bins, normed=1, histtype='bar', stacked=True)
- ax1.set_title('stacked bar')
-
- ax2.hist(x, n_bins, histtype='step', stacked=True, fill=False)
- ax2.set_title('stack step (unfilled)')
-
- # Make a multiple-histogram of data-sets with different length.
- x_multi = [np.random.randn(n) for n in [10000, 5000, 2000]]
- ax3.hist(x_multi, n_bins, histtype='bar')
- ax3.set_title('different sample sizes')
-
- fig.tight_layout()
- return fig
-
-def PyplotArtistBoxPlots():
- """
- =========================================
- Demo of artist customization in box plots
- =========================================
-
- This example demonstrates how to use the various kwargs
- to fully customize box plots. The first figure demonstrates
- how to remove and add individual components (note that the
- mean is the only value not shown by default). The second
- figure demonstrates how the styles of the artists can
- be customized. It also demonstrates how to set the limit
- of the whiskers to specific percentiles (lower right axes)
-
- A good general reference on boxplots and their history can be found
- here: http://vita.had.co.nz/papers/boxplots.pdf
-
- """
-
- import numpy as np
- import matplotlib.pyplot as plt
-
- # fake data
- np.random.seed(937)
- data = np.random.lognormal(size=(37, 4), mean=1.5, sigma=1.75)
- labels = list('ABCD')
- fs = 10 # fontsize
-
- # demonstrate how to toggle the display of different elements:
- fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(6, 6), sharey=True)
- axes[0, 0].boxplot(data, labels=labels)
- axes[0, 0].set_title('Default', fontsize=fs)
-
- axes[0, 1].boxplot(data, labels=labels, showmeans=True)
- axes[0, 1].set_title('showmeans=True', fontsize=fs)
-
- axes[0, 2].boxplot(data, labels=labels, showmeans=True, meanline=True)
- axes[0, 2].set_title('showmeans=True,\nmeanline=True', fontsize=fs)
-
- axes[1, 0].boxplot(data, labels=labels, showbox=False, showcaps=False)
- tufte_title = 'Tufte Style \n(showbox=False,\nshowcaps=False)'
- axes[1, 0].set_title(tufte_title, fontsize=fs)
-
- axes[1, 1].boxplot(data, labels=labels, notch=True, bootstrap=10000)
- axes[1, 1].set_title('notch=True,\nbootstrap=10000', fontsize=fs)
-
- axes[1, 2].boxplot(data, labels=labels, showfliers=False)
- axes[1, 2].set_title('showfliers=False', fontsize=fs)
-
- for ax in axes.flatten():
- ax.set_yscale('log')
- ax.set_yticklabels([])
-
- fig.subplots_adjust(hspace=0.4)
- return fig
-
-def ArtistBoxplot2():
-
- # fake data
- np.random.seed(937)
- data = np.random.lognormal(size=(37, 4), mean=1.5, sigma=1.75)
- labels = list('ABCD')
- fs = 10 # fontsize
-
- # demonstrate how to customize the display different elements:
- boxprops = dict(linestyle='--', linewidth=3, color='darkgoldenrod')
- flierprops = dict(marker='o', markerfacecolor='green', markersize=12,
- linestyle='none')
- medianprops = dict(linestyle='-.', linewidth=2.5, color='firebrick')
- meanpointprops = dict(marker='D', markeredgecolor='black',
- markerfacecolor='firebrick')
- meanlineprops = dict(linestyle='--', linewidth=2.5, color='purple')
-
- fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(6, 6), sharey=True)
- axes[0, 0].boxplot(data, boxprops=boxprops)
- axes[0, 0].set_title('Custom boxprops', fontsize=fs)
-
- axes[0, 1].boxplot(data, flierprops=flierprops, medianprops=medianprops)
- axes[0, 1].set_title('Custom medianprops\nand flierprops', fontsize=fs)
-
- axes[0, 2].boxplot(data, whis='range')
- axes[0, 2].set_title('whis="range"', fontsize=fs)
-
- axes[1, 0].boxplot(data, meanprops=meanpointprops, meanline=False,
- showmeans=True)
- axes[1, 0].set_title('Custom mean\nas point', fontsize=fs)
-
- axes[1, 1].boxplot(data, meanprops=meanlineprops, meanline=True,
- showmeans=True)
- axes[1, 1].set_title('Custom mean\nas line', fontsize=fs)
-
- axes[1, 2].boxplot(data, whis=[15, 85])
- axes[1, 2].set_title('whis=[15, 85]\n#percentiles', fontsize=fs)
-
- for ax in axes.flatten():
- ax.set_yscale('log')
- ax.set_yticklabels([])
-
- fig.suptitle("I never said they'd be pretty")
- fig.subplots_adjust(hspace=0.4)
- return fig
-
-def PyplotScatterWithLegend():
- import matplotlib.pyplot as plt
- from numpy.random import rand
-
- fig, ax = plt.subplots()
- for color in ['red', 'green', 'blue']:
- n = 750
- x, y = rand(2, n)
- scale = 200.0 * rand(n)
- ax.scatter(x, y, c=color, s=scale, label=color,
- alpha=0.3, edgecolors='none')
-
- ax.legend()
- ax.grid(True)
- return fig
-
-def PyplotLineStyles():
- """
- ==========
- Linestyles
- ==========
-
- This examples showcases different linestyles copying those of Tikz/PGF.
- """
- import numpy as np
- import matplotlib.pyplot as plt
- from collections import OrderedDict
- from matplotlib.transforms import blended_transform_factory
-
- linestyles = OrderedDict(
- [('solid', (0, ())),
- ('loosely dotted', (0, (1, 10))),
- ('dotted', (0, (1, 5))),
- ('densely dotted', (0, (1, 1))),
-
- ('loosely dashed', (0, (5, 10))),
- ('dashed', (0, (5, 5))),
- ('densely dashed', (0, (5, 1))),
-
- ('loosely dashdotted', (0, (3, 10, 1, 10))),
- ('dashdotted', (0, (3, 5, 1, 5))),
- ('densely dashdotted', (0, (3, 1, 1, 1))),
-
- ('loosely dashdotdotted', (0, (3, 10, 1, 10, 1, 10))),
- ('dashdotdotted', (0, (3, 5, 1, 5, 1, 5))),
- ('densely dashdotdotted', (0, (3, 1, 1, 1, 1, 1)))])
-
- plt.figure(figsize=(10, 6))
- ax = plt.subplot(1, 1, 1)
-
- X, Y = np.linspace(0, 100, 10), np.zeros(10)
- for i, (name, linestyle) in enumerate(linestyles.items()):
- ax.plot(X, Y + i, linestyle=linestyle, linewidth=1.5, color='black')
-
- ax.set_ylim(-0.5, len(linestyles) - 0.5)
- plt.yticks(np.arange(len(linestyles)), linestyles.keys())
- plt.xticks([])
-
- # For each line style, add a text annotation with a small offset from
- # the reference point (0 in Axes coords, y tick value in Data coords).
- reference_transform = blended_transform_factory(ax.transAxes, ax.transData)
- for i, (name, linestyle) in enumerate(linestyles.items()):
- ax.annotate(str(linestyle), xy=(0.0, i), xycoords=reference_transform,
- xytext=(-6, -12), textcoords='offset points', color="blue",
- fontsize=8, ha="right", family="monospace")
-
- plt.tight_layout()
- return plt.gcf()
-
-def PyplotLinePolyCollection():
- import matplotlib.pyplot as plt
- from matplotlib import collections, colors, transforms
- import numpy as np
-
- nverts = 50
- npts = 100
-
- # Make some spirals
- r = np.arange(nverts)
- theta = np.linspace(0, 2 * np.pi, nverts)
- xx = r * np.sin(theta)
- yy = r * np.cos(theta)
- spiral = np.column_stack([xx, yy])
-
- # Fixing random state for reproducibility
- rs = np.random.RandomState(19680801)
-
- # Make some offsets
- xyo = rs.randn(npts, 2)
-
- # Make a list of colors cycling through the default series.
- colors = [colors.to_rgba(c)
- for c in plt.rcParams['axes.prop_cycle'].by_key()['color']]
-
- fig, axes = plt.subplots(2, 2)
- fig.subplots_adjust(top=0.92, left=0.07, right=0.97,
- hspace=0.3, wspace=0.3)
- ((ax1, ax2), (ax3, ax4)) = axes # unpack the axes
-
- col = collections.LineCollection([spiral], offsets=xyo,
- transOffset=ax1.transData)
- trans = fig.dpi_scale_trans + transforms.Affine2D().scale(1.0 / 72.0)
- col.set_transform(trans) # the points to pixels transform
- # Note: the first argument to the collection initializer
- # must be a list of sequences of x,y tuples; we have only
- # one sequence, but we still have to put it in a list.
- ax1.add_collection(col, autolim=True)
- # autolim=True enables autoscaling. For collections with
- # offsets like this, it is neither efficient nor accurate,
- # but it is good enough to generate a plot that you can use
- # as a starting point. If you know beforehand the range of
- # x and y that you want to show, it is better to set them
- # explicitly, leave out the autolim kwarg (or set it to False),
- # and omit the 'ax1.autoscale_view()' call below.
-
- # Make a transform for the line segments such that their size is
- # given in points:
- col.set_color(colors)
-
- ax1.autoscale_view() # See comment above, after ax1.add_collection.
- ax1.set_title('LineCollection using offsets')
-
- # The same data as above, but fill the curves.
- col = collections.PolyCollection([spiral], offsets=xyo,
- transOffset=ax2.transData)
- trans = transforms.Affine2D().scale(fig.dpi / 72.0)
- col.set_transform(trans) # the points to pixels transform
- ax2.add_collection(col, autolim=True)
- col.set_color(colors)
-
- ax2.autoscale_view()
- ax2.set_title('PolyCollection using offsets')
-
- # 7-sided regular polygons
-
- col = collections.RegularPolyCollection(
- 7, sizes=np.abs(xx) * 10.0, offsets=xyo, transOffset=ax3.transData)
- trans = transforms.Affine2D().scale(fig.dpi / 72.0)
- col.set_transform(trans) # the points to pixels transform
- ax3.add_collection(col, autolim=True)
- col.set_color(colors)
- ax3.autoscale_view()
- ax3.set_title('RegularPolyCollection using offsets')
-
- # Simulate a series of ocean current profiles, successively
- # offset by 0.1 m/s so that they form what is sometimes called
- # a "waterfall" plot or a "stagger" plot.
-
- nverts = 60
- ncurves = 20
- offs = (0.1, 0.0)
-
- yy = np.linspace(0, 2 * np.pi, nverts)
- ym = np.max(yy)
- xx = (0.2 + (ym - yy) / ym) ** 2 * np.cos(yy - 0.4) * 0.5
- segs = []
- for i in range(ncurves):
- xxx = xx + 0.02 * rs.randn(nverts)
- curve = np.column_stack([xxx, yy * 100])
- segs.append(curve)
-
- col = collections.LineCollection(segs, offsets=offs)
- ax4.add_collection(col, autolim=True)
- col.set_color(colors)
- ax4.autoscale_view()
- ax4.set_title('Successive data offsets')
- ax4.set_xlabel('Zonal velocity component (m/s)')
- ax4.set_ylabel('Depth (m)')
- # Reverse the y-axis so depth increases downward
- ax4.set_ylim(ax4.get_ylim()[::-1])
- return fig
-
-def PyplotGGPlotSytleSheet():
- import numpy as np
- import matplotlib.pyplot as plt
-
- plt.style.use('ggplot')
-
- # Fixing random state for reproducibility
- np.random.seed(19680801)
-
- fig, axes = plt.subplots(ncols=2, nrows=2)
- ax1, ax2, ax3, ax4 = axes.ravel()
-
- # scatter plot (Note: `plt.scatter` doesn't use default colors)
- x, y = np.random.normal(size=(2, 200))
- ax1.plot(x, y, 'o')
-
- # sinusoidal lines with colors from default color cycle
- L = 2 * np.pi
- x = np.linspace(0, L)
- ncolors = len(plt.rcParams['axes.prop_cycle'])
- shift = np.linspace(0, L, ncolors, endpoint=False)
- for s in shift:
- ax2.plot(x, np.sin(x + s), '-')
- ax2.margins(0)
-
- # bar graphs
- x = np.arange(5)
- y1, y2 = np.random.randint(1, 25, size=(2, 5))
- width = 0.25
- ax3.bar(x, y1, width)
- ax3.bar(x + width, y2, width,
- color=list(plt.rcParams['axes.prop_cycle'])[2]['color'])
- ax3.set_xticks(x + width)
- ax3.set_xticklabels(['a', 'b', 'c', 'd', 'e'])
-
- # circles with colors from default color cycle
- for i, color in enumerate(plt.rcParams['axes.prop_cycle']):
- xy = np.random.normal(size=2)
- ax4.add_patch(plt.Circle(xy, radius=0.3, color=color['color']))
- ax4.axis('equal')
- ax4.margins(0)
- fig = plt.gcf() # get the figure to show
- return fig
-
-def PyplotBoxPlot():
- import numpy as np
- import matplotlib.pyplot as plt
-
- # Fixing random state for reproducibility
- np.random.seed(19680801)
-
- # fake up some data
- spread = np.random.rand(50) * 100
- center = np.ones(25) * 50
- flier_high = np.random.rand(10) * 100 + 100
- flier_low = np.random.rand(10) * -100
- data = np.concatenate((spread, center, flier_high, flier_low), 0)
- fig1, ax1 = plt.subplots()
- ax1.set_title('Basic Plot')
- ax1.boxplot(data)
- return fig1
-
-def PyplotRadarChart():
- import numpy as np
-
- import matplotlib.pyplot as plt
- from matplotlib.path import Path
- from matplotlib.spines import Spine
- from matplotlib.projections.polar import PolarAxes
- from matplotlib.projections import register_projection
-
- def radar_factory(num_vars, frame='circle'):
- """Create a radar chart with `num_vars` axes.
-
- This function creates a RadarAxes projection and registers it.
-
- Parameters
- ----------
- num_vars : int
- Number of variables for radar chart.
- frame : {'circle' | 'polygon'}
- Shape of frame surrounding axes.
-
- """
- # calculate evenly-spaced axis angles
- theta = np.linspace(0, 2 * np.pi, num_vars, endpoint=False)
-
- def draw_poly_patch(self):
- # rotate theta such that the first axis is at the top
- verts = unit_poly_verts(theta + np.pi / 2)
- return plt.Polygon(verts, closed=True, edgecolor='k')
-
- def draw_circle_patch(self):
- # unit circle centered on (0.5, 0.5)
- return plt.Circle((0.5, 0.5), 0.5)
-
- patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch}
- if frame not in patch_dict:
- raise ValueError('unknown value for `frame`: %s' % frame)
-
- class RadarAxes(PolarAxes):
-
- name = 'radar'
- # use 1 line segment to connect specified points
- RESOLUTION = 1
- # define draw_frame method
- draw_patch = patch_dict[frame]
-
- def __init__(self, *args, **kwargs):
- super(RadarAxes, self).__init__(*args, **kwargs)
- # rotate plot such that the first axis is at the top
- self.set_theta_zero_location('N')
-
- def fill(self, *args, **kwargs):
- """Override fill so that line is closed by default"""
- closed = kwargs.pop('closed', True)
- return super(RadarAxes, self).fill(closed=closed, *args, **kwargs)
-
- def plot(self, *args, **kwargs):
- """Override plot so that line is closed by default"""
- lines = super(RadarAxes, self).plot(*args, **kwargs)
- for line in lines:
- self._close_line(line)
-
- def _close_line(self, line):
- x, y = line.get_data()
- # FIXME: markers at x[0], y[0] get doubled-up
- if x[0] != x[-1]:
- x = np.concatenate((x, [x[0]]))
- y = np.concatenate((y, [y[0]]))
- line.set_data(x, y)
-
- def set_varlabels(self, labels):
- self.set_thetagrids(np.degrees(theta), labels)
-
- def _gen_axes_patch(self):
- return self.draw_patch()
-
- def _gen_axes_spines(self):
- if frame == 'circle':
- return PolarAxes._gen_axes_spines(self)
- # The following is a hack to get the spines (i.e. the axes frame)
- # to draw correctly for a polygon frame.
-
- # spine_type must be 'left', 'right', 'top', 'bottom', or `circle`.
- spine_type = 'circle'
- verts = unit_poly_verts(theta + np.pi / 2)
- # close off polygon by repeating first vertex
- verts.append(verts[0])
- path = Path(verts)
-
- spine = Spine(self, spine_type, path)
- spine.set_transform(self.transAxes)
- return {'polar': spine}
-
- register_projection(RadarAxes)
- return theta
-
- def unit_poly_verts(theta):
- """Return vertices of polygon for subplot axes.
-
- This polygon is circumscribed by a unit circle centered at (0.5, 0.5)
- """
- x0, y0, r = [0.5] * 3
- verts = [(r * np.cos(t) + x0, r * np.sin(t) + y0) for t in theta]
- return verts
-
- def example_data():
- # The following data is from the Denver Aerosol Sources and Health study.
- # See doi:10.1016/j.atmosenv.2008.12.017
- #
- # The data are pollution source profile estimates for five modeled
- # pollution sources (e.g., cars, wood-burning, etc) that emit 7-9 chemical
- # species. The radar charts are experimented with here to see if we can
- # nicely visualize how the modeled source profiles change across four
- # scenarios:
- # 1) No gas-phase species present, just seven particulate counts on
- # Sulfate
- # Nitrate
- # Elemental Carbon (EC)
- # Organic Carbon fraction 1 (OC)
- # Organic Carbon fraction 2 (OC2)
- # Organic Carbon fraction 3 (OC3)
- # Pyrolized Organic Carbon (OP)
- # 2)Inclusion of gas-phase specie carbon monoxide (CO)
- # 3)Inclusion of gas-phase specie ozone (O3).
- # 4)Inclusion of both gas-phase species is present...
- data = [
- ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', 'O3'],
- ('Basecase', [
- [0.88, 0.01, 0.03, 0.03, 0.00, 0.06, 0.01, 0.00, 0.00],
- [0.07, 0.95, 0.04, 0.05, 0.00, 0.02, 0.01, 0.00, 0.00],
- [0.01, 0.02, 0.85, 0.19, 0.05, 0.10, 0.00, 0.00, 0.00],
- [0.02, 0.01, 0.07, 0.01, 0.21, 0.12, 0.98, 0.00, 0.00],
- [0.01, 0.01, 0.02, 0.71, 0.74, 0.70, 0.00, 0.00, 0.00]]),
- ('With CO', [
- [0.88, 0.02, 0.02, 0.02, 0.00, 0.05, 0.00, 0.05, 0.00],
- [0.08, 0.94, 0.04, 0.02, 0.00, 0.01, 0.12, 0.04, 0.00],
- [0.01, 0.01, 0.79, 0.10, 0.00, 0.05, 0.00, 0.31, 0.00],
- [0.00, 0.02, 0.03, 0.38, 0.31, 0.31, 0.00, 0.59, 0.00],
- [0.02, 0.02, 0.11, 0.47, 0.69, 0.58, 0.88, 0.00, 0.00]]),
- ('With O3', [
- [0.89, 0.01, 0.07, 0.00, 0.00, 0.05, 0.00, 0.00, 0.03],
- [0.07, 0.95, 0.05, 0.04, 0.00, 0.02, 0.12, 0.00, 0.00],
- [0.01, 0.02, 0.86, 0.27, 0.16, 0.19, 0.00, 0.00, 0.00],
- [0.01, 0.03, 0.00, 0.32, 0.29, 0.27, 0.00, 0.00, 0.95],
- [0.02, 0.00, 0.03, 0.37, 0.56, 0.47, 0.87, 0.00, 0.00]]),
- ('CO & O3', [
- [0.87, 0.01, 0.08, 0.00, 0.00, 0.04, 0.00, 0.00, 0.01],
- [0.09, 0.95, 0.02, 0.03, 0.00, 0.01, 0.13, 0.06, 0.00],
- [0.01, 0.02, 0.71, 0.24, 0.13, 0.16, 0.00, 0.50, 0.00],
- [0.01, 0.03, 0.00, 0.28, 0.24, 0.23, 0.00, 0.44, 0.88],
- [0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]])
- ]
- return data
-
- N = 9
- theta = radar_factory(N, frame='polygon')
-
- data = example_data()
- spoke_labels = data.pop(0)
-
- fig, axes = plt.subplots(figsize=(9, 9), nrows=2, ncols=2,
- subplot_kw=dict(projection='radar'))
- fig.subplots_adjust(wspace=0.25, hspace=0.20, top=0.85, bottom=0.05)
-
- colors = ['b', 'r', 'g', 'm', 'y']
- # Plot the four cases from the example data on separate axes
- for ax, (title, case_data) in zip(axes.flatten(), data):
- ax.set_rgrids([0.2, 0.4, 0.6, 0.8])
- ax.set_title(title, weight='bold', size='medium', position=(0.5, 1.1),
- horizontalalignment='center', verticalalignment='center')
- for d, color in zip(case_data, colors):
- ax.plot(theta, d, color=color)
- ax.fill(theta, d, facecolor=color, alpha=0.25)
- ax.set_varlabels(spoke_labels)
-
- # add legend relative to top-left plot
- ax = axes[0, 0]
- labels = ('Factor 1', 'Factor 2', 'Factor 3', 'Factor 4', 'Factor 5')
- legend = ax.legend(labels, loc=(0.9, .95),
- labelspacing=0.1, fontsize='small')
-
- fig.text(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios',
- horizontalalignment='center', color='black', weight='bold',
- size='large')
- return fig
-
-def DifferentScales():
- import numpy as np
- import matplotlib.pyplot as plt
-
- # Create some mock data
- t = np.arange(0.01, 10.0, 0.01)
- data1 = np.exp(t)
- data2 = np.sin(2 * np.pi * t)
-
- fig, ax1 = plt.subplots()
-
- color = 'tab:red'
- ax1.set_xlabel('time (s)')
- ax1.set_ylabel('exp', color=color)
- ax1.plot(t, data1, color=color)
- ax1.tick_params(axis='y', labelcolor=color)
-
- ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
-
- color = 'tab:blue'
- ax2.set_ylabel('sin', color=color) # we already handled the x-label with ax1
- ax2.plot(t, data2, color=color)
- ax2.tick_params(axis='y', labelcolor=color)
-
- fig.tight_layout() # otherwise the right y-label is slightly clipped
- return fig
-
-def ExploringNormalizations():
- import matplotlib.pyplot as plt
- import matplotlib.colors as mcolors
- import numpy as np
- from numpy.random import multivariate_normal
-
- data = np.vstack([
- multivariate_normal([10, 10], [[3, 2], [2, 3]], size=100000),
- multivariate_normal([30, 20], [[2, 3], [1, 3]], size=1000)
- ])
-
- gammas = [0.8, 0.5, 0.3]
-
- fig, axes = plt.subplots(nrows=2, ncols=2)
-
- axes[0, 0].set_title('Linear normalization')
- axes[0, 0].hist2d(data[:, 0], data[:, 1], bins=100)
-
- for ax, gamma in zip(axes.flat[1:], gammas):
- ax.set_title(r'Power law $(\gamma=%1.1f)$' % gamma)
- ax.hist2d(data[:, 0], data[:, 1],
- bins=100, norm=mcolors.PowerNorm(gamma))
-
- fig.tight_layout()
- return fig
-
-def PyplotFormatstr():
-
- def f(t):
- return np.exp(-t) * np.cos(2*np.pi*t)
-
- t1 = np.arange(0.0, 5.0, 0.1)
- t2 = np.arange(0.0, 5.0, 0.02)
-
- plt.figure(1)
- plt.subplot(211)
- plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
-
- plt.subplot(212)
- plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
- fig = plt.gcf() # get the figure to show
- return fig
-
-def UnicodeMinus():
- import numpy as np
- import matplotlib
- import matplotlib.pyplot as plt
-
- # Fixing random state for reproducibility
- np.random.seed(19680801)
-
- matplotlib.rcParams['axes.unicode_minus'] = False
- fig, ax = plt.subplots()
- ax.plot(10 * np.random.randn(100), 10 * np.random.randn(100), 'o')
- ax.set_title('Using hyphen instead of Unicode minus')
- return fig
-
-def Subplot3d():
- from mpl_toolkits.mplot3d.axes3d import Axes3D
- from matplotlib import cm
- # from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatter
- import matplotlib.pyplot as plt
- import numpy as np
-
- fig = plt.figure()
-
- ax = fig.add_subplot(1, 2, 1, projection='3d')
- X = np.arange(-5, 5, 0.25)
- Y = np.arange(-5, 5, 0.25)
- X, Y = np.meshgrid(X, Y)
- R = np.sqrt(X ** 2 + Y ** 2)
- Z = np.sin(R)
- surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet,
- linewidth=0, antialiased=False)
- ax.set_zlim3d(-1.01, 1.01)
-
- # ax.w_zaxis.set_major_locator(LinearLocator(10))
- # ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))
-
- fig.colorbar(surf, shrink=0.5, aspect=5)
-
- from mpl_toolkits.mplot3d.axes3d import get_test_data
- ax = fig.add_subplot(1, 2, 2, projection='3d')
- X, Y, Z = get_test_data(0.05)
- ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
- return fig
-
-def PyplotScales():
- import numpy as np
- import matplotlib.pyplot as plt
-
- from matplotlib.ticker import NullFormatter # useful for `logit` scale
-
- # Fixing random state for reproducibility
- np.random.seed(19680801)
-
- # make up some data in the interval ]0, 1[
- y = np.random.normal(loc=0.5, scale=0.4, size=1000)
- y = y[(y > 0) & (y < 1)]
- y.sort()
- x = np.arange(len(y))
-
- # plot with various axes scales
- plt.figure(1)
-
- # linear
- plt.subplot(221)
- plt.plot(x, y)
- plt.yscale('linear')
- plt.title('linear')
- plt.grid(True)
-
- # log
- plt.subplot(222)
- plt.plot(x, y)
- plt.yscale('log')
- plt.title('log')
- plt.grid(True)
-
- # symmetric log
- plt.subplot(223)
- plt.plot(x, y - y.mean())
- plt.yscale('symlog', linthreshy=0.01)
- plt.title('symlog')
- plt.grid(True)
-
- # logit
- plt.subplot(224)
- plt.plot(x, y)
- plt.yscale('logit')
- plt.title('logit')
- plt.grid(True)
- # Format the minor tick labels of the y-axis into empty strings with
- # `NullFormatter`, to avoid cumbering the axis with too many labels.
- plt.gca().yaxis.set_minor_formatter(NullFormatter())
- # Adjust the subplot layout, because the logit one may take more space
- # than usual, due to y-tick labels like "1 - 10^{-3}"
- plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
- wspace=0.35)
- return plt.gcf()
-
-
-def AxesGrid():
- import numpy as np
- import matplotlib.pyplot as plt
- from mpl_toolkits.axes_grid1.axes_rgb import RGBAxes
-
- def get_demo_image():
- # prepare image
- delta = 0.5
-
- extent = (-3, 4, -4, 3)
- x = np.arange(-3.0, 4.001, delta)
- y = np.arange(-4.0, 3.001, delta)
- X, Y = np.meshgrid(x, y)
- Z1 = np.exp(-X ** 2 - Y ** 2)
- Z2 = np.exp(-(X - 1) ** 2 - (Y - 1) ** 2)
- Z = (Z1 - Z2) * 2
-
- return Z, extent
-
- def get_rgb():
- Z, extent = get_demo_image()
-
- Z[Z < 0] = 0.
- Z = Z / Z.max()
-
- R = Z[:13, :13]
- G = Z[2:, 2:]
- B = Z[:13, 2:]
-
- return R, G, B
-
- fig = plt.figure(1)
- ax = RGBAxes(fig, [0.1, 0.1, 0.8, 0.8])
-
- r, g, b = get_rgb()
- kwargs = dict(origin="lower", interpolation="nearest")
- ax.imshow_rgb(r, g, b, **kwargs)
-
- ax.RGB.set_xlim(0., 9.5)
- ax.RGB.set_ylim(0.9, 10.6)
-
- plt.draw()
- return plt.gcf()
-
-# The magic function that makes it possible.... glues together tkinter and pyplot using Canvas Widget
-def draw_figure(canvas, figure):
- figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
- figure_canvas_agg.draw()
- figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
- return figure_canvas_agg
-
-def delete_figure_agg(figure_agg):
- figure_agg.get_tk_widget().forget()
- plt.close('all')
-
-
-# -------------------------------- GUI Starts Here -------------------------------#
-# fig = your figure you want to display. Assumption is that 'fig' holds the #
-# information to display. #
-# --------------------------------------------------------------------------------#
-
-# print(inspect.getsource(PyplotSimple))
-
-
-fig_dict = {'Pyplot Simple':PyplotSimple, 'Pyplot Formatstr':PyplotFormatstr,'PyPlot Three':Subplot3d,
- 'Unicode Minus': UnicodeMinus, 'Pyplot Scales' : PyplotScales, 'Axes Grid' : AxesGrid,
- 'Exploring Normalizations' : ExploringNormalizations, 'Different Scales' : DifferentScales,
- 'Pyplot Box Plot' : PyplotBoxPlot, 'Pyplot ggplot Style Sheet' : PyplotGGPlotSytleSheet,
- 'Pyplot Line Poly Collection' : PyplotLinePolyCollection, 'Pyplot Line Styles' : PyplotLineStyles,
- 'Pyplot Scatter With Legend' :PyplotScatterWithLegend, 'Artist Customized Box Plots' : PyplotArtistBoxPlots,
- 'Artist Customized Box Plots 2' : ArtistBoxplot2, 'Pyplot Histogram' : PyplotHistogram}
-
-
-sg.ChangeLookAndFeel('LightGreen')
-figure_w, figure_h = 650, 650
-# define the form layout
-listbox_values = list(fig_dict)
-col_listbox = [[sg.Listbox(values=listbox_values, change_submits=True, size=(28, len(listbox_values)), key='-LISTBOX-')],
- [sg.T(' ' * 12), sg.Exit(size=(5, 2))]]
-
-col_multiline = sg.Column([[sg.Multiline(size=(70, 35), key='-MULTILINE-')]])
-col_canvas = sg.Column([[ sg.Canvas(size=(figure_w, figure_h), key='-CANVAS-')]])
-col_instructions = sg.Column([[sg.Pane([col_canvas, col_multiline], size=(800,600))],
- [sg.Text('Grab square above and slide upwards to view source code for graph')]])
-
-layout = [[sg.Text('Matplotlib Plot Test', font=('ANY 18'))],
- [sg.Column(col_listbox), col_instructions],]
-
-# create the form and show it without the plot
-window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI',layout, resizable=True, finalize=True)
-
-canvas_elem = window.FindElement('-CANVAS-')
-multiline_elem= window.FindElement('-MULTILINE-')
-figure_agg = None
-
-while True:
- event, values = window.Read()
- if event in (None, 'Exit'):
- break
-
- if figure_agg:
- # ** IMPORTANT ** Clean up previous drawing before drawing again
- delete_figure_agg(figure_agg)
- choice = values['-LISTBOX-'][0] # get first listbox item chosen (returned as a list)
- func = fig_dict[choice] # get function to call from the dictionary
- window['-MULTILINE-'].Update(inspect.getsource(func)) # show source code to function in multiline
- fig = func() # call function to get the figure
- figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig) # draw the figure
-
diff --git a/DemoPrograms old/Demo_Matplotlib_Ping_Graph.py b/DemoPrograms old/Demo_Matplotlib_Ping_Graph.py
deleted file mode 100644
index b5687502..00000000
--- a/DemoPrograms old/Demo_Matplotlib_Ping_Graph.py
+++ /dev/null
@@ -1,674 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import matplotlib.pyplot as plt
-from matplotlib.backends.backend_tkagg import FigureCanvasAgg
-import matplotlib.backends.tkagg as tkagg
-import tkinter as tk
-
-
-"""
-A graph of time to ping Google.com
-Demonstrates Matploylib used in an animated way.
-
-Note this file contains a copy of ping.py. It is contained in the first part of this file
-
-"""
-
-
-"""
- A pure python ping implementation using raw sockets.
-
- (This is Python 3 port of https://github.com/jedie/python-ping)
- (Tested and working with python 2.7, should work with 2.6+)
-
- Note that ICMP messages can only be sent from processes running as root
- (in Windows, you must run this script as 'Administrator').
-
- Derived from ping.c distributed in Linux's netkit. That code is
- copyright (c) 1989 by The Regents of the University of California.
- That code is in turn derived from code written by Mike Muuss of the
- US Army Ballistic Research Laboratory in December, 1983 and
- placed in the public domain. They have my thanks.
-
- Bugs are naturally mine. I'd be glad to hear about them. There are
- certainly word - size dependencies here.
-
- Copyright (c) Matthew Dixon Cowles, .
- Distributable under the terms of the GNU General Public License
- version 2. Provided with no warranties of any sort.
-
- Original Version from Matthew Dixon Cowles:
- -> ftp://ftp.visi.com/users/mdc/ping.py
-
- Rewrite by Jens Diemer:
- -> http://www.python-forum.de/post-69122.html#69122
-
- Rewrite by George Notaras:
- -> http://www.g-loaded.eu/2009/10/30/python-ping/
-
- Enhancements by Martin Falatic:
- -> http://www.falatic.com/index.php/39/pinging-with-python
-
- Enhancements and fixes by Georgi Kolev:
- -> http://github.com/jedie/python-ping/
-
- Bug fix by Andrejs Rozitis:
- -> http://github.com/rozitis/python-ping/
-
- Revision history
- ~~~~~~~~~~~~~~~~
- May 1, 2014
- -----------
- Little modifications by Mohammad Emami
- - Added Python 3 support. For now this project will just support
- python 3.x
- - Tested with python 3.3
- - version was upped to 0.6
-
- March 19, 2013
- --------------
- * Fixing bug to prevent divide by 0 during run-time.
-
- January 26, 2012
- ----------------
- * Fixing BUG #4 - competability with python 2.x [tested with 2.7]
- - Packet data building is different for 2.x and 3.x.
- 'cose of the string/bytes difference.
- * Fixing BUG #10 - the multiple resolv issue.
- - When pinging domain names insted of hosts (for exmaple google.com)
- you can get different IP every time you try to resolv it, we should
- resolv the host only once and stick to that IP.
- * Fixing BUGs #3 #10 - Doing hostname resolv only once.
- * Fixing BUG #14 - Removing all 'global' stuff.
- - You should not use globul! Its bad for you...and its not thread safe!
- * Fix - forcing the use of different times on linux/windows for
- more accurate mesurments. (time.time - linux/ time.clock - windows)
- * Adding quiet_ping function - This way we'll be able to use this script
- as external lib.
- * Changing default timeout to 3s. (1second is not enought)
- * Switching data syze to packet size. It's easyer for the user to ignore the
- fact that the packet headr is 8b and the datasize 64 will make packet with
- size 72.
-
- October 12, 2011
- --------------
- Merged updates from the main project
- -> https://github.com/jedie/python-ping
-
- September 12, 2011
- --------------
- Bugfixes + cleanup by Jens Diemer
- Tested with Ubuntu + Windows 7
-
- September 6, 2011
- --------------
- Cleanup by Martin Falatic. Restored lost comments and docs. Improved
- functionality: constant time between pings, internal times consistently
- use milliseconds. Clarified annotations (e.g., in the checksum routine).
- Using unsigned data in IP & ICMP header pack/unpack unless otherwise
- necessary. Signal handling. Ping-style output formatting and stats.
-
- August 3, 2011
- --------------
- Ported to py3k by Zach Ware. Mostly done by 2to3; also minor changes to
- deal with bytes vs. string changes (no more ord() in checksum() because
- >source_string< is actually bytes, added .encode() to data in
- send_one_ping()). That's about it.
-
- March 11, 2010
- --------------
- changes by Samuel Stauffer:
- - replaced time.clock with default_timer which is set to
- time.clock on windows and time.time on other systems.
-
- November 8, 2009
- ----------------
- Improved compatibility with GNU/Linux systems.
-
- Fixes by:
- * George Notaras -- http://www.g-loaded.eu
- Reported by:
- * Chris Hallman -- http://cdhallman.blogspot.com
-
- Changes in this release:
- - Re-use time.time() instead of time.clock(). The 2007 implementation
- worked only under Microsoft Windows. Failed on GNU/Linux.
- time.clock() behaves differently under the two OSes[1].
-
- [1] http://docs.python.org/library/time.html#time.clock
-
- May 30, 2007
- ------------
- little rewrite by Jens Diemer:
- - change socket asterisk import to a normal import
- - replace time.time() with time.clock()
- - delete "return None" (or change to "return" only)
- - in checksum() rename "str" to "source_string"
-
- December 4, 2000
- ----------------
- Changed the struct.pack() calls to pack the checksum and ID as
- unsigned. My thanks to Jerome Poincheval for the fix.
-
- November 22, 1997
- -----------------
- Initial hack. Doesn't do much, but rather than try to guess
- what features I (or others) will want in the future, I've only
- put in what I need now.
-
- December 16, 1997
- -----------------
- For some reason, the checksum bytes are in the wrong order when
- this is run under Solaris 2.X for SPARC but it works right under
- Linux x86. Since I don't know just what's wrong, I'll swap the
- bytes always and then do an htons().
-
- ===========================================================================
- IP header info from RFC791
- -> http://tools.ietf.org/html/rfc791)
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |Version| IHL |Type of Service| Total Length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Identification |Flags| Fragment Offset |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Time to Live | Protocol | Header Checksum |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Source Address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Destination Address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Options | Padding |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
- ===========================================================================
- ICMP Echo / Echo Reply Message header info from RFC792
- -> http://tools.ietf.org/html/rfc792
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Code | Checksum |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Identifier | Sequence Number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Data ...
- +-+-+-+-+-
-
- ===========================================================================
- ICMP parameter info:
- -> http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml
-
- ===========================================================================
- An example of ping's typical output:
-
- PING heise.de (193.99.144.80): 56 data bytes
- 64 bytes from 193.99.144.80: icmp_seq=0 ttl=240 time=127 ms
- 64 bytes from 193.99.144.80: icmp_seq=1 ttl=240 time=127 ms
- 64 bytes from 193.99.144.80: icmp_seq=2 ttl=240 time=126 ms
- 64 bytes from 193.99.144.80: icmp_seq=3 ttl=240 time=126 ms
- 64 bytes from 193.99.144.80: icmp_seq=4 ttl=240 time=127 ms
-
- ----heise.de PING Statistics----
- 5 packets transmitted, 5 packets received, 0.0% packet loss
- round-trip (ms) min/avg/max/med = 126/127/127/127
-
- ===========================================================================
-"""
-
-# =============================================================================#
-import argparse
-import os, sys, socket, struct, select, time, signal
-
-__description__ = 'A pure python ICMP ping implementation using raw sockets.'
-
-if sys.platform == "win32":
- # On Windows, the best timer is time.clock()
- default_timer = time.clock
-else:
- # On most other platforms the best timer is time.time()
- default_timer = time.time
-
-NUM_PACKETS = 3
-PACKET_SIZE = 64
-WAIT_TIMEOUT = 3.0
-
-# =============================================================================#
-# ICMP parameters
-
-ICMP_ECHOREPLY = 0 # Echo reply (per RFC792)
-ICMP_ECHO = 8 # Echo request (per RFC792)
-ICMP_MAX_RECV = 2048 # Max size of incoming buffer
-
-MAX_SLEEP = 1000
-
-
-class MyStats:
- thisIP = "0.0.0.0"
- pktsSent = 0
- pktsRcvd = 0
- minTime = 999999999
- maxTime = 0
- totTime = 0
- avrgTime = 0
- fracLoss = 1.0
-
-
-myStats = MyStats # NOT Used globally anymore.
-
-
-# =============================================================================#
-def checksum(source_string):
- """
- A port of the functionality of in_cksum() from ping.c
- Ideally this would act on the string as a series of 16-bit ints (host
- packed), but this works.
- Network data is big-endian, hosts are typically little-endian
- """
- countTo = (int(len(source_string) / 2)) * 2
- sum = 0
- count = 0
-
- # Handle bytes in pairs (decoding as short ints)
- loByte = 0
- hiByte = 0
- while count < countTo:
- if (sys.byteorder == "little"):
- loByte = source_string[count]
- hiByte = source_string[count + 1]
- else:
- loByte = source_string[count + 1]
- hiByte = source_string[count]
- try: # For Python3
- sum = sum + (hiByte * 256 + loByte)
- except: # For Python2
- sum = sum + (ord(hiByte) * 256 + ord(loByte))
- count += 2
-
- # Handle last byte if applicable (odd-number of bytes)
- # Endianness should be irrelevant in this case
- if countTo < len(source_string): # Check for odd length
- loByte = source_string[len(source_string) - 1]
- try: # For Python3
- sum += loByte
- except: # For Python2
- sum += ord(loByte)
-
- sum &= 0xffffffff # Truncate sum to 32 bits (a variance from ping.c, which
- # uses signed ints, but overflow is unlikely in ping)
-
- sum = (sum >> 16) + (sum & 0xffff) # Add high 16 bits to low 16 bits
- sum += (sum >> 16) # Add carry from above (if any)
- answer = ~sum & 0xffff # Invert and truncate to 16 bits
- answer = socket.htons(answer)
-
- return answer
-
-
-# =============================================================================#
-def do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size, quiet=False):
- """
- Returns either the delay (in ms) or None on timeout.
- """
- delay = None
-
- try: # One could use UDP here, but it's obscure
- mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
- except socket.error as e:
- print("failed. (socket error: '%s')" % e.args[1])
- raise # raise the original error
-
- my_ID = os.getpid() & 0xFFFF
-
- sentTime = send_one_ping(mySocket, destIP, my_ID, mySeqNumber, packet_size)
- if sentTime == None:
- mySocket.close()
- return delay
-
- myStats.pktsSent += 1
-
- recvTime, dataSize, iphSrcIP, icmpSeqNumber, iphTTL = receive_one_ping(mySocket, my_ID, timeout)
-
- mySocket.close()
-
- if recvTime:
- delay = (recvTime - sentTime) * 1000
- if not quiet:
- print("%d bytes from %s: icmp_seq=%d ttl=%d time=%d ms" % (
- dataSize, socket.inet_ntoa(struct.pack("!I", iphSrcIP)), icmpSeqNumber, iphTTL, delay)
- )
- myStats.pktsRcvd += 1
- myStats.totTime += delay
- if myStats.minTime > delay:
- myStats.minTime = delay
- if myStats.maxTime < delay:
- myStats.maxTime = delay
- else:
- delay = None
- print("Request timed out.")
-
- return delay
-
-
-# =============================================================================#
-def send_one_ping(mySocket, destIP, myID, mySeqNumber, packet_size):
- """
- Send one ping to the given >destIP<.
- """
- # destIP = socket.gethostbyname(destIP)
-
- # Header is type (8), code (8), checksum (16), id (16), sequence (16)
- # (packet_size - 8) - Remove header size from packet size
- myChecksum = 0
-
- # Make a dummy heder with a 0 checksum.
- header = struct.pack(
- "!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber
- )
-
- padBytes = []
- startVal = 0x42
- # 'cose of the string/byte changes in python 2/3 we have
- # to build the data differnely for different version
- # or it will make packets with unexpected size.
- if sys.version[:1] == '2':
- bytes = struct.calcsize("d")
- data = ((packet_size - 8) - bytes) * "Q"
- data = struct.pack("d", default_timer()) + data
- else:
- for i in range(startVal, startVal + (packet_size - 8)):
- padBytes += [(i & 0xff)] # Keep chars in the 0-255 range
- # data = bytes(padBytes)
- data = bytearray(padBytes)
-
- # Calculate the checksum on the data and the dummy header.
- myChecksum = checksum(header + data) # Checksum is in network order
-
- # Now that we have the right checksum, we put that in. It's just easier
- # to make up a new header than to stuff it into the dummy.
- header = struct.pack(
- "!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber
- )
-
- packet = header + data
-
- sendTime = default_timer()
-
- try:
- mySocket.sendto(packet, (destIP, 1)) # Port number is irrelevant for ICMP
- except socket.error as e:
- print("General failure (%s)" % (e.args[1]))
- return
-
- return sendTime
-
-
-# =============================================================================#
-def receive_one_ping(mySocket, myID, timeout):
- """
- Receive the ping from the socket. Timeout = in ms
- """
- timeLeft = timeout / 1000
-
- while True: # Loop while waiting for packet or timeout
- startedSelect = default_timer()
- whatReady = select.select([mySocket], [], [], timeLeft)
- howLongInSelect = (default_timer() - startedSelect)
- if whatReady[0] == []: # Timeout
- return None, 0, 0, 0, 0
-
- timeReceived = default_timer()
-
- recPacket, addr = mySocket.recvfrom(ICMP_MAX_RECV)
-
- ipHeader = recPacket[:20]
- iphVersion, iphTypeOfSvc, iphLength, \
- iphID, iphFlags, iphTTL, iphProtocol, \
- iphChecksum, iphSrcIP, iphDestIP = struct.unpack(
- "!BBHHHBBHII", ipHeader
- )
-
- icmpHeader = recPacket[20:28]
- icmpType, icmpCode, icmpChecksum, \
- icmpPacketID, icmpSeqNumber = struct.unpack(
- "!BBHHH", icmpHeader
- )
-
- if icmpPacketID == myID: # Our packet
- dataSize = len(recPacket) - 28
- # print (len(recPacket.encode()))
- return timeReceived, (dataSize + 8), iphSrcIP, icmpSeqNumber, iphTTL
-
- timeLeft = timeLeft - howLongInSelect
- if timeLeft <= 0:
- return None, 0, 0, 0, 0
-
-
-# =============================================================================#
-def dump_stats(myStats):
- """
- Show stats when pings are done
- """
- print("\n----%s PYTHON PING Statistics----" % (myStats.thisIP))
-
- if myStats.pktsSent > 0:
- myStats.fracLoss = (myStats.pktsSent - myStats.pktsRcvd) / myStats.pktsSent
-
- print("%d packets transmitted, %d packets received, %0.1f%% packet loss" % (
- myStats.pktsSent, myStats.pktsRcvd, 100.0 * myStats.fracLoss
- ))
-
- if myStats.pktsRcvd > 0:
- print("round-trip (ms) min/avg/max = %d/%0.1f/%d" % (
- myStats.minTime, myStats.totTime / myStats.pktsRcvd, myStats.maxTime
- ))
-
- print("")
- return
-
-
-# =============================================================================#
-def signal_handler(signum, frame):
- """
- Handle exit via signals
- """
- dump_stats()
- print("\n(Terminated with signal %d)\n" % (signum))
- sys.exit(0)
-
-
-# =============================================================================#
-def verbose_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS,
- packet_size=PACKET_SIZE, path_finder=False):
- """
- Send >count< ping to >destIP< with the given >timeout< and display
- the result.
- """
- signal.signal(signal.SIGINT, signal_handler) # Handle Ctrl-C
- if hasattr(signal, "SIGBREAK"):
- # Handle Ctrl-Break e.g. under Windows
- signal.signal(signal.SIGBREAK, signal_handler)
-
- myStats = MyStats() # Reset the stats
-
- mySeqNumber = 0 # Starting value
-
- try:
- destIP = socket.gethostbyname(hostname)
- print("\nPYTHON PING %s (%s): %d data bytes" % (hostname, destIP, packet_size))
- except socket.gaierror as e:
- print("\nPYTHON PING: Unknown host: %s (%s)" % (hostname, e.args[1]))
- print()
- return
-
- myStats.thisIP = destIP
-
- for i in range(count):
- delay = do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size)
-
- if delay == None:
- delay = 0
-
- mySeqNumber += 1
-
- # Pause for the remainder of the MAX_SLEEP period (if applicable)
- if (MAX_SLEEP > delay):
- time.sleep((MAX_SLEEP - delay) / 1000)
-
- dump_stats(myStats)
-
-#=============================================================================#
-def quiet_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS,
- packet_size=PACKET_SIZE, path_finder=False):
- """
- Same as verbose_ping, but the results are returned as tuple
- """
- myStats = MyStats() # Reset the stats
- mySeqNumber = 0 # Starting value
-
- try:
- destIP = socket.gethostbyname(hostname)
- except socket.gaierror as e:
- return 0,0,0,0
-
- myStats.thisIP = destIP
-
- # This will send packet that we dont care about 0.5 seconds before it starts
- # acrutally pinging. This is needed in big MAN/LAN networks where you sometimes
- # loose the first packet. (while the switches find the way... :/ )
- if path_finder:
- fakeStats = MyStats()
- do_one(fakeStats, destIP, hostname, timeout,
- mySeqNumber, packet_size, quiet=True)
- time.sleep(0.5)
-
- for i in range(count):
- delay = do_one(myStats, destIP, hostname, timeout,
- mySeqNumber, packet_size, quiet=True)
-
- if delay == None:
- delay = 0
-
- mySeqNumber += 1
-
- # Pause for the remainder of the MAX_SLEEP period (if applicable)
- if (MAX_SLEEP > delay):
- time.sleep((MAX_SLEEP - delay)/1000)
-
- if myStats.pktsSent > 0:
- myStats.fracLoss = (myStats.pktsSent - myStats.pktsRcvd)/myStats.pktsSent
- if myStats.pktsRcvd > 0:
- myStats.avrgTime = myStats.totTime / myStats.pktsRcvd
-
- # return tuple(max_rtt, min_rtt, avrg_rtt, percent_lost)
- return myStats.maxTime, myStats.minTime, myStats.avrgTime, myStats.fracLoss
-
-# =============================================================================#
-
-
-
-#================================================================================
-# Globals
-# These are needed because callback functions are used.
-# Need to retain state across calls
-#================================================================================
-SIZE=(320,240)
-
-class MyGlobals:
- axis_pings = None
- ping_x_array = []
- ping_y_array = []
-
-g_my_globals = MyGlobals()
-
-#================================================================================
-# Performs *** PING! ***
-#================================================================================
-def run_a_ping_and_graph():
- global g_my_globals # graphs are global so that can be retained across multiple calls to this callback
-
- #===================== Do the ping =====================#
- response = quiet_ping('google.com',timeout=1000)
- if response[0] == 0:
- ping_time = 1000
- else:
- ping_time = response[0]
- #===================== Store current ping in historical array =====================#
- g_my_globals.ping_x_array.append(len(g_my_globals.ping_x_array))
- g_my_globals.ping_y_array.append(ping_time)
- # ===================== Only graph last 100 items =====================#
- if len(g_my_globals.ping_x_array) > 100:
- x_array = g_my_globals.ping_x_array[-100:]
- y_array = g_my_globals.ping_y_array[-100:]
- else:
- x_array = g_my_globals.ping_x_array
- y_array = g_my_globals.ping_y_array
-
- # ===================== Call graphinc functions =====================#
- g_my_globals.axis_ping.clear() # clear before graphing
- set_chart_labels()
- g_my_globals.axis_ping.plot(x_array,y_array) # graph the ping values
-
-#================================================================================
-# Function: Set graph titles and Axis labels
-# Sets the text for the subplots
-# Have to do this in 2 places... initially when creating and when updating
-# So, putting into a function so don't have to duplicate code
-#================================================================================
-def set_chart_labels():
- global g_my_globals
-
- g_my_globals.axis_ping.set_xlabel('Time', fontsize=8)
- g_my_globals.axis_ping.set_ylabel('Ping (ms)', fontsize=8)
- g_my_globals.axis_ping.set_title('Current Ping Duration', fontsize = 8)
-
-def draw(fig, canvas):
- # Magic code that draws the figure onto the Canvas Element's canvas
- figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
- figure_w, figure_h = int(figure_w), int(figure_h)
- photo = tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)
- canvas.create_image(SIZE[0] / 2, SIZE[1] / 2, image=photo)
- figure_canvas_agg = FigureCanvasAgg(fig)
- figure_canvas_agg.draw()
- tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
- return photo
-
-#================================================================================
-# Function: MAIN
-#================================================================================
-def main():
- global g_my_globals
-
- # define the form layout
- layout = [[ sg.Canvas(size=SIZE, background_color='white',key='canvas') , sg.Button('Exit', pad=(0, (210, 0)))]]
-
- # create the form and show it without the plot
- window = sg.Window('Ping Graph', background_color='white', grab_anywhere=True).Layout(layout).Finalize()
-
- canvas_elem = window.FindElement('canvas')
- canvas = canvas_elem.TKCanvas
-
- fig = plt.figure(figsize=(3.1, 2.25), tight_layout={'pad':0})
- g_my_globals.axis_ping = fig.add_subplot(1,1,1)
- plt.rcParams['xtick.labelsize'] = 8
- plt.rcParams['ytick.labelsize'] = 8
- set_chart_labels()
- plt.tight_layout()
-
- while True:
- event, values = window.Read(timeout=0)
- if event in ('Exit', None):
- exit(0)
-
- run_a_ping_and_graph()
- photo = draw(fig, canvas)
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Matplotlib_Ping_Graph_Large.py b/DemoPrograms old/Demo_Matplotlib_Ping_Graph_Large.py
deleted file mode 100644
index 38f7cf60..00000000
--- a/DemoPrograms old/Demo_Matplotlib_Ping_Graph_Large.py
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import matplotlib.pyplot as plt
-import ping
-from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureCanvasAgg
-import matplotlib.backends.tkagg as tkagg
-import tkinter as tk
-
-#================================================================================
-# Globals
-# These are needed because callback functions are used.
-# Need to retain state across calls
-#================================================================================
-class MyGlobals:
- axis_pings = None
- ping_x_array = []
- ping_y_array = []
-
-g_my_globals = MyGlobals()
-
-#================================================================================
-# Performs *** PING! ***
-#================================================================================
-def run_a_ping_and_graph():
- global g_my_globals # graphs are global so that can be retained across multiple calls to this callback
-
- #===================== Do the ping =====================#
- response = ping.quiet_ping('google.com',timeout=1000)
- if response[0] == 0:
- ping_time = 1000
- else:
- ping_time = response[0]
- #===================== Store current ping in historical array =====================#
- g_my_globals.ping_x_array.append(len(g_my_globals.ping_x_array))
- g_my_globals.ping_y_array.append(ping_time)
- # ===================== Only graph last 100 items =====================#
- if len(g_my_globals.ping_x_array) > 100:
- x_array = g_my_globals.ping_x_array[-100:]
- y_array = g_my_globals.ping_y_array[-100:]
- else:
- x_array = g_my_globals.ping_x_array
- y_array = g_my_globals.ping_y_array
-
- # ===================== Call graphinc functions =====================#
- g_my_globals.axis_ping.clear() # clear before graphing
- g_my_globals.axis_ping.plot(x_array,y_array) # graph the ping values
-
-#================================================================================
-# Function: Set graph titles and Axis labels
-# Sets the text for the subplots
-# Have to do this in 2 places... initially when creating and when updating
-# So, putting into a function so don't have to duplicate code
-#================================================================================
-def set_chart_labels():
- global g_my_globals
-
- g_my_globals.axis_ping.set_xlabel('Time')
- g_my_globals.axis_ping.set_ylabel('Ping (ms)')
- g_my_globals.axis_ping.set_title('Current Ping Duration', fontsize = 12)
-
-def draw(fig, canvas):
- # Magic code that draws the figure onto the Canvas Element's canvas
- figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
- figure_w, figure_h = int(figure_w), int(figure_h)
- photo = tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)
- canvas.create_image(640 / 2, 480 / 2, image=photo)
- figure_canvas_agg = FigureCanvasAgg(fig)
- figure_canvas_agg.draw()
- tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
- return photo
-
-#================================================================================
-# Function: MAIN
-#================================================================================
-def main():
- global g_my_globals
-
- # define the form layout
- layout = [[sg.Text('Animated Ping', size=(40, 1), justification='center', font='Helvetica 20')],
- [sg.Canvas(size=(640, 480), key='canvas')],
- [sg.Button('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]]
-
- # create the form and show it without the plot
- window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout).Finalize()
-
- canvas_elem = window.FindElement('canvas')
- canvas = canvas_elem.TKCanvas
-
- fig = plt.figure()
- g_my_globals.axis_ping = fig.add_subplot(1,1,1)
- set_chart_labels()
- plt.tight_layout()
-
- while True:
- event, values = window.Read(timeout=0)
- if event in ('Exit', None):
- break
-
- run_a_ping_and_graph()
- photo = draw(fig, canvas)
-
-
-if __name__ == '__main__':
- main()
diff --git a/DemoPrograms old/Demo_Media_Player.py b/DemoPrograms old/Demo_Media_Player.py
deleted file mode 100644
index 74101bb0..00000000
--- a/DemoPrograms old/Demo_Media_Player.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
- # import PySimpleGUIQt as sg # portable to QT
-else:
- import PySimpleGUI27 as sg
-
-#
-# An Async Demonstration of a media player
-# Uses button images for a super snazzy look
-# See how it looks here:
-# https://user-images.githubusercontent.com/13696193/43159403-45c9726e-8f50-11e8-9da0-0d272e20c579.jpg
-#
-def MediaPlayerGUI():
- background = '#F0F0F0'
- # Set the backgrounds the same as the background on the buttons
- sg.SetOptions(background_color=background, element_background_color=background)
- # Images are located in a subfolder in the Demo Media Player.py folder
- image_pause = './ButtonGraphics/Pause.png'
- image_restart = './ButtonGraphics/Restart.png'
- image_next = './ButtonGraphics/Next.png'
- image_exit = './ButtonGraphics/Exit.png'
-
- # A text element that will be changed to display messages in the GUI
-
- ImageButton = lambda image_filename, key:sg.Button('', button_color=(background,background), image_filename=image_filename, image_size=(50, 50), image_subsample=2, border_width=0, key=key)
-
- # define layout of the rows
- layout= [[sg.Text('Media File Player', font=("Helvetica", 25))],
- [sg.Text('', size=(15, 2), font=("Helvetica", 14), key='output')],
- [ImageButton(image_restart, key='Restart Song'), sg.Text(' ' * 2),
- ImageButton(image_pause, key='Pause'),
- sg.Text(' ' * 2),
- ImageButton(image_next, key='Next'),
- sg.Text(' ' * 2),
- sg.Text(' ' * 2),ImageButton(image_exit, key='Exit')],
- ]
-
- # Open a form, note that context manager can't be used generally speaking for async forms
- window = sg.Window('Media File Player', auto_size_text=True, default_element_size=(20, 1),
- font=("Helvetica", 25)).Layout(layout)
- # Our event loop
- while(True):
- event, values = window.Read(timeout=100) # Poll every 100 ms
- if event == 'Exit' or event is None:
- break
- # If a button was pressed, display it on the GUI by updating the text element
- if event != sg.TIMEOUT_KEY:
- window.FindElement('output').Update(event)
-
-MediaPlayerGUI()
-
diff --git a/DemoPrograms old/Demo_Menu_With_Toolbar.py b/DemoPrograms old/Demo_Menu_With_Toolbar.py
deleted file mode 100644
index 9a9afa94..00000000
--- a/DemoPrograms old/Demo_Menu_With_Toolbar.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-
-def ShowMeTheButtons():
- # ------ Menu Definition ------ #
- menu_def = [['&File', ['&Open', '&Save', '&Properties', 'E&xit' ]],
- ['&Edit', ['&Paste', ['Special', 'Normal',], 'Undo'],],
- ['&Toolbar', ['---', 'Command &1', 'Command &2', '---', 'Command &3', 'Command &4']],
- ['&Help', '&About...'],]
-
- sg.SetOptions(auto_size_buttons=True, margins=(0,0), button_color=sg.COLOR_SYSTEM_DEFAULT)
-
- toolbar_buttons = [[sg.Button('', image_data=close64[22:],button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0,0), key='_close_'),
- sg.Button('', image_data=timer64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_timer_'),
- sg.Button('', image_data=house64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_house_'),
- sg.Button('', image_data=cpu64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_cpu_'),
- sg.Button('', image_data=camera64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_camera_'),
- sg.Button('', image_data=checkmark64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_checkmark_'),
- sg.Button('', image_data=cookbook64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_cookbook_'),
- sg.Button('', image_data=download64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_download_'),
- sg.Button('', image_data=github64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_github_'),
- sg.Button('', image_data=psg64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_psg_'),
- sg.Button('', image_data=run64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_run_'),
- sg.Button('', image_data=storage64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_storage_'),
- ]]
-
- # layout = toolbar_buttons
- # ------ GUI Defintion ------ #
- layout = [ [sg.Menu(menu_def, )],
- [sg.Frame('', toolbar_buttons,title_color='white', background_color=sg.COLOR_SYSTEM_DEFAULT, pad=(0,0))],
- [sg.Text('', size=(20,8))],
- [sg.Text('Status Bar', relief=sg.RELIEF_SUNKEN, size=(55, 1), pad=(0, 3), key='_status_')]
- ]
-
- window = sg.Window('Toolbar').Layout(layout)
-
- # ---===--- Loop taking in user input --- #
- while True:
- button, value = window.Read()
- print(button)
- if button in ('_close_', 'Exit') or button is None:
- break # exit button clicked
- elif button == '_timer_':
- pass # add your call to launch a timer program
- elif button == '_cpu_':
- pass # add your call to launch a CPU measuring utility
-
-
-
-if __name__ == '__main__':
- house64 = 'data:image/png;base64,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'
-
- timer64 = 'data:image/png;base64,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'
-
- close64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAE30lEQVRIiZ2VXYgdRRqGn6+quvucM/85iRoTNevMBJFEWY0GFQTBC1HBlaz/jMpoFFfXBdmFvdiLvRIEFRHFGBXMjUQhF/6Bol6sSNaIruCNir/R/Dlx5iRzck736e6qby/6JDlx9CIWFN10Ue/7vW+9X7XcDn8bryWPL2vERkNQQPj9Q72K7F3s7Hxb9bZ98L0bj91jt1y23kxNTxIEGUQ/aTYR6WW9cud/Prx01zf7/7FP5EHXHG7Y6bVTpBPLMSegCWKEEMKvkihgjEWDP+FbEjxTa1bjv9l/CsIKF3ypHhUDSFGACCKC956iKKjV6/hfkCjgUNK0TW1oCA3h+EJk8UUBYFCsQaSyRajArUWLnEONcTrT68nTLtZaEKmmMTiUlsREGy9HO0dgcL1y6lgtZrAsEYFexhwxq2buYfru+1mcOo+828UYg4rgUH7OSkY3zbDq1lkaV1yFP9TqEyy18jiBCMF7DjYmOOu+hxifnCSKItZuvp/F6fPJ05TEwE+dHhN33MfpGy4iFAVjf7qF8etvBV9y1IilBApGIMt6TExOM372JKqKqhLFMdOz93Jk6jx+bHVoztzLyj9eiHqP2Gq7O3UlGAuq1RwYDlUwhoChMdSAz3ZxaEeD8T/fBggaAnGtxpqZWdKFBSbOPLMCCQGJItJPdrHw4lOYRgNsBM6dSCDGErIuodtGkhoyPEr68U5svcbI1ZsQY0CV2vAw9ZGRKjEiSBTR/fQjDm9/AddcjqoSul182kYHVDhJauRffUH7wD7ilatxzVOwI6PM7XiJLO2x4rob0CgGVTSEKigidD94j/ltW9Dg0b0/4BfmyQ8ewKUdWLZ6wCIB9SXFXJvQ+hLkc6QeEznHf199jY1rpjh1w0ZUFTGm7z18/tSj2Hffor5shKLdhhJCADMcw7IlKRIkAqkJRIa4LPl6d5c/PPJkBd5vpArcArD+ue101l1Md08bFxuIBUlOyOUggUIAVIl94Kv5wKqtz7L+7r/0bRHEmApcFbwnHhljw6tv0b3kEtK5gDWmj/GbfQAWZbdaztjyPOfP3oN6D8GDCO133uDAvx9CyxKsRX1JMjbBBa+8Rnbl5RSpR35RfXUGfVLnYGFBcTfdwLo77yLkPYy14CLa773JngfuoNy7QOh2WPnw09WVkufUm8s598G/s+eT9wmBJZ1m+sVTFNBc4Wi8vJ3v//kAJk7AOhbf3MGezTfjWwuYCcv8s1s58K+/okWOxDGdjz5g7+YZtKRSoL+igCp5FKVntGk48sTTzDWb1C+4mB833wgETD2CELBjEfNbtyAjo4xdcz27N11L6B5GGoZQhN+26KiSoII9LebnJx9BkggzNIQkyfEdItiRQGvbM7S2bQHJMGN1NO8ds2dQhBORYBCjAFEE1kFSw0QxuAiTJCAGce64vz4gviTkOTJcErIMMRbyDIxg7bHTFnc47clcmpdj43VkeBRJEkytgdTqSL2OiRMkSRDroH9t4EtCUaBZhmYpIUurZ9pFfVnuX+w62xfjeq3D3/6vbifXrT1XkzgWdREmipA4RlwMUYRY21cg/X+lJ5gSbIHGOVovCHmOCSX7DrbMx599icIhVI2cA5c5mC1gbGnITm4oqAOr0PoOXs9g51HAGiITyCDByXDp4KuiaoESmP8/YC0Y5GajmEsAAAAASUVORK5CYII='
-
- psg64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABlbkiVhkyZikyFjmShjkyhlly1mli5nlylnmS5olyppnC5qmi5rmzBpmDBpmTFqmDFqmTFqmjNrmzFrnDNsmzJsnDJtnTFunjNvnzRsmTRtmzVunTVunjVvnzZwnjlxny5toDFvozJwoTNzpjVwoDRzpDRzqDd4rThyojp0ozl1pTt2pjt3pz11ozt4qDl4qTp6rTl6rzx4qD55qTx5qj97qz17rT58rD98rT9+rz5+sEB3pEF9rkB+r0F+sEF/sT2AtD6AtT6Btk+Aqk2CrEOBs0GBtEKCtEGCtUSBskWBs0SCtEWDtUaEtkWFt0aGt0KFuUCEukOGu0eFuEWHu0eJvEiGuUiHukiIuUiIukmJu0uKvEyKvFCAp1CCqlODrVKCrl2Kr1OEs1KGsFWGsFaIsVaPvFqKsl6NsmKNsWeTuG6YvHadvlySwV6UxF+YxW+bxW6dxnKewHGex3SdwHSfx3egwXGizHmgwHqkxnyjxHio0f/RMf7QMv/TMf/SMv3SNf7UOv7UO//UPP/UPf/UPv/VP//WPP/XPv/VQ//WQv7XQ//WRP/XRf/WR//YRv/YSP/YSf/YSv/ZS//aS//ZTf/aTP7aTf7aTv7bT//cT//bUP/cUP7cUv/cU/7cVf/eVf/fVv/eV/7dWP/eWP/eWf/fWv/fW//fYvzcaf/hW//gXP/gXv/gX//hYP/hYf/hY//iYP/jY//gZf/iZP7iZf/jZv/iZ//lZv/jaf/kav7ka//maf/ma//kbf/lbv7mbP/mbv/mb//id//mcP/ncv/nc//ld//ndv/meP/ocf/ocv/oc//odP/odf/odv/peP/pff/qfY+11ZSzz5G41qC81aW/1P/jgf/qiv/qjv7qoMnZ5szb587d6eDm2+fo1+7v3e/x3vXw1fHx3gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJblQd8AAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAABcQAAAXEAEYYRHbAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjFjKpxLAAABzUlEQVQoU2P4jwNAJZIEuLJA9M2u/iNgAaiEELOgIFPc//+r6puaalvAQmAJdg4pPj4h5oT/2+raWtqaGmAS/PxC/IJAGdbEB7saW5pb20AyQAkFNiFhUSEgkGZNfjizua29u70XJJHr8j+eV0RGVkRMTJb56u2mvt7eSR0gCT2gPsbMGzbi8hJyPDl3OidPnDRlwhagRHbG/zTXe5WSqqqqmpzXb/VMmz5jztSVIDtSWFLvl3Jrampq8ZY8WThj1tx586ZCXFV9t1xRR1tbR6Lw0f6ZC+YvWDAb6tz/xUom+rrGymWPD8xaunjZ0oUgMZBEsYqZqampWsnTY/PWLF+xZhFIHCRRpW5raWFhUPT/3IJ1a9euW/H//5oTYAlDezs7Kwvv//+XbN6wcev6//+3/z8FltDwcrC3N8/7v3rHtu07Nv3/vxVo0CWQhJGPm5ubdf7/TXt279699//JnTA70j38fH19wv//33b00OGj+w6fPXz5KMRVTiH+/gHuFf//7zl+5szZs2fO7YPo+H/FOSIyPMqz5v//g+dAMocvQCX+XwsMjYmNdgSy9p0/d/bgRZAYWOL//4LgoDAwY+++02AaJoEJcEj8/w8A4UqG4COjF7gAAAAASUVORK5CYII='
-
- cpu64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAFi0lEQVRIiZ1WS2wbRRj+/5l92O6u7WycTW03xLEd6uBUjVO1hfbSByLQEwhxoIhbCwcuvApUiEOFhAQVEiAOvK4gqoojSEhtgUNApaJKG5qkdWpa1JfcZL3teu3sZmeGQ9ZVGhIJ8Z/+2Vn93//45psBWMMqlcoXxWLxEACAaZpju3btOkkIoZRSsnv37hOmaY4BABSLxUOVSuXzteJIq32klMqyLBuqqhoAAKqqGpTSpKIoSUQESZK6OnuKohiKohiUUpkxtvivWCvWBABEOp1+sr+//5V169ZtnJub+6FUKh3Rdf3hVqv1l6Zp5Ww2ezASifQ0Go3fhoaGjsZisYdardaM4zjTiEgAQHQC4j0HkQghAAC4oiiJRCKxBQBIs9m8oOt6iRASa7VaVwEAYrFYP+e85TjOpXg8PiyE4LZtn/F93wYAgogghOD3AYS+UFW1q1AovGoYxp4wGxIEgS2EEIQQCQCAcx7gkslCCB8AwLbt07Va7SPP8xqdWPdmIElSxDTNfZZlncrn828MDg6+VavVPvF9fy4Wi/X19fUdWJHMfSaEYJlMZgwRpVqtdtQwjD31ev2HIAgWpJGRkS8VRTEMw9g9OTm5v7u7+9GpqamXq9XqxwAAmzZt+oBzjpzzYC0QIQRDRJpIJLanUqmdw8PDX1mW9ZPv+5bkOM5FVVVTiURia1i24rruDQCAUqn09sDAwCHGGEdEadnwlgOJZT5BRMIYc5rN5iXP8+ax0y9N04qc84Vt27aduHjx4uuEED46Ovo95xxEOH1ExKWEhQh9DPe4JEl0fn7+14mJiecQUWo2m7MAgNQ0zb3d3d3bhoaGjrTb7Wld1x/p6uoa2bBhw4uyLGsAEFBKKSIi51xQSjFcIiICIQRDAhDXdWue502Vy+X3hRALqqr2SoODg2/KsmzE4/GNlNJ1nPOF9evXPxYEAbiue7lWq72rKIphmub+GzdufBeNRg1d14cZYx4hhBJClFQqNRbOQlBKo8lkcms+n48vLi5a0vj4+OOKoiTT6fQzjuNcJYRIQRCALMswOzv7LSEk0tPT85TjOBeCIKi12+1rtm3/ruv6FgDgAMB7e3vHgiAAQgh1HOfquXPnXr958+Zx3/dtshopltp7nyEiUtd1rxuG8URfX99B13Un2+32rKIo3ZzztRgMdOfOnT/mcrkX+vv79zcajVOapm3XNC3HGINoNNpnWdZJz/P+TiQSOzRNK6bT6WcjkUh/q9WaQUTIZrMHEFEjhECz2fzL9/2ZkZGRz0zT3JfNZp+WqtXq+5FIJJXL5V5kjLVDdgDnnMVisYFyufxVSFHgnO9gjDFElIvF4jth34ExxgCAIiIyxtq2bZ+5cuXK5wsLC3NSvV4/BQDCsqw/hBBBLpeTO+WF/KdhC0TIHAoAIggCjogYMnjpEBAi27Z96ezZsy90aCoVCoXXVFVNZbPZ/TMzMy9xzr1ljSdhYLHicN0DCkFYWKFnGMamUqn06fXr17/xPG9e0nV9Y6jnWqiAPCydrTm5laxY+pcCABdCcEqprmnag4qiWNLExMTBZWI3Ho/Hd2Qymb1CCBpm+V8AQJZluHPnzum5ubnx8+fPH+iI3apync/nX04mk9vDXihCiMX/K9drXTjJZDK5FRHJ3bt3/9R1/cH/e+Esb0FnkKK3t3ff5s2bv+7p6Rm7devWsXK5/GGhUDjsOM5kNBp9oFKpfKNp2kC9Xv9xdHT0eCaTed513fPhlYmd4CsBOiDQarVmu7q6KpZl/XLt2rVjQggvHo8PTE9PH242m1PpdPrRy5cvf3L79u2fo9GoyRi7U61W3wsDL5fv1V8VjLFF3/ct3/ctAADP86wgCBq+7zcAABljtud5FgCA7/uWLMvWai8KAIB/ACsf4Gh+DNwbAAAAAElFTkSuQmCC'
-
- camera64 = 'data:image/png;base64,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'
-
- checkmark64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAD2ElEQVRIibWVe4hUVRzHP+feuTOz82gfrqwu5gM0zTQpS1yfoGQPyc3IjOwlYRElPcDICEP6Q6i/IvojCCIpTA0tSlSqJSvbTLZE0dbWxz4nXWdnxrk7M/feOY/+sHyEa7pt57/z45zP53x/B84R/B/jzeNLgeXADDHE4IeBV2Ihpo6LK1rzNqEhAW9oGw18UhelYeWUGHFL0tx5lqPZyBAI3mi9o8YRm16cWTlsVFLQVwjY2+4SSI2W+j8KXj+ybmwytO69xjo7Wyqzr8sldbaE60ksIdBlhTVo+KuHXppY5azftKzeNsbQkurntOuTKQQobYhFbCgPNsGaA5NDWm94ZlYV7fmAX3pcenIlTucDAqlJRENUxcJQLgwiwfMtYcpq4503JMJjq8M0d+XpyBRJnfUpBpJwyKYqFqbCcSCQg0gQyCeq4qHp90yr5Pd0kY6+ImnXJ1CaeDhEdSJCTSJKzLEHLXhu4oQEuWKZ79uzZAoX2hKPhOn+I6DtuEdfLriC4NE9L4CYhzEP8dH84Hz9kT0NBHLqvMlJmo5nyBQDylITj4RwM5rmw70orcEA0AL8Q/DgN8OBr/DltL8q64G1F52+obomwr6US7boE0hNhRPiVIdHx7H+EvA2sJ0tC3/+e8uFS27c/SS+7ElGrGkbnp5EfV0UArmGxt0Lzq/x5YzKWocz/T4FXyGEINvj0XE410QgJ7Fl4dqL4ecS3PVlJYgdllKzx04ZxqolY8h4mkm315JPl+z+nP8Bd++4hZ2LM/hyuokLCr7Eti28TJnOA5ndGLOUnYtLl+u2YMHnJ4BxY2bWsWj2SA72eoBBG4PnBvy2qwvpq81gVjhJp1Q7q9axLIFVMqSaz3ytfLWEpsbLwgFs6pc1o/R9+e7+eK9joSMWvjR4gSLA4FSGKLS7UyirUmRkbJFTG0VI6N17+oR0/bl8d/+A8HMJAG7bPB7BTmGL8TVz64mMiKGNQSuN0hqvq59CS59Kzq2zo8MrcH/s1V6qMIf9y5uvBL8gALj54xpgG5aYH589klB9BdoYjDY0XJ9k9HURPj2aRZ/ycL/tfouDK17+N/ilAoAbP6wAsRGLB8INI7BGJUAYLGEhLAtLCApfnDymc95NtD4eDMC8ZNiXzNKfSdLbt5K8N6o68nNMwoHqKCAwlkVwKI06ln2MtpWtVwMHBnjspHyNQO1Xe7pRbTmUEchCGbk/laKsdl0tfGBB51OKQM0hUD/ppk7kkTTy11NQku/TuUpdi+DKn/7wdyuAHzDcii0Uykwg/ezJoRMAVL9TCWwFjpJdvfpa4AB/Akx4zQw8GDagAAAAAElFTkSuQmCC'
-
- cookbook64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAIAAAB1KUohAAAACXBIWXMAAAsSAAALEgHS3X78AAADMUlEQVQ4jY1UQUgCWxS9782M5hQzle3NTRGEQdBipCKKECoEg4JaJAqCmyBsYauEaNOqjQtXLSKINuFiKMiwIMtF1iLK2kWRZLUoDRxo5s37ixfSt4+/u7xzz51z7r3nwc7Ojt1uBwCEEPwtWKXL5eIvLy+HhoYIIYIgCIJAKa0Do5RyHPfy8nJycnJ1dcUjhJxOZygUOj09zefzFoulDp5SihCKRqPLy8vJZBI4jgOAo6Mjj8cDABjj/6WdTqdDoRAAfJeyFn8MQohhGADAY4xFUSyVSpIkAYBpmgih+soRQmxm2GazbW5u7u7ujoyMKIrCmP+ePMdxv9nhSqXi8/lmZmb29vay2Syrs1gs8EM/QogQQgipBWOMOzs7397eWlpabDYbAMiyHAwGu7u7mQTWzu/3R6PRxsZG+HERvNVqjcVix8fHfX19Nzc3T09PHo+HUjo1NVUulx8fHwFgbW0tEolQSguFwtbWVpU/rlQqs7Ozc3NzqqrmcjmXy9Xe3m61WgcGBubn5wGgo6NjYWEBAEql0t3dHQBUx8ljjNva2orFYnNzM8/zBwcHFoslGo329/cXCgUA6OnpwRh/fHwsLS3lcjm2qm9wQ0NDPB7f398fHBx8eHjIZrOqqhaLRUmSwuFwPB53OBw+ny+dTn9+ftYujed5AEilUhMTE9U9saTX66WUJhKJmv0dHh4Gg0FgF4YxJoQwANNjGIaiKLFYbHp62ul0Li4umqb5H5crSVIymQwEAolEwu12s6SiKNfX15OTkwDgcDguLi4ikUgVUv0zCIJgs9lUVWWlrP3q6qrf72dfAaCrq2tjY0OW5RowTynVNM1qteq6XqW9srJiGAZCSNd1hNDt7W04HGZm+NeFiaKYTCa3t7fHx8fdbjez+9fXV7UR87Cu66Zp1oI1TQsEAl6vN51Os9smhCCEfpbWmMw0TZbBpmm+v7+3traWy2VKKdP825I/M7Isi6IIAFxTU9P6+nomk+nt7X19fX1+fsYY1/ez0+k8Pz+/v7/nMMblcnl4eDifz5+dnWmaVgfGolQq2e32sbGx7wcok8mMjo7C396wVCpFKSWE/ANWXYLwO0+V8wAAAABJRU5ErkJggg=='
-
- download64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAEl0lEQVRIia2WS2hdZRDHf/Odc+7NvbZpYky1Gk2rEbRa26pt8UWLitYHIqigCD426kIQxCfWhYu68U0RBBERXCq+WrXoorYIFWpbEY0lpk0NTWKtuUlzn+d834yLm5smqQspzurMcM785j+c+eYTTtUcESAzvhIAm/+azHacA4FodszAVNFTrUPm+Q6iecmUyJkEna5OiDCCXCtvJ2cnV+Ep+9R7/VIfQhmeryKeySywok+SSMMKMwqAihDXPIcPDDMURUQCgiPWjJCck6x87ZXXV3cXu3XTO5tkYOvAHbnIfZipTpghLdAMIEngi1cXvtlzwfrHpG0x5ismzsvo0E9D9z7z++M799s2EcSm67OUkAs5cpbzkkoMtPtAAzdXQ9zqjHkt1Ol5SHofx0KWYRUxrdiS3FlLtzz51wd7+v2OQl7qHnPtorUXS3ZxPRUKUT5x4mTDWu559LbCNS+9X9v025Duc4KoYdMAA7A4Mk92EMp/JFIZwR/rx9dL1teVdC2/Qe8yzQg+pS0JvLUzx3hjioPVQamGGlcu47KNq6qrPj+fsd+GeAEYA2SmRQiCNSJKP1Ad3IVaG0nnlWRxKqkkVlYxJxGZwhmFIo34U/fh0Hv4v6YYrY+ihYtkorDUNj+298GPvzv6ZRrkMzA/oyCXh9rEMOOHfiLfcx+5zhXkOnppswxEpJHVxdTjs0CycDHy9XcMlwc5a0E3EoTconOls/dyBsb6lYRLY4m/9T6blDgi8oHw3rPx83fesubl4oVPWFvXBUKoQzqB92Xitpite77n/k/epaN7AZO1CTIROtZ14fJC6ccS9ndGUhRLK0Eum1h2YGpH5eFfD47sjluzcFo+f+vp655F03alNhZhASMjloA1qtzedzab125kiw2QLhHaQ0zIFM2MztUdkBcqx1Lp+0o59NGRP49OVQs0Z3d6nEyMUMP8OGgVtAJaA19CagP4xn4e6DPuPhox1V9HTRFr/h9mRmWkwbJtGSsHK4xXq4cQGQDCDABM0ClEy6DlJiA9DLV90BgktirFzhrPXX0mT6Y9lAaqkAhRItRKGT3bjetTYd2aYM7JYcwm5wwaAP44hDyQYukokg5jliICZoFIoNjZ4Ol1HdhueOPgCLlFjt7twvo63HwztGuipml20lEBBlrGfBXzR5BsDGjOPBrAAkJKRKBwuuepNUXyP5/HN7tKXFGvcuMGY/3qhAO/NLCTJ7kFmIT0OPgjmAhiYKYIASFgGoCUyAILu+o8ckng0jSwsF1YuzxP0hYwm3tizwIIpKPQOIY4BXUYCiiYYWSIKYYHMoRAV1fKTddFxJKQOA/mmW9zFWRjoCmYw6R1lrcg2kxgAfCIeRxKMa+YBSw0Vc7fOScAZuAnMXWYE8yaIUFBDFSbS8sCgscsayZWD3jMAmhT7b8CnDPIeZw6RGTOLmwWFRALMA3BZvkamoBcwM3Zh7MA9Yb5I3v/YKoKTlr9sROKZVrlTGDWsylmkMTGxCQ4h0ObGaT1aRJzHsbtwJJmWSet0/9kIpB69gPbgersJA4oMm/pn6JlQI1/uWX87/YP06p9rkZQnAYAAAAASUVORK5CYII='
-
- github64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAADAwMDQ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhyjGAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdUAAA3VAT3WWPEAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAABzSURBVChTbYxRFoAgDMPQ+98Z1zbIeJqPbU3RMRfDECqyGpjMg6ivT6NBbKTw5WySq0jKt/sHrXiJ8PwpAAVIgQGkwABSYAApMIAUGEAalFmK9UJ24dC1i7qdj6IO5F+xnxfLu0jS0c7kqxd3Dk+JY8/5AKFrLuM7mfCAAAAAAElFTkSuQmCC'
-
-
- run64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAszD0iAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdUAAA3VAT3WWPEAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAABqSURBVChTpY5JDsAwCMTy/09TMGvFpVF9aAZPRHpkcXC7OIodPg0uCjPq+MwCrWRGKkiIvLyTqzw3aqoI73eqUNAoXBXlg4zudxF+NONfPIVvbSZPgww5oW0Vz8T4Lgbt/xbjia+rahR5AEYEg4vdzh2JAAAAAElFTkSuQmCC'
-
- storage64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABwcHDQ0NDg4ODw8PFxcXGRkZGhoaGxsbHh4eIyMjJSUlJiYmJycnKCgoMTExMjIyNTU1NjY2Nzc3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAouNksgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdQAAA3UAe+RuhUAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAAC5SURBVChTfZLbDsMgDEPpbb3TDv7/W7PYuAztYUeqhO2QAGowkXIMIeYkaSU4QsNBi4GcyhNINpTglmq4GWSphvy/ldkuLXZ4HmAxy3NmFJaA4guKGCwsjClfV05+fWdhYBtFw+amB292aygW3M7fsPTwjmadZkCvHEtWaAYTViBqVwgTA3tJVnB6D/xhaimItDhjMBvlhtFsaIafnEtOaAY/twAw/eslK70CbX8obUvgJNw9Jv0+Zh8D4s5+VAm/LwAAAABJRU5ErkJggg=='
-
- ShowMeTheButtons()
-
diff --git a/DemoPrograms old/Demo_Menus.py b/DemoPrograms old/Demo_Menus.py
deleted file mode 100644
index 92235224..00000000
--- a/DemoPrograms old/Demo_Menus.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python
-import PySimpleGUI as sg
-"""
- Demonstration of MENUS!
- How do menus work? Like buttons is how.
- Check out the variable menu_def for a hint on how to
- define menus
-"""
-def second_window():
-
- layout = [[sg.Text('The second form is small \nHere to show that opening a window using a window works')],
- [sg.OK()]]
-
- window = sg.Window('Second Form', layout)
- event, values = window.read()
- window.close()
-
-def test_menus():
-
-
- sg.change_look_and_feel('LightGreen')
- sg.set_options(element_padding=(0, 0))
-
- # ------ Menu Definition ------ #
- menu_def = [['&File', ['&Open', '&Save', '&Properties', 'E&xit' ]],
- ['&Edit', ['&Paste', ['Special', 'Normal',], 'Undo'],],
- ['&Toolbar', ['---', 'Command &1', 'Command &2', '---', 'Command &3', 'Command &4']],
- ['&Help', '&About...'],]
-
- # ------ GUI Defintion ------ #
- layout = [
- [sg.Menu(menu_def, tearoff=False, pad=(20,1))],
- [sg.Output(size=(60,20))],
- ]
-
- window = sg.Window("Windows-like program",
- layout,
- default_element_size=(12, 1),
- auto_size_text=False,
- auto_size_buttons=False,
- default_button_element_size=(12, 1))
-
- # ------ Loop & Process button menu choices ------ #
- while True:
- event, values = window.read()
- if event is None or event == 'Exit':
- return
- print('Event = ', event)
- # ------ Process menu choices ------ #
- if event == 'About...':
- window.disappear()
- sg.popup('About this program','Version 1.0', 'PySimpleGUI rocks...', grab_anywhere=True)
- window.reappear()
- elif event == 'Open':
- filename = sg.popup_get_file('file to open', no_window=True)
- print(filename)
- elif event == 'Properties':
- second_window()
-
-test_menus()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Multiple_Windows_Experimental.py b/DemoPrograms old/Demo_Multiple_Windows_Experimental.py
deleted file mode 100644
index a5902d60..00000000
--- a/DemoPrograms old/Demo_Multiple_Windows_Experimental.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout1 = [[ sg.Text('Window 1') ],
- [sg.Input(do_not_clear=True)],
- [ sg.Button('Read')]]
-
-window1 = sg.Window('My new window', location=(800,500)).Layout(layout1)
-
-
-layout2 = [[ sg.Text('Window 2') ],
- [sg.Input(do_not_clear=True)],
- [ sg.Button('Read')]]
-
-window2 = sg.Window('My new window', location=(800, 625), return_keyboard_events=True).Layout(layout2)
-
-
-layout3 = [[ sg.Text('Window 3') ],
- [sg.Input(do_not_clear=False)],
- [ sg.Button('Read')]]
-
-window3 = sg.Window('My new window', location=(800,750), return_keyboard_events=True).Layout(layout3)
-
-
-while True: # Event Loop
- event, values = window1.Read(timeout=50)
- if event is None:
- break
- elif event != '__timeout__':
- print(event, values)
-
- event, values = window2.Read(timeout=0)
- if event is None:
- break
- elif event != '__timeout__':
- print(event, values)
-
- event, values = window3.Read(timeout=0)
- if event is None:
- break
- elif event != '__timeout__':
- print(event, values)
diff --git a/DemoPrograms old/Demo_Multithreaded_Logging.py b/DemoPrograms old/Demo_Multithreaded_Logging.py
deleted file mode 100644
index b5f0deb6..00000000
--- a/DemoPrograms old/Demo_Multithreaded_Logging.py
+++ /dev/null
@@ -1,98 +0,0 @@
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUIQt as sg
-else:
- import PySimpleGUI27 as sg
-
-import queue
-import logging
-import threading
-import time
-
-"""
- This code originated in this project:
- https://github.com/john144/MultiThreading
- Thanks to John for writing this in the early days of PySimpleGUI
- Demo program showing one way that a threaded application can function with PySimpleGUI
- Events are sent from the ThreadedApp thread to the main thread, the GUI, by using a queue
-"""
-
-logger = logging.getLogger('mymain')
-
-
-def externalFunction():
- logger.info('Hello from external app')
- logger.info('External app sleeping 5 seconds')
- time.sleep(5)
- logger.info('External app waking up and exiting')
-
-
-class ThreadedApp(threading.Thread):
- def __init__(self):
- super().__init__()
- self._stop_event = threading.Event()
-
- def run(self):
- externalFunction()
-
- def stop(self):
- self._stop_event.set()
-
-
-class QueueHandler(logging.Handler):
- def __init__(self, log_queue):
- super().__init__()
- self.log_queue = log_queue
-
- def emit(self, record):
- self.log_queue.put(record)
-
-
-def main():
- window = sg.FlexForm('Log window', default_element_size=(30, 2), font=('Helvetica', ' 10'), default_button_element_size=(8, 2), return_keyboard_events=True)
-
- layout = \
- [
- [sg.Multiline(size=(50, 15), key='Log')],
- [sg.Button('Start', bind_return_key=True, key='_START_'), sg.Button('Exit')]
- ]
-
- window.Layout(layout).Read(timeout=0)
- appStarted = False
-
- # Setup logging and start app
- logging.basicConfig(level=logging.DEBUG)
- log_queue = queue.Queue()
- queue_handler = QueueHandler(log_queue)
- logger.addHandler(queue_handler)
- threadedApp = ThreadedApp()
-
- # Loop taking in user input and querying queue
- while True:
- # Wake every 100ms and look for work
- event, values = window.Read(timeout=100)
-
- if event == '_START_':
- if appStarted is False:
- threadedApp.start()
- logger.debug('App started')
- window.FindElement('_START_').Update(disabled=True)
- appStarted = True
- elif event in (None, 'Exit'):
- break
-
- # Poll queue
- try:
- record = log_queue.get(block=False)
- except queue.Empty:
- pass
- else:
- msg = queue_handler.format(record)
- window.FindElement('Log').Update(msg+'\n', append=True)
-
- window.Close()
- exit()
-
-
-if __name__ == '__main__':
- main()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Multithreaded_Long_Tasks.py b/DemoPrograms old/Demo_Multithreaded_Long_Tasks.py
deleted file mode 100644
index f74bee00..00000000
--- a/DemoPrograms old/Demo_Multithreaded_Long_Tasks.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/python3
-
-import queue
-import threading
-import time
-
-# This program has been tested on all flavors of PySimpleGUI and it works with no problems at all
-# To try something other than tkinter version, just comment out the first import and uncomment the one you want
-import PySimpleGUI as sg
-# import PySimpleGUIQt as sg
-# import PySimpleGUIWx as sg
-# import PySimpleGUIWeb as sg
-
-"""
- DESIGN PATTERN - Multithreaded Long Tasks GUI
- Presents one method for running long-running operations in a PySimpleGUI environment.
- The PySimpleGUI code, and thus the underlying GUI framework, runs as the primary, main thread
- The "long work" is contained in the thread that is being started.
-
- A queue.Queue is used by the threads to communicate with main GUI code
- The PySimpleGUI code is structured just like a typical PySimpleGUI program. A layout defined,
- a Window is created, and an event loop is executed.
- What's different is that within this otherwise normal PySimpleGUI Event Loop, there is a check for items
- in the Queue. If there are items found, process them by making GUI changes, and continue.
-
- This design pattern works for all of the flavors of PySimpleGUI including the Web and also repl.it
- You'll find a repl.it version here: https://repl.it/@PySimpleGUI/Async-With-Queue-Communicationspy
-"""
-
-
-def long_operation_thread(seconds, gui_queue):
- """
- A worker thread that communicates with the GUI through a queue
- This thread can block for as long as it wants and the GUI will not be affected
- :param seconds: (int) How long to sleep, the ultimate blocking call
- :param gui_queue: (queue.Queue) Queue to communicate back to GUI that task is completed
- :return:
- """
- print('Starting thread - will sleep for {} seconds'.format(seconds))
- time.sleep(seconds) # sleep for a while
- gui_queue.put('** Done **') # put a message into queue for GUI
-
-
-###### ## ## ####
-## ## ## ## ##
-## ## ## ##
-## #### ## ## ##
-## ## ## ## ##
-## ## ## ## ##
-###### ####### ####
-
-def the_gui():
- """
- Starts and executes the GUI
- Reads data from a Queue and displays the data to the window
- Returns when the user exits / closes the window
- """
-
- gui_queue = queue.Queue() # queue used to communicate between the gui and the threads
-
- layout = [[sg.Text('Long task to perform example')],
- [sg.Output(size=(70, 12))],
- [sg.Text('Number of seconds your task will take'),sg.Input(key='_SECONDS_', size=(5,1)), sg.Button('Do Long Task', bind_return_key=True)],
- [sg.Button('Click Me'), sg.Button('Exit')], ]
-
- window = sg.Window('Multithreaded Window').Layout(layout)
-
- # --------------------- EVENT LOOP ---------------------
- while True:
- event, values = window.Read(timeout=100) # wait for up to 100 ms for a GUI event
- if event is None or event == 'Exit':
- break
- elif event.startswith('Do'):
- try:
- seconds = int(values['_SECONDS_'])
- print('Starting thread to do long work....sending value of {} seconds'.format(seconds))
- threading.Thread(target=long_operation_thread, args=(seconds , gui_queue,), daemon=True).start()
- except Exception as e:
- print('Error starting work thread. Did you input a valid # of seconds? You entered: %s' % values['_SECONDS_'])
- elif event == 'Click Me':
- print('Your GUI is alive and well')
- # --------------- Check for incoming messages from threads ---------------
- try:
- message = gui_queue.get_nowait()
- except queue.Empty: # get_nowait() will get exception when Queue is empty
- message = None # break from the loop if no more messages are queued up
-
- # if message received from queue, display the message in the Window
- if message:
- print('Got a message back from the thread: ', message)
-
- # if user exits the window, then close the window and exit the GUI func
- window.Close()
-
-
-## ## ### #### ## ##
-### ### ## ## ## ### ##
-#### #### ## ## ## #### ##
-## ### ## ## ## ## ## ## ##
-## ## ######### ## ## ####
-## ## ## ## ## ## ###
-## ## ## ## #### ## ##
-
-if __name__ == '__main__':
- the_gui()
- print('Exiting Program')
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Multithreaded_Queued.py b/DemoPrograms old/Demo_Multithreaded_Queued.py
deleted file mode 100644
index 5e397925..00000000
--- a/DemoPrograms old/Demo_Multithreaded_Queued.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/python3
-
-# Rather than importing individual classes such as threading.Thread or queue.Queue, this
-# program is doing a simple import and then indicating the package name when the functions
-# are called. This seemed like a great way for the reader of the code to get an understanding
-# as to exactly which package is being used. It's purely for educational and explicitness purposes
-import queue
-import threading
-import time
-import itertools
-
-# This program has been tested on all flavors of PySimpleGUI and it works with no problems at all
-# To try something other than tkinter version, just comment out the first import and uncomment the one you want
-import PySimpleGUI as sg
-# import PySimpleGUIQt as sg
-# import PySimpleGUIWx as sg
-# import PySimpleGUIWeb as sg
-
-"""
- DESIGN PATTERN - Multithreaded GUI
- One method for running multiple threads in a PySimpleGUI environment.
- The PySimpleGUI code, and thus the underlying GUI framework, runs as the primary, main thread
- Other parts of the software are implemented as threads
-
- A queue.Queue is used by the worker threads to communicate with code that calls PySimpleGUI directly.
- The PySimpleGUI code is structured just like a typical PySimpleGUI program. A layout defined,
- a Window is created, and an event loop is executed.
- What's different is that within this otherwise normal PySimpleGUI Event Loop, there is a check for items
- in the Queue. If there are items found, process them by making GUI changes, and continue.
-
- This design pattern works for all of the flavors of PySimpleGUI including the Web and also repl.it
- You'll find a repl.it version here: https://repl.it/@PySimpleGUI/Async-With-Queue-Communicationspy
-"""
-
-
-######## ## ## ######## ######## ### ########
- ## ## ## ## ## ## ## ## ## ##
- ## ## ## ## ## ## ## ## ## ##
- ## ######### ######## ###### ## ## ## ##
- ## ## ## ## ## ## ######### ## ##
- ## ## ## ## ## ## ## ## ## ##
- ## ## ## ## ## ######## ## ## ########
-
-def worker_thread(thread_name, run_freq, gui_queue):
- """
- A worker thrread that communicates with the GUI
- These threads can call functions that block withouth affecting the GUI (a good thing)
- Note that this function is the code started as each thread. All threads are identical in this way
- :param thread_name: Text name used for displaying info
- :param run_freq: How often the thread should run in milliseconds
- :param gui_queue: Queue used to communicate with the GUI
- :return:
- """
- print('Starting thread - {} that runs every {} ms'.format(thread_name, run_freq))
- for i in itertools.count(): # loop forever, keeping count in i as it loops
- time.sleep(run_freq/1000) # sleep for a while
- gui_queue.put('{} - {}'.format(thread_name, i)) # put a message into queue for GUI
-
- ###### ## ## ####
-## ## ## ## ##
-## ## ## ##
-## #### ## ## ##
-## ## ## ## ##
-## ## ## ## ##
- ###### ####### ####
-
-def the_gui(gui_queue):
- """
- Starts and executes the GUI
- Reads data from a Queue and displays the data to the window
- Returns when the user exits / closes the window
- (that means it does NOT return until the user exits the window)
- :param gui_queue: Queue the GUI should read from
- :return:
- """
- layout = [ [sg.Text('Multithreaded Window Example')],
- [sg.Text('', size=(15,1), key='_OUTPUT_')],
- [sg.Output(size=(40,6))],
- [sg.Button('Exit')],]
-
- window = sg.Window('Multithreaded Window').Layout(layout)
- # --------------------- EVENT LOOP ---------------------
- while True:
- event, values = window.Read(timeout=100) # wait for up to 100 ms for a GUI event
- if event is None or event == 'Exit':
- break
- #--------------- Loop through all messages coming in from threads ---------------
- while True: # loop executes until runs out of messages in Queue
- try: # see if something has been posted to Queue
- message = gui_queue.get_nowait()
- except queue.Empty: # get_nowait() will get exception when Queue is empty
- break # break from the loop if no more messages are queued up
- # if message received from queue, display the message in the Window
- if message:
- window.Element('_OUTPUT_').Update(message)
- window.Refresh() # do a refresh because could be showing multiple messages before next Read
- print(message)
- # if user exits the window, then close the window and exit the GUI func
- window.Close()
-
-
-## ## ### #### ## ##
-### ### ## ## ## ### ##
-#### #### ## ## ## #### ##
-## ### ## ## ## ## ## ## ##
-## ## ######### ## ## ####
-## ## ## ## ## ## ###
-## ## ## ## #### ## ##
-
-if __name__ == '__main__':
- #-- Create a Queue to communicate with GUI --
- gui_queue = queue.Queue() # queue used to communicate between the gui and the threads
- #-- Start worker threads, one runs twice as often as the other
- threading.Thread(target=worker_thread, args=('Thread 1', 500, gui_queue,), daemon=True).start()
- threading.Thread(target=worker_thread, args=('Thread 2', 200, gui_queue,), daemon=True).start()
- threading.Thread(target=worker_thread, args=('Thread 3', 1000, gui_queue,), daemon=True).start()
- #-- Start the GUI passing in the Queue --
- the_gui(gui_queue)
- print('Exiting Program')
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Nice_Buttons.py b/DemoPrograms old/Demo_Nice_Buttons.py
deleted file mode 100644
index 2640cd48..00000000
--- a/DemoPrograms old/Demo_Nice_Buttons.py
+++ /dev/null
@@ -1,74 +0,0 @@
-import PySimpleGUI as sg
-import os
-import io
-from PIL import Image, ImageDraw, ImageTk, ImageFont
-import base64
-import subprocess
-import sys
-
-
-def image_file_to_bytes(image64, size):
- image_file = io.BytesIO(base64.b64decode(image64))
- img = Image.open(image_file)
- img.thumbnail(size, Image.ANTIALIAS)
- bio = io.BytesIO()
- img.save(bio, format='PNG')
- imgbytes = bio.getvalue()
- return imgbytes
-
-
-
-def ShowMeTheButtons():
- bcolor = ('black', 'black')
- wcolor = ('white', 'black')
-
- sg.ChangeLookAndFeel('Black')
- sg.SetOptions(auto_size_buttons=True, border_width=0, button_color=sg.COLOR_SYSTEM_DEFAULT)
-
- toolbar_buttons = [ [sg.Text('Who says Windows have to be ugly when using tkinter?', size=(45,3))],
- [sg.Text('All of these buttons are part of the code itself', size=(45,2))],
-
- [sg.RButton('Next', image_data=image_file_to_bytes(button64, (100,50)),button_color=wcolor, font='Any 15', pad=(0,0), key='_close_'),
- # [sg.RButton('Exit', image_data=image_file_to_bytes(black64, (100,50)),button_color=bcolor, font='Any 15', pad=(0,0), key='_close_'),],
- sg.RButton('Submit', image_data=image_file_to_bytes(red_pill64, (100,50)),button_color=wcolor, font='Any 15', pad=(0,0), key='_close_'),
- sg.RButton('OK', image_data=image_file_to_bytes(green_pill64, (100,50)),button_color=bcolor, font='Any 15', pad=(0,0), key='_close_'),
- sg.RButton('Exit', image_data=image_file_to_bytes(orange64, (100,50)),button_color=bcolor, font='Any 15', pad=(0,0), key='_close_'),],
- ]
-
- # layout = toolbar_buttons
- layout = [[sg.Frame('Nice Buttons', toolbar_buttons, font=('any 18'), background_color='black')]]
-
- window = sg.Window('Demo of Nice Looking Buttons',
- no_titlebar=False,
- grab_anywhere=True,
- keep_on_top=True,
- use_default_focus=False,
- font='any 15',
- background_color='black').Layout(layout).Finalize()
-
- # ---===--- Loop taking in user input --- #
- while True:
- button, value = window.Read()
- print(button)
- if button == '_close_' or button is None:
- break # exit button clicked
-
-if __name__ == '__main__':
-
- # To convert your PNG into Base 64:
- # Go to https://www.base64-image.de/
- # Drag and drop your PNG image onto the webpage
- # Choose "Copy image"
- # Create a string variable name to hold your image
- # Paste data from webpage as a string
- # Delete the "header" stuff - up to the data portion (data:image/png;base64,)
- orange64 = 'iVBORw0KGgoAAAANSUhEUgAAAiIAAADLCAMAAABkvgh7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAANtvJ99sId5tIt5uI91tJNxuJNxuJttvKN90NN91Ntt3PN52ONx3Otx3PNt4Pdp4Ptx4PepfD+pfEOtgD+piD+tkD+ttD+dnFOdoE+doFOVoFuNqG+JrHOFrHuFsHuRpGORpGuRqGORqGupgEOpiEOpkEOlmEOhnEupoEOpoEupqFettEetsF+tuFOxqFetrGOtsGetvHOxrGOxsGOxtGuxuG+xuHexxFutwH+xxGOxyGOxyGuxxHuBsIOJvJ+NvKORvKONwKeNwKuJxLONyLeJyLuRwKeRwKuRxLOtxIexyIexzJOx0JOx1Ju11KOx2KOx2Kux5Iux4Kux5Le1/LeFyMOFzMuB0NOB1Nux7MOx8MOx8Mu19NO1+NO1+Ntd7RdV8RtN+S9J/TdF/TtV9SNR9Stl5QNl6Qdh6Qth7RK+Tfa+Tfq6Ufr+JZb+JZr+KZ7uMbr6KaL6LaryMbLyNb7yOb7WPdLuNcLqOcLmOcrmPdLOQd7SQdrKReLKRerGSerCTfLCTfrmQde2AN+2AOO2BOu2COu6DPO6EPe6EPsWDV8OFXcOFXsOGXcOGXsaDWMSEWsqCVs+AUM2AUs6CU82CVMqDWMmEWtCAT9CAUMKHYMCIYsCIZMCKZu6FQO6GQe6GQu6HRO6IRe6JRu6KR+6KSO+LSu+MS++MTO+OTe+OTu+OUO+RUu+TVfCNTvCOTvCPUPCQUfCQUvCSU/CRVPCSVPCSVvCUV/CUWPCVWvGWWvGXXPGYXvCWYPGaYfGcYvGcZPKdZvKeZ/GdavKeaPKebfKebvKgavKhbPKibfGibvKjcPGkcfKmdPKiePOod/OpePSpePSqevSrfPSsfPSsfvSqg/SugfWwgvWwhPWyhfWyhvWxi/Wyj/W0ifW2jfa4j/a1kPW2kva2lfW2lvW4kPa6kfa7kva5lvW7lPa8lPW8lve+l/a4mva5nPa6nPa7nva+mPa+mva/nPa8oPa9ovbAm/bAnfXAnvbCofbEo/XGp/bGqPbIqQAAAC/NnaUAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjFjKpxLAAAJXElEQVR4Xu3de3zVdR3H8Xb9/sJh60LlOTtubdIZEyckSdedMzkdZyRGIePmZdqki8s0KllJmtGCTAXRlUAyrireUeZga2JRkooYRWR0JbXMLsIqZ5fT7/L5nRvj9/md0/fhw/Px/fyHP+D33fb4vPj+LvsxXpMA8IREgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgIFEgJF7Ih1Xf3bVsuu/AYXu+mUrL+u8iqbqIcdErvhme0V8SjQCIpwWe+0nli+k2R5NTolc0jYzqpQBcigV+UDltZ57SQ6JfLqyRRXRyiCIis7u7qAhj8B3Ip1tLdg/pFLR0Z+hOR/JbyIrWxGIZCp289E2Ep+J3HzEFqLKy0qhUJUfeUkZnf8lGnYWX4l0tDfTOg5VEqoJNNTXh6EgmaMLBKuaymmcJFLRSfPO5CuRtgitYisPBehDQUFrqC3O2EtUxRdo4Bn8JHJhlNawlNZh85Aj2JQeiRp9JY08nY9Euk+nFUwq1ECLgww1ZTRaS+R8mnk6PpEF8dTDkNIgLQxiHFdNw7U0d9PU07CJdLw+tRUVpy5Cxo19+bz9lYI+n5cNfdhcjWGZf2jsCTTJcDiUmnBR/HKaewqbSHfqQqSJrkLGvuuctZu3jOgBD1u99B7Fg6a+Vwrrk8kNfRX+0XE2+qg527adsc38M723d01yK3lbqhH1SZp7CpfIolnJw4udQk44ddPOn/3q6b+M6K8+/c2vF+jXVw29X/ALI7N+Z3jome+f/QZ7pOG6VCMtl9Dkk7hElifvd0uPs1cb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'
-
- green_pill64 = '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'
-
- red_pill64 = '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'
-
- button64 = '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'
-
- ShowMeTheButtons()
-
diff --git a/DemoPrograms old/Demo_NonBlocking_Form.py b/DemoPrograms old/Demo_NonBlocking_Form.py
deleted file mode 100644
index f3561f7c..00000000
--- a/DemoPrograms old/Demo_NonBlocking_Form.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import time
-
-# Window that doen't block
-# good for applications with an loop that polls hardware
-def StatusOutputExample():
- # Create a text element that will be updated with status information on the GUI itself
- # Create the rows
- layout = [[sg.Text('Non-blocking GUI with updates')],
- [sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='output')],
- [sg.Button('LED On'), sg.Button('LED Off'), sg.Button('Quit')]]
- # Layout the rows of the Window and perform a read. Indicate the Window is non-blocking!
- window = sg.Window('Running Timer', auto_size_text=True).Layout(layout)
-
- #
- # Some place later in your code...
- # You need to perform a Read on your window every now and then or
- # else it won't refresh.
- #
- # your program's main loop
- i=0
- while (True):
- # This is the code that reads and updates your window
- event, values = window.Read(timeout=10)
- window.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
- if event in ('Quit', None):
- break
- if event == 'LED On':
- print('Turning on the LED')
- elif event == 'LED Off':
- print('Turning off the LED')
-
- i += 1
- # Your code begins here
-
- # Broke out of main loop. Close the window.
- window.Close()
-
-
-def RemoteControlExample():
-
- layout = [[sg.Text('Robotics Remote Control')],
- [sg.T(' '*10), sg.RealtimeButton('Forward')],
- [ sg.RealtimeButton('Left'), sg.T(' '*15), sg.RealtimeButton('Right')],
- [sg.T(' '*10), sg.RealtimeButton('Reverse')],
- [sg.T('')],
- [sg.Quit(button_color=('black', 'orange'))]
- ]
-
- window = sg.Window('Robotics Remote Control', auto_size_text=True).Layout(layout).Finalize()
-
- #
- # Some place later in your code...
- # You need to perform a ReadNonBlocking on your window every now and then or
- # else it won't refresh.
- #
- # your program's main loop
- while (True):
- # This is the code that reads and updates your window
- event, values = window.Read(timeout=0, timeout_key='timeout')
- if event != 'timeout':
- print(event)
- if event in ('Quit', None):
- break
-
- window.Close()
-
-
-def main():
- RemoteControlExample()
- StatusOutputExample()
- sg.Popup('End of non-blocking demonstration')
-
-
-if __name__ == '__main__':
-
- main()
diff --git a/DemoPrograms old/Demo_Notification_Window_Alpha_Channel.py b/DemoPrograms old/Demo_Notification_Window_Alpha_Channel.py
deleted file mode 100644
index ea645eae..00000000
--- a/DemoPrograms old/Demo_Notification_Window_Alpha_Channel.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-import sys
-import time
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-# Demonstrates a notification window that's partially transparent
-# The window slowly fades-in
-# Includes a small red-X button to close the window
-# Base 64 encoded button is in-lined to avoid reading a file
-# Free online encoder - https://www.base64-image.de/
-red_x ="R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
-
-
-sg.ChangeLookAndFeel('Topanga')
-sg.SetOptions(border_width=0, margins=(0,0))
-bcolor=('black', '#282923')
-
-sg.SetOptions(border_width=0, margins=(0,0))
-
-layout = [[sg.T('Notification'+' '*14),
- sg.CloseButton('', image_data=red_x, button_color=('#282923', '#282923'))],
- [sg.T('')],
- [sg.T('You have 6 new emails')],]
-
-window = sg.Window('',
- no_titlebar=True,
- grab_anywhere=True,
- keep_on_top=True,
- alpha_channel=0
- ).Layout(layout).Finalize()
-
-# Classy fade-in
-for i in range(1, 75, 2):
- window.AlphaChannel = float(i)/100
- time.sleep(.01)
-
-event, values = window.Read()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_OpenCV.py b/DemoPrograms old/Demo_OpenCV.py
deleted file mode 100644
index 194980af..00000000
--- a/DemoPrograms old/Demo_OpenCV.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import cv2 as cv
-from PIL import Image
-import io
-from sys import exit as exit
-
-"""
-Demo program to open and play a file using OpenCV
-It's main purpose is to show you:
-1. How to get a frame at a time from a video file using OpenCV
-2. How to display an image in a PySimpleGUI Window
-
-For added fun, you can reposition the video using the slider.
-"""
-
-def main():
- # ---===--- Get the filename --- #
- filename = sg.PopupGetFile('Filename to play')
- if filename is None:
- exit(69)
- vidFile = cv.VideoCapture(filename)
- # ---===--- Get some Stats --- #
- num_frames = vidFile.get(cv.CAP_PROP_FRAME_COUNT)
- fps = vidFile.get(cv.CAP_PROP_FPS)
-
- sg.ChangeLookAndFeel('Black')
-
- # ---===--- define the window layout --- #
- layout = [[sg.Text('OpenCV Demo', size=(15, 1), font='Helvetica 20')],
- [sg.Image(filename='', key='_image_')],
- [sg.Slider(range=(0, num_frames), size=(60, 10), orientation='h', key='_slider_')],
- [sg.Button('Exit', size=(7, 1), pad=((600, 0), 3), font='Helvetica 14')]]
-
- # create the window and show it without the plot
- window = sg.Window('Demo Application - OpenCV Integration', no_titlebar=False, location=(0,0)).Layout(layout)
-
- image_elem = window.Element('_image_') # locate the elements we'll be updating. Does the search only 1 time
- slider_elem = window.Element('_slider_')
-
- # ---===--- LOOP through video file by frame --- #
- cur_frame = 0
- while vidFile.isOpened():
- event, values = window.Read(timeout=0)
- if event in ('Exit', None):
- exit(69)
- ret, frame = vidFile.read()
- if not ret: # if out of data stop looping
- break
- if int(values['_slider_']) != cur_frame-1: # if someone moved the slider manually, the jump to that frame
- cur_frame = int(values['_slider_'])
- vidFile.set(cv.CAP_PROP_POS_FRAMES, cur_frame)
- slider_elem.Update(cur_frame)
- cur_frame += 1
-
- imgbytes = cv.imencode('.png', frame)[1].tobytes() # ditto
- image_elem.Update(data=imgbytes)
-
-"""
- # This was another way updates were being done, but seems slower than the above
- img = Image.fromarray(frame) # create PIL image from frame
- bio = io.BytesIO() # a binary memory resident stream
- img.save(bio, format= 'PNG') # save image as png to it
- imgbytes = bio.getvalue() # this can be used by OpenCV hopefully
- image_elem.Update(data=imgbytes)
-"""
-
-main()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_OpenCV_4_Line_Program.py b/DemoPrograms old/Demo_OpenCV_4_Line_Program.py
deleted file mode 100644
index 6e032cf3..00000000
--- a/DemoPrograms old/Demo_OpenCV_4_Line_Program.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import cv2, PySimpleGUI as sg
-window, cap = sg.Window('Demo Application - OpenCV Integration', [[sg.Image(filename='', key='image')],], location=(800,400)), cv2.VideoCapture(0)
-while window(timeout=20)[0] is not None:
- window['image'](data=cv2.imencode('.png', cap.read()[1])[1].tobytes())
diff --git a/DemoPrograms old/Demo_OpenCV_7_Line_Program.py b/DemoPrograms old/Demo_OpenCV_7_Line_Program.py
deleted file mode 100644
index b1cc0ff7..00000000
--- a/DemoPrograms old/Demo_OpenCV_7_Line_Program.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import cv2, PySimpleGUI as sg
-window = sg.Window('Demo Application - OpenCV Integration', [[sg.Image(filename='', key='image')],], location=(800,400))
-cap = cv2.VideoCapture(0) # Setup the camera as a capture device
-while True: # The PSG "Event Loop"
- event, values = window.Read(timeout=20, timeout_key='timeout') # get events for the window with 20ms max wait
- if event is None: break # if user closed window, quit
- window.FindElement('image').Update(data=cv2.imencode('.png', cap.read()[1])[1].tobytes()) # Update image in window
-
-"""
-Putting the comment at the bottom so that you can see that the code is indeed 7 lines long. And, there is nothing
-done out of the ordinary to make it 7 lines long. There are no ; for example. OK, so the if statement is on one line
-but that's the only place that you would traditionally see one more line. So, call it 8 if you want.
-"""
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_OpenCV_Draw_On_Webcam_Image.py b/DemoPrograms old/Demo_OpenCV_Draw_On_Webcam_Image.py
deleted file mode 100644
index 46a1cdb4..00000000
--- a/DemoPrograms old/Demo_OpenCV_Draw_On_Webcam_Image.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import PySimpleGUI as sg
-import cv2
-
-"""
- Demonstration of how to use a GRAPH ELEMENT to draw a webcam stream using OpenCV and PySimpleGUI.
- Additionally, the thing this demo is really showcasing, is the ability to draw over the top of this
- webcam stream, as it's being displayed. To "Draw" simply move your mouse over the image, left click and hold, and
- then drag your mouse. You'll see a series of red circles on top of your image.
- CURRENTLY ONLY WORKS WITH PySimpleGUI, NOT any of the other ports at this time.
-"""
-
-def main():
- layout = [[sg.Graph((600,450),(0,450), (600,0), key='_GRAPH_', enable_events=True, drag_submits=True)],]
-
- window = sg.Window('Demo Application - OpenCV Integration', layout)
-
- graph_elem = window.Element('_GRAPH_') # type: sg.Graph
-
- id = None
- # ---===--- Event LOOP Read and display frames, operate the GUI --- #
- cap = cv2.VideoCapture(0)
- while True:
- event, values = window.Read(timeout=0)
- if event in ('Exit', None):
- break
-
- ret, frame = cap.read()
- imgbytes=cv2.imencode('.png', frame)[1].tobytes()
- if id:
- graph_elem.DeleteFigure(id) # delete previous image
- id = graph_elem.DrawImage(data=imgbytes, location=(0,0)) # draw new image
- graph_elem.TKCanvas.tag_lower(id) # move image to the "bottom" of all other drawings
-
- if event == '_GRAPH_':
- graph_elem.DrawCircle(values['_GRAPH_'], 5, fill_color='red', line_color='red')
- window.Close()
-
-main()
diff --git a/DemoPrograms old/Demo_OpenCV_Simple_GUI.py b/DemoPrograms old/Demo_OpenCV_Simple_GUI.py
deleted file mode 100644
index 7399dc96..00000000
--- a/DemoPrograms old/Demo_OpenCV_Simple_GUI.py
+++ /dev/null
@@ -1,88 +0,0 @@
-import sys
-
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import cv2
-import numpy as np
-from sys import exit as exit
-
-"""
-Demo program that displays a webcam using OpenCV and applies some very basic image functions
-
-- functions from top to bottom -
-none: no processing
-threshold: simple b/w-threshold on the luma channel, slider sets the threshold value
-canny: edge finding with canny, sliders set the two threshold values for the function => edge sensitivity
-contour: colour finding in the frame, first slider sets the hue for the colour to find, second the minimum saturation
- for the object. Found objects are drawn with a red contour.
-blur: simple Gaussian blur, slider sets the sigma, i.e. the amount of blur smear
-hue: moves the image hue values by the amount selected on the slider
-enhance: applies local contrast enhancement on the luma channel to make the image fancier - slider controls fanciness.
-"""
-
-
-def main():
- sg.ChangeLookAndFeel('LightGreen')
-
- # define the window layout
- layout = [[sg.Text('OpenCV Demo', size=(40, 1), justification='center')],
- [sg.Image(filename='', key='image')],
- [sg.Radio('None', 'Radio', True, size=(10, 1))],
- [sg.Radio('threshold', 'Radio', size=(10, 1), key='thresh'),
- sg.Slider((0, 255), 128, 1, orientation='h', size=(40, 15), key='thresh_slider')],
- [sg.Radio('canny', 'Radio', size=(10, 1), key='canny'),
- sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='canny_slider_a'),
- sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='canny_slider_b')],
- [sg.Radio('contour', 'Radio', size=(10, 1), key='contour'),
- sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='contour_slider'),
- sg.Slider((0, 255), 80, 1, orientation='h', size=(20, 15), key='base_slider')],
- [sg.Radio('blur', 'Radio', size=(10, 1), key='blur'),
- sg.Slider((1, 11), 1, 1, orientation='h', size=(40, 15), key='blur_slider')],
- [sg.Radio('hue', 'Radio', size=(10, 1), key='hue'),
- sg.Slider((0, 225), 0, 1, orientation='h', size=(40, 15), key='hue_slider')],
- [sg.Radio('enhance', 'Radio', size=(10, 1), key='enhance'),
- sg.Slider((1, 255), 128, 1, orientation='h', size=(40, 15), key='enhance_slider')],
- [sg.Button('Exit', size=(10, 1))]]
-
- # create the window and show it without the plot
- window = sg.Window('Demo Application - OpenCV Integration',
- location=(800, 400))
- window.Layout(layout).Finalize()
-
- cap = cv2.VideoCapture(0)
- while True:
- event, values = window.Read(timeout=0, timeout_key='timeout')
- if event == 'Exit' or event is None:
- sys.exit(0)
- ret, frame = cap.read()
- if values['thresh']:
- frame = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)[:, :, 0]
- _, frame = cv2.threshold(frame, values['thresh_slider'], 255, cv2.THRESH_BINARY)
- if values['canny']:
- frame = cv2.Canny(frame, values['canny_slider_a'], values['canny_slider_b'])
- if values['blur']:
- frame = cv2.GaussianBlur(frame, (21, 21), values['blur_slider'])
- if values['hue']:
- frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
- frame[:, :, 0] += values['hue_slider']
- frame = cv2.cvtColor(frame, cv2.COLOR_HSV2BGR)
- if values['enhance']:
- enh_val = values['enhance_slider'] / 40
- clahe = cv2.createCLAHE(clipLimit=enh_val, tileGridSize=(8, 8))
- lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)
- lab[:, :, 0] = clahe.apply(lab[:, :, 0])
- frame = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
- if values['contour']:
- hue = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
- hue = cv2.GaussianBlur(hue, (21, 21), 1)
- hue = cv2.inRange(hue, np.array([values['contour_slider'], values['base_slider'], 40]),
- np.array([values['contour_slider'] + 30, 255, 220]))
- _, cnts, _ = cv2.findContours(hue, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
- cv2.drawContours(frame, cnts, -1, (0, 0, 255), 2)
- imgbytes = cv2.imencode('.png', frame)[1].tobytes() # ditto
- window.FindElement('image').Update(data=imgbytes)
-
-
-main()
diff --git a/DemoPrograms old/Demo_OpenCV_Webcam.py b/DemoPrograms old/Demo_OpenCV_Webcam.py
deleted file mode 100644
index 287f485a..00000000
--- a/DemoPrograms old/Demo_OpenCV_Webcam.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-import PySimpleGUI as sg
-# import PySimpleGUIQt as sg
-import cv2
-import numpy as np
-import sys
-from sys import exit as exit
-
-"""
-Demo program that displays a webcam using OpenCV
-"""
-def main():
-
- sg.ChangeLookAndFeel('Black')
-
- # define the window layout
- layout = [[sg.Text('OpenCV Demo', size=(40, 1), justification='center', font='Helvetica 20')],
- [sg.Image(filename='', key='image')],
- [sg.Button('Record', size=(10, 1), font='Helvetica 14'),
- sg.Button('Stop', size=(10, 1), font='Any 14'),
- sg.Button('Exit', size=(10, 1), font='Helvetica 14'),]]
-
- # create the window and show it without the plot
- window = sg.Window('Demo Application - OpenCV Integration', layout,
- location=(800,400))
-
- # ---===--- Event LOOP Read and display frames, operate the GUI --- #
- cap = cv2.VideoCapture(0)
- recording = False
- while True:
- event, values = window.Read(timeout=20)
- if event == 'Exit' or event is None:
- sys.exit(0)
- elif event == 'Record':
- recording = True
- elif event == 'Stop':
- recording = False
- img = np.full((480, 640),255)
- imgbytes=cv2.imencode('.png', img)[1].tobytes() #this is faster, shorter and needs less includes
- window.FindElement('image').Update(data=imgbytes)
-
- if recording:
- ret, frame = cap.read()
- imgbytes=cv2.imencode('.png', frame)[1].tobytes() #ditto
- window.FindElement('image').Update(data=imgbytes)
-
-main()
-exit()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_OpenCV_Webcam_ASCII.py b/DemoPrograms old/Demo_OpenCV_Webcam_ASCII.py
deleted file mode 100644
index 61232d00..00000000
--- a/DemoPrograms old/Demo_OpenCV_Webcam_ASCII.py
+++ /dev/null
@@ -1,67 +0,0 @@
-from PIL import Image
-import numpy as np
-import PySimpleGUI as sg; font_size=6; USING_QT=False
-# import PySimpleGUIQt as sg; font_size=8; USING_QT=True # if using, be sure and use the second layout that is commented out
-# import PySimpleGUIWeb as sg; font_size=12; USING_QT=False # yes, it runs in a webpage too! Not as good as tkinter but works
-import cv2
-
-"""
- Interesting program that shows your webcam's image as ASCII text. Runs in realtime, producing a stream of
- images so that it is actually animated ASCII text. Wild stuff that came about from a post on Reddit of all
- places. The software bits that turn the image into ASCII text were shamelessly taken from this gist:
- https://gist.github.com/cdiener/10491632
- Brilliant work to have pulled off so much with so little Numpy
- What's remarkable about this program is that the animation is created by updating individual Text Elements going
- down the window, one line at a time, every time through the loop. That's 48 lines of text every time. Rough
- timing shows an animation of more than 10 fps when running any of the PySimpleGUI ports.
- Also added onto this are a spinner and a slider. They do essentially the same thing, enable a pair of parameters
- to be modified on the fly.
-
- You need PySimpleGUI installed as well as OpenCV. Both are easily installed via pip:
- pip install PySimpleGUI
- pip install opencv-python
-
- On Linux / Mac use pip3 instead of pip
-"""
-
-# The magic bits that make the ASCII stuff work shamelessly taken from https://gist.github.com/cdiener/10491632
-chars = np.asarray(list(' .,:;irsXA253hMHGS#9B&@'))
-SC, GCF, WCF = .1, 1, 7/4
-
-sg.ChangeLookAndFeel('Black') # make it look cool
-
-# define the window layout
-NUM_LINES = 48 # number of lines of text elements. Depends on cameras image size and the variable SC (scaller)
-if USING_QT:
- layout = [[sg.T(i, size_px=(800, 12), font=('Courier', font_size), key='_OUT_' + str(i))] for i in range(NUM_LINES)]
-else:
- layout = [[sg.T(i,size=(120,1), font=('Courier', font_size), pad=(0,0), key='_OUT_'+str(i))] for i in range(NUM_LINES)]
-
-layout += [[ sg.Button('Exit', size=(5,1)),
- sg.T('GCF', size=(4,1)), sg.Spin([round(i,2) for i in np.arange(0.1,20.0,0.1)], initial_value=1, key='_SPIN_GCF_', size=(5,1)),
- sg.T('WCF', size=(4,1)), sg.Slider((1,4), resolution=.05, default_value=1.75, orientation='h', key='_SLIDER_WCF_', size=(15,15))]]
-
-# create the window and show it without the plot
-window = sg.Window('Demo Application - OpenCV Integration', layout, location=(800,400), font='Any 18')
-
-# ---===--- Event LOOP Read and display frames, operate the GUI --- #
-cap = cv2.VideoCapture(0) # Setup the OpenCV capture device (webcam)
-while True:
- event, values = window.Read(timeout=0)
- if event in ('Exit', None):
- break
- ret, frame = cap.read() # Read image from capture device (camera)
-
- img = Image.fromarray(frame) # create PIL image from frame
- GCF = float(values['_SPIN_GCF_'])
- WCF = values['_SLIDER_WCF_']
- # More magic that coverts the image to ascii
- S = (round(img.size[0] * SC * WCF), round(img.size[1] * SC))
- img = np.sum(np.asarray(img.resize(S)), axis=2)
- img -= img.min()
- img = (1.0 - img / img.max()) ** GCF * (chars.size - 1)
-
- # "Draw" the image in the window, one line of text at a time!
- for i, r in enumerate(chars[img.astype(int)]):
- window.Element('_OUT_'+str(i)).Update("".join(r))
-window.Close()
diff --git a/DemoPrograms old/Demo_OpenCV_Webcam_Minimal.py b/DemoPrograms old/Demo_OpenCV_Webcam_Minimal.py
deleted file mode 100644
index 3d08fa03..00000000
--- a/DemoPrograms old/Demo_OpenCV_Webcam_Minimal.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import PySimpleGUI as sg
-# import PySimpleGUIQt as sg
-# import PySimpleGUIWeb as sg # has a known flicker problem that's being worked
-import cv2
-
-"""
- Demo of using OpenCV to show your webcam in a GUI window.
- This demo will run on tkinter, Qt, and Web(Remi). The web version flickers at the moment though
- To exit, right click and choose exit. If on Qt, you'll have to kill the program as there are no right click menus
- in PySimpleGUIQt (yet).
-"""
-
-sg.ChangeLookAndFeel('Black')
-
-# define the window layout
-layout = [[sg.Image(filename='', key='_IMAGE_', tooltip='Right click for exit menu')],]
-
-# create the window and show it without the plot
-window = sg.Window('Demo Application - OpenCV Integration', layout, location=(800,400),
- no_titlebar=True, grab_anywhere=True,
- right_click_menu=['&Right', ['E&xit']], ) # if trying Qt, you will need to remove this right click menu
-
-# ---===--- Event LOOP Read and display frames, operate the GUI --- #
-cap = cv2.VideoCapture(0) # Setup the OpenCV capture device (webcam)
-while True:
- event, values = window.Read(timeout=20, timeout_key='timeout')
- if event in ('Exit', None):
- break
- ret, frame = cap.read() # Read image from capture device (camera)
- imgbytes=cv2.imencode('.png', frame)[1].tobytes() # Convert the image to PNG Bytes
- window.FindElement('_IMAGE_').Update(data=imgbytes) # Change the Image Element to show the new image
diff --git a/DemoPrograms old/Demo_PDF_Viewer.py b/DemoPrograms old/Demo_PDF_Viewer.py
deleted file mode 100644
index 48671c6d..00000000
--- a/DemoPrograms old/Demo_PDF_Viewer.py
+++ /dev/null
@@ -1,187 +0,0 @@
-"""
-@created: 2018-08-19 18:00:00
-
-@author: (c) 2018 Jorj X. McKie
-
-Display a PyMuPDF Document using Tkinter
--------------------------------------------------------------------------------
-
-Dependencies:
--------------
-PyMuPDF, PySimpleGUI > v2.9.0, Tkinter with Tk v8.6+, Python 3
-
-
-License:
---------
-GNU GPL V3+
-
-Description
-------------
-Read filename from command line and start display with page 1.
-Pages can be directly jumped to, or buttons for paging can be used.
-For experimental / demonstration purposes, we have included options to zoom
-into the four page quadrants (top-left, bottom-right, etc.).
-
-We also interpret keyboard events to support paging by PageDown / PageUp
-keys as if the resp. buttons were clicked. Similarly, we do not include
-a 'Quit' button. Instead, the ESCAPE key can be used, or cancelling the window.
-
-To improve paging performance, we are not directly creating pixmaps from
-pages, but instead from the fitz.DisplayList of the page. A display list
-will be stored in a list and looked up by page number. This way, zooming
-pixmaps and page re-visits will re-use a once-created display list.
-
-"""
-import sys
-import fitz
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-from sys import exit as exit
-from binascii import hexlify
-
-sg.ChangeLookAndFeel('GreenTan')
-
-if len(sys.argv) == 1:
- fname = sg.PopupGetFile('PDF Browser', 'PDF file to open', file_types=(("PDF Files", "*.pdf"),))
- if fname is None:
- sg.PopupCancel('Cancelling')
- exit(0)
-else:
- fname = sys.argv[1]
-
-doc = fitz.open(fname)
-page_count = len(doc)
-
-# storage for page display lists
-dlist_tab = [None] * page_count
-
-title = "PyMuPDF display of '%s', pages: %i" % (fname, page_count)
-
-
-def get_page(pno, zoom=0):
- """Return a PNG image for a document page number. If zoom is other than 0, one of the 4 page quadrants are zoomed-in instead and the corresponding clip returned.
-
- """
- dlist = dlist_tab[pno] # get display list
- if not dlist: # create if not yet there
- dlist_tab[pno] = doc[pno].getDisplayList()
- dlist = dlist_tab[pno]
- r = dlist.rect # page rectangle
- mp = r.tl + (r.br - r.tl) * 0.5 # rect middle point
- mt = r.tl + (r.tr - r.tl) * 0.5 # middle of top edge
- ml = r.tl + (r.bl - r.tl) * 0.5 # middle of left edge
- mr = r.tr + (r.br - r.tr) * 0.5 # middle of right egde
- mb = r.bl + (r.br - r.bl) * 0.5 # middle of bottom edge
- mat = fitz.Matrix(2, 2) # zoom matrix
- if zoom == 1: # top-left quadrant
- clip = fitz.Rect(r.tl, mp)
- elif zoom == 4: # bot-right quadrant
- clip = fitz.Rect(mp, r.br)
- elif zoom == 2: # top-right
- clip = fitz.Rect(mt, mr)
- elif zoom == 3: # bot-left
- clip = fitz.Rect(ml, mb)
- if zoom == 0: # total page
- pix = dlist.getPixmap(alpha=False)
- else:
- pix = dlist.getPixmap(alpha=False, matrix=mat, clip=clip)
- return pix.getPNGData() # return the PNG image
-
-
-window = sg.Window(title, return_keyboard_events=True, use_default_focus=False)
-
-cur_page = 0
-data = get_page(cur_page) # show page 1 for start
-image_elem = sg.Image(data=data)
-goto = sg.InputText(str(cur_page + 1), size=(5, 1), do_not_clear=True)
-
-layout = [
- [
- sg.Button('Prev'),
- sg.Button('Next'),
- sg.Text('Page:'),
- goto,
- ],
- [
- sg.Text("Zoom:"),
- sg.Button('Top-L'),
- sg.Button('Top-R'),
- sg.Button('Bot-L'),
- sg.Button('Bot-R'),
- ],
- [image_elem],
-]
-
-window.Layout(layout)
-my_keys = ("Next", "Next:34", "Prev", "Prior:33", "Top-L", "Top-R",
- "Bot-L", "Bot-R", "MouseWheel:Down", "MouseWheel:Up")
-zoom_buttons = ("Top-L", "Top-R", "Bot-L", "Bot-R")
-
-old_page = 0
-old_zoom = 0 # used for zoom on/off
-# the zoom buttons work in on/off mode.
-
-while True:
- event, values = window.Read(timeout=100)
- zoom = 0
- force_page = False
- if event is None:
- break
-
- if event in ("Escape:27",): # this spares me a 'Quit' button!
- break
- # print("hex(button)", hexlify(button.encode()))
- if event[0] == chr(13): # surprise: this is 'Enter'!
- try:
- cur_page = int(values[0]) - 1 # check if valid
- while cur_page < 0:
- cur_page += page_count
- except:
- cur_page = 0 # this guy's trying to fool me
- goto.Update(str(cur_page + 1))
- # goto.TKStringVar.set(str(cur_page + 1))
-
- elif event in ("Next", "Next:34", "MouseWheel:Down"):
- cur_page += 1
- elif event in ("Prev", "Prior:33", "MouseWheel:Up"):
- cur_page -= 1
- elif event == "Top-L":
- zoom = 1
- elif event == "Top-R":
- zoom = 2
- elif event == "Bot-L":
- zoom = 3
- elif event == "Bot-R":
- zoom = 4
-
- # sanitize page number
- if cur_page >= page_count: # wrap around
- cur_page = 0
- while cur_page < 0: # we show conventional page numbers
- cur_page += page_count
-
- # prevent creating same data again
- if cur_page != old_page:
- zoom = old_zoom = 0
- force_page = True
-
- if event in zoom_buttons:
- if 0 < zoom == old_zoom:
- zoom = 0
- force_page = True
-
- if zoom != old_zoom:
- force_page = True
-
- if force_page:
- data = get_page(cur_page, zoom)
- image_elem.Update(data=data)
- old_page = cur_page
- old_zoom = zoom
-
- # update page number field
- if event in my_keys or not values[0]:
- goto.Update(str(cur_page + 1))
- # goto.TKStringVar.set(str(cur_page + 1))
diff --git a/DemoPrograms old/Demo_PNG_Thumbnail_Viewer.py b/DemoPrograms old/Demo_PNG_Thumbnail_Viewer.py
deleted file mode 100644
index b11a71bd..00000000
--- a/DemoPrograms old/Demo_PNG_Thumbnail_Viewer.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import os
-from sys import exit as exit
-from PIL import Image
-import io
-import numpy as np
-
-thumbnails = {}
-
-ROWS = 8
-COLUMNS = 8
-sg.SetOptions(border_width=0)
-# Get the folder containing the images from the user
-# folder = 'A:/TEMP/pdfs'
-folder = sg.PopupGetFolder('Image folder to open')
-if folder is None:
- sg.PopupCancel('Cancelling')
- exit(0)
-def image_file_to_bytes(filename, size):
- try:
- image = Image.open(filename)
- image.thumbnail(size, Image.ANTIALIAS)
- bio = io.BytesIO() # a binary memory resident stream
- image.save(bio, format='PNG') # save image as png to it
- imgbytes = bio.getvalue()
- except:
- imgbytes = None
- return imgbytes
-
-def set_image_to_blank(key):
- img = Image.new('RGB', (100, 100), (255, 255, 255))
- img.thumbnail((1, 1), Image.ANTIALIAS)
- bio = io.BytesIO()
- img.save(bio, format='PNG')
- imgbytes = bio.getvalue()
- window.FindElement(key).Update(image_data=imgbytes)
-
-
-
-# get list of PNG files in folder
-png_files = [os.path.join(folder, f) for f in os.listdir(folder) if '.png' in f]
-filenames_only = [f for f in os.listdir(folder) if '.png' in f]
-
-if len(png_files) == 0:
- sg.Popup('No PNG images in folder')
- exit(0)
-
-# define menu layout
-menu = [['&File', ['&Open Folder', 'E&xit']], ['&Help', ['&About',]]]
-
-buttons = []
-for display_index in range(ROWS):
- row = []
- for j in range(COLUMNS):
- row.append(sg.Button('',border_width=0,button_color=sg.COLOR_SYSTEM_DEFAULT, key=(display_index, j)))
- buttons.append(row)
-
-col_buttons = [[]]
-
-# define layout, show and read the window
-col = [[sg.Text(png_files[0], size=(80, 3), key='filename')],
- [sg.Image(data=image_file_to_bytes(png_files[0], (500,500)), key='image')],]
-
-layout = [[sg.Menu(menu)], [sg.Column(buttons), sg.Column([[sg.Slider((len(png_files),0),default_value=0,size=(38,20),orientation='v', key='_slider_', change_submits=True)]]), sg.Column(col)]]
-window = sg.Window('Image Browser',
- return_keyboard_events=True,
- use_default_focus=False ).Layout(layout).Finalize()
-
-# -------========= Event Loop =========--------
-display_index=0
-while True:
- for x in range(ROWS): # update thumbnails
- for y in range(COLUMNS):
- cur_index = display_index + (x * 4) + y
- if cur_index < len(png_files):
- filename = png_files[cur_index]
- if filename not in thumbnails:
- imgbytes = image_file_to_bytes(filename, (100,100))
- thumbnails[filename] = imgbytes
- else:
- imgbytes = thumbnails[filename]
- button_elem = window.FindElement(key=(x,y))
- button_elem.Update(image_data=imgbytes)
- else:
- set_image_to_blank((x,y))
-
- event, values = window.Read()
- display_index = values['_slider_']
- # --------------------- Button & Keyboard ---------------------
- if event in (None, 'Exit'):
- break
- elif event in ('MouseWheel:Down', 'Down:40',) and display_index < len(png_files)-1:
- display_index += 4
- elif event in ('MouseWheel:Up', 'Up:38',) and display_index > 0:
- display_index -= 4
- elif event in ('Prior:33', 'Prev'):
- display_index -= 16
- elif event in ('Next:34', 'Next'):
- display_index += 16
-
- window.FindElement('_slider_').Update(display_index)
- # ----------------- Menu choices -----------------
- if event == 'Open Folder':
- newfolder = sg.PopupGetFolder('New folder', no_window=True)
- if newfolder is None:
- continue
- folder = newfolder
- png_files = [os.path.join(folder, f) for f in os.listdir(folder) if '.png' in f]
- filenames_only = [f for f in os.listdir(folder) if '.png' in f]
- display_index = 0
- thumbnail = {}
- for j in range(ROWS):
- for i in range(COLUMNS):
- set_image_to_blank((i,j))
- elif event == 'About':
- sg.Popup('Demo PNG Viewer Program', 'Please give PySimpleGUI a try!')
- elif type(event) is tuple:
- x, y = event
- image_index = display_index + (x * 4) + y
- if image_index < len(png_files):
- filename = png_files[image_index]
- imgbytes = image_file_to_bytes(filename, (500, 500))
- window.FindElement('image').Update(data=imgbytes)
- window.FindElement('filename').Update(filename)
-
diff --git a/DemoPrograms old/Demo_PNG_Viewer.py b/DemoPrograms old/Demo_PNG_Viewer.py
deleted file mode 100644
index 4fba5b1a..00000000
--- a/DemoPrograms old/Demo_PNG_Viewer.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import os
-from sys import exit as exit
-
-# Simple Image Browser based on PySimpleGUI
-
-# Get the folder containing the images from the user
-folder = sg.PopupGetFolder('Image folder to open')
-if folder is None:
- sg.PopupCancel('Cancelling')
- exit(0)
-
-# get list of PNG files in folder
-png_files = [folder + '\\' + f for f in os.listdir(folder) if '.png' in f]
-filenames_only = [f for f in os.listdir(folder) if '.png' in f]
-
-if len(png_files) == 0:
- sg.Popup('No PNG images in folder')
- exit(0)
-
-
-# define menu layout
-menu = [['File', ['Open Folder', 'Exit']], ['Help', ['About',]]]
-
-# define layout, show and read the window
-col = [[sg.Text(png_files[0], size=(80, 3), key='filename')],
- [sg.Image(filename=png_files[0], key='image')],
- [sg.Button('Next', size=(8,2)), sg.Button('Prev', size=(8,2)),
- sg.Text('File 1 of {}'.format(len(png_files)), size=(15,1), key='filenum')]]
-
-col_files = [[sg.Listbox(values=filenames_only, size=(60,30), key='listbox')],
- [sg.Button('Read')]]
-layout = [[sg.Menu(menu)], [sg.Column(col_files), sg.Column(col)]]
-window = sg.Window('Image Browser', return_keyboard_events=True, location=(0,0), use_default_focus=False ).Layout(layout)
-
-# loop reading the user input and displaying image, filename
-i=0
-while True:
-
- event, values = window.Read()
- # --------------------- Button & Keyboard ---------------------
- if event is None:
- break
- elif event in ('Next', 'MouseWheel:Down', 'Down:40', 'Next:34') and i < len(png_files)-1:
- i += 1
- elif event in ('Prev', 'MouseWheel:Up', 'Up:38', 'Prior:33') and i > 0:
- i -= 1
- elif event == 'Exit':
- exit(69)
-
- filename = folder + '/' + values['listbox'][0] if event == 'Read' else png_files[i]
-
- # ----------------- Menu choices -----------------
- if event == 'Open Folder':
- newfolder = sg.PopupGetFolder('New folder', no_window=True)
- if newfolder is None:
- continue
- folder = newfolder
- png_files = [folder + '/' + f for f in os.listdir(folder) if '.png' in f]
- filenames_only = [f for f in os.listdir(folder) if '.png' in f]
- window.FindElement('listbox').Update(values=filenames_only)
- window.Refresh()
- i = 0
- elif event == 'About':
- sg.Popup('Demo PNG Viewer Program', 'Please give PySimpleGUI a try!')
-
- # update window with new image
- window.FindElement('image').Update(filename=filename)
- # update window with filename
- window.FindElement('filename').Update(filename)
- # update page display
- window.FindElement('filenum').Update('File {} of {}'.format(i+1, len(png_files)))
-
diff --git a/DemoPrograms old/Demo_Paned_Window.py b/DemoPrograms old/Demo_Paned_Window.py
deleted file mode 100644
index 0bc884ac..00000000
--- a/DemoPrograms old/Demo_Paned_Window.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import PySimpleGUI as sg
-
-sg.ChangeLookAndFeel('GreenTan')
-
-col1 = sg.Column([[sg.Text('in pane1', text_color='blue')],
- [sg.T('Pane1')],
- [sg.T('Pane1')],
- ])
-col2 = sg.Column([[sg.Text('in pane2', text_color='red')],
- [sg.T('Pane2')],
- [sg.Input(key='_IN2_', do_not_clear=True)],
- [sg.T('Pane2')],
- [sg.T('Pane2')],
- ], key='_COL2_', visible=False)
-col3 = sg.Column([[sg.Text('in pane 4', text_color='green')],
- [sg.In(key='_IN3_', enable_events=True, do_not_clear=True)],
- ], key='_COL3_', visible=False)
-col4 = sg.Column([[sg.Text('Column 4', text_color='firebrick')],
- [sg.In()],
- ], key='_COL4_')
-col5 = sg.Column([[sg.Frame('Frame', [[sg.Text('Column 5', text_color='purple')],
- [sg.In()],
- ])]])
-
-layout = [ [sg.Text('Click'), sg.Text('', key='_OUTPUT_')],
- [sg.Button('Remove'), sg.Button('Add')],
- [sg.Pane([col5, sg.Column([[sg.Pane([col1, col2, col4], handle_size=15, orientation='v', background_color='red', show_handle=True, visible=True, key='_PANE_', border_width=0, relief=sg.RELIEF_GROOVE),]]),col3 ], orientation='h', background_color=None, size=(160,160), relief=sg.RELIEF_RAISED, border_width=0)]
- ]
-
-window = sg.Window('Window Title', default_element_size=(15,1), resizable=True, border_depth=5).Layout(layout)
-
-while True: # Event Loop
- event, values = window.Read()
- print(event, values)
- if event is None or event == 'Exit':
- break
- if event == 'Remove':
- window.Element('_COL2_').Update(visible=False)
- window.Element('_COL3_').Update(visible=False)
- elif event == 'Add':
- window.Element('_COL2_').Update(visible=True)
- window.Element('_COL3_').Update(visible=True)
- window.Element('_IN2_').Update(values['_IN3_'])
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Password_Login.py b/DemoPrograms old/Demo_Password_Login.py
deleted file mode 100644
index 1f7abfbd..00000000
--- a/DemoPrograms old/Demo_Password_Login.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import hashlib
-from sys import exit as exit
-
-"""
- Create a secure login for your scripts without having to include your password
- in the program. Create an SHA1 hash code for your password using the GUI. Paste into variable in final program
- 1. Choose a password
- 2. Generate a hash code for your chosen password by running program and entering 'gui' as the password
- 3. Type password into the GUI
- 4. Copy and paste hash code from GUI into variable named login_password_hash
- 5. Run program again and test your login!
- 6. Are you paying attention? The first person that can post an issue on GitHub with the
- matching password to the hash code in this example gets a $5 PayPal payment
-"""
-
-# Use this GUI to get your password's hash code
-def HashGeneratorGUI():
- layout = [[sg.T('Password Hash Generator', size=(30,1), font='Any 15')],
- [sg.T('Password'), sg.In(key='password')],
- [sg.T('SHA Hash'), sg.In('', size=(40,1), key='hash')],
- ]
-
- window = sg.Window('SHA Generator', auto_size_text=False, default_element_size=(10,1),
- text_justification='r', return_keyboard_events=True, grab_anywhere=False).Layout(layout)
-
- while True:
- event, values = window.Read()
- if event is None:
- exit(69)
-
- password = values['password']
- try:
- password_utf = password.encode('utf-8')
- sha1hash = hashlib.sha1()
- sha1hash.update(password_utf)
- password_hash = sha1hash.hexdigest()
- window.FindElement('hash').Update(password_hash)
- except:
- pass
-
-# ----------------------------- Paste this code into your program / script -----------------------------
-# determine if a password matches the secret password by comparing SHA1 hash codes
-def PasswordMatches(password, hash):
- password_utf = password.encode('utf-8')
- sha1hash = hashlib.sha1()
- sha1hash.update(password_utf)
- password_hash = sha1hash.hexdigest()
- return password_hash == hash
-
-
-login_password_hash = 'e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4'
-password = sg.PopupGetText('Password', password_char='*')
-if password == 'gui': # Remove when pasting into your program
- HashGeneratorGUI() # Remove when pasting into your program
- exit(69) # Remove when pasting into your program
-if PasswordMatches(password, login_password_hash):
- print('Login SUCCESSFUL')
-else:
- print('Login FAILED!!')
diff --git a/DemoPrograms old/Demo_Pi_LEDs.py b/DemoPrograms old/Demo_Pi_LEDs.py
deleted file mode 100644
index c82b9583..00000000
--- a/DemoPrograms old/Demo_Pi_LEDs.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-# GUI for switching an LED on and off to GPIO14
-
-# GPIO and time library:
-import time
-
-if sys.platform == 'win32':
- from random import randint
-
- class GPIO():
- LOW = 0
- HIGH = 1
- BCM = OUT = 0
- current_value = 0
- @classmethod
- def setmode(self, mode):
- return
- @classmethod
- def setup(self, arg1, arg2):
- return
- @classmethod
- def output(self, port, value):
- self.current_value = value
- @classmethod
- def input(self, port):
- return self.current_value
-else:
- import RPi.GPIO as GPIO
-
-# determine that GPIO numbers are used:
-GPIO.setmode(GPIO.BCM)
-GPIO.setup(14, GPIO.OUT)
-
-def SwitchLED():
- varLedStatus = GPIO.input(14)
- if varLedStatus == 0:
- GPIO.output(14, GPIO.HIGH)
- return "LED is switched ON"
- else:
- GPIO.output(14, GPIO.LOW)
- return "LED is switched OFF"
-
-
-def FlashLED():
- for i in range(5):
- GPIO.output(14, GPIO.HIGH)
- time.sleep(0.5)
- GPIO.output(14, GPIO.LOW)
- time.sleep(0.5)
-
-layout = [[sg.T('Raspberry Pi LEDs')],
- [sg.T('', size=(20, 1), key='output')],
- [sg.Button('Switch LED')],
- [sg.Button('Flash LED')],
- [sg.Exit()]]
-
-window = sg.Window('Raspberry Pi GUI', layout, grab_anywhere=False)
-
-while True:
- event, values = window.Read()
- if event in (None, 'Exit'):
- break
-
- if event == 'Switch LED':
- window.FindElement('output').Update(SwitchLED())
- elif event == 'Flash LED':
- window.FindElement('output').Update('LED is Flashing')
- window.Refresh()
- FlashLED()
- window.FindElement('output').Update('')
-
-window.Close()
-sg.Popup('Done... exiting')
diff --git a/DemoPrograms old/Demo_Pi_Robotics.py b/DemoPrograms old/Demo_Pi_Robotics.py
deleted file mode 100644
index 0c2ea577..00000000
--- a/DemoPrograms old/Demo_Pi_Robotics.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-# Robotics design pattern
-# Uses Realtime Buttons to simulate the controls for a robot
-# Rather than sending a single click when a button is clicked, Realtime Buttons
-# send button presses continuously while the button is pressed down.
-# Two examples, one using fancy graphics, one plain.
-
-def RemoteControlExample():
- # Make a form, but don't use context manager
- sg.SetOptions(element_padding=(0,0))
- back ='#eeeeee'
- image_forward = 'ButtonGraphics/RobotForward.png'
- image_backward = 'ButtonGraphics/RobotBack.png'
- image_left = 'ButtonGraphics/RobotLeft.png'
- image_right = 'ButtonGraphics/RobotRight.png'
-
- sg.SetOptions(border_width=0, button_color=('black', back), background_color=back, element_background_color=back, text_element_background_color=back)
-
- layout = [[sg.Text('Robotics Remote Control')],
- [sg.T('', justification='center', size=(19,1), key='status')],
- [ sg.RealtimeButton('', key='Forward', image_filename=image_forward, pad=((50,0),0))],
- [ sg.RealtimeButton('', key='Left', image_filename=image_left),
- sg.RealtimeButton('', key='Right', image_filename=image_right, pad=((50,0), 0))],
- [ sg.RealtimeButton('', key='Reverse', image_filename=image_backward, pad=((50,0),0))],
- [sg.T('')],
- [sg.Quit(button_color=('black', 'orange'))]]
-
- window = sg.Window('Robotics Remote Control', auto_size_text=True, grab_anywhere=False).Layout(layout)
-
- #
- # Some place later in your code...
- # You need to perform a ReadNonBlocking on your form every now and then or
- # else it won't refresh.
- #
- # your program's main loop
- while (True):
- # This is the code that reads and updates your window
- event, values = window.Read(timeout=0, timeout_key='timeout')
- if event is not None:
- window.FindElement('status').Update(event)
- elif event != 'timeout':
- window.FindElement('status').Update('')
- # if user clicked quit button OR closed the form using the X, then break out of loop
- if event == 'Quit' or values is None:
- break
-
- window.Close()
-
-
-def RemoteControlExample_NoGraphics():
- # Make a form, but don't use context manager
-
- layout = [[sg.Text('Robotics Remote Control', justification='center')],
- [sg.T('', justification='center', size=(19,1), key='status')],
- [sg.T(' '*8), sg.RealtimeButton('Forward')],
- [ sg.RealtimeButton('Left'), sg.T(' '), sg.RealtimeButton('Right')],
- [sg.T(' '*8), sg.RealtimeButton('Reverse')],
- [sg.T('')],
- [sg.Quit(button_color=('black', 'orange'))]]
- # Display form to user
- window = sg.Window('Robotics Remote Control', auto_size_text=True, grab_anywhere=False).Layout(layout)
-
- #
- # Some place later in your code...
- # You need to perform a Read on your form every now and then or
- # else it won't refresh.
- # Notice how the timeout is 100ms. You don't have to use a timeout = 0 for all of your hardware
- # applications. Leave some CPU for other threads or for your GUI. The longer you are in the GUI, the more
- # responsive the GUI itself will be Match your timeout with your hardware's capabilities
- #
- # your program's main loop
- while (True):
- # This is the code that reads and updates your window
- event, values = window.Read(timeout=100, timeout_key='timeout')
- # print(event, values)
- if event != 'timeout':
- window.FindElement('status').Update(event)
- else:
- window.FindElement('status').Update('')
- # if user clicked quit button OR closed the form using the X, then break out of loop
- if event in (None, 'Quit'):
- break
-
- window.Close()
-
-# ------------------------------------- main -------------------------------------
-def main():
- RemoteControlExample_NoGraphics()
- # Uncomment to get the fancy graphics version. Be sure and download the button images!
- RemoteControlExample()
- # sg.Popup('End of non-blocking demonstration')
-
-if __name__ == '__main__':
-
- main()
diff --git a/DemoPrograms old/Demo_Ping_Line_Graph.py b/DemoPrograms old/Demo_Ping_Line_Graph.py
deleted file mode 100644
index d7e8f182..00000000
--- a/DemoPrograms old/Demo_Ping_Line_Graph.py
+++ /dev/null
@@ -1,665 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-from threading import Thread
-import time
-from sys import exit as exit
-
-# !/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-"""
- A pure python ping implementation using raw sockets.
-
- (This is Python 3 port of https://github.com/jedie/python-ping)
- (Tested and working with python 2.7, should work with 2.6+)
-
- Note that ICMP messages can only be sent from processes running as root
- (in Windows, you must run this script as 'Administrator').
-
- Derived from ping.c distributed in Linux's netkit. That code is
- copyright (c) 1989 by The Regents of the University of California.
- That code is in turn derived from code written by Mike Muuss of the
- US Army Ballistic Research Laboratory in December, 1983 and
- placed in the public domain. They have my thanks.
-
- Bugs are naturally mine. I'd be glad to hear about them. There are
- certainly word - size dependencies here.
-
- Copyright (c) Matthew Dixon Cowles, .
- Distributable under the terms of the GNU General Public License
- version 2. Provided with no warranties of any sort.
-
- Original Version from Matthew Dixon Cowles:
- -> ftp://ftp.visi.com/users/mdc/ping.py
-
- Rewrite by Jens Diemer:
- -> http://www.python-forum.de/post-69122.html#69122
-
- Rewrite by George Notaras:
- -> http://www.g-loaded.eu/2009/10/30/python-ping/
-
- Enhancements by Martin Falatic:
- -> http://www.falatic.com/index.php/39/pinging-with-python
-
- Enhancements and fixes by Georgi Kolev:
- -> http://github.com/jedie/python-ping/
-
- Bug fix by Andrejs Rozitis:
- -> http://github.com/rozitis/python-ping/
-
- Revision history
- ~~~~~~~~~~~~~~~~
- May 1, 2014
- -----------
- Little modifications by Mohammad Emami
- - Added Python 3 support. For now this project will just support
- python 3.x
- - Tested with python 3.3
- - version was upped to 0.6
-
- March 19, 2013
- --------------
- * Fixing bug to prevent divide by 0 during run-time.
-
- January 26, 2012
- ----------------
- * Fixing BUG #4 - competability with python 2.x [tested with 2.7]
- - Packet data building is different for 2.x and 3.x.
- 'cose of the string/bytes difference.
- * Fixing BUG #10 - the multiple resolv issue.
- - When pinging domain names insted of hosts (for exmaple google.com)
- you can get different IP every time you try to resolv it, we should
- resolv the host only once and stick to that IP.
- * Fixing BUGs #3 #10 - Doing hostname resolv only once.
- * Fixing BUG #14 - Removing all 'global' stuff.
- - You should not use globul! Its bad for you...and its not thread safe!
- * Fix - forcing the use of different times on linux/windows for
- more accurate mesurments. (time.time - linux/ time.clock - windows)
- * Adding quiet_ping function - This way we'll be able to use this script
- as external lib.
- * Changing default timeout to 3s. (1second is not enought)
- * Switching data syze to packet size. It's easyer for the user to ignore the
- fact that the packet headr is 8b and the datasize 64 will make packet with
- size 72.
-
- October 12, 2011
- --------------
- Merged updates from the main project
- -> https://github.com/jedie/python-ping
-
- September 12, 2011
- --------------
- Bugfixes + cleanup by Jens Diemer
- Tested with Ubuntu + Windows 7
-
- September 6, 2011
- --------------
- Cleanup by Martin Falatic. Restored lost comments and docs. Improved
- functionality: constant time between pings, internal times consistently
- use milliseconds. Clarified annotations (e.g., in the checksum routine).
- Using unsigned data in IP & ICMP header pack/unpack unless otherwise
- necessary. Signal handling. Ping-style output formatting and stats.
-
- August 3, 2011
- --------------
- Ported to py3k by Zach Ware. Mostly done by 2to3; also minor changes to
- deal with bytes vs. string changes (no more ord() in checksum() because
- >source_string< is actually bytes, added .encode() to data in
- send_one_ping()). That's about it.
-
- March 11, 2010
- --------------
- changes by Samuel Stauffer:
- - replaced time.clock with default_timer which is set to
- time.clock on windows and time.time on other systems.
-
- November 8, 2009
- ----------------
- Improved compatibility with GNU/Linux systems.
-
- Fixes by:
- * George Notaras -- http://www.g-loaded.eu
- Reported by:
- * Chris Hallman -- http://cdhallman.blogspot.com
-
- Changes in this release:
- - Re-use time.time() instead of time.clock(). The 2007 implementation
- worked only under Microsoft Windows. Failed on GNU/Linux.
- time.clock() behaves differently under the two OSes[1].
-
- [1] http://docs.python.org/library/time.html#time.clock
-
- May 30, 2007
- ------------
- little rewrite by Jens Diemer:
- - change socket asterisk import to a normal import
- - replace time.time() with time.clock()
- - delete "return None" (or change to "return" only)
- - in checksum() rename "str" to "source_string"
-
- December 4, 2000
- ----------------
- Changed the struct.pack() calls to pack the checksum and ID as
- unsigned. My thanks to Jerome Poincheval for the fix.
-
- November 22, 1997
- -----------------
- Initial hack. Doesn't do much, but rather than try to guess
- what features I (or others) will want in the future, I've only
- put in what I need now.
-
- December 16, 1997
- -----------------
- For some reason, the checksum bytes are in the wrong order when
- this is run under Solaris 2.X for SPARC but it works right under
- Linux x86. Since I don't know just what's wrong, I'll swap the
- bytes always and then do an htons().
-
- ===========================================================================
- IP header info from RFC791
- -> http://tools.ietf.org/html/rfc791)
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |Version| IHL |Type of Service| Total Length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Identification |Flags| Fragment Offset |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Time to Live | Protocol | Header Checksum |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Source Address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Destination Address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Options | Padding |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
- ===========================================================================
- ICMP Echo / Echo Reply Message header info from RFC792
- -> http://tools.ietf.org/html/rfc792
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Code | Checksum |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Identifier | Sequence Number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Data ...
- +-+-+-+-+-
-
- ===========================================================================
- ICMP parameter info:
- -> http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml
-
- ===========================================================================
- An example of ping's typical output:
-
- PING heise.de (193.99.144.80): 56 data bytes
- 64 bytes from 193.99.144.80: icmp_seq=0 ttl=240 time=127 ms
- 64 bytes from 193.99.144.80: icmp_seq=1 ttl=240 time=127 ms
- 64 bytes from 193.99.144.80: icmp_seq=2 ttl=240 time=126 ms
- 64 bytes from 193.99.144.80: icmp_seq=3 ttl=240 time=126 ms
- 64 bytes from 193.99.144.80: icmp_seq=4 ttl=240 time=127 ms
-
- ----heise.de PING Statistics----
- 5 packets transmitted, 5 packets received, 0.0% packet loss
- round-trip (ms) min/avg/max/med = 126/127/127/127
-
- ===========================================================================
-"""
-
-# =============================================================================#
-import argparse
-import os, sys, socket, struct, select, time, signal
-
-__description__ = 'A pure python ICMP ping implementation using raw sockets.'
-
-if sys.platform == "win32":
- # On Windows, the best timer is time.clock()
- default_timer = time.clock
-else:
- # On most other platforms the best timer is time.time()
- default_timer = time.time
-
-NUM_PACKETS = 3
-PACKET_SIZE = 64
-WAIT_TIMEOUT = 3.0
-
-# =============================================================================#
-# ICMP parameters
-
-ICMP_ECHOREPLY = 0 # Echo reply (per RFC792)
-ICMP_ECHO = 8 # Echo request (per RFC792)
-ICMP_MAX_RECV = 2048 # Max size of incoming buffer
-
-MAX_SLEEP = 1000
-
-
-class MyStats:
- thisIP = "0.0.0.0"
- pktsSent = 0
- pktsRcvd = 0
- minTime = 999999999
- maxTime = 0
- totTime = 0
- avrgTime = 0
- fracLoss = 1.0
-
-
-myStats = MyStats # NOT Used globally anymore.
-
-
-# =============================================================================#
-def checksum(source_string):
- """
- A port of the functionality of in_cksum() from ping.c
- Ideally this would act on the string as a series of 16-bit ints (host
- packed), but this works.
- Network data is big-endian, hosts are typically little-endian
- """
- countTo = (int(len(source_string) / 2)) * 2
- sum = 0
- count = 0
-
- # Handle bytes in pairs (decoding as short ints)
- loByte = 0
- hiByte = 0
- while count < countTo:
- if (sys.byteorder == "little"):
- loByte = source_string[count]
- hiByte = source_string[count + 1]
- else:
- loByte = source_string[count + 1]
- hiByte = source_string[count]
- try: # For Python3
- sum = sum + (hiByte * 256 + loByte)
- except: # For Python2
- sum = sum + (ord(hiByte) * 256 + ord(loByte))
- count += 2
-
- # Handle last byte if applicable (odd-number of bytes)
- # Endianness should be irrelevant in this case
- if countTo < len(source_string): # Check for odd length
- loByte = source_string[len(source_string) - 1]
- try: # For Python3
- sum += loByte
- except: # For Python2
- sum += ord(loByte)
-
- sum &= 0xffffffff # Truncate sum to 32 bits (a variance from ping.c, which
- # uses signed ints, but overflow is unlikely in ping)
-
- sum = (sum >> 16) + (sum & 0xffff) # Add high 16 bits to low 16 bits
- sum += (sum >> 16) # Add carry from above (if any)
- answer = ~sum & 0xffff # Invert and truncate to 16 bits
- answer = socket.htons(answer)
-
- return answer
-
-
-# =============================================================================#
-def do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size, quiet=False):
- """
- Returns either the delay (in ms) or None on timeout.
- """
- delay = None
-
- try: # One could use UDP here, but it's obscure
- mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
- except socket.error as e:
- print("failed. (socket error: '%s')" % e.args[1])
- raise # raise the original error
-
- my_ID = os.getpid() & 0xFFFF
-
- sentTime = send_one_ping(mySocket, destIP, my_ID, mySeqNumber, packet_size)
- if sentTime == None:
- mySocket.close()
- return delay
-
- myStats.pktsSent += 1
-
- recvTime, dataSize, iphSrcIP, icmpSeqNumber, iphTTL = receive_one_ping(mySocket, my_ID, timeout)
-
- mySocket.close()
-
- if recvTime:
- delay = (recvTime - sentTime) * 1000
- if not quiet:
- print("%d bytes from %s: icmp_seq=%d ttl=%d time=%d ms" % (
- dataSize, socket.inet_ntoa(struct.pack("!I", iphSrcIP)), icmpSeqNumber, iphTTL, delay)
- )
- myStats.pktsRcvd += 1
- myStats.totTime += delay
- if myStats.minTime > delay:
- myStats.minTime = delay
- if myStats.maxTime < delay:
- myStats.maxTime = delay
- else:
- delay = None
- print("Request timed out.")
-
- return delay
-
-
-# =============================================================================#
-def send_one_ping(mySocket, destIP, myID, mySeqNumber, packet_size):
- """
- Send one ping to the given >destIP<.
- """
- # destIP = socket.gethostbyname(destIP)
-
- # Header is type (8), code (8), checksum (16), id (16), sequence (16)
- # (packet_size - 8) - Remove header size from packet size
- myChecksum = 0
-
- # Make a dummy heder with a 0 checksum.
- header = struct.pack(
- "!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber
- )
-
- padBytes = []
- startVal = 0x42
- # 'cose of the string/byte changes in python 2/3 we have
- # to build the data differnely for different version
- # or it will make packets with unexpected size.
- if sys.version[:1] == '2':
- bytes = struct.calcsize("d")
- data = ((packet_size - 8) - bytes) * "Q"
- data = struct.pack("d", default_timer()) + data
- else:
- for i in range(startVal, startVal + (packet_size - 8)):
- padBytes += [(i & 0xff)] # Keep chars in the 0-255 range
- # data = bytes(padBytes)
- data = bytearray(padBytes)
-
- # Calculate the checksum on the data and the dummy header.
- myChecksum = checksum(header + data) # Checksum is in network order
-
- # Now that we have the right checksum, we put that in. It's just easier
- # to make up a new header than to stuff it into the dummy.
- header = struct.pack(
- "!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber
- )
-
- packet = header + data
-
- sendTime = default_timer()
-
- try:
- mySocket.sendto(packet, (destIP, 1)) # Port number is irrelevant for ICMP
- except socket.error as e:
- print("General failure (%s)" % (e.args[1]))
- return
-
- return sendTime
-
-
-# =============================================================================#
-def receive_one_ping(mySocket, myID, timeout):
- """
- Receive the ping from the socket. Timeout = in ms
- """
- timeLeft = timeout / 1000
-
- while True: # Loop while waiting for packet or timeout
- startedSelect = default_timer()
- whatReady = select.select([mySocket], [], [], timeLeft)
- howLongInSelect = (default_timer() - startedSelect)
- if whatReady[0] == []: # Timeout
- return None, 0, 0, 0, 0
-
- timeReceived = default_timer()
-
- recPacket, addr = mySocket.recvfrom(ICMP_MAX_RECV)
-
- ipHeader = recPacket[:20]
- iphVersion, iphTypeOfSvc, iphLength, \
- iphID, iphFlags, iphTTL, iphProtocol, \
- iphChecksum, iphSrcIP, iphDestIP = struct.unpack(
- "!BBHHHBBHII", ipHeader
- )
-
- icmpHeader = recPacket[20:28]
- icmpType, icmpCode, icmpChecksum, \
- icmpPacketID, icmpSeqNumber = struct.unpack(
- "!BBHHH", icmpHeader
- )
-
- if icmpPacketID == myID: # Our packet
- dataSize = len(recPacket) - 28
- # print (len(recPacket.encode()))
- return timeReceived, (dataSize + 8), iphSrcIP, icmpSeqNumber, iphTTL
-
- timeLeft = timeLeft - howLongInSelect
- if timeLeft <= 0:
- return None, 0, 0, 0, 0
-
-
-# =============================================================================#
-def dump_stats(myStats):
- """
- Show stats when pings are done
- """
- print("\n----%s PYTHON PING Statistics----" % (myStats.thisIP))
-
- if myStats.pktsSent > 0:
- myStats.fracLoss = (myStats.pktsSent - myStats.pktsRcvd) / myStats.pktsSent
-
- print("%d packets transmitted, %d packets received, %0.1f%% packet loss" % (
- myStats.pktsSent, myStats.pktsRcvd, 100.0 * myStats.fracLoss
- ))
-
- if myStats.pktsRcvd > 0:
- print("round-trip (ms) min/avg/max = %d/%0.1f/%d" % (
- myStats.minTime, myStats.totTime / myStats.pktsRcvd, myStats.maxTime
- ))
-
- print("")
- return
-
-
-# =============================================================================#
-def signal_handler(signum, frame):
- """
- Handle exit via signals
- """
- dump_stats()
- print("\n(Terminated with signal %d)\n" % (signum))
- sys.exit(0)
-
-
-# =============================================================================#
-def verbose_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS,
- packet_size=PACKET_SIZE, path_finder=False):
- """
- Send >count< ping to >destIP< with the given >timeout< and display
- the result.
- """
- signal.signal(signal.SIGINT, signal_handler) # Handle Ctrl-C
- if hasattr(signal, "SIGBREAK"):
- # Handle Ctrl-Break e.g. under Windows
- signal.signal(signal.SIGBREAK, signal_handler)
-
- myStats = MyStats() # Reset the stats
-
- mySeqNumber = 0 # Starting value
-
- try:
- destIP = socket.gethostbyname(hostname)
- print("\nPYTHON PING %s (%s): %d data bytes" % (hostname, destIP, packet_size))
- except socket.gaierror as e:
- print("\nPYTHON PING: Unknown host: %s (%s)" % (hostname, e.args[1]))
- print()
- return
-
- myStats.thisIP = destIP
-
- for i in range(count):
- delay = do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size)
-
- if delay == None:
- delay = 0
-
- mySeqNumber += 1
-
- # Pause for the remainder of the MAX_SLEEP period (if applicable)
- if (MAX_SLEEP > delay):
- time.sleep((MAX_SLEEP - delay) / 1000)
-
- dump_stats(myStats)
-
-
-# =============================================================================#
-def quiet_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS,
- packet_size=PACKET_SIZE, path_finder=False):
- """
- Same as verbose_ping, but the results are returned as tuple
- """
- myStats = MyStats() # Reset the stats
- mySeqNumber = 0 # Starting value
-
- try:
- destIP = socket.gethostbyname(hostname)
- except socket.gaierror as e:
- return False
-
- myStats.thisIP = destIP
-
- # This will send packet that we dont care about 0.5 seconds before it starts
- # acrutally pinging. This is needed in big MAN/LAN networks where you sometimes
- # loose the first packet. (while the switches find the way... :/ )
- if path_finder:
- fakeStats = MyStats()
- do_one(fakeStats, destIP, hostname, timeout,
- mySeqNumber, packet_size, quiet=True)
- time.sleep(0.5)
-
- for i in range(count):
- delay = do_one(myStats, destIP, hostname, timeout,
- mySeqNumber, packet_size, quiet=True)
-
- if delay == None:
- delay = 0
-
- mySeqNumber += 1
-
- # Pause for the remainder of the MAX_SLEEP period (if applicable)
- if (MAX_SLEEP > delay):
- time.sleep((MAX_SLEEP - delay) / 1000)
-
- if myStats.pktsSent > 0:
- myStats.fracLoss = (myStats.pktsSent - myStats.pktsRcvd) / myStats.pktsSent
- if myStats.pktsRcvd > 0:
- myStats.avrgTime = myStats.totTime / myStats.pktsRcvd
-
- # return tuple(max_rtt, min_rtt, avrg_rtt, percent_lost)
- return myStats.maxTime, myStats.minTime, myStats.avrgTime, myStats.fracLoss
-
-
-# =============================================================================#
-def main():
- parser = argparse.ArgumentParser(description=__description__)
- parser.add_argument('-q', '--quiet', action='store_true',
- help='quiet output')
- parser.add_argument('-c', '--count', type=int, default=NUM_PACKETS,
- help=('number of packets to be sent '
- '(default: %(default)s)'))
- parser.add_argument('-W', '--timeout', type=float, default=WAIT_TIMEOUT,
- help=('time to wait for a response in seoncds '
- '(default: %(default)s)'))
- parser.add_argument('-s', '--packet-size', type=int, default=PACKET_SIZE,
- help=('number of data bytes to be sent '
- '(default: %(default)s)'))
- parser.add_argument('destination')
- # args = parser.parse_args()
-
- ping = verbose_ping
- # if args.quiet:
- # ping = quiet_ping
- ping('Google.com', timeout=1000)
- # ping(args.destination, timeout=args.timeout*1000, count=args.count,
- # packet_size=args.packet_size)
-
-
-# set coordinate system
-canvas_right = 300
-canvas_left = 0
-canvas_top = 0
-canvas_bottom = 300
-# define the coordinates you'll use for your graph
-x_right = 100
-x_left = 0
-y_bottom = 0
-y_top = 500
-
-# globale used to communicate with thread.. yea yea... it's working fine
-g_exit = False
-g_response_time = None
-
-def ping_thread(args):
- global g_exit, g_response_time
-
- while not g_exit:
- g_response_time = quiet_ping('google.com', timeout=1000)
-
-
-def convert_xy_to_canvas_xy(x_in,y_in):
- scale_x = (canvas_right - canvas_left) / (x_right - x_left)
- scale_y = (canvas_top - canvas_bottom) / (y_top - y_bottom)
- new_x = canvas_left + scale_x * (x_in - x_left)
- new_y = canvas_bottom + scale_y * (y_in - y_bottom)
- return new_x, new_y
-
-
-
-# start ping measurement thread
-thread = Thread(target=ping_thread, args=(None,))
-thread.start()
-
-layout = [ [sg.T('Ping times to Google.com', font='Any 18')],
- [sg.Canvas(size=(canvas_right, canvas_bottom), background_color='white', key='canvas')],
- [sg.Quit()] ]
-
-window = sg.Window('Ping Times To Google.com', grab_anywhere=True).Layout(layout).Finalize()
-
-canvas = window.FindElement('canvas').TKCanvas
-
-prev_response_time = None
-i=0
-prev_x, prev_y = canvas_left, canvas_bottom
-while True:
- time.sleep(.2)
-
- event, values = window.Read(timeout=0)
- if event == 'Quit' or event is None:
- break
-
- if g_response_time is None or prev_response_time == g_response_time:
- continue
- try:
- new_x, new_y = convert_xy_to_canvas_xy(i, g_response_time[0])
- except: continue
-
- prev_response_time = g_response_time
- canvas.create_line(prev_x, prev_y, new_x, new_y, width=1, fill='black')
- prev_x, prev_y = new_x, new_y
- if i >= x_right:
- i = 0
- prev_x = prev_y = last_x = last_y = 0
- canvas.delete('all')
- else: i += 1
-
-# tell thread we're done. wait for thread to exit
-g_exit = True
-thread.join()
-
-
-exit(69)
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Pong.py b/DemoPrograms old/Demo_Pong.py
deleted file mode 100644
index df4111e4..00000000
--- a/DemoPrograms old/Demo_Pong.py
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import random
-import time
-from sys import exit as exit
-
-
-"""
- Pong code supplied by Daniel Young (Neonzz)
- Modified. Original code: https://www.pygame.org/project/3649/5739
-"""
-
-class Ball:
- def __init__(self, canvas, bat, bat2, color):
- self.canvas = canvas
- self.bat = bat
- self.bat2 = bat2
- self.playerScore = 0
- self.player1Score = 0
- self.drawP1 = None
- self.drawP = None
- self.id = self.canvas.create_oval(10, 10, 35, 35, fill=color)
- self.canvas.move(self.id, 327, 220)
- self.canvas_height = self.canvas.winfo_height()
- self.canvas_width = self.canvas.winfo_width()
- self.x = random.choice([-2.5, 2.5])
- self.y = -2.5
-
- def checkwin(self):
- winner = None
- if self.playerScore >= 10:
- winner = 'Player left wins'
- if self.player1Score >= 10:
- winner = 'Player Right'
- return winner
-
-
- def updatep(self, val):
- self.canvas.delete(self.drawP)
- self.drawP = self.canvas.create_text(170, 50, font=('freesansbold.ttf', 40), text=str(val), fill='white')
-
- def updatep1(self, val):
- self.canvas.delete(self.drawP1)
- self.drawP1 = self.canvas.create_text(550, 50, font=('freesansbold.ttf', 40), text=str(val), fill='white')
-
- def hit_bat(self, pos):
- bat_pos = self.canvas.coords(self.bat.id)
- if pos[2] >= bat_pos[0] and pos[0] <= bat_pos[2]:
- if pos[3] >= bat_pos[1] and pos[3] <= bat_pos[3]:
- return True
- return False
-
- def hit_bat2(self, pos):
- bat_pos = self.canvas.coords(self.bat2.id)
- if pos[2] >= bat_pos[0] and pos[0] <= bat_pos[2]:
- if pos[3] >= bat_pos[1] and pos[3] <= bat_pos[3]:
- return True
- return False
-
- def draw(self):
- self.canvas.move(self.id, self.x, self.y)
- pos = self.canvas.coords(self.id)
- if pos[1] <= 0:
- self.y = 4
- if pos[3] >= self.canvas_height:
- self.y = -4
- if pos[0] <= 0:
- self.player1Score += 1
- self.canvas.move(self.id, 327, 220)
- self.x = 4
- self.updatep1(self.player1Score)
- if pos[2] >= self.canvas_width:
- self.playerScore += 1
- self.canvas.move(self.id, -327, -220)
- self.x = -4
- self.updatep(self.playerScore)
- if self.hit_bat(pos):
- self.x = 4
- if self.hit_bat2(pos):
- self.x = -4
-
-
-class pongbat():
- def __init__(self, canvas, color):
- self.canvas = canvas
- self.id = self.canvas.create_rectangle(40, 200, 25, 310, fill=color)
- self.canvas_height = self.canvas.winfo_height()
- self.canvas_width = self.canvas.winfo_width()
- self.y = 0
-
- def up(self, evt):
- self.y = -5
-
- def down(self, evt):
- self.y = 5
-
- def draw(self):
- self.canvas.move(self.id, 0, self.y)
- pos = self.canvas.coords(self.id)
- if pos[1] <= 0:
- self.y = 0
- if pos[3] >= 400:
- self.y = 0
-
-
-class pongbat2():
- def __init__(self, canvas, color):
- self.canvas = canvas
- self.id = self.canvas.create_rectangle(680, 200, 660, 310, fill=color)
- self.canvas_height = self.canvas.winfo_height()
- self.canvas_width = self.canvas.winfo_width()
- self.y = 0
-
- def up(self, evt):
- self.y = -5
-
- def down(self, evt):
- self.y = 5
-
- def draw(self):
- self.canvas.move(self.id, 0, self.y)
- pos = self.canvas.coords(self.id)
- if pos[1] <= 0:
- self.y = 0
- if pos[3] >= 400:
- self.y = 0
-
-
-def pong():
- # ------------- Define GUI layout -------------
- layout = [[sg.Canvas(size=(700, 400), background_color='black', key='canvas')],
- [sg.T(''), sg.Button('Quit')]]
- # ------------- Create window -------------
- window = sg.Window('The Classic Game of Pong', return_keyboard_events=True).Layout(layout).Finalize()
- # window.Finalize() # TODO Replace with call to window.Finalize once code released
-
- # ------------- Get the tkinter Canvas we're drawing on -------------
- canvas = window.FindElement('canvas').TKCanvas
-
- # ------------- Create line down center, the bats and ball -------------
- canvas.create_line(350, 0, 350, 400, fill='white')
- bat1 = pongbat(canvas, 'white')
- bat2 = pongbat2(canvas, 'white')
- ball1 = Ball(canvas, bat1, bat2, 'green')
-
- # ------------- Event Loop -------------
- while True:
- # ------------- Draw ball and bats -------------
- ball1.draw()
- bat1.draw()
- bat2.draw()
-
- # ------------- Read the form, get keypresses -------------
- event, values = window.Read(timeout=0)
- # ------------- If quit -------------
- if event is None or event == 'Quit':
- exit(69)
- # ------------- Keypresses -------------
- if event is not None:
- if event.startswith('Up'):
- bat2.up(2)
- elif event.startswith('Down'):
- bat2.down(2)
- elif event == 'w':
- bat1.up(1)
- elif event == 's':
- bat1.down(1)
-
- if ball1.checkwin():
- sg.Popup('Game Over', ball1.checkwin() + ' won!!')
- break
-
-
- # ------------- Bottom of loop, delay between animations -------------
- # time.sleep(.01)
- canvas.after(10)
-
-if __name__ == '__main__':
- pong()
-
-
-
diff --git a/DemoPrograms old/Demo_Pong_Multiple_Platforms.py b/DemoPrograms old/Demo_Pong_Multiple_Platforms.py
deleted file mode 100644
index 2e88127c..00000000
--- a/DemoPrograms old/Demo_Pong_Multiple_Platforms.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# !/usr/bin/env python
-# Based on work by - Siddharth Natamai
-# At the moment, this source file runs on TWO of the 4 PySimpleGUI ports with a third one coming soon (Qt).
-# import PySimpleGUIQt as sg # not quite working on Qt yet... needs Graph.Relocate fixed first
-# import PySimpleGUIWeb as sg
-import PySimpleGUI as sg
-import random
-
-GAMEPLAY_SIZE = (700, 400)
-BAT_SIZE = (20, 110)
-STARTING_BALL_POSITION = (327, 200)
-player_1_Starting_Score = 0
-player_2_Starting_Score = 0
-BALL_RADIUS = 12
-# BACKGROUND_COLOR = 'lightblue' # if running on PySimpleGUIWeb
-BACKGROUND_COLOR = 'black'
-# BALL_COLOR = 'black' # if running on PySimpleGUIWeb
-BALL_COLOR = 'green1'
-num_rounds = 0
-while num_rounds == 0:
- try:
- num_rounds = int(sg.PopupGetText('How many rounds would you like to play?'))
- except Exception as e:
- num_rounds = 0
-
-
-class Ball:
- def __init__(self, graph, bat_1, bat_2, colour):
- self.graph = graph # type: sg.Graph
- self.bat_1 = bat_1
- self.bat_2 = bat_2
- self.player_1_Score = player_1_Starting_Score
- self.player_2_Score = player_2_Starting_Score
- self.draw_P1 = None
- self.draw_P2 = None
- self.id = self.graph.DrawCircle(STARTING_BALL_POSITION, BALL_RADIUS, line_color=colour, fill_color=colour)
- self.curx, self.cury = STARTING_BALL_POSITION
- # self.graph.RelocateFigure(self.id, STARTING_BALL_POSITION[0], STARTING_BALL_POSITION[1])
- self.x = random.choice([-2.5, 2.5])
- self.y = -2.5
-
- def win_loss_check(self):
- winner = None
- if self.player_1_Score >= num_rounds:
- winner = 'Player Right Wins'
- if self.player_2_Score >= num_rounds:
- winner = 'Player Left Wins'
- return winner
-
- def update_player1_score(self, val):
- self.graph.DeleteFigure(self.draw_P1)
- self.draw_P1 = self.graph.DrawText(str(val), (170, 50), font=('Courier 60'), color='white')
-
- def update_player2_score(self, val):
- self.graph.DeleteFigure(self.draw_P2)
- self.draw_P2 = self.graph.DrawText(str(val), (550, 50), font=('courier 40'), color='white')
-
- def hit_bat(self, pos):
- bat_pos = (self.bat_1.curx, self.bat_1.cury)
- if pos[0] >= bat_pos[0] and pos[0] <= bat_pos[0]+BAT_SIZE[0]:
- if bat_pos[1] <= pos[1] <= bat_pos[1]+BAT_SIZE[1]:
- return True
- return False
-
- def hit_bat2(self, pos):
- bat_pos = (self.bat_2.curx, self.bat_2.cury)
- if pos[0] >= bat_pos[0] and pos[0] <= bat_pos[0]+BAT_SIZE[0]:
- if bat_pos[1] <= pos[1] <= bat_pos[1]+BAT_SIZE[1]:
- return True
- return False
-
-
- def draw(self):
- self.curx += self.x
- self.cury += self.y
- self.graph.RelocateFigure(self.id, self.curx, self.cury)
- if self.cury <= 0: # see if hit top or bottom of play area. If so, reverse y direction
- self.y = 4
- self.cury = 0
- if self.cury >= GAMEPLAY_SIZE[1]-BALL_RADIUS/2:
- self.y = -4
- self.cury = GAMEPLAY_SIZE[1]-BALL_RADIUS/2
- if self.curx <= 0: # see if beyond player
- self.player_1_Score += 1
- self.graph.RelocateFigure(self.id, STARTING_BALL_POSITION[0], STARTING_BALL_POSITION[1])
- self.x = 4
- self.update_player2_score(self.player_1_Score)
- self.curx, self.cury = STARTING_BALL_POSITION
- if self.curx >= GAMEPLAY_SIZE[0]:
- self.player_2_Score += 1
- self.graph.RelocateFigure(self.id, STARTING_BALL_POSITION[0], STARTING_BALL_POSITION[1])
- self.x = -4
- self.update_player1_score(self.player_2_Score)
- self.curx, self.cury = STARTING_BALL_POSITION
- if self.hit_bat((self.curx, self.cury)):
- self.x = 4
- if self.hit_bat2((self.curx, self.cury)):
- self.x = -4
-
-
-class PongBat():
- def __init__(self, graph:sg.Graph, colour, x, width=BAT_SIZE[0], height=BAT_SIZE[1]):
- self.graph = graph
- self.id = graph.DrawRectangle((x - width / 2, 200), (x + width / 2, 200 + height), fill_color=colour)
- self.y = 0
- self.x = x
- self.curx = x
- self.cury = height/2
-
- def up(self, amount):
- self.y = -amount
-
- def down(self, amount):
- self.y = amount
-
- @property
- def curr_pos(self):
- pos = self.cury
- return pos
-
- def draw(self):
- self.graph.RelocateFigure(self.id, self.curx, self.cury)
- if self.cury + self.y + BAT_SIZE[1] <= GAMEPLAY_SIZE[1] and self.cury + self.y + BAT_SIZE[1] >= 0:
- self.cury += self.y
- if self.cury <= 0:
- self.cury = 0
- self.y = 0
- if self.cury >= GAMEPLAY_SIZE[1]:
- self.cury = GAMEPLAY_SIZE[1]
- self.y = 0
-
-
-def pong():
- layout = [[sg.Graph(GAMEPLAY_SIZE, (0,GAMEPLAY_SIZE[1]), (GAMEPLAY_SIZE[0],0), background_color=BACKGROUND_COLOR, key='_GRAPH_')],
- [sg.T(''), sg.Button('Exit'), sg.T('Speed'), sg.Slider((0,20),default_value=10, orientation='h', enable_events=True, key='_SPEED_')]]
-
- window = sg.Window('Pong', layout, return_keyboard_events=True).Finalize()
-
- graph_elem = window.FindElement('_GRAPH_') # type: sg.Graph
-
- bat_1 = PongBat(graph_elem, 'red', 30)
- bat_2 = PongBat(graph_elem, 'blue', 670)
-
- ball_1 = Ball(graph_elem, bat_1, bat_2, 'green1')
- sleep_time = 10
-
- while True:
- ball_1.draw()
- bat_1.draw()
- bat_2.draw()
-
- event, values = window.Read(timeout=sleep_time) # type: str, str
- if event is None or event == 'Exit':
- break
- elif event.startswith('Up') or event.endswith('Up'):
- bat_2.up(5)
- elif event.startswith('Down') or event.endswith('Down'):
- bat_2.down(5)
- elif event == 'w':
- bat_1.up(5)
- elif event == 's':
- bat_1.down(5)
- elif event == '_SPEED_':
- sleep_time = int(values['_SPEED_'])
-
- if ball_1.win_loss_check():
- sg.Popup('Game Over', ball_1.win_loss_check() + ' won!!')
- break
- window.Close()
-
-if __name__ == '__main__':
- pong()
diff --git a/DemoPrograms old/Demo_Popup_Custom.py b/DemoPrograms old/Demo_Popup_Custom.py
deleted file mode 100644
index 718adb8f..00000000
--- a/DemoPrograms old/Demo_Popup_Custom.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-'''
- Use this code as a starting point for creating your own Popup functions.
- Rather than creating a long list of Popup high-level API calls, PySimpleGUI provides
- you with the tools to easily create your own. If you need more than what the standard PopupGetText and
- other calls provide, then it's time for you to graduate into making your own windows. Or, maybe you need
- another window that pops-up over your primary window. Whatever the need, don't hesitate to dive in
- and create your own Popup call.
-
- This example is for a DropDown / Combobox Popup. You provide it with a title, a message and the list
- of values to choose from. It mimics the return values of existing Popup calls (None if nothing was input)
-'''
-
-
-def PopupDropDown(title, text, values):
- window = sg.Window(title).Layout([[sg.Text(text)],
- [sg.DropDown(values, key='_DROP_')],
- [sg.OK(), sg.Cancel()]])
- event, values = window.Read()
- return None if event != 'OK' else values['_DROP_']
-
-
-# ----------------------- Calling your PopupDropDown function -----------------------
-
-values = ['choice {}'.format(x) for x in range(30)]
-
-print(PopupDropDown('My Title', 'Please make a selection', values))
diff --git a/DemoPrograms old/Demo_Popups.py b/DemoPrograms old/Demo_Popups.py
deleted file mode 100644
index a2435a82..00000000
--- a/DemoPrograms old/Demo_Popups.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-from PySimpleGUI import Print as print
-
-
-print('test')
-sg.PopupGetFile('Get file', save_as=True,file_types=(("ALL Files", "*.jpg"),))
-
-# Here, have some windows on me....
-[sg.PopupNoWait('No-wait Popup', location=(500+100*x,500)) for x in range(10)]
-
-answer = sg.PopupYesNo('Do not worry about all those open windows... they will disappear at the end', 'Are you OK with that?')
-
-if answer == 'No':
- sg.PopupCancel('OK, we will destroy those windows as soon as you close this window')
- sys.exit()
-
-sg.PopupNonBlocking('Your answer was',answer, location=(1000,600))
-
-text = sg.PopupGetText('This is a call to PopopGetText', location=(1000,200))
-sg.PopupGetFile('Get file')
-sg.PopupGetFolder('Get folder')
-
-
-sg.Popup('Simple popup')
-
-sg.PopupNoTitlebar('No titlebar')
-sg.PopupNoBorder('No border')
-sg.PopupNoFrame('No frame')
-sg.PopupCancel('Cancel')
-sg.PopupOKCancel('OK Cancel')
-sg.PopupAutoClose('Autoclose')
diff --git a/DemoPrograms old/Demo_Progress_Meters.py b/DemoPrograms old/Demo_Progress_Meters.py
deleted file mode 100644
index 0ffc4c8e..00000000
--- a/DemoPrograms old/Demo_Progress_Meters.py
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-from time import sleep
-
-
-"""
- Demonstration of simple and multiple OneLineProgressMeter's as well as the Progress Meter Element
-
- There are 4 demos
- 1. Manually updated progress bar
- 2. Custom progress bar built into your window, updated in a loop
- 3. OneLineProgressMeters, nested meters showing how 2 can be run at the same time.
- 4. An "iterable" style progress meter - a wrapper for OneLineProgressMeters
-
- If the software determined that a meter should be cancelled early,
- calling OneLineProgresMeterCancel(key) will cancel the meter with the matching key
-"""
-
-
-
-"""
- The simple case is that you want to add a single meter to your code. The one-line solution.
- This demo function shows 3 different OneLineProgressMeter tests
- 1. A horizontal with red and white bar colors
- 2. A vertical bar with default colors
- 3. A test showing 2 running at the same time
-"""
-
-def demo_one_line_progress_meter():
- # Display a progress meter. Allow user to break out of loop using cancel button
- for i in range(10000):
- if not sg.OneLineProgressMeter('My 1-line progress meter', i+1, 10000, 'meter key','MY MESSAGE1', 'MY MESSAGE 2', orientation='h', bar_color=('white', 'red')):
- print('Hit the break')
- break
- for i in range(10000):
- if not sg.OneLineProgressMeter('My 1-line progress meter', i+1, 10000, 'meter key', 'MY MESSAGE1', 'MY MESSAGE 2',orientation='v' ):
- print('Hit the break')
- break
-
- layout = [
- [sg.T('One-Line Progress Meter Demo', font=('Any 18'))],
- [sg.T('Outer Loop Count', size=(15,1), justification='r'), sg.In(default_text='100', size=(5,1), key='CountOuter', do_not_clear=True),
- sg.T('Delay'), sg.In(default_text='10', key='TimeOuter', size=(5,1), do_not_clear=True), sg.T('ms')],
- [sg.T('Inner Loop Count', size=(15,1), justification='r'), sg.In(default_text='100', size=(5,1), key='CountInner', do_not_clear=True) ,
- sg.T('Delay'), sg.In(default_text='10', key='TimeInner', size=(5,1), do_not_clear=True), sg.T('ms')],
- [sg.Button('Show', pad=((0,0), 3), bind_return_key=True), sg.T('me the meters!')]
- ]
-
- window = sg.Window('One-Line Progress Meter Demo').Layout(layout)
-
- while True:
- event, values = window.Read()
- if event is None:
- break
- if event == 'Show':
- max_outer = int(values['CountOuter'])
- max_inner = int(values['CountInner'])
- delay_inner = int(values['TimeInner'])
- delay_outer = int(values['TimeOuter'])
- for i in range(max_outer):
- if not sg.OneLineProgressMeter('Outer Loop', i+1, max_outer, 'outer'):
- break
- sleep(delay_outer/1000)
- for j in range(max_inner):
- if not sg.OneLineProgressMeter('Inner Loop', j+1, max_inner, 'inner'):
- break
- sleep(delay_inner/1000)
-
-
-'''
- Manually Updated Test
- Here is an example for when you want to "sprinkle" progress bar updates in multiple
- places within your source code and you're not running an event loop.
- Note that UpdateBar is special compared to other Update methods. It also refreshes
- the containing window and checks for window closure events
- The sleep calls are here only for demonstration purposes. You should NOT be adding
- these kinds of sleeps to a GUI based program normally.
-'''
-
-def manually_updated_meter_test():
- # layout the form
- layout = [[sg.Text('This meter is manually updated 4 times')],
- [sg.ProgressBar(max_value=10, orientation='h', size=(20,20), key='progress')]]
-
- # create the form`
- window = sg.Window('Custom Progress Meter', layout).Finalize() # must finalize since not running an event loop
-
- progress_bar = window.FindElement('progress') # Get the element to make updating easier
-
- # -------------------- Your Program Code --------------------
- # Spot #1 to indicate progress
- progress_bar.UpdateBar(1) # show 10% complete
- sleep(2)
-
- # more of your code.... perhaps pages and pages of code.
- # Spot #2 to indicate progress
- progress_bar.UpdateBar(2) # show 20% complete
- sleep(2)
-
- # more of your code.... perhaps pages and pages of code.
- # Spot #3 to indicate progress
- progress_bar.UpdateBar(6) # show 60% complete
- sleep(2)
-
- # more of your code.... perhaps pages and pages of code.
- # Spot #4 to indicate progress
- progress_bar.UpdateBar(9) # show 90% complete
- sleep(2)
- window.Close()
-
-
-'''
- This function shows how to create a custom window with a custom progress bar and then
- how to update the bar to indicate progress is being made
-'''
-
-def custom_meter_example():
- # layout the form
- layout = [[sg.Text('A typical custom progress meter')],
- [sg.ProgressBar(1, orientation='h', size=(20,20), key='progress')],
- [sg.Cancel()]]
-
- # create the form`
- window = sg.Window('Custom Progress Meter').Layout(layout)
- progress_bar = window.FindElement('progress')
- # loop that would normally do something useful
- for i in range(10000):
- # check to see if the cancel button was clicked and exit loop if clicked
- event, values = window.Read(timeout=0)
- if event == 'Cancel' or event == None:
- break
- # update bar with loop value +1 so that bar eventually reaches the maximum
- progress_bar.UpdateBar(i+1, 10000)
- # done with loop... need to destroy the window as it's still open
- window.Close()
-
-
-'''
- A Wrapper for OneLineProgressMeter that combines your iterable with a progress meter into a single interface. Two functions are provided
- progess_bar - The basic wrapper
- progress_bar_range - A "convienence function" if you wanted to specify like a range
-'''
-
-
-def progress_bar(key, iterable, *args, title='', **kwargs):
- """
- Takes your iterable and adds a progress meter onto it
- :param key: Progress Meter key
- :param iterable: your iterable
- :param args: To be shown in one line progress meter
- :param title: Title shown in meter window
- :param kwargs: Other arguments to pass to OneLineProgressMeter
- :return:
- """
- sg.OneLineProgressMeter(title, 0, len(iterable), key, *args, **kwargs)
- for i, val in enumerate(iterable):
- yield val
- if not sg.OneLineProgressMeter(title, i+1, len(iterable), key, *args, **kwargs):
- break
-
-
-def progress_bar_range(key, start, stop=None, step=1, *args, **kwargs):
- """
- Acts like the range() function but with a progress meter built-into it
- :param key: progess meter's key
- :param start: low end of the range
- :param stop: Uppder end of range
- :param step:
- :param args:
- :param kwargs:
- :return:
- """
- return progress_bar(key, range(start, stop, step), *args, **kwargs)
-
-
-# -------------------- Demo Usage --------------------
-def demo_iterable_progress_bar():
- my_list = list(range(1000)) # start with a list of 100 integers as the user's list
-
- # first form takes an iterable and a key and will return a value from your iterable
- # and bump the progress meter at the same time
- for value in progress_bar('bar1', my_list, ):
- # do something useful with value, a value from your list.
- print(value)
-
- # Since the progress_bar is an iterator, you can use it within a list comprehension
- my_list = [x for x in progress_bar('bar1', my_list)]
-
-
-
-demo_iterable_progress_bar()
-manually_updated_meter_test()
-custom_meter_example()
-demo_one_line_progress_meter()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_PyGame_Integration.py b/DemoPrograms old/Demo_PyGame_Integration.py
deleted file mode 100644
index dae260ff..00000000
--- a/DemoPrograms old/Demo_PyGame_Integration.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import pygame
-import PySimpleGUI as sg
-import os
-
-"""
- Demo of integrating PyGame with PySimpleGUI, the tkinter version
- A similar technique may be possible with WxPython
- Only works on windows from what I've read
-"""
-# --------------------- PySimpleGUI window layout and creation --------------------
-layout = [[sg.T('Test of PySimpleGUI with PyGame')],
- [sg.Graph((500,500), (0,0), (500,500), background_color='lightblue', key='_GRAPH_' )],
- [sg.B('Draw'), sg.Exit()]]
-
-window = sg.Window('PySimpleGUI + PyGame', layout).Finalize()
-graph = window.Element('_GRAPH_')
-
-# -------------- Magic code to integrate PyGame with tkinter -------
-embed = graph.TKCanvas
-os.environ['SDL_WINDOWID'] = str(embed.winfo_id())
-os.environ['SDL_VIDEODRIVER'] = 'windib'
-
-# ----------------------------- PyGame Code -----------------------------
-
-screen = pygame.display.set_mode((500,500))
-screen.fill(pygame.Color(255,255,255))
-
-pygame.display.init()
-pygame.display.update()
-
-while True:
- event, values = window.Read(timeout=10)
- if event in (None, 'Exit'):
- break
- elif event == 'Draw':
- pygame.draw.circle(screen, (0, 0, 0), (250, 250), 125)
- pygame.display.update()
-
-window.Close()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_PyGame_Snake_Game.py b/DemoPrograms old/Demo_PyGame_Snake_Game.py
deleted file mode 100644
index 6d1485e7..00000000
--- a/DemoPrograms old/Demo_PyGame_Snake_Game.py
+++ /dev/null
@@ -1,138 +0,0 @@
-import pygame
-import PySimpleGUI as sg
-import os
-
-"""
- Demo - Simple Snake Game using PyGame and PySimpleGUI
- This demo may not be fully functional in terms of getting the coordinate
- systems right or other problems due to a lack of understanding of PyGame
- The purpose of the demo is to show one way of adding a PyGame window into your PySimpleGUI window
- Note, you must click on the game area in order for PyGame to get keyboard strokes, etc.
- Tried using set_focus to switch to the PyGame canvas but still needed to click on game area
-"""
-
-# --- Globals ---
-# Colors
-BLACK = (0, 0, 0)
-WHITE = (255, 255, 255)
-
-# Set the width and height of each snake segment
-segment_width = 15
-segment_height = 15
-# Margin between each segment
-segment_margin = 3
-
-# Set initial speed
-x_change = segment_width + segment_margin
-y_change = 0
-
-
-class Segment(pygame.sprite.Sprite):
- """ Class to represent one segment of the snake. """
- # -- Methods
- # Constructor function
- def __init__(self, x, y):
- # Call the parent's constructor
- super().__init__()
-
- # Set height, width
- self.image = pygame.Surface([segment_width, segment_height])
- self.image.fill(WHITE)
-
- # Make our top-left corner the passed-in location.
- self.rect = self.image.get_rect()
- self.rect.x = x
- self.rect.y = y
-
-# --------------------------- GUI Setup & Create Window -------------------------------
-
-layout = [[sg.T('Snake Game - PySimpleGUI + PyGame')],
- [sg.Graph((800,600), (0,0), (800,600), background_color='lightblue', key='_GRAPH_')],
- [sg.Exit()]]
-
-window = sg.Window('Snake Game using PySimpleGUI and PyGame', layout).Finalize()
-
-# ------------------------ Do the magic that integrates PyGame and Graph Element ------------------
-graph = window.Element('_GRAPH_') # type: sg.Graph
-embed = graph.TKCanvas
-os.environ['SDL_WINDOWID'] = str(embed.winfo_id())
-os.environ['SDL_VIDEODRIVER'] = 'windib'
-
-# ----------------------------- PyGame Code -----------------------------
-# Call this function so the Pygame library can initialize itself
-# pygame.init()
-screen = pygame.display.set_mode((800,600))
-screen.fill(pygame.Color(255,255,255))
-
-pygame.display.init()
-pygame.display.update()
-
-# Set the title of the window
-pygame.display.set_caption('Snake Example')
-
-allspriteslist = pygame.sprite.Group()
-
-# Create an initial snake
-snake_segments = []
-for i in range(15):
- x = 250 - (segment_width + segment_margin) * i
- y = 30
- segment = Segment(x, y)
- snake_segments.append(segment)
- allspriteslist.add(segment)
-
-clock = pygame.time.Clock()
-
-while True:
- event, values = window.Read(timeout=10)
- if event in (None, 'Exit'):
- break
- pygame.display.update()
-
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- break
- # Set the speed based on the key pressed
- # We want the speed to be enough that we move a full
- # segment, plus the margin.
- if event.type == pygame.KEYDOWN:
- if event.key == pygame.K_LEFT:
- x_change = (segment_width + segment_margin) * -1
- y_change = 0
- if event.key == pygame.K_RIGHT:
- x_change = (segment_width + segment_margin)
- y_change = 0
- if event.key == pygame.K_UP:
- x_change = 0
- y_change = (segment_height + segment_margin) * -1
- if event.key == pygame.K_DOWN:
- x_change = 0
- y_change = (segment_height + segment_margin)
-
- # Get rid of last segment of the snake
- # .pop() command removes last item in list
- old_segment = snake_segments.pop()
- allspriteslist.remove(old_segment)
-
- # Figure out where new segment will be
- x = snake_segments[0].rect.x + x_change
- y = snake_segments[0].rect.y + y_change
- segment = Segment(x, y)
-
- # Insert new segment into the list
- snake_segments.insert(0, segment)
- allspriteslist.add(segment)
-
- # -- Draw everything
- # Clear screen
- screen.fill(BLACK)
-
- allspriteslist.draw(screen)
-
- # Flip screen
- pygame.display.flip()
-
- # Pause
- clock.tick(5)
-
-window.Close()
diff --git a/DemoPrograms old/Demo_Pyplot_Bar_Chart.py b/DemoPrograms old/Demo_Pyplot_Bar_Chart.py
deleted file mode 100644
index 34265b3d..00000000
--- a/DemoPrograms old/Demo_Pyplot_Bar_Chart.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env python
-import sys
-
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-import matplotlib
-
-matplotlib.use('TkAgg')
-from matplotlib.backends.backend_tkagg import FigureCanvasAgg
-import matplotlib.backends.tkagg as tkagg
-import tkinter as Tk
-
-"""
-Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window.
-
-Paste your Pyplot code into the section marked below.
-
-Do all of your plotting as you normally would, but do NOT call plt.show().
-Stop just short of calling plt.show() and let the GUI do the rest.
-
-The remainder of the program will convert your plot and display it in the GUI.
-If you want to change the GUI, make changes to the GUI portion marked below.
-
-"""
-
-# ------------------------------- PASTE YOUR MATPLOTLIB CODE HERE -------------------------------
-
-import numpy as np
-import matplotlib.pyplot as plt
-
-values_to_plot = (20, 35, 30, 35, 27)
-ind = np.arange(len(values_to_plot))
-width = 0.4
-
-p1 = plt.bar(ind, values_to_plot, width)
-
-plt.ylabel('Y-Axis Values')
-plt.title('Plot Title')
-plt.xticks(ind, ('Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'))
-plt.yticks(np.arange(0, 81, 10))
-plt.legend((p1[0],), ('Data Group 1',))
-
-
-# ------------------------------- END OF YOUR MATPLOTLIB CODE -------------------------------
-
-# ------------------------------- Beginning of Matplotlib helper code -----------------------
-
-
-def draw_figure(canvas, figure, loc=(0, 0)):
- """ Draw a matplotlib figure onto a Tk canvas
-
- loc: location of top-left corner of figure on canvas in pixels.
-
- Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
- """
- figure_canvas_agg = FigureCanvasAgg(figure)
- figure_canvas_agg.draw()
- figure_x, figure_y, figure_w, figure_h = figure.bbox.bounds
- figure_w, figure_h = int(figure_w), int(figure_h)
- photo = Tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)
- canvas.create_image(loc[0] + figure_w / 2, loc[1] + figure_h / 2, image=photo)
- tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
- return photo
-
-
-# ------------------------------- Beginning of GUI CODE -------------------------------
-
-fig = plt.gcf() # if using Pyplot then get the figure from the plot
-figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
-
-# define the window layout
-layout = [[sg.Text('Plot test', font='Any 18')],
- [sg.Canvas(size=(figure_w, figure_h), key='canvas')],
- [sg.OK(pad=((figure_w / 2, 0), 3), size=(4, 2))]]
-
-# create the form and show it without the plot
-window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', force_toplevel=True).Layout(
- layout).Finalize()
-
-# add the plot to the window
-fig_photo = draw_figure(window.FindElement('canvas').TKCanvas, fig)
-
-# show it all again and get buttons
-event, values = window.Read()
diff --git a/DemoPrograms old/Demo_Pyploy_Bar_Chart2.py b/DemoPrograms old/Demo_Pyploy_Bar_Chart2.py
deleted file mode 100644
index fa02b35f..00000000
--- a/DemoPrograms old/Demo_Pyploy_Bar_Chart2.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-import matplotlib
-matplotlib.use('TkAgg')
-from matplotlib.backends.backend_tkagg import FigureCanvasAgg
-import matplotlib.backends.tkagg as tkagg
-import tkinter as Tk
-
-"""
-Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window.
-
-Paste your Pyplot code into the section marked below.
-
-Do all of your plotting as you normally would, but do NOT call plt.show().
-Stop just short of calling plt.show() and let the GUI do the rest.
-
-The remainder of the program will convert your plot and display it in the GUI.
-If you want to change the GUI, make changes to the GUI portion marked below.
-
-"""
-
-#------------------------------- PASTE YOUR MATPLOTLIB CODE HERE -------------------------------
-import matplotlib.pyplot as plt
-import numpy as np
-label = ['Adventure', 'Action', 'Drama', 'Comedy', 'Thriller/Suspense', 'Horror', 'Romantic Comedy', 'Musical',
- 'Documentary', 'Black Comedy', 'Western', 'Concert/Performance', 'Multiple Genres', 'Reality']
-no_movies = [941, 854, 4595, 2125, 942, 509, 548, 149, 1952, 161, 64, 61, 35, 5]
-
-index = np.arange(len(label))
-plt.bar(index, no_movies)
-plt.xlabel('Genre', fontsize=5)
-plt.ylabel('No of Movies', fontsize=5)
-plt.xticks(index, label, fontsize=5, rotation=30)
-plt.title('Market Share for Each Genre 1995-2017')
-
-#------------------------------- END OF YOUR MATPLOTLIB CODE -------------------------------
-
-#------------------------------- Beginning of Matplotlib helper code -----------------------
-
-
-def draw_figure(canvas, figure, loc=(0, 0)):
- """ Draw a matplotlib figure onto a Tk canvas
-
- loc: location of top-left corner of figure on canvas in pixels.
-
- Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
- """
- figure_canvas_agg = FigureCanvasAgg(figure)
- figure_canvas_agg.draw()
- figure_x, figure_y, figure_w, figure_h = figure.bbox.bounds
- figure_w, figure_h = int(figure_w), int(figure_h)
- photo = Tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)
- canvas.create_image(loc[0] + figure_w/2, loc[1] + figure_h/2, image=photo)
- tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
- return photo
-
-#------------------------------- Beginning of GUI CODE -------------------------------
-
-fig = plt.gcf() # if using Pyplot then get the figure from the plot
-figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
-
-# define the window layout
-layout = [[sg.Text('Plot test', font='Any 18')],
- [sg.Canvas(size=(figure_w, figure_h), key='canvas')],
- [sg.OK(pad=((figure_w / 2, 0), 3), size=(4, 2))]]
-
-# create the form and show it without the plot
-window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', force_toplevel=True).Layout(layout).Finalize()
-
-# add the plot to the window
-fig_photo = draw_figure(window.FindElement('canvas').TKCanvas, fig)
-
-# show it all again and get buttons
-event, values = window.Read()
diff --git a/DemoPrograms old/Demo_Script_Launcher.py b/DemoPrograms old/Demo_Script_Launcher.py
deleted file mode 100644
index 7dff6a4f..00000000
--- a/DemoPrograms old/Demo_Script_Launcher.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import glob
-import ntpath
-import subprocess
-
-LOCATION_OF_YOUR_SCRIPTS = ''
-
-# Execute the command. Will not see the output from the command until it completes.
-def execute_command_blocking(command, *args):
- expanded_args = []
- for a in args:
- expanded_args.append(a)
- # expanded_args += a
- try:
- sp = subprocess.Popen([command,expanded_args], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = sp.communicate()
- if out:
- print(out.decode("utf-8"))
- if err:
- print(err.decode("utf-8"))
- except:
- out = ''
- return out
-
-# Executes command and immediately returns. Will not see anything the script outputs
-def execute_command_nonblocking(command, *args):
- expanded_args = []
- for a in args:
- expanded_args += a
- try:
- sp = subprocess.Popen([command,expanded_args], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- except: pass
-
-def Launcher2():
- sg.ChangeLookAndFeel('GreenTan')
- window = sg.Window('Script launcher')
-
- filelist = glob.glob(LOCATION_OF_YOUR_SCRIPTS+'*.py')
- namesonly = []
- for file in filelist:
- namesonly.append(ntpath.basename(file))
-
- layout = [
- [sg.Listbox(values=namesonly, size=(30, 19), select_mode=sg.SELECT_MODE_EXTENDED, key='demolist'), sg.Output(size=(88, 20), font='Courier 10')],
- [sg.Checkbox('Wait for program to complete', default=False, key='wait')],
- [sg.Button('Run'), sg.Button('Shortcut 1'), sg.Button('Fav Program'), sg.Button('EXIT')],
- ]
-
- window.Layout(layout)
-
- # ---===--- Loop taking in user input --- #
- while True:
- event, values = window.Read()
- if event in ('EXIT', None):
- break # exit button clicked
- if event in ('Shortcut 1', 'Fav Program'):
- print('Quickly launch your favorite programs using these shortcuts')
- print('Or copy files to your github folder. Or anything else you type on the command line')
- # copyfile(source, dest)
- elif event == 'Run':
- for index, file in enumerate(values['demolist']):
- print('Launching %s'%file)
- window.Refresh() # make the print appear immediately
- if values['wait']:
- execute_command_blocking(LOCATION_OF_YOUR_SCRIPTS + file)
- else:
- execute_command_nonblocking(LOCATION_OF_YOUR_SCRIPTS + file)
-
-
-if __name__ == '__main__':
- Launcher2()
-
diff --git a/DemoPrograms old/Demo_Script_Launcher_Realtime_Output.py b/DemoPrograms old/Demo_Script_Launcher_Realtime_Output.py
deleted file mode 100644
index 12b54c6b..00000000
--- a/DemoPrograms old/Demo_Script_Launcher_Realtime_Output.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import subprocess
-import sys
-import PySimpleGUI as sg
-
-"""
- Demo Program - Realtime output of a shell command in the window
- Shows how you can run a long-running subprocess and have the output
- be displayed in realtime in the window.
-"""
-
-def main():
- layout = [ [sg.Text('Enter the command you wish to run')],
- [sg.Input(key='_IN_')],
- [sg.Output(size=(60,15))],
- [sg.Button('Run'), sg.Button('Exit')] ]
-
- window = sg.Window('Realtime Shell Command Output', layout)
-
- while True: # Event Loop
- event, values = window.Read()
- # print(event, values)
- if event in (None, 'Exit'):
- break
- elif event == 'Run':
- runCommand(cmd=values['_IN_'], window=window)
- window.Close()
-
-
-def runCommand(cmd, timeout=None, window=None):
- """ run shell command
- @param cmd: command to execute
- @param timeout: timeout for command execution
- @param window: the PySimpleGUI window that the output is going to (needed to do refresh on)
- @return: (return code from command, command output)
- """
- p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- output = ''
- for line in p.stdout:
- line = line.decode(errors='replace' if (sys.version_info) < (3, 5) else 'backslashreplace').rstrip()
- output += line
- print(line)
- window.Refresh() if window else None # yes, a 1-line if, so shoot me
-
- retval = p.wait(timeout)
- return (retval, output)
-
-
-main()
diff --git a/DemoPrograms old/Demo_Script_Parameters.py b/DemoPrograms old/Demo_Script_Parameters.py
deleted file mode 100644
index 82fdda64..00000000
--- a/DemoPrograms old/Demo_Script_Parameters.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-
-'''
-Quickly add a GUI to your script!
-
-This simple script shows a 1-line-GUI addition to a typical Python command line script.
-
-Previously this script accepted 1 parameter on the command line. When executed, that
-parameter is read into the variable fname.
-
-The 1-line-GUI shows a form that allows the user to browse to find the filename. The GUI
-stores the result in the variable fname, just like the command line parsing did.
-'''
-
-if len(sys.argv) == 1:
- event, (fname,) = sg.Window('My Script').Layout([[sg.T('Document to open')],
- [sg.In(), sg.FileBrowse()],
- [sg.CloseButton('Open'), sg.CloseButton('Cancel')]]).Read()
-else:
- fname = sys.argv[1]
-
-if not fname:
- sg.Popup("Cancel", "No filename supplied")
- raise SystemExit("Cancelling: no filename supplied")
diff --git a/DemoPrograms old/Demo_Sort_Visualizer.py b/DemoPrograms old/Demo_Sort_Visualizer.py
deleted file mode 100644
index 1f07a1b9..00000000
--- a/DemoPrograms old/Demo_Sort_Visualizer.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import PySimpleGUI as sg
-import random
-# ------- Sort visualizer. Displays bar chart representing list items -------
-BAR_SPACING, BAR_WIDTH, EDGE_OFFSET = 11, 10, 3
-DATA_SIZE = GRAPH_SIZE = (700,500) # width, height of the graph portion
-
-def bubble_sort(arr):
- def swap(i, j):
- arr[i], arr[j] = arr[j], arr[i]
- n = len(arr)
- swapped = True
- x = -1
- while swapped:
- swapped = False
- x = x + 1
- for i in range(1, n - x):
- if arr[i - 1] > arr[i]:
- swap(i - 1, i)
- swapped = True
- yield arr
-
-def draw_bars(graph, items): # draws all the bars for all values across screen
- # type: (sg.Graph, List)->None
- for i, item in enumerate(items):
- graph.draw_rectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, item),
- bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='#76506d')
-
-def main():
- sg.change_look_and_feel('LightGreen')
- # Make list to sort
- num_bars = DATA_SIZE[0]//(BAR_WIDTH+1)
- list_to_sort = [DATA_SIZE[1]//num_bars*i for i in range(1,num_bars)]
- random.shuffle(list_to_sort)
-
- # define window layout
- graph = sg.Graph(GRAPH_SIZE, (0,0), DATA_SIZE)
- layout = [[graph],
- [sg.T('Speed Faster'), sg.Slider((0,20), orientation='h', default_value=10, key='-SPEED-'), sg.T('Slower')]]
-
- window = sg.Window('Sort Demonstration', layout, finalize=True)
- draw_bars(graph, list_to_sort) # draw the initial window's bars
-
- sg.popup('Click OK to begin Bubblesort') # Wait for user to start it up
- bsort = bubble_sort(list_to_sort) # get an iterator for the sort
- timeout=10 # start with 10ms delays between draws
- while True: # ----- The event loop -----
- event, values = window.read(timeout=timeout)
- if event is None:
- break
- try:
- partially_sorted_list = bsort.__next__()
- except:
- sg.popup('Sorting done!')
- break
- graph.Erase()
- draw_bars(graph, partially_sorted_list)
- timeout = int(values['-SPEED-'])
- window.close()
-main()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Spinner_Compound_Element.py b/DemoPrograms old/Demo_Spinner_Compound_Element.py
deleted file mode 100644
index dc9bb246..00000000
--- a/DemoPrograms old/Demo_Spinner_Compound_Element.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-"""
- Demo of how to combine elements into your own custom element
-"""
-
-sg.SetOptions(element_padding=(0,0))
-# sg.ChangeLookAndFeel('Dark')
-# --- Define our "Big-Button-Spinner" compound element. Has 2 buttons and an input field --- #
-NewSpinner = [sg.Button('-', size=(2,1), font='Any 12'),
- sg.In('0', size=(2,1), font='Any 14', justification='r', key='spin'),
- sg.Button('+', size=(2,1), font='Any 12')]
-# --- Define Window --- #
-layout = [
- [sg.Text('Spinner simulation')],
- NewSpinner,
- [sg.T('')],
- [sg.Ok()]
- ]
-
-window = sg.Window('Spinner simulation').Layout(layout)
-
-# --- Event Loop --- #
-counter = 0
-while True:
- event, values = window.Read()
-
- if event == 'Ok' or event is None: # be nice to your user, always have an exit from your form
- break
-
- # --- do spinner stuff --- #
- counter += 1 if event == '+' else -1 if event == '-' else 0
- window.FindElement('spin').Update(counter)
diff --git a/DemoPrograms old/Demo_Stdout.py b/DemoPrograms old/Demo_Stdout.py
deleted file mode 100644
index 1ad90090..00000000
--- a/DemoPrograms old/Demo_Stdout.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-"""
- Demo program that reroutes stdout and stderr.
- Type something in the input box and click Print
- Whatever you typed is "printed" using a standard print statement
- Use the Output Element in your window layout to reroute stdout
- You will see the output of the print in the Output Element in the center of the window
-
-"""
-
-
-layout = [
- [sg.Text('Type something in input field and click print')],
- [sg.In()],
- [sg.Output()],
- [sg.Button('Print')]
- ]
-
-window = sg.Window('Reroute stdout').Layout(layout)
-
-while True: # Event Loop
- event, values = window.Read()
- if event is None:
- break
- print('You typed: ', values[0])
diff --git a/DemoPrograms old/Demo_Super_Simple_Form.py b/DemoPrograms old/Demo_Super_Simple_Form.py
deleted file mode 100644
index 48bf949a..00000000
--- a/DemoPrograms old/Demo_Super_Simple_Form.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import PySimpleGUI as sg
-
-layout = [[sg.Text('Please enter your Name, Address, Phone')],
- [sg.Text('Name', size=(10,1)), sg.InputText(key='-NAME-')],
- [sg.Text('Address', size=(10,1)), sg.InputText(key='-ADDRESS-')],
- [sg.Text('Phone', size=(10,1)), sg.InputText(key='-PHONE-')],
- [sg.Button('Submit'), sg.Button('Cancel')]]
-
-window = sg.Window('Simple Data Entry Window', layout)
-event, values = window.read()
-print(event, values['-NAME-'], values['-ADDRESS-'], values['-PHONE-'])
diff --git a/DemoPrograms old/Demo_Table_CSV.py b/DemoPrograms old/Demo_Table_CSV.py
deleted file mode 100644
index 0662e83d..00000000
--- a/DemoPrograms old/Demo_Table_CSV.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import csv
-
-def table_example():
- filename = sg.PopupGetFile('filename to open', no_window=True, file_types=(("CSV Files","*.csv"),))
- # --- populate table with file contents --- #
- if filename == '':
- sys.exit(69)
- data = []
- header_list = []
- button = sg.PopupYesNo('Does this file have column names already?')
- if filename is not None:
- with open(filename, "r") as infile:
- reader = csv.reader(infile)
- if button == 'Yes':
- header_list = next(reader)
- try:
- data = list(reader) # read everything else into a list of rows
- if button == 'No':
- header_list = ['column' + str(x) for x in range(len(data[0]))]
- except:
- sg.PopupError('Error reading file')
- sys.exit(69)
- sg.SetOptions(element_padding=(0, 0))
-
- layout = [[sg.Table(values=data,
- headings=header_list,
- max_col_width=25,
- auto_size_columns=True,
- justification='right',
- alternating_row_color='lightblue',
- num_rows=min(len(data), 20))]]
-
-
- window = sg.Window('Table', grab_anywhere=False).Layout(layout)
- event, values = window.Read()
-
- sys.exit(69)
-
-table_example()
diff --git a/DemoPrograms old/Demo_Table_Element.py b/DemoPrograms old/Demo_Table_Element.py
deleted file mode 100644
index 4a2eac26..00000000
--- a/DemoPrograms old/Demo_Table_Element.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-import sys
-
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import random
-import string
-
-
-# ------------------ Create a fake table ------------------
-class Fake():
- @classmethod
- def word(self):
- return ''.join(random.choice(string.ascii_lowercase) for i in range(10))
-
- @classmethod
- def number(self, max=1000):
- return random.randint(0,max)
-
-
-def make_table(num_rows, num_cols):
- data = [[j for j in range(num_cols)] for i in range(num_rows)]
- data[0] = [Fake.word() for _ in range(num_cols)]
- for i in range(1, num_rows):
- data[i] = [Fake.word(), *[Fake.number() for i in range(num_cols - 1)]]
- return data
-
-data = make_table(num_rows=15, num_cols=6)
-# sg.SetOptions(element_padding=(0,0))
-headings = [data[0][x] for x in range(len(data[0]))]
-
-layout = [[sg.Table(values=data[1:][:], headings=headings, max_col_width=25, background_color='lightblue',
- auto_size_columns=True, display_row_numbers=True, justification='right', num_rows=20, alternating_row_color='blue', key='_table_', tooltip='This is a table')],
- [sg.Button('Read'), sg.Button('Double'), sg.Button('Update')],
- [sg.T('Read = read which rows are selected')],[sg.T('Double = double the amount of data in the table')]]
-
-window = sg.Window('Table', grab_anywhere=False, resizable=True).Layout(layout)
-
-while True:
- event, values = window.Read()
- print(event, values)
- if event is None:
- break
- if event == 'Double':
- for i in range(len(data)):
- data.append(data[i])
- window.FindElement('_table_').Update(values = data)
- elif event == 'Update':
- window.FindElement('_table_').Update( row_colors=((8,'white', 'red'), (9,'black')))
-
- # sg.Popup(event, values)
- # print(event, values)
-window.Close()
-sys.exit(69)
diff --git a/DemoPrograms old/Demo_Table_Pandas.py b/DemoPrograms old/Demo_Table_Pandas.py
deleted file mode 100644
index bc192046..00000000
--- a/DemoPrograms old/Demo_Table_Pandas.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import pandas as pd
-
-
-def table_example():
- sg.SetOptions(auto_size_buttons=True)
- filename = sg.PopupGetFile('filename to open', no_window=True, file_types=(("CSV Files", "*.csv"),))
- # --- populate table with file contents --- #
- if filename == '':
- sys.exit(69)
- data = []
- header_list = []
- button = sg.PopupYesNo('Does this file have column names already?')
- if filename is not None:
- try:
- df = pd.read_csv(filename, sep=',', engine='python', header=None) # Header=None means you directly pass the columns names to the dataframe
- data = df.values.tolist() # read everything else into a list of rows
- if button == 'Yes': # Press if you named your columns in the csv
- header_list = df.iloc[0].tolist() # Uses the first row (which should be column names) as columns names
- data = df[1:].values.tolist() # Drops the first row in the table (otherwise the header names and the first row will be the same)
- elif button == 'No': # Press if you didn't name the columns in the csv
- header_list = ['column' + str(x) for x in range(len(data[0]))] # Creates columns names for each column ('column0', 'column1', etc)
- except:
- sg.PopupError('Error reading file')
- sys.exit(69)
-
- layout = [[sg.Table(values=data, headings=header_list, display_row_numbers=True,
- auto_size_columns=False, num_rows=min(25,len(data)))]]
-
- window = sg.Window('Table', grab_anywhere=False)
- event, values = window.Layout(layout).Read()
-
- sys.exit(69)
-
-table_example()
diff --git a/DemoPrograms old/Demo_Table_Simulation.py b/DemoPrograms old/Demo_Table_Simulation.py
deleted file mode 100644
index 32018c5a..00000000
--- a/DemoPrograms old/Demo_Table_Simulation.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import csv
-
-
-def TableSimulation():
- """
- Display data in a table format
- """
- sg.SetOptions(element_padding=(0,0))
-
- menu_def = [['File', ['Open', 'Save', 'Exit']],
- ['Edit', ['Paste', ['Special', 'Normal',], 'Undo'],],
- ['Help', 'About...'],]
-
- columm_layout = [[]]
-
- MAX_ROWS = 20
- MAX_COL = 10
- for i in range(MAX_ROWS):
- inputs = [sg.T('{}'.format(i), size=(4,1), justification='right')] + [sg.In(size=(10, 1), pad=(1, 1), justification='right', key=(i,j), do_not_clear=True) for j in range(MAX_COL)]
- columm_layout.append(inputs)
-
- layout = [ [sg.Menu(menu_def)],
- [sg.T('Table Using Combos and Input Elements', font='Any 18')],
- [sg.T('Type in a row, column and value. The form will update the values in realtime as you type'),
- sg.In(key='inputrow', justification='right', size=(8,1), pad=(1,1), do_not_clear=True),
- sg.In(key='inputcol', size=(8,1), pad=(1,1), justification='right', do_not_clear=True),
- sg.In(key='value', size=(8,1), pad=(1,1), justification='right', do_not_clear=True)],
- [sg.Column(columm_layout, size=(800,600), scrollable=True)] ]
-
- window = sg.Window('Table', return_keyboard_events=True).Layout(layout)
-
- while True:
- event, values = window.Read()
- # --- Process buttons --- #
- if event is None or event == 'Exit':
- break
- elif event == 'About...':
- sg.Popup('Demo of table capabilities')
- elif event == 'Open':
- filename = sg.PopupGetFile('filename to open', no_window=True, file_types=(("CSV Files","*.csv"),))
- # --- populate table with file contents --- #
- if filename is not None:
- with open(filename, "r") as infile:
- reader = csv.reader(infile)
- try:
- data = list(reader) # read everything else into a list of rows
- except:
- sg.PopupError('Error reading file')
- continue
- # clear the table
- [window.FindElement((i,j)).Update('') for j in range(MAX_COL) for i in range(MAX_ROWS)]
-
- for i, row in enumerate(data):
- for j, item in enumerate(row):
- location = (i,j)
- try: # try the best we can at reading and filling the table
- target_element = window.FindElement(location)
- new_value = item
- if target_element is not None and new_value != '':
- target_element.Update(new_value)
- except:
- pass
-
- # if a valid table location entered, change that location's value
- try:
- location = (int(values['inputrow']), int(values['inputcol']))
- target_element = window.FindElement(location)
- new_value = values['value']
- if target_element is not None and new_value != '':
- target_element.Update(new_value)
- except:
- pass
-
-TableSimulation()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Tabs.py b/DemoPrograms old/Demo_Tabs.py
deleted file mode 100644
index 733cb334..00000000
--- a/DemoPrograms old/Demo_Tabs.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-sg.SetOptions(background_color='cornsilk4', element_background_color='cornsilk2', input_elements_background_color='cornsilk2')
-
-tab1_layout = [[sg.T('This is inside tab 1', background_color='darkslateblue', text_color='white')],
- [sg.In(key='_in0_')]]
-
-tab2_layout = [[sg.T('This is inside tab 2', background_color='tan1')],
- [sg.In(key='_in2_')]]
-
-
-tab3_layout = [[sg.T('This is inside tab 3')],
- [sg.In(key='_in2_')]]
-
-tab4_layout = [[sg.T('This is inside tab 4', background_color='darkseagreen')],
- [sg.In(key='_in3_')]]
-
-tab5_layout = [[sg.T('This is inside tab 5')],
- [sg.In(key='_in4_')]]
-
-
-layout = [[sg.TabGroup([[sg.Tab('Tab 1', tab1_layout, background_color='darkslateblue', key='_mykey_'),
- sg.Tab('Tab 2', tab2_layout, background_color='tan1'),
- sg.Tab('Tab 3', tab3_layout)]],
- key='_group2_', title_color='red',
- selected_title_color='green', tab_location='right'),
- sg.TabGroup([[sg.Tab('Tab 4', tab4_layout,background_color='darkseagreen', key='_mykey_'),
- sg.Tab('Tab 5', tab5_layout)]], key='_group1_', tab_location='top', selected_title_color='purple')],
- [sg.TabGroup([[sg.Tab('Tab 1', tab1_layout, background_color='darkslateblue', key='_mykey_'),
- sg.Tab('Tab 2', tab2_layout, background_color='tan1'),
- sg.Tab('Tab 3', tab3_layout)]],
- key='_group3_', title_color='red',
- selected_title_color='green', tab_location='left'),
- sg.TabGroup([[sg.Tab('Tab 4', tab4_layout,background_color='darkseagreen', key='_mykey_'),
- sg.Tab('Tab 5', tab5_layout)]], key='_group4_', tab_location='bottom', selected_title_color='purple')],
- [sg.Button('Read')]]
-
-window = sg.Window('My window with tabs', default_element_size=(12,1)).Layout(layout)
-
-
-while True:
- event, values = window.Read()
- sg.PopupNonBlocking(event, values)
- print(event, values)
- if event is None: # always, always give a way out!
- break
diff --git a/DemoPrograms old/Demo_Tabs_Nested.py b/DemoPrograms old/Demo_Tabs_Nested.py
deleted file mode 100644
index 8868cb53..00000000
--- a/DemoPrograms old/Demo_Tabs_Nested.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-sg.ChangeLookAndFeel('GreenTan')
-tab2_layout = [[sg.T('This is inside tab 2')],
- [sg.T('Tabs can be anywhere now!')]]
-
-tab1_layout = [[sg.T('Type something here and click button'), sg.In(key='in')]]
-
-tab3_layout = [[sg.T('This is inside tab 3')]]
-tab4_layout = [[sg.T('This is inside tab 4')]]
-
-tab_layout = [[sg.T('This is inside of a tab')]]
-tab_group = sg.TabGroup([[sg.Tab('Tab 7', tab_layout), sg.Tab('Tab 8', tab_layout)]])
-
-tab5_layout = [[sg.T('Watch this window')],
- [sg.Output(size=(40,5))]]
-tab6_layout = [[sg.T('This is inside tab 6')],
- [sg.T('How about a second row of stuff in tab 6?'), tab_group]]
-
-layout = [[sg.T('My Window!')], [sg.Frame('A Frame', layout=
- [[sg.TabGroup([[sg.Tab('Tab 1', tab1_layout), sg.Tab('Tab 2', tab2_layout)]]), sg.TabGroup([[sg.Tab('Tab3', tab3_layout), sg.Tab('Tab 4', tab4_layout)]])]])],
- [sg.T('This text is on a row with a column'),sg.Column(layout=[[sg.T('In a column')],
- [sg.TabGroup([[sg.Tab('Tab 5', tab5_layout), sg.Tab('Tab 6', tab6_layout)]])],
- [sg.Button('Click me')]])],]
-
-window = sg.Window('My window with tabs', default_element_size=(12,1)).Layout(layout).Finalize()
-
-print('Are there enough tabs for you?')
-
-while True:
- event, values = window.Read()
- print(event, values)
- if event is None: # always, always give a way out!
- break
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Tabs_Simple.py b/DemoPrograms old/Demo_Tabs_Simple.py
deleted file mode 100644
index d666c326..00000000
--- a/DemoPrograms old/Demo_Tabs_Simple.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-tab1_layout = [[sg.T('Tab 1')],
- [sg.T('Put your layout in here')],
- [sg.T('Input something'),sg.In(key='_IN0_')]]
-
-tab2_layout = [[sg.T('Tab2')]]
-
-
-layout = [[sg.TabGroup([[sg.Tab('Tab 1', tab1_layout), sg.Tab('Tab 2', tab2_layout)]], key='_TABGROUP_')],
- [sg.Button('Read')]]
-
-window = sg.Window('My window with tabs', default_element_size=(12,1)).Layout(layout)
-
-
-while True:
- event, values = window.Read()
- sg.PopupNonBlocking('button = %s' % event, 'Values dictionary', values)
- if event is None: # always, always give a way out!
- break
diff --git a/DemoPrograms old/Demo_Template.py b/DemoPrograms old/Demo_Template.py
deleted file mode 100644
index 581bf934..00000000
--- a/DemoPrograms old/Demo_Template.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#choose one of these are your starting point. Copy, paste, have fun
-
-# ---------------------------------#
-# DESIGN PATTERN 1 - Simple Window #
-# ---------------------------------#
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [[ sg.Text('My layout') ],
- [ sg.CloseButton('Next Window')]]
-
-window = sg.Window('My window').Layout(layout)
-event, values = window.Read()
-
-
-# --------------------------------------------------#
-# DESIGN PATTERN 2 - Persistent Window (stays open) #
-# --------------------------------------------------#
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [[ sg.Text('My Window') ],
- [ sg.Button('Read The Window')]]
-
-window = sg.Window('My Window Title').Layout(layout)
-
-while True: # Event Loop
- event, values = window.Read()
- if event is None: # if window closed with X
- break
- print(event, values)
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Threaded_Work.py b/DemoPrograms old/Demo_Threaded_Work.py
deleted file mode 100644
index e4dd3b9b..00000000
--- a/DemoPrograms old/Demo_Threaded_Work.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/python3
-import queue
-import threading
-import time
-import PySimpleGUI as sg
-
-"""
- You want to look for 3 points in this code, marked with comment "LOCATION X".
- 1. Where you put your call that takes a long time
- 2. Where the trigger to make the call takes place in the event loop
- 3. Where the completion of the call is indicated in the event loop
-
- Demo on how to add a long-running item to your PySimpleGUI Event Loop
- If you want to do something that takes a long time, and you do it in the
- main event loop, you'll quickly begin to see messages from windows that your
- program has hung, asking if you want to kill it.
-
- The problem is not that your problem is hung, the problem is that you are
- not calling Read or Refresh often enough.
-
- One way through this, shown here, is to put your long work into a thread that
- is spun off, allowed to work, and then gets back to the GUI when it's done working
- on that task.
-
- Every time you start up one of these long-running functions, you'll give it an "ID".
- When the function completes, it will send to the GUI Event Loop a message with
- the format:
- work_id ::: done
- This makes it easy to parse out your original work ID
-
- You can hard code these IDs to make your code more readable. For example, maybe
- you have a function named "update_user_list()". You can call the work ID "user list".
- Then check for the message coming back later from the work task to see if it starts
- with "user list". If so, then that long-running task is over.
-
-"""
-
-# ############################# User callable CPU intensive code #############################
-# Put your long running code inside this "wrapper"
-# NEVER make calls to PySimpleGUI from this thread (or any thread)!
-# Create one of these functions for EVERY long-running call you want to make
-def long_function_wrapper(work_id, gui_queue):
- # LOCATION 1
- # this is our "long running function call"
- time.sleep(5) # sleep for a while as a simulation of a long-running computation
- # at the end of the work, before exiting, send a message back to the GUI indicating end
- gui_queue.put('{} ::: done'.format(work_id))
- # at this point, the thread exits
- return
-
-
-############################# Begin GUI code #############################
-def the_gui():
- gui_queue = queue.Queue() # queue used to communicate between the gui and long-running code
-
- layout = [[sg.Text('Multithreaded Work Example')],
- [sg.Text('Click Go to start a long-running function call')],
- [sg.Text('', size=(25, 1), key='_OUTPUT_')],
- [sg.Text('', size=(25, 1), key='_OUTPUT2_')],
- [sg.Graph((10,10),(0,0),(10,10),background_color='black',key=i) for i in range(20)],
- [sg.Button('Go'), sg.Button('Popup'), sg.Button('Exit')], ]
-
- window = sg.Window('Multithreaded Window').Layout(layout)
- # --------------------- EVENT LOOP ---------------------
- work_id = 0
- while True:
- event, values = window.Read(timeout=100) # wait for up to 100 ms for a GUI event
- if event is None or event == 'Exit':
- break
- if event == 'Go': # clicking "Go" starts a long running work item by starting thread
- window.Element('_OUTPUT_').Update('Starting long work %s'%work_id)
- window.Element(work_id).Update(background_color='red')
- # LOCATION 2
- # STARTING long run by starting a thread
- thread_id = threading.Thread(target=long_function_wrapper, args=(work_id, gui_queue,), daemon=True)
- thread_id.start()
- work_id = work_id+1 if work_id < 19 else 0
- # --------------- Read next message coming in from threads ---------------
- try:
- message = gui_queue.get_nowait() # see if something has been posted to Queue
- except queue.Empty: # get_nowait() will get exception when Queue is empty
- message = None # nothing in queue so do nothing
-
- # if message received from queue, then some work was completed
- if message is not None:
- # LOCATION 3
- # this is the place you would execute code at ENDING of long running task
- # You can check the completed_work_id variable to see exactly which long-running function completed
- completed_work_id = int(message[:message.index(' :::')])
- window.Element('_OUTPUT2_').Update('Complete Work ID "{}"'.format(completed_work_id))
- window.Element(completed_work_id).Update(background_color='green')
-
- if event == 'Popup':
- sg.Popup('This is a popup showing that the GUI is running')
- # if user exits the window, then close the window and exit the GUI func
- window.Close()
-
-############################# Main #############################
-
-if __name__ == '__main__':
- the_gui()
- print('Exiting Program')
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Timer.py b/DemoPrograms old/Demo_Timer.py
deleted file mode 100644
index 4bf3d386..00000000
--- a/DemoPrograms old/Demo_Timer.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import PySimpleGUI as sg
-import time
-
-# form that doen't block
-# good for applications with an loop that polls hardware
-def Timer():
- sg.ChangeLookAndFeel('Dark')
- sg.SetOptions(element_padding=(0,0))
- # Make a form, but don't use context manager
- window = sg.Window('Running Timer', no_titlebar=True, auto_size_buttons=False)
- # Create a text element that will be updated with status information on the GUI itself
- # Create the rows
- form_rows = [[sg.Text('')],
- [sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
- [sg.Button('Pause', key='-RUN-PAUSE-'), sg.Button('Reset'), sg.Exit(button_color=('white','firebrick4'))]]
- # Layout the rows of the form and perform a read. Indicate the form is non-blocking!
- window.Layout(form_rows)
- #
- # your program's main loop
- i = 0
- paused = False
- start_time = int(round(time.time() * 100))
- while (True):
- # This is the code that reads and updates your window
- button, values = window.read(timeout=0)
- window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
-
- if values is None or button == 'Exit':
- break
-
- if button == 'Reset':
- i=0
- elif button == '-RUN-PAUSE-':
- paused = not paused
- window['-RUN-PAUSE-'].Update('Run' if paused else 'Pause')
-
- if not paused:
- i += 1
-
-
- # Broke out of main loop. Close the window.
- window.close()
-
-Timer()
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Touch_Keyboard.py b/DemoPrograms old/Demo_Touch_Keyboard.py
deleted file mode 100644
index 350eab31..00000000
--- a/DemoPrograms old/Demo_Touch_Keyboard.py
+++ /dev/null
@@ -1,103 +0,0 @@
-import PySimpleGUI as sg
-# import PySimpleGUIQt as sg # 100% portable to Qt by changing to this import
-
-
-class keyboard():
- def __init__(self, location=(None, None), font=('Arial', 16)):
- self.font = font
- numberRow = '1234567890'
- topRow = 'QWERTYUIOP'
- midRow = 'ASDFGHJKL'
- bottomRow = 'ZXCVBNM'
- keyboard_layout = [[sg.Button(c, key=c, size=(4, 2), font=self.font) for c in numberRow] + [
- sg.Button('⌫', key='back', size=(4, 2), font=self.font),
- sg.Button('Esc', key='close', size=(4, 2), font=self.font)],
- [sg.T(' ' * 4)] + [sg.Button(c, key=c, size=(4, 2), font=self.font) for c in
- topRow] + [sg.Stretch()],
- [sg.T(' ' * 11)] + [sg.Button(c, key=c, size=(4, 2), font=self.font) for c in
- midRow] + [sg.Stretch()],
- [sg.T(' ' * 18)] + [sg.Button(c, key=c, size=(4, 2), font=self.font) for c in
- bottomRow] + [sg.Stretch()]]
-
- self.window = sg.Window('keyboard',
- grab_anywhere=True,
- keep_on_top=True,
- alpha_channel=0,
- no_titlebar=True,
- element_padding=(0,0),
- location=location
- ).Layout(keyboard_layout).Finalize()
- self.hide()
-
- def _keyboardhandler(self):
- if self.event is not None:
- if self.event == 'close':
- self.hide()
- elif len(self.event) == 1:
- self.focus.Update(self.focus.Get() + self.event)
- elif self.event == 'back':
- Text = self.focus.Get()
- if len(Text) > 0:
- Text = Text[:-1]
- self.focus.Update(Text)
-
- def hide(self):
- self.visible = False
- self.window.Disappear()
-
- def show(self):
- self.visible = True
- self.window.Reappear()
-
- def togglevis(self):
- if self.visible:
- self.hide()
- else:
- self.show()
-
- def update(self, focus):
- self.event, _ = self.window.Read(timeout=0)
- if focus is not None:
- self.focus = focus
- self._keyboardhandler()
-
- def close(self):
- self.window.Close()
-
-
-class GUI():
- def __init__(self):
- layout = [[sg.Text('Enter Text')],
- [sg.Input(size=(17, 1), key='input1', do_not_clear=True)],
- [sg.InputText(size=(17, 1), key='input2', do_not_clear=True)],
- [sg.Button('on-screen keyboard', key='keyboard')],
- [sg.Button('close', key='close')]]
-
- self.mainWindow = sg.Window('On-screen test',
- grab_anywhere=True,
- no_titlebar=False,
- ).Layout(layout).Finalize()
- location = self.mainWindow.CurrentLocation()
- location = location[0]-200, location[1]+200
- self.keyboard = keyboard(location)
- self.focus = None
-
- def run(self):
- while True:
- cur_focus = self.mainWindow.FindElementWithFocus()
- if cur_focus is not None:
- self.focus = cur_focus
- event, values = self.mainWindow.Read(timeout=200, timeout_key='timeout')
- if self.focus is not None:
- self.keyboard.update(self.focus)
- if event == 'keyboard':
- self.keyboard.togglevis()
- elif event == 'close' or event is None:
- break
- self.keyboard.close()
- self.mainWindow.Close()
-
-
-if __name__ == '__main__':
- app = GUI()
- app.run()
diff --git a/DemoPrograms old/Demo_Tree_Element.py b/DemoPrograms old/Demo_Tree_Element.py
deleted file mode 100644
index e83ec3e8..00000000
--- a/DemoPrograms old/Demo_Tree_Element.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-import sys
-import os
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-
-"""
- A PySimpleGUI or PySimpleGUIQt demo program that will display a folder heirarchy with icons for the folders and files.
- Note that if you are scanning a large folder then tkinter will eventually complain abouit too many bitmaps and crash
- Getting events back from clicks on the entries works for PySimpleGUI, but appears to not be implemented in PySimpleGUIQt
- If you need tree events using PySimpleGUIQt then post an Issue on the GitHub http://www.PySimpleGUI.com
-"""
-
-# Base64 versions of images of a folder and a file. PNG files (may not work with PySimpleGUI27, swap with GIFs)
-
-folder_icon = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABnUlEQVQ4y8WSv2rUQRSFv7vZgJFFsQg2EkWb4AvEJ8hqKVilSmFn3iNvIAp21oIW9haihBRKiqwElMVsIJjNrprsOr/5dyzml3UhEQIWHhjmcpn7zblw4B9lJ8Xag9mlmQb3AJzX3tOX8Tngzg349q7t5xcfzpKGhOFHnjx+9qLTzW8wsmFTL2Gzk7Y2O/k9kCbtwUZbV+Zvo8Md3PALrjoiqsKSR9ljpAJpwOsNtlfXfRvoNU8Arr/NsVo0ry5z4dZN5hoGqEzYDChBOoKwS/vSq0XW3y5NAI/uN1cvLqzQur4MCpBGEEd1PQDfQ74HYR+LfeQOAOYAmgAmbly+dgfid5CHPIKqC74L8RDyGPIYy7+QQjFWa7ICsQ8SpB/IfcJSDVMAJUwJkYDMNOEPIBxA/gnuMyYPijXAI3lMse7FGnIKsIuqrxgRSeXOoYZUCI8pIKW/OHA7kD2YYcpAKgM5ABXk4qSsdJaDOMCsgTIYAlL5TQFTyUIZDmev0N/bnwqnylEBQS45UKnHx/lUlFvA3fo+jwR8ALb47/oNma38cuqiJ9AAAAAASUVORK5CYII='
-
-file_icon = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABU0lEQVQ4y52TzStEURiHn/ecc6XG54JSdlMkNhYWsiILS0lsJaUsLW2Mv8CfIDtr2VtbY4GUEvmIZnKbZsY977Uwt2HcyW1+dTZvt6fn9557BGB+aaNQKBR2ifkbgWR+cX13ubO1svz++niVTA1ArDHDg91UahHFsMxbKWycYsjze4muTsP64vT43v7hSf/A0FgdjQPQWAmco68nB+T+SFSqNUQgcIbN1bn8Z3RwvL22MAvcu8TACFgrpMVZ4aUYcn77BMDkxGgemAGOHIBXxRjBWZMKoCPA2h6qEUSRR2MF6GxUUMUaIUgBCNTnAcm3H2G5YQfgvccYIXAtDH7FoKq/AaqKlbrBj2trFVXfBPAea4SOIIsBeN9kkCwxsNkAqRWy7+B7Z00G3xVc2wZeMSI4S7sVYkSk5Z/4PyBWROqvox3A28PN2cjUwinQC9QyckKALxj4kv2auK0xAAAAAElFTkSuQmCC'
-
-starting_path = sg.PopupGetFolder('Folder to display')
-
-if not starting_path:
- sys.exit()
-
-treedata = sg.TreeData()
-
-def add_files_in_folder(parent, dirname):
- files = os.listdir(dirname)
- for f in files:
- fullname = os.path.join(dirname,f)
- if os.path.isdir(fullname): # if it's a folder, add folder and recurse
- treedata.Insert(parent, fullname, f, values=[], icon=folder_icon)
- add_files_in_folder(fullname, fullname)
- else:
-
- treedata.Insert(parent, fullname, f, values=[os.stat(fullname).st_size], icon=file_icon)
-
-add_files_in_folder('', starting_path)
-
-
-layout = [[ sg.Text('File and folder browser Test') ],
- [ sg.Tree(data=treedata,
- headings=['Size', ],
- auto_size_columns=True,
- num_rows=20,
- col0_width=30,
- key='_TREE_',
- show_expanded=False,
- enable_events=True),
- ],
- [ sg.Button('Ok'), sg.Button('Cancel')]]
-
-window = sg.Window('Tree Element Test').Layout(layout)
-
-
-while True: # Event Loop
- event, values = window.Read()
- if event in (None, 'Cancel'):
- break
- print(event, values)
-
diff --git a/DemoPrograms old/Demo_Turtle.py b/DemoPrograms old/Demo_Turtle.py
deleted file mode 100644
index dcc2b0b2..00000000
--- a/DemoPrograms old/Demo_Turtle.py
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-import turtle
-
-"""
- Demo showing how to integrate drawing on a Canvas using Turtle with PySimpleGUI
- The patern to follow:
- Create Window & Finalize
- Get the tkinter Canvas from the Canvas element
- Draw on the tkinter Canvas using turtle commands.
- Results are shown on the canvas immiedately after button press / drawing command
-"""
-
-
-layout = [[ sg.Text('My layout') ],
- [sg.Canvas(size=(800,800), key='_canvas_')],
- [ sg.Button('F'), sg.Button('B'), sg.Button('L'), sg.Button('R')],
- [sg.Button('Spiral'), sg.Button('Inside Out'), sg.Button('Circles')]]
-
-window = sg.Window('My new window').Layout(layout).Finalize()
-
-canvas = window.FindElement('_canvas_').TKCanvas
-
-t = turtle.RawTurtle(canvas)
-t.pencolor("#ff0000") # Red
-
-t.penup()
-t.pendown()
-
-while True: # Event Loop
- event, values = window.Read()
- if event is None:
- break
-
- if event == 'F':
- t.forward(100)
- elif event == 'B':
- t.back(100)
- elif event == 'L':
- t.left(90)
- elif event == 'R':
- t.right(90)
- elif event == 'Spiral':
- canvas.config(bg='light green')
- t.color("blue")
- def sqrfunc(size):
- for i in range(4):
- t.fd(size)
- t.left(90)
- size = size - 5
- sqrfunc(146)
- sqrfunc(126)
- sqrfunc(106)
- sqrfunc(86)
- sqrfunc(66)
- sqrfunc(46)
- sqrfunc(26)
- elif event == 'Inside Out':
- canvas.config(bg = "light green")
- t.color("blue")
- def sqrfunc(size):
- for i in range(4):
- t.fd(size)
- t.left(90)
- size = size + 5
- sqrfunc(6)
- sqrfunc(26)
- sqrfunc(46)
- sqrfunc(66)
- sqrfunc(86)
- sqrfunc(106)
- sqrfunc(126)
- sqrfunc(146)
- elif event == 'Circles':
- t.speed(0)
- for i in range(400):
- t.circle(2 * i*.25)
- t.circle(-2 * i*.25)
- t.left(i)
diff --git a/DemoPrograms old/Demo_Uno_Card_Game.py b/DemoPrograms old/Demo_Uno_Card_Game.py
deleted file mode 100644
index a275789e..00000000
--- a/DemoPrograms old/Demo_Uno_Card_Game.py
+++ /dev/null
@@ -1,1531 +0,0 @@
-import os
-import sys
-import random
-import math
-import time
-import PySimpleGUI as sg
-
-
-#-------------------------------------------------------------------------------#
-# Works on Python 3 #
-# Uno card game using a GUI interface provided by PySimpleGUI #
-# Based on this excellent text based version: #
-# http://code.activestate.com/recipes/580811-uno-text-based/ #
-# Contains all of the graphics inside the source file as base64 images #
-# Cards were obtained from Wikipedia #
-# https://en.wikipedia.org/wiki/Uno_(card_game) #
-# Up to 4 players... any number can be computer controlled #
-# Still needs some work but close enough for fun #
-#-------------------------------------------------------------------------------#
-
-yellow_color = '#FFAA00'
-blue_color = '#5555FF'
-red_color = '#FF5555'
-green_color = '#55AA55'
-
-
-
-wildblue = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABQUFCQkJDQ0NERERFRUVGRkZHR0dICAgJSUlKysrMTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWlpaXV1dYWFhZWVlaWlpbm5ucXFxdXV1eXl5fX19R13JWlvZWVrcS13gU07kVE3jUE/sW07gU1DtU1frU1ftVFDuUVzsXlnvUlL3UlL5VVX+U1rwXFz1Wlr9TXTDU2ffVGvcVW3aVH3AWnXWXHbWXXTYXnnVUmPjUWLlUmTiVmHlXWLjak7PbE/PZV/VY13aZF3aal/Zal/dYFHmY13tbV7obl/vYVfzY1jzZ1rxalzwaWPaYHHaYX3UZH/Ud2bCdmbEc2TOemnJcmPQeGPcaGHoZWL6amH1a2f5amr/bm7/cGflcmLudmXtc2rjdWzieW/hemntfWztfHLhcnL/e3v/W4TAYorBZo7CaITUbIjUbJLEcY3VdJjHepzJd5LWfJbXf6HMgGq7hWTdiW/Xi2vejW/fiHbKjXvKgG/tgnLuhnfvg3nhi33wk3Xglnnhl3zimX/kgYGBhYWFiYmJjIyMkJCQlZWVmZmZnZ2doaGhoaOlpaWloqWqqampra2tsbGxtbW1urq6vLy8gZnZhp7alYTNmIjPmorQm4zRnY/Un5HVi4LjhIT/jYHxlY3om4HlnIPmnofokoj0lo31k5P/mZP4mJj/haXOjaLdi6nRkazUmrLYlqnhoJLWopXYpJfaoZjYpprcpJzYp5zdoo7qpJLspZXtoJvyqJrwq5/zoLbdq6LjrqbooaH/pKT/q6L1rab3qqr/r6n5rq7/oLDlp7XpprrgqrzisKnqs63vtK/xsa37tbHzt7T3srL+ubf6urr+scHmucXrvsjv3Zi53py8wcHBxcXFysrKzc3N0dHR1dXV2NjY3d3dw8P/wcrxycn/y9D20NL60dH/1dX+3Nz+3unt4eHh5eXl6enp7e3t5eX+5+306eTz6ef46en+7O/57Oz/8fHx9fX18vL+9PT++fn5+Pj+/v7+AAAAP81AhwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABapSURBVHhe3Z15YB3HXcff02mrPmRZdnxIogVaDkMEjhPSug6Uoy03xPQAQwPldJJSk0ALuNBCaSzbcozxIZUAaQMhHA1JablCcNOkdh2gARfVdsCWLKk5cJD0FioqUWXN7zfz293Z672Z2d97+zafP7y23r7VfLyz353dnZ0pXa2B21RQoWpRw4o21lxQ2apQ1Yq20pxQGROpYkXfbnKosGFSrehLBYAKrJJiRV8oBlRmhUQrWrswULEDEqxo1UJBRfeIWdFqRYNKT0StaKXiQeWXRKxolSJCBoKwFa1QTMgBCVnRx0WFLADVij4sLKQBKFb0WYEhEdWKPikyZKJY0Qdxpi+NjjQVo5emqGgxyMW3oh9HmB7obis1Ia2r+yepiGHIpprVyBraSFPSfZyKqUI2ZEU/VJnroa83Ld0zVFQFqSOt6Ecqx5qy6oVpO0yFDRA6qVaH6ItNzgEqboDwEVb0A4WCSCVoVbE6Tt+pTrm9c1nu9fQIFdkn1Wqunb6SRtuagaMTFbnusbX0w3xojUZGqlUvfSOZl+2boPWIyVX0SS6soVL4pFhdpPWTaOtLOv1tpk9z4QQVwoOs6F8+6buqc3hRruKMnXn0j3/r3//6iSeviH/nqdUtSqCQaDVDa8doO7iEnztjp+76/kHkdfjHLf+JP8yzEsaahUlW+2nlKBtEPDhnflYYIa+UizH48WVaKQ/6sVwqSVbJmdY5ip85n/huaYK8ipaDuLdyTMJ4FQQr+qtPJ60cogd3lHNKcRocvJaWg7vhs6O0Yg60iWIrJFjN0bohBuADZ+xnyELyFbQEIDISv9YgYgdW3GqSVlUoYyvS+RNSIN5ISwSPrFZaOQcuiYIrlGIVcIJWDSjjlYzzXjLwoKgQPAErJFbcxiAOeZW41Tit6lM+Bj913k4CHn5UIJ+CNTpo9RywsbobfujIE5SCHxXIp2GVHNu5FlZ4NohLKVEB4HFFq+eBuRWeDOJSalQAz+abgcZWHXMJx1Q4KoAXEipuAzG2ggax8z4qe0AoKoAXXfcIfSEPTK3WwQ8+QUVXCEWFbFv00TfywNCqFevf91LZA8JRMTj4EfhaN30lDwythkAqaKJ7RKJicPDzrruUY9PC0KodrhFPU8kVIlExuPVLrnuJvpILZlb7YVf9BBU9IBoVg/fBt/rpK7lgZNUCVx+nqOQKkagQFdBdTt/JBSOrDfCvvVTygK+69uvDfCNUwHiTuJEYWUED/wtveWuYd7+c5AJuhy9tpK/kg4nVMvjHx6jkPm+ipcIF113IMwHNrDa77vyPUMl9voaWAa/+P9c9QF/JCRMrWPffqOQ+305LhWdcdzHHayvEwKq85Lp/RSX3eAMtFX4BdlXavbZGYWC1EirgT1LRPV5By4DXgtRcvkeVkdUm1z1HRfd4PS0VICrcdfSN3DCwOhS3ikfFB2FXnaAv5IeBFaz6FJWd+DZaBuzE+pdzVAAGVtOu+zdUeMHXvfnL6G8+N4JUrpcghIEVtNc/RKUXvHnwy+lvHjegVJ5Xix76VmX46+9T8QU/FJUSe6opHovrW7XCX++h8guiUYHHVJ7PDBTsraKtCkw/92hZrpwzZjVQOa4irYqbLqDUsFw1dwzSYtJ1HycHINyqwGZSzs+4VQyshqHF9J1kEW5VbH8GpeZW04r5Y2AF7UD3k+ShRsXNT4sddbxWT5MGYmBVGoGd9WFp4kfFtgefF06zubf9VEyslsN5eP5xrIQyKnbc/tBzQsld3Jd3Kz2MiVVpLf5z/ql7f+937njXw+evSCPXrQzVu/KVO7pW9azbsLlvYN/Q0L7+jWtXVP9fNLIqraWeMCqXNrTQp+yUl3dvGDoyOrVAv0pl5tjml9FqccysSsvh2FJYHNm8jD7hpdy1buj4lOh5U4XZ4ZW0fgRDq1JpxcHL+MsqUyPDG1fUpSXRdc2hiQQfZ0zg0D+JqU1JddHYCmmpV50rr+ofCVU3UDlz8pH737/3V3+ZnsT82Natu3bf95GxKy/SKpWBuJeVVX3o2jyiHLbO2OlH7tr7fVIlIHh0u/XWJ2m/zW2gLfg0iVVLz6GgC6YzdvL+vfGHZIKttJTsPvcl8Y3xLtoO0QxWreuOeTvJGTvzQJoQ8qO09Nn1aeG1FG6C5m7V0hsonXkg/hgpxPfQUmUX9oKABpt6dOVstfIQhQPUuvdX2UfELlqG2f0CbmFSOcfkadXeR33DnLFHQj3y0oj18iC2PolbmQ0OrvysVh6RJyVdJSAcFSr34dFV8RsbOVmV18vO4lDxahxKCrGoULjli7C1OW9v5WLV1j8rtqx22a1NUlQE7MKT1ww1s3Owat8vEsIZezTtOEkmOSp8hNYl2YZruFXHQRHkztlop8la1PwveBtWQnk/qMFW7Qek05lwj10d0qPC41ZsGopX3xpq1bpP1r1T+gnhUy0qPP4MNj6HnS0babVxDjcX6S2uSfWo8MCOHnhLvHFW3eItGee0jVPNqCB24aG1onFWy8QLos4Zi7qH6KYl1sHRRlmVBzAknLPmGUHUjgoCm4SrG2O1WrT3ErqA6qITFZJb4ReNNMKqDXuKu87J2k3yNPSiQoKvf3XV36oHW0fOWcsDSqAXFRLsxbe/3lat4r3kDJUPMGtYQQzO1dlqNd6NcE6blSuKdlQI8LWHyNujvFblIfx+7DUZQ/SjQoD9s2Pv4zNaLRuHbzunY3e/zDCJCgG03b07IT58Vmux0ZftiEJMokJwThY7BJdVGV+Id87atY8UzA9JbF9EYbJqvwjfjL5NZ4NZVCBvk8UOwWO1QpykMsYEYhgVAnk/NwSL1To4XBlqn0VUIJHHJgiHFQa686f0OzJhHBXIs7LcKtmtWo7Cl5w/pF+RCbuzd0IIZrZqw9danV+n35AN86hA5I33EFmtOvGSN+FlEhtsogIQ96fDZLTqgvBzzmZsThBWUQGwW62ogNSf09azYhUVALfVKmgk8YQfYN3QZz6uuvE0xdCekNhFBcBrJaRYEh2xjAqANdm7lzilbKMCwHudEaytVuOe+k3acHZsowJgtFrJK5XlnoAYjSeMpVUXRjqflH1UAOLhdxg7q2V48mU7prJEBcDVZm+fBim2SM8UFQDT9VXLOEhxnXyRDFEBULlVbKyOgxRXMwnJdvtwF5VbxcLqIKx0hjbJQpaokDcEo5hb4bvRDk8rXZIpKuSd9ijGVqthFYfhFoVPtqiQw1BEMbXqxBEvrJ+2JZEtKuSN9iiGVi0TIMV49s0aFUBCg8nU6m6QYjxRAdmiArjiutQ9L8DM6hr4/CxtjYeMUQF80XXFwIYqRlZd2KTNXGVUskYF7GsocqYnPS2T3EmROSrk6SphpD36i0+6FR5UjE1agGG/4yORLM8ae+FD1jYFQ1TIO0z4QCaEvlUHXlKxHlQMUSHuslcyPO3GscF4bjx7ZI8KACJw1N4Kmn+sVx9A9qiQLfaD1ladcKYboy0xwVKbsW273toK6x9vqHNEhRw707rHz3qQ4m0psUSFCItF295ZbdBSZ65/LFEhwuKirRWef036omvAERXyAf6QpRW+EJ0w4FkWmE582LLosbTCiyre8y9PVMgnB212VhtBivVKkSsqxGF12a7fLQ5j2ZxRIQ6rg3ZWB/hPVTxR4R1WNlbLlhKHscwC2zH6eTkgqIXVEdhVnHfKAKaoELfYcUBQc6su+NFJ2ggTXFEh+n3jgKDmVtgA5LxTyxcV8jk3vgZobLUCfvIobYQJrqgQT67ENCHGViOwq+z72yfBdzq/BUorXisztcJd9fe0ESbYokJchYhR1kyt8Kji3VVsUSEqYEW82GhohQHIu6v4okJUwLtFMQ2t8FzFG4B8USEehshh/sysOqFZwXuu4mz5QwWcs3mzFluAvFcgfFEhTsE00JqRVesC98UiY1SISysaHcfICq+rePqeEoxRIQaFn6KCGllNcj+sYowKcRHiDQpvYoXPte+ibbDAeohegYsQb/RWEyuI9flf+S4+fvgHX8PHnVBSf1ZJA6s2iHV/pD0OvpmWLNwBJfWn1DWwwoHMf5y2wcEP0JKH51x3mgpqZHU5YSDzLHwDLVnAQeGD0Yv0rbAJeC9tg4NvoSUP5113MZiaSt8K2hXBsJzZ4a1/18OuOijLiehbzbruv9A2OGCNisHHoJzKXB/aVnCymv852gYDvLvqJthV6qjI2lbD8dHZs8AaFYMfhWKuEMWUaFtBBYyMzp4F3qjYAbtqRJSS0LVaxVoBeeuf2FWh2WR1rSABGSsgb1TgBBKjwsZD12qKMwHrvat0rZbD8g9oI9nhjYpt0aNK2wrbgGynYN6oGPwMlFENQEDTaoSxDchc/3BegugI/npWLYvxyWys4Y2KwafhajE6hZieVTdUwOhkNrYw76qfh12ltAAlelZDjLnOGxWDz7tuJTaPrJ7VJb5cZ46K34VdtYlcArSsWuDaPjZJmR3M9Q+vQBJmc9eywvY602HFHBU4g1PCzPtaVgNshxXzrnon7KrDZKKiZXWC7WzFGxXYVq8kjeOvZTXnun9HG8oGc1Sch9JdQyIhdKxwRsPQDD221OFUFWkAEjpWvRAWsRkNbeCNCqx/C8kTFOhYcZ2DmXcV1r+UKTx1rCAsPktbygRvVODUQMn1T89qhicseKMCz7+VTrKIomGFr5IwXDEy17/noFS9JBFDwwqHt/k12lYGeKPiL2FXyV4ISWhYTbNcB/PuKmxUTKXPaqNhNcsSgaxRgQfVYmReChUNqwpHe4k1Krb8NxQrNomIgoYVXN1nfsTIW//wTJXUqPXRsIKLq4/T5qxhjQq8UpyoOqmOhhUQmn3SAtZdhUkxV30qJz2rrG1bzqjAO2VLNSbm07N6D23REs6owDu1NWdw17LKeLrirH8i/mJ3yqJoWWU8XXFGxdNQHL+zSCoNsOLcVf8E9W+89pxiWlafo23awRgV/whSUxoTDmpZZbrDyRgV2KStkekSLStlUldjGOvfX4BUpUrrL0DLKkuDiS8qUGohZSrDCFpWGa6E+XYVSi1qTourZZWhGcgWFXhMLepO315nK7aoMJLSs7LuasZW//A8pS9VZyumqNiCk4IvJDz7SEPLyvYOE9Ou2vFfUIZK5DF9VepqxRMV1/8vFGFG6zzlUU8rnqi4GWqfO5l2PzOZOh5XPPXvF1HqYux5dnW0rOySnSUq8NzrHjGdx1jLyqrFxLGrdmD4ufuorPpoWVm12Rmi4kbMicXUu+npaFnZXDUyRMUv4Y6aSZ9zPJ16WWWvf1vOo9So1aT0WlYWnS0yR8V2rH3ufrv5zrWszEMw864S2VcRU0paoGG1YPEANWNU3PAMSl0yO/UqaFjNmt8QzBgVIiYsAt1HwwqfNZq1mbLVP7mjpvWu5ZPRsBqfMq2CmaJCHFHuofQHiRroWPVDFTR5nSzLrrr5eZSa0b9ATETHqmPJ7OaZfVRsE+codzjTjgJ0rEqHYWfpd/mxjootDwunySxHlETLCl+T0371xbr+YWcXaPb12Z14Q2hZiXdqf4p+eS0so2Lnc0LqqPU5SkXPCodg0nyOb7ertos0dycM7rhUQ8+qtA921h9RCapjExXkNJPYg9EGTasWOGfN/zQVohoWUbFTOlX6aj+X0kXTqrQC6qBGDprXv3fK42lhyPDWRFV0rUpwKtY4tAyj4qaHrpCT1WVUKtpWOBHF/D9QadIw21U3fkYouZUBzv2E6Fu1TtTWMoiKHe+SVc+d3sR3PHnoW5U6sEvdZ6tdk+hHxU7ZNIJrqF6Gk24MA6tSJ2i5/5PeztWtf9sfk0eTu3jI5laLBiZWctbC+d+gwsXQiYot7/CU3ImNWRuxqRhZldpw4PP5p5JrYe1dte0Or+K5cwfrtJsEZlal8jD+ZP7DVMwQ1aPite/4qLh0QhYOr6nH0RRgaFUq9eL8D/Ofi1fDKlFx/Z7AyK0c7qmvEmBsVeqAExd6fTzc0kipf9fveeiCdyABkwdW110JMLcqlXrkFBDz/3qvIhaNih237Xnwn59XhNzKsQ06/Vo4sLEqlTdgxgPz5x7/2D3vwfCAXbXluuuu+6bbbt9z50OPXbii6gCzRzcZPSw0oLWjI5alVlbg1atMAzF/7ty5F6IePpXR/b0sl4JRWrv7j4zPit8xe8QftEhgaQUs33eZVkhjYfxwf09dhEqlrgGcxljhsnq3w94K6Fx/aAKuUCIszowfH+5ft5K3Ga7StinhP3RJ6baayUqwbHXvxs19fZs3bbymd82qrs66NRg8Og4uyoI5Y2dPPvCB//jbT43JGRoDrexWDabtgKwdzun75bDP34p/7BbzafqVsGhW6+ewSM6Zu/yBXF8pFzgmov8+dLGsOk5ggZxTytCMr6KlmP3Ue95VKKs1uKOc06EBx6+lpZghyhvnokhWeOvEGQtPjfGVtASuwJUArVkgq0NQlujMQG+kJYIDflMAF8aqfAyK4ryPDDwoKgRPwAp0zi+M1VEoifN2EvDwowIpoJWofrF5CfyoQHDAZboFVxCrPihHfFRkJSoAPK5o9WJYJc+1qkYF8GzBMrAdzlOxYyocFQA0Br2iFsIKZ2WOpl8kKoAXXfcIfaEIVjiDYsKg3KGokG0LmxGXc6IVrncTZiUIR4UcR9rr0FAAq30gFZ9BMRIVcgJe79qu+a3aFxJn8IxEhT+ZjaD5rYZgV8UHhY9GhZjRcIC+0vxWLZXEGZwiUSGvGv2bc01vhfMy76WSB3zttRG2Qq4HQ4M1vdUl1/3CW94a5t0vJ7mA26GgwShuzW7VCQWI9Y99Ey0VLrjuQnB3q9mtcEDQWIeIr6ZlAL6cbzU6dj4kDQj6HbRUeMZ1F71JD4AmtyonDAj6Bloq4OAQB+grSJNbrYQKGO3s9gpaBuDYYHNqn40mt9oUf/Hh9bRUiI1N1+RWcGEftYpHBXYUD48N1uRWULxIJ9J4VOwEqYoSFUCTW01HXyyPR8VrQCqYSUTS5FbQXg+/fhiLihtQyrta9GhuqzL8+tBrD7GoEHsqNuBZc1u1wq8PjS8UjQo8ptxjtHaAhtUErZoDUatoVHxQSMV7cGhYTdKqOYA18ENkAESiQr7LmTTeXuRJOFpFtbxbh3kwGXqXIxwV2EyKB4WAuoMExK3cRvVoSQDOwsG7X6GoeLXoWT0XiXRJmyy3QoKVxautXOBk7v7bykpUbBeVzz0RPvl6rMHPVK6CVVRLbQ03GjjuvX57flRsoy67c+tppSgDotgKSVY0tWMudMGlyPwnsRLKqNhy24PUC3lxf2rPjuhhdTXJyk37P2kEeDvanX/83nt+e8+dD5/3O0stHEiufEgPreMjraJaebaZSr3UE0alepdduH4Ok2yVPLB2o+gKn1OXLvZFp6QIs5ZW9AGhRKuFOvUc02TlsOhnuTh98e7Nq2r16ceHXWE8q5hW2oDNjaO1VTOz8Fl/mFSr2OwqTQs+Fg+DPilWRdGKSylWCVqj+R5bWrSL/tsRUCfVyl3INQl1EH3tY6AOWSVpuePrc2xl1KLcG7v+EAibalbQeDrQm2MLPp3Otftlb+k4wsazStECKpMT403FxGTsFBUgZWpbFQqS8a1eGlrk8tKyIhXF6iWgRSIhq+JrkUfYquhaZAGErAqtRQqCsFWBtUhAErEqqhaV3iNqVUgvKnlA3KpwXlRqlSSrQnlRicMkWxXGi0obJc2qCFpU0gRSrQD6cnNCZUymmpWANtJMUMlSuXr1/wEgaN6It2W3hwAAAABJRU5ErkJggg=='
-wildgreen = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABQUFCQkJDQ0NERERFRUVGRkZHR0dICAgJSUlKysrMTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWlpaXV1dYWFhZWVlaWlpbm5ucXFxdXV1eXl5fX19Ap0AC5UADp8LD5kUCpwYCZ4cFZoAGpcUCp4gDpksEZImEZgzAKMABKQNAKoABKkABasEBqwGCqYPDqkACqwKC6YWCKAZFaYKEqoCG6EAHKALGaoAHKwKFKQUEa8QGKMQH6YRHa8RE7ASGbAUGrIaE6chFackHaguJ5oNL5sANJYRIKcMIa0KLKoAKa8PIqcTJqcXK6gcLrATK7IZMaoAOaQYMbEVN7IaO7MeIaEiIaM6IaoyJao2La4+I7UjKbcpLLgsMakgN6smOqwpPa0sMroyNrs2O707K6hBL6RQNqNINqZWOKdYPKpbP6tdNLBETbIZR6olRKouSaEoQa8wRLcnSLgsRLAzRbE1TrU3SrM6VKY1Wac5XKs+VLQgWrcnX7gtUbs2VL06aaoAYroyab08Sp9yQq1fQLZPQb9BS7tXX6xCUbdDVLlHV7tLVb9fXL5RSrBlUbRqVbdtXbtyYq5FZ7JMabNPbb9Ca7VSbrhXcrhNYL10db1hRcBFTcNNVMVUWMdYXchdWsNiYMJJb8FFYsJZc8JLd8VSesdYfMhbZsZgY8pja81raMF5cctkecFofcVvcsd/cM9wddB1fNJ8c5+YeMuCrKlxgMpihM1sgcl1gsx4hc99idB1jdN9gYGBhYWFiYmJjIyMkJCQlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1urq6vLy8gNCFgtWCh9GBhdOIitSFiNeIi9iLjNiMkdaGk9iLk9qTl9qSmNyYo+CjquKqsuWyuOe4vOi8wcHBxcXFysrKzc3N0dHR1dXV2NjY3d3dwurCzevHy+3L0e/R1Oza3u/S1vDW2/Lb3vPe4eHh5eXl6enp7e3t5PXk6ffp7Pjs8fHx9fX19Pv0+fn5+fz5/v7+AAAAeLMFJAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABaXSURBVHhe3Z15fBznWcd3ddqqbcmyfEviKlfJQkCBQIoB1dz3faXCHMGUlFLuI9yEpuXoQSENxbH9CUc46pCkNgU3DpJtOZZlS7HjopI4dmtLlmQKZCXtupaqvuZ53nlm5p1r931nnt3ZyfcPr6yd2X2/et/5zTsz78ybu10F0VBQoapRxYo+rLGgslWgohV9SmNCZQylghWt3eBQYb1EWtFKGYAKrBJhRStkAyqzQqgVLZ0ZqNguIVa0aKagotsErGixrEGlJ/xWtFD2oPJb+KxokSxCBhKvFS2QTcgB8VjR21mFLADVit7MLKQBKFb0XoYhEdWK3skyZKJY0RtB5q9NTjQUk9fmqGgByMWxol/7mO/vask1IM2dfbNURC9kU8lqYiN9SEPSdZaKqUI2ZEW/VCl10+oNS9ciFVXB0rGs6Fcq4w3Z9Ly0nKbCukidSKtTtGKDc4KK6yJ9pBX9QiEjUiFaFazO0jqVybe2r0m9nY5RkR0irUqttEoULRv7z8yUrWXHN9Ev06HZHxmRVj20RjivGZ6h5YjZDfROKmykUjhEWF2l5cNo6Q3b/e2kd1PhHBXChqzofw7RVdU+umItUpy68ORf/eW//ez9b9k3VYT/p6nVZRXJJdRqkZYO0HJyFd8vTj3z8HcWkM+T/74dtdJshIFuYZjVcVrYzzYZD8ULPyVdkNdaL/eC1nVaKA36ZLEVwqzCM619Et8rfvi7LBPks+lV1laKSRhsgmBFPzq008IeurGiis8oTk5VAVNCnKEFU6DFKrdLiFWJlvXQD28Up36SJCw+h16BfRGr1YnAhhW0mqVFFfLYiyy+mxSIz6JX5CF4v5kWToFrsuAK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'
-wildred = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABQUFCQkJDQ0NERERFRUVGRkZHR0dICAgJSUlKysrMTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWlpaXV1dYWFhZWVlaWlpbm5ucXFxdXV1eXl5fX19tEx6tEx8y19C3ltJ3lRx3VR0w3RNwH1U32dT2m1V3GtU1nVa1nZc1Xle2HFYxHF32Gx01H1h1H9k415D5V5E4FxK5FpJ7VpJ4lBd5lBZ7VFY7FJc7FxR9lFS91dT9Vdf81tT+VJT/VRU+llS/VhS/l1T+Fpf/1tb/l1e71Ri7ltr8lZh8lpl8F1r+Fpg42NS4mRS5WJR4W5b/mFT/mNU/mdX/mpZ/mxa/m9d/nZU/nJf/ntZ4mBm5WN87WR17Wd47Wt8/2Ji/2ho/21t/nVn/nhl/ntp/3Jy/nZ2/3t73WyC2myP3mqK3m6O3nCP3HCT3HKU3XWW3nqZ6m2B7nKC4HSS4niU432Y8HuJq7F7wIRbwYtjxJJrx5h0yZ161IRo1Ihs1Y1x1pJ315Z8zKF//oBe5YFn5YNq94Nk/oNj/oZm/ohp/ops/oxv/oFw/oRz/o9z/o1+/pF1/pJ4/pV8gYGBhYWFiYmJjIyMkJCQlZWVmZmZnZ2dsbOBoaGhpaWlqampra2tsbGxtbW1urq6vLy82ZmB2p6GzqWF0amL3aKN1KyR2LKa3bag5YOb8oOP/4KC/4yM9YyV/pqE/pyH/5CQ/5WV/puT/5ub/p2d44Wg5Ymi6o6h6ZGm7ZWl7Jiq8Zyp4amW/qCM/qOS/qWV/qaY/qmc5bCg4Lqm4ryq6bWn9KGr/qOj/q2j+Kit+qyv/6mp/62t+Kyy/rGq/rSv+rG0/rKy/ra1/rm5/76+5sGx68W578i+wcHBxcXFysrKzc3N0dHR1dXV2NjY3d3d8crB/8LC/8XF/8vL9tDL/dTT/9nZ/tzc7ene/uTd4eHh5eXl6enp7e3t9O3n/+Pj/ubm+e/s/ujo/+3t8fHx9fX1/vHx//X1+fn5//n5/v7+AAAA1zju8QAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABZTSURBVHhe3Z17YBzHWcDv9LRV2ZZl2ZatB7QQnKQGYmhLqXnkgPJoSuMChfJoEwqkLaWFAgGStJS2vAqFQCvZloJfkUpCGkh4BBfSECgJFNyEUvAztmRJcRzFIOtQOOthj/t9s9++d+9mZr+73c3vD691t7uan2bmm9nd2ZnC1RqITEGJqkUNKzpZtqC0VaGqFZ0lm1AaI6liRUdnHEqsn1grOigHUIK9xFjRAfmA0uwh0or2zg2UbJcIK9o1V1DSbUJWtFveoNQTQSvaKX9Q+i0CVrRLHiEDid+Kdsgn5ID4rOjrvEIWgNeKvswtpAF4rOi7HEMiXiv6Js+QiceKvggzc2Z8LFOMn5mmpIUgF8eKPg4wM9jVUsggzesGpiiJfsimmtXYejpJJuk6RMn0QjZkRR96me+mwzNL1xwl1YOlY1nRR14OZrLo+WnZR4l1kTqxVqN0YMbZQ8l1kT7Sij7wkBOpCK0qVofomOoUW9tXpV5O91OSHWKt5lvpkDha1g8emCxb+x7cQB+mQ3MwZMRa9dAR0bxsaJL2I6bW0jepsJ5S4RBjdZr2j6KlP6r566NvU+FeSoQNWdFPDvFZ1T6yRPuIlQvPHfvMu9/3/s9W8Kc0tbpkejxEWs3R3iFa9l629rh04pF3lIDX4j9vkF5pFsJQtzDKajftHKTXCg8rx9+FMsCNtP1F0DpLO6XBgEyXhyir6JjWPi6/rBz+bnIplV5H29JnY49qCOEiCFb0X4d22tlHt8yoSx6n0jfTFgohZNYB2jEFWmSyPURYzdO+PgblV8c8Tj4gsyIPaxChihW2mqJdPRRlL3LBrk8WMlQQ74evm2nnFDiDyfNSCBXASdrVpSivZJ7zZ5QdKiTvg+8jC25jsKq8h7DVBO3qUDyIH/8HCdg4oQL5edihjXZPAROre/DTRyj9Nm6oQH4B9kixn2tgJVuDv6Hkx4D1inZPA30r2RgEc8oXKoC/TzcGalu1zcNHwTrlDxXAP0QU3AaibYUd4vOUdhdfqAD+W4j9dEAa6FpthA8qt1LaHfyhwupb9NMRaaBp1Yzl7yFKezw/C3t10SFpoGk1DD8fp6S7BEJFqfR3QlxOsWuhadUK14jLofIXDBWl0n8KcYYOSQU9q93w4xFKuUswVJS+D6rVAB2SClpWTXD1cSnUTQ+VPyyAYjUdkwpaVr0Q/955Y4Bv+Yqv8vMGLIDhLnEj0bKCDv4xyg6Xb6Cty5uhAG6hQ9JBx2oV/PAJSrnLq2jrckqIxTQjoJ5VHxTAH6CUO7yati6vXBZiDx2SEjpWsO9/UcodvoO2Hp4VYinFaytEw6p4WYhPUsodXkFbl9+ArIq719YoNKzWQAF8CyXd5jW0dXkTSM2nW6u0rLZGdJYiQ4XYSEekhobVaNgqHCo+BVl1Lx2QHhpWsOuTlHYiHCp2YPlLOVQAGlYzQvwVJZ4IhYrrQSrVSxBCwwr6639MqbcIhYprUSrNq0Ubdasi/Pf3KfkWwVAhcyoTj8XVrZrhvx+j9EuCoQLrVJrPDDyYWwVDBUY/caBo7ZwyeiXwbjJA/KHi5lMoNWLtmjoa0WJKiCfIAfCHCuwmpfyM24uG1Qj0mL6LLPyhYvuzKDW/jnZMHw0r6AeKfyYPb6i44RmZUYdqjTRpIBpWhTHIrD+0TJxQse2+Wel0MfW+nxcdq9XQDleekIXw5fjPrjvvf14qiaWhtHvpfnSsChvwx8qTd//eb//JRx84aWUSUB6ud+ErtnWs7d7Y29c/ODQ8PDSwZUNn9b+illVhgzMSxuVMbxN9y05xdVfv8P7x6UX6VV7mDva9jHYLo2dVWA11y8PSWN8q+oaXYsfG4UPTNPImlosja2j/AJpWhULn3rP4y8rTYyNbOuvSk+jYPDoZ7/PiUeBF+kGI6a1RZVHbCmmqV5krrh0YCxa3lYXZc0ePHH74oXfd9o5bb/2eb8M4ddN7bn/0aXIrD4a9jKzqQ0ffmK/aLs+eOPLwbYFnFW+kLfL2xy2x+V46g0NGrJq6R71DMBfOHXko9OgFeT1tbW55SnpNdNB5iCxYNW886GbSyvkjD8WNI4KiR1uXt0mvy/4uaOpWTT2uEhjdRomNJiwF3CLL4SFv7UrZas2oExwWvlglj6rzF6g15Wlj0rRq7XfGhs0e/klKYTW8ocLH21Hrolu50rNas99ulGYPR0aGEMFQ4eEmrF1lp7ORklVxkz1YfOGISi5JImuVzV+C1rydW6lYtQxctE7tDtlVoKqUpTVH3ewUrFp3U4S48IhpeIgEtc5YfbiGW7XttQL5lXMa2YTEhgoH1LLuBzXYqnWP5bRyVLk2EVVChcPTcGb56ltDrZqHrLJ36Yh+0atRqyRvxIiBgy0babUFB0EFRouroiJVKv0SaOEt8cZZdVlvySybOCnz7/AbOhtntcp6QXTFoOwhtUOFBZbB8UZZFQdlkLhyTK0TEUIlVFhgl3BdY6zWWf298/K9HxPUapXkqBBjjbBqkSPFxULtwZJxaEiVHoVf1VF/q27ZO7piWKG0uQmK4O56WzVb7yWf1210vaiGCgsIg/N1tlon70Ys1xjTXx31UCF5G2RW4O1RXqsiDtMV4jnDyEfo1CoE4kXofXxGq1UTePjyw/TbDNGVKj0uhHtzh+Cz2iA7feeTZZQBvyJT7YfLqihfiL9ymH6VMXqhAsH+RRAmq9bTeOhC9RthCmiGCglUrCA8Vp2ykTqXvI3SrlXAUzLZPlisNmJ1TV76zKQwXAThsJIB/ZLmFTwffy6T7SO5VdMBPOoFjtinHyqQiCCY2KpFvtZ6gqPbZxIqgNtlsn0ktWqXl7zhl0lMMKpVpdIvy2T7SGjVgcHvSsLuBGEoxW/ViW/nL6cWJyy4rdZiJ6mSuOm1MAsVAHO96sJmaiHJpZQHw1AB8FpJqQtcvVnTWsUc2bvwedQLXBfy5lKsrfA6zKnZBt2dqAqj1RpeKeNQAeBtpgCGVh0Y0vmkzEMF8JiVbi9mVquw8b3AV/wS1Cq+PnvrDOy3wHctn0iK6/qqCW+7hN/OTwuma2F83rFsfBM9TJJQAfBY7YWdVhj7folCBcBi1Ys78fTSLZLVKnmnPYi21Trch+EWhUNCqdJ7ZKr96Fq148Pe8BvfKRJxIaJr1YQ36ln7SQlDRWSHSdcKn7gxNlTJQ4XsMDnD82z0rDbD91eYrhItktYq+QDLmtjQg5ZVB3ZpEz2cCpJcKvGTnia8n5SpSIGAVcRMe/Qfh3grrFRsl4mSxKECTpHwWWMPfLnC2FHiCBVWYJcPZLyoW7VhnWStVBy1CgN7OcHTbpwb7ASdigcOKQyB4+ZW2P2rsFYqHiBY7DW2aseWjvcmLUOogPyGYLHJ2ArL31E6Ew8coaJUei+ky3jEzyb4YoG3/LHUKgwWS6ajs1qwp85b/nikMFicNrXC9jc8N10WgGAxbGiFL0Rf4r37whIqrJ5Ft6EV9kh421+eUGE9OWgxs9oCn87SaZhgqlVYrc6ajbuV01iyXlSxSck22MwKRyjxNlVsWNXKxGrVZRExjWUimEKFbK1wQlADK1yGhPNOWan0/bRNzlPWhKD6Vh3wUSZ7FQhUK5wQVN8KO4Ccd2o5pW6BaoWvAWpbdcInF+gkmeNxWiZE2wonTTAfbx8FW6iQBVC+VqZrhVn1Ap2DB75QIQd9y1nWdK2wVvFmFV+twgJYli82alphAOTNKkYpLID3yGRqWmFbxRsAGXEKoKZVO3QrFugcPDCGCiyA8yZv1mIPkPUKhDFUuBFQ06p5MWp27CRw1ipsgml2HC0rvK7iGXtKcEphH3CaEqplNSXElcyMqgiCFyH2pPA6Vvhcm/UW9E/QloVH4SLEnr1VxwrCeuWn3sLH73zdj/Px9ZBVzqqSGlYtENY/R38YFr6dtix8AFLqLKmrYYUTmf8QnYODiOnCE/C8EDOUUC2rsxETmSfhW2nLAk4K785epG6FXUDvbKNJ4c2qk0IsuUtTqVtBv8IzLWdivpO2PFwHWbXXSieibnVRiC/QOThgDRWlByGdnrU+lK2gsar8KJ2DAd7ydzNklXdWZGWrEd6HIKyhovRpSGanTKaFshUUwMDs7EngzapdkFVjMpWEqtVa1gLIGypkVvlWk1W1ggjIWAB5QwUuIDEubWxUraY5IyBv+QtnlarVath+nE6SHN5QsS1Yq5StsA/I1gQzZ9XnIY3eAAgoWo0x9gGZQwWuSxCcwV/NqmkpYjEbU3hDRekZuFoMLiGmZtUFBTC4mI0pzOXv1yGrPD1ACzWrYca4zhsqSrNClEPryKpZneGL68xZ9aeQVVvJxUXJqgmu7cOLlBnBHCrwCiRiNXclK+yvM1Ur5lCBKzhFrLyvZDXIVq2Yy9+HIKv2kYkXJat72Vor3lCBffVy1Dz+SlbzQvw1nSgZzFl1ElK3mUR8qFjhioa+FXpMYQ4V2FQFOoCEilUPBIvQioYm8IYKLH+L0QsUqFhxtcF1KH8xS3iqWEGw+BKdKRG8oQKXBoouf2pWczzBgjersP0tt5NFEAUrHLjJcMXIHCqeh1T1kEQIBSt8HenH6FwJ4A0V/whZZY1CiELBaoblOpi3/GGnYjp+VRsFq4ssIZA1VGClWgqsS+FFwarM0V9izaqd/wfJCi0i4kHBCq7uEz9i5A0V2FJFdWodFKzg4irxPQvWUIFXipNVF9VRsAL8q0/qw1r+MFLMV1/KSc3qN+mEpnCGCrxTdrnGwnxqVm+lMxrCmVV4p7bmCu5KVgmbK85QIcNf6E5ZECWrhM0VZ6h4BpLjDBaJpQFWnOXv36D8TdReU0zJKtlL6Yyh4l9AalphwUElq0R3OBmzCru0NWK6hZKVZ1FXbRhDxZ+BVLlK789FySpJh4kvVKDUYsxShgGUrBJcCfOVP5RaUlwWV8kqQTeQLVRgnVpSXb69zlZsWaUlpWZlPNSMLVRgO6UuVWcrplCxExcFX4x49hGHkpXpHSam8rfrfyAN5cBj+qrU1YonVFz3/5CEOaV2yqaeVjxZdQOUPjEVdz8zmjrWK55Q8WGUOh16nl0dJSuzyM4SKrDtFft11zFWsvon+hVacJS/XRj8xBClVR0lK6M+O0OouB7jxFLs3fR4lKxMrhoZsuojmFFz8WuOx1Mvq+ShYudJlBo3WpReycpgsEXiULEdS5/YbbbeuZKVfhBMXP5k7CvLJSUNULBaNHiAmjBUXPssSp3Ra3o9KFhd1L8hmDCrZJgwCOgOClb4rFGvz5QsVFgZNaN2LR+NgtXEtG4RTBQqZI0So/EPEhVQsRqAIqjzOlmS8nfDLErNqV8gRqJi1XZZ7+aZeajYJtsoMZIoowAVq8I+yKwfpF9cG+Os2vmAdJpKUqMslKzwNTnlV1+MQwUOdoFuX79Zw+tDyUq+U/vD9MtrYRgqdjwvpQ4Yt1Fe1KxwCibF5/hm5W+7jOZiUuOOSzXUrApDkFl/RCmojkmoIKe5yBGMJihaNUGbVfkRSkQ1DLJqh+VU7q/9XEoVRatCJ5RBhaGP+qHiQ1Z9WhzWvDVRFVWrAjTFClVLM1TcfL9sdMHJ6DIqFmUrXIii8reUmjj0yt/1n5dKojzImU+IulXzZG0tjVCx66NW0RMzW/nqk426VaENh9R9qdo1iXpW7bC6RnAN1cPQ6IbQsCq047o1/xvfz1UNFdsftGqTWBo1udWigI6VtWph5WcocSFUQsXOO20lMbklaSc2Fi2rQgtOfF55MroU1i5/2z5gFzwxv7dO2STRsyoUR/CTyh9QMn1UDxVvuvPTdiaJxX3r61GbXDStCoUenGu+cuynKbEuVbLqurtcI1He111fJUDbqtCGKyiB1yf9PY2YUHHdXfefco3E1J51dVcC9K0KhW5rCYjKF+72XEoGQ8WuO+66719nPUKifLBXZVwLByZWhWIvxnigcvyJT/zuWzF4QPnbec0113zNHXfe9cH7Hzzl0wEuHtiq9bBQg+a2tlAsNbICrx7PMhCV48ePXwh6OJTHd/ewXAoGae4a2D+B69nBH22/M2mRxNAKWD10lnaIY3Fi30B3XYQKhY5BuYyxy1nv3Q5zK6B90+gkXKEEWJqbODQysHENbzfcS8vWiD/oZc+w1URWklXrerb09ff3bd2yuWf92o72unUYbNr24upAkisL549/5t3vvf2xoy/CT65WcqsG07KHSsfyucNy3vFvwn9Kv4paTiHMm9UmnEVdiJUT9kSuN9IW50R03ofOl1UbTkwrxKUj7oSTVlYBmFv2865cWa2XGbV82DOJ5mtpCxx157nIkxXeOhHiuG+2ydfRFngUrgRozxxZjWJiKv5FTJzyB+DC1hSAc2NVPIhpOe+fFtQOFZKfg++pzc+N1QFMyhdJwMabVXm0ksUvuC6BJ1QAuEgZ3YLLiVU/JiQ0K7InVABYr2j3fFhFr7XqK39yfYpcxcBWbKeCdcofKoDH3KTmwgrvKZyntLsEsqr0tBD76YA8WOEKiuEVnPyhAqBVN5AcWDXj9W54VQJ/qLDmkbYHNOTAagjSEJ6+Olj+5AK89rVd9q1aF+HCI1T+gqHCWcxGkn2rYUhCeFL4UFbhioaDdEj2rZrKcO0Rmr8/FCrkImXOzbnMW22Gfvo7KeUON37lV/v5Xozr7tRgmbc6E/Wy6DfS1uXNUADdWdyybtUOCQiPj30VbV1OCbHo3t3KuhVOCBoaEPFq2rrgy/lGs2OnQ9SEoBHPlJ4VYsle9ADIuFUxakLQV9DWBSeH2EOHIBm3WgMFMDjY7TW0dcG5wea9YzYybrU14sWHcKgIzU2XcSu4sA9ahUMFDhT3zw2WcStIXmAQaThU7ACpsidUABm3mgm9WB4KFV8LUu5KIhYZt4L+uv/1w1CouBal7KtFm2xbFeHX+197CIYKmVOhCc+ybdUMv943d2YwVGCdEgdpbxcFq0naNQWCVsFQ8SkpFR7BoWA1RbumAJZAb73yhwrrXc6o+fYCT8LRKqhl3zpMgynfuxz+UIHdpHCgkNBwEJewlWjUiJYIoBX2vPvlDRWvlCOr5wMh3aLFSreHCCuDV1u5wMXcnfldPKFiuyx84l5/42uzHr/zchWsglre3nCjgXpvj9tzQsU2GrI7v4l2CjIok+0hyoqWdkyFDrgUqXxOFsKX4z8777iPRiEv7Y4d2RGsVlejrETc36QR4O1oUXni7o/91q998IGTzmCpxT3RhQ/ppn0cLKugVpp9pkKPMxLGpfqQXVwC2Ue0VfTE2o2iw9+mXj7dH1ySws8G2tEBhCKtFus0ckyRNSNynOXSzOl7+tbWGtMvH3b5sK1CWnETNjeO5mbFmCWf9fuItQqtrpJZ5GNxH+gTY5UXrbCUxypCazzduqVEqxy/HQB1Yq3EYqqRUAU51j4E6pBVlJaY2JRiL6MWxZ7Q9YdE2lSzgs7Tnp4Ue/DxtG/YbY2WDiNtbKsYLaA8NTmRKSanQk2UiyVT2ypXkIxj9dLQIpeXlhWpeKxeAlok4rPKvxZ5+K3yrkUWgM8q11qkIPFb5ViLBCwCVnnVotTbBK1y6UUpdwlb5c6LUu0lyipXXpRiP9FWufGi1AaJs8qDFqU0glgrgA7OJpTGaKpZSegkWYJSFsvVq18GGiFy+rWftK4AAAAASUVORK5CYII='
-wildyellow = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABQUFCQkJDQ0NERERFRUVGRkZHR0dICAgJSUlKysrMTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWlpaXV1dYWFhZWVlaWlpbm5ucXFxdXV1eXl5fX1915U1xa4Ny6oAw68SwrEVwLMe364N3K8Q1rMc1rQf2rAT2LEY2rMdz6Q3wLYnwLgtyLgtwbozw7062ag31LUj1Lgr1Loy1Lw41b8/5pgW5pwW5ZoZ554e6pUW7J8R858L5p4i4qEA56IA5asG4KwK6KIA6aQA66oD5aYd4K8Q47AU9KYA9aEI9KwI+qYD+KYF/KYD+6YI/qYK/qYO/qoA/6wJ86YW8qMa/qYR/qcX/aQa/q4Q/qgc/7AU/7Md6aEl76ck7agu7aoy7ao27a4+5bUi8Kch/qEo/qkh/qsm/qwp/q0s/qUx/qc2/q8w/qs+/7Uj/7cp/7gr/rAz/rE1/rM6/7oz/749xL9C3qNI3qVK3qRQ3qZW3qdY4Kpb4Ktd4q1f7rBE/qxC/q5F/q9I8LZP/rdD/rJN/rlH/rtL8rtX9L9f/rVS/rhX/r5R47Bl5bRq57dt6bty6710/qpp/qlx/qt2/r1hxcBEx8JKycVSzMdZ1sFH18RO2cZV2shczsphycFz0sxq3Mlg3sxo1c9z2NJ6/8BD/8NM/8VU/sJZ4c9x7cF55dN998Ni/sZg/sFo/sVv/8pj/81r8cd//sl1/89w/sx4/s99/9By/9J7gYGBhYWFiYmJjIyMkJCQlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1urq6vLy83dWC4NeJ4tiO6daF5tyW9MuC+NCF/tGB/9WD/tSG+tOI/9eI/tiM/9uU/92c696g/9+g7+Cm8eKq/+Cl/+Kr9ua1/+Sx+ue6/ui8wcHBxcXFysrKzc3N0dHR1dXV2NjY3d3d7fHX/urC/+7N/+/R//DV/vLa4eHh5eXl6enp7e3t9PTg/fXj//fo/vjs8fHx9fX1//ry+fn5//z4/v7+AAAAA7tHUwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABaESURBVHhe3Z0LfBzHXcfv9LRV2ZJl2bGtB7TgpAFaCDblDa1NDJQ3R3gUAjQFysM8CqWFpjQ8WvNooMFASAslNVAIBIihxaaSZSuWH1Iopq6DapM0qWtJlkRKVtYRIlkZ9/+f/d/u7OtuZvZ/t7f5fj7JSbq9vfl6Z387uzs7U7hRA9FUUKFqUcOKVtZcUNmqUNWK1tKcUBljqWJFn25yqLBBEq3oQzmACqySYEUfyAdUZoVYK1o6N1CxfWKsaNFcQUWvELGixfIGlZ4IW9FC+YPK7xKyokXyCBlIgla0QD4hByRgRW/nFbIAVCt6M7eQBqBY0Xs5hkRUK3onz5CJYkVvRFmcmZpsKqZmFqhoEcjFs6I/h1gc7m0rNCGtPUPzVMQgZFPNanITraQp6T1DxVQhG7KiP6os99HHm5beJSqqgqvjWtGfVE43ZdUL0naSCusjdRKtxumDTc4YFddH+kgr+oNCTqRitKpYnaHPVKfY3rku83o6QUX2SLRabqePJNG2afjUXNld9vRm+mM2tIYjI9Gqnz4Rz0tG5mg5Yn4jvZMJm6gUHglWV2j5ONoG4w5/A/RuJpylQlQgK/rNI3lTdZ5YdRdxps8/8u7f/ONfufsdB6cd+D1LrV63SD6xVku0dIS242v4vjN95MD3lZBvkf9/J2plWQkjzcI4q2O0cJhtMh6c8z8tXRTuAq2rtFAWDMliK8RZxWda5xS+53z4+0kF+DZ6lVsrwySMVkGwoh89OmnhAH24oZwjilPpO+gVmBbiFC2YAW1uuX1irJZp2QDD8IYz/VMk4fLt9AocTPhYg4jsWFGreVpUoYitSOf3SYHw6h9wD7zfSgtnwIws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'
-
-
-plusfour = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAwQKBwgHCgQDCAcJDAgACwsLBwgZDxEPFggGGxMAFBQUFxQaFxgZGBUXHBwcDQ0qDw8yEQ8uFxkhExQ8JQsNLw8SKBgEIB8eNxMTOCUAJCQkKCYnKScoLCwsMigpMS8yMTExODU2Ojo6FxVEHB5XICBfPz5AJiZvJiZ0PkA+RRcZVBweXx8gQSsASjIBWTsAXyAgZyEidycnQEA+aUcAcksAe1EBZFk4Q0NDSEdIS0tLT09QT1FPUE5RUVBPVVVVVlZYW1tbYF5hY2NjaGZoa2trc3NzeHd1ent6LSyHMC2SMTSaOjipOzuzPkDAQD+8VliDfn6PQ0LISEjcTU3rT1T4UE7sVFX+XWH+YF78aWnkZGT9Z2n7a2v+d3f9TqtQValUXq5gXrBgYK1eY65kaLNobrZwdrp2fMF7gSsrjjAyky8ymTMyqDg3uDw8tj1AhFcAmGUBvEA9p24ArXQBt3oAgm1AyEA/xkJD10dH5ExM709Q9U5S91JO/lRU/Wdn/25w/HZ1gX/+v4EAgIJ/woMB0Y0A2pIB6poA7qMA/qkA/q4R/bIY/rYl/ro0/YB9/r5B/cJK/cZY/stl/s5y/tBr/dF5goKCh4iGi4uLjIyQkI+Rk5OTl5iXmZeWmJaZm5ubnZ+ggr+CpoaGoJ+eoaKeoqKiq6urr7CvsK+wtLS0ura7u7u7hIT+iYf+ion8lpX9oZ/+vb7Bp6j8sq//tbP7ubX9vLv+icSJj8aRmMuYmNCYoM+gp9OnvsC+sNetu9y7vd/E0JeX/YmJ/ZGP/Zua/aOi/q2w/bu7wb/Bwd+//NeH/duV/eGn/ea3w8PDx8nHycnGysrKw97C0c/O09PT19jW29nX3NzbyMn90tP819j729v9xuLG1+rX3+Hg/cTF/djY4N/74PDf/evG/u/R/fLa5OTk5Ovk6Ofo6Onn6urq5eT+5uj76Of76+v+6PPn7fbw7vD+/eno8e/3/PXm8/Pz8vP99Pn09vn5/PTz+vb6+/r1/v7+AAAADa/O5QAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABkUSURBVHhe7Z1/kCTlWceHutBh6ehQBak76MokaxM1IUELJDqMWsOymc2eIf4gKEYDOZXLJQokaFBAsxopA7kAGrCYTDKlq8aZchwiBiNHDIpSKprjVoeMGfDuvLPwOpdBOT22uSM7Z3e/z/t29/u+T/fbPT2/tu5zf9xM9zs773ee98fzPu+Pzp3ajESq6g2mmB5kUgauCj481UBWBRBVNnxs6rEhw2GkquATMwJkOohE1czYiSLaS1DVgaQzRRcyT+FVzZyhCJy5OFWQaAYBAYSwKkgxk4AEj5AquD+jgAiXoCq4O7OADIeAKrg3w4CQoCq4M9OAFF8VXJ9xQAxVZcHlGadP1FBVcHXmIWpAFVwTsZrLiwvlqWJhcamJj/w8OURVFy5xWMv53JSiLyHCvMEkUQVXwvTK8BemlJJcF1Mlvb2qwaenlzpkNYRFVcH7IHYJPjnVFGVDDFyVXYTPTTnzElkdogreBZgVUXJZmKoKfGYGWIAsB0BUteETM0ELMu3TdVXBax87eS9ltCk6XBkbeh+y7SNVVYf0CWjARwcNuDBGavDVPlJVBUiujgGfTPPZocnDV/vIVKWoVavw0UETLoyVJnw5w1El+IBLkFgd/9eagKlyuUX4coaVEyOAJiRWh3kuEzFVbh6+3ScnVqvE/p9vqnm4MmYEw4iqepBUHdYIteDCuBGi6KKqLiRVRocPTsxUuTX4foaoqgNJlWGmmphL0oYMMIZXpbNSnbyZyYgRqKrC5yboPWavyjfV5EYv2atiplqDCxMgc1Ua85gnONDMXNUyfCpxdcySrFX5pppk9CZrVVNhqsSqGhYgd8Z9U5Wd1hCSWmNv4pOqYkEB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'
-plusfourblue = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAwQDBQUFBwgHCQkJDQ0NDxEPERERFRUVGRkZHh4eDAwmDg4sDxAuFBQuFhY2FxU4GxgzFyE0ISEhJiYmKSkpLS0tMDAwMjQyNDQ0OTk5Ojw5PT09KipNJzFFMTJRPTtcPkA+Qj9hQUFBREZDRUVFSUlJTU1NT1FPUE5QUVFRU1RTVlZWVlVYWVlZXFxaXV1dRkdqSUptUVF0U1N4WFl9YF5hYWFhY2RmZWVlaWlpbW1tcXFxdXVzdXV1eHl4fX19LCuAMjKXMzOYNDmROD2WOzyiPD2pPj+8PUOiXVyEQEanQUepQkirQECwRkyySE21Sk+5RVK1SFS3SVW7Sli/ZGOJZ2iMbGyUcnKXRkjOSUrERknQSEvWS0zcTlTDTVjBTFTXTFTZUFbHUFrFUFbfTU7iUFTjUlbsUljrUlP0VFX+U1jwWVzzWl74XmXuXWH0XGD4Y27bZnLbaXfcbHvccHHfYmvtYmX2ZWr1aGv0a3bpbHD1c3TrdH7qcHT0dXn2en72cIDedYDqeYPrf4ntfID3fID4gIJ/goKCg4OEgoSAhIOEhYWFh4iGiYmJi42KjY2LjY2NjIyQkZGRlJOUlJWSlZWVl5iXmJaZmZmZnZ2djo+1oaGhpaWlqampqqysra2tr7CvsLCxs7G0s7S1tLKztbW1ura7ubm5u726vbu9vLy8hofQiInRgoPug4zuhofwgoP5hozwh4j7i43yi5Hvi5Hyj5D5kZXzkpL9lpr1mZz2m574m6LunKPwnqH5pab9pqj9qKf+qKn+trbvtrb+v7/+vsC+wcHBxMTEx8nHysrKzMvLzc3Lzc3N0c/O0tLS09TT1NPU1dXS1dXV19jW29nX2dnZ3d3dzc7rzNnl1dby3d303Nz43+Hg3uD54eHh5OTj5eXl5+jn6Ofo6Onn6Ojo7e3t4+P95uj86Of96Oj98O/w8fHt8fHx8/Ty9PP09fX19/j29vj4+vf6+Pr3+fn5+vr8+v76+v38/fr9/f36/v7+AAAAAAAAOABVigAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABpySURBVHhe7Z0JfCvHXcdVIaGj5ZRs18JQwNgGYYwplIcPbPN6UI5wPMJVQgiBNq9xWwoh0KQkJCQfwBRjakwNNrYxBozB0JRSwkuaJnYfh12Ba8BgccYVRVL6qIKAqs/Rfh5z/Hf2mJndWWklS/68b94n8q52pflpjv3Pf/4zE7hxHnFUday1MFlIpAi5Kri5pYGkckhUleC2lqcMCbYiVFWBW9qCCiTajEBV2+STDp9fnKoMXNpWHELideyqynBdm2HLLpsquKgNAQEUqyq4oi0BCQSLKni/TQERGLMqeLdtARkIkyp4r40BIWZV8E5bA1IMVXC+zQExuqocnG5zClSNrgrOtj1UDaiCczwn65MXhgZbiqELE2tZSB4PkUNVHcIpGyeTsUCLEp2QCCOdSaoKzljJDgbhI1qTAXFXnakSvr0UhrtbltA8JNVCTlcFx2bK/XBrS9Mr6gvKVZV74b4Wp1sgK0NVwZGJdhElliVTNQr3tAHDkGQTElXbcEdbsAGJNjjEqjiPUjkON6iT3Aa2InCmaUQLkGwDrAr+NFiE6z2wArdqq3CiiczBVxsIVXXC5eokWH53wJkmEoevNhCpqqFWLcGt2hqcaCrr8OUMpOoI/mSMw8XqxFlWec9mHxiBL2ecBHgPYA9crM4i3Kmtw4nm0gnfbhDgq1UILlYmxn6YLjjTXIJcxvCqjuFadRbgTm0TTjSbA/h+Bq/qEC5VJsp+qm4402z24PsZvKoMXKoM6w9swYmmsw0JYNSvysiqFJxpOg1QNQv3naH16L+qCOsKnF3vxX9VM3CbtgcnzgDfVYWZxdwHZ84A31VNwV2eq6Of+K3KyKqz9N74rWoS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'
-plusfourgreen = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABwgHCQcKCwsLDBYMCxgMDRsTEQ0NERkNFBQUEh0RER4bGBUXHBwcFiwWHSkcHygiIB8eJCQkIi4jKCYnLCwsJDEkLTosMS8yMD4vMTExMT0wODU2Ojo6Pz5AI0UjJkslJ00oKkskKU4pL1AmK1EqLlg1NEM0PkA+MVMmNFYsN1knN1kvOlsrM1syMFw6PV0yP2AsNWU0OWU3OGY8PG05NWRDOGhHOmtLQEA+Q2UrRGQ2S2s5THEvSnc0U3c2Q0NDSEdIS0tLT09QQ1JDR1dIT1FPUE5RUVBPVVVVVlZYW1tbR3FAQn5MQHZUVnZBW3xDYF5heHlEY2NjaGZoa2tra35rc3NzeHd1ent6ToE6YpE8Q4FORYJQSo5WTJFWT5dYT5hYUYVFU4dIVIxJW4xKV5BLWJRDWJRMWZlGWZlNUZxYWZ1QTqtQWqJNVKZTU6FYValUVqpYWKpVW6xbXapiXrBgYp9hfZB8Y6tcaa9bbLBdY61kY6xqbK1jY7FjZbJqaLJnbLRsbLJycq1xcrNidrJueLVnebZpfbhucbVzdLl0eLNwerl2e717fMF7dIiBe7OLfLqBgIJ/k456ha9yiLF1jLR8iL98kL1zlMB6goKCh4iGi4uLjIyQkI+Rk5OTl5iXmZeWmJaZm5ubnZ+gg76BhbqRir6UkbqDlL2JoJ+eoaKeoqKiq6urr7CvsK+wtLS0ura7u7u7vb7Bv7/+hcGGh8eLi8ODisOKjMiLjsOUksaNmsSCm8WKnsiMk8SblMqTm8WSmceem8mXmsqdmNCYnsygoMmPo8yVo8yaoc6hpNGjqdGjrNSrvsC+sNetsdextNm0vd28vd/Ewb/BwMy/wd+/w8PDx8nHycnGysrKw97C0c/O09PT19jW29nX3NzbxOHEy+PL0+bS1OnT1uvY2OnW2+zb3OTg3uvg4+3e4fDe5OTk4u3i6Ofo6Onn6urq4/Dj6/Tq7fbw8O/w8PTt8fjv8/Pz9Pn09vn4+Pb3+vf6+Pn2/v7+AAAARX10/QAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABlESURBVHhe7Z0LlCRXWccbayOpaBvT0AkMtkl2zxgSTQCVoCQkzQBqM77i2A6Db3wlm8DauxsUCaxuRCUr4BMkY0sfHYGIPce2MSREMAFizCZZhfgY6dDSmwSXbHpi92qoRam1qu6/bj3u/apuVVf3dM/ZX87JTFfd2rn//u7ju999VO7UdiRSVc+cYnrIpAxaFR6eapBVAUKVgcemHgMZDiJVhSdmBGTaj0TVzNjJRbSXoKqDpDNFF5l3CauaOUMxQuYKqUKiGQQCGEFVSDGTQIJDQBXuzygQYeNXhbszC2RY+FTh3gwDIX5VuDPTQIqnCtdnHIhxVfVxecYZMDWuKlydeZgaqMI1kf76ytJiZapYXFpep0d+jhymqotLIfor+dyUoi8TwpzBJFOFK0F6FfwLU8qCXBdXJb29puHp6aWBrAbou6rw2Y+xgCenmrJsiEGrMsp4bsqZk8jqMFX45GNWRMllUaqqeGYGWESWfRCq2nhiJmgh0x5dWxV+9zCS91KFtouOKxNDHyDbHlJVDaRPQBOPmk1cmCB1/GkPqaoikqtTwJNpnh2ZPP60h0xVilq1hkfNdVyYKOv44xxLleADLiOxOt63tQWmyuWW8Mc5/ZwYASwhsTrcc9kSU+Xm8Nc9cmK1Suz/eaaaw5UJIxhGVNVDUnV4I9TChUkjRNFFVV0kVUbHg1tmqtwG/j5HVNVBUmW4qbbMJWkjA5zRVem8VCdvZjJiDKpW8dwWeo/Zq/JMtXWjl+xVcVNt4MIWkLkqjXvMWzjQzFzVCp5KXB2zJGtVnqm2MnqTtaqpMFViVc0+kDvjnqkqVmuIpP2JN/FJVfGggNwZWsZdx83inlNi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'
-plusfourred = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAgQJBwgHCgQECQcKCwsLCgoeDxEPGQkJFBQUFxQaFxgZGBUXHBwcFxkhJQwLJA4SJA8aLw8SKxELJhISJhEdIB8eLhkZOhwKNxMTKBQlLhYvMhgzJCQkKCYnKScoLCwsMyYnMS8yMTExODU2Ojo6Pz5APkA+RRcZVBweXx8gXyAgYiIeZiMidycnezAifi9CQEA+fVg8Q0NDSEdIS0tLT09QT1FPUE5RUVBPVVVVVlZYW1tbYF5hdld6Y2NjaGZoa2trc3NzeHd1ent6fn6PgSsrhDMkjjAyky8ylz0nmTMyqDg3uDw8gjFEhjNIiDRJlDpUmDxXmz1Ztj1An0EpqEYquU4uvEA9mGhDpUFhrURmsEVpuElsyEA/wVAvylQx1lc25F45xkJDxEhc10dHw01w1Exg2U9h3Xxs5ExM709Q6VdD7FJe9U5S9lZL81FQ8VNc9VtX815Y/lRU/VVY/l1T/Vpa41Bg719u9Vdg81hj8F5s7mZe+GRY/nhW7Wxj7mNy7HFo7Hlx/Wdn/25w/npo/HZ1i2TD3mSF3muK7nCB4XWT4nqVgIJ/3oV14ol7/Yhq/opz/pN6goKCh4iGi4uLjIyQkI+Rk5OTl5iXmZeWmJaZm5ubnZ+gpoaGoJ+eoaKeoqKiq6urr7CvsK+wtLS0ura7u7u7vb7Bv7/+vsC+0JeX442A5oOb6Ied6Iuf5pOI7JyT+omH/ZqG/pWW+5yb6o6g7ZOj8Jel8pyn8p2o7qGZ/qGM+aWa86ei9aGq9Kmk9q2q/aCg+Kat/qyi+ayt/q2w/rKr/bSz/ra7/Lm3/by8wb/Bw8PDx8nHycnGysrK0c/O09PT19jW29nX3Nzb3t/+3+Hg6NnP7t3V/cPC/8DJ/snK/d7M8N7W/dPT/tfZ/tjX/Nrb7dTj89rl+eLa5OTk5+jn6Ofo6Onn6urq9+Li++Xk/ebo/ejm/enp8O/w+fPs8/Pz8fL+9fj09vj4/PPz/PX5+vr2/v7+AAAAAAAAAAAAAAAAAAAAHYHLzAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABlASURBVHhe7Z17lCTVXcfbrCVTxg7xgAmr1qHDWAY87h616ajNYKcnoyjPqDFqiMoGMUIWJwkzm5cuhJBgYghgOm366PjoPrYddZVlMaKJq4kGxeCYTptWdwWJwJZLM+yGMpDtf9aqur97q+re+6u6VV39mrMfOGe7q27N3O/87uN3f/dRudPbkUhV/eEM04dMysBVwcMzDWRVAFFlw2Mzjw0ZDiNVBU/MCZDpIBJVc2MnimgvQVUXks4VPcg8hVc1d4YicObiVEGiOQQEEMKqIMVcAhI8Qqrg/pwCIlyCquDu3AIyHAKq4N4cA0KCquDOXANSfFVwfc4BMVSVBZfnnAFRQ1XB1bmHqAFVcE3Eaq1UlsozxVJluYWP/Dw5RFUPLnFYK/ncjKIvI8K8wSRRBVfC9MvwE2aUklwXUyW9vaHB07NLA7IawqKq4HsQuwRPzjRF2RADV2UX4bkZZ1Eiq0tUwbcA8yJKLgtTVYVn5oAlyHIARFUHnpgL2pBpn56rCj772Ml7KaND0eHKxNAHkG0fqaoGpE9AEx4dNuHCBKnDr/aRqipAcnUMeDLNsyOTh1/tI1OVolZtwKPDFlyYKC345QxHleADLkNidfy/1hRMlctV4JczrJwYATQhsTrMc5mKqXKL8Nt9cmK1Suz/+aZahCsTRjCMqKoPSdVhjVAbLkwaIYouqupBUmV0eHBqpsptwu9niKq6kFQZZqqpuSQdyABjdFU6K9XJm5mMGIOqGjw3Re8xe1W+qaY3esleFTPVJlyYApmr0pjHPMWBZuaqVuCpxNUxS7JW5ZtqmtGbrFXNhKkSq2pagNwZ901VdlpDSGpNvIlPqooFBeTO0DLc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'
-plusfouryellow = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAgQJBwgHCgQCCQcKDAgACwsLCgoeDxEPFAoFHBMBFBQUFxQaGBUXHBwcFxkhIRUCJBkEIxkNKxsCLB8MJhwTIB8eKB8aNhwHLiQOLyQQOCUANisUJCQkKyQlKCcoLCwsMiQnMC0vMS8yMTExODU2Ojo6Pz5APkA+QiUGSjIBWTsAUjceSDojQEA+ZkQCdUoCe1EBflYbZFk4Q0NDSEdIS0tLT09QT1FPUE5RUVBPVVVVVlZYW1tbYF5hY2NjaGZoa2tqdmdqc3NzeHd1ent6fn6PhVcBhFsdiF4fmFwKhl0giF4gmGUBjWEjkmcomWsqp2YKrXQBtmsOvW8Qt3oApXMvpnQwrXgysHs0gm1AynYQ134Ri3ewv4EAuIE1gIJ/t41rwoMBxIYe1YgG24AS2pIB1JAe2ZQcw4g23bU054cR65gD5ZsX4pkY654T9ZsH7qMA7aAS764X7q8Y7bAe9KQA8aIO86sM/KUB/qYM/qkA/a0L9KYU86YY8K0S/qYR/q4R/qga/bIY76gq76My7qkw7LMl6bg48Kcj/qMv/qol/qwp/qc2/rYl/rg03qBH3qJM36dV3rpA7q9B4atd4r5M5L9Q/q1G/bNK/rVU4q1h5LFl57Vr6Ldu6blv671z/b5j48BP5cFV+8FK/cZY68hn7cB278N578xw/cNr/stj/Mtq8cV88c508sh+/sdy/cx0/c15/tBr+NF6goKCh4iGi4uLjIyQkI+Rk5OTl5iXmZeWmJaZm5ubnZ+goJ+eoaKeoqKiq6urr7CvsK+wtLS0ura7u7u7vb7Bv7/+vsC+wb/B9cuB+M+E9tOC+NKE+9WI+9iH/diL/dqT/eGn/ea3w8PDx8nHycnGysrK0c/O09PT19jW29nX3Nzc3t/+3+Hg7N/Z7OnI7eLU7uLY++nI8+XZ9e7T9erZ/OzT+u7Z9/DW+vDV/fLb/Pje5OTk5+jn6Ofo6Onn6urq8O/w/fXl8/Pz8fL+9fj09vj4+/X1+vf6/Pr1/v7+AAAAeSzGFgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABkISURBVHhe7Z17lCTVXcc7Z0MJW0nL48ghYpn2ZKyTTdRBbSZ6OsOknUzAXVazCEoE8ahIlGDccExkMyDqRkN8gM9FwAdhYGMCEqP06djqGLu1bZ/Bw7JDOi2tEjcEsmNl004Z4vRaVfd3b1Xde39Vt6qrHzVnP/vHdlfd7rnf/t3H7/7uowqndyKRqvrDGaYPmZSBq4IPzzSQVQFElQ0fm3lsyHAYqSr4RE6ATAeRqMqNnSiivQRVXUiaK3qQeQqvKneGInDm4lRBohwCAghhVZAil4AEj5AquJ9TQIRLUBXczS0gwyGgCu7lGBASVAV3cg1I8VXB9ZwDYqgqCy7nnAFRQ1XB1dxD1IAquCZitVaWFiszxeLScgsf+XlyiKoeXOKwVoqFGUVfRoR5g0miCq6E6VfgG2aUBbkupkp6e12DT88uDchqCIuqgvdB7AX45ExTlg0xcFV2GT4348xJZHWJKngXIC+i5LIwVVX4TA5YhCwHQFR14BO5oA2Z9um5quC1j528lzI6FB2uTAx9ANn2kapqQPoENOGjwyZcmCB1+NM+UlUlSK6OAZ9M89mRKcKf9pGpSlGr1uGjwxZcmCgt+OMMR5XgAy5DYnX8X2sKpioUluCPM6yCGAE0IbE6zHOZiqkKc/DXfQpitUrs//mmmoMrE0YwjKiqD0nVYY1QGy5MGiGKLqrqQVJldPjg1ExV2IC/zxBVdSGpMsxUU3NJOpABxuiqdFaqkzczGTEGVTX43BS9x+xV+aaa3ugle1XMVBtwYQpkrkpjHvMUB5qZq1qBTyWujlmStSrfVNOM3mStaiZMlVhV0wLkzrhvqorTGkJSa+JNfFJVLCggd4aW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'
-
-
-bluebutton = b'iVBORw0KGgoAAAANSUhEUgAAAGMAAAAnCAMAAAAsLAbdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAE5a71VV/kZq1ICN7pal7QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJIhjsUAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAAzElEQVRYR+2X0Q6EIAwEgaP//8lYoLVgcomJ3T4Y59EYJrtGKKldIAdkKWVzEP1ycaDumsVBVV7xoC4Wc3gaOlXWNQe5lLSRNYo4vENMJMp0YBQqGQ6UopRRV3eQPACQ1YGLMdtiBzAGw22xAxljBEngGD1IjANbVS8roWNwkM9xm89xnxhHxD/4mv0qYm8POaMiztrW/Oc35ZwZgG2dsw+urWWGg4y7zFSoA/JNRGEO977sBmKOiDsOQ06a/PeuNpBb4zNkLeXq8Ke1A1yYxppnbkkqAAAAAElFTkSuQmCC'
-greenbutton = b'iVBORw0KGgoAAAANSUhEUgAAAGMAAAAnCAMAAAAsLAbdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAGmCwCqAAyjKU/AWXHLfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFeD53sAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAAzElEQVRYR+2X0Q6EIAwEgaP//8lYoLVgcomJ3T4Y59EYJrtGKKldIAdkKWVzEP1ycaDumsVBVV7xoC4Wc3gaOlXWNQe5lLSRNYo4vENMJMp0YBQqGQ6UopRRV3eQPACQ1YGLMdtiBzAGw22xAxljBEngGD1IjANbVS8roWNwkM9xm89xnxhHxD/4mv0qYm8POaMiztrW/Oc35ZwZgG2dsw+urWWGg4y7zFSoA/JNRGEO977sBmKOiDsOQ06a/PeuNpBb4zNkLeXq8Ke1A1yYxppnbkkqAAAAAElFTkSuQmCC'
-redbutton = b'iVBORw0KGgoAAAANSUhEUgAAAGMAAAAnCAMAAAAsLAbdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAALhqYuVaWP5VVeSNi+KlogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPXdpGwAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAAzElEQVRYR+2X0Q6EIAwEEej/fzIWaC2YXGJy3T4Y59EYJrtGKKndIAdkKWVzEB25OFB3zeKgKq94UBeLOTwNnSrrmoNcStrIGkUc3iEmEmU6MAqVDAdKUcqoqztIHgDI6sDFmG2xAxiD4bbYgYwxgiRwjB4kxoGtqpeV0DE4yOd4zOd4Towj4h98zX4VsbeHnFERZ21r/vObcs0MwLau2QfX1jLDQcZdZirUAfkmojCHe192AzFHxB2HISdN/nlXG8it8T9kLeXu8Ke1E2qb0ylAVTgZAAAAAElFTkSuQmCC'
-
-
-blank = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAszD0iAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAAFbSURBVHhe7c8BDQAwEMSg+Td908GnOODtolaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5WjlaOVo5Wjour7QMC20VI3QCuyAAAAABJRU5ErkJggg=='
-
-plusfour = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAwQKBwgHCgQDCAcJDAgACwsLBwgZDxEPFggGGxMAFBQUFxQaFxgZGBUXHBwcDQ0qDw8yEQ8uFxkhExQ8JQsNLw8SKBgEIB8eNxMTOCUAJCQkKCYnKScoLCwsMigpMS8yMTExODU2Ojo6FxVEHB5XICBfPz5AJiZvJiZ0PkA+RRcZVBweXx8gQSsASjIBWTsAXyAgZyEidycnQEA+aUcAcksAe1EBZFk4Q0NDSEdIS0tLT09QT1FPUE5RUVBPVVVVVlZYW1tbYF5hY2NjaGZoa2trc3NzeHd1ent6LSyHMC2SMTSaOjipOzuzPkDAQD+8VliDfn6PQ0LISEjcTU3rT1T4UE7sVFX+XWH+YF78aWnkZGT9Z2n7a2v+d3f9TqtQValUXq5gXrBgYK1eY65kaLNobrZwdrp2fMF7gSsrjjAyky8ymTMyqDg3uDw8tj1AhFcAmGUBvEA9p24ArXQBt3oAgm1AyEA/xkJD10dH5ExM709Q9U5S91JO/lRU/Wdn/25w/HZ1gX/+v4EAgIJ/woMB0Y0A2pIB6poA7qMA/qkA/q4R/bIY/rYl/ro0/YB9/r5B/cJK/cZY/stl/s5y/tBr/dF5goKCh4iGi4uLjIyQkI+Rk5OTl5iXmZeWmJaZm5ubnZ+ggr+CpoaGoJ+eoaKeoqKiq6urr7CvsK+wtLS0ura7u7u7hIT+iYf+ion8lpX9oZ/+vb7Bp6j8sq//tbP7ubX9vLv+icSJj8aRmMuYmNCYoM+gp9OnvsC+sNetu9y7vd/E0JeX/YmJ/ZGP/Zua/aOi/q2w/bu7wb/Bwd+//NeH/duV/eGn/ea3w8PDx8nHycnGysrKw97C0c/O09PT19jW29nX3NzbyMn90tP819j729v9xuLG1+rX3+Hg/cTF/djY4N/74PDf/evG/u/R/fLa5OTk5Ovk6Ofo6Onn6urq5eT+5uj76Of76+v+6PPn7fbw7vD+/eno8e/3/PXm8/Pz8vP99Pn09vn5/PTz+vb6+/r1/v7+AAAADa/O5QAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABkUSURBVHhe7Z1/kCTlWceHutBh6ehQBak76MokaxM1IUELJDqMWsOymc2eIf4gKEYDOZXLJQokaFBAsxopA7kAGrCYTDKlq8aZchwiBiNHDIpSKprjVoeMGfDuvLPwOpdBOT22uSM7Z3e/z/t29/u+T/fbPT2/tu5zf9xM9zs773ee98fzPu+Pzp3ajESq6g2mmB5kUgauCj481UBWBRBVNnxs6rEhw2GkquATMwJkOohE1czYiSLaS1DVgaQzRRcyT+FVzZyhCJy5OFWQaAYBAYSwKkgxk4AEj5AquD+jgAiXoCq4O7OADIeAKrg3w4CQoCq4M9OAFF8VXJ9xQAxVZcHlGadP1FBVcHXmIWpAFVwTsZrLiwvlqWJhcamJj/w8OURVFy5xWMv53JSiLyHCvMEkUQVXwvTK8BemlJJcF1Mlvb2qwaenlzpkNYRFVcH7IHYJPjnVFGVDDFyVXYTPTTnzElkdogreBZgVUXJZmKoKfGYGWIAsB0BUteETM0ELMu3TdVXBax87eS9ltCk6XBkbeh+y7SNVVYf0CWjARwcNuDBGavDVPlJVBUiujgGfTPPZocnDV/vIVKWoVavw0UETLoyVJnw5w1El+IBLkFgd/9eagKlyuUX4coaVEyOAJiRWh3kuEzFVbh6+3ScnVqvE/p9vqnm4MmYEw4iqepBUHdYIteDCuBGi6KKqLiRVRocPTsxUuTX4foaoqgNJlWGmmphL0oYMMIZXpbNSnbyZyYgRqKrC5yboPWavyjfV5EYv2atiplqDCxMgc1Ua85gnONDMXNUyfCpxdcySrFX5pppk9CZrVVNhqsSqGhYgd8Z9U5Wd1hCSWmNv4pOqYkEB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'
-
-wild = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABQUFCQkJDQ0NERERFRUVGRkZHR0dICAgJSUlKCgoLS0tMTExNTU1OTk5PT09Pn4AQn4AQUFBRUVFSUlJTU1NUVFRVVVVWlpaXV1dYWFhZWVlaWlpbm5ucXFxdXV1eXl5fX19az+RUUGvU0G0UkK4TUrcUVH0U1P6VVX+XV30Wlr+YmH9amr/bm7/cnL/eXH2e3v/BJUAFYUAGIQAAKMAAKoAC60LEa8QE7ASGrIaI7UjKbcpK7grM7cpNbgqMroyPL08e4UAZb48Qb9BRMBETMNMVMVUWcdZXchdY8pja81rcM9wddB1fNN8Z5a2cJuqlkJ0mkNyzktfykpg81FS+lNT/lVV/1tb819p/l9g82Bs/2Ji/2ho/21t/3Jy/3t7vHy+gXn2mn3hvH3A3W+Q3XCSgYYAl749mL08vZUAwpYAyrcpyLgq7aMA7K8Q8KQA/qoA/6wJ/68Q/7AU/7Md/7Uj/7cp/7gr/7oz/7499Zhr/5ZnzsBD/8BD/8NM/8VU/8pj/81r/89w/9By/9J7gYGBhYWFiYmJjIyMkJCQlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1urq6vLy8hIT/k5P/mJj/gKfCoZjYpJzYoaH/pKT/qqr/rq7/s7P/u7v/gtWCiNeIi9iLk9qTm92bo+Cjq+OrsuWyuOe4vOi8/4KC/4yM/5CQ/5WV/5ub/6qF/qOj/6mp/62t/7Ky/7W1/7m5/76+wcSDwcaJ/9WD/9eI/9mO/9uU/92c/9+g/+Cl/+Kr/+Sx/+e5/+i8wcHBxcXFysrKzc3N0dHR1dXV2NjY3d3dw8P/ycn/0dH/1dX/3Nz/w+rDy+3L0e/R1fDV3PPc/8LC/8XF/8vL/9TU/9nZ/9zc/+vE/+7N/+/R//DV//La4eHh5eXl6enp7e3t5eX/7Oz/5PXk6ffp7Pjs/+Pj/+np/+3t//Xj//fo//js8fHx9fX19PT+9Pv0//Hx//X1//ry+fn5+Pj++fz5//n5//z4/v7+AAAAwISkTAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABclSURBVHhe3Z15YBXHfcff0wkoQIsQAnNIpGlcFWLqtEGA6tYkMTS2oadLDzdO77vp5TZNL/cIt7ksuWnrxA6JDxK7pooP2rShcVqQkKjrJG0wmKa20GsOgRspAeTgob/fzG/v3fdmZn/v7Vt//rCl92af5sPb/e7szuxM4WoFRF1BlapEBSv6sPqC6laGslb0KfUJ1TGWMla0dZ1DlQ2SaEUb5QCqsJ8EK9ogH1CdfcRaUencQNX2iLGiormCqu4QsaJieYNqT4StqFD+oPorQlZUJI+QgSRoRQXyCTkgASt6O6+QBeC3ojdzC2kAPit6L8eQiN+K3skzZOKzojeinDw+0F9XDBwfpapFIBfXil4OcXJ5e1OhDmmc1z1CVQxCNuWs+ufTh9Ql7Qeomn7IhqzoRT/jHbR53dI+RlX1oXSUFb3kZ39d7npBmvZQZT2kTqLVbtqwztlB1fWQPtKKXvCRE6kYrTJWB2ib8hSbW2dkvp/upSq7JFqNN9MmSTTNX75vuKTK7l9AL2ZDYzgyEq06aYt4Xrd1mMoRI3PpnUyYT7VwSbA6RuXjaOqKO/0to3cz4R6qhANZ0W8uyV9V664pKiMunX3+qY//zX33Pyd/y1KrXdbAR6zVGJWO0LRzWpW4cOTxd24BfrAHuO4/8KUsd8JIszDOajsVDrNYxcOlp9+FRsBtb0Srnp4H4NUTVCgLumW9fMRZxWda64B88/zhHyOnLVter6R6evDbyjAJo7sgWNGPLq1UOECH/KIu+Jy2/Mi1JNWzCt7aRwUzoAmr5ifGapzKBlgu33rK57Rly7eSEwCREbtZjYgcWFGrESrqoyhbkRPO8aSQUUHgkdVI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'
-
-
-b0 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sbH/srL/tLT/trb/uLj/urr/vLz/vr7/xMTExcXFxsbGx8fHyMjIycnJy8vLzMzMzs7Oz8/P0NDQ0tLS1NTU1dXV1tbW19fX2NjY2dnZ2tra3d3d3t7ewMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/4uLi4+Pj5OTk5eXl5+fn6Ojo6enp6+vr7Ozs7u7u7+/v4OD/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/8fHx8vLy8/Pz9PT09fX19/f38PD/8vL/9PT/9vb/+Pj4+fn5+vr6+/v7+Pj/+vr//Pz8/f39/Pz//v7+/v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV9lm+wAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABGoSURBVHhe7Z3nf9vGGYBNUpRESZa1t+RYw5qWrdnldKRO26TWHrakNt21ZI2kaTSahLRp/uEsSLw4HHAD7x1ADP/4fLF4OMh4BBC337tX/hiRWX36QynGfP9zuEwOQqu/wcmx5iu4WDcCqw9wWux5DxfshGsFZyQEuGgajlVi7pPFO7hwG8YqEd8nN3+Gi7dwWyXuRpm4vl4uK8iUQEDAxGH1AnIkkl+CRAXa6ks4nlBegIYBZfUFHE0sn4EIbfUpHEswYEJbwZFEAyq2FaQnmw8gY1l9B+kJ5xvTBqyeQ2riMXXACtIYbvYWhnu6OmNFV8/Ik/0buECGqo5p9Q9IcrE/nE7FlPToIVykiz/ZVpDiZP8B/IaY0vkKLtQJsfo3JNDcTcLJ8SU9k4eLpfmrZQWfac7vw6mxpuMKLpcGrH4PHynO2+C8mPOAo/XctIJPFJcJkUql2q/hkm2MophrVRyAcxLAKFwzRdWKbYCswBmJYAMu2uZXFSv42eYyCydQdIyvvH578fZoZbwDUuJCE1Mgv+dazUJ+QsPEGzhU4c0kxzpCFuG6bHhW+SbIbvHY/de4nY5TnaO1CJdF4FmtQ26g7QDSaQ7j9JLchosiGFZ/hx8Jn0Bmk75bSHZy1w/HY8AUXBPhi3tsD2A7ZK7SdwepbmKk1Q2XRPjuHvMA3kLeKt0iKUOrB/JETqYAl0RgrY4gb4XsW0jkcR6bV+EZXBGBtTqErBWWIY1PbArrE7ggAmt1AFkNuql3ZmGzL5fN9W3Qd7sX8kXNMVwPQWq1CUkGyy2QlnsGKQZbkBY1SlYt9n1ZgKQKc5Bm1IJbISlilKzmIcUpRWs50yNDyYpUKt5A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'
-b1 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sLD/srL/tLT/trb/uLj/urr/vLz/v7//xMTExcXFyMjIycnJy8vLzc3Nzs7Oz8/P0NDQ0dHR09PT1NTU1dXV1tbW19fX2NjY2dnZ2tra29vb3Nzc3d3d39/fwMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/4ODg4uLi4+Pj5ubm5+fn6enp6+vr7Ozs7e3t7u7u4OD/4uL/5OT/5ub/6en/6ur/7Oz/7u7/8PDw8fHx8vLy9PT09fX19vb28PD/8vL/9fX/9vb/+Pj4+fn5+vr6+/v7+Pj/+vr//Pz8/f39/Pz//v7+/v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqB9+GQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAA0jSURBVHhe7d35XxNJGsdxkgAiioiI4sUI3iKisLizs8fs7LrXzIrKeONezs4oLLDrjGhGBzTmD8/28U1fVZ081fVUH3n15xdD6DT9NpCrq6v7Wr1YR9WrZo57/1tspaRY1Ve4ca77DhsbLUb1E26W/36BLQ4lVX3ELYrR59jqQBLVWyxdmD5iw/0E1R+xaKH6Lza+XVRVuDsKYfNRRIVlCtivIXAKq7BEIfs7DHZB1af4fkF7BoZVUIXvFrZ/wRFS4XsF7i+QBFT4TqEDxVd9wDeKHTBt1T9xdcF772raKlxb+L50NFDFvZ6tP5yfmjg0lq8OH59d2cIGCjkcV/U5roq0Ol2r5LXJuw1sZbhXvgrXhHs6gRXktP23saHhPNUXuCJYYy6/91O7qdfY2GBv2yp8HexNzu8ot73PsbnB4lVvDuN2OW9IwvrGVb3Dl371gqAs1gtsciBXhS8CncNtCtDYLrbZL0b1ALcoRLPYaL//2arv8YXXzj7cwK26tIkWcU2uqop/WrYKF/1uYHm36i1c3WzewVX5ahpb5ydVHcLiTgFUTlW1bWyel0z1BEs7BVE5VVWuYvO8vpKo5rCwXQiVV9VRbJ7X+77WX3HR6yQWtgqj8qoaFF7n9rV+cC/4DWNhAZVXVWUN2+fVJ7y1qmNREZVb1Qq2z6tP+LPaxqIiKrcq4S2JqNrEopWDuMIvryrhv5+i8l5p9ZJq6ywu9JJq64D3fNA7qq0D/rNcz6gsVO+pbFTPqRxUr6lcVI+pgOot1T6gekvlVaoyqVR5lapMKlVepSqTSpVXqcqkUuVVqjKpVHmVqkwqVV6lKpNKlVepyqRS5ZWJamh07ND4xJHJ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'
-b10 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX9Vlb9WFj9Wlr9XFz9Xl79YGD9YmL9ZGT9Zmb9aGj9amr9bGz9bm79cHD9cnL9dHT9dnb9eHj9enr9fHz9fn79vb29gID9goL9hIT9hob9iIj9ior9jIz9jo79kJD9kpL9lJT9lpb9mJj9mpr9nJz9np79oKD9oqL9pKT9pqb9qKj9qqr9qqr+rKz9rKz+r6/9rq7+sLD+srL+tLT+trb+uLj9uLj+urr+vLz+vr7+wcH9wMD+wsL+xMT9xMT+xsb+yMj+ysr+zMz+zs7+0ND+0tL+1NT+1tb+2Nj+2tr+3Nz+3t7+7+/v4OD+4uL+5OT+5ub+6Oj+6ur+7Oz+7u7+9/f38PD+8vL+9PT+9vb++Pj++vr+/Pz+/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJ0rWgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABVmSURBVHhe3Z1pQ9u8loAnCRC2t5R1WFrKTgtcLkOBoTBwoSwt20BfoMOSBP//P9FxkhNZ8jmSj2THce7zBZAd8IM3LUdH//Enmv+Er+1DtJWXTeDoaExW8PnsAseJ0VrBB7MOHG0IjRV8ph2AI1agrGD3tgEOWwJbwa7tBBx5ALKCHdsMOPgGYSvYq+2AwwdCVrBPGwICdVQr2KMtAYUaihVsb1NAoopsBVvbFtDwkaxgWxsDIv9mVkIrsIINbQ2oBFZQ3uaATMMKSkNU7g6WxocHs8Xw2MLeTQWOMEzdBqygTOV5669cVuld/w1HGaKmo7cqfemE35BNCgsvcKQKNZ26FZTIXL2DT2eXvnM4VgWT1W4ePppp1t7gcCWEFfwssQMfyzqrWEtv9Q0+lH3W4IglwAp+CrgtwGfaAHxv1a3gh4DyIHyiHejDT0LaagM+QNA5urx/9ev+/tf1weexLihsLYtw1AGkVakb9g/TvXKnvNIrv9Z6YVML6XiCwxGQVvuwe4jxozLsIFE+noDNrWMDjkVAWg3D3gpDN7AVcUvunyJ9qE5IWL3AzjKFDeI8Nah87YDdWsQdHIjAt4LvBOewr8QI+pzKrxHYsTUcwGEICKtN2DdgXlftF1QWYdeWsARHISCs5mBfwedIKZ8V2LkVTMAxCAirT7Bvg2Uoj+AL7N4CRuEQBITVR9gXmFPP1MPe0mh3Z2fP4OfTVygCFuAD6TMMRyCItHovP/wqJ1NSA6Uwdiwbl4egPHWsrfLXUFrl+j2UCj7AlhotqxNbW61CoU9pBTUke/+GbXXWoThtbK0GguvvZRTKAkJSXhmdy3SwtfoJZb4UvmvCUp53CVtS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'
-b11 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX9Vlb9WFj9Wlr9XFz9Xl79YGD9YmL9ZGT9Zmb9aGj9amr9bGz9bm79cHD9cnL9dHT9dnb9eHj9enr9fHz9fn79gID9goL9hIT9hob9iIj9ior9jIz9jo79kJD9kpL9lJT9lpb9mJj9mpr9nJz9np79oKD9oqL9pKT9pqb9qKj9qqr+rKz+rq7+sLD9sLD+srL+tLT+trb+uLj+urr9urr+vLz+vr7+19fXwcH9wMD+w8P9wsL+xMT+xsb+ycn9yMj+y8v9ysr+zMz9zMz+zs79zs7+0ND90ND+0tL+1NT+1tb+2Nj+2tr+3Nz+39/+4OD+4uL+5OT+5ub+6Oj+6ur+7Oz+7u7+8PD+8vL+9PT+9vb++Pj++vr+/f39/Pz+/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5tFg+wAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAA+7SURBVHhe3d15Q9NcFoDxSQtlE0VBQUVBXhdAZFwYZYZRX8dxGFFRVJB9Yr7/d3CS3JM0yV1yzrlJmuvzT7FNSn4CbZrl5i+/fscwqqBtwXLpM6rgSdoZLKMygwrmbm+wnIq0Kpiz5cHCFtOoYCYHggXOp1TBDI4EC51NoYKJHQoWvJ+sgindCpY9SVLBZK4FSw8VVTCRgwEgrqCCKZwMCFF5FTzuaIAIy6rgQXcDR04FDzkcQLIqeMTpgNJXwf2OBxiz6uf+q+W56cvt6srVO892z2AJCwEmUcG9uc42r3htrffgOyxlPqEBFdyXzX8yCs/QzjrzB7Ck2QRHqOCubN+vwdztrbf5ExY2U+yJVXBHtu1hmLXVLfiwuP1S1f/gjkzbXZiv5d2WWKkK/p3pvSMoHStU/R3+2e+o3a8TuTZgmdNAJf3J/bwFc7jQcPEVHlTwr36vYQap6wc/CrXghzoLS52mUU3D9HKLxd/iMXhgkO3CsiSpVbswtaoiqw2qRViWJLVqEaZWVmC1QdU9goVJUqrGYWp1j2EqURtU3htYmKRIBV+m/YBp1c3mV5ZboVqBhUlTqN7AtMoKqHao5mBh0hSqdZhWVRHVDtU4LEyaQvUQplUkodqhGoGFSVOoVmFaORnVDlUPFiaNolKg3FepUM6rlCjXVTLqQ7SW4bZKRr2IV56cVqlQ8Tqhyyo1KmI5rNKhQlYrNgWwVGrU6MfL4uHBx1FpUHvBXls2RDFUWlQQrIgpBh5dZUAFhx0xzaAjq64ZUEFwXUw06KiqiRO4My2LCp6JqQYdVVXcIpBHBR/EVIOOqLoGd6XlUcGhmGzQEVWbcFdSARWciMkGHU3V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'
-b12 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAQEBAgICBAQEBgYGAwMKBAQMCAgICgoKDAwMDg4OEREREhISFRUVFhYWGBgYHBwcHh4eDw8sICAgIyMjJCQkJiYmKioqLCwsLi4uMzMzNDQ0ODg4Ojo6PDw8Pj4+GRlLGhpQHR1WHx9cIyNoJSVuJyd0LS10QUFBQkJCRERERkZGSEhISkpKTExMUFBQVFRUWlpaXFxcX19fYGBgYmJiZGRkZWVlZmZmaGhoampqaGhvbGxsbm5ub29vcnJyc3NzdHR0dnZ2enp6f39/MzOYNTWfPT23Pz+8RkbSSEjWSEjYSkrcS0vgUFDuU1P3VVX9Vlb9WFj9Wlr9XFz9Xl79YGD9YmL9ZGT9Zmb9aGj9amr9bGz9bm79cHD9cnL9dHT9dnb9eHj9enr9fHz9fn79gICAhYWFhoaGh4eHi4uLjIyMjo6OkJCQkpKSmpqam5ubnJycoKCgo6OjpaWlp6enqampqqqqrKysrq6usLCwsrKytbW1tra2ubm5vLy8vr6+gID9goL9hIT9hob9iIj9ior9jIz9jo79kJD9kpL9lJT9lpb9mJj9mpr9nJz9np79oKD9oqL9pKT9pqb9qKj9qqr+rKz+rq7+sLD+srL+tLT+trb+uLj+urr+vLz+vr7+wMDAwcHBwsLCxsbGyMjIysrKzMzMzs7O0tLS1NTU1tbW2NjY2tra3Nzc3d3d3t7ewMD+wsL+xMT+xsb+yMj+ysr+zMz+zs7+0ND+0tL+1NT+1tb+2Nj+2tr+3Nz+3t7+4ODg4uLi5eXl5ubm6Ojo6+vr7Ozs7+/v4OD+4uL+5OT+5ub+6Oj+6ur+7Oz+7u7+8vLy8/Pz9PT09vb28PD+8vL+9PT+9vb++Pj4+vr6+Pj++vr+/Pz8/f39/Pz+/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA47wMlAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABQYSURBVHhe3Z35Yx5HfYc3xuCYkoQU2pCkCRRoS5NACKRHWrcQWtrSlqL79KXDJUBaWo42TeqCfMiyJVu+FFk+YlEITUvSxrIl+bZJaRNZliyIdQS95dX+Je6++352d2Z3dvY7++7su8vzi0ezs8fj932/Ozs7h3FLytfxb5b4Pv6VILcyMwsuMIS8WpXARQqQWWHnLIMr9RNuhf2yDq6WJ8QKu+QCXDKL0ArFcwMu20NkhbJ5AlfuELRCuZyBiwcBK5TKH7h+G78ViuQRGJTwWaFAPoGDBW+FzXkFFj4rbMwt0OCssCnPwISxwoZ8AxfXCtl5pyzjWCHTz9zE0I6uzdmio7tv5MISLtDPim0DK+TxFMd7arJKff8VXKWPV0o6EqvT7ThCRum+igvlKemUrZDBMt+HnbNL3XARF8viWuFvlqkW7JppuhdxuSzhVlPN2C/jdAm0Qq2u5UTK0goGQ1jhL4/CZuyTAwZxzQwhVoexRy44j4v2EFtdrcUOJOq3HDw9NTM7fe7IrlZkpUrbMi7bxbZC2qMf5SmsP7qAvSyKE9uRnSancHYXodV8HYpH0zzmv2Nc24JN6dG5gnM7CK2GUTqaXfPYhaF4rB5bU+MyTu0gtCJX/kawg4+rad8WhnFiB5FVsRGFoziKHQKkfQvvxXldBFbTKBuF/3+IYaoBZdKhFad1EVhNoGwEPaKapcMLKJQS/vqFZYWUyxiKymmYQXEx6Ub4QNAKWp1CUTnsj2pueGNTY9seNhTN0u8OCXADZ3WJadXofeiLexyDzovIstiNvFRIysqrUy52Isui4QIyTfMSslIhKaspFOakOK1NyEqDhKyaUDZQvV/vRsZB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'
-b2 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sLD/srL/tLT/trb/uLj/urr/vLz/vr7/xMTExcXFx8fHycnJzMzMz8/P0NDQ0dHR1NTU1dXV1tbW19fX2NjY2dnZ2tra29vb3Nzc3d3d3t7e39/fwMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/4ODg4eHh4uLi5OTk5eXl5+fn6Ojo6enp6urq6+vr7Ozs7u7u4OD/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/8PDw8fHx8vLy8/Pz9PT09fX19vb29/f38PD/8vL/9PT/9vb/+Pj4+fn5+vr6+/v7+Pj/+vr//Pz8/f39/Pz//v7+/v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/IkxoQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABI6SURBVHhe3Z1pQxRHGoBhZhgmIIcgAh6IqAiIiCBmc+2VZLNZRUUO0exu9gxyyF5JYFizg47zu2f7eLu6uuvouvoony/MVPeM9dg9XfdbHe33Ea7VP1oF5t2XkEsKTKtP38Gni8z3kNk4DKsf4GPF5wvIcQSq1U/wCTv4BnKNQbEq9K+JykeQcwRpBWdaxWvIe0Dcyr4L5QPZB2JWb+Ek+/gDGHhEreAMK/knOLhErOC4pfwAFg64FRy1llALs4JjFvMdmGBWNtSQkgiqhsjq33DAbkAmsPoEkm3HtwmsINF6/Oc7WLHq6I3tpasjQ2eLxfDYzOo+ZJDA0wErSIqxd7PaWVSG7jcgl1HeuTq+FfX5d3AJvqCg1O42IacRQitIiHC/uNcp4Dz1Pgys3sB7jOYV+GSh6XoK2cUJrOAtRnMCPldwKhStN77VH+FtiC1SnZ3ldcgyhm8FbzCW4DMWUDuCPId8Rrfa64KP2MBlyHTIO9fq5/AmZBQ+gNFzeWF992B/Z3VmtAJJReER5DrEtSJa9dtwesj4E6xoOF48A8nFYBjyFeJawcuQSTg94PxLOBDQfFiDQ4VgG7KF+JxidVSGs30qtCL86DIcLQJXIVOINxSrR3CyT+0FJMe4A8cLQA9kKYRiNQsne9R2IJVgEc4oAK8gS4gOsr2IPwG7mFKt1m04J3+eQI4QHe2v4BWiB851uQdpNJqUAiAfFiBHiI721/AK0Q3nOoxDEp39ohTW85AhREf7t/AKEbZAygeQ5LI92VvtHpg/hLcuRflpzUF+EB3tb+EVIrS6AikOW8OQVp6sQ1KrVS/IxZKzegYprdYmlv/hUOsGJOWMlNUgJESl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'
-b3 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sLD/srL/tLT/trb/uLj/urr/vLz/vr7/w8PDxMTExcXFx8fHyMjIycnJy8vLzs7Oz8/P0NDQ0dHR0tLS09PT1NTU1dXV19fX2NjY2dnZ2tra3d3d3t7e39/fwMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/4eHh4+Pj5OTk5eXl5ubm5+fn6Ojo6enp6urq7Ozs7e3t7u7u4OD/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/8PDw8fHx8vLy8/Pz9fX19vb29/f38PD/8vL/9PT/9vb/+Pj4+fn5+vr6+/v7+Pj/+vr//Pz8/f39/Pz//v7+/v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEN6WYAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABLjSURBVHhe3Z37Q9RGHsCbfYE8RUBARUBQFBEBxbZ3vWvv0bve9RQRxQW37fXaayvKo71rC2x7Ze26//beJvvdySTfSfKdx24SP78Ak2TJZ/OazHznO2/V30TCrL6sJZlPYS9FBFr9ChsnmV9gXxFiq69hs+TzOeyxF5HVf2GLdPA17DUPtvoM1k4PH/0Gdp2BrGDNVPEa9p3hs/oE1ksbH8L+A16rn2Cl9PEdGDTxWL2GVdKI5y7PW8HylPIrWNhwVrA0tXBarlWaT78m//sGVFyrH2FRmvnmbyDTskrrLd3L+2DTsoLitAM2YAWFqedV87nVtPoUCv1US2uz54eHksXw2NX7u1XYQz8fOD5NKyjycbjYYyWV/uUT2Esfjo9jJXz1OJnNwickk/z1U9hTD5+93bKCAg9PemHr5DK4A/vqwRayrb6Cv3luwpaJJnMH9pbnI7CCP3kWYLukswr7y/MqyCoVR8rhLuwxR/NYvYK/XJ7AJikg+xz22eW7D2wr+MPlJPk3CpehCuy1i3Os4HeXOdiAp3durbS392xtNnGPsFuw1y621b/gd8YRfk4NP2TP8sr6OShMCN3osfW7hhX86nILVmfklj31k+pSsh7P92C/GD//FVtV/edYVwmWMHYKsCgRDMNeubzCVruwcgsslTQtVCMUnIH3YN0Wj6HcwwYsTARbsFMMgdVVWBeYhWIf07A4CSzBPjEEVuOwbpPcMRT7OEzQHWMG9okhsBqFdZsEHKpEHazLsEsMgdUwrNvErezvXC50TT2DP2q1p7BCArgEu8SIssqxJ9Wmc8rlnsCftdPknILSVqNQWDvtahacYdWuoWZBApC2mobC2gMo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'
-b4 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/qKioqampqqqqq6urrKysra2trq6ur6+vsLCwsbGxsrKytLS0tbW1tra2uLi4urq6u7u7vb29vr6+gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sLD/srL/tLT/trb/uLj/urr/vLz/vr7/wMDAwcHBw8PDxMTExcXFxsbGycnJysrKy8vLzc3Nzs7Oz8/P0NDQ1NTU1tbW19fX2NjY2dnZ2tra29vb3Nzc3t7e39/fwMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/4eHh4uLi4+Pj5eXl5+fn6enp6urq6+vr7Ozs7u7u7+/v4OD/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/8PDw8fHx8vLy8/Pz9vb29/f38PD/8vL/9PT/9vb/+Pj4+fn5+vr6+/v7+Pj/+vr//Pz8/f39/Pz//v7+/v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1va/bwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABBfSURBVHhe7Z35X9zGGYfNch82YGzSpk2TNGma+Ai+MLZjYzAG47Q52qZJm54QGxuDgaZN0iQ2tnFzEUgccNb736qS9qvRMaPd95VGWg0fnl+8Gh3MY2lX0sw77+yx6vGiZf2mSDz11K9+gqrFUsvqX08qBebTZ1FNBXFWz3+PnYvMkzdR2yhqqw+xW/H5H2ocRmX1MfYwg69R6yCy1XvY2hw+Rs19JKsfsalRPI/Ke0Ss3sFmpvHRKxCoErb6FBuZxyMYVAlZfYdNTOQJHFyCVo+xgaHAwiFg9QPWGgs8bHyrb7DOXPyLUFiZdetV8+ivkPGs3sIKs/nomaqNZ4Vi03mhagOrRyg1nqpO1Sr2+ludPXtooL9YDAwOX1neRgWjfPK0b4WiCBuT+5qKSufoGmoZwfVxrf6GkhDbo604QjEpnfoWNQ3xzW89KxSEWOnH3sWlcw51DeEIOVaqB/WZZuxaaM6htkG+eq5qhcUgV0vYr+CcRX2D4FxhKcCsIVLKs/V710p+VrrXgn0M4Drq7PPkXccKCz7lA9jDBDrXUWsf91zhs89l7BDlxho4i4JCcBK19nnRtnoFnwXlbmwf4RDWVzbbUVIISg9QLcEXttWX+Cy4hs2j3ML6yjgKCsJ5VMvn/T3yBXgIW0c4iNWVzQ6UFIQO6ZnwsWy1FXP/ncf6ygQKCsMSKiawr0B8Eixh2wgHsLqy1YmSwjCJmgkUVpPYNsINrI79hWwcp1AzgcLqDLYNsx9rK9tdKCkO4jLyUFgNY9sw4hY+hYIC0Y+qCRRWp7BtiL4y1m7H3MwaSS/qJqBaXcPKyjQKikRSq17vVJX3oqRIJLWaxbrKDAoKRUKr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'
-b5 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/t7e3ubm5urq6u7u7vr6+v7+/gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sLD/srL/tLT/trb/uLj/urr/vLz/vr7/wMDAwcHBwsLCw8PDxMTExcXFycnJysrKy8vLz8/P0NDQ0tLS1NTU1dXV1tbW19fX2NjY2dnZ2tra29vb3Nzc3d3d3t7e39/fwMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/4ODg4uLi4+Pj5eXl5+fn6Ojo6enp6+vr7e3t7u7u4OD/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/8fHx8vLy8/Pz9vb29/f38PD/8vL/9PT/9vb/+Pj4+fn5+vr6+/v7+Pj/+vr//Pz8/f39/Pz//v7+/v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3CowtwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABLMSURBVHhe7Z35X9RIGodNQ4MCcgnuzO4K3gLKCIojqLM7s9esu7Ozp6jgBbjjXjOOAq4zgzAH7bb9T/cmnW+/qaTeqlSuTvL5+PxCUlWd1EOnk0qdB5oG/KxINJvvIltqdFafvGkUmJcaOaXVV/hwobmJzAbhrW7iU8XnW+TYD2f1J3yiHLxGrkVkqw+Qujx8hZx7SFbfIGmp+BUy3yZohWRl46ufIP8ufqs/I1H5eAMDF5/V50hSSuDQQrQqxSNKDSwcBKuXiC0t8LDxrP6NuBIDE8Hqt4gpM3TLICtElJtvINO2QnDZ+Z1rA6v/ILT0uDqwQpjE1p2Lk2MjxWJ0/OzVtX1kMMj3LR3X6n8I81O7dcQqKtXzXyKXAVo+rhVC/CwdwhEKyuRzZNTHmw/bVtyb/NYEPlxcqkvIq4932lbYF3nYg48WmpM1ZFfAeWg5Vt9hX+BhFZ8rOMcZLVhhT+BRSaRsrTqy7PF5y+oj7Hns9uMzJWABeRb42LF6jR2Pc/hEGeh6ikx7tL4rbHvcc9PPbYdx0k2YL0eQa4+/slbH3ORXsKvmrJswZx4gN8Qb2+rX2Ca+ROqyWJ1Ebjz+cKD5NTaJ80hdFqvKFrJD2N8VtjwGkbosVtYNZIdgrHaRtjxW55Ed4kPZ6gHSlsdKugt+KlstIW15rHqQHeKJbHUFactj1YXsEJ/JVgtI61lNdyuoIGXeIJ+EkVXhC1DIJ/GPt1aFBfkk3loVF+STeGtVXJBPwshqugoK84AKgHwSRlYCL1YvTRZPDZkjolo5bM8XrVIXGSPiWDUa+3PF+r6QLSKeVaOxPoREhQCZIuJaNfbGkaoIIE9EbKtCaSFLRHyr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'
-b6 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sLD/srL/tLT/trb/uLj/urr/vLz/vr7/wMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/4OD/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/8PD/8vL/9PT/9vb/+Pj/+vr//Pz8/f39/Pz//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfdmegAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABMCSURBVHhe3Z3nQtuwFoCvk7DLDLNQoGxoWQXKLrusQAPkXvv9X6TXTo5l2Ro+Gknsfn9KFcf4I7GscXT0n7//InIrzyM/ZIDoSuo/SRBb1d+eaeBCOYis4I0ZBy6WgW8Fb8oDcMVxeFZwfE6Ai47BWsHBOQIunIKxgiPzBVw7IWkFh+UNuPqQuBUck0NAAIhZwRG5BBQa0Fbwek4BiTqUFbyaW0AjILKC13IMiPj8S1aRFrGCF/INuPxjVqFWaAWlSf6cf58eHRnOFCNjX7Yu3+ACkzRswArK4rjnU05WKc7dwFXGaehIrM764QwZpXwLF0rT0GlYQRHN21d4c3YpbNTgYinqPnUrKKB57IO3ZppyFS43Qmb12AvvyzjDjJbE6jknUr4WUxmGVvDfCHcU3pMDvsI1E4RWW/COXHAGFx0isnoqwhsohhf3b58qD7eHs51QkhV63uGyQwRWy3A8oWP5AV7yqV2tdUB5NvgBFxbSsIL/EN4SF11YS96RlWl4KRMMwlURuFY/4GhggNc0Oc1SJXkJFxXCtYp/EFMfUBznLUPV5DpcUwjXKvYxCKQ8rzoIR7SfSbgkgm8FPxFe4Ng64yIp/+bKTJuq04VLCvkfa3UJxwZ0VqCQx0MXHNV2XuGKCKzVORwa8BPK+CSqlfbxDBdEYK1O4VCfCSgKqB2O9XR0zxxQtXxtAI5rN49wQQSp1TkU+Wx3Q1kvaaG8rJSgrN0oWfVHd+EqFAV8r5dkx0nRahtK4lKOs58tJ0UrMi5wAwVA8TpTTmpWRTIqMAclWUXFagQKvFdOzyRTqFjNQoF3CAWZRcWK9J13oaBQKsBPGUPFagEKgg5/cXzzNuhzVi+3vmSrpgjQsxo8ovuN1e1PcERW0LJ6SbaJ3d381uzEisNjpsbWbFl5tVk4KgtYs8qUlj0rr5adyS2LVt5rZvrCJlbu20t8YPAIDmw7+laVjaDf2LtJjxFMNA5sO7pWta9hY6m4Ej29zqCs3Wha1eiRz69Ey83I4JmelRsfzo1e+A4lbUbPih5MCyCd5AsoaDN6Vskn0zyUe1UoaDNaVo9QQCj+gVe8bIRkaFn9hIIIMlCYjbpdy2oHCiIO4RXvMxS0FxUrcvew4+kn8Apzx7UHFasZKPBOoCDiGl7xxqCgvahYDUCB95Fsxn4Kn8NuNib0Vawc0pZdg4IQMlT9BAVtRsmKzCI/x4c5O0jwUEZa7UpWq1Di31m0VimaM5+HojajZNUVRZ1QWpRUVoaqlayCKZ2Qm5lGV6Q49xtKfDbrRe1HzWqAnsGvfJubno91Gqs9cFwTKPQODo+Mjk1MTo2Xh8N5ThFqVs4alPFpwl3VPfx54dve2V1iYLVysj4peYgoWhXI45aD1Z5wx/ja0U2FE0dLcJ92RW1pRSunj5n0J9ynfS+wlEZXDh+Tg95c3F+fubMyqlZiLStSxfLSwT1KKORpjTNep2zl9N1DeZwbc6n+tWvZN05ElZ3PVbdyilvsH7O2YTo/V96kAikVOUn+RTWsHGc0EYDnng/BK3oUp/Ze4FR6/PkCZwK0rBxncC+KG3/dMerWd84dJ0NDNTiK1fOaVj79s1v7P/c3vxgNARZmfuncShzu6EpD38oC3RuywDxFaK02Wo38FEdQ6kBptcuqOM9fLmVCpNUeq/hMijXuwhD1dliNnliqIRj24Te03mowuY7DJjBw12qr3gOlVp4qL43HVmutOrfsVnssjcCxVloVV8kkQ/Ooz6y10GpO3DWzyGsQe9Qyq8k7OF2zCZbKtsiqj4oZbzJ3/q9rjdWChVY5mtHWWPW27oMK8KvBFljNsyuTm0qtp/lWPadwmtax0XSr2RY8opJcNdmq6xjO0VLeCk21mm5KfyOdwSZaFXbgBC1nvnlWnb/g/a1nt2lWA8yZW8dNs6wmW/yQivHRJCsqErIdPMG/BBtWxQN4a7tohlX3FbyzbaitrEUxhOgdVk42N1aXllbW9y/N5g342LeaTibNSPB69u1zbFa8NLx2Zfk2tG41Kx3rc8+nuBNdXbMnNsVs31dSqeq2ZE7o007Kh6yAZSuZ1PNCyiKtrnVbXWa7VjKpPURymV4SPWmGVSuJVGUSjklh2sqMlk0ridQBOhqyw8bHZbHFJJZ6V4kxLmzCu/R5t2clkVIMxp2X3J0oHq1Z2ZOSJqdBcWnLatqilH82s0fykSWrYeETVEeKXpKiw7Ydq25hg9bVXGKxAe/XYtWKVVEcNcguvkBiMs86a8VK3El81F7J3mMwPDpmw2oFDmQxyRH5Bc6hQb8FqylxhWWUI/IITqJOydxqQNzQvheGtxeGvv44v7w43ZdkimRyNmKpmo+zdzJniBA1lPo2o5umdrEiihfXbTo9GFsVLuAoDk/8+M6e48RX9m2Re2BZcmopF8ZWu3AQj3gqqpA5zvjnFZsgraw/QXloakUWmnFgVmkFFPhZ7T4SSaoNnDzvm6FVt+yhEoZK0RREFZs7A0cEGDkFt7OZlbSHx4swJqs6GT5Ie9HQyfO6zazm4Agut3AQzRK8xgPyeho7eRWzOfwe6bxHmIqK4pP0CXTv14TmTvW1pCZW8gYoJ8NbSlW9YMPJ89aNrJjk2nHYyppkfxNgKcpu0sSqVz4k+cY+WVs0/+O3wfStUqZ96XyyDbqaHfHYIFjcq221CK+K2IbjIqbhlSYTLO7VtZJXZz7sasBGUtKmE7TTdK1SW550W6GBlQounXH/V2laTcFrYtjkCYgpSAu4wSSFnlWBWiMsIPiTxWlN+M9D8Kv0rEimCzHsiEXUEnk63V6aHOjr6e0fHF3cvzMdgI6xF/wqLasSYjpGZPV2upjMDFkqLx1aq/XrM0paVvK10A34VtezgqGMrjU7t91b/fw6Vl3SVi3AsartD8OPPAqfbYRzNVJR6FhF6aQlsFY/UnOSDphX/o3UjBpWfah7gLXC8NVwvrumvfpFnk8/RM/K6dMdWGrwq3EWdash3NySppXfwDQJu1hqnEPdCnlPa1s5A/qRTS5sEqJsNQ6laehbOf3aWuFYibIVNujewEpfy+/c11G16sPO2JpYaWuF28+oWm1BYSpGVppaJAOgolUJPQNoZuWM6Mzik+kyRSv83LqhlU7P2SWNF0Ur/DI+U6tiehcuSZSNR81qFIoQmFo5Q8rdriisTc1KYao23arY2SlNIKYaclHvBTdQsupR+PPJrca/ndVruafjNWHvpKC4apXa00/J6huUYJBYdSzFEt8Ie5JqsQn0nn4qVkWVh4jYil0+98QO3QQUlOI66WShKlZklxQMIqtu3kyeu8ONoVG6s+jZChWr5IaBUgRWfUxIbINrXqxxt8J9HMv1rGDVpfS451uJpARa4glXhli+bgWrlPmqBFyrTqGU511ygi7K8Fo6z7F3K1ipLfzlWkkHB5KJWQPQw2lhH6QB3qqk1vPmWX2G1/h8cLaxxK7MfYvHduCtFKefOFbFlJqanchDjacGxD8qBSvF+U+OVepTlY3QQI4nvCQeDGirgmJsJccqdQldfeQ/Rie8ksICHB6CthqD/2FhrfrhFTHvbNOJuT4eD8nqE22FGoamYK0Q00NlODQC9cSK7y3hg7aSPGm4sFayoDsABikpMF3iKzg2Ams1BP9Bw1oh0rUdwKERyQ2QebCfMNZKOWqetUK0wGGYnEIcf01gc+CjrciOIVjYhRSISpT9LqWFdXhejbNWEmlVUh7I0prtZp/Dsti7BrxNjZFWqvU6LzIBUd+wOZujlPAC3nl5dpFWiK93AjaKBNE6ZjOhp97PG3BgDKSVQkcHSD7uURUO+6dIe0zecvovaCvmsFTYUE5mP3eW2B71dVKmHnntfB+cFbMVezo38Asioj0fRPyGIylS5ol5fTIfnBW9CzmSD/arkZodh/3WprQdb7jfP6wVtptDw45eUtt+c6myA03SKGzvQ7SnO85KJ1kU+4dPG9DmVGfyj3cFjmLAWelE47CdJadL+iC+4wzhSrtkbEskBGXVBT8pQQ3mE2SjBDVOddYhGyt5F8faoKzSYxx58IaZxR0Ll7fDubS9xHZbCCgr5QZ7nWP4FTFEWi531w7+ZgQN2PZ9BMpKL41BGNIRZ51bEb5zN7yVjcW8cc8OoKzUJzPr8DdvLHP2N7ji3yKSv6Yr3RQNZaUZMSvYi6j0PdHTel7iP0xlsR2CRgWAsSqot5caiHa4Kc3fkFN+CDY68ZHEdrC7EMbAWPXBD8q88NYANiiNLu/s7e0sDounhmNbHcW5Eb+rDsYKPzORpJGrWo+CeFChkrZ3E8ZKtiQzBWakDo94dOldFr5bB2O1DD9o8Kq9z4043MJNbInCAWNlkp6G+yhGUBSHJSB2+8VY4QJtBSQWAmMR9+w5w38MGCujOHNu+y4VcXvxNyZjBsZK1hpLR0dLLPWM2kAHY4VZaiBBXUsilRrpXwdhZbxThqqWsRTGynz5hrsqahRxKIlnhLBSGCulkBgBV+gtssrMFRHQUhgrKxlR35dRHxdvd7cQvFTLrPyPHFF7jUiqWwUpjJVs40kV3rdTrmv4QBKNpSLVSiu/1hBkUA0ozkl/j5IUxsrq9luPK9w+V993eX9bTarlVj5PR6vjVNhc1+TGadqU8Z3ilnxtsApwH04O93d/HByeYYaFj1WzpbX0vtLD/QbXiif7Vu/pnUQGhFV785JXUrvzHBBWNpbxBvQUU2EHa6+1hggQVqeW0gKIh9EITADEQcoQmQCMlaXEFOpWLj9TWjoYK5WFFBKUrarSsXQZGCt5EDAaVatfslkPORirbvjBEDWrt0Uo0wFjhYmBQ6Bkhem3iEFZ/YCfzHh6TCX8871Ta6l0QFkNwk+t4tpoy2wflJXaah5TPlTGbvjgrAxmRZS5FQW8KICzUlu1ZsLbmvEH5YOzQoUqW6C2qz0zFANphUqAY4p7pNaPF4O0wiwcMOVypH5FNsBaGeVLx/Bbu9HHAW1lki89ncq8jUqCgLZSW1erRnVNdbglBbyVVugjhqdV9MYwWBSsujTDmaS4v1T2hcGiYNUErbcd0xYfHxUr21r3i7yVzzZQsrKpVTvhpxSwgpqVNa377/rdd5/e6e9nVzdXx+sT/IpG0crp2IdSfdzrNaO7qThHjfy7J7zNZVStHGdKMwNUg4+zBcMG7FJyePKe9VK3cjq1I4CqP2dM6wdeJj73R/KsGlaOM63xcdV+706Yt4om+KthHhNjN1pWTnFeZZ2j+/BzedRKm2hCFN6ZCATSs/Ip45K5JiYWzZDsYfYcq1O1rRyne/1C3Jd0//w+P1ifRIwB4umUffFjQfsGVgH9cztX9FqO6v3Fz83lmdE+vbkMOfJliPRYr6FVnVJXz6fenu7OjqLVTlISerWKez4zPFBeoAM+36kQYxtWLYIalNwLH+NjVEVPRa7mx4oaQKaWnxWj9brUUof8WEWD/bE1dZRWtIImP1bkShPL2kukIo42BsqNVbS4N7lUmqx9jBbm5saKLO6tJCtasrS1RtovubEiiwHZHAmkz0dWRubGiiRPYON/SO1OkpL8C1YkzIXkP8nfN5Ddg5T0H0j+k9xYkfYSSUAc0kviWvNnFa3ETu5rHgX1588qWjWfSMNSjMYxcmhFsse58cVPe1Dsk0OraHVlTIuSyqMVlRLK3QgHNz/FepJ5tKIn0N73y92l3qmz+PqLPFqlb6CVSyv5/pA+ubRyZsQLfurk08qZlWvl1MqZleZgzquVMyxbEJtbK6e4mRyWrpC2VH6t/HYuva1Z7XqlSMJ28mzlOIXy0sHdU+Xhdm8maGQQq/z1GiXkuIcvIcejMWIGyMgZGZLOoVVyEokMVd9BQQ6tBo/v4sOcHWSqWDoindTKktXQif91i41zlqLlYdGiulxZ1Z18qCFBSooaqs6R1QA4+VyGs3JT1KJLagIoR1b0hk61i+XRkYlV+uqrVMwNwuocDm078mBSOv0YswjZt0poiRNFtphu5iOgiH2jmMhn1uoPHNp++sQBFw90zFcPFBL+y1p5tlYEmDMkSur7EMt8xixZ/Mux4uZhbA9j/Kj63/F0bkw6HZ6VSWY523RxwvjcrUQjKhk69pdnVbOz0MYSE8k87zfJfQ+YPf0aVkktbg70tlGaO4oGBj9+smtmmBTIfKtXq6FjFiiMbR6dXZwdLI1wosAGmHEovlWm7qw02ByRvhDXipPkPrOwKYdDK0arqpNloi18ZsdBhVben5xo8aVEVt4fdjOXDMIbsY6sOFrMsy57dHJjWAMdsOJoeffNWCplj+I8t/Fbt5FYed4TP/NVFhBm36rbhFZ8LV/seO3rbLaYW9g4FfZRGjLESqSVL8AlsvoXtMCEtsq9Fmj40FY51wKJgJhVrrVAoU7cKsdaINAgYZVXLbj6kKRVPrXg2gmMVR614MojWKvcecFV0/Cs8uUFlxyDb5UjL7jeOCKrnGjBxSYRWuXBCy6URWJVB96fReAKeaRZ+cBJsgVcmwCEVe74+/f/0kDnznCsvK0AAAAASUVORK5CYII='
-b7 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/ra3/rq7/sLD/srL/tLT/trb/uLj/u7v/vLz/vr7/wMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3d3/3t7/4eH/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/9vb28PD/8vL/9PT/9vb/+Pj/+vr//Pz//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYmWdhQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAA2DSURBVHhe3Z39Q9M6G4bPGN+ICA6Rj6PgJyKichT1KIKCeJCPF5Ct//9f4ru197q2SdsnyZM24frFrUtKLrfdzdok/evPTYRoFTgEmlREgRV24iRoYh65VqjuLminlBwr1HQcNFZEaoVKHoAGZ5FZoYYnoNEpRCsU9gg0PIFghZJ+gbbHZK1QzDfQ+j4ZKxTyEAhEpKxQwFMg0SNphVe9BRpdElZ4zWMgkrTCKz4DkxtmFWvFVtjuOZDpW2Frlqv9rb/n52adYq61vLl7gQZmiWwKrQ4eNhuusrjbQSvThDawwqYUh3exA0eZ/oKGpgh1IitsSdLeGEJtd1m7QmOTFFldzKGm00wdo7kJCqwuZlHPcSZFrdgKzwdceSLV1TpBkwfkWq2hjge0hCjMs/qCGl7wGo0eEFnhSczvibD43Fk5T8KStdL8hWbHyK22o+LzeFrEelS0Vp6iLTGhFR7HdG5HpX2xGhGOWjKrPZT2xaqxjcbEyKxeoLA3VitoTIzMagGFvbGaRGMGiFadURT2xqpxhtbEiFbnKOqR1T5aE/OX8AH8haIeWe2iNTGi1TGKDqy+DGf5hFeC+yhbL5/RmhiSFTbEjF/jlfh9rRceq+d4IT4I1AyPVf9HTTvqMNYOi9U9bA/+xYa6YbH6iO2OZAWPlWtZwWPlWlaoWbV+g0/YAFzLCjWrHJzLChYr57KCw8q9rOCwci8rOKzcywoGKwezgsHKwawwtxpvo5RDWWFutY5CLmWFuZWLWWFs5WRWGFs5mRWmVm5mhamVm1lhauVmVhhaLaCEY1lhaOVoVphZuZoVZlauZoWZlatZYWTlbFYYWTmbFSZW7maFiZW7WWFi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'
-b8 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/i4uLgID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sLD/srL/tLT/trb/uLj/urr/vLz/vr7/xcXFwMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/6urq6+vr7u7u7+/v4OD/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/8vLy8/Pz9PT08PD/8vL/9PT/9vb/+fn5+Pj/+vr//Pz8/Pz//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbZCRbQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABOaSURBVHhe7Z17X9NMFoDtjbYgyE1WkFduioIIAgLLRXhFeHEvgoC7C+Vtt/n+H4Jt05OZSeZMcs4kbRN/+/wjnaSYh6aTuZw58+Qxmr/Av9mBYOWkDrgwM2Yr+A3pBa4Tw2gFb003cK0aJit4W+qByw2AW8FbMgFcsg/MCk7PCnDVKroVnJsl4MolmhWcmC3g2gVBKzgta8DVe/it4JwsAgYdfFZwQjYBBxfVCg5nFbBo8wtZKVqKFRzLMCCiWsGRTAMqv5iVpyWsoDhA/Xxr4fn4WLqYnFk9uoELDNKR8ayg0M/lcimXVib3G3CVflwbsIIiHz9m4BeklOonuFA/bR2z1af0fk4e09h92NbpWEGBQuM3eGeqGfgKl6sQYtV4Ce9LOSVcC7dqZkSqpXUGlywxWm3AezLAUA2uWeBZwUvB9wK8JQsswkVLDFbj8AaVsZXDy5vrs6351FWNX+CqBR0reCE4hdMVXsnbt7Y9BIUpYRouTIBbzcLpguoxHOlQW4LylHAJ1yVoW8GPgps8nO0xegdHBHvBU/rKMlyV4E/Eag9O9tClHGc/TVojcFESxGoZTgZK11DuYxWOpgKtckesJuBcYAeK/TRG4XAaOIWLEiBWA3Buh1EoDfIFjqcBrfGOWPkfwfhH1WpUjcAJKWATrkmAWMGpHYoPUOo4n6dK1bey7f8RzkgBG3BJgieP/4GfBHBqh+dQ6LUNh37AS+fcfZ0KEKt/wU8COLXDWyh0vkPBDLx26ump3NlW21DovIWCnLgH09NwYluJyuIVFOTOocAZhoL+w7YS1cs7KMjfQoFThZL+w7Z6D4XOJRS8hNdOswgl/YdtNQGFXk3+VLSf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'
-b9 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVVX/Vlb/WFj/Wlr/XFz/Xl7/YGD/YmL/ZGT/Zmb/aGj/amr/bGz/bm7/cHD/cnL/dHT/dnb/eHj/enr/fHz/fn7/gID/goL/hIT/hob/iIj/ior/jIz/jo7/kJD/kpL/lJT/lpb/mJj/mpr/nJz/np7/oKD/oqL/pKT/pqb/qKj/qqr/rKz/rq7/sLD/srL/tLT/trb/uLj/urr/vLz/vr7/ysrKy8vLzMzM0tLS2NjY2dnZ3Nzc3t7ewMD/wsL/xMT/xsb/yMj/ysr/zMz/zs7/0ND/0tL/1NT/1tb/2Nj/2tr/3Nz/3t7/4eHh4OD/4uL/5OT/5ub/6Oj/6ur/7Oz/7u7/8PD/8vL/9PT/9vb/+Pj/+vr//Pz//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQLQ3wAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABNHSURBVHhe3Z1pQ9s8EoA3CQQKFMp9lqaQQqFQyrm77x4c5aaw5Sbk+v+/ouskE1m2RvJIchKL50uDbKd+EsfWMRr97c9bhG5VTQ5wRnIirOBtEgicII7cCo5OMHCiCDIrODDpwNmGkVjBQQ4AJxwEs4L9nQFOm0O0gl1dAs7cR7CCHR0DTr5J2Ar2cg44fSBkBfu4CBjUCVrBDm4CDjUCVrDZVcDCg7eCje4CHgEr2OQyYMJZwQa3ARdmBcWOAzIRVuXrnYWJ0eFkMTq5dHAHJximIdO0gsIgT6u9qaQyuPUKZxmkbqOwevmchndIJtlvZTjTADUbsIISnuN3cHRyGb6Bc+Wp6UitluHIRJPZh7PlYVbwN8cSHJdw0ntwvhxyKye+qRrpAzhjDrCCv3x+wjEO0H0P5+wjsXpJ7g1dZLwCZ81oWMEfPjk4gKNnZu3k9uHh9ufKVDcUJYVNOGsf1OpReE6NHXCPhuL2EBQng37xy8KsVmD3Jh+uYAPjuA82JYKfcFYMzKrcA3s3SK8gj/DXz7A1CUzCSfl4VvCK8Qt2btB1BsUhdpNTncoIHztitQU715FJVat7ydH6BafEQKz4iystlfK+Ldin82zBGTEQqzHYt8YqlKHMw04d5wucEAOx+gD7enxA6/pNXpJSq1+AE2IgVtzTiL9gb/MD2Z7BlUf4s8YB7NZpPsP5MJRW41DicTsJZem5ZyiqViv9UNhhEKv/wSuGb3UIJZ4UVzMc9LXWoajDIFZ/wSsGs+plvypeitd6ScbdHbH6B7xiMKs5KKhWJ6AE8H+d3J2lgyBWf4dXDGa1DgXV31DQpKsAG6oLUNJZtKzYE3gRChgbsKG6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'
-g0 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL+AgcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+wN/A0NDQ0tLS3t7eweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e5+fn4O/g6Ojo6enp6urq4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8Pfw8fjx8vjy9Pn09fr19vr2+fn5+Pv4+vr6+fz5+vz6/Pz8/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiD0LYAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABGuSURBVHhe7Z39XxNHHsebYKiI2uJD42FV1BYLRcUHUHwAaVEK9YHenVQtLRWxoJ53Jz6gcBXhOGLIH+1tsp/Mzu487MzsZDfrK++fYHY2mTchu7Mz3/nOJx+UKNUNaJAcJav//Puf9cM//v4vNEtMiBX+QHUIGshHZoXz6xY0k4PQCmfWOWhsEIEVTkoBaLAfrhVOSAloNA3HCpVTBBruwVqhZqpA0wlBK1RLG2h9lYAVKqUQCLj4rVAjlUChgs8Kx1MKJMrQVjiaWqDh4FnhUJqByUdvhQPpBi7ECsVpBzawQmGQzfmxk3u2NefqiuZtX/SOP95EE/24NrD6Lwr9rI3vydQt+RvraKaPig6sUOSjOL4VL1CntEzwPq+KT8XqfyiheX0EJ9cxx5bRWArPCgU083X+Qbm0PkNzKSRW6ZDialWt8CvFs5RIOVov0WSC0KqwD+ekgINFNJogshrEGQGyuSx+qieuodEEgdUC2/hc98jMinPo3czV7maU1QlbXrutJgis+lCf0DZaNqqyMroL5fXBJbSrimuFXwgrgQ+jeTz4r1u8Xk+f17YNNKsK12oMtcEh5irj8KoDR+uBn9CoKlyrblR2OclcYyoUe3G8DjiNNlXhWn2OyhUEUnWltQ9NIjhW+InwJ+pW+EYk5Wh1oU7iZJneO2s1h7plWt+ikMfKdtRKnOdoEYG1eoCqZe6hzGV1aRU/uUyhVuI8QYMIrNUMqjp0oqjM8vBOp2T7lSX8XuaYWy1xHqE9BKnVNIqcL1F/E8qa+t6jzFc1UbSs9pBLRfEEisr0eFp7UZQwWlZXUVIqnUSJSw9KS6VRlCSMltUfKCnNoqDKDMpL8yhI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'
-g1 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL+AgcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+gotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixtNm0tdq1t9u3uNu4udy5uty6vN28vd69vt6+wN/A1NTU39/fweDBwuDCxeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4eHh4uLi5eXl5ubm4O/g6Ojo6enp4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8Pfw8fjx8vjy9Pn09fr19vr2+Pj4+Pv4+/v7+fz5+vz6/Pz8/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAl8giSgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAAy2SURBVHhe7d35QxTnHcdxFlwUQZCq0WokGK0GxaLUqxqNFVHj1RZCRaNEq8YetlhUAhWKpawLfzWdmf3sXM8c32ee7zPHZt6/uMfMw/OKcdnjmdm2TUIbeQpzioyi+sM//5Gn/vj3v/wVMwsrWoX/PHkMMwwuQoXdcxumGVSoCrvmOkxVLESF3fIeZisUpMIuhQhT9hWgwvZFCbP2JKqwcXHCvN0JKmxaqDB1J58KmxUuTL+ZV4VtChgAyK3CBgUNCCuXCvcWNjDMHBXuK3CAGLWSymHZKtxR7GD5eapm74zu6+6s5quuXcPjT+uYoTdgmirc6qk2ebCS23aOLWOanhqaCNWDXgyQ06pXa5ipO0sDFW5ytTyCnXPcgTeYrCuL01DhFlfz/dgz11W/x3SdLE+IqhioUFaw6kNBUAbrKaZsZ6tw3W59CPsUoL4VTNouTDWBPVB7J9qCG3LVKCZtF6Ja6cIOjTrtv+Qp3JKvfsDsmoWobmDzRg4qp6qvMDu7hgpXmtV3YXMrFyqnqvb3mF6zQNUTbG3lRuVUVfka07MzVbhodwUbm3lQeVUNYHp26wGqI9jYyIvKq6r6CfOza9v8Hy41W9+OjQVUXlWVV5ifXZvwV7WCTUVUblUPMD87UbWITQOejORVNYn52YmqBWxa2YsbnPKqmsD87Cgq+5lWK6leD+NCK6ledx9qXGgl1evuSuupDFTrqUxUy6ksVKupGqgWUwHVWqpuoFpLZVeqMqlU2ZWqTCpVdqUqk0qVXanKpFJlV6oyqVTZlapMKlV2pSqTSpVdqcqkUmWXgaraPzA0fHJk9My5C2dPDR92lhUElm9VR9/BoXPX7j+eFRYK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'
-g10 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL+ArKyssLCwt7e3uLi4ubm5urq6vb29gcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+wMDAwsLCw8PDxMTEyMjIysrKy8vLzMzMz8/PwN/A0NDQ09PT1NTU1dXV2NjY2dnZ2tra29vb3d3d39/fweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4ODg4+Pj7fbt7vbu8/Pz8Pfw9vb29/f38fjx8vjy9Pn09fr19vr2+Pj4+fn5+Pv4+vr6+/v7+fz5+vz6/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAji4xRwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABaPSURBVHhe3Z37QxRHnsDTg4P4QlEUJUFh77EXjFl8EUEIPoKiRAxrlN175zZ3t7cn4iMajc94BzEnj102jBn6j62bnvlOVXV/v1VdVd3T07OfX4CqmqE/0z3d9fzWeyw7fArIS5csrbJDZ/UOPs58svk/cJgESit4bb6BY0UorOBV+efdX8ERh6Cs8n3lRdmEo5YhrKB06/AjHLggavWPULK1+BqOvk7Y6u9b70TV+AEEgLDVT1Co9Qh/u0JWm1CkJQGHKrIVZLcqYBEgWUFm6wIeFYRVS19+NcBEsvoj5LQyP/8JZLgVZLQ24MKtILnV+c+aDVhBYutT09FbrdyfHOzsKOaLjp39FxaW4Aij1HRqVpAUgY0WvbzSdvoFfdOu+qitln4Fb5BX+snD/olbQYLM5vw2eHF+aZ8tw9HKaKw2z8Er880pooH7f2AFf0psTsDL8s5JQqtm9Vv4S+IivCj/DON7xv9Wrf4EfwmewEtagdtwzIJKU6tiBX8IVvfAK1Rs2QK/5IAOfPy0lfpL1dY7Mvt8tXLnKa+9vDHamwu543DUgsDqv+B3zmo7lI/ywa01KAJs3D4MWU2kgE5LYIXuIteheJitY68hPwQb74ACTeMCHIqgYgW/CbqhdIgTqoqX//Y0FGkW20pwJBzCagkKy+y8C5kkD3ZBsSaBLiLC6hsoK3HqLeQpWB6Ggs3hSzgMDmF1GcoKpiFHwwwUbQqjcBAcwgp97jcgQ8utApRuAh/CMXAIqxNQts4spAuW2WLwzArzJRRvAn1wCBzCagjKAlOQDDy5MLgjSG4/NhN55XS1eDP4AI6AE2s1IJ+U5Wuhu/6uqdBT+SNIzhxrq3Y5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'
-g11 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAW1tbVapVVqpWV6tXWKtYWaxZWqxaW61bXK1cXa5dXq5eX69fYK9gYa9hYbBhYrBiY7FjZLFkZbJlZrJmZ7NnaLNoabRparRqa7VrbLVsbbZtbrZub7dvcLdwcbhxcrhyc7lzdLl0dbp1drp2d7t3eLt4ebx5erx6e717fL18fb59fr5+f79/l5eXmJiYmZmZm5ubnZ2dgL+AoKCgoqKipaWlqqqqq6urra2tsbGxtLS0t7e3urq6u7u7vb29vr6+v7+/gcCBgsCChMGEhsKGh8OHiMOIicSJisSKi8WLjMWMjcaNjsaOj8ePkMeQkciRksiSk8mTlMmUlcqVlsqWl8uXmMuYmcyZmsyam82bnM2cnc6dns6eoM+godChotCipNGkpdKlptKmp9OnqNOoqdSpqtSqq9WrrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6u927vN28vd69vt6+v96/wMDAwcHBwsLCxMTExcXFx8fHyMjIycnJysrKy8vLzMzMzc3Nz8/PwN/A0tLS1NTU1dXV1tbW2dnZ2tra29vb3d3d3t7e39/fweDBwuDCw+HDxOHExeLFxuLGx+PHyOPIyeTJyuTKzOXMzebNzubOz+fP0OfQ0ejR0ujS1OnU1erV1urW1+vX2OvY2ezZ2uza2+3b3O3c3e7d3u7e4ODg4+Pj5eXl5+fn4O/g6Ojo6+vr7u7u7+/v4fDh4vDi5PHk5fLl5vLm5/Ln6PPo6fTp6vTq6/Xr7PXs7fbt7vbu7/fv8PDw8vLy8Pfw9PT09fX19vb28fjx8vjy8/nz9Pn09fr19vr29/v3+Pj4+fn5+Pv4+vr6+/v7+fz5+vz6+/37/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8fCpXwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABEwSURBVHhe3d2LnxV1Gcdxm2Vb1oW4qHhDXE0NCTOjzEqzBCVDRDJQFBAhBC+gYIpkVl7SzLJENPKGICCoWFEKiCAgSoqKm5eFbXf+lW0u3zNnZn6/mXmeZ2bOmV+f18vXOWfOzGHe7tmzc+Z6RP//Y1mq79736P0P/7NK/f3VV3934TcxewmlqO7+xK5yfX/+OmZULUn1YB8mrnSvn43ZjaVXvYupql/fDzHLkXSq9zCFIWlcqupvGNmcejDn9eKqbxnx+xTvMcx9rZjqjxjNtD7H/KOoypxPCaVzQfCKqD7HGEZ2IRBuYdV/8byh/QoMp5DKcFT4p1VXVXv5iFTwuxWo/oVnjA6WQPVrDDe72gd8TYXBpoc/x1D9H/xS+fkcX3U3hsXrXr1w4rGDBlarI4eNnvnQLsxhPH+Z0FdhUKy3rh9iVbaLn+vFbEb7QaB6GEMifTyjBS9Q0U7eiDmNFqjwONILx2Hi6tYy9xBmNpz7w3JVv8TjcLdjymp35kHMbqg+qDRfqZZisqo3WsOCCo9C3YWJqt+Z6pvwNU/1Jzyqt2MgpjGgeZjnUJ4K9+v1jsEU8dra4+GJJtayCXNd72taVeInxdgujBF0FJ5pYp3K361HHdV5uB/UOxLjqymsCqis5zEvQX2O6lXcD1qNsXXFWVVQTcS81HNUyuf6pRhbW4xVBVXLbsxMkKPCvaC+9IW/RRjNrwoqayVmJugbqupNjKtvWvR3sxKq2ZiZoAtU1RMYV1sMVQ3VGMxM0L2q6iaMqyuOqobqaMxM0AOqaj7G1aSgqqEajJkJukdVzcO4aiqqGqoOzEzQfQyVBlVR1W/pKh3KeJUWZbpKRd3hLmWY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'
-g12 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAgICBAQEBAkEBw8HCAgICgoKDQ0NCBEIEhISFBQUFhYWGBgYGhoaHBwcFSoVFi0WICAgJCQkJiYmKSkpLi4uMTExMjIyNTU1ODg4Ozs7PT09IUMhIkUiJUolLVotL14vMmQyNGU0OXM5QEBARUVFSUlJTExMUFBQVlZWWFhYWlpaXFxcXl5eYGBgYmJiZGRkampqbGxsb29vcHBwcnJydHR0d3d3eHh4enp6fX19QoRCRIpESJBITJlMTp1OUKBQUqVSVKlUVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gICAgoKChISEhoaGiIiIioqKkJCQkpKSkZSRlpaWmJiYnJycnp6egL+AoKCgoqKipKSkpamlqKiora2trq6usbGxtra2uLi4urq6vLy8vr6+gcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+wMDAwsLCxsbGyMjIzMzMzs7OwN/A0NDQ0tLS1NTU1tbW2NjY2tra3Nzc3t7eweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4ODg4eHh4uLi5OTk5eXl5ubm5+fn4O/g6Ojo6urq7Ozs7u7u4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8/Pz8Pfw9PT09fX19vb28fjx8vjy9Pn09fr19vr2+Pj4+Pv4+vr6+fz5+vz6/Pz8/f39/f79/v7+AAAAAAAAGpDFhgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABSPSURBVHhe3Z19nBXVeccPJMRohcZEIybpS1pN1JgUm5im1jZJ770s7nZZBFmyuBuIbU1iW0NtE1NSA6gIiK4soiDrxpUVRNEk9aU1CStvYtEVxLVpTKQBWRcWqw3LbnDv9s6HzNz7m9czc+Y5c+fMvcP3H849c+bly937zMw5Z55hJyj87Oc/QykdCK20qgYH6Ueg1f9j3aoGx8oRYIW1qh8crwc/q7exRjrAQbvgrX6O1ukBB+6AsxpF0zSBQ7fxWqFd2sDRm5wkVh4tjxXapBEYFHFboUE6gYOB0wpLUws0dBxWWJZiIHKSWVlathUWpBu4WFaoTjmQMa1Qm3pKNrBCnZfRnnVLZ9bVVBdT6me3PrwfR8hR1ClZ+d9MDXZOz1Qtc7rzOEw3RZ+SFWpc5DtqsIEqZdp2HKkby8rvqzrQjJWrmOWDOFgnlhU+O3muyr+oEjMO4XCdwOpX+OggHVL+WrDCJwc9KZHStd7CIdsEWQ1dgXVSwGIcs4Oi1Tv4YNOKNejkKvflduOgbYpWKNu8gPY0Zqx4pFc/dRQObVt7NaoSpW4Ih23hb3Uz2lNY+GwBaxm8vqoW9QmyHju38bN6I4vm4TS9jHUsjsn/9ZbLTOf/axHd6k0ULdagdSjZtX4XLTunYXFi7MKeLXQrlGzmoHEYuW1YwcNAIxokRTt2bOFjlSeGsyCp5LUWYb8W+/jfVS/ahsFHVIuBBrRJhnrs1uJXvNU2tA3hNjT35Vk0SggutvN/gd1oKmaa63J59OiRERRL3IFmyXAEe7XgrTajqZjNaG2wZ/lkvablCYfY4OWlZskwgL1aRLSaasf0/hbUZeodP7WVqEuEuKzsYNo/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'
-g2 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL6AgcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjsWOjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cns2enc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4utu6udy5uty6vN28vd69vt6+y8vLwN/AweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ufS0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4ODg5eXl5ubm4O/g6Ojo6enp6urq6+vr7Ozs7e3t7+/v4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8vLy8Pfw9PT09vb29/f38fjx8vjy9Pn09fr19vr2+Pj4+fn5+Pv4+vr6+/v7+fz5+vz6/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHWJ+1wAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABiESURBVHhe3Z39Q9tGf8DL+QWDeS8UmjxJYdBQWKGhUFjhMSUhbzTJCmEpjISErFDaELaHPu2zBcKrN54VG3d+Zrk6/lkmWd/T60m+k2Rb3ucncTqb+1h3p7vT3em9SwYuAgMkqBgsVv/0Uzn4sy0/6/nl3yFVThSz+vXX3/72W97M77ZgW+DX9gdInR1OVnl/U+IzkEgqdla//Q4fDjaQWjM2VoG+SkYgxQboVvCB6gDSrIdmBbGrB0i3BsUKolYTkHIVqxVErC4g7QSzFcSqPiD9CiYriFKNgEEBoxVEqE7AQcZgBaerFbCQ0FvByeoFPP6fWalaOis4U82Aic4KTpQajEWZfF5QyMlksxmFc5m0RErh7OzsVCKpcHJyciyTPDsX6C1VcHG2Enaf/rGvq739fYm2trZWhRaJ5ubmJoVGmQaJuEJ9fX2dREyhtrY2KhHxk1hb/8zzg/M8JNKA4qJaQagOnFoeaKqPhlBNAEHv33qTplwvRcbeKvP8ejwM3xFI4tMHAqRVR0GGWEGYCj6YbAjkRdIR/mgtA8nVKNjYWInbvVH4bJBpXqBrgRWEEMTt7kBnPpXmhSwkWUXWoVrht38Xgo8FnZanlqpQtYK/CcnJ6rhSEujKjrkmtLHKLsXgMyaCWMlHb55DsgnECv4E8O4V+IRGtCex9OYoefxudXYgDmEBoXnRerEoVpl5U6FCzYkfz85zIpaaO0I2vTdnta4g4X5zhUG12u+D+ED91Dt96wSL2eOFFjgXBN7/DlJGUKzgD0BYi0D0AqErz9MinCLg3NYQnA4AsUlTFsQUq9Q9iF0g3LtLaZZg8ehWYGoO1GNOIbZaHd+E2DKSlPlC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'
-g3 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+kpKSmZmZm5ubgL+AoqKio6Ojp6enqamptLS0ubm5gcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+z8/PwN/A1dXV19fX2NjY3t7e39/fweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4eHh4+Pj5+fn4O/g6Ojo6enp7u7u7+/v4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8vLy8Pfw9PT09vb29/f38fjx8vjy9Pn09fr19vr2+fn5+Pv4+vr6+/v7+fz5+vz6/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8DgQ0gAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABMISURBVHhe3Z39QxTHHYfdQxBEfAHjCwmGtvZVDAqiKIqiEAxqRIlGm75pUBGiETHSNm0jgYjQpg0XqSlHjv1P6b18bvZlZnbnbe92eX65u5m5u31gb3Z2Xr6zaT2YP/zjRztO4LBCCLH6xfpv/7j+l7/FiT//7e84OD58q5//bg1/n3iCw2TCs/on3htvcLAUHCu8K/78FwfshWmFdySD/+Gg3TCsUDo54LhdUFYomSxw7AS/FYolDRx9CZ8VCiUPHD/wWqFIEoFBEY8VCiQTOBRwWyE7qcAij8sKmckFHjkcK2QlGZg4Vv9BRqKBC7H6PdITTlGGWCE18RRtYPUVEv0sjva3bqutjhe129sGH3yPI/RRsIHVb5DmZW3qeJUVV2rOvMBheig4weoHpHmYa8UHxJWjizhSNwWpohVS3GRHqvHm+FJ3l+6DKEjxrFa78M54c56jlbfCaxcJkbKsPkqLb7XWjTfFnwEcsgPX6hO8JQk8xjETYIVXDq9q8Q4fmzfjSZzY+RpHTeBYdeINblqvTy7b9vLk8LtIiA19OGpCwepfeEH4JoXyDt2uS950zGqSGv8/q2CF5w79KE5oeIgc8KAeGfHgOg6LwLLK1KF0iaYF5BDmdyErFuzGURFYVs9RuEQjJRU3rW9xVIT1TT/BM8JNlAVVz5Hu4Sn926sc4zgowvqmX+IZoQdlwRCSfVA/vgpCHeL6pl/jGeEgyhbZuoJkH6+3oEAM6MYxEdY3/RTPCC0oW6QfqXkW3SfwWRSIAcdwSA6bfoUnhHdQtsgMUm17dJ9lNT/AC9v+AgViQAcOyYGuAz1WtVmk2jcKr1O38dLOxOf+i7Ji1Oweq4NI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'
-g4 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL+AgcCBgsCChMGEhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+wN/A3d3dweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4O/g4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8fHx8vLy8Pfw8fjx8vjy9Pn09fr19vr2+Pv4+fz5+vz6/Pz8/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAkGwwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAA/HSURBVHhe7Z39f9TEFofvbtlSbAWBcgtoeRORNylF3q6VF+0tWqnFaxUpIAiCIO9Ir0rpQin5v3E3+e5kkjPZnpNMspn99Plld2cy23m6bTaZOXPmX2+7kbRWf/35/yZ//oXX5WI5K08GWpF2KC2KZCv0p8ygp5REKzQsOehsnAQrNHIAdDiK0QoNHAGd1jFZ4Wh3QL9DqBWOdAp0XUGscJxjoPMt4lY4yj3Q/4CYFQ5xERj4RK1wgJvAoUnECtWuAosG3W+FSneBR8QKVS4DE80KFW4Dl/ZWC7Ond6/tq5WLvoHtJ2eeoYcx4KKsUKzz4NjqSlmp7r/5Bt2MEMgkWz0/gDcoK8P30dMIvkzLCmUhl/rRuLzUJpbQWQ3fJsHqzWm0LDd7FtFfjaYNrFDSwhEpo1ZTJ7BCgeJLNCo/e+kfYcsKLxW3qmjjAN+gzyEJVi8H0SJGTy9YhYIy0PsIvVbACq8Up9AgjjqTnkBBKdiNToUYrV69g+Nj7Ee9N1dDSTm4h24pfCs8V0zj6Dh3Ue99hoKScBTdUhittuLoGHtR7T3vRUlJ6K2jYy1MVvWEE+Ad1Cf+23WMG+iYwmB1A8fG+AjV3nwfSkrDOfRM0bDCM8UEjo1xC9XeGRSUhwPomcJgdRTHRvkQtd5C6T6qyvvomsJgNYpjo9xErfcFCkrEELqmMFiN4NgIO1Hp1RO+zDrJJvRNwbW6jkpvHAVlIq3VNtR59TLeS6a1uoo67xwKSkVKK3WSefUuSkpFSqvLqPImUVAu0lltRY23uBYl5SKd1SXUeFMoKBmprIZaQwOL6yuV9VtBiS4xUln9iAr/xmsGz73dQWUZSGO1qfVRvd7QeNUtVsrj+8grt602vkb5kj/y1CVWF1Ds/eC/7A6r9a0h36Uh/3V3WE2h1LsYvO4Kq3VqdH5zUNAVVpMo9GZR0A1Wa1+h0HsfJd1g9RXKvKso6AargZco84ZR0g1WEyjyrqGgG6z61QD2DpR0g9WXKNEHqZ23WrOAEu9DlDRw3uosCrxfUdDEdaueeRR4U4dC1Mj0ePOVOjV2FIlVH1634zsc21lWrFasOsuK1YpVZ1mxqn1l4gGO8i41X32CY63Tv3n3vgOHRo4cPXF89NDeofYxcBIrM7leMa0Z+nDk88mLt57GYxnrN899khAI16C0Vn27xi4+UsMJZuYnN+HoGGW06t1xcuaRISzYxPW9pr/FklnVho9duM8UAk/G6BRTmawGjlxZ5k/OzLOP8AaK0lgNjt2SfUY607GPqxxWw+Pq+yEdT7Wb8wadt1r10dQc3iEDS5M9eL8m2a0+PgXWo0DE5ik1FpKRS5pWdqsMVA+o4QELaFodtBo4nbBkKi2hVseshmcM61QyorQ6Y1U7/Bve2y6YKOyIVf+Xz/HO1kHYafFWtVO2znoGFt7zf0bRVtVRy6eIGNf9n1Kw1R7jykObHGv+mEKthm1+PSVQb0YhFWg1eBHvly/NWfjCrAbO2/9+MrLUuHIryup4fJlNfkwUZbVeRb8XwHytGKtPi/ugmowWYbVWxb4XxN0CrA6/wNsUx3DeVu/O4k2KZCxnq4NqKrlILuZq1V/M9y7hSZ5Wm5/iDQpnGI8Ke1b7ij2f6xzBo8Ka1Zn0g5aZ+RqPCktWtQ79SwX8jEeFHat1aoV0R1CLfltYsRq2MBqbBZUgoIUNq5FUUxsWIXfc2a2qZL24iYM74pxCjQVo3o6sVrUraNaWyzha4xqqLEBmWLJa1Xi3Uh/g8BDyzZkBmrYjmxVT6mccrmHzfsXy2YIp5W3D8SEkIUAWyHh3JiuuVDAWGcHqHcttPCqyWHGlvJ1oELLFmE8uLWTcMYMVW+omGmjYvcD6BY+K9FZsKT1uHAxZ/ai8n/CoSG3Fl7qNFho/oMoS5/GoSGvFl/JI0Edl0PJdiwq8b5HSqkou/hO5gyYa36PKFsfwqEhppZbQLc9eNAnZYPsGk5Pjh2H1KQ5l8DsNEptGlTV24FGRymqHYL5jP9qEqLW6tlhKneNHZ71g9vo+/ajUWl1bzNkYOVtNLpHbcBCNQsK1ura4Y8GqKrmEe0g/KsGJhskVC1bjOIwFfa9wra41prJbHcJRLB7r8W4BrPEAGWczW30g+lUfQauQcK2uPT7NarVWFBTylH5U/0WVTfZktZINodCcfeFaXYtszGhF8nq25RlNtarW6lpkPuMM6gbZb5pmxQ3X6lrkejarKsnq2RZDVlxyy2CD8WxWJ3EAE5oVty+XCdZ9mawGZd+fhqy4FgehNd7LYlUl8ynt+RztQnpzien8O1PEzxiqmRiy4n6GKrtczWI1JLzUpsn4a/nMcp3NYFUVziYasuKeQJVl9mSwOoNKLo3fYIxaThG4a9NbDQr//gxZcclAkB2eNd46rRUZHV0GmhV3VU4xJhkiVKVTaC9pVlxEeizMxwnKU9NMq57SShrsTLPi9jwJaoIUcDoZhzGaeUPSWaks+kwMWXEPo8q21VzzLVJZVaWx9l+jYUi1Nc1u28rP6prKigQ/LYMhK64a7bBt5U9NpLESf9GcR8OQqoodsGxV9/drSWMlvdJeDBba6ITD+5atghVYKaz6pfev36JhSDUc7bVsFeRsSGElHWv1s+JG0c6hdq0Wg6tNudUG6U81JPLQojzsWiFVntxKOi8YZMWNsAdVTexa+auvUlgNSH/oDBpq6EEedq3WBW8htjqNQi5v/o2GIZGdnKxataacpVY90u+q1mJXjV9R5WPVqnW/LbUi88jL8AZZcTV2oSrAqlXrX1hqJb1Yb2XF1YgOjdq0UkFfQqvNKGJDt86Kza/btFIxD0Krb1HE5QraacRmUSxaPVGzszKrNdIpNJr6MX4XbdFqDG8gtZIOS4ZZcRXxWGN7VtqefiKr6mOUcNmOhiEkENWe1QW0byCy0q90OPyCdhokisGelXZiEllJw5hpIOpmEt1ozeoWmjeRWK0ThoaxAlGtWelBNxIr6WArTWVkCES1ZTWnhwdIrIRLHgyBqCp3U4gtq8g4vsCqT/jj9gTNNEyBqJasosNYAqtP8JLJ3aCVzneo0rFkFd2qVWAlDDlnBqLasXoZHXHkW62SxVbcYwai2rGKTbnwrdS2pzzo3vnmQFQrVvE5Z76VLI7UEIhKQud9rFidRNMWfCvZ1PQhv41OQiCqDasn8W3D2VayebhH7EBUG1YkyS7bShSH6h3231zn3YRAGgtWdDED20qUYvIJPxDVghVdIsS12ojnPGjIXHVy2gyd2ppCzfQ07x7BsEaSazWC5zzoaT0VamPmdixtwdEaXCvZREiRVv6WfTG4VrL4sgKtFjC0HoFp1SMLBSzQyrj9NtNqC54yKc7KMODYgGklnLUvzGqenkKbMK2Ei4kKs6IXZj5MK2EwYFFWl3BgHJ5VTfh9X5DV8wEcGIdn9QGecSnIKvHH8KykY2bFWP2Iwyg8K7WhK5NCrOZoeGgLnpU0xqwQq49xlAGWVU26SrkIK20KhMCy2oAnbAqw+o0upQlhWZGl0suRv9Uz80UFYFlJwxHyt3pFcwTpsKyEK5I87/IEG/pFOo6aiYnk0eKEK6UWLCu1+2kOpBq3oNHxUVhWhgkaa6SxmqXjclFYViS5jEVSWN1bjSMTYVk9xJM8kFs9X37jEpZVngk2xVaL4SbAiXCspOHrIsRWdCU1hWMlXOonQ2q13OnPh2MlG2IXIrRiSbGsrGdA0ZFZ8aRYVpYTW0URWTGlWFa5pu2WWHGlWFaX8ZgLAiu2FMsq11z4fCu+FMuKn8IsBWwrgRTLip9tLgVcK4kUyyrPi1uulUiKZZXr7josq9d0SrYtHbe6cTkOjSGcp/PZ7en4/xWDB8lb7ibAsSp6l5MYV2m2heXgWHViS5CQc8vdzhvgWElH2W2ySKNsGHCspAvJLDJHE05z4FiN2s+Fx+SuKeyAAcdqRJjMxxo/0lxHPFhW9rMxcphPvws9y0oWxGSJK23nB9rDsiIH5c+CMeaFC8tKPNeYmZ9TniYAzyqndDxJ1Dljfu3gWfXmuCEr5ZdUe2Xr8KwqZJOi/HgpvOswwbSynUA9mdmN6FkWmFZWd/tow23G1AADrtWOIj6sh/uCTmWGa5VDtuc4c0dT3HOYYVv1kn2K7FI/m/aizwDbqrI9z7/BxW+SguJSwbfKI411i4vikYn2CKxqokUVfOqTm4IfYA+BVWUwj+SMD47LB1uWRWJlX2tpVjrSx0NkZVlrfiLzBV8CMiubWndH28XCZUNoZUvr6WS6waNrC6D9pyy1srG77r2zNJsMEzUuRHOn6YitKpUDWbI/v75xMss/U35WlYG0Q9QvZw/TXKoicrSqVA7JM0Av3jm/N/vpIVerSs9BwaTW69+nj74fX9KbjnytGmyZZqQxWnrw/YltFs/guVtVKu8cm3mYdCE/f//ahfFjO21fDRVg1aRv19jFB388r7+qv3g+9/Tx/eszEycPbN+QwxdsTxOVeXDQfxlD3XVmtSoMzkoBldd5xaqjrFitWHWWFasVq87y3lwTFbn1t/8yQBW6ZxVgumIK99DahZJusFJ7aIWZ/dy36nuBIi2zn/tWKh5Jy+znvNVqtauKltnPeSu1NEfP7Oe6Ve1vFEQy+7lu9R+89u6hwMdxq3C7s8gSZcet1HZn0cx+blut+gMvY8ui3bZS27DGMvs5bdWjtjuLxRw7bTWKF1q++QCXrdQeWmSLaZetVOAs2WLaYauqWkiPfWxCHLOavA7WVioH0T3vGZlvccxKRwUD0zBJd632o3emLabdtVJ7aNEtpt21UtudGbaYdtdK5f5r7hAax1UrlYHcsMW0u1bqi+sMCiI4aqXyTxm2mG7gqJWKi/gCBVE4VvFrx86zEz0zbTHdhCSyNVgZvhA6jFrBnLCQnaSbM1iZMjV3lG3omFdPCIsiu7cbrB7i2NKglneoqZ0YJIWZwWoph3jfLKg9tAxbTAeQZF8NK6KVaiVyfqiML5MoiEM3OfrTYEU3FugkW9Er0xbTATTV0v8MVl66INmcuIROBVt0G1hD8rK9Nf0Fhts7loDeyW8A3WI6gCZx9K2o1nE0cIFtJLqvYWS0qttYl1cMNbqkKsnKe5B0Ei0bq+IbQvpSvpW7Wgap0Mqg9ZBm4ykf/YaMWL5PkpW3OGZt3WFe7DMsIPB1YGXS8m5/XGqv4Z9o0qOYlVHLe/yZ5bV61lg3ou9xHgKblpVZy/NeXP/qi9Pl4uzEbNJiCLiEVklaTgEVzaoLtCDSXVbwaKBZua4Fiya6ldtacPCJWDmsBQEQtXJVC71XxKyc1ELXNeJWDnqh3zrUyjEtdDqKwcohLXSYYLJyRAudNWG0csELHTWTYFVyL/QxkUSrALxLuUDf2rCMVfm00K92vH37DyMY1dDteyuLAAAAAElFTkSuQmCC'
-g5 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL+Avb29gcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatr9evsNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+y8vLwN/A09PT19fX29vb39/fweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4eHh4uLi5OTk5eXl4O/g6Ojo6enp6urq6+vr7e3t7u7u4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8vLy8Pfw9fX19vb29/f38fjx8vjy9Pn09fr19vr2+Pj4+fn5+Pv4+/v7+fz5+vz6/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo18IGgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABKcSURBVHhe7Z35f9TGGYejNb6AQAzmjhNTIAQwGOwApgYbFzAEnEDTA2ICiYMbg7GblLRNoTg20NLWJrQuS5f9a+keX7065p3RaCStJD5+ftnVOyPtPPaupNFcb71+E8mS1d//8uc/fi/hTz/8Dbl0UFn9uxwA8oUEO0cBR5Iit8IBMgwKyiCxwn6ZB8X1w1n9C7vkApTZi2j1A7LnBRTbg2D1CplzBEruwmf1PTLmDJSe8Fr9A7lyB8pv47H6L/LkEBgAt9VL5MglcKjjssrxf6oKLGo4Vv9Eam6BRxWy+g5pOQYmFWyrnyEl18DFsUI850DGtsr9jwrUbWwrBP0Ub53Z39HenC1a1uw4emUOJfRT11FZPR5ea2WW3TdLKKaHuk7dCiEPywNNOEBG2fgNSuqh5iO1utOJnTPMwDIK60Zl9VkBe2aa7UsorguFVT6kLGsbr1WzwqbDeE6kKlrPUWSH/0isFtqwTw4YQJld8FavdtfyN7UEkYn/6CRK7VC3wgZxtZ59FJtyeusZ06VDqBayVq+217PnxMq6jtIQNSu8J6aQOy9W3SiNA2dllzUvVtYDFIeoWOGdwzvInBurT1AcgrF6irz5sepDcYhfilZfIW9+rLaiOMRvRKuLyJsfq1YUh/hWtBpFXsdqcUHCfuRMmQLKSfxetDqLvI7VYQQyC8pJfPdGWv1hxSqzoJzEilV2QTmJFavsgnISWlant4Otm7JZ9Uc5CS0rN3OfD6xBenZA2YjQVhVeXN2BHFkBBSNMrCpcydY3EaUiDK3Kj+qPoTICCkWYWpVfHkSuLIAyEcZWmdJCkQhzq/LLXciXPigREcEqQ8+tUSBCZdU/4Wdy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'
-g6 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL+AgcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+yMjIzMzMzs7OwN/A0dHR2dnZ29vb39/fweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4ODg4uLi4+Pj5OTk5eXl5ubm5+fn4O/g6Ojo6enp6urq6+vr7Ozs7e3t7u7u7+/v4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8/Pz8Pfw9fX19vb28fjx8vjy9Pn09fr19vr2+fn5+Pv4+vr6+fz5+vz6/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzLH1jAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABQfSURBVHhe3Z39QxRHnoe3B3kxKBoXg0FREaOLwaAiBoNCSFASBXV3c7cr51tEDZwc3Nte9jZxT5R1lKx3mTBHGHfsf9Xtnv5MdXXXS1dV98x0+/ziTHXNUI/TXd319q1fvFHArhf4e7FRsvrzH+vEn6p899133z969Oh/Avzw6HuH7/7jv/71dyiYCKkV/gdTCgrJQ2j1Cp9NNT+jsGEEVvhUBkCBg3Ct8IGM8AeUmoJjhcwZAgX3YawycT2FQdkJIat/RLasgeJXCVr9OzJlEBh4BKz+jByZBA4VaKu/4nhGgYULZfUDjmaWP0GEtvoDjmWY30PFt/oHHMk0v4FM1erXSM84sKlavUZyxvk/z6ZqhdTM89uKDayQFqa8MHW8c2tLc6poae86Nb0sOrkqOjKrn6Z2Waml+9omihnkj66OZ4WUAOWLLfiClNI+y/29pFar+/HhFPPhjygszaOqFd7TzKf8h/LoWEVxacRW2ZDia/2byGoxI1KOVh5F9nntWeGdz0YnPpMB+tgqQ2A1gk+EyDXjRaqYRqF9KlZ47bOI/BQtAxe/WXdq+/WH491ISgstL1FsAt/qI+QndF5yjAgvrryL9HTwGcrlw7Naa0J20Ha1jCNVNs7lcCwNdJRQLIJj9d94SfgcuUEfW8vY9vJeHE0Dt1EogmP1M14SDiOzx+nwD+VR/hDHU8BZlIngWOEV4fU7yFxBIGXbpV7kaDz7USQCx2oVeSscF0nZ9vr7yNNwmkP9zW4diJeE+8jrsoOu+8Ks7UCuhvMCJSKwVneQ1eUe0jzWn/+EVx43kKvhMA+DrNVtZHUYQJLL87F2J+W9c/Q3pOUcfIryEKRW/4wk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'
-g7 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0drp2eLt4ebx5erx6fL18fb59fr5+gL+AgcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+wN/A2NjY2dnZ29vb3Nzc3t7e39/fweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4eHh4+Pj4O/g6Ojo6enp7Ozs7u7u4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8/Pz8Pfw9/f38fjx8vjy9Pn09fr19vr2+Pj4+Pv4+/v7+fz5+vz6/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAurfsHQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAA4VSURBVHhe3Z39QxTHHcZzKChijPieRONbNBgploZEY6PFUGkUG9r0LYkRYzVGiPY9VCJC2opSy5lj/2F7t/fsy93M7n5n5ju7M35+YW93Zm8+cPcwuzuz+9LzYgLXeIaGZUKx+u3f/uoSv/vzJ79Gy7LItcKvxlH+g1ZKyLZCXaf5AW3tJssK1dznH2hwB3Ir1PCD79HoFDIrlPaHP6HhMRIrFPWJ/6HpEaIVCnoGGg8EK5TyDjS/TbcVyngIBEI6rVDAT+DQosMKm30FFk3SVtjoLdBokrLCNo+BSNoKW7wGKokV1nsOZCIrrPUd2MAKK7tZvzc1unegr9cp+vp3DU9+3UATu2jr5FmtTb9ac5Ydk4/RzA7aOm0rrOpg/dMB7MBR+i7K/l6hT6bVoxOo7DAHFtDYNLEVXqe5vw01nabvNpqbIsfKD6lMLbnVoidSTa05NDkBVniVsH4EdTxg11M0OiHDaios39NXzIawZKWcRqMTQqsf8CJmuS8sfgAv8zgblqyWb9CWhJYVFhPG26V9sRpBWxJkVnVEhS9WG5bRmBiZ1Rco7YtV7UM0JkZmdRqFvbE6isbE/FdidQCFvbHaso7WxIhWz3pR2Bur2ndoTcxLwp/qIYp6ZHUTrYkRrRZQNLF6uthNfGjjhtUMWhMjWt1H0cRqBisSvsSW4DWsqJZraE2MltX26HDtHlZUDI/VODYEY1hRMSxWPUvYsLoZayqGxWoI64NfYkXVsFg5lhU8Vq5lBY+Va1mhZrXvLpjEijbOZYWaVQbOZQWLlXNZwWHlXlZwWLmXFQxWDmYFg5WDWcFg5WBWmFu5mBXmVi5mhbGVk1lhbOVkVhhb3UAZ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'
-g8 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL+AgcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+wN/AweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4O/g6enp7e3t7u7u7+/v4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8PDw8fHx8vLy8/Pz8Pfw9PT09fX18fjx8vjy9Pn09fr19vr2+fn5+Pv4+vr6+/v7+fz5+vz6/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB03dHgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABRlSURBVHhe3Z2NWxPH2odNIDRURKlYv0pLi9WqWBA/itJqqaIt1eqpPR6t+EXlyHl7rEpFrOfwlkiO5yU07p/Mu0l+Ozu7M7v7PLObZLf3dbWE2dmwt0k28/HMM5s2yFguKEktDCuVl4/+iUdc/vVvPKDw8rdHP//88z8fPXr028uXv/32P9F/NNQKr0w6wTVqCbbCyanmDa7VT5AVTks/uF4veiuckQ1wzTI6K9TODrhuF9UKNTMFLl2gWKFe1sDVA78VKmWPlxCo47NClSzyHyjU8FqhQjZZh4SNxwqHs8r/QcNjhWMZBiKyFY5kGqi4Vn/gQKaBi2uF8owDGccKpVkHNhFWC1dP7N3cVUgX3X0Hz92p4Ap9NGxghTIv1ZtDudTSc3YJl+mlrhNidW87niCldIy/xpV6qOk0rFAg83ocJ6eY/ge4WJkwq9IenJlq8t/jcmUcK/wqUdqN81KOTuuPIKtyRqRsreu4ZIkgq89wTgYoPsc1u9hW9n/4xeUuzvBT6MCDNLHvDa5a8Kb+WuEXwXofTpDoGP5u3v7iW5mZ7EdJariGy3bRWl1HdZeOM+5XXvX2AEpTwh7lxdJaDaK6YPc/cKRB9UInDqSDn3BdgpoVHgoeo7Jg3xqOCO534VAqGMFVCf6rsbqEyg6qlK1VwME00IeLctFYjaEy6C2h3MM0jqaCFVyUQGO1E3XBLRR7qX6Ew2lAuUSNlfczM4hSP3M4ngamcU2CTRu/45Egj7oNpBbJ+tIrPKrxHiqkgAu4JMGmjf/FIwGqNiiKPmd1qjeX+/ghflNvKm3kPC5JsGnj33gkQNUGH6HQuYkU5/CrNV//PRVorP6FRwJUbfA5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'
-g9 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAVapVVqpWWKtYWaxZWqxaXK1cXa5dXq5eYK9gYbBhYrBiZLFkZbJlZrJmaLNoabRparRqbLVsbbZtbrZucLdwcbhxcrhydLl0dbp1drp2eLt4ebx5erx6fL18fb59fr5+gL+AgcCBgsCChMGEhcKFhsKGiMOIicSJisSKjMWMjcaNjsaOkMeQkciRksiSlMmUlcqVlsqWmMuYmcyZmsyanM2cnc6dns6eoM+godChotCipNGkpdKlptKmqNOoqdSpqtSqrNWsrdatrtausNewsdixstiytNm0tdq1ttq2uNu4udy5uty6vN28vd69vt6+ysrKy8vLzMzMzc3Nzs7Oz8/PwN/A0NDQ0dHR0tLS09PT1dXV1tbW19fX2NjY2dnZ2tra29vb3Nzc3d3d39/fweDBwuDCxOHExeLFxuLGyOPIyeTJyuTKzOXMzebNzubO0OfQ0ejR0ujS1OnU1erV1urW2OvY2ezZ2uza3O3c3e7d3u7e4ODg4eHh4+Pj4O/g4fDh4vDi5PHk5fLl5vLm6PPo6fTp6vTq7PXs7fbt7vbu8fHx8Pfw8fjx8vjy9Pn09fr19vr2+Pv4+/v7+fz5+vz6/Pz8/f39/f79/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHWfsaAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABSfSURBVHhe3Z39QxRHmsd3BlAMqDE7vqxGxagQFIKBlYioiBIJGFbubbN3t7f3vixGIqKgBvdOjSiBE3Rchh36j/V6Zr5TXd31VHVVdQ/T7ecXmuoa6A/MdNfLU0/94r0xTl3BRaixsEoBSqst/H2SCS6SQm6F1yYaXKqAxOqveFniwfUGIK2S/c4LgovmoaxQOzXgsjlEK1RNFbh0hmCFeikDF18laIVa6QPXXyFghSppBAZl/FaokFIg4eKzwtm0AgsX3gon0ws8fFY4lWZgwlnhRLqBywduheK0U5GpWqEwyMrUwPHW5qZk0bzn1NDMW1xhkLINrFDkZ2v+bDaTVHb2/4TLDFDSUVg9P4ofkFS61nClPko6FSsU8BRvNOLFyaX1Di7Wh8Kq0IFXJpshooMrt0qJFKlVtcK3HsVOvCj5XMclc8isxvGSFJB9hGv2kFgt7cBLAjQ24CBJ5N7hqhkVK3zjcRIv4Dh8cWqp6H7enk/251CUFIZw1R6k1TNUZzSee4xTZe53Jurh/NEGrotRssKhx69RvUr7Ck4wnn+KU4ngFq6KQVnl/Z+q5kmU82yOJOgjdgQX5UFYzaNyhdbnKA5wvwkV6k82j2tiEFY3ULmMTCpRWvO4JAZh1YW6JXY8QyHBXGLuGaO4IgZhdQR1S4yjjGQAlepOPy6IQVgdRF2Xz9xHlEdh9XUBh2U2kvLk6sUFMQir/ajrfgyXUOSyeeezUknnfXxf4l6lWt05h+thuFZBLc+qAyUucx+jLHPgKYpcvKp1hbLCEcO71FmUuFLcDa/F07qJojpjZPUx+1T57+It7G6fT0Z/2ciqGwW+G0iJThT775f1w8iKPQb8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'
-p4 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAQEBAgICAwMDBAQEBQUFBgYGBwcHCAgICQkJCgoKCwsLDAwMDQ0NDg4ODw8PEBAQEREREhISExMTFBQUFRUVFhYWFxcXGBgYGRkZGhoaGxsbHBwcHR0dHh4eHx8fICAgISEhIiIiIyMjJCQkJSUlJiYmJycnKCgoKSkpKioqKysrLCwsLS0tLi4uLy8vMDAwMTExMjIyMzMzNDQ0NTU1NjY2Nzc3ODg4OTk5Ojo6Ozs7PDw8PT09Pj4+QEBAQUFBQkJCQ0NDRERERUVFRkZGR0dHSEhISUlJSkpKS0tLTU1NTk5OT09PUFBQUVFRUlJSU1NTVFRUVVVVVlZWV1dXWFhYWVlZWlpaW1tbXFxcXV1dXl5eX19fYGBgYWFhYmJiY2NjZGRkZWVlZmZmZ2dnaGhoaWlpampqa2trbGxsbW1tbm5ub29vcHBwcnJyc3NzdHR0dXV1dnZ2d3d3eHh4eXl5enp6e3t7fHx8fX19fn5+f39/gICAgYGBgoKCg4ODhISEhYWFhoaGh4eHiIiIiYmJioqKi4uLjIyMjY2Njo6Oj4+PkJCQkZGRkpKSk5OTlJSUlZWVlpaWl5eXmJiYmZmZm5ubnJycnZ2dnp6en5+foKCgoaGhoqKio6OjpKSkpaWlpqamp6enqKioqampqqqqq6urrKysra2trq6ur6+vsLCwsbGxsrKys7OztLS0tbW1tra2t7e3uLi4ubm5urq6u7u7vLy8vb29vr6+v7+/v7/+wMDAwcHBwsLCw8PDxMTExcXFxsbGx8fHyMjIycnJysrKy8vLzMzMzc3Nzs7Oz8/P0NDQ0dHR0tLS09PT1NTU1dXV1tbW19fX2NjY2dnZ2tra29vb3Nzc3d3d3t7e39/f4ODg4eHh4uLi4+Pj5OTk5eXl5ubm5+fn6Ojo6enp6urq6+vr7Ozs7e3t7u7u7+/v8PDw8fHx8vLy8/Pz9PT09fX19vb29/f3+Pj4+fn5+vr6+/v7/Pz8/f39/v7+////AAAAAAAAAAAALXB5YwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAA7sSURBVHhe7Z15mBTFGYdnl0MEQbkWMMKiqEAUQYOokBBQMNEoiAoxJqIxXhFFg0GCxhuNiaiIEY8IHhEUUaPigRoPJC6ooLgKBJC4gCCIAgvsAjv1PJM+flPTPd09W9VH9dfz7PvPVH1d1f29zNLTR3V1KlOMFLT6b5qRJb0aSbrhbbUX3QlTh1QdeFhtRT/yVCNhO65WteiSCPYgaSsuVon5nrI4vy+H1QdomiiWIPks+VbVaJcwdiF9kGdFeFdeDxAwsVuhRSKBgoHNCssTCiR0rFZYmligoWGxwrIEAxGrFZYkGqjkrBJw2Fc/achkrdYhnnA2mzZZK0QTj2kDK69f3/SaZ8aPHjWSFKNGj5u52vNwwdAxrZYilEfVhE4porT/w2okmYdxMmlaIWJn9VmNsAqSlJy2DIna4VYrELCSnrYfupOl2eQ6JGtlbdYKdSvVp6IraQZ9j3SteFtV/xT9iNPPRavCtHJ+jzsSIqVpOc/ctZ9i3Qo1C79HnwTwG6RswcNqHnokgueQdI5PdKs9qHCqu6CDOIfNA68egIgyyrYgbU5at0I5x9/RXoJH0ZU9gYBC7sCmc7hZpY9Ac3EO3o2+dT0RUUi543TDzeoNtJbgQXRlsxBQyhxsnKNZVaLIuQqNxemSvdhb1wsRpVyIrXOqUs4rgD9BY3HuR082BwG19MbWOXUpxx/g3hZoLMyBu9CVHYOIWhrtwOY5TquVaCvOPejJXkRANR9j+xyn1RI0FabDTvRkxyGimnexfY7TahGaCvNXdGSvIqCceUiAE9yqHd/dDEBEORFYTUI/9iYC6gnfqvU29GODEFFP+FY3oRt7D4EYCN2q1XfoxoYi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'
-r0 = b'iVBORw0KGgoAAAANSUhEUgAAANQAAAE/CAMAAAAJ9B3fAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAA/1VV/1ZW/1dX/1hY/1lZ/1pa/1tb/1xc/11d/15e/19f/2Bg/2Fh/2Ji/2Nj/2Rk/2Vl/2Zm/2dn/2ho/2lp/2pq/2tr/2xs/21t/25u/29v/3Bw/3Fx/3Jy/3Nz/3R0/3V1/3Z2/3d3/3h4/3l5/3p6/3t7/3x8/319/35+/39/iYmJi4uLj4+PkZGRk5OTlJSUmJiYmpqanJycnZ2dnp6en5+foKCgoaGho6OjpKSkpqamqKioqqqqq6urrKysrq6usLCwsrKys7OztLS0tbW1urq6u7u7v7+//4CA/4GB/4KC/4OD/4SE/4WF/4aG/4eH/4iI/4mJ/4qK/4uL/4yM/42N/46O/4+P/5CQ/5GR/5KS/5OT/5SU/5WV/5aW/5eX/5iY/5mZ/5qa/5ub/5yc/52d/56e/5+f/6Cg/6Gh/6Ki/6Oj/6Sk/6Wl/6am/6en/6io/6mp/6qq/6ur/6ys/62t/66u/6+v/7Cw/7Gx/7Ky/7Oz/7S0/7W1/7a2/7e3/7i4/7m5/7q6/7u7/7y8/729/76+/7+/w8PDxMTExcXFxsbG09PT1dXV2dnZ/8DA/8HB/8LC/8PD/8TE/8XF/8bG/8fH/8jI/8nJ/8rK/8vL/8zM/83N/87O/8/P/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9fX/9jY/9nZ/9ra/9vb/9zc/93d/97e/9/f4ODg4eHh4uLi5eXl5ubm5+fn6Ojo6enp6urq6+vr7Ozs7e3t7u7u/+Dg/+Hh/+Li/+Pj/+Tk/+Xl/+bm/+fn/+jo/+np/+rq/+vr/+zs/+3t/+7u/+/v8PDw8fHx8/Pz9PT09fX19vb29/f3//Dw//Hx//Ly//Pz//T0//X1//b2//f3+fn5+vr6//j4//n5//r6//v7/fz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATF6XsQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABMBSURBVHhe7Z39gxTFnYd3ZndhBeQtKIuuBgVxs7lL7uLlXvRyMYl3ueNNBEUgQNDjEoKKCL5tFiSAHHAvSdwAIhAQFnFVRO5yl/PuEszyqq4kxgRB2Mi6zM6/Mdfd85mq6qmXrqru6Z7OzfPL9lRV99SzM93TXS/fqiso+PIPfpuvSj74/pdQRSFSqbs+wAGqlve/gqpyiKX+vOqNirx/GyrsRyT19UHskwIG70KlWXipO1Ok5JK7AxWncFK/RtkU8StUnVAm9XcolzL+BtUHfqn/QqHU8RMIFPFJ/a5YIo38BgoerFQOBVLJFUi4MFIpu+qVk4OGA5VK9efkQj8rIpXi86nEB1AhUqm97rH8O2QgldLfp3K+VrSBFBJTT9GmKCW/N8qd6O46UFV0dZ+SX6d/7ul4UnciqZzjK6cNz1QhI2asPoUqlvNFIiU0H9wzA8eoRrL37BfW2ruuu1J/iwQf78zE7lXLvWdRVR93Qkqk3FmV3zs/I19AZVncGwtH6i/wkqUD+1U5m1Bdls97Ur/BK4aUOAmtnAugI4UXDD/CLilgD6rM4ErdhW3Kuyk4n0qM/hCVptzhSHGtYYPC695VrXPmzfnMVXhVPcxDrSn/60hhk/JjFGeYubWn+GSSO/7cLKRVC91exVhEUuUf1JBlJ5BT5OTyocipCviPqlD3ZWwRTqBwiSl+JZeTrcirBup7USvCF+t+gC3CShQukm0XPRHnOrLIrwI6UCnCv9Zxv1LTUdYj24nUcrZXj9VcVInwZh02CDn2ei51qiara1AjQo6TOomiHu1IFFE9dx3nUCMCJ/UKSrpMUbUw5armatGDGhE4qYMo6TDEd9073Lmx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'
-r1 = b'iVBORw0KGgoAAAANSUhEUgAAANQAAAE/CAMAAAAJ9B3fAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAA/1VV/1ZW/1dX/1hY/1lZ/1pa/1tb/1xc/11d/15e/19f/2Bg/2Fh/2Ji/2Nj/2Rk/2Vl/2Zm/2ho/2lp/2pq/2xs/21t/25u/29v/3Bw/3Fx/3Jy/3Nz/3R0/3Z2/3h4/3l5/3p6/3t7/3x8/319/35+/39/s7Oztra2urq6u7u7vLy8vr6+/4CA/4GB/4KC/4SE/4aG/4eH/4iI/4qK/4uL/4yM/42N/46O/4+P/5CQ/5KS/5SU/5WV/5aW/5eX/5iY/5qa/5yc/52d/56e/5+f/6Cg/6Ki/6Oj/6Sk/6am/6io/6qq/6ys/62t/66u/7Cw/7Gx/7Ky/7S0/7W1/7a2/7e3/7m5/7q6/7u7/7y8/729/76+wMDAwsLCxcXFx8fHyMjIysrKzMzMzc3Nz8/P0dHR0tLS09PT1dXV1tbW2dnZ2tra29vb/8DA/8HB/8LC/8PD/8TE/8XF/8bG/8fH/8jI/8nJ/8rK/8vL/8zM/83N/87O/8/P/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9fX/9jY/9nZ/9ra/9vb/9zc/93d/97e4ODg4eHh4uLi5ubm6Ojo6enp6urq7Ozs7e3t7u7u7+/v/+Dg/+Hh/+Li/+Pj/+Tk/+Xl/+bm/+jo/+vr/+zs/+3t/+7u/+/v8PDw8fHx8vLy8/Pz9PT09fX19vb29/f3//Dw//Hx//Ly//Pz//T0//X1//b2//f3+Pj4+fn5+vr6+/v7//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWNr1QAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAA2QSURBVHhe7d35fxR3Hcfx7HIfclquJlAoh2cEGkRKSpsgEKCUcmMErVhatWrDjUq5WsNRsFWxVUiBCCjaFoQQEULY5C9bZ2fe+53jO7Pz/c73852d2ce8fpnZ2ZnZeT5ybXZnvltXrNRbtwcT2cNf4gD9C0Z9ih0ktv9+E0fKFYD6BBsmvIc4XE++qKfYJg39BMfszAf1CKunpW/guO041J+xaorivgm9KKyXsvbi6JEb9Q5WSl3/BMDKhUr8b/HgCiCYOVFfYoV0BkQpB+oh7k1rYBjZqC9wX3oDxIH6C+5Jceznqox6G3ekun8BU0Zhccr7mYUBagBL056lsVAfYRnfQPeZ0yeTVWdXAQfH98jkWCgs8nZj4+LxuQQ2cn7bBRyitzcY6nMscXdm2VDsJInNPeD/DxJD4barnhXYOrHNuYpDdfVzoPy+UKcnY9MEN3yb3+83oHDL2dEkf+fZtfmojP8ZDdSvcctRSky+KuN5hYHCDUdn02LK5TbjkB35ox5PwxYpaNhlHLTdXgP1C8zbrcIGaOqL6HksSFSz+nHUrAEDxX1XXsXqqOEulg8ewpJk1Y6jszNQmLNzf6FsU0JRDdxXxQf1YDTWNnOYEorKfYDDY73BozqwrpnTlFTUyzg81l/r3sIc6/tYt5TLlFTUszg8u7pLmGHNwbpGblNSUfkHOD5WnfeV86fDsS5nSiqK/6Gqw5R1D2vypsSiDuP4WBzqJtbMTfCaEovqwPGxONQNrJlrwAK7WkKdx7SWUDu/g5kaQu3MNVozNYTamas9lGGqOVTJVGso01RjKMtUWyiYagrFntjWEoqVoapRhkIZqhplKJShqlGGQhmqGmUo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'
-r10 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwPz8/S0tL/1VV/1ZW/1dX/1hY/1lZ/1pa/1xc/11d/15e/2Bg/2Ji/2Nj/2Rk/2Vl/2Zm/2ho/2lp/2pq/2xs/21t/25u/29v/3Bw/3Jy/3Nz/3R0/3Z2/3d3/3h4/3p6/3x8/319/35+/39//4CA/4GB/4KC/4SE/4WF/4aG/4eH/4iI/4mJ/4qK/4yM/42N/46O/5CQ/5GR/5KS/5OT/5SU/5aW/5eX/5iY/5qa/5yc/56e/5+f/6Cg/6Ki/6Sk/6am/6en/6io/6qq/6ur/6ys/62t/66u/7Cw/7Gx/7Ky/7S0/7a2/7i4/7q6/7u7/7y8/76+x8fHyMjIysrKy8vLzMzMzc3Nzs7O0dHR0tLS09PT1NTU1dXV1tbW19fX2NjY2dnZ2tra29vb3d3d39/f/8DA/8HB/8LC/8TE/8bG/8fH/8jI/8rK/8vL/8zM/83N/87O/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9jY/9ra/9vb/9zc/93d/97e4ODg4eHh4uLi4+Pj5OTk5eXl5ubm5+fn6Ojo6enp7e3t7u7u7+/v/+Dg/+Hh/+Li/+Tk/+Xl/+bm/+jo/+rq/+vr/+zs/+3t/+7u8PDw8fHx8vLy8/Pz9PT09fX19vb29/f3//Dw//Hx//Ly//Pz//T0//X1//b2//f3+fn5+vr6+/v7//j4//n5//r6/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF6KyZgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABdwSURBVHhe1Z35QxRZfsDNUQ2CgIDiAQNB1wPHcfAcHG/wGHQQD7K7ySabTTbZrIqiI+LFKOwms9kkG0FhPLJJZkYHHWZXm6b+P1LHt1+9V9/vq3qvqrq6+vOD0u8V3fWhql+98/uWLQXyRcHMIov/DucnQW7100V4i8zyCzhTjMTqx5lXcvl7OF8fpNW/we9UAr+DcxYgrH4Fx1cK/wHnzYGt4NhKAs7cw2/1X3BgZfE1nH0Rn1WFFBIYOH9AtIJDKpEfgoIDb/WXcEBl8nOwsOGsfgTZlQr3UOasILNy+VsQ4a0gq5IBE84KMiobcClamd9DemVT+MrVca3+8DNIrnR+82PHx7H614D7b37i3li2uPvgDZwbgSPlWplfQ5qPhWv723JGBlm379I7OEcfhf8pWi3Sl+pV/yp4kyzS0PcMzlPElrKtfmEuQIrA1Qb4/axSe56stX7vWpnUpZrbA7+bZbY9h7Plca/Vb81v4DXHXAf8YrZZ8xTOl2Px97YVdakqRIrWsq/Vz8y/glcehR/AL2Wf9W/hnD1+Y1lZlwxeeZyBX6kEDsM5cyxYVvgGnFoOv0HSsHnHzp07tjTCy7JzB87aw75W2Op9OB5Rtf3kDXYjP//s1I5A/ZR4D91rttUX8DPjCRzup6X/BRzBeHlmDWSWkXtwMozv/8H6Xvk5DEeLdI2SXe6FW9Irmxa74FQ8CtiqUA9H89RfhlyC4TJXQqpwZdd6XvmgbsBudO/xvNwFh5UJVF7YT2Efl+FYj9phyJJytQ4OLQtn4CwYhNUROJZR/znkBDBRzrsQfbEIq71wbJGGKcgIZLqMz68tcA4Mu27hYyccC9RNQHqR+fGh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'
-r11 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwPz8/S0tL/1VV/1ZW/1dX/1hY/1lZ/1pa/1tb/1xc/11d/15e/19f/2Bg/2Fh/2Ji/2Nj/2Rk/2Vl/2Zm/2ho/2lp/2pq/2xs/21t/25u/3Bw/3Fx/3Jy/3R0/3V1/3Z2/3d3/3h4/3l5/3p6/3x8/35+l5eXmZmZmpqanJycnZ2dnp6eoKCgoqKio6OjpKSkpqamqKioqqqqq6urrKysra2trq6usbGxsrKys7OztLS0tbW1tra2t7e3uLi4urq6u7u7vLy8vr6+v7+//4CA/4KC/4SE/4WF/4aG/4iI/4qK/4uL/4yM/42N/46O/4+P/5CQ/5KS/5SU/5aW/5eX/5iY/5qa/5ub/5yc/56e/6Cg/6Gh/6Ki/6Oj/6Sk/6am/6io/6mp/6qq/6ys/66u/7Cw/7Ky/7S0/7a2/7e3/7i4/7m5/7q6/7u7/7y8/76+wMDAwcHBwsLCxMTEx8fHyMjIysrKy8vLzMzMzs7Oz8/P09PT1NTU1dXV1tbW19fX2NjY2dnZ2tra29vb3d3d3t7e39/f/8DA/8LC/8TE/8bG/8jI/8rK/8vL/8zM/87O/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9fX/9jY/9nZ/9ra/9zc/93d/97e/9/f4ODg4eHh4+Pj5OTk5ubm5+fn6enp6urq6+vr7Ozs7e3t7u7u7+/v/+Dg/+Hh/+Li/+Pj/+Tk/+bm/+jo/+rq/+zs/+3t/+7u8PDw8fHx8vLy8/Pz9PT09vb29/f3//Dw//Hx//Ly//T0//X1//b2//f3+Pj4+vr6+/v7//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeyflvwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABGPSURBVHhe1Z2Lf9XUHcC7R9oCBWqHIKgrAkK3idvUTbe5qduUIiDyUhk4R3lIsQNB3eZrvqcrpVrAjjkQcT7mhMlAimxzSktXkNKW/EN3Sc4vuUnOSfL7/ZLcm/P9fPDmJuek52tukvM+NaU4bv3jF2YRuXjkd9dAEpVEW/12FE5RWN77FiRVIsLqZ2MQs+C8A+kNobR6AeLowGeQ5gCy1Y1PQ3hd+C8k3Idkdc1FCKwRL/4AEu8SsrrjbQioF6OQfJeQ1TkIph2PgIAgaAVBdOSVG8HBxm/1fQigJx/cARoWPqub4LCuHH4MRHxW354PB/Xl/Z+Ai2f1HZ3vKZfnQaZ8rTTJIsXzQ5ABK/MD2K85wgaszt0Me3Xn8yccH8fqnZib6sKhfXuLRe/+05A2BeI5aFtdb74L+0JcfP0Xc8YZBeSypR1nII1h/uNaXVRfqvNbvw4nKSINq49BOoO8/Q1h9QfzCOwJ8MYMiF9U6taPQFIDwLUyVZdq5IFaiFxgrjoKqfXzimP1vqkofYwsgYjFpvEgpNfPv20r1aXSREqt9WPL6lnzu/DNxz0Qqfg0noQklzl3e6nGNP8F38q8ClF0YKFcI2FdK8UPsH8KxAgza3mY8XCkimyDVJe5UWl1P4SXaPoIQnhcCkeqyOQhSIvH4fk15s9h22NoEoSXkbQKYKW4WM/XmIdh02MrhFYR1iqCVbN0Z41ZT4swcyG0kpBWEawM6eluv69CjMTmZ+t2QTBBIax+DYnxuF62OghhldR1QSigEFarIDEej8hW2yCsirBUMayaITEej8tWmyCsAkmqGFZTIDEeT8pPizYIKyNLFcNqEiTG41H5WkVaKaQK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'
-r12 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAQEBAgICBAICBAQEBgYGCAgICgoKDAwMDg4OEQYGFgcHHAoKEBAQEhISFBQUFhYWGRkZGhoaHBwcHx8fNxISISEhIiIiJCQkJycnKCgoKioqLCwsLi4uMDAwMjIyNDQ0NjY2ODg4PDw8Pz8/QBUVTBkZUhsbZSEhQEBAQkJCRUVFR0dHSEhISkpKTU1NUFBQUlJSVFRUVlZWWFhYWlpaXFxcXl5eYGBgYWFhYmJiZGRkZmZmaGhoaWlpampqbGxsgysrii4urjo6tz09wEBAzURE00ZG1kdH2EhI5ExM7k9P5F1d8VBQ9VFR+FJS/lRU/1ZW/1hY/1pa/1xc/15e/2Bg/2Ji/2Rk/2Zm/2ho/2pq/2xs/25u/3Bw/3Jy/3R0/3Z2/3h4/3p6/3x8/35+qampqqqqq6urrKysrq6ur6+vsLCwsrKytLS0tra2ubm5urq6u7u7vb29vr6+/4CA/4KC/4SE/4aG/4iI/4qK/4yM/46O/5CQ/5KS/5SU/5aW/5iY/5qa/5yc/56e/6Cg/6Ki/6Sk/6am/6io/6qq/6ys/66u/7Cw/7Ky/7S0/7a2/7i4/7q6/7y8/76+wMDAwsLCxMTExsbGyMjIysrKzMzMzs7Oz8/P0dHR0tLS1NTU1tbW2dnZ2tra3d3d3t7e/8DA/8LC/8TE/8bG/8jI/8rK/8zM/87O/9DQ/9LS/9TU/9bW/9jY/9ra/9zc/97e4ODg4uLi5OPj5OTk5ubm6Ojo6urq7Ozs7e3t7u7u7+/v/+Dg/+Li/+Tk/+bm/+jo/+rq/+zs/+7u8PDw8vLy8/Pz9PT09vb2//Dw//Ly//T0//b2+Pj4+fn5+vr6//j4//r6/fz8/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfVCjXAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABVDSURBVHhe3Z35Y9XGncAnbCjp7qZpmt2w2zSEdrNH98g2zZY2QAN7H93DzzYGbGzsgMvSpkma5XLAnMEEGxsMhjSwaa4t2OAYAwaWhCSLsY1DOewGW9Zfo9Xx1UijGY2+oyfpPfXzQyLrjd7TB0lfjUYz3yGGjB+/97leltx8C/ZQTJjV95575VfwDWXLp7CvPGKrZ/+zTI9RkE9ghwMIrX4G2+QBzXgO9toHb7X+FSifF+7BjvvgrXJy7vn56Eew7y4Bqw0noGDOgN13Ya2Wfgalcse7YODgt1pgaFAmh3y6HiwsmGMFBfLJ7Q1gYeK3go/zyufHwIOxgg/zy+0XwcRnleNryuVjUPGsfgmf5JqfL3RkHKul+tuwPufYNq7VvfxfVA4zx20f2+qy5KLShs8NlBdnz4/NwM7xXPKs9DdgXZChtubqijJkxZaOG7CLQajVjPj803rXwpeUI5XbzsN+stwCq/fFoeL687B92bJzAnaVAax00aGaOVgF25YxtWdhb/1YB4sYH+o/hb99zOyFDcubytOwv35sK10QAHMiJdZ6caFB3hGdgJ2wUflTKYgZGwyi6/zj77VK2CYH1E/BTnuYx0p/jrulTTfBFlhqN7+6tWV1Af7KmNdgrz3Wm1b8CXgYyqNYtqd/3Nls6nxnPazMlBHn5z0+EVnNrIbiCFZ1T8JWDgMt8EGG8AfrXcLXls5C6WgKbfxJfXoFfJgZy9h/WBON6P8Hi5QdUDqS2nOwBcOdV+HjzDgJv0wxyEJY8miAwlHUjcIGAbTtUCAr9sAPU6y7cIAJZCwLk8peaw38LuUoWQxLlEEoG0HVdSgvQGuGQtlQFawcHSfPwRKl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'
-back = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABQUFCQkJDQ0NERERFRUVGRkZHR0dICAgJSUlKCgoLS0tMTExNTU1OTk5PT09Pn4AQn4AQUFBRUVFSUlJTU1NUVFRVVVVWlpaXV1dYWFhZWVlaWlpbm5ucXFxdXV1eXl5fX19az+RUUGvU0G0UkK4TUrcUVH0U1P6VVX+XV30Wlr+YmH9amr/bm7/cnL/eXH2e3v/BJUAFYUAGIQAAKMAAKoAC60LEa8QE7ASGrIaI7UjKbcpK7grM7cpNbgqMroyPL08e4UAZb48Qb9BRMBETMNMVMVUWcdZXchdY8pja81rcM9wddB1fNN8Z5a2cJuqlkJ0mkNyzktfykpg81FS+lNT/lVV/1tb819p/l9g82Bs/2Ji/2ho/21t/3Jy/3t7vHy+gXn2mn3hvH3A3W+Q3XCSgYYAl749mL08vZUAwpYAyrcpyLgq7aMA7K8Q8KQA/qoA/6wJ/68Q/7AU/7Md/7Uj/7cp/7gr/7oz/7499Zhr/5ZnzsBD/8BD/8NM/8VU/8pj/81r/89w/9By/9J7gYGBhYWFiYmJjIyMkJCQlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1urq6vLy8hIT/k5P/mJj/gKfCoZjYpJzYoaH/pKT/qqr/rq7/s7P/u7v/gtWCiNeIi9iLk9qTm92bo+Cjq+OrsuWyuOe4vOi8/4KC/4yM/5CQ/5WV/5ub/6qF/qOj/6mp/62t/7Ky/7W1/7m5/76+wcSDwcaJ/9WD/9eI/9mO/9uU/92c/9+g/+Cl/+Kr/+Sx/+e5/+i8wcHBxcXFysrKzc3N0dHR1dXV2NjY3d3dw8P/ycn/0dH/1dX/3Nz/w+rDy+3L0e/R1fDV3PPc/8LC/8XF/8vL/9TU/9nZ/9zc/+vE/+7N/+/R//DV//La4eHh5eXl6enp7e3t5eX/7Oz/5PXk6ffp7Pjs/+Pj/+np/+3t//Xj//fo//js8fHx9fX19PT+9Pv0//Hx//X1//ry+fn5+Pj++fz5//n5//z4/v7+AAAAwISkTAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABclSURBVHhe3Z15YBXHfcff0wkoQIsQAnNIpGlcFWLqtEGA6tYkMTS2oadLDzdO77vp5TZNL/cIt7ksuWnrxA6JDxK7pooP2rShcVqQkKjrJG0wmKa20GsOgRspAeTgob/fzG/v3fdmZn/v7Vt//rCl92af5sPb/e7szuxM4WoFRF1BlapEBSv6sPqC6laGslb0KfUJ1TGWMla0dZ1DlQ2SaEUb5QCqsJ8EK9ogH1CdfcRaUencQNX2iLGiormCqu4QsaJieYNqT4StqFD+oPorQlZUJI+QgSRoRQXyCTkgASt6O6+QBeC3ojdzC2kAPit6L8eQiN+K3skzZOKzojeinDw+0F9XDBwfpapFIBfXil4OcXJ5e1OhDmmc1z1CVQxCNuWs+ufTh9Ql7Qeomn7IhqzoRT/jHbR53dI+RlX1oXSUFb3kZ39d7npBmvZQZT2kTqLVbtqwztlB1fWQPtKKXvCRE6kYrTJWB2ib8hSbW2dkvp/upSq7JFqNN9MmSTTNX75vuKTK7l9AL2ZDYzgyEq06aYt4Xrd1mMoRI3PpnUyYT7VwSbA6RuXjaOqKO/0to3cz4R6qhANZ0W8uyV9V664pKiMunX3+qY//zX33Pyd/y1KrXdbAR6zVGJWO0LRzWpW4cOTxd24BfrAHuO4/8KUsd8JIszDOajsVDrNYxcOlp9+FRsBtb0Srnp4H4NUTVCgLumW9fMRZxWda64B88/zhHyOnLVter6R6evDbyjAJo7sgWNGPLq1UOECH/KIu+Jy2/Mi1JNWzCt7aRwUzoAmr5ifGapzKBlgu33rK57Rly7eSEwCREbtZjYgcWFGrESrqoyhbkRPO8aSQUUHgkdVIhTPgOFbPTyGyAw5TUY+ivJJ5PvBFuVEhuQ/ej91xa4M65H1ErYaoqEtxP778cbJxcKMC+QAUaKHiGWBjdTe++jjJOHhRgXwQSmTYzrWwkmeDvyMZF19UAHhcUfEsMLeSJ4PwNxWICuDZbDPQ2KplHF4KH1PBqAA+E7Pj1hBjK2wQnyYXj0BUAK8IsZc2yAJTq4XwwvnbycUlGBWqbdFFW2SBoVUj7n+PkotHMCp6et4PpdppkywwtNoGvz9NKh6hqOjp+XchpjNsWhhaNcM14sXI/heOip4VXxPiOG2SCWZW2+HXQXLxCEdFz71QrJs2yQQjqwa4+rgQbP0B4aiQO6CYSdtkgpHVYvht8LYw33JtiG+HHTDaJK4lRlbQwH/1d38rxFtXh9kEGy2hTbLBxGoG/PIpcnH5jTeTi0vvl4SYzDIBzayWwS9/SjIu30QuHrdCsR20SUaYWEHZy+Ti8itvIReXtV8RYirDayvEwKo4LcSnScblO8nF4yHYJOleW60wsJoDP/85yThEo+LtUGo826PKyGop/PwHZENEo2INRIVYSFtkhoHVbvj5t0mHiEbFISh0D22QHQZWUPQlsiGiUXEQyo9nHBWAgdVJIf6VdIhIVNyC5bO8BCEMrKC9/i+ko4hExTuweJZXiw76VkX48Z/JRxKJCvlN1UW3uL5VI/z4CRKShKMCj6ks+wx82FuFomItpp/YV1SFM8ZsDzxKRkgwKm7C85TYpYpmjkFajAjxIhkBgahYi82kjPu4/RhY7YKf30tOgajo3QQNWjhPzaOC2WNghe3A/3EaF15UrN38ZVnsQKWRJjXEwKrQD798Wmm5UbHhkW/IQucyb/v5MbGaiWMrXvwTtMKo6F1/66GvqyJTW7NupQcxsSoskL+/dPSf/vHBhz/2efkLUtpW7Z2v2NI2t2Ph4mVdy7du27a1e8mC2eX/FY2sCgvckTAexxc30LvsFGe2L962d2B0kv6Un7H9y15HxaKYWRVm4rHlMdW/bAa9w0uxbeG2A6M08iaRc7vmUPkQhlaFwuydJ/CPlUb7dy2ZXZWWRNs1u4cr+biMLo3bF42tkIZq7XPFud394d3t0sSZU08OHn7s0Xfd8c7bb/+Jn1mxYuWqe9//wHOv0Pul5VEvK6vq0LasP3DYXjxzZPCxO0J9FT9NN717elZcf///qoLji+kTXOrEqqFjt38I5sSpwUcjXS/Ij68kJ8WqD31Nlh+aRZ9D1INV48L93pd06fTgo5EOCpefJR2XlR+UXtPBJmjmVg2dnhIY3UHVj+fnycXPShwFAQ02/9GVsdWc3W44TDxR5jsivoNMgqz6DG4/4jvHZGnV3OWODTtz+Keo4uXwoiLIivvxM8610edmaTVnr3NSOnM4NhkihKLCz714dJXcxkZGVsVFzmDxiUGdb0kSiQof130RPmvcicJMrJq6z6mP9obsahAXFR4r8eQ1Rs3sDKyat1NCnH28Yjz4iY8KF6l1XLXham7VslMF+ZVTBl8TkhQVLm/CnVDdD6qxVfMO5XTpSe2jiSgTFQ7XY9NQPvpWU6vGrWrfuzBotOtJykWFw1/BZ4/jYMtaWi3BQVCh0eK6lI8KBxzogbfEa2fVrp6SuWjjVDEqiJV4aM2undUM9YDoJYt9D6kYFQTugwO1sioulyFx5Sm9RkQEjaggsEk4rzZW81R777R87scGnahQXA9/p78WVk1ypLiYiA6W1EUvKhT4+Nes6lt1yNbRFcsDSqIXFQocxbej2laN6rnk06YnXT+6UaGAGByvstU8eTfiYmRMvwn6USHBxx5CT4/yWhVxmK4Qz1smH6EfFRIcnx15Hp/RasYQbn7xMaqdJSZRIYG2u3dzh+CzWiAbfafTfVFmUSH5kKx1EC6ronwg/sphqps1ZlGBYPsiDJNV8zHcdKL8jTANDKMCeZOsdRAeq9nyJHUqxTmKMIwKibqfG4DFaiEerun3PouoQOj2ux8OKxnoFwyv4GMxjgrkWVntAOmtGvbhVi+kzT7EPCqQmBBMbdUkH2s9kv6QsooKRN14D5DWqlVe8kYfJrHBJioAeX86SEqrWRh+V1I2JwirqADYrWbj0/kXOXICsIoKgNtqLjaSzqc+9SrsogJgPq7a8TQ1keZSyodlVAC8VlLqLEeiI5ZRAbAmezv2R73AkeiIbVQAeK8zhLXVPPymznBJWUcFwGg1h1fKOioAORtPEEurNox0Pin7qABk53cQO6sZePI9yyaVIioArjZ780koN8GVfqmiAmC6vmrA2y7Rp/PtSREVgKp2ABsr7O+4aH0TPUqaqOjpWamqHcDCaicUusTU9kNSRYW6IRjG3AqfjRY8rXRFqqhQd9rDGFvNwzIMtyhc0kWFmoYijKlVK3b2PkUVYiFdVKgb7WEMrRrwRj3f2RdIFxVATIPJ1Ap73BhPVKmjAnhOCHd4noOZ1TXw/hWmq0RFyqgAviiEmtjQh5FVGzZpU3VOhUkbFT09K6BKqXp6GvB+EmtSpI4KdbqKmWmPfnBJtsKDiu0yUZI6KlSXSJq+xk548xJjQ4kjKtQdJtkh40ffqgWPSdaDiiEq5F32Uorebpwb7AhVh4dfoIqlAiJwwN4Km3/nWQ8qhqhQLfad1lateKZjbKgDDFGh2raLrK1w/3uSqsMDR1SouTPbbK0WwRsTvPsfR1TIsJiyHZ3VhC113v2PJSpkWByztcLzb3RuulRwRIXqwN9maYUPRF/gbKkzRYVqWXRYWmGLhPf8yxMVquegyc5qCbx6hqrDBE9UyMPqhN24WzmNJetFFVdUyMNqp50VjlDiPVUxRYVzWNlYzZgWMdNYpoIpKuQ9C5wQ1MIKlyHhvFO2ZctPMkWFvMWOE4KaW7XBS3XZqgBw3DdOCGpuhQ1Azju1fFGh+rnxMUBjq9nwylmqDhNcUSF7ruQyIcZWOGmC/Xj7ONiiouc6qJt8rMzUCr+qF6g6PPBFhbwKkbOsmVrhUcX7VbFFhdwBS/LBRkMrDEDer4ovKuQOeLespqEVnqt4A5AvKmRniJrmz8yqFZoVE1QdHn6OasQB7IDjNk/WYguQ9QqEMSrkKZgmWjOyapyMmx07DYxRIS+taHYcIyu8ruIZe0owRoWcFH6UKmpkNSLEFdbGOmNUyIsQZ1J4Eyvs12a9Bc0ZFdjFOO3M3mpihbH+93/Exx/+wPfz8ddQOXdVSQOrJoj1L8gZ6Zh4m5rWjocHoabukroGVjiR+Z9RhTj4NaoPC71fF+IkVdTI6oQQl0MzLqfie6lCLOCk8N7sRfpW2AT0zzaall+m+vDweSGmvKWp9K2wXSFnROTh3WupPixshMrtVPVE9K3OCfEy1YgD1qhY/Tmop2+tD20rPFkFpiZOB2tUrL4JKuefFVnbCueFfQ9ViQHWqFj9WajcbFlNhbYV7ICh2dnTwBsV66GW/bKWhK7VXPiBbwfkjQr5VQVWk9W1wgQMLXqQAt6owAUkBqSNg67VKGcC8kZF9KvStZoJ//8k1Sk9vFGxAeoWOKq0rbANyHYK5o2K1f8FdfMHIKBp1R+zmI0tzFGB6xKEZ/DXs2qYilnMxhbeqOj9MlwthpcQ07PC9TTDi9nYwhwVH4Gq+VqACj0rfAT996lWaeGNir5vCFGKrCOrZ3WcL9eZo+KjUMGl5OKhZdUA1/aRRcrsYI4KvAKJWc1dywrb60yHFXNU4MoYMSvva1nh0uM87XXmqMBbMHvIxI+W1T1sZyveqMC2eiluHn8tq3Eh/o2qlQ7eqOjFRQquIZEAOla4oiHLVQhzVOCpKtQAJHSscNx6ZEVDG3ijAve/yfgFCnSs8Bx8J1UsDbxRIfe/hCU8dawgLL5KFUsFb1Tg0kDx+5+e1RhPWPBGBZ5/S61kEUbDCgduMlwx8kZFH64600kSETSs8HEkhl4D/tuaahRCHBpW+DS6u0KUNbxRgY2K0eRVbTSscOKAyKrCxrBGBR5UU97U+RE0rEoc7SXWqLgBD6rIIiI+NKzg6j51FyNrVKzBM1Vco9ZFwwourp6hylnDGhV4pThcdlEdDSsgsPqkBaxRgUkxXn4pJz2rv6Da2fI9VCEO8E7ZdIWF+fSs7qLaWcIZFXintuIK7npW6U5XnFFxI8Zf5E5ZGD2r36P62cEYFX24iqI7WCQRPatUAxIYo2IdZvpQ5TXFtKxepfrZwRcVa7GjYFRjwUEtq1R3OPmiohebtBUyXaFl5VvU1Ri+qOjF3rdSmdafh5ZVmgYTW1RIqcmEpQxDaFmluBJmiwopNaW5LK6WVYpmIFdUrMFjakp3+fYqW3FFxVojKT0r66Fm715DtUqJPE/pS1XZiikqbsCuj8mYvo8ktKxs7zD9OtUqJetxAe1SqJu+LFW14omKjbja9Fho9czyVNOKJyo2Yw1Gku5nxlPF44olKnofxgoci/Rnl0fLyi7ZOaJiHZ57xV7TdYy1rP6b6mkER1Ssx/ATW6mu+mhZWbXZGaLiFsyJqcS76cloWdlcNaaPit5H8E+PJa85noyelfl4x/RRcSO2J8SA1aL0elbmgy1SR8Um3PvEdtOcUOhZGYdg2qhY9zH8syW5pKQFGlaTFh2oKaPiHdhGEsfNTr0+NKywp8fwhmC6qFgrY8Ii0F00rLCv0azNlC4q1Bd1Uu9aPh4Nq6FR2AWNsj1NVPTJI0rsTu5I1EDHqhv+Y9IxnCIqejfL6BvTv0CMRceqZdrs5pl9VGyQ5yixK9UXBehYFXB1Qv1uEeuouAG72+A4TnNEKbSs8DE57UdfbKNiHQ52gWZfl92JN4CWlXym9i+p1pWwi4reg9iFI8Q+63OUHz0rnILpst4ALauo6N0k01wMG9xxKYeeVWEr/F/vKssiKhynsdgRjDZoWjXgbL/vo4qX45eopvqsPaicSl2V+6V00bQqzIZ9UGPoo3FU9D2ojqfJbYa3Jsqia1XAU/HlitdZhlFx0yH1Jya3WV1GJaJtJReieLlCB7FRVKy5BbsOgdJyzu8J0bdqxHGCL5cf1m4QFesfVrueOLmU73hy0LcqtOCQuq+WuybRjoq+g6ppBNdQnQwn3QgGVoVW1Lqc3M7VjIq+Tdhtg0zttrnVooGJFa1aeDTpqkQnKm7Y7CiJ4SVpG7GJGFkVmuTE5y/FP+FYMSp6Nzzo7HhifGeVviaJmVWhiA+uC/FMXBaWj4q3b/6svHRCJvfMr8bR5GFoVSh0yvUfXv1kxCs5KtZt/LBnJEp7OqqrBBhbFVrwxAVezwRbGvFR0bfx4CF5r5wY2TGv6kqAuVWh0EFLQPzf0bt+h5wiUbFu/c0HH/lP7xsCSvsX64xr4cDGqlBcjBkvefFT77vrve+5884/7uv77hvX37Tx5k0ffujQ5/xfj+TcvqVag1osaGxpiWSplRV4dUaWgUiiNLC9k+VSMExje/feIbxZCf9oe91JiySWVsDMrSeoQBKTQ3u6O6oiVCjMWi6XMfY44b/bYW8FtC7aPYxXKEGmxoYO7OpeOIe3Ge6naWnMP+i0b9hqKivJjHmdS5Z1dS1buuSazvlz21qr1mBwaNmJqwNJrkycfvqJv/3AA2qFRk8rvVWNadpBe8fFU4flvOM/hFO3rZLrabo7Yd6sFuEs6kJcOuJM5HrbG+WMdHJORPd56HxZteDEtEJcGPQmnHy9klKrnzr9Xbmymi+/qIuHfZNo/vC1JCVXiHLmuciTFd46EeLpwGyTbyAn4Dm4EqCSObLajZU5H1zEREYFgRN+UwDnxqq4H+tyOjgtqBMVkvvgfTrn58ZqH1blCbJxcKMCyaGV3P3C6xJ4UYHghMt0Cy4nVl1YkcisyL6oAPC4ouL5sIpfa9UfFcCzOcvAZjxPhY+pYFQA0Bh0qpoLK7yncJpcPAJRAbwixF7aIA9WOBNFdAWnYFSotoXNjMsZ0YjXu9FVCYJRoeaRdgY05MAK+zmj01eHokItwOtc29W/VfMkXHhE9r9wVLiL2Ujq3wpnQolOCh+OCrmi4XLapP6tGkpw7RGZvz8cFeqq0R3JX/dWuC7z4I+GecO3hVgBue5NDVb3VseFeDUyD8Uv0h1ij01QUW8Wt3q3aoUKRMbH/uabycXjS0JMene36t0KJwSNDIj4ZlLxwIfzrWbHzgacEDTct/mrbyEXlzVfEWLKWfQAqHOrYtyEoN9FLh44OcQO2gSpcytcxDM8DUU0KnBusHH/mI06t1oKfz80ICcaFdG56ercCi/sQ4dVNCpwoHhwbrA6t4LqhQaRRqPiINSx5IsKoM6tTkYeLI9Exc1Yx2CnXL1bQXs9+PhhJCq+D6voXC061LdVEf584LGHSFTIbyoy4Vl9WzXCnw/MnRmOCjymxH4q7aFhNUxFMyBsFYqKXjlocn90BIeG1QgVzQDcA/3HVTAq1LOccfPthXrC0Sqs5dw6zIKRwLMcgahYg82kaFBI3OEgDlErUasRLTHgWdgdZxmIilvlyOrxUKQrmvCtADFWFo+2coHtQHd+Fy8q1mxSo2/uCZ58HebLN31cBauwlr81XGvwuH9GtZncqNhAQ3bHF1GhMDjvdYA4K1raMRNm4diKL8idUEbFjbc8QqOQp7YnjuwIH1ZX46xE0r9JLcDb0RAZRz/xDx956KPuUFAxuSN+50M6qIyLsgprZdlmKnS6I2E8yg/ZxSWQA8RbxU+sXStmBc+p08e6wktSBFlABV1AKNZqskojxzSZs0uOs5w6eezuZXMrjemXnV0BHKuIVtKEzbWjsVEzs2Rff4BEq8jqKnWL7BYPgD4JVnnRikr5rGK0BrI9trRoVuO3g6BOopWYzDQJdVBj7cOgDlnFaYmhRRm2MipR7Ixcf0ikTTkraDzt6MywBZ9M64LtarR0FGnjWCVoAaWR4aG6YngkcoryUDKVrXIFybhWrw0tcnltWZGKz+o1oEUiAav8a5FH0CrvWmQBBKxyrUUKkqBVjrVIQBGyyqsW1d4hbJVLL6q5R9Qqd15Uaz9xVrnyohoHibfKjRfVNkySVR60qKYxJFoBtHF9QnWMp5yVhD6knqCaJXL16v8D2eJ7MOwSqB8AAAAASUVORK5CYII='
-r2 = b'iVBORw0KGgoAAAANSUhEUgAAANQAAAE/CAMAAAAJ9B3fAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAA/1VV/1ZW/1dX/1hY/1lZ/1pa/1xc/11d/15e/19f/2Bg/2Fh/2Ji/2Rk/2Vl/2Zm/2ho/2lp/2pq/2xs/21t/25u/29v/3Bw/3Fx/3Jy/3Nz/3R0/3V1/3Z2/3h4/3l5/3p6/3x8/35+/4CA/4KC/4OD/4SE/4WF/4aG/4iI/4mJ/4qK/4uL/4yM/42N/46O/5CQ/5KS/5SU/5aW/5eX/5iY/5qa/5ub/5yc/56e/6Cg/6Ki/6Oj/6Sk/6am/6io/6mp/6qq/6ys/66u/7Cw/7Gx/7Ky/7S0/7a2/7e3/7i4/7m5/7q6/7y8/76+09PT1NTU1dXV1tbW19fX2NjY2tra3d3d3t7e39/f/8DA/8LC/8TE/8bG/8jI/8rK/8vL/8zM/83N/87O/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9fX/9jY/9nZ/9ra/9zc/93d/97e/9/f4ODg4+Pj5OTk5ubm5+fn6Ojo6enp6urq6+vr7Ozs7e3t7u7u7+/v/+Dg/+Hh/+Li/+Pj/+Tk/+bm/+jo/+rq/+vr/+zs/+7u/+/v8/Pz9PT09fX19vb29/f3//Dw//Hx//Ly//T0//X1//b2//f3+Pj4+fn5+vr6+/v7//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0cgG7QAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABLQSURBVHhe3Z15QxRHGocdBgcEQVwSNR6wKsR4xIsENBohaASNQI5NdhfwjjEuKxpybJJNNsEbybEehDURYegPOtvT/aP6qGOqqqtnun3+mZnq6qYeeqa7uo63lhVEvP9fyypY+JAMrCK/vItPbPhSvxRl/rPoHCRp/PF3u2w/OcVkwZH6pVD4CgdILAtcL6bUYuEL7Jhw8ihwCIbUYuFX7JMGPkSp/VBSPxd+Rva0gIL7oKQ+QtYUsYiiE4JSXxcWkDFdfI7yg4DUE/cukEJ+h4GLXyr/N2RJI3Bw8Et9i+3pBBJFfFLfY2tagYYNkXryL2xLLzDxpL7+C7akGbh4ZwrpqcauDTosSSE55XzryrhSP9vPTc8Fjs3SmUIagwdXL19KFlcmnqFsDBwbVwopYR6f3P2nTAJZ3nrgE87T6xdE6nOkBLnZVYODJJGXTj1FOYMQKXwOMN+Txe5J5YUxFDXAfyDFqvJNbsSuCabq8DxK6wdS+OTnWj12TDa7GFb2YwhbKiVObCtH6nd88LiXFqdM5jUU2Ycjhfceiy9jjzRwDoX2+IEpdQr5A2Q37Njz6rbV+JQcGh+i1B62FPUYNVuH/B5rj1+dczdOXzi4AokJ4ZBbMB+2FN55UCdqxyVscfntnRewIRHUzaJcBIbU4nrkBo1nscFj7nAVNiaBAZSK8D0tdQ15wS76O2szlqA64WaUyYOWOom8LvvzSA5xpxkZKk+OulfRUh3I68BzSpTVdRSJsOw9vCH4f1JbuU6WdSuHTBWH+lEtox47GpHVpuY20pj0IVfFOYoCEZZ9iDcE323oJJIcpkYHBi/gbuWQ34JslaYbBSIs+xJvCJ5Us+/L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'
-r3 = b'iVBORw0KGgoAAAANSUhEUgAAANQAAAE/CAMAAAAJ9B3fAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwNDQ0/1VV/1ZW/1dX/1hY/1lZ/1pa/1xc/11d/15e/2Bg/2Fh/2Ji/2Nj/2Rk/2Vl/2Zm/2ho/2lp/2pq/2tr/2xs/21t/25u/29v/3Bw/3Jy/3Nz/3R0/3Z2/3d3/3h4/3p6/3x8/319/35+/39/gICAgoKChISEhYWFiYmJioqKi4uLjIyMjo6Oj4+PkZGRlJSUlZWVlpaW/4CA/4GB/4KC/4SE/4WF/4aG/4eH/4iI/4qK/4uL/4yM/42N/46O/5CQ/5GR/5KS/5OT/5SU/5aW/5eX/5iY/5qa/5yc/56e/5+f/6Cg/6Ki/6Sk/6am/6en/6io/6qq/6ys/62t/66u/6+v/7Cw/7Gx/7Ky/7Oz/7S0/7a2/7i4/7m5/7q6/7y8/76+/8DA/8HB/8LC/8PD/8TE/8XF/8bG/8fH/8jI/8nJ/8rK/8zM/87O/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9jY/9ra/9vb/9zc/93d/97e4+Pj5OTk5eXl5ubm5+fn6Ojo6enp7Ozs7u7u7+/v/+Dg/+Li/+Pj/+Tk/+Xl/+bm/+fn/+jo/+np/+rq/+vr/+zs/+3t/+7u/+/v8PDw8/Pz9PT09vb29/f3//Dw//Hx//Ly//Pz//T0//X1//b2//f3+fn5+vr6//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA75ob3AAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABOtSURBVHhe3Z39QxTHHYdteweCUDSgUYMBJS9N39JXI7EYojEq+IJGQo0GCvgWNSI10RASmqavhhhjlNA2DVU0CZ7H/ovXvb3Pzc7uzM7O293t+vxyx8zs3T7s3u7O23dWFAT8pvDXZSeJ5D8q/BL7yCNS6vkCPiCxLBd+jH0NEyWFDRPOMvY2BFfqH9gmDXyMfabhSP0NxdMCdpuClULRNIE9J4SlvkK5dPEP7D0ISaFQ6lj+BQQ8glIokkZg4BGQQn46gUMRWgq5aQUWLpQU8tILPGgp5KQZmBCpnyE93UCmLJVHcrr5piQDqY+RmnZKNpBCGofF6SuXk8XVD+9j3zj8qGhTkoo4+ZZO7d6YSSDZTXsvPMQ+hvjKl0JKkNtHWvAhSaRtaAH7GYRI4e8Ay6ON2DyptFzArgZ4KJCa68amSWbXXewtDaQ4jSu31mO7ZNN5B/tL8V9P6uf4iyIlTnwrT+rP+MPn/hPYJvk8zV64PSm8pziALdLAceyzz7Ir9WO893kX5YM0v9Dbu7UZfySHlZ9gr314R2r5SZSnWH/i81LmZ2+sQ1JS2F7aMQpX6hu8JVxBaZ/V56gzN38mYffkz7BjhI9WsD+pXhQm7Ajdu+e3IyMZHMRuEZZZqcU6FC7zCnOByb2MrETQzOwfKxW+TLzEedrNJepYXcdeEVipYygKHuPc3twzMEm/qzPYKQIrFTq1LiI5xFlkJwHmR8VKPYuiJdqRGiafoAep3dgnwgqmxaULRUuMItXl87HxL/DW5QQKJIBe7BKBPVJbULTEPFKd3KtZt8q5j1Q4b6JAAngJu0SIkWpDouPsKiXsxZ+Ok5xLharUDiQ6s0jI3kSC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'
-r4 = b'iVBORw0KGgoAAAANSUhEUgAAANQAAAE/CAMAAAAJ9B3fAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwNDQ0PDw8Pz8/QUFBSUlJS0tLTU1NUlJSV1dXWlpaXFxcXV1dYGBgYWFhYmJiZGRkZmZmbGxsbW1tbm5u/1VV/1ZW/1dX/1hY/1pa/1tb/1xc/11d/15e/19f/2Bg/2Fh/2Ji/2Rk/2Vl/2Zm/2ho/2lp/2pq/2tr/2xs/21t/25u/3Bw/3Jy/3R0/3V1/3Z2/3h4/3l5/3p6/3t7/3x8/319/35+/39/urq6u7u7vr6+v7+//4CA/4KC/4SE/4WF/4aG/4eH/4iI/4mJ/4qK/4yM/42N/46O/4+P/5CQ/5GR/5KS/5SU/5aW/5eX/5iY/5mZ/5qa/5yc/56e/5+f/6Cg/6Ki/6Oj/6Sk/6am/6en/6io/6mp/6qq/6ys/66u/7Cw/7Gx/7Ky/7S0/7W1/7a2/7i4/7m5/7q6/7y8/729/76+wcHBwsLCw8PDxMTExcXFxsbGycnJysrKy8vLzc3Nzs7Oz8/P0dHR0tLS09PT1NTU1tbW19fX2NjY2tra29vb3t7e39/f/8DA/8LC/8TE/8bG/8jI/8rK/8vL/8zM/83N/87O/9DQ/9HR/9LS/9TU/9XV/9bW/9jY/9ra/9vb/9zc/93d/97e/9/f4ODg4eHh4uLi4+Pj5OTk5ubm6urq7Ozs7e3t7u7u/+Dg/+Li/+Pj/+Tk/+bm/+fn/+jo/+np/+rq/+vr/+zs/+3t/+7u/+/v8fHx8vLy8/Pz9fX19vb2//Dw//Hx//Ly//Pz//T0//X1//b2//f3+Pj4+fn5+vr6//j4//n5//r6/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASP4oJQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABDtSURBVHhe7Z39YxTFGcdTa99b+4oJgTRAIFERkqooUAtBSoiABBEsIUIJIK+GWvtisa1W25KAsWmAIFparW/QiIQ3a0F5qybhsn/U9Xb3ezO7O3N3z+zO7u2k+fxytzM7y3643N7uzDPPVGSL8eCbGSuNjL39DM5QSiGpb2afG8MRUsufca4CcqlJv0y9kctLOGE/Uqk30MQEPsQ5e5FI/RG7m8K7k3DiDFEKu5rEb3DqeQJSi97GfmbxX5w+CEil8wpOAOfv4pW6zcQ/vTzPQcLGK7UI9WbyJ1jk8Eg9jVpT+Qc8PFLfMPlvz4X9EvNPCjUmk78hZFIoNxu4QGrRf1BsNmOuDaSeRanpvOPYQAplEoZfP9qfLo68egXnJsGxcaX+jaIAmd61TZMrU8jsVV3DOMcAzh+gK4USP1e334ljpJHp7Wdwnn6ehdSDn6LAR+8sNE8rU3ZK71QhJfugrq9B0zSzcAhn6+UXrpTkG3X9AbRLNw2ncb4ect8qWwpbHgxxklvZUt8Sb87HlqBN+rnzGs6Z8679Sd3EBmcPWpjAGpyzB1sKbzmna9AgwP0rwb0oSAW9OGuOVGoFdg9Qy37Il6IkFcwWLuy/r8j+AW8Z5wrcRDyBeus1FKSEV3BajEyF2NeyCTsHqPkY9VYLSlLCEpwWp+LreMNpwM4B2lFtnUBBariAE2NUCF+p89g1wJSLqLceRklqEC4VotTL2DXAT1BtnUJBetiMM2OIUpuxq58p51FtrUJJehC+VKLUOuzqZz1qrcEqlKSHe3BqDFGqDbv6qD6LWnl1eZmLU2MQpdai0jqdwifhkFKT2VPmoyhJEyGl2lBnnalGSZoIJ1X1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'
-r5 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwPDw8Pz8/QUFB/1VV/1ZW/1dX/1hY/1lZ/1pa/1tb/1xc/11d/15e/19f/2Bg/2Ji/2Nj/2Rk/2Vl/2Zm/2dn/2ho/2lp/2pq/2tr/2xs/25u/3Bw/3Fx/3Jy/3R0/3V1/3Z2/3d3/3h4/3l5/3p6/3t7/3x8/319/35+k5OTlJSUlpaWmZmZnJycnp6en5+foKCgoqKipKSkpqamrKysr6+vsbGxs7OztLS0tbW1tra2ubm5urq6vb29v7+//4CA/4GB/4KC/4OD/4SE/4aG/4iI/4qK/4uL/4yM/42N/46O/4+P/5CQ/5GR/5KS/5OT/5SU/5WV/5aW/5eX/5iY/5qa/5ub/5yc/52d/56e/5+f/6Cg/6Ki/6Oj/6Sk/6Wl/6am/6en/6io/6mp/6qq/6ur/6ys/62t/66u/6+v/7Cw/7Gx/7Ky/7Oz/7S0/7W1/7a2/7e3/7i4/7q6/7y8/729/76+wcHBw8PDxMTEx8fHycnJysrKzMzMzc3Nzs7Oz8/P09PT1NTU1dXV1tbW2dnZ2tra29vb3d3d3t7e39/f/8DA/8HB/8LC/8PD/8TE/8XF/8bG/8fH/8jI/8nJ/8rK/8vL/8zM/87O/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9fX/9jY/9nZ/9ra/9vb/9zc/93d/97e/9/f4ODg4eHh4uLi4+Pj5OTk5eXl5ubm5+fn6Ojo6enp7Ozs7e3t7+/v/+Dg/+Hh/+Li/+Pj/+Tk/+Xl/+bm/+fn/+jo/+np/+rq/+vr/+zs/+7u/+/v8PDw8vLy8/Pz9PT09fX19vb29/f3//Dw//Hx//Ly//Pz//T0//X1//b2//f3+Pj4+fn5+vr6+/v7//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+TpPMwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABPrSURBVHhe7Z35n9bEHcftld2VZZeVQ0SWywPQ3vdtixUXqaJSClK5u4iwImXtutvb3pcgRURcFxTkUNrS1l4CUhTQ2kvAhday7D7kH3ma4/N8kzxzZDJJniSv8v6BJ5n5ZjJvsrkmk8klZRmf+Nl/zVzy52+/H1XkIrb6ek6FPP7wPlSVQWD1qSEsmXN+h/pWwbX6PpYpAv9+Dyrth7X6yLcQXxT+iYr7YKzeVUJwgXgYdSeqrD77UwQWixKqXyFo9a5/I6xwfBMGLkGrC4gpIAeg4OC3+gACismfYWHjs/ogsovKa/CwIKsPlJFZXP4EFc/qg8WXMs2fQ4aszDeRU2g+AxtYmQeQXnBcG1i9+WGkFp03HR3X6oApPlENHtzZly927H4FdePwEFl92BRcJ114+ktThxk55PJZ606hjtWQ1QX+8W/gwckoJI8Mm/cC6hnk97D6qfk8UgLsnYDl80rdkgFUNQCsMBdkqL0eC+eYCc+itn6ed6yeN3+IeR9Dt2PBfNO0C/X141hhOkBBpPhaX7Osfmi+G3M+7sZC+afpKKrsYd1CXmL9IWLOYzsWKQLT2RYJx4qh/wonfvJtYbhxGbMWtfb4tGXF7ljtovBq7nADs6XxNGpD/MOy+iimifOj3PCCWHHqaVn9CpPEI8LoavJhNY7Zsywr5sL2JkQXxcp4CtUhOEeL0ggEF8aqA9UhPs5aHUFscaxmozrEd1mrTYgtjtUVqA7xS9ZqPWKLYzUc1SF+w1p1INaz6usUcA0iM6YO9SQ424q1mouE3IJ6Er9lr9kvWuUE1JO4aJVfUE/iolV+QT2J/2OrrfeA9mV3TqhDbp5APQklqwBntt9x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'
-r6 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwPT09Pz8//1VV/1ZW/1dX/1hY/1lZ/1pa/1tb/1xc/11d/15e/19f/2Bg/2Ji/2Nj/2Rk/2Vl/2Zm/2ho/2lp/2pq/2xs/25u/29v/3Bw/3Fx/3Jy/3Nz/3R0/3Z2/3d3/3h4/3l5/3p6/3t7/3x8/319/35+/39/kpKSlJSUlZWVl5eXmpqanJycnZ2dn5+foKCgoqKio6OjpaWlpqamq6urrKysra2tsLCws7OztbW1t7e3uLi4ubm5urq6v7+//4CA/4GB/4KC/4SE/4WF/4aG/4eH/4iI/4mJ/4qK/4uL/4yM/42N/46O/5CQ/5GR/5KS/5SU/5WV/5aW/5eX/5iY/5mZ/5qa/5ub/5yc/52d/56e/5+f/6Cg/6Ki/6Oj/6Sk/6Wl/6am/6en/6io/6mp/6qq/6ur/6ys/66u/6+v/7Cw/7Gx/7Ky/7S0/7W1/7a2/7e3/7i4/7m5/7q6/7u7/7y8/76+wMDAwcHBxMTExsbGx8fHyMjIycnJz8/P0dHR09PT1NTU1dXV1tbW19fX2dnZ2tra29vb3Nzc3d3d/8DA/8HB/8LC/8PD/8TE/8bG/8fH/8jI/8nJ/8rK/8vL/8zM/83N/87O/8/P/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9fX/9jY/9nZ/9ra/9vb/9zc/93d/97e/9/f4ODg4uLi4+Pj5OTk5ubm5+fn6Ojo6+vr7Ozs7e3t7u7u/+Dg/+Hh/+Li/+Tk/+Xl/+bm/+fn/+jo/+np/+rq/+vr/+zs/+7u/+/v8PDw8fHx8vLy8/Pz9PT09fX19vb29/f3//Dw//Hx//Ly//Pz//T0//X1//b2//f3+Pj4+fn5+vr6+/v7//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6r+4xAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABV+SURBVHhe3Z35YxbHfYfpsa9eBAhhECABsjC2MaRO3LS1G6dN0nIYsMCACSaAwQILDOJQOAzI6Zkmbdo6AgFCxpj7MiaOU7dukA2YK04b21yWnVhIr/YvebvH592d3ZnZnZnd9313+/xg7zs772of3j3m/M6gfBBP/svneiL53x8+gVNkwrf61ic4QmL56M9xqhQcq8cTr2Tzq0dxwl6YVj/Ad9JA7kmcNAlt9Y2/GMAXUkL/YzhzF9oqJdceyXs4dQef1V//LTKmjG/g/IHX6o/eQ67U8SoMbLxWv0OeFPJrKFh4rFL2mPDyW0iYkFbYnVZ+Bw0Dx+pP0v1LmXwBFdfqT9N8TxX4CDKOlf7f2JNqfgIbWOn/gPSU87itY1v9Nu1PCgdLx7b6uf4FEmly7588cjhRHD31If/B9q5j9YT+HaT5ubB66jAtgYx4av1VnKIfx2qAff3l9k3DQZJIZu4xnKcX6/FuWP2b/vdI8XB5Cr6fWBbcwql6+LpthU8+dg7FdxPMqIM4WRKz5DQo/x/6k/hMsg5fTDaZ3ThdEsvKsMNHgnRIsbV+YVj9WGdcgi/jS8kncwSnTGBY6for+OByKQX3VIExd3HSLl81rahibW4yvuGhakrjM7OmjMSn5LAYZ+3ytmFFX4B7kN8lM6f9g5y1L3d23SQkJoW3rBMjYVo9jOwFhjZdxh6b60uwIxnQP5Zh9W1sOpxD7gJTP8QOlxPjsS8JVFIvY8PqbWw6rEBum+wW+9Lzcm9dBvsTwMs4KYfvDNKpk34QmS2y+5HqZwcyJIDv4pQc/t14BvroG4zMJlwpXV+PLOWnHmfk8DFt5bmttiGRxTLkKTuZHpyR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'
-r7 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwPT09Pz8//1VV/1ZW/1dX/1hY/1pa/1tb/1xc/11d/15e/19f/2Bg/2Fh/2Ji/2Nj/2Rk/2Vl/2Zm/2dn/2ho/2lp/2pq/2xs/21t/25u/29v/3Bw/3Fx/3Jy/3Nz/3R0/3Z2/3h4/3p6/3t7/3x8/319/35+/39/k5OTlJSUlZWVl5eXmJiYmpqanJycn5+foKCgoqKio6OjpaWlpqamq6urrKysra2tsLCws7OztbW1t7e3uLi4ubm5urq6v7+//4CA/4GB/4KC/4SE/4WF/4aG/4eH/4iI/4qK/4uL/4yM/46O/4+P/5CQ/5GR/5KS/5SU/5aW/5eX/5iY/5qa/5yc/52d/56e/5+f/6Cg/6Gh/6Ki/6Oj/6Sk/6Wl/6am/6io/6mp/6qq/6ur/6ys/62t/66u/7Gx/7Ky/7Oz/7S0/7W1/7a2/7e3/7i4/7m5/7q6/7u7/7y8/729/76+/7+/wMDAwcHBxMTExsbGx8fHycnJz8/P0dHR09PT1NTU1dXV19fX2dnZ2tra29vb3Nzc3d3d3t7e/8DA/8HB/8LC/8PD/8TE/8XF/8bG/8fH/8jI/8nJ/8rK/8vL/8zM/83N/87O/8/P/9DQ/9HR/9LS/9PT/9TU/9XV/9bW/9fX/9jY/9nZ/9ra/9zc/93d/97e/9/f4ODg4uLi4+Pj5OTk5ubm5+fn6Ojo6+vr7Ozs7e3t7u7u7+/v/+Dg/+Hh/+Li/+Pj/+Tk/+Xl/+bm/+fn/+jo/+np/+rq/+vr/+zs/+7u8PDw8fHx8vLy8/Pz9PT09fX19vb29/f3//Dw//Ly//Pz//T0//X1//b2//f3+Pj4+fn5+vr6+/v7//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA46UD8AAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAA93SURBVHhe1Z35YxTlHcbTY0NCFBpbClgExFCO1lZ6SIutRxWJKIqAQhURzxpEsIh4tLb2sK01giJQpAERRcSrVlsNKEeg2iqCIXhA2My/Mt2ZefadnX3neI/vHO/nB3aO9528H3b32dmd932nwY5j6sP/swrJsT9OQxNDibb60Xs4QmE5dD6ayhFhdfZ/ULPgHDoXDQ4SajWtjEom8CAaXQtv9eMpJ1HeEAZ+gpb78FZvorBBHELTGXVWP5uGgobxa7QfBK2+/ShKGccbMPAIWr2PMgbyGRRcAlafooSRDEDCodbqM+w3FWhUYFbftz/BTmPxn62q1Q/swp8gJcPeW1Ur6xHsMZp/wQZW1rnYbji/8XQ8q09tbDUeV8ezesV6HRt5BvY9t6WrUGzetjv67PsYs5pqRT1V+2+f0VoqIKdMXvw2mljPhVWrgYhQf+aKRhyliFz8VPgzBqs/W9/DhgCHr0L1wjJ5H5oa4CHPyrLCzpQ2fg11C0zLSjQ2gGv1j9B31eNFfvH53Ibm1jLNsbKs17BagyFSoVqfVqz+EPZUbTZFqlRagSbXULGyrO9ixad3OKoYQMseNNrnAcfqZaz4zHPLt16VzBluyVyZyAX8ZxUr/gX4old8AlbjuNErmitr0BafUCvvqTLGim9nmNXh5qjSPEWwKu1AYxgXNFgXYpGxAoWNsboOjWG83GD9BYuMuShsjNV4NIZRbrA+xCJjDAobY9Xcj9YwKsleR1/1E9gYK/6NxVv1oKhBVn9Haxi81Tso6lvtXV4P+89ZgLL5sh6tYYhYrccGn27s6R+GDfmyDs1hOOfsQQSs2J512JAzNFaPYYfVjg05Q2I19Dh2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'
-r8 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwPT09Pz8//1VV/1ZW/1dX/1hY/1lZ/1pa/1tb/1xc/11d/15e/2Bg/2Fh/2Ji/2Nj/2Rk/2Vl/2Zm/2dn/2ho/2lp/2pq/2tr/2xs/21t/25u/3Bw/3Fx/3Jy/3Nz/3R0/3V1/3Z2/3h4/3p6/3t7/3x8/319/35+/39/k5OTlJSUlpaWmZmZm5ubnJycnp6en5+foKCgoqKipKSkpqamq6urrKysr6+vsrKys7OztLS0tbW1tra2urq6u7u7vb29v7+//4CA/4KC/4SE/4WF/4aG/4iI/4qK/4uL/4yM/42N/46O/4+P/5CQ/5GR/5KS/5SU/5WV/5aW/5eX/5iY/5qa/5yc/52d/56e/5+f/6Cg/6Gh/6Ki/6Oj/6Sk/6Wl/6am/6en/6io/6mp/6qq/6ys/62t/66u/6+v/7Cw/7Gx/7Ky/7Oz/7S0/7W1/7a2/7e3/7i4/7m5/7q6/7u7/7y8/729/76+wcHBw8PDxMTEyMjIycnJysrKzMzMzc3Nzs7Oz8/P09PT1NTU1dXV1tbW2dnZ2tra29vb3d3d3t7e39/f/8DA/8HB/8LC/8PD/8TE/8bG/8fH/8jI/8rK/8zM/83N/87O/8/P/9DQ/9HR/9LS/9PT/9TU/9bW/9fX/9jY/9nZ/9ra/9vb/9zc/93d/97e/9/f4ODg4eHh4uLi4+Pj5OTk5ubm5+fn6Ojo6enp7Ozs7e3t7u7u7+/v/+Dg/+Hh/+Li/+Tk/+bm/+fn/+jo/+np/+rq/+vr/+zs/+3t/+7u/+/v8PDw8vLy8/Pz9PT09fX19vb29/f3//Dw//Hx//Ly//Pz//T0//X1//b2//f3+Pj4+fn5+vr6+/v7//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXn6cBAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABYNSURBVHhe1Z35YxTnfYfVYxdJyAghQMiYw0KSFTvpmTg90tZtJTCYOBibIB8EsCorHAoGQznSNG2aJo3jxLLAXEYGc1t13bqpU4SMxaUmbW0QshobHav5T6ZzfPadd+Z9Z+Z935ndnXl+2d33fWc1j2Z39j2/b5kexO//3X9qieSzV/4Ep8jF3+r3foZ3SCyf/Q1OlcHP6t9wZMKZ+jOcrxuu1W//Hw5KA/+Ik6Zhrf5Q/1+UTwvfxZk7sFY/RdkUkfsCzj2Px+ov9WmUTBcv4/yB2+oLf4tSqeMjGNi4rf4VZVLINBQsXFYJ/ckV5IuwMKCtfoHstPIleFBWX9TfR2Z6gYpj9SX9J8hKM5AhVtpfICPVfAobWGk60lPOu7aObfWp/imS086XLR/L6l3te0jkcPPsyb5k8dbAJM6Nxf7ZMq2+7Pv5u71j1fxMAqlsfuYtn6rdj/NW0/q/I8nNpXWVeJck0rBvHOfpBlY/5l+q8Y1ZHJ9UFp/Hqbp4z7YyniCB5uJiHJtgZnRO4WxpLKv3uJfqdBWOTDZPcLR+aFpp2rfxkiIlUnwtw+qHmp7DK4cP7sFByedZnDLFb+llhhpeOORacEgaOImTdnjPtHoELxy6cYCbuhVffaw5eff6BaM4awfDSv8fPCeMzMQBFM09w1be5NvfqEZSUnjBOjEa0wpPHdhLtfQsskzGvlmO5GRQy9Sf/ohjlatHccLmCWSB/iXISAa9OC3COxyrkyhM2IEMh1v3IysRLMdZEabLtK/gKWEbCufZgnSaWwuRmQSqmYpumfYPeEZYjcLgQfbnzOB0kiqJH+CkCGXaO3hGWICyNhUfItnDBuQnAeaLVaYx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'
-r9 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAALi4uMDAwPz8//1VV/1ZW/1dX/1hY/1lZ/1pa/1tb/1xc/11d/15e/2Bg/2Fh/2Ji/2Rk/2Vl/2Zm/2ho/2lp/2pq/2tr/2xs/21t/25u/29v/3Bw/3Fx/3Jy/3Nz/3R0/3V1/3Z2/3h4/3p6/3x8/319/35+/39/kpKSlJSUlZWVl5eXmJiYmZmZnJycnZ2dnp6eoKCgoqKipKSkpqamqKioqampqqqqrKysra2trq6usrKytLS0tbW1tra2uLi4ubm5urq6u7u7vr6+v7+//4CA/4KC/4OD/4SE/4WF/4aG/4iI/4qK/4yM/42N/46O/4+P/5CQ/5GR/5KS/5SU/5WV/5aW/5eX/5iY/5mZ/5qa/5yc/56e/6Cg/6Ki/6Oj/6Sk/6am/6en/6io/6mp/6qq/6ur/6ys/66u/7Cw/7Gx/7Ky/7Oz/7S0/7a2/7i4/7m5/7q6/7u7/7y8/729/76+/7+/wcHBwsLCw8PDxMTExsbGyMjIysrKy8vLzc3Nzs7Oz8/P0NDQ0dHR0tLS09PT1NTU1dXV1tbW19fX2dnZ2tra29vb3d3d3t7e39/f/8DA/8LC/8TE/8bG/8jI/8nJ/8rK/8vL/8zM/83N/87O/9DQ/9HR/9LS/9TU/9XV/9bW/9jY/9ra/9vb/9zc/93d/97e/9/f4eHh4uLi4+Pj5OTk5+fn6Ojo6urq7Ozs7e3t7u7u/+Dg/+Li/+Tk/+bm/+fn/+jo/+np/+rq/+vr/+zs/+3t/+7u/+/v8fHx8vLy8/Pz9fX19vb2//Dw//Hx//Ly//Pz//T0//X1//b2//f3+Pj4+fn5+vr6+/v7//j4//n5//r6//v7/vz8/v39/v7+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI8jCgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAABVhSURBVHhe3Z39YxTHfYfV9g4hhGSwZMybsSwJk7Zum7R22/QlTdNaMkaigDHYCCTABgvzHgQ0tZu3NmlaN22RMAgkMCK8JWnqJiBj8WK5bRAKqE4R0mn/m+2+fG52dmdmd2Z272V5frm92dnTPrrb3Xn9ToUZxnPvfDhjlCO5H/8FTpFLiNW/4RPKlplv40wZRFb/jCPLnJl3cb5++Faf4qA08COcMw1r9UXzp8ifFr6PM/dgrb6JvGnij3HueQJWL5r/i4zp4kOcP/Bb/cYfIVfqyMHAxW/1d8iTRr4IBxuf1b8iQzp5ERYWtNUPsTutfA0elNXvpuXBG8KX4EKsfs98B7vSzG/CJm9lPIcdqWYGNrAyzPIsm6vyP66Oa/VL8z+RnHa+4fg4Vj82fh+JHMZ/8MGZ8uLcpQc4Nw7E6gXh72/i8LqFmTJkVsPr/TmcY4D/ylvNmN9Akp+Rrlp8SjmyYPcvcJ5+nnOtvm+YSPCR21uF48uVx0/hVH185loZxrtIoLmxAseWMxvv42xpHKufcL+q6/U4sLxZztH61LYyjN/CW4qUSPG1LKvvGebP8M7j3gIcVP6sZG/ff2lWWGp4Q7EBh6SBgzhnj2m+VT8O8JFdumr16pefxLvyofo6ztrDsjK/i21Cjn3y1u88d8/deXew6zEklglr3BOj+LxlxTykma9q+fvT2OUweWQZdpQFs27jvAj/ZFlh02MlsoO5h5DuMfVWJXaWA2/irAg5jtUnyAyWjyDdx+Wl2F0G1OOcPDhWJ5HZpVVQPr5TRr/CT3BOhArjBWwR3kBeB5FUWWn145QIFcaXsUWgL6vFE0jkcLtsSvTMhVVhMK0wjchr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'
-y0 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABUVFRYWFhgYGBkZGR0dHR4eHiIiIiUlJSYmJigoKCsrKywsLC4uLjAwMDExMTIyMjMzMzQ0NDk5OTw8PD09PT8/P0BAQEpKSktLS0xMTE5OTk9PT1BQUFJSUlNTU1ZWVllZWVtbW11dXWBgYGFhYWJiYmRkZGhoaGpqam1tbW5ubnBwcHFxcXJycnNzc3V1dXZ2dnl5eXp6en19fX5+fv+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoCAgIKCgoODg4SEhIWFhYeHh4iIiIuLi4yMjI+Pj5CQkJKSkpOTk5WVlZaWlpiYmJqampycnKCgoKKioqSkpKampqioqKqqqqysrK6urq+vr7CwsLa2trm5ubq6ur+/v//UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsDAwMLCwsTExMbGxsjIyMrKyszMzM7Ozs/Pz9DQ0NHR0dLS0tTU1NbW1tjY2NnZ2dvb293d3f/qwP/qwv/rxP/rx//sxv/syP/syv/tzP/uzP/uzv/u0P/v0v/w0v/w1P/x1v/y2P/y2v/z3P/03uHh4eLi4uTk5Ofn5+jo6Orq6uvr6+zs7O7u7v/04P/14v/25P/25v/36P/46v/47P/57vDw8PLy8vPz8/T09Pb29vf39//68P/68v/79P/89vj4+Pr6+v/8+P/9+vz8/P39/f/+/P7+/v///wAAAHrYiUMAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAATyUlEQVR4Xu2df5wUZ33Ht9ra2lh/tNa21ljbmBil0Vp1j+M4OCCQu3CQAwnhVwg/EjgCgUDANqaNqVVr1bRqld+EI/y4C+EgEEitabVaf8AVKFACAY0xNhwcKDX3I9yS3Vnnx2efeWaeZ2ae55nZmZ3Xa99/hNnneXZ33rnd2Wee5/t8n0zRm7e/+8F//s+XXtMqjqs//dY//dW73oHT5OBl9d4/e/i/CniRCqXwnYfei7N1w7e65i9/iKdWON/70Ftwyg54Vm/99C/xpBRw+eHfw2lTsFav/2SKnAwuf/QNOHWC2+qmP/wRGqeIH9yEsy/hsvr65yr8EsHntU/9OgQsnFa/+x00Sx3P/j4UTGir6679GdqkkJ9cBwsDymrIO1N2mXByeQg8dGyrv/3jV1GfUn5paxGrz1/7CmpTy2XyISxZ/ePb/g91KebF0iUDVo8M+R5qUs1/4AJvWX1A+wLKU85nTB1YXXkPStNOweplmFY//rWfopTDYM+5CqMnh1Pj8GOzT2hYfVH7DMrc9O64t2VotuKonbSkox+n6OahklXhTVdQ5OT0kuF4mQpkxLIzOE0nrxg3JrrVD7QvocRB/xI8v1KpWT6IU3XwWdNqiPZbV1FA09WIJ1cw44/hZGlefath9RPtETym2VWBXyeW2n04XZpPGFban3N6FemQ4mu9cEMx813tT/CIYn9KpHStIzhliuuLGY1zrei9Gc9JAU3sJf6zutWN7AdwAZ7hpKFpQlMDjiuIpThpmxd0qzfj2KYL7SnGreg8Z9Z1737gFpRVCifNE6P5g4x2Ew5t5qI5YfqePKoM8k/NQHllsAjnZXND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'
-y1 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABUVFRYWFhgYGBkZGR0dHR4eHiUlJSYmJigoKCsrKywsLC4uLjAwMDExMTIyMjMzMzQ0NDk5OTw8PD09PT8/P0pKSktLS0xMTE5OTlBQUFFRUVNTU1RUVFZWVlhYWFtbW1xcXF1dXV5eXmBgYGFhYWJiYmRkZGhoaGlpaWpqam1tbW5ubm9vb3BwcHFxcXNzc3V1dXp6enx8fH19fX9/f/+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wE/+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3Kf+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/DS//DTf/ETv/EUP/FU//GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/Uf4CAgIGBgYKCgoSEhIeHh4iIiImJiYuLi4yMjJGRkZKSkpSUlJWVlZiYmJqampycnKCgoKKioqWlpaampqioqKmpqaqqqqysrLCwsLKysrm5ubq6ur29vb6+vr+/v//UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/dmf/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsHBwcLCwsTExMbGxsnJycrKysvLy8zMzM7Ozs/Pz9DQ0NHR0dLS0tTU1NXV1dnZ2dra2tvb29zc3N3d3d7e3v/qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uHh4eLi4uTk5OXl5ebm5ujo6Onp6erq6uzs7O3t7e7u7u/v7//04P/14v/25P/25v/36P/46v/47P/57vLy8vT09Pb29v/68P/68v/79P/89vj4+Pr6+vv7+//8+P/9+vz8/P39/f/+/P7+/v///wAAAAvkMikAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAOwklEQVR4Xu3deZwT5R3H8VRbe1hrLw+0WouKWrS2FrMHLHLIscqxIqJsC4qC3LgqWM9aa7WltbbaCgIKVASRywXU3traVi2Iq4Cg1Wq1FhfZ9YAFFskmneObZ45nknlm5vdkZvKazz87mUyenfcLkp0kc6RyhfvS4d1++qc39mYj1/63n/rFjV89DKvpUCHVCced+cf9GCSqPXvLCVhbe86qz5z8Zzwy4r123eewypacVIde8188KAbtuf2LWG1TvOrAU9/CA2LSnlsOwqqz7KrTD38SC8eoN4/D2uezqX7dbQ+WjFc//zgAelbVF+7CUrHrn18GQcus6nz001gmhr3fCQo1k+q0I9/EErFs74lwKBmqmzq9jftj2v6TIDGpbj8q1v9Sah8dAwtT/fjzMX5O5fsg/5IB1c2nxfbVz9zreIHXVV2z3TA/5t2tcaDac2w8//jyna55NNWrHyuymZRpaX4nWu1ox6o59L62TaiqZmZPxTx77cunDe+ejlwVgyc8sAOraO/OvKrjYOet9ObpvTFMBKu+/EWsprUO9Y2Jono6eybmWMrMqcIAUe2yVqyqpcc11anZTzq9SdwyDI+NcH0ewcpaOlRVvZ49GTfNNdXgkdFuIVbX3B2qKvsNh88oYoJyZO3ukkv9LfuVDtw02hIXVDq9FKtsqmsulXV4rcjE4DmVr+YdrLTRY4rqlD/ghtEcPAL1HIL6YUakGsn9V9urqA75CDdY260v6X22YH52GeZEq+VYO6NOqezpmDSagcX1DFREVcOxdkY3pbLfxiSrvQ8W1zKhIqpKb8TqsX6Vys7EJGsFFtYyo6KqmozVY/0n1YV7sWjAwmoWVFRVQ7F6rI5Ut9cxyboACytZUVFVVbZh/VipA+zvFzM9sDCHiqoq/TzWj5U6BROsVizKoyKr4l7blW0LW9uxaLrGjoqs6iGsHyt1IiZYzVg0PQgzjKKqWoL1Y6U+jQkWr9qGn2WlaqzHRDmpGqtG6BPlpGqsSpefSkGVn0pFlZ1KQ5WbSkeVmQqo8lLVAFVeKlaiCqVExUpUoZSoWIkqlBIVK1GFUqJiJapQSlSsRBVKiYqVqEIpUbESVSglKlbpVb0G14+/cvo9s+fMu3/BffdOnzysGnc4F2lVz3MvGnfV/OUbtvF7du/buGhSXSWW44qqqs+oWY2F9uVm7ZhTYFe+CKrOqp++shm/wK3MigvxKEvRUlWPuHLZKxhbtM0TK/Boowipel2+chfG9daGWozAiopqwBXrMxjUe7umYZR8kVDVzd6EAf22bgCG0gtdVTlyAb9Ts/d2jsV4Wr5UvS5B52GG7/rNcX35FiwzAUOq+VJRdeFK/88lLjMrPFWPyS/hFxBlYoWlqp3/IYany2CFoxq1hvC/nlHmEowfgqpyitfNB+FacCxf6VWXvoxxZbRS/x2lVo1owqiSGqf9ltKqBjViTGm19lV/TylVZy+W8hphrVH9TaVT9ZzLHREgpXrld5VKVdXQguFk94jy20qkOn8rBpNfRtl8L4mqal4JnlCs+0qjqiPe4HOptXsJVJWz92GgUjVRvmpI0Le53muSraqcUep/KKV91XJV576AMUrbMKmqK4ucI0RmUySquq/AACVviTxVP+6o3ZL1kjTV8Hfx8BDKcOdNIFKND+kppce94SFRVdyPx4bUGvxkUahqVuOhYfUofrIIVLXcEbilbh1+soKrRjqeP8jcgt72LsA9RK3HT1Zg1UTXbaQFWNLUObiLKPJ/K+4sDFwOKGoV9fPKHyriKp8oatVa/GQFUvlFUatI/175RlGruL+XAVT+UdQqwi2mAChqFX/WDr+qIChqFX/WDp+qQChiVQvV+6vLsHDhiqGIVZuIVHWu3wwURRGrVtOo+rruI1YcRax6kERV7foFoguKWDWbROVwekVrbihi1WQK1dVYsGCuKGLVaALVKLevcdxRxKrzgqsG7cRyBRuIJYtEqzo7sKqX+y4hpVZlKoKqKrk303ylVr0b+Jue32ChYnEqfn9tUtULQVWjsUzR7Kr+r2DCiFS1JKDqLKEP022q/tsymDIiVU0NqFqGRYpnVfXflpWsOj+YagyWcMmiUlCSVfuqA6l6C+7uYlapKMmqjcH2t1iJBdwyqTSUZNWiQKpxuN81Q6WjJKsmBVH1df2SIB9TASVZVRdEJb4DY16VR8lVtVcGUE3AvQJBxVByVU3KcH5V/Vy31I10lYGSq1qoDOdXJfr6p6apTCi5qvHKcD5V/Indi6SqzCi5qsHKcD5VG3CfUIrKgpKq2qUeD+hPdTHuEmugDSVVtUodzpeqwtuX9ANtKKkq9WnlTzUJ9wg20oaSqcr0Uofzo+rucRcl7pgkiar12nB+VDNwh+8kqq7QhvOh6u3hD7BzElX6sag+VE4XY/KWPNVmfTjvqtrg+wfLU83Wh/Ou4q+C4zl5KuVdiJpn1WDMDZI01TsYzrPqAcwNkjRV/nsKr6qe/k5rYE2a6iIM51XVgJmBkqVqzZ9yxauK5ABSWapFGM2r6ruYFyxZqiEYzauKZjdhSarnMJhXVS3NMW+SVJdiMK8qot3U5ai2G6dn8qTqQXSeAzmqezCWkieV+x5YYklRma/p50m1GXOCJkW1FEOpeVFdiBmBk6I6H0OpeVEtxozAyVC9iJG0PKgqyI45l6HSPlvK50HFzsIUOAmqFssJBT2o6I6pkqCai4H0PKjsn+r5j161y3KpVg+qIbhJEL1qFsZB4qp7cJMgctUO4/KfWuIq52vo+4pcNQXD5BNW9cMtiqhVW+2nHRVWTcUtiqhVYzAKS1jFHagVIGKV+v22NVFVT8ozOhCrRmAQI1HVWNwgiValntTHlqjqYdwgiVSVGYQxTImq6DYslEhVD2IIc4KqXpimiVLVdjaGMCeoYtfeJYlSNR0jWBJUTcc0TYSqJv50y0qCqlWYpolO1XYOBrAmqBI9B7dYdKoGPN6WmKovJokiUxmfQVsTU43CJFFUql3Y85BLTDULk0RRqabi0VxiKuIzphCp1uHBfGIqqlNYIxrVzv54MJ+Qqj+mqKJRTcJjHRJSXYIpqkhUa/BQp4RUxC8WJKoWp+2/fEIqsg/YEYFqH/9W0ZSQiju1R8AIVEWeVEpCKqrvrfIFV7kcrCukEj4iRLDAqrWOW+pGIqpqTJAVVLW1Jx5WKBHVAEyQFVD1ofPbD1MiKk8HGogUTJVRz39dPBGV4OGL4gVTFXhPZU5ENQ0TZAVSLcZDiiWimosJsoKonqvCQ4olouLOAxS0AKpN2rEFbomoKL840PKvEkMJqchPSOlbJYgSUpFfe8avShQlpCI/Eb5PlTBKSIWfdPlTiaNipPKAElFtx0+6/Ki8oGKj8oSKi2qjJ1RMVKts+764FYoqu9Ve8S9o52BlhQtH5ak2y6UYhRJQ0b+ye2q7j4tCiqhCuCSIUZN2mS6PiaioPzjz0sPFL2VdIBEV9Ue34mUcv6F3T0Q1BRMlb+dorKXXRFTDMFHqtqinqvCViKo6lJeLzDxfTyktERXlzqnCvTwca+gnIZXISQJpyyzojhX0lZCK+AoS7m1zvB68eEKqdIkvJPSAx41ZLjHVREyWpGb3z9HdElN1p/4Gq0iLa7BqARJTpe/DtPQ2jdTXK1iCqgGluYzkNv1CuoETVKUfxA2ZtTaIfDMgkqiqhuJS/EVrm+v2vah4oqr0SNySVGYJf2pf/wmr5G5grPa9IeuYuKqHtCujZ5sCbkpwiavSI+S8DrYvNR/pS5MHVfpyCazmGdYjEmnyoqJnrR9jPx6MJk8qWtauRezcIdR5UxGyXm4I+uepGlfa682/FfOoSo8juWZm88L8OYYCxN5I2A6rVfKqSg8K/HZ/82yctytglKp05awAH85knmsotGe950hV6fRQnx/mtq0a7+1rqOIRq9JVszyfFGLnunmjA33AwketUl5/Joh/lNG2Yf5Y1z36fESvUhr+sPvzq/2FheMHu+xN6jspqnS6z/iFTc4v9K2b1yy+d8rFQ6neBTomSaVWWTdpUeO65ze+2LRh3drVjzw0d9qY4QP8f5TsJYmqEEtUiSrcElWiCrdElajCLVElqnBLVIkq3BJVogq3RJWowi1RJapw41Xss+9yUtVPxEQ5qerb2FmnykdV32acS6tsVAqq/FQqquxUGqrcVDqqzFRAlZdqPVDFVD/ABCvyKlYRFX4axUfFDkLjVV0xwWrBolGLU+lXC1Vbhjms1AEfYSrfPjl7JgbOrjJQ6bWYxUqd8RamWEOxbMSyqUwo/sRsqRP/iikW2xSOVlaVGTUQ84xS2TsxxWKX1otWFpUZlb4MM1nvpbLXY5JlvQZOZDKrLKh0I+ayfp/KHotJowlYOlqZVFbUQG7n4FtT2YM7MM3aiMWjlaGyohwuk3R8KnvSM5g2IjosirZBU5HtCPBa7lKtHTll24LbZsq2+jlxQUhVPI+VNnpKVZ2MG6ZW4yEx6CqssqlrVdXXX8UtUxF9decbxx9H0JFTVdnv6bcsxYTlgMo+rqsO2q3ftLSM7gA9aVVc7XTEx7GK6gnl5236TWvN38FjI1st/0Kh9ExOUeWUiU85/WNlO1YWPXlz2NXOz78ntna8pvqXMnWzPoNr09S6aL4vqR27usDhRk8qKEWl/mN96w19lkPtTSuWPhStlj9a+MSNHQdC9ZRyg98YjGk/UlGqKqduCP5Mnxn3ntVQmkp9CezCbw3GsN06SlPlnlVmHPmefkec6zhJM0GV+0CZdcRe/a4Yd6OGUdJV2lOr8379vth2m25Rgupade7x9g/R4pWByqty2puso9X/iTGt4wZI1PKqnLZ5cdRr2hIxbHcXOLSYKneG9rT6pbZM7HqmMxR6hiqX017bu8bwFX7/rZ8FAZlVOfVdSTZ7B/ehU8R74vtYf5ZFlbtOe0vS6e44uf7R+RCsvZFVlcvdpS35iZmO77iiV8djxxyBNTdnV+Vyv9WXP+XuPfpEdOv4yzU3HIa1tsarcrmf4M/Wkdff9e+o/l/83+9++LW/fxMrbCuX+z/3VTJd3XOPugAAAABJRU5ErkJggg=='
-y10 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0pKSktLS0xMTE1NTU5OTlFRUVJSUlVVVVZWVldXV1hYWFtbW11dXV5eXl9fX2BgYGFhYWNjY2RkZGVlZWhoaGtra2xsbG1tbW5ubm9vb3FxcXJycnV1dXZ2dnh4eHp6enx8fH5+fn9/f/+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/Tff/UfoCAgIKCgoODg4SEhIaGhoiIiIqKiouLi4yMjI6Ojo+Pj5GRkZKSkpOTk5SUlJaWlpeXl5qampubm5ycnKCgoKGhoaKioqOjo6SkpKWlpaampqmpqaqqqqurq6ysrK+vr7CwsLKysrS0tLW1tbi4uLq6ury8vL29vb6+vv/UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsHBwcPDw8TExMbGxsfHx8jIyMrKys3Nzc7Ozs/Pz9LS0tPT09TU1NbW1tjY2Nra2tvb29zc3N3d3d7e3v/qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uDg4OHh4ePj4+Tk5OXl5efn5+jo6Ovr6+zs7O/v7//04P/14v/25P/25v/36P/46v/47P/57vLy8vT09Pb29vf39//68P/68v/79P/89vj4+Pn5+fr6+vv7+//8+P/9+vz8/P39/f/+/P7+/v///wAAAM9q+HsAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAYc0lEQVR4XtWdeWAc1XnAt3dpKGkbSppSjkDTxAmj2xK2ZRnjU7Z8gPGJMTbCJ24hJJSkaQu5ILQpadPEt3yCjeVDtrGTNqVtCm5DsC2f8tHmaKkl2VYJtkWJRFazmePbN2/m+97MezOzs7O/fzz73ux6ftrZmTfvfe97mZyYX7v5L77x+lsDeur4yX9+66nbbrgGDpNAZPWhG/76f+Ez0spbX7vpfXC0Xmira7/8E3hrunn3q0/+ChyyC8rqg9+BN5UC3/3Ar8Jhc2Cra74F+5cK//KlX4RDZ3it/vDJ92Dn0mHgCx+Go8/jsbr232HP0uJH3/gFELBxW938DuxWarz3iV8HBQve6obPwj6lyFf+ACxMOKvbn4MdSpNvDgIPA8fq01+F6lLl258AE87q81+EytLl67eBC7P64p9AVSnz9HVgA1af+a0UNmLVuRUu8LbVh/W0N2XleOe7lg5YvVtqrSQRrz5h+VhWP7gZCimudHemi+7LPr+WR602oWn1rP4mlHk5uWZGvZY+hkxb2S4we+eVvNXAk1Dkpn9HE3xKGhm7tReO081z19tW/6G/DSUujt0N708r9fvhSF387KBldZv+BBTw9C8vgzenmOarcLQ8z/6OafVj6qreNw3emG4mXIbj5Xj3H00r/ffhJUeJSNFaH78xl3lV/ya8chiYBW9KP01ZOGaHg4/nMsYTF7xy2AZvKQXWwDFzfM+w+iBsO3TVwDtohowYNWrEEHhRdCpOwlE7fMyw+gJsO8yBN2AaZq99+aK9U8+BdXNGQHFRabKPh+Pvb8no34NtRlc57O+h4v7DsAfj6LxKqCwiJ+BgGG89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'
-y11 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0tLS0xMTE1NTU5OTk9PT1BQUFJSUlRUVFZWVldXV1hYWFpaWl1dXV5eXl9fX2BgYGFhYWNjY2RkZGVlZWZmZmhoaGlpaWtra2xsbG1tbW5ubm9vb3FxcXJycnNzc3R0dHV1dXZ2dnl5eXp6ent7e35+fn9/f/+qAP+qAv+rBP+sB/+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+4Kv+4LP+5Lv+6MP+6Mv+7NP+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Na//ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoCAgIODg4SEhIeHh4iIiIuLi4yMjJCQkJGRkZOTk5SUlJWVlZmZmZycnJ6enqCgoKGhoaKioqSkpKampqmpqaqqqqurq6ysrK+vr7CwsLKysrOzs7S0tLa2tri4uLq6ury8vL+/v//UgP/Ugv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/dnf/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/ltP/mtP/mtv/nuP/ouv/ovP/pvsDAwMHBwcLCwsTExMXFxcbGxsfHx8rKyszMzM7OztHR0dLS0tTU1NfX19jY2NnZ2dvb29zc3N3d3d/f3//qwP/rw//rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uDg4OHh4ePj4+Tk5OXl5ebm5ufn5+jo6Ovr6+zs7O7u7v/04P/14v/25P/25v/36P/46v/47P/57vDw8PHx8fLy8vPz8/T09PX19fb29v/68P/68v/79P/89vn5+fr6+v/8+P/9+vz8/P39/f/+/P7+/v///wAAAD9msOwAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAASQElEQVR4XtWdCZgUxRWAJ3c8IsYzhnjFMwfRnnUXkJtFVEAUxGNFFBYUVI7EK0ZDjFcukmhYCTdEblwSRIkxQQ1JTFROLyRqojHcq0YFVlnd7Ukfb3q6u6q733vdPdP1fx92dXfVTP3uTE91ddWrXCGYzx313V/+9e02PXN88Nqf7vjGEftBNSUEWR110O2vw2tklQ9Wnro/1NaP3OqAW/8LRbPNx7869DNQZQ8yqyMnZfBTF8Qrx38Wqu1CtNrvHoWcTJ4+5JNQdQe/1clffw8yK8S9J0Dti/isDngMMqrFO1/6BAjYeK2OVeMiIeEHnwcFC7fVESd9BHkU5LGvgIWJy+qkGyCDmvylA3gYlKxuuglOq8rfTwMTl9Xt34KT6rL6RHBxrO44XLFfKRkrDwIbsLrl4PfhjNLcBhd42+oE/Sk4rjZtX7R0wOrD78Nh1XnzZsvHsnr12JAv1d4dW7PFtqaQ2v7YahOaVnfpq+GYny0zhvXRskfnweNWtEIVfbStKlq1HQOHvLQ9fGkeXiaD1E7fDfX08uRhttVT+qtwxMPmC6B8Vum8QPpJPNSyOlFvD/tu2uZ2hMIZ5tIdUFs3TxxiWr2u/xn2XbSNgYLZptcWqK+bP5pW+pdhz4UiUnKtO9sXcqv122DPxQQolH16N0GVS7x3YyGn62IP2doMX/v8DIc6uzjEsDoS0iX2Bv1G9TzXTwb0G6HWJe4wrL4J6RINkF+gz3bI4dANzlSQHi1QF4fXjs/pkyDtsC+4qoJWBqy0xVCXEnflxK/VIsgtw6+VBavzoC4lDs6JP8GDILcUn1YWrLQXoTIOp+WEi0VrDWSWMxuy2WTC6gGojMMPc+0g5fAC5JVzP+QCMmE1CirjcF/uaEg5zIO8UnxS2bDqB5VxWJU7GVIO90NeGX6pbFh1g8o4PJ47HFIO4yGvBEEqG1adoDIOj4rfq3GQV0SUyoZVR6iMw6qc0LQItJJIZdTqcbyVTEp5K6mU6laCVMs124z/qm0lSl2m9TG0lLaSSRltwm1KW8mlTC2FreRSPYx/fTLRvcaykktdsHe4fbrycKyCpPTdmfj4GTCsAqV0fb6do+LQrUKk9OZOdp5KQ7YaDwcdXFK6Xm9nqjRUq0FwzMEjlZWPINGqyt/P4ZXSN9jZKg3R6go4VMQnpTfZ2SoN0WoFHAL8UvpuO1uloVl18j57FaTUtPJ2iopS+vN2vkpDs6qHIxYSqdC+6zJCsxoDR0xkUvpoO1+lYVtJpVq62vkqDfcTKJXSG+1sFYdmNRCOBEg119rZKg7NqjNc2eVSrowVhmalPWIdaKkzkoMEqbl2ngxAtBph7gdIPWBnyQJEq+qXVZCiWmkXqSBFttKmKCBFsxoDvS1Zl6JZzXnJ0sq8FNFKN7WyL0W1MrQUkCJb6S9XRKqq54C6q8aOb5gydfrMmVMbxl7eG07IIVsJpCiV797/klENDyx/bqc4/nnXiil1Zse+lNhWKUnlz6mfs2EfvEcga4dVQX4vca3SkDrriplrm+H1o9je0B1KuYlplbRUz6HTntkDr42kZfG5ULhEPKtkpfo1PA+vS6Olwf85jGWVoFTV4Flb4VUZbDwHXgaIY5WYVMehC8WBzST2jfOM941hlZBUt5HLI691CNa7rxp8qz2yiw+ZIcsDpuKQ2eSqT4y/ld3UjUOnMZvgtZLApRXnexVT6+w5xGt4FCWtOFZxtPKXPQMvkiCOFslq7HofC8+AM0S6jItxGQ9hE4z2IFklRO/5SVz0pMyx36H8Vl1mpuZkcKH1HuW2qh4vn3yYFFutsRHltcrXm0MIU8UaRVBWq0uEmQ4pcLHxRmW0GvAsvF66bDLeqmxWfR6EV0udi8pmVTVZmOmVGsvLZXX2RnipctBaWxar/Lg0f6FEppfD6qx18Drloqkmfatrsd1FyTE8bavaNfAi5WRuylZXC/3X5WBjqlY97IfjZaelCyQcErQaKAvLUBYugK1DclYjyns9d3MNbB2SsspPh9Ih7F0wP5KXIC+JhbB1SMiq00NQOJSZkDsE72xkJEJTJhmrWuT/4mgtlpXQIZeI1WB0B3OkFstK6OtJwmo0oYEepcWy2gVbh/hWVXOhHI4ILZaV8FGJbdWR2n0ZrsWy2glbh7hWHddCKTyhWiwrIUJKTCuGVLhWFq4WLCnj1gGKS2BZbYatQywrptQS+fgCC5ZVor9XKUjxrIR+xxhWaUjxrBJsMaUixbMSGqFsq3SkeFbzYevAtUpJimc1BbYOTKsq3s18pBTPajRsHZhW/kfGOKKleFZDYevAs7oKstJASPGszoetA8tqEOvZAEaKZ9UHtg4cq1rhfgYDSopl1SpELmJYdWI9QsRJsay2J9HL+TvIRwIpxbLakIDVNMhGAivFsloW30oS3DMatBTLak5sqwGcHlq8FMtqQlyr7sLNNAKCFMtqRFwr38R8FBipYbBlWQ2IaSUEVUSAkXpAnwUphlVLdTyrXoxxizgpvajFsNoY82k3Y+QiVqqoxbCaG89KaPBHg5cCLYbVyFhWtfSHvhQpW4th1S+OVZ5+97uYJGVp0a2aq+JYXQen8VClTC261TothlVf8ugQupShRb/JNv7AbKv8BjiLhiLVMrO42gT9t2N4DCshhlYUJKlLtashSedsvlVvaqOWKKVpwnN4JHvzfCsxsHs4ZCmtK3Py0rNGWaZVf+JMHLoUr41pMN0oyrQi9mlypLT8ejhCwxynz7MaAmeQsKQ07UI4RGK3+V48q+fgDA6mlJbn3JFaca5YVlfCCRxcKV4/z+VmQY7VGbIVfgJ5MFoqPw/yeqW0c+AwgX3WXCWOFakB+Ej0FK0gKU2jzx9+yCrHsOpM+SFp6gKlggmW0mijbExGWeUYVqRP+0goFEyIFP22tNWeA0i36klpq6+FQsGESYmxTaMw7kJM6FaUW4NW30xykVAprSucRANVJVt1ptzWL4FCgYRLaRq1LdjXLka2EgbqhmHO8AojSkojTq0z516ZkK1ehoMYdkb8VEVKUa2mQjGq1UVwDEXEgMZoKapVMX4H1Qo19LnIACgkByFFtHKuuESrWsp9VUtoswIjpdHat84jB6LVDDiE4kUoJAUlVUNajnq78zWmWdWQpjCHXddRUlp/yIRjMpSiWtFuukNWrsRJ0Z7OtpQiONCsXoAjOKxbHSlIKVqTczEUMiBZCROAwgmsMVaK9iRzIBQyIFkRJzIHVRkt1YUykGgjFDKhWHUmjlYKqDNainYj4l5ygWLlD6QfhbzSeCmN0nW2qxoKmVCslsI+FjOAsQBB6izIiaLYBLQgWJ1BfTwx1i7ngSBFur9v7QWFLAhWpIatyUK7nJuS1CVwJJgBlIbFAihkQ7Aid424r0o2FKkqSldqc08oZUOwIs+T3edfQZkiRbs9nQaFALyVuLxtJGdbBR1IUv0oPQlNZ0IpAG81FfYIeJcaJUnVkj4Z10GpIngrxsTdLVZBIF+cEICR6k2KrbXVfyOHtiL9eBQ533oPixSlxOlbaKuxsEOiFF0/TSlxaRa0FSugyN7iBTdNKTOojw+sVRdeSMYH7XdJVeoRKOcCa0VuWABWP2eqUnp/KOgCazUZ0lS21KQt5boFdsBasUbimyxIWWq3t61kg7XihxWZnqqUfH0+pFUPSBK42tfkTkdqOZT0grS6FJIEqkZ5tNKRanIFuXWBtBKWnoymSnNrpSOlXwFFfSCtGIPxqzSXVkpSQStTIa0Y08bMTu+iVkpSO4MWEcNZ9YYUBasr39ZKSUofCmUFcFbCnE4E9gMKUystqeCnEzgrxh0jWBlaaUnt8N0Au8BZcWI+g5U2MiWp4G58rBVnsGjRCgFLah4UloGyqoEECbwVS2pd2ONZlFUtJEigrVhSW0ODqKOshAngGLBWLKm9/aC0HJTV5ZAggbRiSQX/UtmgrEjdqEVwVjypBigdBMqKNc8ZZcWTgt6QYFBWiyBBAmPFk3quBooHgrJiLbyAsOJJ7ZDd03tBWbFW/Yi24kntcz2rDwJlxQpaG2nFk9JHQPEwMFYNsKURZcWUGg/FQ8FYIaKhSoiwYkqFjCJygbH6DWxphFulKoWyWgJbGqFW6UqhrBphSyPMKmUplNUy2NIIsUpbCmX1W9jSCLaqIc0JcsBLoayWw5ZGyN9qpKv7Ew1BCmVFGhftEPa9YmhRpFBWnCgq4VZ0LdSPrwPGihdEL9SKqNUc0J8eBMbqYdjSCLciaW0PH+4vUpnvlQlea4P8cU4IGKukr+wAVmuxe5QmDowVbzWkSCucVivtOmGDsaLPmTQZVR8J4h57T/SQTwkYq8lJLepJZ0vkFEIpGKtxrHUikmBN9LxcKSirBZAoN7Ojv5tyUFaMaFIJsNVee5EDyooxODU+86yVF3mgrKrLtyhcke1R01dDQVlpvHv8GCzqDPXjgbMaCKkysaMOascFZ0UMPhKTpczreQmkVT0ky8Cu4Cl2aJBW1czgSGRa5gaNd6GAtOKF6qXTeJZdrZhgrbqX44+19jy7UrHBWhHj+nB4idU8l4K20ng9uGi2j/LPAIoB3qorKwg7kj0TIp+KUsBbsQae4WielcSFzwXBihxdD8mWscxf3Yun+YETJKvqNJbKfKSO/X2qFrpfi/djFKvktfbMhvA1PAQtllXCWi+NjnELZeHX4lklqNW6jH+rW6La26/MtNKqeR25PlrXXOuZtcymu7ejiGulaWPiLhncvKw+qQu5TyqGldaHt3qSza4Fdcn93vql4lhp+euYa+xumTEowWaRKBXLStP6PkTuzt285LpiDKiEEKViWhkfwxn4cD/bGsdfGDz2nItEKraVptWMQsTG2bl88sWh437ZyKQSsDIYOHapfJBBy7b1jbPHjxgSPZKPi1QqGSuTLkMmLF2xZsNzG9ateWbF8sY5E+ov7pfOX8eNKGVFoEzMqiKIUhu7m40npa0kUmdabUKVraRSVlNXYasAKVNLXasAqWsMI+dhv3JWAVIL9Bn2eQvVrAKl9BZXg0wxq2ApzzRvtay6hUjxoyJWmBohsrlLStevtnMZKGUlPJjxSLlmOqpk1df/0N0rVQz4baCSlT8srU9K32xnM1DIKu+LHGJK5V1SalqdC9UBBClX1GCFrLwBNEUpV1wIhaw8YYYkUq5gcQpZueOhyKRcAW8VsnJNbtvYWSJVulioZFVa8VwqpY+GfAYKWTnxnuVSG13dwgpZdYJ+cLnUbvcIXYWsYGzEBlNKWHRuj2cAikpWVqgrjJRSVmagF5SUWlZ9m3FSClmZgzIG4aQUslow2NpgpBSyWtJsaqGkVLLSDS2clFJWevMQnJRaViJyKcWtAqTUtgqSklkdBymHrFoFSsms2kHKIaNWwVJaJ8ji8Itce0g5RMV0Kg9+qxApce3AVeIncBbkrSw+qzApMZj8qtyhkHKIXkqyHHitQqW0YZDL4dHc0ZByaC4+bq0oHqtwKXFJtbtzX4VUifCwdmXCY2W1CYMRxvrdkNPfhqSDb7WOyuD9BIZq9RZGxB2Z01dC0qEp0YkBTHxXizAtMYDUpJx+IyRLRK+nmz4+qxCtGmH+0VsdcvpJkC6xNe4Q7QQYMtpHfdC40F9DrUtMKuT0L7wLOyXmQwEVGCCOMz3OsNLvgZ0SbcnNjUqbGuE5v/7RRNNKaAkaPxCuZVwyjW/cvsV9B5lW+r/tPTeKaMmk9MMKltXp9p6HPVdCwSzTaw3U1s2/TjGsnjDk/gcHPDQmPPcreUZKl777WsGwKhiJG+x9H7smpz+ilk++7lmop5c3OlhWr+j6Af+BQz72LapLb9xzHGoGjg+KCXesIWVYmX8soeFeYsdDSxZmi0WNzwfPhXjCuFZYVquNnd/bx5Tnw5+bUqZVoc34YwktdzX5tiVlWU00dg8lBCLLLiv3L1kV/mEcuNk+rjSvnG45gVXhfePQT+wzCvPWnZaMgW1lfrX0++xzyvKufaUwAavvmIfV1npnkq1iAlaF75knfmSdVpM3bgcTk6JV4Rbz1PXKXgmfNBtKDo5VocPHxskD37QzKUbbxAPBwqZkVShYTfdJVja1eL3dp0ABcFsVjLsSXT/4n1ZOdfjw1gOg/g4eq8L1H5jZTnndyq0GH919/Keh9iW8VoXCvVbWY560Ntnn7VuPgkaSB79VofAHK3u7m81mVLZ576eH37gf1NqLaFUo3Gk2oAyOmfi42FeYDT5++mentf/bqVBhH4XC/wFcOahFG4NsLQAAAABJRU5ErkJggg=='
-y12 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAFACAMAAAAcQsn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAICAgYGBg4KAAkJCQ0NDRIMABcPABERERUVFRgYGBoaGh0dHR4eHiUZAC4eACEhISUlJSkpKS0tLTAwMDY2Njk5OTo6Ojw8PD4+PlI3AHZOAEFBQURERElJSUpKSkxMTE5OTlBQUFJSUlRUVFZWVlhYWFpaWlxcXF5eXmBgYGNjY2RkZGdnZ2hoaGtra2xsbG5ubnFxcXJycnV1dXh4eHp6enx8fH5+fo5eAJNiAJxoALx9AL2BC5yQecCAAMSCAMaEANaOANmQAOGWAOSYAOucAPGgAPqmAPyoAP+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSf/DTP/ETv/EUf/GVP/GVv/HWP/IWv/IXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoCAgIKCgoSEhIaGhoiIiIuLi4yMjI6OjpCQkJOTk5SUlJaWlpmZmZycnKCgoKKioqWlpaampqioqKqqqqysrLCwsLKysrS0tLi4uLq6ur27ury8vL6+vv/UgP/Vgv/Whf/XiP/Yiv/YjP/Zjv/akf/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsDAwMLCwsXFxcjIyMrKyszMzM7OztDQ0NPT09TU1NbW1tnZ2dra2tzc3N7e3v/qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uHh4eLi4uTk5Obm5ujo6Orq6uzs7O7u7v/04P/14v/25P/25v/36P/46v/47P/57vLy8vT09Pb29v/68P/68v/79P/89vj4+Pr6+v/8+P/9+vz8/P/+/P7+/gAAAHdvKjQAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAWDklEQVR4Xt2deYAVxZ3HCxZ2PbIbDMGV3RDBA1BchEjQva9k152BgUFAUA4PRETkkkPwQCLHGrMSF3Q1GuO6yDWAUUBAcBSTJRIP5D5UJHiCyKAwMwww/dLd79vVR3VX/6pfd7/X+fwB9epVv+7PvNe/rq6ug+WCOa/9Qz9/8/PTWsnR8Mlvnrjy/NY4TB+CrC5t98hmfEapcnrjVefjaL34W7V98CNsWuK80fnbOGQXflaXPNqAjTLAZ7PPxWE7EK1aP5IhJ4PPuv4pDp3jtfpeh09ROENs6oKjt/BYtX0SBbNFw5VnQSCP26rzuyiWOZ45DwomTquO7b5GmQzyzmWwMHBYdb20BC+4dD7tDg8d2+onl2VaStM+vwomDqtHL8q4lP5tdYULt3qswzG8l2HeaQcbWM258GO8k2meQYDPW3XRnkV+xrnS1IFVw/eQm3Ua/sv0Ma0OdJZcqE4eOVRafFHTiEPzYZNZJzSsHteeQp6XI89PubG8rOToNWLampM4RC9mHDSstL9Cjofdk3viY0qQfjO/wGG6+ax93uod7VfIcVEzEduXKj0X+v4SjWsxy3XVOuG1i/X9sXEJM/wDHKyTzy42rD7WfobXTpZhw9KmcicO10lnw0q79AReOsiGlL/Wbzrl2JtaF7xysAoblT6V+3DIDh7KMc0nVhyqxDYZYLgYMq7SrS4RG1/uwBZkrht6w+BeSKfNQhy0zUbd6gKkbVajPI1Ri7fWGls1vvfilN7IS5Oeh82DdnD6cqb9BGmbEShPoPd9ruB6fOkQvJEi87Fzm8eZ9n9IcnajNIExwt+pcWHq9ZH+QuWpO+sktP/d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'
-y2 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABUVFRYWFhgYGBkZGR0dHR4eHiUlJSYmJigoKCsrKywsLC4uLjAwMDExMTIyMjMzMzQ0NDk5OTw8PD09PT8/P0pKSktLS0xMTE5OTk9PT1BQUFNTU1RUVFZWVldXV1lZWVpaWltbW11dXV5eXmBgYGFhYWJiYmRkZGZmZmhoaGpqamtra21tbW5ubnBwcHJycnNzc3V1dXZ2dnh4eHp6en19fX5+fv+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+zHv+0Hv+0IP+1Iv+2JP+2Jv+3KP+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/DTP/ET//EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoCAgIODg4SEhIeHh4iIiIuLi4yMjJCQkJGRkZKSkpSUlJWVlZmZmZycnJ6enqCgoKKioqWlpaampqmpqaqqqqysrK+vr7CwsLKysrOzs7i4uLq6ury8vL6+vr+/v//UgP/Vgv/VhP/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/ltP/mtP/mtv/nuP/ou//ovP/pvsDAwMHBwcPDw8TExMfHx83Nzc7OztHR0dLS0tTU1NbW1tjY2NnZ2dvb29zc3N/f3//qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uDg4OHh4ePj4+Tk5OXl5ebm5ufn5+jo6Ovr6+3t7e7u7v/04P/14v/25P/25v/36P/46v/47P/57vDw8PHx8fLy8vT09Pb29v/68P/68v/79P/89vn5+fr6+v/8+P/9+vz8/P39/f/+/P7+/v///wAAAB2rsOgAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAUOUlEQVR4Xt2de2AUx33Hr2mbPtL0ncQ1bmiTOI7dBjduXd8dQpKFRAUIyYBlEMQ4CIwBY4wskGnjJE2cunEa9+EmDRQLxMM2CGSCa2TLrds4zsOxEGAeAjdJQ9MIS7ZqOwglUnzay+3eV7OPmdmbmZ292/Xnn9ubmV32g253Z+fxm0SWz++8+0/v/8/v/diIHBOvfeOf//ryd+E0GfCsLn/fR56OoI+Lc5+7FGfrhW31q1O//CZ2jTY/vPfXccouWFa/8cffwU4xYOLB38ZpO6Ctfv6938YOMWHigbfj1Aleq6vf/UUUjhFvXIOzn8Rj9eXLX0fJePHML0Agj9vqt/4WpWLHD38XChZOq/dPeQZlYshPp8HCxGE17ZKvo0Q8uQceOWyrT/7e88iOK5+EicPqc1OeQ2Z8uRYuxOr+33waWTFm4g9hA6tPT/sscmLNj3CDz1t92Pj9CWTEm29ZOrD6ydT/Q3Lc+RvLx7L67s/9PRIZTAy/fD5aDF3EqTGYsOqEptXfGdM4v79Md9vSymT0qFu1cwCn6OW5SauJdzyLJDfDHXNwlAiSWv4U+09xZd7qW8ZUJLiY6IziX8lJ00s4VRfftaymGb/0VSQ4GVqOfSNM+SOsP9cVptU54yp8dTIwG3tGmxaG1tdMK+Pqz+Org5hIsbWuyCaeMy57A99shiN8m/CwGafs4LPZhMG6V6zGLjEgdRTnbHMuZ3XV/fhicwh7uJlR11AfwR9m3SjO2iZn9c7vYZswXoMdbMpv33cqY+aN9HYsRVpU2GqdtJM/SxhXY9PmAIoT5u2+gCyL/g3lyIgENeM4L8KDCeMybNrchOJg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'
-y3 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0BAQEJCQkREREZGRklJSUtLS0xMTE9PT1FRUVJSUlZWVldXV1hYWFpaWl1dXV5eXmBgYGFhYWNjY2RkZGVlZWZmZmhoaGtra2xsbG5ubm9vb3FxcXJycnV1dXd3d3h4eHp6enx8fH5+fv+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoCAgIKCgoSEhIaGhoiIiIuLi4yMjI+Pj5CQkJKSkpSUlJWVlZeXl5mZmZqampubm5ycnJ6enqCgoKGhoaKioqSkpKWlpaampqmpqaqqqqurq6ysrK2tra+vr7KysrS0tLa2tri4uLq6ury8vL29vb6+vv/UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsDAwMHBwcPDw8TExMXFxcbGxsfHx8jIyMrKyszMzM7Ozs/Pz9LS0tPT09TU1NbW1tjY2Nra2tvb29zc3N3d3d7e3v/qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uDg4OHh4ePj4+Tk5OXl5ebm5ujo6Ovr6+3t7e7u7u/v7//04P/14v/25P/25v/36P/46v/47P/57vHx8fLy8vT09Pb29vf39//68P/68v/79P/89vj4+Pr6+vv7+//8+P/9+vz8/P39/f/+/P7+/v///wAAAJQ+NvAAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAU6ElEQVR4Xt2deWAc1X3Ht3dJL9IcjSkFktCkJKwky5J8yadsfFs+hLGNbXziM4SQENI2bUoh0JomLbGx5QtjG98HQiW9krZxSRowNr4tt2mcUIwPqRB04Ep0Nds5vvtmZt+bmXft7ow//+zse29G89Huzrx5x++lssH8yie/+tJ//MyIHb3v/PDpP7ztphtwmgyCrG665a/ewUHiypt/8bEP4mzzYVv9xupr2DXe/OzPH/klnLIPltVHvoedksA//uYv47Q90FY3/DPKJ4WXnvx5nDoh3+r3/6wXhZPD+1/6NM4+R57Vr/8YJZPF9//+5yDg4Le6830USxrv3farULDxWn3s6yiTRL58OywsPFa3fwsFkskTD8LDxLV66NvITiqrH4KJx+pr30Rmcnn0M3AhVo/+KbKSzAO/AxtYPfwJZCSa3g/hAu9YfcJ4DxnJ5s0f2DqwunYYyUnnpT+yfWyrHz2ARAa97ZffiheXO3BqLG6z64SW1eNB37/eo2unD0zHj9oZ60/hFPN543DOqvdJJPnp2n4XjhJHJu7twXn6+dKtjtUPDGY1/cVa7B9XRh7Hmfp490e21SeNx5HgpXMR9o0x5atYH9dDN1tWFwzG03z7OOwZb6Z343w9vPmvlpXxWbz1kBApttbv3pxNHTa+j3cuPROxU/yZSV8TvvWVbAqbPtZhlySwE+fs8v4F0+oOvHE5VY49/AyqqxuEzRhRfQln7dLHtHoa2y6M71/l/ENXrawrB+f1RVJcmG2fs5ev3ZEyqCbakyjuUrG2DXkmrSvZH2WpKL+MEyP8+1OM39U8FCeMzquenKhDRjxYhdMi9F5I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'
-y4 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0BAQEREREZGRktLS0xMTE1NTU9PT1FRUVNTU1RUVFZWVldXV1hYWFlZWVpaWl1dXV5eXl9fX2BgYGFhYWJiYmRkZGZmZmpqamtra2xsbG5ubnBwcHFxcXJycnV1dXh4eHp6en9/f/+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+3Kv+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov+9Pf++PP++Pv++QP/AQv/ARP/BRv/CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/Tfv/UfoCAgIKCgoSEhIaGhoeHh4iIiIuLi4yMjI6OjpCQkJOTk5SUlJWVlZaWlpiYmJqampycnJ2dnZ6enp+fn6CgoKKioqSkpKampqioqKmpqaqqqqurq62tra+vr7GxsbKysrS0tLW1tbe3t7i4uLq6ury8vL29vb6+vv/UgP/Vgv/WhP/Whv/XiP/Xiv/Yiv/YjP/Zjv/akf/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/ltP/mtP/mtv/nuP/ouv/ovP/pvsDAwMHBwcPDw8TExMbGxsnJyczMzM7OztDQ0NLS0tTU1NXV1dbW1tfX19jY2Nra2tvb29zc3N7e3v/qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uHh4ePj4+Tk5Obm5ujo6Orq6u3t7e/v7//04P/14v/25P/25v/36P/46v/47P/57vDw8PLy8vPz8/T09Pb29vf39//68P/68v/79P/89vj4+Pr6+vv7+//8+P/9+vz8/P/+/P7+/v///wAAAGcqjO8AAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAASDklEQVR4Xu2deZzWxBnH397Vth5tvVqLtNjisRcILCBUuxwrVAW5VHRFUXAFuopASyse9a5t1VZbri6KyKnAUhFQa6vV1mJVEN1yqWjLcnoDCstu3r5Jfu/kmMn7PpNM8ib72e8/bzJHNt99d5PJZOaZVNqbL7W97v7V7zdrseOjN5666fvHH4LTFOBldfwxd/wXx4grH/7+u0fgbN2Irb568weoGm/233PYF3DKDkRWRz0Zw786L/75rS/itG3wVofch/JJ4bm7PotTZ7itfjDhUxRODs13noSzz+Ky+spzKJks3jnsMxAwcVod9yGKJY3miV+GgoHd6rgJCbpKuLn7RFjo2KxOvBkFksnTE+CRwbKadBuyk8rfJsHEZnXLFGQml6dOgQuzuvUkZCWZO4+FDawmtzuInERzMi7wplU77R2kJ5v9qw0dWH16L5KTzr+vN3wMqzePRaKIPdsb4sX23Tluq5ONNqFudbu2BWlu1tde2KMofpQPrnnZw2z/c1mr5muQ5KSpbiCOEkd6z92L83Tyu7am1WrtPaQ4qO+D+nGl23KcqYPmNw2rE7VTkWCnaWYpKseYSz/G2dq5p41utUV7G/s2GoejYrzpswvna+Pg33Ur7RvYtZEQKbHWxDbp1PPab7Fn41JUij+VB3DKFm9dl05p2ifYs1iKKklgLM7ZxpaM1ZHYtthZjhouuvcBpyMhDhSvxVlbXJux+gW2LS5DBRclDcjXLkZKLOjL3Y//enJKewbbjF1lKO/iMuRrG4uREg9ewWkxPr07pXE9ZbUo7aJkM/K1EUiJCRfitCy2pL6JLYszUNrFJcjWNpcgJSaU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'
-y5 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0BAQEREREZGRkpKSktLS0xMTE9PT1FRUVJSUlRUVFZWVldXV1hYWFpaWlxcXF1dXV5eXl9fX2BgYGFhYWJiYmRkZGVlZWZmZmlpaWtra2xsbG1tbW5ubm9vb3FxcXJycnNzc3V1dXZ2dnd3d3h4eHp6ent7e35+fn9/f/+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+4K/+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoCAgIODg4SEhIeHh4iIiIuLi4yMjI6Ojo+Pj5CQkJOTk5SUlJmZmZqampycnJ6enqCgoKKioqOjo6SkpKWlpaampqenp6qqqq2tra6urrKysrS0tLa2tri4uLq6ury8vL6+vv/UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsDAwMHBwcPDw8TExMbGxsjIyMnJycrKyszMzM3Nzc/Pz9DQ0NLS0tTU1NfX19jY2Nra2tzc3N7e3t/f3//qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uHh4eLi4uTk5OXl5ebm5ufn5+jo6Onp6evr6+zs7O/v7//04P/14v/25P/25v/36P/46v/47P/57vDw8PLy8vPz8/T09PX19fb29v/68P/68v/79P/89vj4+Pr6+vv7+//8+P/9+vz8/P39/f/+/P7+/v///wAAAIAkMWMAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAUiElEQVR4Xu2deYAW5X3H3941bdWkidbGkFpjUptWbWfZw11YUETlEEGR+wjIIcppo6a1qWnSNDFqeiD3ERCX+xCSpo29kpAUkFsEj6aNgZVlm7TCrpaV3Xk7x/f9zfE8z8wzz8y8M5Py+eed+T3PzDyfffed45nnKJXF/NJVf/zV7/xXj5473n3jH754w9WXoJgcRFZXX/q517GPvPK/f/f7l6O0fvhWv/onP8Sm+abnm1f9AorsgWf1oa9cwFYF4N+v/0UU2wVrdclfFMjJ5PXf/FkUnfBb/c51P0bmAvGNT6L0FXxWv/K3yFgs/ue3fwYCNl6rq/4T2QrHl38ZChZuq6s++i7yFJB/+gQsTFxWn7gphxdceb7/CDwMHKvH/gDJReW1x2Disvr8xwv9TZl87ya4kNUXLi/YVYrHt66EDawe/1gBL1MsX8AJ3ra6Tv9XxAvORywdWL37GUSLzo//zPKxrF678j1EOXSePpUvWs90o2gc/sq6JzStvqS/iJifUyun3K7lj5vvnbNNZPaBilXPlYh46dk7oQa7ySG3LDmDcnrZfY1ttVvfjYiH1lHYPq80rOFeYT9qWX1c/yDW3fS0NGLjHDOqFaV1s7uXafUD/e+x7qJnPjbMN/1eQXndXGZa6b/OfpEFkeJrPd2rXPq2/ijWXCzDRvmnXxuK7PDuZ8sl46YQaw6He2ObAjCe/U8zviv9/Vh2OD/Iyt88OIxcnFBaUGqHpwyrj2HZYYWdfSlWxXzKzpgtTR0oDfGjG0r6l7FMdA+wsxfESluD0jg8XWIvwduQuyhWg5hf1tWlDzI3tuOQuyhW2n4Uh3isxJws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'
-y6 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0BAQEREREZGRkpKSktLS0xMTE1NTU5OTk9PT1FRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWlxcXF1dXV9fX2BgYGFhYWJiYmRkZGVlZWZmZmlpaWtra2xsbG5ubm9vb3FxcXJycnV1dXZ2dnh4eHp6ent7e3x8fH5+fn9/f/+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoODg4SEhIaGhoeHh4iIiIqKiouLi4yMjI2NjY6OjpCQkJGRkZKSkpWVlZmZmZqampycnJ6enqCgoKKioqOjo6Wlpaampqqqqqurq7CwsLGxsbKysrW1tba2trq6ury8vP/UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsDAwMPDw8TExMbGxsnJyc3Nzc/Pz9HR0dLS0tPT09TU1NbW1tfX19jY2NnZ2dra2tvb293d3d7e3v/pwP/qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uDg4OHh4eLi4ubm5ufn5+np6evr6+3t7e/v7//04P/14v/25P/25v/36P/46v/47P/57vDw8PHx8fLy8vPz8/T09Pb29v/68P/68v/79P/89vj4+Pn5+fr6+vv7+//8+P/9+vz8/P39/f/+/P7+/v///wAAAKxo9DAAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAV8UlEQVR4Xt2deWAU133Ht3fdNnZrpy2mbpripnFSu2mOkYQEAmQQt5A5TEAgwGAhwOauY9duHbdNmqRp67TmPmQjJAtzI8dpk7ZJmjStzI0wUDtOYw4BbhxLyHF2YTXbOb775nhv3rw3M7s7488/zL55u5oPu/v2Hb/3m1TOm1/67Uf//t9+eEONHdd/8PUvf+qWm3CZDLysPnjzk98dwIvElBvfeORWXK0bttWvffJVPDXm/PtHfgGX7IBldftfv4MnJYA3P/OLuGwbtNVNTyTISefNP/5ZXDrBbfVH7/8+KieIb92Dq8/jsvrVL8a8iWBz/TM/AwETp9UH/gPVEsdLvwwFA7vVB+78P9RJIK9+FBY6NquP3v4T1EgkbzwKDw3L6vHB13E+ofzocZjYrP7mfe/ibGJ54+NwIVZfuPUtnEswr90BG1h99q7/wZlE8zU08KbVXerTKE84jxk6sHr3TpQmnRt/ZfgYVq/d8SZKGaQvX4gXF69kcGkMvmP0CXWrv1W/iDI3V1ubJ5crsWPo1Id29eMS3RjtoG41cAd7vHuquRIvE0OqV53HZTr50YdMq/9Uv4ISB71NeH5cKV/L/CQ+YVh9RB3E6qd3jsaTY0zdKVysnbeG6Favq5/DYzvteGK8qXwZl2tHG2ylcupv/RgPbSRDiq313SG51DfVD+KRjX14UvypPIlLtvGXuZTKaCsuj8BzEsCkNC7a4nHN6ra38YAw0IhnOBk5fmLtSBzHiDW4aotva1Z34djiIOrbGLtm70Xj3OX2BcNRFhPKzhoXZmPgYyn1kzi2mIX6hIaDWZzSyXRNR3k8WI7rshiUUv8B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'
-y7 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0BAQEREREZGRkpKSktLS0xMTE1NTU5OTk9PT1FRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV9fX2BgYGFhYWJiYmRkZGVlZWZmZmlpaWtra2xsbG5ubm9vb3FxcXJycnV1dXh4eHp6enx8fH5+fn9/f/+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2Jf+2Jv+3KP+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++Pf++Pv+/QP/AQv/ARP/BR//CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/Rdf/Rdv/SeP/Sev/TfP/UfoODg4SEhIaGhoeHh4iIiIqKiouLi4yMjI2NjY6OjpCQkJGRkZKSkpSUlJqampycnJ6enqCgoKKioqOjo6Wlpaampqqqqqurq7CwsLGxsbOzs7S0tLa2trq6ury8vP/UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/enf/env/foP/go//gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsDAwMPDw8TExMfHx8nJyc3Nzc/Pz9HR0dLS0tPT09TU1NbW1tfX19jY2NnZ2dra2tvb29zc3N/f3//pwP/qwP/qwv/rxP/rxv/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03+Hh4eLi4uPj4+Xl5ebm5ufn5+jo6Onp6evr6+3t7e/v7//04P/14v/25P/25v/36P/46v/47P/57vDw8PLy8vPz8/T09Pb29v/68P/68v/79P/89vj4+Pn5+fr6+vv7+//8+P/9+vz8/P39/f/+/P7+/v///wAAACsZAT0AAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAQLUlEQVR4Xt2de4BUVR3Hp3dWvoAKVs0MKtFE090FBEFeCriISBAqkgjyCAmENDVTy8qyBwXiIg9BFHkoIqilFZamLQQIqKBZZro8NRUWH7uwe6f7+M6ZO3Pu3DmP332cPv/sufeec+d8dma+c+fOuedmsqX5xJFn3PbYqwet1HHotT/+8nufPwzdDKCU1QlHXP34IewkpbQ8dWMr9LaYYKvPnPQnNE05L53+MXS5gCCrdte8iUYG8O6PPo5u++CtDuv0OhoYwrs3fBhdZxRbfa3NE6hsEP9qg97nKLL69DUpjLzytNz6IQh4FFod/wiqGcdfPgkFF7/V8R1eQh0DefNkWDj4rE5uZ1hMFPJeO3jY5K2ur/gvthvKwQqY+Kx+crjRz5TD+4fDhVn9tNU/sM1g3joWNrC6qeOj2GI0zyDgPauO1nVYbzi/cnVg9X6HlB+fC9PB9XGtXj7uSawMoGnvzh3pYk8juhbAm+4xoWP1c+s0rCvmwNJJQ7pUpo7qmvF3v4EuFnNrzqrl2OBPqvopZ2E3KaTr+K3oZiGHvuJZ/dX6PtYU0DS9GjtIK+P2oasFzHCtTrLavoUVfrbWoG2K6bManfXT0t6xesXqhGU/dV3RMt3ci+76ucWxsj73FBZ9GCIVqPV2+2xmrXUClnxsMUWqsvIBdNnHCdmMFZAVjeehiQH03INO55lhW7X+MxbyXOXW71pTnh5uzUQZ1YJeM96xrTpya7dXudWHYDGM77g1k2UV+pLn1IzVFsU8k73aplhdhL7kOT1jXYsio6G7V9sUq8pt6AzjV5m2M1Bk3IPKxlhNRWcYT2f4sBiPysZYDUVn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'
-y8 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0BAQEREREZGRkpKSktLS0xMTE1NTU5OTk9PT1FRUVJSUlRUVFZWVldXV1hYWFlZWVpaWlxcXF1dXV5eXl9fX2BgYGFhYWJiYmRkZGVlZWlpaWtra2xsbG1tbW5ubm9vb3FxcXJycnNzc3V1dXZ2dnd3d3h4eHp6en5+fn9/f/+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+4Kv+4LP+5Lv+6MP+7M/+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/DTP/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/LZP/MZv/MaP/Nav/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoGBgYKCgoSEhIiIiIuLi4yMjI6Ojo+Pj5CQkJOTk5WVlZqampycnJ2dnaCgoKKioqOjo6SkpKWlpaampqenp6urq62tra+vr7KysrS0tLa2trm5ubq6ur29vf/UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/akP/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/mtP/mtv/nuP/ouv/ovP/pvsDAwMHBwcPDw8TExMbGxsjIyMnJycrKyszMzM3Nzc/Pz9DQ0NLS0tTU1NfX19jY2Nra2tzc3N3d3d7e3t/f3//qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6evr6+zs7O7u7v/04P/14v/25P/25v/36P/46v/47P/57vDw8PLy8vPz8/T09PX19fb29v/68P/68v/79P/89vj4+Pr6+vv7+//8+P/9+vz8/P39/f/+/P7+/v///wAAABfKiGAAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAWaklEQVR4XtWdeWAdx13HH2dJoXFJg+OG0DSmTgrhaGB1WbJs+YyP+IitxLcdK/J9xDYQAoGUltJCkxZ8yld83zdQIFxt0oJvy7YslxoKTX1ICikgWwQpedrHHt83O7szuzszu++93c8/fm9m9mk/fm935/xNJufPh/p85gt//a/v6Ymj9z+/8ZXfeegenCYHP6uH7/3Vv/w/fEhSuf7Ze3G2XvhWP/XQ13pxaLL53u/+GE7ZBc/qgcf/DQelgA/+5Mdx2hSs1T0/dx0HpIQP/vCHceoEr9Uv3v8XKJwi3n0MZ5/HY/WTn/pvlEwXf/ZDELBxWz30JZRKHf/xE1CwoK0e6v93KJNC3usPCxPK6hce+CeUSCW9T8DDwLH67X7/gvy08mswoaw+95FvIjO19H4aLsTq8/e9gbwU8/59sIHVy49+Hjmp5l3c4G2rx/RPIj3l/KOlA6v3+r+L5LTzkuVjWX3nwa8ikUO249bNZNHWhVPj8L5VJzStvqjfjzQv2SMr6qu15PFkw5ZbOEUvb+Steh98C0luOjYMw6ckkLLZp/lNwI/bVm/p/ZHgonf7QHxAUpnK/b7etKw+rfflfVW3puLYBFOzh/d19TWtvqv3wVuaq3U4Mtms5mj9lWml/8yreEuREimuVu8juczX9YfZvrG2tEhpWhNOmeLFXEbn3Ct6Z+GQFFB+CSft8E3D6mNfxhuHPTjCw/Axo2vwMkGM68ZZOxhWj34frwl3B+EAisGrTt8x867tm46UxLDZOmmaARm9L146bEdxh9pd1H9I6zykJoSRWZwY4UsZ/WG8JPSOQXHCzDZkgUO1yEgGR3BahDcz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'
-y9 = b'iVBORw0KGgoAAAANSUhEUgAAANUAAAE/CAMAAADmNnbhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABkZGR4eHi4uLjAwMDExMTk5OTw8PD09PT8/P0pKSktLS0xMTE1NTU5OTlBQUFNTU1RUVFZWVlhYWFlZWVtbW11dXV5eXmBgYGFhYWJiYmRkZGZmZmpqamtra2xsbG1tbW5ubnBwcHFxcXJycnV1dXh4eHp6en5+fv+qAP+qAv+rBP+sBv+sCP+tCv+uDP+uDv+vEP+wEv+wFP+xFv+yGP+yGv+zHP+0Hv+0IP+1Iv+2JP+2Jv+3KP+3Kv+4Kv+4LP+5Lv+6MP+6Mv+7NP+8Nv+8OP+9Ov++PP++Pv+/QP/AQv/ARP/BRv/CSP/CSv/CTP/DTv/ETv/EUP/FUv/GVP/GVv/HWP/IWv/IXP/JXv/KYP/KYv/KZP/MZv/MaP/Nav/NbP/ObP/Obv/PcP/Qcv/QdP/Rdv/SeP/Sev/TfP/UfoCAgIKCgoSEhIaGhoeHh4iIiImJiYqKioyMjI6Ojo+Pj5CQkJOTk5WVlZaWlpiYmJqampycnJ2dnZ+fn6CgoKKioqOjo6SkpKampqioqKmpqaurq62trbGxsbKysrS0tLW1tba2tri4uLq6ury8vL29vb6+vv/UgP/Vgv/WhP/Whv/XiP/Yiv/YjP/Zjv/ZkP/akP/akv/blP/clv/cmP/dmv/enP/env/foP/gov/gpP/hpv/iqP/iqv/jrP/krv/ksP/lsv/ltP/mtP/mtv/nuP/nuv/ouv/ovP/pvsHBwcPDw8TExMbGxsnJycrKyszMzM7OztDQ0NLS0tTU1NXV1dbW1tfX19nZ2dra2tvb29zc3N7e3v/qwP/qwv/rxP/sxv/syP/tyv/uzP/uzv/v0P/w0v/w1P/x1v/y2P/y2v/z3P/03uHh4ePj4+Tk5Ofn5+jo6Orq6uvr6+zs7O3t7e/v7//04P/14v/25P/25v/36P/46v/47P/57vDw8PLy8vPz8/T09PX19fb29vf39//68P/68v/79P/89vj4+Pr6+vv7+//8+P/9+vz8/P/+/P7+/v///wAAAJqY7cUAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjVkR1hSAAAV7ElEQVR4Xt2deWAVx33HX++6ce06dd3Ubp24dWM/ISEkLiFQOQRGnKKY+zCUSxxNGidtnaZuYsd2mto52iIQUC6Jw8hABQXiuKldp3XtIsRtjtRxmhQkJOqkNgg7T0j7usf3zR4zszszu+9Yf/5A+2Znn/aD9pjzN4k0n1/63S+++L33tIKj78ev/+1f/PZdt+A0GfCsPvY733gXX1Ko/OiZOz+Cs/XCtrr1uZ/i0MLmJ1/681/AKbtgWf3mv+OgGND3ra/+Ik7bAW11y6s4IC5888s/i1MneK1+7yt9yBwfPvjMJ3D2GTxWt/4AOePFq3/3MxCwcFs9Gr8/lMX/3fXLUDBxWt31LPLEkL7P3AMLA4fVfS8hRzz50gPw0LGtPvcv2B1XnnoQJg6rJ17EzvjyhfvgQqye/Ap2xZnfvw02sHrsk9gRa26+gwe8ZfUJLR7lviB+8K+mDqw++E8kx52v/anpY1r912NIZNB3teNyYdFxHafG4jfMMqFh9TTv+utrXVM7KFl4DJu14U2copfvfydj1fcNJLnpbhyFbylEJu/rxXm6+dSdltXrGrP01zIYxxcq1Wdwpi7eec20uk97DglOri3EsQVMcQPrz/XgRw2r72s38dlB1xgcWdjM7sH5Onj7JcNK+xw+OoiJFFvrjrvTie9qb+GTTWosDip8FuKUHfzNo+kENl2swiFxYB/O2eb9N3SrP8EHm+NFOMJFceWokcOYe/LKoE6ctc3tutV3sE3oq8YBNsWzt59MGfu627ZMKzCzReZJO/n8vQntA2wTWpGdMHSd6//jYl05dhQE/a/ivAgvP824r2Yhe4blN7CD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'
-
-
-
-Update = lambda elem, value: window.Element(elem).Update(value)
-
-class BadInputError(Exception):
- pass
-
-
-class Player():
-
- def __init__(self, name):
- self.id = None
- self.name = name
- self.type = 'Human'
- self.hand = Hand()
- self.legalCards = []
- self.wildCards = []
- self.valueChangeCards = []
- self.zeroCards = []
- self.canSkip = False
- self.canReverse = False
- self.canDrawTwo = False
- self.canDrawFour = False
- self.canValueChange = False
- self.drew = False
- self.scrollMax = 0
- self.points = 0
- self.forceDraw = 0
-
- def addCard(self, card):
- self.drew = True
- if self.forceDraw > 0:
- self.forceDraw -= 1
- self.drew = False
- self.hand.addCard(card)
-
- def beginTurn(self):
- self.drew = False
-
- def didDraw(self):
- return self.drew
-
- def getLegalCards(self, color, value, zeroChange=False):
- self.canSkip = False
- self.canReverse = False
- self.canDrawTwo = False
- self.canDrawFour = False
- self.canValueChange = False
- self.canZeroChange = False
- self.legalCards = []
- self.wildCards = []
- self.valueChangeCards = []
- self.zeroCards = []
- plusFours = []
- for card in self.hand:
- if card.isWild():
- if card.getValue() == '+4':
- plusFours.append(card)
- else:
- self.wildCards.append(card)
- elif zeroChange and card.isZero():
- self.canZero = True
- self.zeroCards.append(card)
- elif card.getColor() == color or card.getValue() == value:
- if card.getColor() != color:
- self.canValueChange = True
- self.valueChangeCards.append(card)
- if card.getValue() == "+2":
- self.canDrawTwo = True
- elif card.getValue() == 'R':
- self.canReverse = True
- elif card.getValue() == 'X':
- self.canSkip = True
- self.legalCards.append(card)
- if len(self.legalCards) == 0 and len(plusFours) > 0:
- self.canDrawFour = True
- self.wildCards += plusFours
-
- def getValidCards(self):
- return self.legalCards
-
- def getAllValidCards(self):
- return self.legalCards + self.wildCards + self.zeroCards
-
- def hasLegalCard(self):
- return len(self.legalCards) > 0
-
- def addPoints(self, amount):
- if (self.points + amount) <= 999999999999999999999:
- self.points += amount
-
- def removeCard(self, index):
- return self.hand.removeCard(index)
-
- def assignID(self, identity):
- self.id = identity
-
- def getName(self):
- return self.name
-
- def getID(self):
- return self.id
-
- def getPoints(self):
- return self.points
-
- def getType(self):
- return self.type
-
- def getCardNum(self):
- return len(self.hand)
-
- def getHand(self, scrollNum=0, hide=False):
- return self.hand.show(scrollNum, hide)
-
- def getForceDraws(self):
- return self.forceDraw
-
- def addForceDraw(self, num):
- self.forceDraw += num
-
- def decreaseForceDraw(self):
- self.forceDraw -= 1
-
- def removeForceDraw(self):
- self.forceDraw = 0
-
- def checkCard(self, index):
- return self.hand.getCard(int(index))
-
- def discardHand(self):
- self.hand.discard()
-
- def __str__(self):
- return self.name
-
- def __repr__(self):
- return '({},{})'.format(self.name, self.points)
-
-
-class Hand():
- ''''deck' (Deck) : Card's Color (rgby)
- 'numberOfCards' (int) : Card's Value (0-9, R, X, W, +2, +4)'''
-
- def __init__(self, deck=None, numberOfCards=0):
- self.hand = []
- if deck != None:
- self.draw(deck, numberOfCards)
-
- def __iter__(self):
- return iter(self.hand)
-
- def __len__(self):
- return len(self.hand)
-
- def __getitem__(self, item):
- try:
- return self.hand[item]
- except:
- return ''
-
- def addCard(self, card):
- self.hand.append(card)
-
- def removeCard(self, index):
- index = int(index)
- if (0 <= index < len(self)):
- return self.hand.pop(index)
-
- def discard(self):
- self.hand = []
-
- def show(self, scrollNum=0, hide=False):
- return ''
-
- def getCard(self, index):
- return self.hand[index]
-
- def indexCard(self, card):
- return self.hand.index(card)
-
-
-class GameSettings():
- playerIdentities = ('play1', 'play2', 'play3', 'play4')
- computerNames = ('Watson', 'SkyNet', 'Hal', 'Metal Gear')
-
- def __init__(self):
- self.playerStaging = [] # Where Player Objs Are Stored Before Game Starts
- self.players = {} # ID : Player Obj
- self.numPlayers = 0
- self.useColor = True
- self.displayEffects = True
- self.hideComputerHands = True
- self.zeroChange = False
- self.computerSimulation = False
- self.mainMenuError = ''
- self.computerSpeed = 'normal'
-
- def canAddPlayer(self):
- return (self.numPlayers < 4)
-
- def canRemovePlayer(self):
- return (self.numPlayers > 0)
-
- def canBegin(self):
- return (self.numPlayers > 1)
-
- def addPlayer(self, player):
- self.playerStaging.append(player)
- self.numPlayers += 1
-
- def removePlayer(self, number):
- number -= 1
- del self.playerStaging[number]
- self.numPlayers -= 1
-
- def clearStaging(self):
- self.numPlayers = 0
- self.playerStaging = []
-
- def finalizePlayers(self):
- self.players.clear()
- identity = 0
- for player in self.playerStaging:
- playerID = GameSettings.playerIdentities[identity]
- player.assignID(playerID)
- self.players[playerID] = player
- identity += 1
-
- def getPlayerNum(self):
- return self.numPlayers
-
- def getComputerName(self):
- complete = False
- index = self.numPlayers
- while not complete:
- name = self.computerNames[index]
- complete = True
- for player in self.playerStaging:
- if player.getName() == name:
- index += 1
- if index >= len(self.computerNames):
- index = 0
- complete = False
-
- return self.computerNames[index]
-
- def getRandomIdentity(self):
- '''For Getting a Random Player for First Turn.'''
- return random.choice(self.players.keys())
-
-
- def changeComputerSpeed(self):
- return
-
-
-
-class Deck():
- ''''shuffle' (bool) : shuffle deck.'''
-
- colors = ('red', 'yellow', 'green', 'blue')
- values = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'X', 'R', '+2')
-
- def __init__(self, populate):
- '''Initializes proper deck of 108 Uno Cards.'''
- self.deck = []
- if populate:
- self.populate(True)
-
- def __getitem__(self, index):
- return self.deck[index]
-
- def populate(self, shuffle=True):
- for color in self.colors:
- for value in self.values:
- self.deck.append(Card(color, value))
- if value != '0':
- self.deck.append(Card(color, value))
- for i in range(4):
- self.deck.append(Card('wild', '+4'))
- self.deck.append(Card('wild', 'W'))
- if shuffle:
- self.shuffle()
-
- def __iter__(self):
- return iter(self.deck)
-
- def __len__(self):
- return len(self.deck)
-
- def draw(self):
- return self.deck.pop()
-
- def place(self, card):
- return self.deck.append(card)
-
- def insert(self, card):
- self.deck.insert(0, card)
-
- def shuffle(self):
- random.shuffle(self.deck)
-
-
-class ComputerPlayer(Player):
-
- def __init__(self, name):
- super().__init__(name)
- self.type = 'Computer'
- self.begun = False
- self.colorsInHand = {'red': 0, 'blue': 0, 'green': 0, 'yellow': 0, 'wild': 0}
- self.colorsOutHand = {}
- self.currentColor = ""
-
- def addCard(self, card):
- Player.addCard(self, card)
- color = card.getColor()
- self.colorsInHand[color] += 1
-
- def indexCard(self, cardColor, cardValue):
- for card in self.hand:
- if card.getValue() == cardValue:
- if cardValue in ('+4', 'W'):
- return self.hand.indexCard(card)
- else:
- if card.getColor() == cardColor:
- return self.hand.indexCard(card)
- raise ValueError("Card Cannot Be Found")
-
- def think(self, match):
- card = None
- self.currentColor = match.currentColor
- currentValue = match.currentValue
- zeroChangeRule = match.zeroChange
- twoPlayers = False
- previousTurnID = match.getNextTurn(True)
- nextTurnID = match.getNextTurn(False)
- previousPlayer = match.getPlayer(previousTurnID)
- # nextPlayer = match.getPlayer(nextTurnID)
- if previousTurnID == nextTurnID:
- twoPlayers = True
- if self.canSkip == False and self.canReverse == True:
- self.canSkip = True
- self.canReverse = False
-
- self.getLegalCards(self.currentColor, currentValue, zeroChangeRule)
-
- ### DRAW CASE ###
-
- if len(self.legalCards) == 0 and len(self.wildCards) == 0:
- return "d"
-
- else:
-
- ### NO LEGAL CARD, USE WILD CARD ###
-
- if len(self.legalCards) == 0:
-
- if zeroChangeRule and self.canZeroChange:
- bestZeroColor = self.getBestColor(self.zeroCards)
- card = self.getCardByColor(self.zeroCards, bestZeroColor)
-
- else:
-
- if self.canDrawFour:
- card = self.getCardByValue(self.wildCards, "+4")
- # print(card)
-
- else:
- card = random.choice(self.wildCards)
-
- else:
-
- ### HAS LEGAL CARD ###
-
- if twoPlayers and self.canSkip: # Always play a skip card in a two player game
- # print("Shed Skip Strategy")
- card = self.getCardByValue(self.legalCards, "R", "X")
-
- if self.canReverse and previousPlayer.didDraw():
- # print("Reverse Strategy")
- reverseCards = self.getAllCardsByValue(self.legalCards, "R")
- for reverseCard in reverseCards:
- if reverseCard.getColor() == self.currentColor:
- card = reverseCard
-
- if self.canValueChange:
- # Computer Can Value Change, However, Should it?
- # Computer Checks to See if Value Change Color is Better Than Current
- currentColorNum = self.colorsInHand[self.currentColor]
- bestValueChangeColor = self.getBestColor(self.valueChangeCards)
- if self.colorsInHand[bestValueChangeColor] > currentColorNum or len(self.valueChangeCards) == len(
- self.legalCards):
- card = self.getCardByColor(self.valueChangeCards, bestValueChangeColor)
-
- if card == None:
- # print("Random Strategy")
- card = random.choice(list(set(self.legalCards) - set(self.valueChangeCards)))
-
- color = card.getColor()
- self.colorsInHand[color] -= 1
- return str(self.indexCard(card.getColor(), card.getValue()))
-
- def getWildColor(self):
- maxKey = max(self.colorsInHand, key=self.colorsInHand.get)
- if maxKey == 'wild':
- return random.choice(('r', 'g', 'b', 'y'))
- else:
- return maxKey
-
- def getCardByValue(self, cardList, *values):
- for card in cardList:
- if card.getValue() in values:
- return card
-
- def getAllCardsByValue(self, cardList, *values):
- cards = []
- for card in cardList:
- if card.getValue() in values:
- cards.append(card)
- return cards
-
- def getCardByColor(self, cardList, *colors):
- for card in cardList:
- if card.getColor() in colors:
- return card
-
- def getBestColor(self, cardList):
- bestColor = None
- bestColorNum = 0
- for card in cardList:
- color = card.getColor()
- if self.colorsInHand[color] > bestColorNum:
- bestColor = color
- bestColorNum = self.colorsInHand[color]
- return bestColor
-
-
-class Card():
- '''
- 'suit' (string) : Card's Color (rgby)
- 'rank' (string) : Card's Value (0-9, R, X, W, +2, +4)
- '''
- # 11 = reverse, 12 = +2
- # 0-9, X, R, W, +2, +4
- # '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'X', 'R', '+2', '+4', 'W'
- green_dict = {'0':g0, '1':g1, '2':g2, '3':g3, '4':g4, '5':g5, '6':g6, '7':g7, '8':g8, '9':g9, 'X':g10, 'R':g11, '+2':g12, '+4':plusfourgreen, 'W':wildgreen}
- red_dict = {'0':r0, '1':r1, '2':r2, '3':r3, '4':r4, '5':r5, '6':r6, '7':r7, '8':r8, '9':r9, 'X':r10, 'R':r11, '+2':r12, '+4':plusfourred, 'W':wildred}
- blue_dict = {'0':b0, '1':b1, '2':b2, '3':b3, '4':b4, '5':b5, '6':b6, '7':b7, '8':b8, '9':b9, 'X':b10, 'R':b11, '+2':b12, '+4':plusfourblue, 'W':wildblue}
- yellow_dict = {'0':y0, '1':y1, '2':y2, '3':y3, '4':y4, '5':y5, '6':y6, '7':y7, '8':y8, '9':y9, 'X':y10, 'R':y11, '+2':y12, '+4':plusfouryellow, 'W':wildyellow}
- green_cards = [g0, g1, g2, g3, g4, g5, g6, g7, g8, g9, g10, g11, g12 ]
- red_cards = [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12 ]
- blue_cards = [b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12 ]
- yellow_cards = [y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12 ]
- wild_card = wild
-
-
- colors = {
- 'red': '\033[91m',
- 'green': '\033[92m',
- 'yellow': '\033[93m',
- 'blue': '\033[94m',
- 'purple': '\033[95m',
- 'cyan': '\033[96m',
- 'white': '\033[97m',
- 'wild': '',
- 'dwild': '',
- 'dred': '\033[31m',
- 'dgreen': '\033[32m',
- 'dyellow': '\033[33m',
- 'dblue': '\033[34m',
- 'dpurple': '\033[35m',
- 'dcyan': '\033[36m',
- 'dwhite': '\033[37m',
- }
-
- idMap = {
- 'red': 'R', 'blue': 'B', 'green': 'G', 'yellow': 'Y', 'wild': 'W',
- '0': '0', '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9',
- '+2': '+', 'R': 'R', 'W': 'W', '+4': '$', 'X': 'X'
- }
-
-
- def __init__(self, color, value):
- '''Initializes Uno Card w/ Color and Value.'''
- self.wild = False # Is wild card?
- self.zero = False
- self.cardID = '{}{}'.format(self.idMap[color], self.idMap[value])
- self.setColor(color)
- self.setValue(value)
- self.setPoints(value)
-
- #############################################
-
- ### -\/- Retrieve Card Information -\/- ###
-
- def __repr__(self):
- return "{},{}".format(self.color, self.value)
-
- def getBigNum(self, reverse, reverseSeed=0):
- '''Returns list of strings to draw card's value on the pile.'''
- return ''
-
- def getColor(self):
- '''Returns card's color.'''
- return self.color
-
- def getColorCode(self):
- '''Returns card's color code.'''
- return self.colorCode
-
- def getValue(self):
- '''Returns card's value.'''
- return self.value
-
- def getPoints(self):
- '''Returns card's point value.'''
- return self.points
-
- def getRow(self, rowNum, hide=False):
- return
-
- #############################################
-
- ### -\/- Set Card Information -\/- ###
-
- def setColor(self, color):
- '''Sets Card's color and escape code.'''
- if color == 'blue':
- self.color = 'blue'
- self.colorCode = self.colors['blue']
- self.colorCodeDark = self.colors['dblue']
- elif color == 'red':
- self.color = 'red'
- self.colorCode = self.colors['red']
- self.colorCodeDark = self.colors['dred']
- elif color == 'yellow':
- self.color = 'yellow'
- self.colorCode = self.colors['yellow']
- self.colorCodeDark = self.colors['dyellow']
- elif color == 'green':
- self.color = 'green'
- self.colorCode = self.colors['green']
- self.colorCodeDark = self.colors['dgreen']
- elif color == 'wild': # No color modification
- self.wild = True
- self.color = 'wild'
- self.colorCodeDark = self.colors['dwild']
- self.colorCode = self.colors['wild']
-
- def setValue(self, value):
- if value in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'X', 'R', '+2', '+4', 'W'):
- self.value = value
- self.displaySpace = ' '
- if len(value) == 2:
- self.displaySpace = ''
- if value == '0':
- self.zero = True
-
- def setPoints(self, value):
- if value in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'):
- self.points = int(value)
- elif value in ("W", "+4"):
- self.points = 50
- else:
- self.points = 20
-
- #############################################
-
- ### -\/- Wild Card Methods -\/- ###
-
- def changeColor(self, color):
- '''Changes Card's Color, Intended for Wild Cards.'''
- self.setColor(color)
-
- def isWild(self):
- '''Returns if card is a wild card.'''
- return self.wild
-
- def isZero(self):
- return self.zero
-
-
-class Match():
- elementsInit = {
- ### Names (final) ###
- 'P1Name': ' ', 'P2Name': ' ', 'P3Name': ' ', 'P4Name': ' ',
- ### Card Values ###
- 'P1Cards': ' ', 'P2Cards': ' ', 'P3Cards': ' ', 'P4Cards': ' ',
- ### Turn Colors / Hand###
- 'P1Turn': '', 'P2Turn': '', 'P3Turn': '', 'P4Turn': '',
- 'HName': '\t\t', 'HVisual': '', 'Hand': '',
- ### Deck ###
- 'DNum': '', 'Deck': ['', '', '', '', '', '', '', '', ''],
- 'PostDNum': '',
- ### Pile ###
- 'uHeader': '\t\t\t\t', 'uMiddle': ' ', 'uLower': ' ',
- 'oHeader': '\t\t\t',
- 'oMiddle': ['\t\t\t', '\t\t\t', '\t\t\t', '\t\t\t', '\t\t\t', '\t\t\t', '\t\t\t', '\t\t\t'],
- ### Messages ###
- 'Console': '', 'Error': ''
- }
-
- speeds = {'slow': 2, 'normal': 1, 'fast': 0}
-
- window = None
-
- def __init__(self, gs):
- ### Decks ###
- self.deck = Deck(True)
- self.pile = Deck(False)
-
- ### Player Information ###
- self.players = gs.players
- self.turnList = []
- self.handTitles = {'play1': '', 'play2': '', 'play3': '', 'play4': ''}
-
- ### Carry Information ###
- self.displayEffects = gs.displayEffects
- self.hideComputerHands = gs.hideComputerHands
- self.zeroChange = gs.zeroChange
- self.computerSpeed = self.speeds[gs.computerSpeed]
- self.simulation = gs.computerSimulation
-
- ### Data ###
- self.handPosition = 0 # For hand displays
- self.drawAmount = 0 # Used for force draws
- self.passes = 0 # Keep track of consecutive passes for emergency color change
- self.passMax = 0 # Max passes before color change
- self.turn = '' # Current turn
- self.event = '' # Wild, Reverse, Skip, etc
- self.wildColorChange = '' # Specifies color to change wild card to
- self.currentColor = '' # Current color
- self.currentValue = '' # Current value
- self.winnerID = '' # ID of Player who Won
- self.reverse = False # Is turn order reversed
- self.turnComplete = False # Is turn complete
- self.matchComplete = False # Is the Game over?
- self.matchAbort = False # Did the match conclude without a winner?
- self.forcedWild = False # Force change wild
-
- self.max_cards_displayed = 0
- self.previous_card = None
- ### Initialize Names / Cards / Deck (Assuming New Game) ###
- self.elements = dict(self.elementsInit)
-
- keyStringName = 'P{}Name'
- keyStringCards = 'P{}Cards'
-
- for i in self.players:
- self.elements[keyStringName.format(i[-1])] = self.players[i].getName() + (
- ' ' * (11 - len(self.players[i].getName())))
- self.elements[keyStringCards.format(i[-1])] = ' ' + (
- ' ' * (3 - len(str(self.players[i].getCardNum())))) + str(
- self.players[i].getCardNum()) + ' Cards'
-
- self.elements['DNum'] = len(self.deck)
-
- if len(str(len(self.deck))) < 2:
- self.elements['PostDNum'] = '\t'
-
- j = 8
- for i in range(int(math.ceil(len(self.deck) / 12))):
- self.elements['Deck'][j] = '='
- j -= 1
-
- for key in GameSettings.playerIdentities:
- try:
- self.buildHandString(key)
- self.turnList += [key]
- except KeyError:
- pass
-
- self.passMax = len(self.turnList)
- # ----------------------------------------- Create the GUI window -----------------------------------------
- sg.SetOptions(background_color='black', element_background_color='black', text_color='white', border_width=0)
- Card = lambda image_data, key: sg.Button('', image_data=image_data, image_subsample=4, image_size=(60, 80), button_color=('white', 'black'), key=key)
- CardBig = lambda image_data: sg.Button(button_text='', image_data=image_data, image_subsample=1, image_size=(200, 300),
- button_color=('white', 'black'), pad=(0, 0))
- CardBig2 = lambda image_data: sg.Image(data=image_data, size=(100, 300), pad=(0, 0), background_color='black')
-
- Elem = lambda key: Match.window.Element(key)
- T = lambda text, key=None, font='Helvetica 16', **kwargs: sg.T(text, key=key, font=font, **kwargs )
-
- MyButton = lambda text, size=(6, 1), font='Helvetica 14', **kwargs: sg.Button(text, size=size, font=font, button_color=('white', 'green3'), **kwargs)
- OvalButton = lambda text, image_data, **kwargs: sg.Button(text, image_data=image_data, font='Helvetica 14', button_color=('white', 'black'), **kwargs)
-
- col_players = [
- [OvalButton('Quit', greenbutton, key='_QUIT_', visible=False)],
- [T('Player', '_P1_', text_color=yellow_color)],
- [T('Cards', '_C1_', text_color=yellow_color)],
- [T(' ' * 15)],
- [T('Player', '_P2_', text_color=red_color)],
- [T('Cards', '_C2_', text_color=red_color)],
- [T(' ' * 15,'_S3_', visible=False,)],
- [T('Player', '_P3_', visible=False)],
- [T('Cards', '_C3_', visible=False)],
- [T(' ' * 15, '_S4_', visible=False,)],
- [T('Player', '_P4_', visible=False)],
- [T('Cards', '_C4_', visible=False)],]
-
- col_cards_left = [
- [OvalButton('Draw', redbutton, key='_DRAW_')],
- [T(' '), Card(back, '_DRAW_')],
- [T('0 Cards Left', font='Helvetica 14', key='_CARDS_LEFT_')],
- [OvalButton('Pass', bluebutton, key='_PASS_')],]
-
- NUM_COLS = 10 # how many cards shown across bottom in 1 row
- NUM_ROWS = 4
- cards = []
- for j in range(NUM_ROWS):
- cards.append([sg.T(' ' * 5,font=('Any 5'))] + [Card(None, j*NUM_COLS+i) for i in range(NUM_COLS)])
-
- layout = [
- [sg.Column(col_cards_left),
- sg.Graph((400, 360), (0, 300), (400, 0), key='_GRAPH_', ),
- sg.Column(col_players)],
- [T(' ')],
- [T(' ')],
- [sg.T('', justification='center', size=(55, 2), font='Helvetica 18', key='_MESSAGES_')],
- [sg.T('', justification='center', size=(55, 2), font='Helvetica 18', key='_MESSAGES2_')],
- ]
- layout += cards
-
- Match.window = sg.Window('Uno',
- background_color='black',
- use_default_focus=False,
- disable_close=True,
- ).Layout(layout).Finalize()
-
- def clearShell(self):
- os.system('cls' if os.name == 'nt' else 'clear')
-
- def begin(self):
- self.elements['Console'] = 'Beginning Game, Click Draw to Deal.'
- self.drawScreen()
- self.enterBreak()
- self.eventDealCards()
- self.turn = random.choice(self.turnList)
- self.elements['Console'] = 'First turn will be {}. Click Draw'.format(self.players[self.turn].getName())
- self.drawScreen(True)
- self.enterBreak()
- self.placeCard()
- self.elements['P{}Turn'.format(self.turn[-1])] = '\033[93m'
- if self.event == 'wild':
- self.eventWildCard()
- elif self.event == 'reverse':
- self.eventReverse()
-
- def end(self, gs):
- if not self.matchAbort:
- points = 0
- self.elements['P{}Turn'.format(self.turn[-1])] = ''
- self.elements['Console'] = '{} Wins! Click Draw to Begin Point Tally'.format(
- self.players[self.winnerID].getName())
- self.drawScreen()
- self.enterBreak()
-
- for identity in self.turnList:
- if identity != self.winnerID:
- self.turn = identity
- self.elements['HName'] = self.handTitles[self.turn]
- self.elements['P{}Turn'.format(self.turn[-1])] = '\033[93m'
- while self.players[identity].getCardNum() > 0:
- card = self.players[identity].removeCard(0)
- points += card.getPoints()
- self.elements['Console'] = '{} Won {} Points!'.format(self.players[self.winnerID].getName(),
- points)
-
- keyStringCards = 'P{}Cards'
- self.elements[keyStringCards.format(identity[-1])] = ' ' + (
- ' ' * (3 - len(str(self.players[identity].getCardNum())))) + str(
- self.players[identity].getCardNum()) + ' Cards'
- self.players[identity].maxScroll = math.ceil((self.players[identity].getCardNum() / 10) - 1)
- if self.handPosition > self.players[identity].maxScroll:
- self.handPosition -= 1
- self.buildHandVisual(identity)
-
- if self.displayEffects and not self.simulation:
- self.drawScreen()
- time.sleep(.1)
- self.elements['P{}Turn'.format(self.turn[-1])] = ''
-
- self.players[self.winnerID].addPoints(points)
- self.elements['Console'] = '{} Won {} Points! Click Draw'.format(self.players[self.winnerID].getName(),
- points)
- self.drawScreen()
- self.enterBreak()
-
- gs.clearStaging()
- for identity in self.turnList:
- self.players[identity].discardHand()
- gs.addPlayer(self.players[identity])
- return gs
-
- def adjustCardAmount(self, playerID):
- keyStringCards = 'P{}Cards'
- self.elements[keyStringCards.format(playerID[-1])] = ' ' + (
- ' ' * (3 - len(str(self.players[playerID].getCardNum())))) + str(
- self.players[playerID].getCardNum()) + ' Cards'
- self.players[playerID].maxScroll = math.ceil((self.players[playerID].getCardNum() / 10) - 1)
- if self.handPosition > self.players[playerID].maxScroll:
- self.handPosition -= 1
- self.buildHandVisual(playerID)
-
- def buildHandString(self, playerID):
- playerName = self.players[playerID].getName()
- if len(playerName) < 9:
- self.handTitles[playerID] = "{}'s Hand\t".format(self.players[playerID].getName())
- else:
- self.handTitles[playerID] = "{}'s Hand".format(self.players[playerID].getName())
-
- def buildHandVisual(self, playerID):
- string = '['
- for i in range(self.players[playerID].maxScroll + 1):
- if i == self.handPosition:
- string += '|'
- else:
- string += '-'
- string += ']'
- self.elements['HVisual'] = string
-
- def checkInput(self, playerInput):
- if playerInput == '':
- return {'valid': False, 'entry': playerInput}
- if playerInput.isnumeric():
- if int(playerInput) + (10 * self.handPosition) < self.players[self.turn].getCardNum():
- return {'valid': True, 'entry': str(int(playerInput) + (10 * self.handPosition)), 'type': 'card'}
- else:
- self.elements['Error'] = '{} is not a card.'.format(playerInput)
- return {'valid': False, 'entry': playerInput}
- else:
- playerInput = playerInput.lower()[0]
- if playerInput in ['<', '>', 'u', 'd', 'p', 'q', 's']:
- return {'valid': True, 'entry': playerInput}
- else:
- self.elements['Error'] = '{} is not a valid selection.'.format(playerInput)
- return {'valid': False, 'entry': playerInput}
-
- def checkColorInput(self, playerInput):
- if playerInput == '':
- return {'valid': False, 'entry': playerInput}
- playerInput = str(playerInput).lower()[0]
- if playerInput[0] == 'b':
- return {'valid': True, 'entry': 'blue'}
- elif playerInput[0] == 'r':
- return {'valid': True, 'entry': 'red'}
- elif playerInput[0] == 'g':
- return {'valid': True, 'entry': 'green'}
- elif playerInput[0] == 'y':
- return {'valid': True, 'entry': 'yellow'}
- return {'valid': False, 'entry': playerInput}
-
- def eventDealCards(self):
- if self.displayEffects and not self.simulation:
- self.elements['Console'] = 'Dealing Cards...'
- for i in ('play1', 'play2', 'play3', 'play4'):
- if i in self.players:
- for j in range(7):
- self.dealCard(i)
-
- def eventReverse(self):
- if self.displayEffects and not self.simulation:
- hide = False
- if self.players[self.turn].getType() == "Computer":
- hide = self.hideComputerHands
- self.elements['Console'] = "Reverse Card Played! Reversing Turn Order.".format(
- self.players[self.turn].getName())
- self.drawScreen(hide)
- time.sleep(1)
- for i in range(10):
- cardBigNums = self.pile[0].getBigNum(self.reverse, i)
- self.elements['oMiddle'] = cardBigNums
- self.drawScreen(hide)
- if self.displayEffects and not self.simulation:
- time.sleep(.1)
- cardBigNums = self.pile[0].getBigNum(self.reverse, 9)
- self.elements['oMiddle'] = cardBigNums
- self.reverse = not self.reverse
- self.event = ''
-
- def eventSkip(self):
- if self.displayEffects and not self.simulation:
- hide = False
- if self.players[self.turn].getType() == "Computer":
- hide = self.hideComputerHands
- self.elements['Console'] = "Skip Card Placed! Skipping {}'s Turn.".format(self.players[self.turn].getName())
- self.drawScreen(hide)
- time.sleep(1)
- for i in range(2):
- self.elements['P{}Turn'.format(self.turn[-1])] = '\033[91m'
- self.drawScreen(hide)
- time.sleep(.3)
- self.elements['P{}Turn'.format(self.turn[-1])] = ''
- self.drawScreen(hide)
- time.sleep(.3)
- self.turnComplete = True
- self.event = ''
-
- def eventWildCard(self):
- hide = False
- if not self.forcedWild:
- if self.players[self.turn].getType() == 'Human':
- self.elements['Console'] = 'Wild Card! Specifiy a Color'
- self.elements['Error'] = 'Specifiy A Color'
- self.drawScreen()
- while True:
- layout=[[sg.T('Wild Card! Specify a Color')],
- [sg.Combo(('Blue', 'Red', 'Green', 'Yellow'))],
- [sg.OK()]]
- window = sg.Window('Wild Card').Layout(layout)
-
- event, values = window.Read()
- try:
- playerInput = values[0].lower()[0]
- except:
- playerInput = ' '
- # playerInput = str(input("Color Change: "))
- checked = self.checkColorInput(playerInput)
- if checked['valid']:
- window.Close()
- break
- else:
- hide = self.hideComputerHands
- checked = self.checkColorInput(self.players[self.turn].getWildColor())
- self.wildColorChange = checked['entry']
- else:
- self.wildColorChange = self.checkColorInput(random.choice(('r', 'b', 'g', 'y')))['entry']
- self.forcedWild = False
- self.currentColor = self.wildColorChange
- self.elements['Error'] = ""
- if self.displayEffects and not self.simulation:
- self.elements['Console'] = 'Wild Card! Changing Color.'
- seed = 1
- for i in range(10):
- if seed > 4:
- seed = 1
- self.drawScreen(hide, wildSeed=seed)
- time.sleep(.1)
- seed += 1
- self.pile[0].changeColor(self.wildColorChange)
- self.wildColorChange = ''
- cardBigNums = self.pile[0].getBigNum(self.reverse)
- self.elements['oHeader'] = '{}\u2666\u2666\u2666=========\u2666\u2666\u2666\033[0m\t'.format(
- self.pile[0].getColorCode())
- self.elements['oMiddle'] = cardBigNums
- self.event = ''
-
- def eventDraw(self):
- self.players[self.turn].addForceDraw(self.drawAmount)
- self.drawAmount = 0
- self.event = ''
-
- def dealCard(self, playerID):
-
- card = self.deck.draw()
- self.players[playerID].addCard(card)
-
- ### Adjust Hand Visual ###
- self.players[playerID].maxScroll = math.ceil((self.players[playerID].getCardNum() / 10) - 1)
- self.handPosition = self.players[playerID].maxScroll
- self.buildHandVisual(playerID)
-
- ### Adjust Player Tile ###
- keyStringCards = 'P{}Cards'
- self.elements[keyStringCards.format(playerID[-1])] = ' ' + (
- ' ' * (3 - len(str(self.players[playerID].getCardNum())))) + str(
- self.players[playerID].getCardNum()) + ' Cards'
-
- ### Adjust Deck ###
- self.elements['DNum'] = len(self.deck)
- if len(str(len(self.deck))) < 2:
- self.elements['PostDNum'] = '\t'
- j = 8
- self.elements['Deck'] = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
- for i in range(math.ceil(len(self.deck) / 12)):
- self.elements['Deck'][j] = '='
- j -= 1
-
- def placeCard(self, card=None):
- if card == None:
- ### Used At Beginning For First Card ###
- card = self.deck.draw()
- self.elements['DNum'] = len(self.deck)
-
- cardColor = card.getColorCode()
- cardBigNums = card.getBigNum(self.reverse)
-
- self.currentColor = card.getColor()
- self.currentValue = card.getValue()
-
- self.pile.insert(card)
- self.elements['oHeader'] = '{}\u2666\u2666\u2666=========\u2666\u2666\u2666\033[0m\t'.format(cardColor)
- self.elements['oMiddle'] = cardBigNums
-
- if len(self.pile) > 1:
- previousCard = self.pile[1]
- previousCardColor = previousCard.getColorCode()
- self.elements['uHeader'] = '{} \u2666\u2666\u2666=========\u2666\u2666\u2666\033[0m\t\t'.format(
- previousCardColor)
- self.elements['uMiddle'] = '{}| |\033[0m'.format(previousCardColor)
- self.elements['uLower'] = '{}\u2666\u2666\u2666\033[0m'.format(previousCardColor)
-
- if self.currentColor == 'wild':
- self.event = 'wild'
-
- if self.currentValue == 'X':
- self.event = 'skip'
- elif self.currentValue == 'R':
- if len(self.players) > 2:
- self.event = 'reverse'
- else:
- self.event = 'skip'
- elif self.currentValue == '+4':
- self.drawAmount = 4
- elif self.currentValue == '+2':
- self.drawAmount = 2
- self.passes = 0
-
- def extractCard(self, playerID, index):
- card = self.players[playerID].removeCard(index)
- if self.players[playerID].getCardNum() == 0:
- self.matchComplete = True
- self.winnerID = self.turn
- self.adjustCardAmount(playerID)
- return card
-
- def enterBreak(self):
- if not self.simulation:
- while True:
- if Match.window is None:
- break
- event, values = Match.window.Read()
- if event == '_DRAW_':
- break
- if event == '_QUIT_':
- if sg.PopupYesNo('Do you really want to quit?') == 'Yes':
- self.matchAbort = True
- self.matchComplete = True
-
- def nextTurn(self):
- self.turnComplete = False
- self.handPosition = 0
- turnType = self.players[self.turn].getType()
- self.players[self.turn].beginTurn()
- ### Prepare Hand Visuals ###
-
- self.elements['HName'] = self.handTitles[self.turn]
- self.buildHandVisual(self.turn)
-
- if self.event == 'skip':
- self.eventSkip()
- elif self.drawAmount > 0:
- self.eventDraw()
- #-------------- Main GUI event loop ---------------
- while not self.turnComplete:
- if turnType == 'Human':
- self.players[self.turn].getLegalCards(self.currentColor, self.currentValue, self.zeroChange)
- if len(self.deck) > 0:
- self.elements['Console'] = 'Select a card or Draw'
- else:
- self.players[self.turn].removeForceDraw()
- self.elements['Console'] = 'Select a card, Draw, or Pass'
- if self.players[self.turn].getForceDraws() > 0:
- self.elements['Error'] = 'Draw Card Played! Draw {} cards.'.format(
- self.players[self.turn].getForceDraws())
- self.drawScreen()
- ## GUI INPUT
- event, values = Match.window.Read()
-
- playerInput = str(event)
- if event == '_DRAW_':
- playerInput = 'd'
- elif event == '_PASS_':
- playerInput = 's'
- elif event == '_QUIT_':
- if sg.PopupYesNo('Do you really want to quit?') == 'Yes':
- self.matchAbort = True
- self.matchComplete = True
- break
-
- if playerInput == '<':
- self.handPosition -= 1
- if self.handPosition == -1:
- self.handPosition = self.players[self.turn].maxScroll
- self.buildHandVisual(self.turn)
- elif playerInput == '>':
- self.handPosition += 1
- if self.handPosition > self.players[self.turn].maxScroll:
- self.handPosition = 0
- self.buildHandVisual(self.turn)
- elif playerInput == 'd':
- if len(self.deck) > 0:
- self.elements['Error'] = ''
- self.dealCard(self.turn)
- else:
- self.elements['Error'] = "Cannot Draw. Deck is Empty"
- elif playerInput == 'p':
- pauseOutput = self.pauseScreen()
- if pauseOutput == 'quit':
- self.matchComplete = True
- self.turnComplete = True
- self.winnerID = 'play1'
- self.matchAbort = True
- elif playerInput == 's':
- if len(self.deck) > 0:
- self.elements['Error'] = "Cannot pass until Deck is empty."
- elif len(self.players[self.turn].getAllValidCards()) > 0:
- self.elements['Error'] = "Cannot pass while having playable cards."
- else:
- self.turnComplete = True
- self.passes += 1
- if self.passes == self.passMax:
- self.forcedWild = True
- self.event = 'wild'
- self.passes = 0
- elif playerInput.isnumeric():
- if self.players[self.turn].getForceDraws() == 0:
- cardCheck = self.players[self.turn].checkCard(playerInput)
- if cardCheck in self.players[self.turn].getAllValidCards():
- card = self.extractCard(self.turn, playerInput)
- self.placeCard(card)
- self.elements['Error'] = ""
- self.turnComplete = True
- else:
- self.elements['Error'] = "Card Doesn't Match The Color {} or Value {}!".format(
- self.currentColor, self.currentValue)
- else:
- pass
-
- elif turnType == 'Computer':
- event, values = Match.window.Read(timeout=0)
- if event == '_QUIT_':
- if sg.PopupYesNo('Do you really want to quit?') == 'Yes':
- self.matchAbort = True
- self.matchComplete = True
- break
-
- self.elements['Console'] = '{}\'s Turn'.format(self.players[self.turn].getName())
- self.drawScreen(self.hideComputerHands)
- if not self.simulation:
- time.sleep(self.computerSpeed)
- # str(input())
- while (True):
- if self.displayEffects and not self.simulation:
- time.sleep(.2)
- if self.players[self.turn].getForceDraws() > 0 and len(self.deck) > 0:
- cardIndex = 'd'
- else:
- cardIndex = self.players[self.turn].think(self)
- if cardIndex.isnumeric():
- card = self.extractCard(self.turn, int(cardIndex))
- if card.getColor() != self.currentColor:
- self.resetDrawBool()
- self.placeCard(card)
- self.turnComplete = True
- break
- else:
- if cardIndex == 'd':
- if len(self.deck) > 0:
- self.dealCard(self.turn)
- self.drawScreen(self.hideComputerHands)
- else:
- self.turnComplete = True
- self.players[self.turn].removeForceDraw()
- self.passes += 1
- if self.passes == self.passMax:
- self.forcedWild = True
- self.event = 'wild'
- self.passes = 0
- break
-
- ### DECODE INPUT ###
- if self.event == 'reverse':
- self.eventReverse()
- elif self.event == 'wild':
- self.eventWildCard()
-
- # Clear Current Turn
- self.elements['P{}Turn'.format(self.turn[-1])] = ''
- # Prepare Next Turn
- self.turn = self.getNextTurn()
- self.elements['P{}Turn'.format(self.turn[-1])] = '\033[93m'
-
- # --------------------------------------- drawScreen ---------------------------------------
- def drawScreen(self, hide=False, wildSeed=0):
- if Match.window is None:
- return
- def get_card_graphic(color, value):
- dict = Card.red_dict
- if color == 'red':
- dict = Card.red_dict
- if color == 'blue':
- dict = Card.blue_dict
- if color == 'green':
- dict = Card.green_dict
- if color == 'yellow':
- dict = Card.yellow_dict
- card_graphic = dict[value] if value != '' else Card.wild_card
- return card_graphic
-
- Update = lambda key, value, **kwargs: Match.window.Element(key).Update(value, **kwargs)
- elem = lambda key: self.elements[key]
- if self.simulation:
- return
-
- currentTurn = self.turn
- if currentTurn == '':
- currentTurn = self.turnList[-1]
- hide = True
-
- Update('_MESSAGES_', elem('Console'))
- Update('_MESSAGES2_', elem('Error'))
- Update('_P1_', elem('P1Name'))
- Update('_C1_', elem('P1Cards'))
- Update('_P2_', elem('P2Name'))
- Update('_C2_', elem('P2Cards'))
- if elem('P3Name') != ' ':
- Update('_P3_', elem('P3Name'), visible=True)
- Update('_C3_', elem('P3Cards'), visible=True)
- Update('_S3_', None, visible=True)
- if elem('P4Name') != ' ':
- Update('_P4_', elem('P4Name'), visible=True)
- Update('_C4_', elem('P4Cards'), visible=True)
- Update('_S4_',None, visible=True)
- Update('_CARDS_LEFT_', '{} Cards Left'.format(elem('DNum')))
- # hand = self.players[currentTurn].hand
- hand = self.players[currentTurn].hand.hand
- i=0
- for i, card in enumerate(hand):
- if card.value == 'W':
- card_graphic = wild
- elif card.value == '+4':
- card_graphic = plusfour
- else:
- card_graphic = get_card_graphic(card.color, card.value)
- if hide:
- card_graphic = back
-
- Update(i, '', image_data=card_graphic, image_subsample=4, image_size=(60, 80), visible=True)
- else:
- for x in range(i+1, self.max_cards_displayed+1):
- Update(x, '', image_data=blank, image_subsample=4, image_size=(60, 80), visible=True)
- self.max_cards_displayed = max(i, self.max_cards_displayed)
-
- card_graphic = get_card_graphic(self.currentColor, self.currentValue)
-
- if self.previous_card is not None:
- Match.window.Element('_GRAPH_').DrawImage(data=self.previous_card, location=(0,0))
- Match.window.Element('_GRAPH_').DrawImage(data=card_graphic, location=(100,40))
-
- self.previous_card = card_graphic
-
- Match.window.Refresh()
-
- return ''
-
- def pauseScreen(self):
- return
-
- def isComplete(self):
- return self.matchComplete
-
- def next(self):
- self.turn = self.getNextTurn()
-
- def getNextTurn(self, forceReverse=False):
- if forceReverse:
- reverse = not self.reverse
- else:
- reverse = self.reverse
- currentIndex = self.turnList.index(self.turn)
- if not reverse:
- if (currentIndex + 1) == len(self.turnList):
- return self.turnList[0]
- else:
- return self.turnList[currentIndex + 1]
- else:
- if currentIndex == 0:
- return self.turnList[len(self.turnList) - 1]
- else:
- return self.turnList[currentIndex - 1]
-
- def getPlayer(self, playerID):
- return self.players[playerID]
-
- def resetDrawBool(self):
- for identity in self.players:
- self.players[identity].drew = False
-
-def clearShell():
- os.system('cls' if os.name == 'nt' else 'clear')
-
-def mainMenu():
- gs = GameSettings()
-
- PLAYER_TYPE_HUMAN = 'HUMAN'
- PLAYER_TYPE_COMPUTER = 'COMPUTER'
- computer_names = ('Watson', 'SkyNet', 'Hal', 'Metal Gear')
- layout = [
- [sg.Button('1 - No Player', size=(20,5), key=0, pad=(1,1)),
- sg.Button('2 - No Player', size=(20, 5), key=1, pad=(1,1), disabled=True)],
- [sg.Button('3 - No Player', size=(20, 5), key=2, pad=(1,1), disabled=True),
- sg.Button('4 - No Player', size=(20, 5), key=3, pad=(1,1), disabled=True)],
- [sg.Text('Enter player 1 (none) name', key='_TXT_'), sg.Input(key='_IN_', do_not_clear=True, size=(22,1)), sg.Button('Set name')],
- [sg.Button('Begin'), sg.Button('Settings')],]
-
- Elem = lambda key: window.Element(key)
-
- button_states = [0] * 4
- player_names = [''] * 4
- player_types = [None] * 4
-
- window = sg.Window('Uno Setup', border_depth=0).Layout(layout)
-
- current_player = 0
- while True: # Event Loop
- event, values = window.Read()
- # print(event, values)
- if event is None or event == 'Exit':
- break
- if event == 'Begin':
- window.Hide()
- gs.finalizePlayers()
- # ---------------------- START THE MATCH ----------------------
- gs = playMatch(gs)
- for i, id in enumerate(gs.players):
- player = gs.players[id]
- window.Element(i).Update('{} - {}\n{} points'.format(i+1, player.name, player.points))
- window.UnHide()
- window.Refresh()
- elif event == 'Settings':
- layout2 = [[sg.Checkbox('Hide computer hands', key='_HIDE_', default=True)],
- [sg.T('Computer speed')],
- [sg.Radio('Fast', 1, key='_FAST_')],
- [sg.Radio('Normal', 1, key='_NORMAL_', default=True)],
- [sg.Radio('Slow', 1, key='_SLOW_')],
- [sg.OK(), sg.Cancel()]
- ]
- win2 = sg.Window('Settings').Layout(layout2)
- ev, vals = win2.Read()
- win2.Close()
- if ev == 'OK':
- if vals['_NORMAL_']:
- gs.computerspeed = 'normal'
- if vals['_FAST_']:
- gs.computerspeed = 'slow'
- if vals['_SLOW_']:
- gs.computerspeed = 'slow'
- gs.hideComputerHands = vals['_HIDE_']
- elif event == 'Set name':
- if values['_IN_'] in player_names:
- sg.Popup('Duplicate - Cannot set to same as other players name')
- else:
- Elem(current_player).Update(str(current_player+1) + ' - '+values['_IN_'])
- player_names[current_player] = values['_IN_']
- Elem(current_player + (current_player < 3)).Update(disabled=False)
- if player_types[current_player] == PLAYER_TYPE_HUMAN:
- addPlayer(gs, values['_IN_'])
- else:
- addComputer(gs, values['_IN_'])
- elif 0 <= event <= 3:
- current_player = event
- state = button_states[event] = button_states[event]+1 if button_states[event] < 2 else 0
- Elem('_TXT_').Update('Enter Player %s (%s) Name'%(str(current_player+1), ('human', 'computer', 'none')[state-1]))
- if state == 1:
- Elem('_IN_').SetFocus()
- Elem('_IN_').Update('Player name', select=True)
- Elem(event).Update(str(event+1) +' - Player')
- player_types[event] = PLAYER_TYPE_HUMAN
- elif state == 2:
- Elem('_IN_').SetFocus()
- Elem('_IN_').Update(computer_names[event], select=True)
- Elem(event).Update(str(event+1) + ' - ' + computer_names[event])
- player_types[event] = PLAYER_TYPE_COMPUTER
- elif state == 0:
- Elem(event).Update(str(event+1) +' - No Player')
- Elem('_IN_').SetFocus()
- Elem('_IN_').Update('', select=True)
- for i in range(event):
- pass
- player_types[event] = None
- player_names[event] = ''
- for i in range(event+1,4):
- Elem(i).Update(text='%s - No player'%i, disabled=True)
- player_names[i] = ''
- try:
- gs.removePlayer(i)
- except:
- pass
- window.Close()
- return player_names
-
-
-def playMatch(gs):
- m = Match(gs)
- m.begin()
- Match.window.Element('_QUIT_').Update(visible=True)
- while (not m.isComplete()):
- m.nextTurn()
- gs = m.end(gs)
- Match.window.Close()
- Match.window = None
- return gs
-
-
-def addPlayer(gs, name):
- p = Player(name)
- gs.addPlayer(p)
- gs.mainMenuError = ""
-
- return gs
-
-
-def addComputer(gs, name):
- c = ComputerPlayer(name)
- gs.addPlayer(c)
-
- return gs
-
-
-
-if __name__ == "__main__":
- mainMenu()
-
diff --git a/DemoPrograms old/Demo_Window_Disappear.py b/DemoPrograms old/Demo_Window_Disappear.py
deleted file mode 100644
index 603fdb0d..00000000
--- a/DemoPrograms old/Demo_Window_Disappear.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-
-layout = [[ sg.Text('My Window') ],
- [ sg.Button('Disappear')]]
-
-window = sg.Window('My window').Layout(layout)
-
-while True:
- event, values = window.Read()
- if event is None:
- break
- if event == 'Disappear':
- window.Disappear()
- sg.Popup('Click OK to make window reappear')
- window.Reappear()
-
diff --git a/DemoPrograms old/Demo_YouTube_Intro.py b/DemoPrograms old/Demo_YouTube_Intro.py
deleted file mode 100644
index 88c2690f..00000000
--- a/DemoPrograms old/Demo_YouTube_Intro.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import PySimpleGUI as sg
-
-layout = [[sg.Text('What is your name?')],
- [sg.InputText()],
- [sg.Button('Ok')]]
-
-window = sg.Window('Title of Window').Layout(layout)
-
-event, values = window.Read()
-
-sg.Popup('Hello {}'.format(values[0]))
\ No newline at end of file
diff --git a/DemoPrograms old/Demo_Youtube-dl_Frontend.py b/DemoPrograms old/Demo_Youtube-dl_Frontend.py
deleted file mode 100644
index c2503b85..00000000
--- a/DemoPrograms old/Demo_Youtube-dl_Frontend.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env python
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import subprocess
-
-"""
-Simple wrapper for youtube-dl.exe.
-Paste the youtube link into the GUI. The GUI link is queried when you click Get List.
-Get List will populate the pulldown list with the language options available for the video.
-Choose the language to download and click Download
-"""
-
-def DownloadSubtitlesGUI():
- sg.ChangeLookAndFeel('Dark')
-
- combobox = sg.InputCombo(values=['',], size=(10,1), key='lang')
- layout = [
- [sg.Text('Subtitle Grabber', size=(40, 1), font=('Any 15'))],
- [sg.T('YouTube Link'),sg.In(default_text='',size=(60,1), key='link', do_not_clear=True) ],
- [sg.Output(size=(90,20), font='Courier 12')],
- [sg.Button('Get List')],
- [sg.T('Language Code'), combobox, sg.Button('Download')],
- [sg.Button('Exit', button_color=('white', 'firebrick3'))]
- ]
-
- window = sg.Window('Subtitle Grabber launcher', text_justification='r', default_element_size=(15,1), font=('Any 14')).Layout(layout)
-
- # ---===--- Loop taking in user input and using it to query HowDoI --- #
- while True:
- event, values = window.Read()
- if event in ('Exit', None):
- break # exit button clicked
- link = values['link']
- if event == 'Get List':
- print('Getting list of subtitles....')
- window.Refresh()
- command = [f'C:\\Python\\Anaconda3\\Scripts\\youtube-dl.exe --list-subs {link}',]
- output = ExecuteCommandSubprocess(command, wait=True, quiet=True)
- lang_list = [o[:5].rstrip() for o in output.split('\n') if 'vtt' in o]
- lang_list = sorted(lang_list)
- combobox.Update(values=lang_list)
- print('Done')
-
- elif event == 'Download':
- lang = values['lang'] or 'en'
- print(f'Downloading subtitle for {lang}...')
- window.Refresh()
- command = [f'C:\\Python\\Anaconda3\\Scripts\\youtube-dl.exe --sub-lang {lang} --write-sub {link}',]
- print(ExecuteCommandSubprocess(command, wait=True, quiet=False))
- print('Done')
-
-
-def ExecuteCommandSubprocess(command, wait=False, quiet=True, *args):
- try:
- sp = subprocess.Popen([command,*args], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- if wait:
- out, err = sp.communicate()
- if not quiet:
- if out:
- print(out.decode("utf-8"))
- if err:
- print(err.decode("utf-8"))
- except Exception as e:
- print('Exception encountered running command ', e)
- return ''
-
- return (out.decode('utf-8'))
-
-
-if __name__ == '__main__':
- DownloadSubtitlesGUI()
-
diff --git a/DemoPrograms old/Demo_psutil_Kill_Processes.py b/DemoPrograms old/Demo_psutil_Kill_Processes.py
deleted file mode 100644
index 95be7052..00000000
--- a/DemoPrograms old/Demo_psutil_Kill_Processes.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python
-import sys
-import sys
-if sys.version_info[0] >= 3:
- import PySimpleGUI as sg
-else:
- import PySimpleGUI27 as sg
-import os
-import signal
-import psutil
-import operator
-
-CONFIRM_KILLS = False
-
-"""
- Utility to show running processes, CPU usage and provides way to kill processes.
- Based on psutil package that is easily installed using pip
-"""
-
-def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
- timeout=None, on_terminate=None):
- """Kill a process tree (including grandchildren) with signal
- "sig" and return a (gone, still_alive) tuple.
- "on_terminate", if specified, is a callabck function which is
- called as soon as a child terminates.
- """
- if pid == os.getpid():
- raise RuntimeError("I refuse to kill myself")
- parent = psutil.Process(pid)
- children = parent.children(recursive=True)
- if include_parent:
- children.append(parent)
- for p in children:
- p.send_signal(sig)
- gone, alive = psutil.wait_procs(children, timeout=timeout,
- callback=on_terminate)
- return (gone, alive)
-
-
-def show_list_by_name(window):
- psutil.cpu_percent(interval=.1)
- procs = psutil.process_iter()
- all_procs = [[proc.cpu_percent(), proc.name(), proc.pid] for proc in procs]
- sorted_by_cpu_procs = sorted(all_procs, key=operator.itemgetter(1), reverse=False)
- display_list = []
- for process in sorted_by_cpu_procs:
- display_list.append('{:5d} {:5.2f} {}\n'.format(process[2], process[0] / 10, process[1]))
- window.FindElement('_processes_').Update(display_list)
- return display_list
-
-def main():
-
- # ---------------- Create Form ----------------
- # sg.ChangeLookAndFeel('Topanga')
-
- layout = [[sg.Text('Process Killer - Choose one or more processes',
- size=(45,1), font=('Helvetica', 15), text_color='red')],
- [sg.Listbox(values=[' '], size=(50, 30), select_mode=sg.SELECT_MODE_EXTENDED, font=('Courier', 12), key='_processes_')],
- [sg.Text('Click refresh once or twice.. once for list, second to get CPU usage')],
- [sg.T('Filter by typing name', font='ANY 14'), sg.In(size=(15,1), font='any 14', key='_filter_')],
- [sg.Button('Sort by Name', ),
- sg.Button('Sort by % CPU', button_color=('white', 'DarkOrange2')),
- sg.Button('Kill', button_color=('white','red'), bind_return_key=True),
- sg.Exit(button_color=('white', 'sea green'))]]
-
- window = sg.Window('Process Killer',
- keep_on_top=True,
- auto_size_buttons=False,
- default_button_element_size=(12,1),
- return_keyboard_events=True,
- ).Layout(layout).Finalize()
-
-
- display_list = show_list_by_name(window)
- # ---------------- main loop ----------------
- while (True):
- # --------- Read and update window --------
- event, values = window.Read()
- if event is None or event == 'Exit':
- break
-
- # skip mouse, control key and shift key events entirely
- if 'Mouse' in event or 'Control' in event or 'Shift' in event:
- continue
-
- # --------- Do Button Operations --------
- if event == 'Sort by Name':
- display_list = show_list_by_name(window)
- # psutil.cpu_percent(interval=.1)
- # procs = psutil.process_iter()
- # all_procs = [[proc.cpu_percent(), proc.name(), proc.pid] for proc in procs]
- # sorted_by_cpu_procs = sorted(all_procs, key=operator.itemgetter(1), reverse=False)
- # display_list = []
- # for process in sorted_by_cpu_procs:
- # display_list.append('{:5d} {:5.2f} {}\n'.format(process[2], process[0]/10, process[1]))
- # window.FindElement('_processes_').Update(display_list)
- elif event == 'Kill':
- processes_to_kill = values['_processes_']
- for proc in processes_to_kill:
- pid = int(proc[0:5])
- # if sg.PopupYesNo('About to kill {} {}'.format(pid, proc[12:]), keep_on_top=True) == 'Yes':
- try:
- kill_proc_tree(pid=pid)
- except:
- sg.PopupNoWait('Error killing process', auto_close_duration=1, auto_close=True)
- elif event == 'Sort by % CPU':
- psutil.cpu_percent(interval=.1)
- procs = psutil.process_iter()
- all_procs = [[proc.cpu_percent(), proc.name(), proc.pid] for proc in procs]
- sorted_by_cpu_procs = sorted(all_procs, key=operator.itemgetter(0), reverse=True)
- display_list = []
- for process in sorted_by_cpu_procs:
- display_list.append('{:5d} {:5.2f} {}\n'.format(process[2], process[0]/10, process[1]))
- window.FindElement('_processes_').Update(display_list)
- else: # was a typed character
- if display_list is not None:
- new_output = []
- for line in display_list:
- if values['_filter_'] in line.lower():
- new_output.append(line)
- window.FindElement('_processes_').Update(new_output)
-
-
-if __name__ == "__main__":
- main()
- sys.exit(0)
\ No newline at end of file
diff --git a/DemoPrograms old/TutorialCPUUtilization.py b/DemoPrograms old/TutorialCPUUtilization.py
deleted file mode 100644
index 003115d7..00000000
--- a/DemoPrograms old/TutorialCPUUtilization.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import PySimpleGUI as sg
-import psutil
-
-layout = [ [sg.Text('CPU Utilization')] ,
- [sg.Text('', size=(8,2), font='Helvetica 20', justification='center', key='_text_')],
- [sg.Exit()]]
-
-window = sg.Window('CPU Meter').Layout(layout)
-
-while True:
- button, values = window.ReadNonBlocking()
-
- if button == 'Exit' or values is None:
- break
-
- cpu_percent = psutil.cpu_percent(interval=1)
-
- window.FindElement('_text_').Update(f'CPU {cpu_percent:02.0f}%')
diff --git a/DemoPrograms old/default_icon.ico b/DemoPrograms old/default_icon.ico
deleted file mode 100644
index 1a41525e..00000000
Binary files a/DemoPrograms old/default_icon.ico and /dev/null differ
diff --git a/DemoPrograms old/ping.py b/DemoPrograms old/ping.py
deleted file mode 100644
index 3df8635d..00000000
--- a/DemoPrograms old/ping.py
+++ /dev/null
@@ -1,572 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-"""
- A pure python ping implementation using raw sockets.
-
- (This is Python 3 port of https://github.com/jedie/python-ping)
- (Tested and working with python 2.7, should work with 2.6+)
-
- Note that ICMP messages can only be sent from processes running as root
- (in Windows, you must run this script as 'Administrator').
-
- Derived from ping.c distributed in Linux's netkit. That code is
- copyright (c) 1989 by The Regents of the University of California.
- That code is in turn derived from code written by Mike Muuss of the
- US Army Ballistic Research Laboratory in December, 1983 and
- placed in the public domain. They have my thanks.
-
- Bugs are naturally mine. I'd be glad to hear about them. There are
- certainly word - size dependencies here.
-
- Copyright (c) Matthew Dixon Cowles, .
- Distributable under the terms of the GNU General Public License
- version 2. Provided with no warranties of any sort.
-
- Original Version from Matthew Dixon Cowles:
- -> ftp://ftp.visi.com/users/mdc/ping.py
-
- Rewrite by Jens Diemer:
- -> http://www.python-forum.de/post-69122.html#69122
-
- Rewrite by George Notaras:
- -> http://www.g-loaded.eu/2009/10/30/python-ping/
-
- Enhancements by Martin Falatic:
- -> http://www.falatic.com/index.php/39/pinging-with-python
-
- Enhancements and fixes by Georgi Kolev:
- -> http://github.com/jedie/python-ping/
-
- Bug fix by Andrejs Rozitis:
- -> http://github.com/rozitis/python-ping/
-
- Revision history
- ~~~~~~~~~~~~~~~~
- May 1, 2014
- -----------
- Little modifications by Mohammad Emami
- - Added Python 3 support. For now this project will just support
- python 3.x
- - Tested with python 3.3
- - version was upped to 0.6
-
- March 19, 2013
- --------------
- * Fixing bug to prevent divide by 0 during run-time.
-
- January 26, 2012
- ----------------
- * Fixing BUG #4 - competability with python 2.x [tested with 2.7]
- - Packet data building is different for 2.x and 3.x.
- 'cose of the string/bytes difference.
- * Fixing BUG #10 - the multiple resolv issue.
- - When pinging domain names insted of hosts (for exmaple google.com)
- you can get different IP every time you try to resolv it, we should
- resolv the host only once and stick to that IP.
- * Fixing BUGs #3 #10 - Doing hostname resolv only once.
- * Fixing BUG #14 - Removing all 'global' stuff.
- - You should not use globul! Its bad for you...and its not thread safe!
- * Fix - forcing the use of different times on linux/windows for
- more accurate mesurments. (time.time - linux/ time.clock - windows)
- * Adding quiet_ping function - This way we'll be able to use this script
- as external lib.
- * Changing default timeout to 3s. (1second is not enought)
- * Switching data syze to packet size. It's easyer for the user to ignore the
- fact that the packet headr is 8b and the datasize 64 will make packet with
- size 72.
-
- October 12, 2011
- --------------
- Merged updates from the main project
- -> https://github.com/jedie/python-ping
-
- September 12, 2011
- --------------
- Bugfixes + cleanup by Jens Diemer
- Tested with Ubuntu + Windows 7
-
- September 6, 2011
- --------------
- Cleanup by Martin Falatic. Restored lost comments and docs. Improved
- functionality: constant time between pings, internal times consistently
- use milliseconds. Clarified annotations (e.g., in the checksum routine).
- Using unsigned data in IP & ICMP header pack/unpack unless otherwise
- necessary. Signal handling. Ping-style output formatting and stats.
-
- August 3, 2011
- --------------
- Ported to py3k by Zach Ware. Mostly done by 2to3; also minor changes to
- deal with bytes vs. string changes (no more ord() in checksum() because
- >source_string< is actually bytes, added .encode() to data in
- send_one_ping()). That's about it.
-
- March 11, 2010
- --------------
- changes by Samuel Stauffer:
- - replaced time.clock with default_timer which is set to
- time.clock on windows and time.time on other systems.
-
- November 8, 2009
- ----------------
- Improved compatibility with GNU/Linux systems.
-
- Fixes by:
- * George Notaras -- http://www.g-loaded.eu
- Reported by:
- * Chris Hallman -- http://cdhallman.blogspot.com
-
- Changes in this release:
- - Re-use time.time() instead of time.clock(). The 2007 implementation
- worked only under Microsoft Windows. Failed on GNU/Linux.
- time.clock() behaves differently under the two OSes[1].
-
- [1] http://docs.python.org/library/time.html#time.clock
-
- May 30, 2007
- ------------
- little rewrite by Jens Diemer:
- - change socket asterisk import to a normal import
- - replace time.time() with time.clock()
- - delete "return None" (or change to "return" only)
- - in checksum() rename "str" to "source_string"
-
- December 4, 2000
- ----------------
- Changed the struct.pack() calls to pack the checksum and ID as
- unsigned. My thanks to Jerome Poincheval for the fix.
-
- November 22, 1997
- -----------------
- Initial hack. Doesn't do much, but rather than try to guess
- what features I (or others) will want in the future, I've only
- put in what I need now.
-
- December 16, 1997
- -----------------
- For some reason, the checksum bytes are in the wrong order when
- this is run under Solaris 2.X for SPARC but it works right under
- Linux x86. Since I don't know just what's wrong, I'll swap the
- bytes always and then do an htons().
-
- ===========================================================================
- IP header info from RFC791
- -> http://tools.ietf.org/html/rfc791)
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |Version| IHL |Type of Service| Total Length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Identification |Flags| Fragment Offset |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Time to Live | Protocol | Header Checksum |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Source Address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Destination Address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Options | Padding |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
- ===========================================================================
- ICMP Echo / Echo Reply Message header info from RFC792
- -> http://tools.ietf.org/html/rfc792
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Code | Checksum |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Identifier | Sequence Number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Data ...
- +-+-+-+-+-
-
- ===========================================================================
- ICMP parameter info:
- -> http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml
-
- ===========================================================================
- An example of ping's typical output:
-
- PING heise.de (193.99.144.80): 56 data bytes
- 64 bytes from 193.99.144.80: icmp_seq=0 ttl=240 time=127 ms
- 64 bytes from 193.99.144.80: icmp_seq=1 ttl=240 time=127 ms
- 64 bytes from 193.99.144.80: icmp_seq=2 ttl=240 time=126 ms
- 64 bytes from 193.99.144.80: icmp_seq=3 ttl=240 time=126 ms
- 64 bytes from 193.99.144.80: icmp_seq=4 ttl=240 time=127 ms
-
- ----heise.de PING Statistics----
- 5 packets transmitted, 5 packets received, 0.0% packet loss
- round-trip (ms) min/avg/max/med = 126/127/127/127
-
- ===========================================================================
-"""
-
-#=============================================================================#
-import argparse
-import os, sys, socket, struct, select, time, signal
-
-__description__ = 'A pure python ICMP ping implementation using raw sockets.'
-
-if sys.platform == "win32":
- # On Windows, the best timer is time.clock()
- default_timer = time.clock
-else:
- # On most other platforms the best timer is time.time()
- default_timer = time.time
-
-NUM_PACKETS = 3
-PACKET_SIZE = 64
-WAIT_TIMEOUT = 3.0
-
-#=============================================================================#
-# ICMP parameters
-
-ICMP_ECHOREPLY = 0 # Echo reply (per RFC792)
-ICMP_ECHO = 8 # Echo request (per RFC792)
-ICMP_MAX_RECV = 2048 # Max size of incoming buffer
-
-MAX_SLEEP = 1000
-
-class MyStats:
- thisIP = "0.0.0.0"
- pktsSent = 0
- pktsRcvd = 0
- minTime = 999999999
- maxTime = 0
- totTime = 0
- avrgTime = 0
- fracLoss = 1.0
-
-myStats = MyStats # NOT Used globally anymore.
-
-#=============================================================================#
-def checksum(source_string):
- """
- A port of the functionality of in_cksum() from ping.c
- Ideally this would act on the string as a series of 16-bit ints (host
- packed), but this works.
- Network data is big-endian, hosts are typically little-endian
- """
- countTo = (int(len(source_string)/2))*2
- sum = 0
- count = 0
-
- # Handle bytes in pairs (decoding as short ints)
- loByte = 0
- hiByte = 0
- while count < countTo:
- if (sys.byteorder == "little"):
- loByte = source_string[count]
- hiByte = source_string[count + 1]
- else:
- loByte = source_string[count + 1]
- hiByte = source_string[count]
- try: # For Python3
- sum = sum + (hiByte * 256 + loByte)
- except: # For Python2
- sum = sum + (ord(hiByte) * 256 + ord(loByte))
- count += 2
-
- # Handle last byte if applicable (odd-number of bytes)
- # Endianness should be irrelevant in this case
- if countTo < len(source_string): # Check for odd length
- loByte = source_string[len(source_string)-1]
- try: # For Python3
- sum += loByte
- except: # For Python2
- sum += ord(loByte)
-
- sum &= 0xffffffff # Truncate sum to 32 bits (a variance from ping.c, which
- # uses signed ints, but overflow is unlikely in ping)
-
- sum = (sum >> 16) + (sum & 0xffff) # Add high 16 bits to low 16 bits
- sum += (sum >> 16) # Add carry from above (if any)
- answer = ~sum & 0xffff # Invert and truncate to 16 bits
- answer = socket.htons(answer)
-
- return answer
-
-#=============================================================================#
-def do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size, quiet = False):
- """
- Returns either the delay (in ms) or None on timeout.
- """
- delay = None
-
- try: # One could use UDP here, but it's obscure
- mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
- except socket.error as e:
- print("failed. (socket error: '%s')" % e.args[1])
- raise # raise the original error
-
- my_ID = os.getpid() & 0xFFFF
-
- sentTime = send_one_ping(mySocket, destIP, my_ID, mySeqNumber, packet_size)
- if sentTime == None:
- mySocket.close()
- return delay
-
- myStats.pktsSent += 1
-
- recvTime, dataSize, iphSrcIP, icmpSeqNumber, iphTTL = receive_one_ping(mySocket, my_ID, timeout)
-
- mySocket.close()
-
- if recvTime:
- delay = (recvTime-sentTime)*1000
- if not quiet:
- print("%d bytes from %s: icmp_seq=%d ttl=%d time=%d ms" % (
- dataSize, socket.inet_ntoa(struct.pack("!I", iphSrcIP)), icmpSeqNumber, iphTTL, delay)
- )
- myStats.pktsRcvd += 1
- myStats.totTime += delay
- if myStats.minTime > delay:
- myStats.minTime = delay
- if myStats.maxTime < delay:
- myStats.maxTime = delay
- else:
- delay = None
- print("Request timed out.")
-
- return delay
-
-#=============================================================================#
-def send_one_ping(mySocket, destIP, myID, mySeqNumber, packet_size):
- """
- Send one ping to the given >destIP<.
- """
- #destIP = socket.gethostbyname(destIP)
-
- # Header is type (8), code (8), checksum (16), id (16), sequence (16)
- # (packet_size - 8) - Remove header size from packet size
- myChecksum = 0
-
- # Make a dummy heder with a 0 checksum.
- header = struct.pack(
- "!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber
- )
-
- padBytes = []
- startVal = 0x42
- # 'cose of the string/byte changes in python 2/3 we have
- # to build the data differnely for different version
- # or it will make packets with unexpected size.
- if sys.version[:1] == '2':
- bytes = struct.calcsize("d")
- data = ((packet_size - 8) - bytes) * "Q"
- data = struct.pack("d", default_timer()) + data
- else:
- for i in range(startVal, startVal + (packet_size-8)):
- padBytes += [(i & 0xff)] # Keep chars in the 0-255 range
- #data = bytes(padBytes)
- data = bytearray(padBytes)
-
-
- # Calculate the checksum on the data and the dummy header.
- myChecksum = checksum(header + data) # Checksum is in network order
-
- # Now that we have the right checksum, we put that in. It's just easier
- # to make up a new header than to stuff it into the dummy.
- header = struct.pack(
- "!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber
- )
-
- packet = header + data
-
- sendTime = default_timer()
-
- try:
- mySocket.sendto(packet, (destIP, 1)) # Port number is irrelevant for ICMP
- except socket.error as e:
- print("General failure (%s)" % (e.args[1]))
- return
-
- return sendTime
-
-#=============================================================================#
-def receive_one_ping(mySocket, myID, timeout):
- """
- Receive the ping from the socket. Timeout = in ms
- """
- timeLeft = timeout/1000
-
- while True: # Loop while waiting for packet or timeout
- startedSelect = default_timer()
- whatReady = select.select([mySocket], [], [], timeLeft)
- howLongInSelect = (default_timer() - startedSelect)
- if whatReady[0] == []: # Timeout
- return None, 0, 0, 0, 0
-
- timeReceived = default_timer()
-
- recPacket, addr = mySocket.recvfrom(ICMP_MAX_RECV)
-
- ipHeader = recPacket[:20]
- iphVersion, iphTypeOfSvc, iphLength, \
- iphID, iphFlags, iphTTL, iphProtocol, \
- iphChecksum, iphSrcIP, iphDestIP = struct.unpack(
- "!BBHHHBBHII", ipHeader
- )
-
- icmpHeader = recPacket[20:28]
- icmpType, icmpCode, icmpChecksum, \
- icmpPacketID, icmpSeqNumber = struct.unpack(
- "!BBHHH", icmpHeader
- )
-
- if icmpPacketID == myID: # Our packet
- dataSize = len(recPacket) - 28
- #print (len(recPacket.encode()))
- return timeReceived, (dataSize+8), iphSrcIP, icmpSeqNumber, iphTTL
-
- timeLeft = timeLeft - howLongInSelect
- if timeLeft <= 0:
- return None, 0, 0, 0, 0
-
-#=============================================================================#
-def dump_stats(myStats):
- """
- Show stats when pings are done
- """
- print("\n----%s PYTHON PING Statistics----" % (myStats.thisIP))
-
- if myStats.pktsSent > 0:
- myStats.fracLoss = (myStats.pktsSent - myStats.pktsRcvd)/myStats.pktsSent
-
- print("%d packets transmitted, %d packets received, %0.1f%% packet loss" % (
- myStats.pktsSent, myStats.pktsRcvd, 100.0 * myStats.fracLoss
- ))
-
- if myStats.pktsRcvd > 0:
- print("round-trip (ms) min/avg/max = %d/%0.1f/%d" % (
- myStats.minTime, myStats.totTime/myStats.pktsRcvd, myStats.maxTime
- ))
-
- print("")
- return
-
-#=============================================================================#
-def signal_handler(signum, frame):
- """
- Handle exit via signals
- """
- dump_stats()
- print("\n(Terminated with signal %d)\n" % (signum))
- sys.exit(0)
-
-#=============================================================================#
-def verbose_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS,
- packet_size=PACKET_SIZE, path_finder=False):
- """
- Send >count< ping to >destIP< with the given >timeout< and display
- the result.
- """
- signal.signal(signal.SIGINT, signal_handler) # Handle Ctrl-C
- if hasattr(signal, "SIGBREAK"):
- # Handle Ctrl-Break e.g. under Windows
- signal.signal(signal.SIGBREAK, signal_handler)
-
- myStats = MyStats() # Reset the stats
-
- mySeqNumber = 0 # Starting value
-
- try:
- destIP = socket.gethostbyname(hostname)
- print("\nPYTHON PING %s (%s): %d data bytes" % (hostname, destIP, packet_size))
- except socket.gaierror as e:
- print("\nPYTHON PING: Unknown host: %s (%s)" % (hostname, e.args[1]))
- print()
- return
-
- myStats.thisIP = destIP
-
- for i in range(count):
- delay = do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size)
-
- if delay == None:
- delay = 0
-
- mySeqNumber += 1
-
- # Pause for the remainder of the MAX_SLEEP period (if applicable)
- if (MAX_SLEEP > delay):
- time.sleep((MAX_SLEEP - delay)/1000)
-
- dump_stats(myStats)
-
-#=============================================================================#
-def quiet_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS,
- packet_size=PACKET_SIZE, path_finder=False):
- """
- Same as verbose_ping, but the results are returned as tuple
- """
- myStats = MyStats() # Reset the stats
- mySeqNumber = 0 # Starting value
-
- try:
- destIP = socket.gethostbyname(hostname)
- except socket.gaierror as e:
- return False
-
- myStats.thisIP = destIP
-
- # This will send packet that we dont care about 0.5 seconds before it starts
- # acrutally pinging. This is needed in big MAN/LAN networks where you sometimes
- # loose the first packet. (while the switches find the way... :/ )
- if path_finder:
- fakeStats = MyStats()
- do_one(fakeStats, destIP, hostname, timeout,
- mySeqNumber, packet_size, quiet=True)
- time.sleep(0.5)
-
- for i in range(count):
- delay = do_one(myStats, destIP, hostname, timeout,
- mySeqNumber, packet_size, quiet=True)
-
- if delay == None:
- delay = 0
-
- mySeqNumber += 1
-
- # Pause for the remainder of the MAX_SLEEP period (if applicable)
- if (MAX_SLEEP > delay):
- time.sleep((MAX_SLEEP - delay)/1000)
-
- if myStats.pktsSent > 0:
- myStats.fracLoss = (myStats.pktsSent - myStats.pktsRcvd)/myStats.pktsSent
- if myStats.pktsRcvd > 0:
- myStats.avrgTime = myStats.totTime / myStats.pktsRcvd
-
- # return tuple(max_rtt, min_rtt, avrg_rtt, percent_lost)
- return myStats.maxTime, myStats.minTime, myStats.avrgTime, myStats.fracLoss
-
-#=============================================================================#
-def main():
-
- parser = argparse.ArgumentParser(description=__description__)
- parser.add_argument('-q', '--quiet', action='store_true',
- help='quiet output')
- parser.add_argument('-c', '--count', type=int, default=NUM_PACKETS,
- help=('number of packets to be sent '
- '(default: %(default)s)'))
- parser.add_argument('-W', '--timeout', type=float, default=WAIT_TIMEOUT,
- help=('time to wait for a response in seoncds '
- '(default: %(default)s)'))
- parser.add_argument('-s', '--packet-size', type=int, default=PACKET_SIZE,
- help=('number of data bytes to be sent '
- '(default: %(default)s)'))
- parser. add_argument('destination')
- # args = parser.parse_args()
-
- ping = verbose_ping
- # if args.quiet:
- # ping = quiet_ping
- ping('Google.com', timeout=1000)
- # ping(args.destination, timeout=args.timeout*1000, count=args.count,
- # packet_size=args.packet_size)
-
-if __name__ == '__main__':
- main()