From 62e0ccc005824c9bc0b67206bcb5fd29f87c3b02 Mon Sep 17 00:00:00 2001 From: Zev Lee <60147316+zevlee@users.noreply.github.com> Date: Fri, 27 May 2022 19:57:44 -0500 Subject: [PATCH] Improve UI and add default setting --- VERSION | 2 +- gui/menu.xml | 8 +- lib/about.py | 30 + lib/application.py | 599 ++---------------- lib/fn.py | 30 - lib/password.py | 65 +- lib/preferences.py | 215 +++++++ lib/utils.py | 65 ++ lib/window.py | 291 +++++++++ .../1024x1024/apps/me.zevlee.Passphraser.png | Bin 0 -> 37261 bytes .../128x128/apps/me.zevlee.Passphraser.png | Bin 0 -> 3613 bytes .../16x16/apps/me.zevlee.Passphraser.png | Bin 0 -> 878 bytes .../24x24/apps/me.zevlee.Passphraser.png | Bin 0 -> 1080 bytes .../256x256/apps/me.zevlee.Passphraser.png | Bin 0 -> 7957 bytes .../32x32/apps/me.zevlee.Passphraser.png | Bin 0 -> 1196 bytes .../48x48/apps/me.zevlee.Passphraser.png | Bin 0 -> 1612 bytes .../512x512/apps/me.zevlee.Passphraser.png | Bin 0 -> 17342 bytes .../64x64/apps/me.zevlee.Passphraser.png | Bin 0 -> 1873 bytes .../72x72/apps/me.zevlee.Passphraser.png | Bin 0 -> 2131 bytes .../scalable/apps/me.zevlee.Passphraser.svg | 0 linux/passphraser.desktop | 2 +- linux/passphraser.spec | 5 +- macos/passphraser.spec | 2 +- me.zevlee.Passphraser.svg | 174 +++++ windows/passphraser.spec | 2 +- 25 files changed, 852 insertions(+), 638 deletions(-) create mode 100644 lib/about.py delete mode 100644 lib/fn.py create mode 100644 lib/preferences.py create mode 100644 lib/utils.py create mode 100644 lib/window.py create mode 100644 linux/icons/hicolor/1024x1024/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/128x128/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/16x16/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/24x24/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/256x256/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/32x32/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/48x48/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/512x512/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/64x64/apps/me.zevlee.Passphraser.png create mode 100644 linux/icons/hicolor/72x72/apps/me.zevlee.Passphraser.png rename passphraser.svg => linux/icons/hicolor/scalable/apps/me.zevlee.Passphraser.svg (100%) create mode 100644 me.zevlee.Passphraser.svg diff --git a/VERSION b/VERSION index 0c62199..0d91a54 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.1 +0.3.0 diff --git a/gui/menu.xml b/gui/menu.xml index a6b3743..ad4b524 100644 --- a/gui/menu.xml +++ b/gui/menu.xml @@ -6,17 +6,13 @@ app.prefs _Preferences - - app.reset - _Reset - app.about _About - app.quit - _Quit + app.reset + _Reset diff --git a/lib/about.py b/lib/about.py new file mode 100644 index 0000000..ffbc838 --- /dev/null +++ b/lib/about.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +from lib.utils import Utils +from os.path import join +from gi import require_versions +require_versions({"Gtk": "3.0"}) +from gi.repository import Gtk +from gi.repository.GdkPixbuf import Pixbuf + + +class About(Gtk.AboutDialog): + + def __init__(self, parent): + super().__init__( + modal=True, + transient_for=parent, + program_name=Utils.NAME, + version=Utils.VERSION, + copyright="Copyright © 2021-2022 Zev Lee", + license_type=Gtk.License.MIT_X11, + website="https://github.com/zevlee/passphraser", + website_label="Homepage" + ) + + # Set up logo + filename = join(Utils.APP_DIR, f"{Utils.ID}.svg") + logo = Pixbuf.new_from_file(filename) + + # Add logo + self.set_logo(logo) diff --git a/lib/application.py b/lib/application.py index 67a1201..eb5035d 100644 --- a/lib/application.py +++ b/lib/application.py @@ -1,578 +1,51 @@ #!/usr/bin/env python3 -from lib.fn import Fn -from lib.password import Password -from os import mkdir, walk -from os.path import dirname, join, exists -from shutil import copyfile -from platform import system -from json import loads, dumps -from gi import require_version -require_version("Gtk", "3.0") +from lib.utils import Utils +from lib.window import Window +from os import mkdir +from os.path import join, exists +from shutil import copytree +from json import dumps +from gi import require_versions +require_versions({"Gtk": "3.0"}) from gi.repository import Gtk, Gio, GLib -from gi.repository.GdkPixbuf import Pixbuf - - -class Header(Gtk.HeaderBar): - - def __init__(self, title, subtitle, version, application, window): - Gtk.HeaderBar.__init__(self) - self.title = title - self.version = version - self.app = application - self.win = window - self.set_title(self.title) - self.set_subtitle(subtitle) - self.set_show_close_button(True) - - # create menu - action = Gio.SimpleAction.new("prefs", None) - action.connect("activate", self.on_prefs) - self.app.add_action(action) - - action = Gio.SimpleAction.new("reset", None) - action.connect("activate", self.win.on_reset) - self.app.add_action(action) - - action = Gio.SimpleAction.new("about", None) - action.connect("activate", self.on_about) - self.app.add_action(action) - - action = Gio.SimpleAction.new("quit", None) - action.connect("activate", self.app.on_quit) - self.app.add_action(action) - - builder = Gtk.Builder.new_from_file( - join(dirname(__file__), "..", "gui", "menu.xml") - ) - menu = builder.get_object("app-menu") - menu_button = Gtk.MenuButton.new() - menu_button.set_image( - Gtk.Image.new_from_icon_name( - "emblem-system-symbolic", - Gtk.IconSize.LARGE_TOOLBAR - ) - ) - menu_button.set_menu_model(menu) - # window decoration layout - if system() == "Darwin": - self.set_decoration_layout("close,minimize,maximize:") - self.pack_start(menu_button) - else: - self.set_decoration_layout(":minimize,maximize,close") - self.pack_end(menu_button) - - def on_prefs(self, action, param): - """ - Open preferences window - """ - prefs = Preferences() - prefs.present() - - def on_about(self, action, param): - """ - Open about dialog window - """ - dialog = Gtk.AboutDialog(modal=True) - dialog.set_position(Gtk.WindowPosition.CENTER) - file = join(dirname(__file__), "..", "passphraser.svg") - logo = Pixbuf.new_from_file(file) - dialog.set_logo(logo) - dialog.set_program_name(self.title) - dialog.set_version(self.version) - dialog.set_copyright("Copyright © 2021-2022 Zev Lee") - license = open(join(dirname(__file__), "..", "LICENSE")).read() - dialog.set_license(license) - dialog.set_wrap_license(True) - dialog.set_website("https://github.com/zevlee/passphraser") - dialog.set_website_label("Homepage") - dialog.present() - - -class Preferences(Gtk.Window): - - def __init__(self): - Gtk.Window.__init__(self) - self.set_icon_from_file( - join(dirname(__file__), "..", "passphraser.svg") - ) - self.set_title("Preferences") - self.set_border_width(40) - self.set_position(Gtk.WindowPosition.CENTER) - self.set_resizable(False) - self.set_modal(True) - self.set_keep_above(True) - - # open stored preferences - with open(join(Fn.conf_dir, "passphraser.json")) as cfg: - self.config = loads(cfg.read()) - cfg.close() - - grid = Gtk.Grid() - grid.set_column_homogeneous(True) - self.add(grid) - grid.set_row_spacing(20) - grid.set_column_spacing(20) - - # list of all symbols - mode_label = Gtk.Label(halign=Gtk.Align.START) - mode_label.set_markup("Included Symbols") - grid.attach(mode_label, 0, 0, 4, 1) - - self.ti = Gtk.CheckButton(label="~") - self.ti.set_active(self.config["~"]) - grid.attach(self.ti, 0, 1, 1, 1) - - self.gr = Gtk.CheckButton(label="`") - self.gr.set_active(self.config["`"]) - grid.attach(self.gr, 1, 1, 1, 1) - - self.ex = Gtk.CheckButton(label="!") - self.ex.set_active(self.config["!"]) - grid.attach(self.ex, 2, 1, 1, 1) - - self.at = Gtk.CheckButton(label="@") - self.at.set_active(self.config["@"]) - grid.attach(self.at, 3, 1, 1, 1) - - self.po = Gtk.CheckButton(label="#") - self.po.set_active(self.config["#"]) - grid.attach(self.po, 0, 2, 1, 1) - - self.do = Gtk.CheckButton(label="$") - self.do.set_active(self.config["$"]) - grid.attach(self.do, 1, 2, 1, 1) - - self.pe = Gtk.CheckButton(label="%") - self.pe.set_active(self.config["%"]) - grid.attach(self.pe, 2, 2, 1, 1) - - self.ca = Gtk.CheckButton(label="^") - self.ca.set_active(self.config["^"]) - grid.attach(self.ca, 3, 2, 1, 1) - - self.am = Gtk.CheckButton(label="&") - self.am.set_active(self.config["&"]) - grid.attach(self.am, 0, 3, 1, 1) - - self.ak = Gtk.CheckButton(label="*") - self.ak.set_active(self.config["*"]) - grid.attach(self.ak, 1, 3, 1, 1) - - self.op = Gtk.CheckButton(label="(") - self.op.set_active(self.config["("]) - grid.attach(self.op, 2, 3, 1, 1) - - self.cp = Gtk.CheckButton(label=")") - self.cp.set_active(self.config[")"]) - grid.attach(self.cp, 3, 3, 1, 1) - - self.un = Gtk.CheckButton(label="_") - self.un.set_active(self.config["_"]) - grid.attach(self.un, 0, 4, 1, 1) - - self.hy = Gtk.CheckButton(label="-") - self.hy.set_active(self.config["-"]) - grid.attach(self.hy, 1, 4, 1, 1) - - self.pl = Gtk.CheckButton(label="+") - self.pl.set_active(self.config["+"]) - grid.attach(self.pl, 2, 4, 1, 1) - - self.eq = Gtk.CheckButton(label="=") - self.eq.set_active(self.config["="]) - grid.attach(self.eq, 3, 4, 1, 1) - - self.oc = Gtk.CheckButton(label="{") - self.oc.set_active(self.config["{"]) - grid.attach(self.oc, 0, 5, 1, 1) - - self.ob = Gtk.CheckButton(label="[") - self.ob.set_active(self.config["["]) - grid.attach(self.ob, 1, 5, 1, 1) - - self.cc = Gtk.CheckButton(label="}") - self.cc.set_active(self.config["}"]) - grid.attach(self.cc, 2, 5, 1, 1) - - self.cb = Gtk.CheckButton(label="]") - self.cb.set_active(self.config["]"]) - grid.attach(self.cb, 3, 5, 1, 1) - - self.vl = Gtk.CheckButton(label="|") - self.vl.set_active(self.config["|"]) - grid.attach(self.vl, 0, 6, 1, 1) - - self.bs = Gtk.CheckButton(label="\\") - self.bs.set_active(self.config["\\"]) - grid.attach(self.bs, 1, 6, 1, 1) - - self.co = Gtk.CheckButton(label=":") - self.co.set_active(self.config[":"]) - grid.attach(self.co, 2, 6, 1, 1) - - self.sc = Gtk.CheckButton(label=";") - self.sc.set_active(self.config[";"]) - grid.attach(self.sc, 3, 6, 1, 1) - - self.dq = Gtk.CheckButton(label="\"") - self.dq.set_active(self.config["\""]) - grid.attach(self.dq, 0, 7, 1, 1) - - self.sq = Gtk.CheckButton(label="'") - self.sq.set_active(self.config["'"]) - grid.attach(self.sq, 1, 7, 1, 1) - - self.lt = Gtk.CheckButton(label="<") - self.lt.set_active(self.config["<"]) - grid.attach(self.lt, 2, 7, 1, 1) - - self.cm = Gtk.CheckButton(label=",") - self.cm.set_active(self.config[","]) - grid.attach(self.cm, 3, 7, 1, 1) - - self.gt = Gtk.CheckButton(label=">") - self.gt.set_active(self.config[">"]) - grid.attach(self.gt, 0, 8, 1, 1) - - self.pd = Gtk.CheckButton(label=".") - self.pd.set_active(self.config["."]) - grid.attach(self.pd, 1, 8, 1, 1) - - self.qu = Gtk.CheckButton(label="?") - self.qu.set_active(self.config["?"]) - grid.attach(self.qu, 2, 8, 1, 1) - - self.fs = Gtk.CheckButton(label="/") - self.fs.set_active(self.config["/"]) - grid.attach(self.fs, 3, 8, 1, 1) - - self.sp = Gtk.CheckButton(label="(space)") - self.sp.set_active(self.config[" "]) - grid.attach(self.sp, 0, 9, 1, 1) - - # all symbol options - self.symbols = [ - self.ti, self.gr, self.ex, self.at, - self.po, self.do, self.pe, self.ca, - self.am, self.ak, self.op, self.cp, - self.un, self.hy, self.pl, self.eq, - self.oc, self.ob, self.cc, self.cb, - self.vl, self.bs, self.co, self.sc, - self.dq, self.sq, self.lt, self.cm, - self.gt, self.pd, self.qu, self.fs, - self.sp - ] - - deselect_button = Gtk.Button(label="Deselect All") - deselect_button.connect("clicked", self.on_deselect_clicked) - grid.attach(deselect_button, 0, 10, 2, 1) - - select_button = Gtk.Button(label="Select All") - select_button.connect("clicked", self.on_select_clicked) - grid.attach(select_button, 2, 10, 2, 1) - - adv_label = Gtk.Label(halign=Gtk.Align.START) - adv_label.set_markup("Advanced") - grid.attach(adv_label, 0, 11, 4, 1) - - self.dbg = Gtk.CheckButton(label="Debug Mode") - self.dbg.set_active(self.config["dbg"]) - grid.attach(self.dbg, 0, 12, 4, 1) - - cancel_button = Gtk.Button(label="Cancel") - cancel_button.connect("clicked", self.on_cancel_clicked) - grid.attach(cancel_button, 0, 13, 2, 1) - - select_button = Gtk.Button(label="Save") - select_button.connect("clicked", self.on_save_clicked) - grid.attach(select_button, 2, 13, 2, 1) - - self.show_all() - - def on_select_clicked(self, button): - """ - Set all symbol options to true - """ - for sym in self.symbols: - sym.set_active(True) - - def on_deselect_clicked(self, button): - """ - Set all symbol options to false - """ - for sym in self.symbols: - sym.set_active(False) - - def on_cancel_clicked(self, button): - """ - Close preferences dialog without saving - """ - self.destroy() - - def on_save_clicked(self, button): - """ - Save preferences then close dialog - """ - with open(join(Fn.conf_dir, "passphraser.json"), "w") as cfg: - for k, v in zip(Fn.symbols, self.symbols): - self.config[k] = v.get_active() - self.config["dbg"] = self.dbg.get_active() - cfg.write(dumps(self.config)) - cfg.close() - self.destroy() - - -class AppWindow(Gtk.ApplicationWindow): - - def __init__(self, app): - Gtk.Window.__init__(self, application=app) - self.app = app - self.set_icon_from_file( - join(dirname(__file__), "..", "passphraser.svg") - ) - self.set_border_width(40) - self.set_position(Gtk.WindowPosition.CENTER) - self.set_resizable(True) - self.set_titlebar( - Header( - title="Passphraser", - subtitle="Phrase-Based Password Generator", - version="Version " + Fn.version, - application=app, - window=self - ) - ) - - with open(join(Fn.conf_dir, "passphraser.json"), "r") as cfg: - self.config = loads(cfg.read()) - cfg.close() - - grid = Gtk.Grid() - self.add(grid) - grid.set_row_spacing(20) - grid.set_column_spacing(20) - - lst_label = Gtk.Label(halign=Gtk.Align.START) - lst_label.set_markup("Word list") - grid.attach(lst_label, 0, 0, 1, 1) - - choose_list = Gtk.Button.new_with_mnemonic("_Choose Word List") - choose_list.connect("clicked", self.on_file_clicked) - grid.attach(choose_list, 1, 0, 1, 1) - - self.lst = Gtk.Entry() - self.lst.set_text(self.config["lst"]) - grid.attach(self.lst, 0, 1, 2, 1) - - min_label = Gtk.Label(halign=Gtk.Align.START) - min_label.set_markup("Minimum word length") - grid.attach(min_label, 0, 2, 1, 1) - - self.min = Gtk.Entry() - self.min.set_text(str(self.config["min"])) - grid.attach(self.min, 1, 2, 1, 1) - - max_label = Gtk.Label(halign=Gtk.Align.START) - max_label.set_markup("Maximum word length") - grid.attach(max_label, 0, 3, 1, 1) - - self.max = Gtk.Entry() - self.max.set_text(str(self.config["max"])) - grid.attach(self.max, 1, 3, 1, 1) - - wrd_label = Gtk.Label(halign=Gtk.Align.START) - wrd_label.set_markup("Number of words") - grid.attach(wrd_label, 0, 4, 1, 1) - - self.wrd = Gtk.Entry() - self.wrd.set_text(str(self.config["wrd"])) - grid.attach(self.wrd, 1, 4, 1, 1) - - sep_label = Gtk.Label(halign=Gtk.Align.START) - sep_label.set_markup("Separator") - grid.attach(sep_label, 0, 5, 1, 1) - - self.sep = Gtk.Entry() - self.sep.set_text(self.config["sep"]) - grid.attach(self.sep, 1, 5, 1, 1) - - self.cap = Gtk.CheckButton(label="Capitalize") - self.cap.set_active(self.config["cap"]) - grid.attach(self.cap, 0, 6, 2, 1) - - self.num = Gtk.CheckButton(label="Add number") - self.num.set_active(self.config["num"]) - grid.attach(self.num, 0, 7, 2, 1) - - self.sym = Gtk.CheckButton(label="Add symbol") - self.sym.set_active(self.config["sym"]) - grid.attach(self.sym, 0, 8, 2, 1) - - gen_pwd = Gtk.Button(label="Generate Password") - gen_pwd.connect("clicked", self.on_gen_pwd_clicked) - grid.attach(gen_pwd, 0, 9, 2, 6) - - self.pwd_label = Gtk.Entry() - self.pwd_label.set_editable(False) - self.pwd_label.set_hexpand(True) - self.pwd_label.set_vexpand(True) - grid.attach(self.pwd_label, 0, 15, 2, 1) - - self.pwd_len = Gtk.Label(halign=Gtk.Align.START) - grid.attach(self.pwd_len, 0, 16, 2, 1) - - self.show_all() - - def on_file_clicked(self, widget): - """ - Open dialog to choose word list - """ - dialog = Gtk.FileChooserDialog( - title="Choose the word list", - parent=None, - action=Gtk.FileChooserAction.OPEN - ) - dialog.add_buttons( - Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, - Gtk.STOCK_OPEN, Gtk.ResponseType.OK, - ) - dialog.set_current_folder(join(Fn.conf_dir, "wordlists")) - dialog.set_position(Gtk.WindowPosition.CENTER) - response = dialog.run() - if response == Gtk.ResponseType.OK: - file = dialog.get_filename() - self.lst.set_text(file) - dialog.destroy() - - def gen_pwd(self): - """ - Gather parameters then generate the password - """ - lst = self.lst.get_text() - min = int(self.min.get_text()) - max = int(self.max.get_text()) - wrd = int(self.wrd.get_text()) - sep = self.sep.get_text() - cap = self.cap.get_active() - num = self.num.get_active() - sym = self.sym.get_active() - pwd = Password(lst, min, max, wrd, sep, cap, num, sym) - gen_pwd, pwd_len = pwd.password() - self.pwd_label.set_text(gen_pwd) - self.pwd_len.set_text(f"Length: {str(pwd_len)}") - with open(join(Fn.conf_dir, "passphraser.json"), "r") as cfg: - self.config = loads(cfg.read()) - cfg.close() - for k, v in zip( - ["lst", "min", "max", "wrd", "sep", "cap", "num", "sym"], - [lst, min, max, wrd, sep, cap, num, sym] - ): - self.config[k] = v - with open(join(Fn.conf_dir, "passphraser.json"), "w") as cfg: - cfg.write(dumps(self.config)) - cfg.close() - - def on_gen_pwd_clicked(self, button): - """ - When generate password is clicked, call `gen_pwd` - """ - config = loads(open(join(Fn.conf_dir, "passphraser.json"), "r").read()) - if not config["dbg"]: - try: - self.gen_pwd() - except FileNotFoundError: - dialog = Gtk.MessageDialog( - transient_for=None, - flags=0, - message_type=Gtk.MessageType.INFO, - buttons=Gtk.ButtonsType.OK, - text="File not found" - ) - dialog.set_position(Gtk.WindowPosition.CENTER) - dialog.run() - dialog.destroy() - except Exception: - dialog = Gtk.MessageDialog( - transient_for=None, - flags=0, - message_type=Gtk.MessageType.INFO, - buttons=Gtk.ButtonsType.OK, - text="Invalid input" - ) - dialog.set_position(Gtk.WindowPosition.CENTER) - dialog.run() - dialog.destroy() - else: - self.gen_pwd() - - def on_reset(self, action, param): - """ - Reset fields to default parameters - """ - for k, v in zip( - ["lst", "min", "max", "wrd", "sep"], - [self.lst, self.min, self.max, self.wrd, self.sep] - ): - v.set_text(str(self.app.dflt[k])) - for k, v in zip( - ["cap", "num", "sym"], - [self.cap, self.num, self.sym] - ): - v.set_active(self.app.dflt[k]) - with open(join(Fn.conf_dir, "passphraser.json"), "w") as cfg: - cfg.write(dumps(self.app.dflt)) - cfg.close() - self.pwd_label.set_text("") - self.pwd_len.set_text("") class Application(Gtk.Application): def __init__(self): - Gtk.Application.__init__( - self, - application_id="me.zevlee.Passphraser", + super().__init__( + application_id=Utils.ID, flags=Gio.ApplicationFlags.FLAGS_NONE ) - GLib.set_application_name("Passphraser") + + # Set application name + GLib.set_application_name(Utils.NAME) + + # Set program name + GLib.set_prgname(Utils.ID) def do_startup(self): Gtk.Application.do_startup(self) - # default parameters - self.dflt = { - "lst": join(Fn.conf_dir, "wordlists", "eff_large.txt"), - "min": 3, - "max": 9, - "wrd": 6, - "sep": "-", - "cap": True, - "num": True, - "sym": False, - "dbg": False - } - for symbol in Fn.symbols: - self.dflt[symbol] = True - if not exists(Fn.conf_dir): - mkdir(Fn.conf_dir) - if not exists(join(Fn.conf_dir, "wordlists")): - mkdir(join(Fn.conf_dir, "wordlists")) - for subdir, dirs, files in walk( - join(dirname(__file__), "..", "wordlists") - ): - for file in files: - copyfile( - join(subdir, file), - join(Fn.conf_dir, "wordlists", file) - ) - if not exists(join(Fn.conf_dir, "passphraser.json")): - with open(join(Fn.conf_dir, "passphraser.json"), "w") as default: - default.write(dumps(self.dflt)) - default.close() - def do_activate(self): - win = AppWindow(self) - win.present() + # Restore any missing files and folders + if not exists(Utils.CONFIG_DIR): + mkdir(Utils.CONFIG_DIR) + if not exists(join(Utils.CONFIG_DIR, "wordlists")): + copytree( + join(Utils.APP_DIR, "wordlists"), + join(Utils.CONFIG_DIR, "wordlists") + ) + if not exists(join(Utils.CONFIG_DIR, "settings.json")): + with open(join(Utils.CONFIG_DIR, "settings.json"), "w") as s: + default = Utils.read_config("default.json") + s.write(dumps(default)) + s.close() + if not exists(join(Utils.CONFIG_DIR, "default.json")): + with open(join(Utils.CONFIG_DIR, "default.json"), "w") as d: + d.write(dumps(Utils.DEFAULT)) + d.close() - def on_quit(self, action, param): - self.quit() + def do_activate(self): + win = Window(self) + win.show() diff --git a/lib/fn.py b/lib/fn.py deleted file mode 100644 index 168c68f..0000000 --- a/lib/fn.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 - -from os.path import dirname, join, expanduser -from platform import system -from gi.repository import GLib - - -class Fn: - - # config directory - if system() == "Darwin": - conf_dir = expanduser( - "~/Library/Application Support/me.zevlee.Passphraser" - ) - else: - conf_dir = join(GLib.get_user_config_dir(), "Passphraser") - # list of possible symbols to add to password - symbols = [ - "~", "`", "!", "@", - "#", "$", "%", "^", - "&", "*", "(", ")", - "_", "-", "+", "=", - "{", "[", "}", "]", - "|", "\\", ":", ";", - "\"", "'", "<", ",", - ">", ".", "?", "/", - " " - ] - # application version - version = open(join(dirname(__file__), "..", "VERSION")).read() diff --git a/lib/password.py b/lib/password.py index f23b51b..e2a5796 100644 --- a/lib/password.py +++ b/lib/password.py @@ -1,37 +1,40 @@ #!/usr/bin/env python3 -from lib.fn import Fn +from lib.utils import Utils from secrets import choice, randbelow from re import split -from os.path import join -from json import loads class Password: - def __init__(self, lst, min, max, wrd, sep, cap, num, sym): - # word list + def __init__( + self, lst, min, max, wrd, sep, cap, num, sym, + config + ): + # Word list self.lst = split(r"\s+", open(lst, "r").read()) - # minimum word length + # Minimum word length self.min = min - # maximum word length + # Maximum word length self.max = max - # number of words + # Number of words self.wrd = wrd - # separator + # Separator self.sep = sep - # capitalize + # Capitalize self.cap = cap - # add number + # Add number self.num = num - # add symbol + # Add symbol self.sym = sym + # Config directory + self.config = config def _form_lexicon(self): """ - Forms lexicon from which words are chosen to create passwords + Form lexicon from which words are chosen to create passwords """ - # filter self.lst based on length + # Filter word list based on length lexicon = [] for word in self.lst: if len(word) >= self.min and len(word) <= self.max: @@ -39,21 +42,17 @@ def _form_lexicon(self): return lexicon def _form_sym_list(self): - with open(join(Fn.conf_dir, "passphraser.json"), "r") as cfg: - config = loads(cfg.read()) - cfg.close() - symbols = [] - for symbol in Fn.symbols: - if config[symbol]: - symbols.append(symbol) - sym_list = [] - for char in symbols: - if char not in self.sep: - sym_list.append(char) - return sym_list + """ + Form the list of possible symbols to add + """ + return [symbol for symbol in Utils.SYMBOLS if self.config[symbol]] def _add_num_sym(self, sym_list, num_ind, sym_ind, ind): + """ + Add a number and symbol + """ result = "" + # half the time, adding a number is prioritized if choice([True, False]): if self.num and ind == num_ind: num = str(randbelow(10)) @@ -76,29 +75,29 @@ def _add_num_sym(self, sym_list, num_ind, sym_ind, ind): result += f"{num}{self.sep}" return result - def password(self): + def generate_password(self): """ - Creates password of `wrd` words from lexicon + Generates password of `wrd` words from lexicon """ lexicon = self._form_lexicon() sym_list = self._form_sym_list() result = "" - # choose a random point to add a number + # Choose random points to add a number and symbol num_ind = randbelow(self.wrd + 1) sym_ind = randbelow(self.wrd + 1) for i in range(self.wrd): - # num and sym + # Num and sym result += self._add_num_sym(sym_list, num_ind, sym_ind, i) - # word + # Word word = choice(lexicon) if self.cap: result += f"{word.capitalize()}{self.sep}" else: result += f"{word.lower()}{self.sep}" - # num and sym end case + # Num and sym end case result += self._add_num_sym(sym_list, num_ind, sym_ind, self.wrd) if self.sep != "": result = result[:-len(self.sep)] - return result, len(result) + return result diff --git a/lib/preferences.py b/lib/preferences.py new file mode 100644 index 0000000..ae9aef5 --- /dev/null +++ b/lib/preferences.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python3 + +from lib.utils import Utils +from os.path import join +from shutil import copyfile +from platform import system +from json import dumps +from gi import require_versions +require_versions({"Gtk": "3.0"}) +from gi.repository import Gtk + + +class Preferences(Gtk.Window): + + def __init__(self, parent): + super().__init__( + modal=True, + transient_for=parent, + resizable=False + ) + + # Set up header + header = Gtk.HeaderBar(title="Preferences", show_close_button=True) + + # Set decoration layout + if system() == "Darwin": + header.set_decoration_layout("close,minimize,maximize:") + else: + header.set_decoration_layout(":minimize,maximize,close") + + # Add header + self.set_titlebar(header) + + # Set up grid + spacing = 20 + grid = Gtk.Grid( + row_homogeneous=True, + column_homogeneous=True, + margin_start=spacing, + margin_end=spacing, + margin_top=spacing, + margin_bottom=spacing, + row_spacing=spacing, + column_spacing=spacing + ) + + # Open stored preferences + self.config = Utils.read_config("settings.json") + + # Included symbols label + symbols_label = Gtk.Label(halign=Gtk.Align.START) + symbols_label.set_markup("Included Symbols") + + # Symbol check buttons + self.ti = Gtk.CheckButton(label="~") + self.ti.set_active(self.config["~"]) + self.gr = Gtk.CheckButton(label="`") + self.gr.set_active(self.config["`"]) + self.ex = Gtk.CheckButton(label="!") + self.ex.set_active(self.config["!"]) + self.at = Gtk.CheckButton(label="@") + self.at.set_active(self.config["@"]) + self.po = Gtk.CheckButton(label="#") + self.po.set_active(self.config["#"]) + self.do = Gtk.CheckButton(label="$") + self.do.set_active(self.config["$"]) + self.pe = Gtk.CheckButton(label="%") + self.pe.set_active(self.config["%"]) + self.ca = Gtk.CheckButton(label="^") + self.ca.set_active(self.config["^"]) + self.am = Gtk.CheckButton(label="&") + self.am.set_active(self.config["&"]) + self.ak = Gtk.CheckButton(label="*") + self.ak.set_active(self.config["*"]) + self.op = Gtk.CheckButton(label="(") + self.op.set_active(self.config["("]) + self.cp = Gtk.CheckButton(label=")") + self.cp.set_active(self.config[")"]) + self.un = Gtk.CheckButton(label="_") + self.un.set_active(self.config["_"]) + self.hy = Gtk.CheckButton(label="-") + self.hy.set_active(self.config["-"]) + self.pl = Gtk.CheckButton(label="+") + self.pl.set_active(self.config["+"]) + self.eq = Gtk.CheckButton(label="=") + self.eq.set_active(self.config["="]) + self.oc = Gtk.CheckButton(label="{") + self.oc.set_active(self.config["{"]) + self.ob = Gtk.CheckButton(label="[") + self.ob.set_active(self.config["["]) + self.cc = Gtk.CheckButton(label="}") + self.cc.set_active(self.config["}"]) + self.cb = Gtk.CheckButton(label="]") + self.cb.set_active(self.config["]"]) + self.vl = Gtk.CheckButton(label="|") + self.vl.set_active(self.config["|"]) + self.bs = Gtk.CheckButton(label="\\") + self.bs.set_active(self.config["\\"]) + self.co = Gtk.CheckButton(label=":") + self.co.set_active(self.config[":"]) + self.sc = Gtk.CheckButton(label=";") + self.sc.set_active(self.config[";"]) + self.dq = Gtk.CheckButton(label="\"") + self.dq.set_active(self.config["\""]) + self.sq = Gtk.CheckButton(label="'") + self.sq.set_active(self.config["'"]) + self.lt = Gtk.CheckButton(label="<") + self.lt.set_active(self.config["<"]) + self.cm = Gtk.CheckButton(label=",") + self.cm.set_active(self.config[","]) + self.gt = Gtk.CheckButton(label=">") + self.gt.set_active(self.config[">"]) + self.pd = Gtk.CheckButton(label=".") + self.pd.set_active(self.config["."]) + self.qu = Gtk.CheckButton(label="?") + self.qu.set_active(self.config["?"]) + self.fs = Gtk.CheckButton(label="/") + self.fs.set_active(self.config["/"]) + self.sp = Gtk.CheckButton(label="(space)") + self.sp.set_active(self.config[" "]) + + # Deselect all and select all buttons + deselect_button = Gtk.Button(label="Deselect All") + deselect_button.connect("clicked", self.on_deselect_clicked) + select_button = Gtk.Button(label="Select All") + select_button.connect("clicked", self.on_select_clicked) + + # Advanced label + advanced_label = Gtk.Label(halign=Gtk.Align.START) + advanced_label.set_markup("Advanced") + + # Debug mode check button + self.dbg = Gtk.CheckButton(label="Debug Mode") + self.dbg.set_active(self.config["dbg"]) + + # Save settings as default check button + self.default = Gtk.CheckButton( + label="Save current settings as default" + ) + # Cancel and save buttons + cancel_button = Gtk.Button(label="Cancel") + cancel_button.connect("clicked", self.on_cancel_clicked) + save_button = Gtk.Button(label="Save") + save_button.connect("clicked", self.on_save_clicked) + + # Attach widgets to grid + symbols = [ + [self.ti, self.gr, self.ex, self.at, self.po, self.do], + [self.pe, self.ca, self.am, self.ak, self.op, self.cp], + [self.un, self.hy, self.pl, self.eq, self.oc, self.ob], + [self.cc, self.cb, self.vl, self.bs, self.co, self.sc], + [self.dq, self.sq, self.lt, self.cm, self.gt, self.pd], + [self.qu, self.fs, self.sp] + ] + widgets = [[symbols_label]] + symbols + [ + [deselect_button, select_button], + [advanced_label], + [self.dbg], + [self.default], + [cancel_button, save_button] + ] + for i in range(len(widgets)): + width = max(len(row) for row in widgets) // len(widgets[i]) + for j in range(len(widgets[i])): + if widgets[i] == symbols[-1]: + # Special case for last row of symbols + grid.attach(widgets[i][j], j, i, int(2 ** (j / 2)), 1) + else: + grid.attach(widgets[i][j], j * width, i, width, 1) + + # Add grid + self.add(grid) + + # Show all added widgets + self.show_all() + + # Flattened list of symbol check buttons + self.symbols = [symbol for row in symbols for symbol in row] + + def on_select_clicked(self, button): + """ + Set all symbol check buttons to true + """ + for widget in self.symbols: + widget.set_active(True) + + def on_deselect_clicked(self, button): + """ + Set all symbol check buttons to false + """ + for widget in self.symbols: + widget.set_active(False) + + def on_cancel_clicked(self, button): + """ + Close preferences dialog without saving + """ + self.destroy() + + def on_save_clicked(self, button): + """ + Save preferences then close dialog + """ + with open(join(Utils.CONFIG_DIR, "settings.json"), "w") as c: + for k, v in zip(Utils.SYMBOLS, self.symbols): + self.config[k] = v.get_active() + self.config["dbg"] = self.dbg.get_active() + c.write(dumps(self.config)) + c.close() + if self.default.get_active(): + copyfile( + join(Utils.CONFIG_DIR, "settings.json"), + join(Utils.CONFIG_DIR, "default.json") + ) + self.destroy() diff --git a/lib/utils.py b/lib/utils.py new file mode 100644 index 0000000..12779ff --- /dev/null +++ b/lib/utils.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 + +from os.path import dirname, join, expanduser +from platform import system +from json import loads +from gi.repository import GLib + + +class Utils: + + # Application name + NAME = "Passphraser" + + # Application ID + ID = "me.zevlee.Passphraser" + + # Application directory + APP_DIR = dirname(dirname(__file__)) + + # Application version + VERSION = open(join(APP_DIR, "VERSION")).read() + + # Config directory + if system() == "Darwin": + CONFIG_DIR = join(expanduser("~/Library/Application Support"), ID) + else: + CONFIG_DIR = join(GLib.get_user_config_dir(), NAME) + + # List of possible symbols to add to password + SYMBOLS = [ + "~", "`", "!", "@", "#", "$", + "%", "^", "&", "*", "(", ")", + "_", "-", "+", "=", "{", "[", + "}", "]", "|", "\\", ":", ";", + "\"", "'", "<", ",", ">", ".", + "?", "/", " " + ] + + # Default parameters + DEFAULT = { + "lst": join(CONFIG_DIR, "wordlists", "eff_large.txt"), + "min": 3, + "max": 9, + "wrd": 6, + "sep": "-", + "cap": True, + "num": True, + "sym": False, + "dbg": False + } + for symbol in SYMBOLS: + DEFAULT[symbol] = True + + # Read config function + @staticmethod + def read_config(filename): + """ + Given a file name `filename`, return the configuration dictionary or + the default configuration if `filename` is not found + """ + try: + config = loads(open(join(Utils.CONFIG_DIR, filename), "r").read()) + except FileNotFoundError: + config = Utils.DEFAULT + return config diff --git a/lib/window.py b/lib/window.py new file mode 100644 index 0000000..8a5c91d --- /dev/null +++ b/lib/window.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python3 + +from lib.utils import Utils +from lib.password import Password +from lib.about import About +from lib.preferences import Preferences +from os.path import join +from shutil import copyfile +from platform import system +from json import dumps +from gi import require_versions +require_versions({"Gtk": "3.0"}) +from gi.repository import Gtk, Gio +from gi.repository.GdkPixbuf import Pixbuf + + +class Window(Gtk.ApplicationWindow): + + def __init__(self, app): + super().__init__( + application=app, + resizable=True + ) + + # Set up icon + filename = join(Utils.APP_DIR, f"{Utils.ID}.svg") + icon = Pixbuf.new_from_file(filename) + + # Add icon + self.set_icon(icon) + + # Set up header + header = Gtk.HeaderBar(title=Utils.NAME, show_close_button=True) + + # Build menu + builder = Gtk.Builder.new_from_file( + join(Utils.APP_DIR, "gui", "menu.xml") + ) + menu = builder.get_object("app-menu") + menu_button = Gtk.MenuButton() + menu_button.set_image( + Gtk.Image.new_from_icon_name( + "open-menu-symbolic", + Gtk.IconSize.SMALL_TOOLBAR + ) + ) + menu_button.set_menu_model(menu) + + # Add menu actions + action = Gio.SimpleAction.new("prefs", None) + action.connect("activate", self.on_prefs_clicked) + app.add_action(action) + action = Gio.SimpleAction.new("about", None) + action.connect("activate", self.on_about_clicked) + app.add_action(action) + action = Gio.SimpleAction.new("reset", None) + action.connect("activate", self.on_reset_clicked) + app.add_action(action) + + # Set decoration layout + if system() == "Darwin": + header.set_decoration_layout("close,minimize,maximize:") + header.pack_start(menu_button) + else: + header.set_decoration_layout(":minimize,maximize,close") + header.pack_end(menu_button) + + # Add header + self.set_titlebar(header) + + # Set up grid + spacing = 20 + grid = Gtk.Grid( + row_homogeneous=True, + column_homogeneous=True, + margin_start=spacing, + margin_end=spacing, + margin_top=spacing, + margin_bottom=spacing, + row_spacing=spacing, + column_spacing=spacing + ) + + # Open stored preferences + self.config = Utils.read_config("settings.json") + + # Word list label, button, and entry field + lst_label = Gtk.Label(halign=Gtk.Align.START) + lst_label.set_markup("Word list") + lst_button = Gtk.Button.new_with_mnemonic("_Choose Word List") + lst_button.connect("clicked", self.on_file_clicked) + self.lst = Gtk.Entry() + self.lst.set_text(self.config["lst"]) + + # Minimum word length label and entry field + min_label = Gtk.Label(halign=Gtk.Align.START) + min_label.set_markup("Minimum word length") + self.min = Gtk.Entry() + self.min.set_text(str(self.config["min"])) + + # Maximum word length label and entry field + max_label = Gtk.Label(halign=Gtk.Align.START) + max_label.set_markup("Maximum word length") + self.max = Gtk.Entry() + self.max.set_text(str(self.config["max"])) + + # Number of words label and entry field + wrd_label = Gtk.Label(halign=Gtk.Align.START) + wrd_label.set_markup("Number of words") + self.wrd = Gtk.Entry() + self.wrd.set_text(str(self.config["wrd"])) + + # Separator label and entry field + sep_label = Gtk.Label(halign=Gtk.Align.START) + sep_label.set_markup("Separator") + self.sep = Gtk.Entry() + self.sep.set_text(self.config["sep"]) + + # Capitalize words option + self.cap = Gtk.CheckButton(label="Capitalize") + self.cap.set_active(self.config["cap"]) + + # Add number option + self.num = Gtk.CheckButton(label="Add number") + self.num.set_active(self.config["num"]) + + # Add symbol option + self.sym = Gtk.CheckButton(label="Add symbol") + self.sym.set_active(self.config["sym"]) + + # Generate password button + generate = Gtk.Button(label="Generate Password") + generate.connect("clicked", self.on_generate_clicked) + + # Generated password field + self.password = Gtk.Entry() + self.password.set_editable(False) + self.password.set_hexpand(True) + self.password.set_vexpand(True) + + # Password length + self.password_length = Gtk.Label(halign=Gtk.Align.START) + + # Attach widgets to grid + widgets = [ + [lst_label, lst_button], + [self.lst], + [min_label, self.min], + [max_label, self.max], + [wrd_label, self.wrd], + [sep_label, self.sep], + [self.cap], + [self.num], + [self.sym], + [generate], + [self.password], + [self.password_length] + ] + for i in range(len(widgets)): + width = max(len(row) for row in widgets) // len(widgets[i]) + for j in range(len(widgets[i])): + grid.attach(widgets[i][j], j * width, i, width, 1) + + # Add grid + self.add(grid) + + # Show all added widgets + self.show_all() + + def on_prefs_clicked(self, action, param): + """ + Open preferences window + """ + prefs = Preferences(self) + prefs.show() + + def on_about_clicked(self, action, param): + """ + Open about dialog window + """ + about = About(self) + about.show() + + def on_reset_clicked(self, action, param): + """ + Reset fields to default parameters + """ + default = Utils.read_config("default.json") + for k, v in zip( + ["lst", "min", "max", "wrd", "sep"], + [self.lst, self.min, self.max, self.wrd, self.sep] + ): + v.set_text(str(default[k])) + for k, v in zip( + ["cap", "num", "sym"], + [self.cap, self.num, self.sym] + ): + v.set_active(default[k]) + self.password.set_text("") + self.password_length.set_text("") + copyfile( + join(Utils.CONFIG_DIR, "default.json"), + join(Utils.CONFIG_DIR, "settings.json") + ) + + def on_file_clicked(self, widget): + """ + Open dialog to choose word list + """ + dialog = Gtk.FileChooserDialog( + title="Choose the word list", + transient_for=self, + modal=True, + action=Gtk.FileChooserAction.OPEN + ) + dialog.add_buttons( + "_Cancel", Gtk.ResponseType.CANCEL, + "_Open", Gtk.ResponseType.OK, + ) + dialog.set_current_folder(join(Utils.CONFIG_DIR, "wordlists")) + dialog.connect("response", self._select_file) + dialog.show() + + def _select_file(self, dialog, response): + """ + Set file when chosen in dialog + """ + if response == Gtk.ResponseType.OK: + self.lst.set_text(Gio.File.get_path(dialog.get_file())) + dialog.destroy() + + def _generate_password(self): + """ + Gather parameters then generate the password + """ + # Open stored preferences + self.config = Utils.read_config("settings.json") + lst = self.lst.get_text() + min = int(self.min.get_text()) + max = int(self.max.get_text()) + wrd = int(self.wrd.get_text()) + sep = self.sep.get_text() + cap = self.cap.get_active() + num = self.num.get_active() + sym = self.sym.get_active() + password = Password( + lst, min, max, wrd, sep, cap, num, sym, + self.config + ) + generated = password.generate_password() + self.password.set_text(generated) + self.password_length.set_text(f"Length: {len(generated)}") + # Save the settings used to generate the password + for k, v in zip( + ["lst", "min", "max", "wrd", "sep", "cap", "num", "sym"], + [lst, min, max, wrd, sep, cap, num, sym] + ): + self.config[k] = v + with open(join(Utils.CONFIG_DIR, "settings.json"), "w") as c: + c.write(dumps(self.config)) + c.close() + + def on_generate_clicked(self, button): + """ + Generate password when button is clicked + """ + config = Utils.read_config("settings.json") + if not config["dbg"]: + dialog = Gtk.MessageDialog( + transient_for=self, + modal=True, + message_type=Gtk.MessageType.INFO, + buttons=Gtk.ButtonsType.OK + ) + dialog.connect("response", self._confirm) + try: + self._generate_password() + except FileNotFoundError: + dialog.set_markup("File not found") + dialog.show() + except Exception: + dialog.set_markup("Invalid input") + dialog.show() + else: + self._generate_password() + + def _confirm(self, dialog, response): + """ + Close upon confirming + """ + dialog.destroy() diff --git a/linux/icons/hicolor/1024x1024/apps/me.zevlee.Passphraser.png b/linux/icons/hicolor/1024x1024/apps/me.zevlee.Passphraser.png new file mode 100644 index 0000000000000000000000000000000000000000..84a83eceb501dea9ca4103d0ff94c23867a3f558 GIT binary patch literal 37261 zcmeFZg;!Qx^e(yqQ3NqT1PM`58l(jYK|nx|P63sYM!LbmKtw{iyHUEq4-utPq`SMD z_s;!-zjMbK=l%hAjI+P->AUw{IoDisKJ%Gt`(9p7l9-T!5J3=Psr&a75#$*BJcbY) zhrc|im|h_W&TC^aF?lI5u`5>AmWIY=1_(m$=jJDPzgmQ{MpsEDQJHcsX5?%Fzs6b8 z=N*hBv7#xYns)5PYeZpO*BMwpy)^y)-M1#~m3MB|>8zJmws1zK#uBEk(jBm|#}u1yYe3En@4o)*32=u#5uDkFs}ytHMf7iH&o<1eN2aPQtueS z0axa?8OBzt zcFEn8E>4x=i<&kLXzud4A#EKhE64fxj!6&&mM<(XEHn)q2)55Gp13_`{rR14?b`~ztY8=VKaMDUxFb9~VJjsoeqsWjobc*}+IUH81i6Ap z-Mg#o*fZDf;Ha!}P`lh5$%QL*C6Gjv4d=Wx$+2_i0`0y%#vwIJk9imKcT3|ev$_@O zkA)o899*6c>UYzwTzScr8oMbcDthI5LPOsmjr7IqoHjQ@rEdJ*UB6T6+aS2v6w2w~ z?<#Dwc>6pI;s0L$R|5Z60{=ggK;Rh(jfJw}-2my0wQCNHlVd7|1F0A5q_XvTY{bTX zom3o{zA~VLPDmd|S@UTXDen)dga-{!rn|bpDUOCU$+k9*;iW6NfR*b7A*Js^0Y3>9KOl z&F%eqZf3wVZlth=hZe7+yp|AF{cdJS=JA)EeIIY?UOB|-w9S0TR@sH#N^W0PQ(8$O zBOXhaBZ7Q@7GJfayXO^t`k}8Um!I$5kF;Wddu2{~82Z!%Y z?CVDfoo$f97E58jC894XA+H?F^RwpFX3#Ej#bZ6ZoO0Ja#3V|JcqsD(TC7N)DDYhC zeF;ZA^5OMFX>NmKszEOqWs(@iBmG08=?tj+oUAu#FamBZm13Unc8o~6=5vM;FuUb_ z#}TL5pSGM1?wnl>QiabiVr4?e^0a!UPIc3STw&fIy;GI&)cP|I&fSm(J*F|foClxq zgr%H9-M1)4R~m|_rD(~7!yYZ*diD(t%C%LHGc{&hdlAuu4$E`(?@N8t7BL)Rm%0=? zzfEZkmrs-@$bNm(OQWn+-BBZu&(tuKk6$46F+7tL6pmE&adGous@AT3%JcDy=)^XG zi$hEJtWB%H(9J;k(}uZuSc&R}EY0udj_)zAk#CU&_zwFIbFD8RV=PX4WVJ7xBKdN0 z(27RgaRT%)^EMn;DT1a}`9B@p*qu=`i0Yds8$H`H^~d9cy`!;wD6F4aWp{mrTbpgD zeUk;YM-q~xDjA7is*7Q5v#$gtH`W(_RjhML8BTwav?@yVawu5)>53%s3`ZGPJhP$H z;(swhgVwtuC9!@F-wu;z>+Lb^t96FeS>i?H;Fp)zqzl=KlTTgK8!a5*Q%=Q4wwZi* z8!q(zce@5V(1M~Y!WkYZ33V#rnRXSzom~?0Cw4OVG!uTh;S<^JxoV-rNJ9trE54)R z5`v_T+b)VC?*`W!3DVQ6EG`%*n`?%h^Q0vItyiayd@gk!yI}aUi7{dV9hUreZ_G{? z!;*jS_3DX2H!jh565CD>gV((Dy8)C{(Pi4fr}W-xrek(izgC=uE8yez(X;J0(#B)UpoAmhKCp~a*UZD$kIEqCWez^$ z*U`(0@*(vj9`i+&ru+VE`R;pm{?!glzs3zHTUI=Dvj-4^ zPHf!wr|3AP*gkdTw!NI%L0WJb1@2hnorJ-k_G%In#^hcdB^K}E{=*BboFVO^^?af< zM0ZVkT-CEri9t;evsX_>YA|?yao(ozUd0WU(}k$$5D|P3+_U7|X#u7KqJm`0Ag75C zv;5Ng63cbcMl~3XPh#E%%4rPo&QFKQMG`4EY(CXL=v9v!H6l7qyfZGpCZ=8bs5`;5 zi&f?#i)NsK)1d!cO0oTeGHVX{1FSG`IZX0`SSC0ox%J!&taId~{V6*6E4SF_8ysK` zGir39;%o<;8^+twHI~gY95} zZ3E;n@9G7im57jQ(1N+&RTpBX5xk)&n|?lKk(5czcx? zE?Ju~BDONy3#bf1|Ho$AQ#Qm0i!afNNTI`d&HGv5c8{ef5-uD4@zSk0>Z5Y^y5o9C zSCOc<2px3ZF__QFQ2qhK_CU!m$#{3HhDp92rCde8u|G&RdbI2W}GI~!T6T_ zw?BhSL|G~)n^c(bILPc1uMO0nvXsxMHi`9VO!B)X@sZ%hVXs>i^29#=xT0kaBHo2~ zKU9d6lW)WdmCs@JkQg0fpRes6VM!Fy1qX-SAcI7wHxF*Hcp+b2emu``Kqqx~m`*59 z)dHVgc9r2b7r|kp6{PAlytVn4a0Blzv;8JWQ)H|*9ai-`eodmR--pJq08^LXrUx^F*?Rz^ATx=hni(>}c8Cw{0GY13xs32o$)jH?e zrs+D}b^nK=2qz|w=2SsDeT?Sngx2|g0}luvZXX$BPxvDjw8PYTw(3N7?z2RX;X>SF z$5QZ)Mq|`4N5U}ZqJ~3~ytQdS@HnbRZANe2L{y~R_Uz&0Tq$rIGx?eXoT?O;X+HDG z7fgLx5cBNJmgXoYLFP8%Z&fZaBGv3+M=S4o8Aso2Rdm_oex*+c_IRyMgi~fM;K@+??F$`m zjD#P>zqae|l$7avV_u$+xp9pBp;>@+n~c3YF;n=d!D-YhHgT#3Lj8@|wnqkQX+51> z%Nqg`i*P-kxE<}1s>y~qJ?pt}75aWK z?$wd>DR;!<>tv0`IZSIApw z^MPO6t#Ffdmkq6=_&B*x-@CMJdST+53XFJE7|)dU!j;2nftOYvq|IF(aOh4lnG7cV zyyUs~!9$JK^Ua9vMuhML!Do#R`4y9DIR8c%=+;YSP5Ef5gvWAU{Vu^!z)0oSvsKc| zYz&x9g+zf>jBXragxO0MkrPBa5c$pVrE&xxfQYoj__JVI&vX3)^RL|o2yq(L^vSu| zth+nDSr&lP+Y+C)bk2LhbU3O++MC+j-Y2AslOOS{IxTz15e#K*@wW3YdejiP^L+ke ziGSs=U?Ab@5BqVOuI^;sc4|4eiPYwdtW&P|Nu#BXf_*RfMlhOt^lJN-o!lOJdyzY&GqtL*`q}Xbop0pJf^~-^vFniuE;N6&e|kk{=Lx6C?2V7D>-lz z+sp@gVZoL_Yr&pc`eo$GH;ld3Q;z|bqgSS@>ZP$UCSjeF&&cgl{f1)hIhEVc#lLre)R z=Yu2#gV{Mhsm3hwrd@1BPhJz(_Rgf$%Z_wN2xr{$zss!6 zk)jnmbDHUyk&tcIcvY__a_0y4ug*avar{oSgbGLJ-URv?y<|(e|_uOVZnfvLHg?mJ8^%_XRHFrFFf_c;3K(jJAJ=& zeEN=+OiaWV%%s`Z&=&>u2J2pjdM5wpsi!b55*}Mme%NK5%{E*2OS7K_r!HVy9_Ko~ zwMwgH6*F?_3id&r!M1MI#fwkVzn?wq>60EJmh(of0H2fZa4ho_gH&4ibvUQ6p&2s% z`gs#3nha4s`Hg|^v&x}f)4%#sVZbA%sN5-X{AgBjU(Kp+Nad&hQ%zPzx0{#E{Yfr9 zRnjMgXb-(&%C<~-9t-T!5S!$n3@}^<6>SbV->x9{(2aX9 z^bZRL_Dc``{<(_lDSg+ALh=o}74~r;XF;XVSv3~8n{ocB(wDR0Gk*yD zt7#3!`46^qKc!|odb={8G?x@;87%sdGBosrBi3paWoe6=O5xC+Iws#?QhD~pfU9)4 zEMdC7k~*D{5|NqWz(-R@OLTfgBpv2)A2rR%31axhF}ghLnOK4e8NYhm$_G1t#M4^$ z;83{`dH2YGQ^zED=%}Kq?Fjra{a{QlZS8qm$47H6Mp*h;X}_A<%7#dvs709 zH(dp<6NUf4m;3;UKhZG`MnrnvND-oMlf0+U)smRuf>bDj=_P^~N?Kr8oN+{acnIhA zr~%Y_3Li&mdFd?&s9<$39%Kd4Dkb&W_Z><>#OWXIlpp>#*PpkwiL0Pd^okLM=FrO% z`zP30(qy&W(hB0Edr!iDKdh^-92SWw>)Q76-uO3*|5-Gq|8c=(O%BeN|2e?_afwG2 zsw{7p|F7<^UOjB|s2605+xt)y^2f_I2VBy0%1e4N=Dh_zs11BWs1JL5$-}5ALc!U& zq}SfQG!pxK1kL-wRmV^CzXbVDq9WK=prG%E_nbY7dyei!Zrk&aT{(Og^FQA8$or_&svJw{;Pn8Ylk(QQL+})V(EOWBS_8lH5ci}eu z!)*Td>s_q^vsSqM5*nI1H)m#GXqaZwnMQc}w5ksUw{o%^RZUF|gOHHU`}gmqA3RX5 z_98a8B;gl5$R(SpnJ-Ork-24}G5kwJM8;^X@9dBF7wVdtf~tq*$LqeR6k8jJOG+}a zvdY=b{!#J1$P)PZbIhMit#rf2Flxa`%gX&ErDVBcvkTPJS*NM^BQ`^-hg;^lbJwfS z2tR`f^pv|4%0==g&UB_T-MAs)bD8%~rFMdZh6d&JnNAg$a;8S^&*|kk`_cmQ-lWEGUen$Jb97-oQQnRddwZIJ zj!qn89Mo^o^*i7uDLHv6i22Q%H>s+bnkM}v`8|2Y@iMH%_h5lGc0y=`T-9?88{5E| zo9%j{G<&E+N6l&Mps&p*-J{PfA9XoFp60NK1Q{MXNx0^rsK$ z*|S6W2MI|@CQT8yHNQQ5!(%y+5g164n3%}G!XoRh43mWwW&j~WeWlHX{!SS5Q$ZtD z)gbr%b+y9zFfQY`8PlKD@Z+(i$i3Jo5hL+U{aysi3=+)z{;v zF2$(nIEllOtrmHJhO~o1=NmRsfIgD#t{0eg$w7bZ!UxM|-n@NFmOd55Vemo1mwG;D zDJRZ(eP-tGw|Lg_HAUh}>>>&Z3PBt74GkS3xAfMQYiVYyUf|Wth{a3zbbQm3)OOz< zr{J@S>D_?+Y`0qy;P2lgAer=xN_mreU# zi;0F%RD}o$%Z#Gk{um6teEE{FpU0$wet&D!SF_wXpM#Urdw*N%{(bpM_x+ASOI=^F z_{tp^_j-?MwsCikfi)kcxRBhvd$0Lzr(!-)38d*(x|5OoQf&;mB}U`E6$_i^W@-OI zYsK>Nvh!N2?Py5zu$sBct~lM*rsL`jS$L43-u?v^@92H_xJDHXyhWoyfXan^+{M$ zKeZ2-+}Phr4+Rsqwj5zyEAH3wJs)|URlcFA?XkZOO&EWJrudy!5?wL4uUi%cvYHLjvS^*n zu3Tt!-`!kP0}GI6)}5m`yZe!x({?_;YX%nC-D5!C$Y}QGWy_8Pseli8n4Wx7yG|9g z>6TbAq3OZCVw=u#7Y8aK*T17~HrCc1$q#8*)W25UbnC5fD=o2|juUj**y`U6i;BuR z*x#K6E!>=%ybBA1zU$64+O3(rB!U z*eJN`;Gt2bvQ@L-X2gvLA@Uh|2?+@)T7?!pl^&J4WjETn*5`7YXI7hq3(J~egXX(z zE-230n3$w3lr9R5kBx2Z-_{FD+F74Xc3PbvEj_#NCo{aOqDE*I)I+s7O3<4-$i7s2 ze|K}!c~CA|D3e;ynVycWCfmErVbD!Y@8`#FeFxLY(X4G>L@JhcX0y{hFb6sq=I(iW z!SxO$=ixVGu5F8@3nlgOx2^;3z%1+kqyy(ps%mJMR67_bU^Dmk7Fd(2Y@I>yC1$BD znnhNz?t9C%iu1GJ2w2G8B$|Vr3IjW&_9@?>{-Vt0y32^4B(;L7s_Hl2T$fD?*j!EN zZZ6PO9@rWVg)w3pp+~)imW6B72b-0cb#EJ+y{%>Ejcy~i9m?#ol@DFIi^+D`EfI)vJVtNVY<}*VSv+NH1PYDl5AK zp4S9(u)hO(gxXG-%~eBv{bvm!w=Bd?r*FD+W$WtpmpZ6Dc(w@0qS+%0~SkcyDwy++Z`Iu%_3I z#%b)F-9le?+cA$sH%PRDTE?`DtTYKMcA)zW1rvZ)_+7WYUSw8};T?2sUlBY2IixKV zPf~ZA{bBuTGFVY=QL$}^T7jV8s{)QoF%lmy#rg^#{59`=D71YqyL=<8{(xDh?COh&3W|`x+#HZQ6D(~Upaa#?E^xJi5OM`c~fBzkd(ZGC8`|u8YwbgoO9Oew* zuk0eSw_aX49;DTgsl^M9eERPW*$JTmzy7fl=TEK{Nd3L*-#E~Sabfx zWk5YM11^i5R1STy6>hsT^=y^4E*X&m4kpkuzD(q8o7G0%+3zQ4Iue6*W}bVDj*M_w z^znhNO-DKmJn!BBc}UC2sn!RvL>An3UQ4Oh>jRmhZUMGI)Iuf3z25_~&u=sFu>y18 zA{)jf_2R_~R&QztiBFW%1zW;eX49HGL+pGn64S=;Y z06trn-5RhKd9K^m+HUKe;s<+=Y#O;s7Atm{*I8imfGI3osMxg_pPV#Btq0%pxL&$z zWNbPaZ-~fB1l<8p=js1G-wAl2WnLvsxfK8zTXtzIl zgl(V;DL8n?QvfnuRMfYyptbY$>({I6*@}tMGySE7h7BRH zO_2fu=0*m^Y-)p5CFe;=6KiQa9@Pi4ZSFXYE(m^n_pYUI&^>)>>RDkehivYz`exE3 z0Q;~UpW0gz92N(hhhCgurmCN53yFH?>)QoTh0Aqoi3t4sVsFgdR}mNU7h&=JK45GF zcc$V$ynAQWy8v#T;m>5U^cP0)8QsT^W1QEfVqw{)|7cm-b#Dw}4hnaLPZ5hn+I=Fpdk$!pJeNlcjTL@<(qU$LzGmg zT%@G{1q#gpHpjzy&42+>1|#|3BcDEvJAeK>;SF5oEZAr2npw+$SvRJN(4e7r0+3eC zj)p_l?m}tv&DF<OqdL7XAD( z^FgfIGp&qx0`_xX_x1(|5O5F;Y}b(`m19;-)j-2Aa;XK3lHRy=t5s2eDc2zzxBwI_ z!pe`fcTHt^PJX;1dmao;xZ zjT#)bdIrF-C)dc=usO<2=X*aWR=?Y3f62klthStpItf@f1;A{ALY95_h-&j?2iA(M zr!w=RVqz@5xxB9e;+hzi)qel}?Yvw=#_hIa8$Dn>%KCY>Gdr#M+qqrZN`qv8&uF$Q+tTS1DI&7WeggJ83nOFQ&H47W zwnr8;x2+R;3N05`M|7<#SzUp9VQF4jgk!!&c~--s#MF1xVe9`1cqo+Gp8T-1-}2XI zTIx!&CfGSM>Dd)+fU`3|$BjpRyw_nl3z{{)OnQ8P-!kJXh1{`Y$J8tKYqS9IPktHw zc$rrYScz7ERO74LJbk1a;MWuY9G0&<0=$LBLs9NK#+{j3YJi~~T;v>gKfH}|9oQQ$ zLlB_oJe6W&V}lG^g@ZfmleFDTw@}YlJQ=l`ZkHjvJ$51AqQ57-wxOx%4@B9pI%6Ac zqY&ZEfCJg=DXcbv5JMfTib}MQTiQ4*|cXK}o40xz`Gn79K<+L&e) z|D3+(k;r{+LSum7X&HAcJyIopY-zH(0SAfsudcaS4YshPcncU3mV6tY>P-l_SO%5) z6QnMnMunJyOWw@PEVdRU6a~Zn*7ws4(|GKCLxb7E5R?Go@&EUZ3xzykXT!fSy^;+g#S=vE2Hw1bsQr`5%ioIO}jIPO8 z2h2}A3c}~j7Am%?Z{ND5fN~OmRs?|plOQ5v?Er<$2iD4bpse^8{x)=}TZrSiRy%iq zLVGm2HZU+SULL7IfiI7FPXdI{#y~=ehlQ~6@~TCK&aQDA#h?m@6J4yqLbqXgl3jV;bOwi|h%KvFr0o9S^}nMBZ$mp@Ky? zfPY{*OU#XOy9vvE`)3k&90r_{6YYT*%~L+>6aZcZVhEIRo*8~i^9QI38Y(`kD#gcs z!NJL}+eu5$(9+U=@by*mr55C}osxHh4TuK(sL8V*1jrt=<%If_`N7IT^HSJiX;J|< zT+6e}cv}1}KSVW54`@HdyBN@~sDC+906fdyjbP zL!=;5vjIVzR>hrN2-5SohE-N48i~pSduIxLRN3&NAzIe`_yqVxPznQMR(#z?bseC6 z%U9}{=r;DEU02?Z@9qqOuFA|~iKB;A>QRontDMGd30M22N6c|>a42}pLJ}=khy*-9 z3T6y^J1g~US47s?S(IX&f<~lmIXWhF3i-f zmz9U7pruyVWuCh;RY?*C+7&16{UI;!@7D6D_uiiPEwJi>OI3JswX?wdbY&I}m`rO; zpnfB(bYY}=>SgE2xdHcG^WY2fRQ$I0dHbwhsr|_ozKj5NQw`R(54|B5p`MWbKsD=8 zDlm*>+j~@8&ps!TUIZhT0I1q&FZUWJrxMtVP-u`Jbs%jCQaTz3XON-#M=?wKo>B;o zNLxcFXJ^rKJ#D}cDA^AECjpK!J=ojUEVfP@ABFHZzU3rBrxC?v0aP^_9uGK<66Zr4 zFtiNJxoiZV!ZpcH9T2yc?d-_5ckFGia(f)O0yIuXQwBRT>44yvKumnv{FV^Sp)3(f z4i`2nK=2lf?+C8qr!P%5WE+?`I1~YJc9E(*ihce1SiV`eBDYCL(c@@pE4memP5fM)mR#js57g2d=7MP_1 z_P$sWSGzIa%WXHK>_aWsV=hlZNtpqDfwUwO7z~uZXV&gqYL%ohUg#@!o{D{I+b+wS z3LBcN&)FYRK@fSEqGk1!#m@C;G`;Bd&%Sg_ije!gk6E}C~{QTufG|23#WfBzB zhMj2ax9R)-eJdzs^NAK8U>v|F{BDz`1hl6HAdU3=`8bdWBlsiO3`~BOne+CgkVqig z2Wx=u`{wm)5?6cR;l6+cg(RBqjpe=FK};6#O1JwDU=e5E(zv(4D)v#Ef@gD{Nljks zPo!4sZVth7qx)zu_Xf$TWb0@HC%f)c2|RJ2 zzrW&GbJ~+jJC&GS;b3#rm1S2RXsSJW{zg)bFJk`@4pPT1=3m30gY_q*pegA4FHCBz z8{aI-*HvW#{sZGEPp0eoP3=E#h&Ip^p~2G(Ng&dG{P>~hmW`sy; z1Mm^~DP}Y&%$Nsx!DoOJ2+y2hQ&m`jv%>0(1g~Db;@10lsxw=+@>jDO*k?3hgU$wn z8M$?;d~c;5l0VN<*JELns9&}NNAEZv0e3 zKuV|n!4ik#(qkDLvj{Z)%6wF;*rn}2b@LRm6dnL8dyr<@l?7S28m9{j8Z6hnPE)0U zj=Crl{QUV7MFBIwbJx0=w9GF6WY|T z;yEfZ57_sbgVi$d``HsIuvn%9@WGb!4deY;^!xi%ukaBOS~iN>-!P zGPmVG#D()n-6i6c0xm7+2|qX zTW5ZY9hgmk#8YMKEs#B)-r(^>!}~rV5FM%~K%bPN^GDkS``J@smtGr?RP*!ajMrrg zd5H2Ljj>5&NakP&q!OfEJ0Q!n4i5Aggw~ps?&V;&CYS$0idz$)VEoS7^yvD?WH!Iu zOv2chzT4LDTM7aD43vk>Ggns+f&3gR0OO4N!BMr4F^3r6qBqjTy{H|GcwznQ?Qo}q zM}B^OK|2$fTB<s{pR)5 zhtWbM^98+m&qpO7{gX1Z8UVC)U*98N9W{VtGI1+l$cm(^gtX|Vh5JTJ^q7N{k~FN`WAfVUvef_g3; z-JE$qu_zJ;2_}Q9>o((2NmUew?V$o0Y;8H#DJB%T7TYABrsRtO(*l`SJv8qPrg>#` zl}PpYJ4hD*-bRN9=M5b5&p=`vMYdZRghSXh)vF!__w z?Svnd3|w?N;F=<{0LUZ`dSJ?1%poDzR`-Poz&tC23#jF^o9RG>Jk_% zi$=~pNL(mF76~%%Y09Z_KYcFG#(A@@IGt4v0f&la5Ko+;?tt8u9UPzlV6KU>K`@qQ z&z^lxyNJfffFNbY2KK?fKLgF<2fi4%qd-WAH8ecHKYpAM{PmM3Pd@ngsGzfi=R+@se+gt6JLgFDbL{q60b$ZapIZPpNPNE&Xn+Ods}-mrbgkJfo0St zyBeTZS}^emfK9*rUG2=$)nA|AvhIgdKuCysS^$-* zGSFo!r7koVJL`pe)o>T~z7n8-7S z9U)*R&`Tcg=!XdQ7C}T`M4m_Z6f#EeayBwz;AO-|Or+4~yXQQwJh`6(1C8jYRG-sK z@-HrwM~6MsY^BUmMR!>Hm|L>0;8EWu|N1o%MIQg=dq9pYLa>fh8O$ePPopBo*gOnz z*omwE-b+1vc~_za5&475h;2gTo$ZcLNRTme0>~1s*AKE61(A1FB&`0*qWF+`1mS8Y zwVICJm9n8fJQ_z!iQM-;<#vw&eTfk0bZV17mR8()@ykP|F7Xle;pD(STLvX^$wB{OU5k7gc6~&qZZQeHoBB4R>woJ_ z4z}Fc|8P97zv=yNAs|r982f}^7^y0n?$XZ5NWV^%a0mPB*qLje5fT5Z&RIGJ#kK(n zxOLdWi6WmlU5_FDBu@2d-AU6k%uN6U;JPvus*-tXw>AvlE7n`zm?{w~jG^o2hcc1I znV&?9-%P}dwC4?`@zRLU@*-9o`%eDP+tc>mMWtJCp6YV)cTX}y-yp9aBl4_ewPE7J zrfS-s7e5x8nm&nC8g3N*cNXCM(MYVmp4h?F`}inc(!pK$D#y%3$?z_#B~?IdU zt9Vw;zq_L*UT|-76rdf18uFJ!+HwpkDVdp>-)-g(ba8oZ=(&j{KWXG<5!5-@in%6H zInEof;#;N?GAv)Dk-^>`OVA#xI=yZ)KkVnTU4%BOJpMV8Rvh`1t9Kd+OHO1N2>E85 zoxo%WaJE!MfY(qNxO94oI-+Ynw6iuXFDvDwkyyr-38u{OCam%M5f&XYNA%ioW|gOZ*z z*ROXZ5meFWW2&#IH~Dci%2m&jgCgD`&;K-RAMHi6^$*rmN?R8myl9qh}Y&ns$_=wjNb#OUOzj88O_)`X6LfiBd_8T4) zU2S&801s91IP_F- z^UmcmhpR}Cgbb}-Ht;s~a}Ir?8EG(0D3$!%pV@cy)TajiXT_Atkk5m;K0b*U3PQnTQ<}T1dk;Im+VqCE3G~fN>F#o28Q)4#bYZ^DHr9=<}dlvyCngt6-ij zj~$7SQ`Ho5N5)7t>3SozUtg;~zdUx05K%tFDzxO4BDOG>eEHs}2Y)HS)T*Q7#ZWI8XUAh?yZ%9k!f^75gV{It%#XjRhXybf zjJV>fV@E0@Dukp^nJYbbEyaCUdmKz@*q@W}*pt-AYiC4Wcp&TVeM7v%J(hrnh_$6A zzxH-H^qN=`P1nKE$@g9c+Z#eK4K1|IzF}hha1sam2%c1NCA5d%W4!v&`>0Si6#8%8 ztLYgY6?H%36MFQ4uQl0RS$2%4XGz-G?rZx+BH2TgADaKDb(1uXi1U4lZBT}TCa%u zT+r^x>582{Aw6cLa1Z-dlo6pPqk59&^vWu+lc+1}&fASKfxN}fGIVlHgxC^S^l_0* zZ*ve{DaG}_1{y&tge>EvCALL>6RX8pNdwib`5svpT_@{49Qk*0L|Grs*vFl!5qFAK zYsq0Q{z%Gr@K7=hRhAg(CuFig3dt;Q5V@a7RkUZ-jbvrl&uOSKq=b#f9ItwAsCYE1 z!}df7zA9lK+zbaOKD)F*usNzEmzoV>hvFqqY#9;y?n2Ax(_@Ra!k>J6NcV-8YOPKl z);?T(^a-x4?AKg}~6sPr!*_M<6bfkY8 ziM#y!0Y;b*2dVn~S7vS-J`EuFrtAqX(JKY#$P!+`-X8v2Oz_k5=r-cg#iOBdqlc}~ z>wg>DF?<0!c={bqY!FlM>!;M_1nY*PcwGU^A=m@_?xSr&DPj@q-|&w=9sYgg==LVn5vcSGdw=xke-rxA4634kT|F!if2Ph^yYBoJRFKcUSMi$I?ur6?CFFb3t;OrWl-iAldzx%>@ zQXC%@Ma8)2iwDZaPIvFVfWwj`O9k`&rD{w-?Buz&CpAJyN9b6#KKlnfxcnuEO}pd) zqz!R=H%DL6j9V8ovgopVyoiu9648SL$Fp#1Ei3O1oEw)3VkUO%wO<^_9Q4ptG2Vvw z>q~gRKceCyF$z~N3d!hX?rGEEbDhl2O zDVRuM&oX*g>OGrmTcpEA>twWSYKOe6qv6Yg=k1LlA1c^Ee-XM+GAx{K!#|KSS{y)wBVcNipKjcixt3rI-CCYdNL0VJDSw? zLMHsi14p_2-TwIO$}r7o8<5UPv~St%J)%lcUs&GR3Ktrn|E>Y=%tk%S!DIOB$C6)3 zzM3U)&sQr=9Za(aD7dXr4sGn4#l%Mq=b?kQaLNfUFf>$SUL8)Gp~AG2Y1Ufb8S7%o z^q6gQ=vbZ53EOJBK0Zk^@)kA<&R0}Xb7)_^1&V0W7RX#6FHOhm2K#1D(+Fk2VI>{b zV42*?&`be~N*TygY}{6Lcdu~nw@y!bz+j#;(G;2f-+!W;I|lXc3Kk0&(ZftDW4v6} zKlD^AdRNAoY)!L!`y^$P-RHai%7*i6Lu645Q?eBb*O5a%&MTy=j#Ew zpmTL1DvV>C2o|t0Y~4pPpmJ(b9L=|_K(5+p<{GOwZ|PTE0%-2PEjYpvHrB8B6VQxmnkiKY#pksC#f8afq78*v+(@{ zH4G-ecB+LI{XBx4JiKofD4g^+L>~U|aYILTa+>a-OWLVBz~IGeId8PVle%$hu+e&+$~ay7676}uY(zM2oBg~~>Fc&{VE5ANM%X`eK*xQ0^Vrn2;zwYu7BePeM+vk?I$aU^(fY{_-WRl>d`U&O_gK zfzD%z)^vb_ z^E2Jad!l5bCq12V@n^V&ytK6SoB7ZQp;6jvdI74L{ML*+n0~ABu)=2xHq3Cqad3Zg zJEMQjaw4Uu==o5+S;{=cup6#1*@|{CvjaVI|{czT2*S zNl|;vLai{S>^`LTf|Q-t%AanvCdr!G&G#hMEj#z^odF8-*EJFPLc>N)`1Ixb{?vcWFfv}=J`+i9FsuR_Jn2~@C!OJ|b~Ann2e&+5;OXafZ`}n<3{L0% zbYmO$%r`%dQ)2#Hi@Qz>vkl2|f^8{lGj`srm3uiRwX<#GjJ^_OWeRt!hGO8DbLGN~ ziEpj(9Ys>3jI~g$+UpGZ`OWpzxhV_d+|~B~qWg%=pFTDBp~2(U*U<<-i*g@pvK;X^@Wn$ZE?My zLOSNJBH<9)a`Q)rE{n!6lw}r6?9p}{#s_wHpmSjs4x2A5??-UkB*9k^k642x={Krg zZO&%oHjSZH5TJ$C4@f>FXgRM3D!ad4)iN+^XaOc3&t#@faOGDu|7Zi}b*akzjZ*ac z98`xMj&2mD1|+BWHChwiqqF$4tfYbti)7E10%_7KEqnllAV;*=lQ}Hj&fE? z`MWce>ObvSn_jp!az<#)b5K@WSvfE&lwAk*hC!p@G~I=9StCcsq9|%iAe`ESC5Jc@I{_FoCAZ; zrP})>f1EhwsBRR|`X_t&(`oOz=8Fv3{jG!bBGqwlRuKL8Y;}_D^L4tLyq&)kuEFud zny=3m2i$i4pZ3l(s;Mn{@S&(EiUkoxiUNvKl_DZScuGfl6Qud1hzLmU38*MyLAro| zQU!!aml`ZcQ;;T7LlNm65+H4MC~wyK&zi6EX|k5CklcGux##Y)%Wv<@q1o>&3{&li z_%;daOO~A`(tY!2(me)54ZF~X%wFYwojI56or8+!hV^VtTY8w)U52?Y0uTd|3GR&L znfH{UvA^<6av;tyUK^W)!H@eYW!O*lxyg=K%vHBTc$7xb`z)b;(!9eBrxKR|TK<@z ziiYsiJCB5RNax^$tw$(JE28?7s; zk=R=bBXGSO*jR*&DH*S)Icb?$LumGFz`T9!hnZ=KLkc4v~V6MM~u<=yQrw5G< z4V|DixI*{@`GLL<76zy#~yJxF>@ zU!RD{4z)eEE8Q-=PKB`4?XJ9jfV5s-u(duTD|90>(K9~DcXBuO>U)4A?bnNraW_%s zsCmYai-o)!bj$FAex4>({-!gQZ_$jc`%r%vD=RCRML0;O6ttLK%*@Qg44ONhrD$sx zp5X~({dCtoYnol_(%&vLamLG+m|Gehla$xdaX3AejE0CnCze{(_@g1(K0Y)wv~9|{ zG6TY&;8`{?i8F!dQY1v6qX9vzQx1#ZhiX<&O;?C>>YAE{rl#3??QKyI@`bR*1ck_b zFFC2NQprs-emMfL9wT4BPtP=IZ0ffR&B@jgo^pJT1HT#&>9M@Le9oYpFJH#D^>=cidDUdin6AKYXHi|>gnr8#aPH2#RKLe zI05*!LE*A{ z7!><^ZU`~OV#i+3xQwhrO_TpEwL`xY0=27NXq1S|$h6p2h9S?w7 zg$)?p!^6veZ(y1x+++IH7wX4)VE^97DX9=4=`_s>c8wr$uU>RgOh!kM!RTM7R=)lF zU)q?!i0<^_-8H@O#~d5_^@iNe^y4asco)k{^I-{2MzA}n6H2?oTf7>h#Fl4e=gJ(q zDhRogE=x$k0BxGU2C7d5@O$I7yrg5w+pCWtjnA^L*l%{t4p!3p z9|=taiS_`2U}>CS;wT#IhjC!(jP974PEcZ=9|tJ}p$`Y#KmhE!G#oU+xhfBYi8|F5 zl7}$6xGS-3Ee}AI$^t#`at!VMs%tql?!Pg3)Wi>^-_Vz!{hNrn=B>Kxb6bB{dwaXw z-x|6*1=0ilvUUIwYgQ80V=%P^`j-%&V8xx4_Ie6>-tB+7&(=ekgd=~ewYo=L8%ABT zTFe6s4GawIpM`e4i9O8j07mfaRD2T%m8Nrh31@%zmO2{8=9K$Xp?z!P8iCm?Mv-@t zjfP$@Mi>CYO(;=IUt;rLOBT!N$I+f+xIODQY7FOY-D~ zJS6838=2Gh+KfE^#XqbknrFhR%nX)Vc`ku#_6b4=o;Vk3709-!u3U_JUC^teEj=LF z-!&PUSN+NxE&xeMOMj{jjZPxI95<kNhx@8AuP!PZg@)*_{lEtnT6{aB2vOiQ^2!70SV`lG{cLo(9AtA`?6&J&7&}p8Kxf1&1iHuY6(Gk4{ynYjPEj1$uzJhQ95{9>3vJ(s_5Kj;<72i8C<29h??k-|uV|!LsAak0@ z>BVFxW{ex7)qiQy8>Nz-k#^>kl+xL=XVulzetmm>%y&NMG1w7VVEZMyst3Tm)Gl(y z$=ldPztBf1e*E`pTzq_rQ7+~0c_UCkmSG!pSaiTt)J?fJ)B@UoadmTxj*iX+EYHTy zMo38L#?70aUJ~69(@#&2p0P6xjfm7Yz@p^9{4ppiyFqJec=+Fa+~TTsuU)={&onj~ zd1}1?H^TTp3FMd*JK(g=HZ-VfYIsnw?Gpyc73+<*g$RGsd;R zEh;fF6$q!!TtDm2pTR>nd7ru2*i}7LPd`F~AS0uc)AhbJP-SO1p;&iBd3}0G8(er*R%mjkuA*Rxt(=VS?IXrVM(Ue> znZDb77hmwVEALmXw(KI8nuejPt3HkEX4oa4EpkKM!5BORx?ytZSaPn-gtv(aq}S_e zX}#FP%q&O$7H?N7Movmg`-nw@F<)MxZAl29hW(Gc^Z?ie_tyoE-(eo~f~WpWbz(A^ z#maRW8Z>E`6KqPS1Oyyv7ukS$I5``jsixLymmJmwicNp=KWiV^oE_o@gw1JD`a9hO zQ7I`UpdH$JovTv6e-|cr_m_LM|Bxo!b2j#bZ)IhBx%NH`ew_7V!ZFJ9CNeTI0n(Cn z_am1>Xn-uNZy8P&fZ3G6j)ALtc6)W33{5`-X^{|3IB!N7k^OQzX9roEFO#134C zyOd*(fpeuycR*t)mgdKj_gd)$>WJq0nVibf2X9u6hG>=ItvY$`pZtLlMcxb4!mTmRhRbynA;>6Gb)zzCn1f zM~*a)5TSaMUGgZuPRk^d^LwGEr?VlrE6OnW@Xi6UqOaQ^w5Lvs!#`!NS)irFwN3m#v@q!fB#Y zpVcxx4OTKVFGXbXpO1Tw??e{>f zPDUFGl!=XHvA7`+bv*E&04Dn{;)8!8gO$r}@G(d%q^r?xoLXCPmw8SOrmUx52Q-$? zQ&P3nhuPTdfBzh!m3{!rv?JYt-DAqsx2eDf*V0a$qe={B8sio5L;ZI)oS)CHkS)40KF2AMwr6zcuECcf(v3s5mY zGkvaqedRdhII>z`dI_Td>~P56O#{=54LS_D_*aZQCWO@>@xR=!f=t_#<<`FH7YJ(r zQmd1x#hwE;U$i4Z0yscJg%QoT#bDYUs_--~_tb?QgyuK>^x&~?B08n9M^4HD{G5$< zyq**NN+A~z$|AHE2*1z=W400^1x&{zGFpDp6n`}^E~=a5N*_@0r7?E~Qp))4!7IH& zauZ|hcm>RwQG`2yIshVT!ISS{nLq+rWks-MJ_(AU+xF)T=js`+ znQxcnjpE|sBGN?7F?!YpX?fM<6&0S5r>kkXnb4I1IX@})`k#A>mq-I_v?cxFAkE)s zIU)j%F-#>XJFU%UN8V(c2^i_%wo;mX=>V%9)ivAiHPBA5iKHumoH{VPf3A&rx#J$W zfJ>W}M7s0^$~DtEoZN z;E~uf5`7_Y_wL>0gP)mSJY>`k!{C|j*y~GcfuA)ZZFTjcSD_E2ozU>K2z5JWo{NLJ zkQnf$aRGdkBdvX2AYM5nFQ&W8HgQxezI;QfcQypVExXGiaT?_h4?u;ORTZxzSzMlrjC$BdRHa}6=8tEd+0ga zH_B4mIE7xbi7gv5`(0s&ftbLw$4=@-?qh2hmkjHlf+jIHTv&y_>?tV8!^TZL5)g+( z2i2KKj(&P!A3s~D#6MBxh3f(nd+p>dM2(9AtQCHLO7~$eeRePaocdo#<{6tUc!kBy z0H#O7(}|ok--v|mcXy-{JYS~8>o?Lf-d8rPPc~t4`bq$kGY4AP3n_}UF%^`f59l;Z z?4N?ZPPAV3lK|fZ*=#+?#WJ~ zYT(<&zv?GXVKRNH68|lO2-A3ibF~Z73GB;wX=L%0qxblqofQ;pdp04F-B$u`$va^G z&(;CP?$+{*2f8mLYdK_5YSUySVz#Q^SxmHjQ8z(mbLaxyE6j)W2)R-flwbKekV(n@ z>tcina%*dAdCK(Oy=s%cigW6ODeW0rIg9nHu+u>5e7J;qPqC~9XoeP8FNhEPT0Umj zMN8Ce1uv>l2c_PGF|CUpU=ZmE`_atk3}CI zdtioHY1#{)G7HAFR|`pY4_L>9c|ew7!@0fYZY!PKQ%%PUK^5z&n5!B&XyM&nIQGML zv@@3GcK~ZL`|4vi!RL0Ry&fx4##1BO^4Xr^HFl?;b=8M|VdLS+1n~9yt(33u9D0D) zjb{J;yt;of(F>;sPM4N^;G$O=GI^$AEK0#{G50c|?!AaK3Y z`UV|xa||3kRFuno`O>*qn!wg9db|WQ_duuv!B>Ti+qJJ`+MSK0ehc4 z<<@sK4Gnw7ySH0A^j~Xp|7U9_zM5>u;hDb0$m?vMv}gOI_@85}o1M^!++r&Ze12cB zv}3y;f_b-mp&G!(>ut^UXuk1nesaRvWb2Y0ukqVe2!Bp42b|da{>}d!HY4BEyD9qr zIh{;iu1^ygdhG>-UY;-)2I%h2w(%nP3E>#*WxR zBOl=P&?s|mt7bPsYWpUhtljRgZ3*=nJ=35f#p=?llVgof4$~t7BNwpkJ7mw&A9$ZA z4*|i**)c zV8s34V{Yx)GZFc({-d=5`Aym~w^^yXEws~_sohV{JjAU4PseO~!V#cg)u2ubhzj}fcb%~W<6}yapA=d&6=wf7LWhH%MB&l+cA#;i zS=u5UTt_DZK&Ui8BDy_FCw|?W0|cX7VRrP8oN?9ZFOwn@2R7+eK-~~(q2u}Mx0-An z1nhT=Zgh6=EA#R)TEl2%<1$6A=HC9gyG%HECr+gAq_unE<131M>v%!_nUt~Y-LBS5_S#LS5wByDr9dv+%z{4f5%U|0s_5z>eZ3n z7o)jQC&tpXHQl(RM>p#C0-@5@6!j+9^N2uJJ=^JHk3K&?)V{jep2aaf8hzJTnmlD{zh^3e2JsQA;vwr*$4SkfE4W@0pj+S{SNUHb#S3Wt9!!5&Di4ueQHFr)RVAp%w~&)?wg2#W)Fn z^pVHgd?=T3qXpntN@yIqS3h*Gal*ZE^xpyn+R=vKK}=(+d9oM4*eI#Sh-#_I{yje< z1VueBB`QHS$rjzpDJGBkUixAZM}2dUPuXAKDo)R3voVXm3rD}&9`&NF%MHN+%%aur z4>#i?cKVt(^lu!5Sann(A2w#?G08u0)_$kW4%$a2 z9x?<%Vo~&AcJ=}O2`snJ$4#g(a6~Auof_r`m>rbSk})$g^G>%WJ=Wg1PGIDNHM_l+ zAb9%)bkeea#JOV(u5E#|LGO`g5ij|_oO^$e?~zuNnVrUZTobJ&Kw(k)stC2!3C>F` z0~s)`_rjv0l{Ez&5|_n!W3@LP_dsmYf^l`6jft^pyk_^t054v^U>B5|2jqzH-ZK?d ziF7(8^;_I4WB9F$Wa&7Q3fuZYo~*gF3-@8+8mOlz-6En9!Q`L^{YaPv#V>$~)FWZd?*r)k&= z?ZuR5B>$5wefzJQ|50ZG+t)uK=}Qu1-`Xz@6l{}sSKilQ4sC4_C;tP${wi%_Y7dpe zEKkvIHge^e(&ih5AJ4W~V5aBX*zEr#?2+xQ>A>tljz0+Ijn~PPY_q`4w}Cnni#gY~ zw@#)H*(U#NexYz%<-aB+x38izy%bQO55IpAh*edq{v-I71#wSY;;x>znX2;U(ddJ9 zXr2g%x_^Ps6L6#Q#AbgGZNHMbg1oaMcJsmqI)t%F+x>o5OtCQ9CKhcVfDVob?=<_8 zUWjz$TKzYu`Sdq$bedv>J&;)$kt5V zxxzTO^xrN|pEDV~y$5M!&i(fVqbyRKZhLN{42QJ0&qi#$xgR%*Q{O(|XKUH^*7&w< z)Hpw4Yeo-@h-?>kJz-Ez5;QurHSjC`qx9R&s>fRH*uKz1!=aW`W7<9mum2KA4$x;` zTHh}FyKnohsD8*cQ`|gKVZ4|U{rfC!1qDVLDLQt?L$zqhnCRHE#=ov*@h6ufD2j;9 zbvK_`kSKM{Hc>)I#LGrA)~$cn;d*W5D{jH&i!ToA5>=7y*~y%^l^BoP%sc4)ODPtc z+Dl!9%X52PzI?+`wu%^?*NES}&*yJbPBpwUv@9tJt6yk8v4@fIC>_*0+2}*q&B$=~ za)RMXk3P?v@?TpI#eu`-&)W&blvJs66e8GFm`jMfSoG|jZvl&Qq%gY& z-Qm^Nt?J7HNaNk5WCr?)<$%ixo0~a;DfkyQ{#u~KMk5FQ{VEyl(&!@|X{vGXi8$|_ zSnhws`uL{iJxyefG!);;|08@!evTcT{ry{PLx}TfzU(CHM-75~A`WwR%3S}}UwY;8 zr>yn4^;gN7+S7sb z$O)Tk;SMVa1$zkGy|TaTg@|!it@#sY$yFTYyf+g3MjPW#)kU0-7C#nlX(I*>ej*;3?@HW!bsUHer&0&k;S13s;kGv8V+?()Jm0Fa;7 z!=3_?vAH8|5jRJg9$Aeq=4=Wb##>7~{W^GN%jkn9b%e-Jd_zxZ3DoCHE^U#pb_l?H z@0iLC(7us_5|6Cl?8X0b6f3+bK;^(g14qL>tdUfohP}+*7Yheu#M|>mm>-{L-ti)h zVUqx6G$%MmlJCc=3t*P;8q~aW*Z1CPzh*~OEc9}M?q;q;#-Sc`b^Y!QGiVsVS#$j! zCyPwIK6zux&mU+h_WEMV)iO`aOU}nOut4MbluC>O_-|NupRjm=L<<$XZbtb z7rCPBp32uEQ)HO;JULp6|8|&Ye`(Rwi@Rg3V$@!9SI2d2wv&7AeXj7wZVHuuzFnI* zo$4tx_uLyV?Mk|=SnxVY?(>kNtFVt*Nu_Xi^U?A2rspqnSE^ivIR~qDJGmtjc3MQZ zt+~181>ly*i-n_RE9GXr?1Iy61pf`}(2>PnY?ktjCZdCJESrM*z_q>lCGG2e)L&+Dzqe`6_Vp%~(!==hEDhwl+oA-r(sdJ5e-ISaIWr&Ptz2r;VRd0Wa-TzMv^JcMh zg>w?x6XU7J#3F?3O3*((RZGcZR;0DF{L^sn(RqYNGGjNgRuxv9$6f1t^2fhkP$d4U zZ)^gmKji(*S2y;G>uvTE`!FWm;PQLU#Z2~y9}hDB`566; zGVCxl=BdKebp4JH2Ej$r<-PF>sliAbH61BJV03+p(DAHmWH|mVbnN&+HrvmH1yuSiPNph)V*FJEQ@mNtV)6YADZnI%H%?Y}2pl|5^3 zxe$UC$qxO;%%5A~z{!mR?uWGSk=e9*2^!w7=R8iWsZcCB`O!gU?9NC1y=#)!3g3QC zwlLaSkeRnJ1j?lhdxbAY^Un?#Uu3pno6W+L`5RPk&r**YRlbLK-PRZnP7T`5{qWX1 zo*cR2-jQMI_2aS(GelXiD%EWh0KUN~>g>^x&}cB~v-&LfLPo7=idH|)(JF;h&w zj23l8xXlowomT8FRH@_LzNtR?p+T5?=~l}uf1&0SSmgy?{>?k z@g}>G$;+oqpG7PDVyY4)mX^bI*m#XCHdl7VEv@mJHOKiR5unN^(Jz@0_bJGKCaYC$ zD$I4Ivv}kEjCvLc5vc81&#N+nJmv%T_!BWVwc{Iljj>#oy3l2P?x##{g;weOb28y zeiatE^is#k&}#guGVPuUv(urx4VROvq|2QtR_-cfLnzctDi-=&*|N zA5IAObUyx}D&cYIS_74=mg6Il|Q%FygmM z{ug?Bstl`%ILbTLNo8__qYyq^#DeP{pE6X5NzW;%mNJsvL(RMR)|*u1r2M*%waSf! zrMmr0b{XZl=I6&d%7UgBUlDn~r z=kOGt?9g&}z)A@!Z(jOfO{nyzPBd+*PN3-qJD6WkYzQCgEqt`BS(n?X-R7;tPnk11 z?<7h4z4!Gxz~H@2tTRcrLl)~{xC2e4{%^`Lrx+i_(9!Y>0~apkq+n;Td@Q0`>`I>G zGcnHOsq57%Uk*0;&1j#I?hQkqDWf%2pNc(PMZBOi7bKKYI7=FT?fU8MTdF{{e2QOR zYs=hBSdp8e5r2ipGV@#XX>SALSg32<8!ZN|2{UY5siyB6C5`qaV#$2x(epJetN?z0aU=ZV&^r};wp(i9otYLi)a_SU_6?BT z`9_JwQ#-zOKKYx`4%&t9v;{2fVj-@nl%k}8HgK*(=$Ia}I$XMO(aW`4)8cl7Qn#Os z4!;2(bGY`{XMSsIi{PUB`7czSNqi!%z)kDTKADkc64Q)`#;4?4lXOnBz66?xF{CZD z7}2g4D1-mkaeHRl_ETJ5l`|u3%iyp;`t>Rc={Yycbw@f6b_D*S0UUm=3K-bLb0>zv z_EHb7gdwiGzk^S$?m#Uv`l2`VKgnX^8oc39C3?w}s4W}#^)u4-pz%4SODs%;9CA5(v; z(oPXM=#qGq3BDYWTmD%x2T?xiXsR1!d}=yzXBRc{=EfR$R!AtH%9FE8nNK#bY??

_a&^Y8r>Lq>YCVP+|mMW2<5vy23{RNIJ@;LRe3bU>>}VidvopPEc)CmW=l>5Q$z0J z^0<1P6XJ5l(Zna(m9wu#2lyt&j4Aucc7~>>Xo-*+WmE5_z= ziF-Xem#6JyR0GFE&jIGKprwBgCB~VX)qP_4HeOm%Xe4^?0==4zcAmTD?ZwJ_+|N)d z6WF78KYOSJ3rKFQ_heQwH}&@|?MhoB-VT-3rQILYYx1d+Dmk8c*s}Y>P@C8H4!bpt zBcfGOyv<1Q&}aQ2cjv`UJ9~}Cwih?GdRiZC*~7Rtp^wThsTJJI*E@F6t;rte&vT0y zcd63u)DgOjIfvEu!YhW4gCy(s;!qDx*+u$UWZNSzVt@nsP-5=tMB`D@Fk zS3&s1IQ2?UwkE5`CSy;mgsrUJ*} z1)Ol7OZdWk^UTBVI7yp?h*g*$nUI4TjMU+4=Bo|76)8Uxl!rW(EMH~SFqfxDKTx;) zUV9t+sofpd+(V)itxMuQ)XUb%BCyxtC^W&-FnFq0X4lhncm&;G2 zD?K)wOFAW*^K~@M_A~YCRDv?bn{NpD+yZ0Z9q^EvB6I7$+|TUyt=Cq?7R8-KNh;PY zBBG)e$Isv5LzX%tC$dAlvlaFTy*1B|RlQ>s7mBc-)V`RN=AoK;#g-3R z-pqfCA50D<$YtQNh_9!`P%FU?#h)_q$&c=)vi*IS&olZI)r?6?Iv;Q$PVyN$Mn0P3 z^yB2e_U(|*OZZ_%XVspupR1miShslJqm})JlCyYwN$#@Jg-oTuf<3#7D_x@42kKDY z&$zFk)`!22*H}z@$dnw=8PvZmyNB+eVc4Em?~m$ee-y=@_~5#S!QePPVK+%+H+ks* zDK%x#(o;vQ;?+xK4DM?{=K+ck)l5EveC;7M)akftu(OZg+8$J17)eRKCHCSStDYQc zdu40d@4`y|`F1hN#RqQ46=b5)-GoWaHyykRcgF9a!g&=U2|LcxN0~6*?iHa6AG@W? ztjwTT`%jfeaNrqgHpx0@C`3Vybw`kHFkQDdT&|=TLV1t7>9AEyPTfdEobgvDEbo`taQw&Z}ZEL7|VR9k(l@+A@IG+EJu^eIF&pR*O+ z1yB!~)CRu~-G!X%EnOGmtBqM~uCRTyT#8Rh47I2%vv^osluXe~i5H7+ zNc2_X^{~l{grc-jVYlxIx7LhF8kH^Rzj^DWQlwbvcI-T|!jkQGp9q7<$2s)+TPja4 z6pDd#7ql%iBG!@;UK>K0vprbR=y$WZCoQmbJ^&etuvtE@zeInn)tJqV!Qi}_)gQ9A z$)LVtVsM~;zk#%I&GJpFnq2yQ!6WOo71}bPj0}5r7G9TBm0<{Ya&;vES>3sVvVIj^ z`-ODlFewvNfmyu4aGKa;sg0I-)Lm+mK^6au&Rc=U;`R+!l3;|C?VoC@s*6Wy0{P3E z3lhjPE;nxuN$XkTo`taPbnL0$_x%yoHO7hW%&(G(8@s=WzIlY_OZr`}L-Aa8Th?(`tST5aKMYe6(C}|gFJyXQJkf zr-aO|8jXG^5vpzG->T$gZGz7WxtRCb>ayd)n_8tn^|^`U8Qz-T^0wtnI-d71yhX<6 zr30@h$ox}WT_cCtL022Z#xbw4m$dST68`|*h+7igMP2-i-d%d&ea$?MWV~Y!wUC{n zL1{7|@qfpO);{0GGVM1;lUL2;v2b8s-1M!xRKAu!xlan=t(o58qZD}hDPk1g`j=OM zxPHSWI8a7x=liJpfmc4gen<=#O75wc(F~^Sjxq1zzkeTnOu$Ys3$wc`=l1O*l&8Ve z^D{TtDQ>yWt)KsSaFtrP>Mz|iQ2OD+y?eF(&G68BYbtu$gs#q*h|)_+^J72Le-0I* zKRlHgKR=LngMLzkvEzIyIYCYR|S4yu$No1kX}5G2cV>Ce<6?e zAg18(6yLv^Zc2d}PJB9y?~0htxdcjcyveE==rblt88Dq$DdYOsWFEf7d%mSiuJB$bHh&(;N+4oh&Lb~8EWP)+rfe@&g(SJ4_@|ptp19f$ zQ|dQKS9v6LT)DC(Dki3G*33!#Wmgislij=81O5qkBi$Cf9p214mV z=?xA}oARvQIJT}LcCz#1yJf!My&+L6z3 zM<_Wg)H3PJ6#^LHU{)#HF)HqvplDGMp zDkfz7{S#FI7Mw)l{UG0G&GRvdg8TD%74qdS>ITk5d7rjpO;SlsGWx<8w1@7&ejSli z`V3i>>?zkI>hc+u?+*3JLC?9eEo+B~hPgBRiOa`#Q}o4d*<#kI!$GLCW2%BH{K8Ym ze}%r_zK!~$P)L|zm&xM`v&Q}u{n1*2Q&>d~XI`aN96so$7dmz+@prghPrM%9Dl^gv w3k)R>e%EG|9nhBl|LgzH!2jDB7`#p0Z?@*tykyYufY!2_l9poL6|4LI3$S?WrT_o{ literal 0 HcmV?d00001 diff --git a/linux/icons/hicolor/128x128/apps/me.zevlee.Passphraser.png b/linux/icons/hicolor/128x128/apps/me.zevlee.Passphraser.png new file mode 100644 index 0000000000000000000000000000000000000000..81ee6711fe12650ff6d49bf7be99a0cbaeeb3a45 GIT binary patch literal 3613 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 Eg5lVcaR2}S literal 0 HcmV?d00001 diff --git a/linux/icons/hicolor/24x24/apps/me.zevlee.Passphraser.png b/linux/icons/hicolor/24x24/apps/me.zevlee.Passphraser.png new file mode 100644 index 0000000000000000000000000000000000000000..c84297c3b792dacf02b3476c03b5f7dd45c3e2d3 GIT binary patch literal 1080 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 literal 0 HcmV?d00001 diff --git a/linux/icons/hicolor/32x32/apps/me.zevlee.Passphraser.png b/linux/icons/hicolor/32x32/apps/me.zevlee.Passphraser.png new file mode 100644 index 0000000000000000000000000000000000000000..f8b3888662f2ac799450bcb7c67005267ec26fd1 GIT binary patch literal 1196 zcmV;d1XKHoP)EX>4Tx04R}tkv&MmKpe$iQ;Sk64t7v+$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMxx6k5c1aNLh~_a1le0HIM~n$AQI0q!?cMvh^IGg zgY!Odl$B(a_?&pmqze*1a$WKGjdRgufoDd|OnRO;N-P#TSm|I^GBx5U;+U%GlrLmG zRyl8R)+#mDx+i~OB(JY5bDicel32tNB#2N@Lm3s=h|{W*Vj)fY2_OHE>zBx-kgE(v zjs;YqL3aJ%fAG6ot1vm?B}EcI=*4k9Mu6^JpjmgE?_rFCJM)-Dz*Rs0;x$vK~z}7?UqYx6Hye$e|P3K zP1@R|Ngp7ULQ73+#VS%z5UL>Pz7)g{py0xV?z(ZSyMhJx;>L{&=?72*7gEuvh+1sZ zx2S!jNoJB}a*vCYw%Q~{>0{IX?w;rW%$alUg##R5pP?l7pgA}BcwXEe_MRo}xq(^! zgj59|YA^40?`3k71vRbM7@Y54F6f-yoUQJ=v&SDk3pFidnp%JIVz_@<_6hNL{Fy${ zxDrZ?Uftb-yRQ-KIA2ty{k8|GcV+#nE>bJ|C{@Qd?V#<2Z!F;fgwA0Xj+3OqFeplrs#!xeh35 zw#YgFZvuSl=Kx>;Kj3V2mOQ5OT*=saJb!%T%$581cJm*sFQe0e#Ou3~n%&*qL#{c9!ZlI%P1h1w~_K#52@@O3{PBU4i| z&-IQ)^IVdn1C^Wi+yY-GJ4ZnBRA;6)M>lj7jE4$#f~Aq=kI3rehTe6S!N(2~_><3S z9911cRz5>6iL52J+pLdaW=AsW0Ew<4M5H3~z~R#*R@P7eu~=**lu`<%EG!E^ zQ8*XwF6*~tsEX9HIbIlpK!K2eF#;Gw3bK6OFg7-p;Q$BNZ~OvtAaA4i$ofnG0000< KMNUMnLSTZu|0Wp# literal 0 HcmV?d00001 diff --git a/linux/icons/hicolor/48x48/apps/me.zevlee.Passphraser.png b/linux/icons/hicolor/48x48/apps/me.zevlee.Passphraser.png new file mode 100644 index 0000000000000000000000000000000000000000..09d2b7734a151777efd8523e0e2b370503a70bfd GIT binary patch literal 1612 zcmV-S2DABzP)EX>4Tx04R}tkv&MmKpe$iQ;Sk64t7v+$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMxx6k5c1aNLh~_a1le0HIM~n$AQI0q!?cMvh^IGg zgY!Odl$B(a_?&pmqze*1a$WKGjdRgufoDd|OnRO;N-P#TSm|I^GBx5U;+U%GlrLmG zRyl8R)+#mDx+i~OB(JY5bDicel32tNB#2N@Lm3s=h|{W*Vj)fY2_OHE>zBx-kgE(v zjs;YqL3aJ%fAG6ot1vm?B}EcI=*4k9Mu6^JpjmgE?_rFB`cudX)6E#1W8FmK~!ko?U-F_Ttyhie{**B zt(((icTJPpt!|Ri8rvd*L9Jd!Aw&v#QLw>VA&C6|YD?)w?}YjV>{V|J0r5hqP(DG8Mq3DWN!-TlW|MAqH#xiK%y_ZcY%sOimqd19{~VY(XU@z#FY`SAnSmBsXrYA` z>VN>SZhvve$j+PvEgN29PsoeCR1k)Yxdx0;2_RB;zgDwX`x@Tbk+;#ij-ag+;>Kwn zuN+Go0K!>rYl`L4aR7VnS3G6}q@TYZ+e1b(t#@_*JYJ6%=Z`O;kU@i6e*5u0uXyeA zdmgv1tJwm0_NQy}(&(_Sr4xTXAB?`*bQwqsx0ZXKalfo{kFq*5(?E+|AOd?T`c>}R z<$*h&1qyc>$+9l&cdil$1U6TomI;i=AV$y8?FrP_cR17EqqVNYQMD-`%qa7o!z2<3 z{C+8jj7z`2$ zh04}nybsfr%ThD*j*pLX{rYtV1_qdzm>?7i(bd&OB9S1SP7@3U$>;N&J9iG#G$|Ac zEG;dON~P%T?#Ao&Vp$faPMxZ2BT=&gkw}EW!9h&ZWO#U(TrNjA944F1a{2OQhK7c4 z90%LB@%emYG8v?lEG#V0+uKV#9>+9Id_G@YOHKj`sEW|^{B4H%c0yqeQtKM#Aq*UU z1xS2T{+@=8)oQm3i2XtjKnk4Hzs64dR!uY_XI8q#!|mSp9Hm_q_gk2Sg|Y3+LUJ$O zNaHht$m&k-K%w*gl zpU-0$F0|HYt%_R#rBO;DgeY25YYf9cO36!+%|lK2JF9S29ZcNU+qdy_twF6SVu&KO zl-?gcjBQU4*V@tNuZ}@W9@*lpA5tS6K@}thsM#xMJ5$wEQCnf(*qre7{N3t25L@oP zu&cv=T&Y6k-pFJibERr~EpIs!Yvjeu(GN#I7~L(Ue5)CW%s6r4ge9e1X-467JwaS6 zvJ>ZVrZ3eshV$G}f`^XPmqu%az3>2k`qsuQwPQCr_h?;o2Efifag1d0Ai;Xm=+@u5 z?MH+UBX;(ot$BpmgHGN;O<(-)Y^ZeOD4;Vl;H;oi_Ym!UsQAz5!qWB;*_JDio+{U~ ze^pLotF_$!CFqXV&tO@f)-^^*7R9zK%T-d~bTXOjGz^#j$&7E5o~Li(Hx?VxUb*u0 zdmp7(J+5yYBcCtuFc!0J-n?~SZJv`S&%7a}c+)US!WtMxQTTFMYI9M1iYk@b*XjC% zdjeG!N3Hv^DyZX>1b2!ps@%R-Dz#R39EIcPOSI5J3oW!z5B>o<*O)?z_-z{i0000< KMNUMnLSTZkJo>Ew literal 0 HcmV?d00001 diff --git a/linux/icons/hicolor/512x512/apps/me.zevlee.Passphraser.png b/linux/icons/hicolor/512x512/apps/me.zevlee.Passphraser.png new file mode 100644 index 0000000000000000000000000000000000000000..b62fb2c82453f8d848bee08e59afa02d833521ca GIT binary patch literal 17342 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 literal 0 HcmV?d00001 diff --git a/linux/icons/hicolor/64x64/apps/me.zevlee.Passphraser.png b/linux/icons/hicolor/64x64/apps/me.zevlee.Passphraser.png new file mode 100644 index 0000000000000000000000000000000000000000..b972e3c0afdcb107c5615b9c633d600b80507991 GIT binary patch literal 1873 zcmV-X2d?;uP)EX>4Tx04R}tkv&MmKpe$iQ;Sk64t7v+$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMxx6k5c1aNLh~_a1le0HIM~n$AQI0q!?cMvh^IGg zgY!Odl$B(a_?&pmqze*1a$WKGjdRgufoDd|OnRO;N-P#TSm|I^GBx5U;+U%GlrLmG zRyl8R)+#mDx+i~OB(JY5bDicel32tNB#2N@Lm3s=h|{W*Vj)fY2_OHE>zBx-kgE(v zjs;YqL3aJ%fAG6ot1vm?B}EcI=*4k9Mu6^JpjmgE?_rFB^vQQX%PSb1x`ssK~#9!?V4Ro6jv0-e|Khf z*$-faW$OwAi2~wBn~I>uhRTDs540vm?L!lzFHIWLH2R=v(l+o`-x|~S)h0G+Bqk=c z!3V3=wl4y~79U7gu!UMb3yZLeumdbRbNhf$ZH&4wQkI>6GPyImGk5R#&zy7q=j?zD z8#Zj%uwlc7jr4>7kfGDgM9=r#W?x$&(wLuyW)`9>u0=*VFne23g0HnXUjL#}129Ja z++~KZ6wce*tZ2wr4q!-wgqnlXh-2RUY0deQ2j5iyB#E4P{hT|pQ2Z}5-hBp_e<{LO z0>J$t^J66~9DOW;*>wu<#?QeV$Gmk8027&`0Vs|fUFNQs-z4;2X8isyV2pt$i0}k4 zA`YpY-htZhDvt%;*pqe{KtFQSP_oL4&-~SV;zYXUK*f_G-cDZ)AkbD9xy6v$L#*|) zls3l9E+cFCwxqAqG8}>odf-MwN)vG3vvwK;2sEn}psqfEP@J=W=c65%-QP|-23SWx z$vdFBp8Nc8I7}oGVcD`}GyCB?m!?gCz(N85PM$nTcXu~iw{E4mxtaX@e0q9%C@3f( z91fG4o6F6cHyIchpsK2hhK2^VZQDjyR~MzFrG&#_7A;ytUtb@=V30^8!ri-fsi>%+ zsi}#&x;hlaLhU9jCZN5&oj@Q!V`C$sPzZpEiVCh@zfMt65p8X4^!N9(YSk)2p%67S zHC(uGfkYy~&Ye5iw{IT+m6erTyLOF^jt&Y73z1T?Y11Zaji1Z{R!-=4yIHqx9aU9T zghC;_UN6JL!{p`V5sgNvt*zzo;lpg+yqU7HGIU+1y1E*GU@*x3{rmBHy~JWM{C+rz<=y)@lk$+=I9_d2@2dOuz30nMq3gJxnZBW(#-QIL`GKpDjBZAtCQ&XtGol_oEQ z{Fy3#Zjku-y_7G8l1+n13zeX{~u`8?&cr`YvFZFI9XrV8Ya4~6N~9MoDLTFe3(*V8U_!Bh6n@# zvmXSloNQywMl?-BN{ON<7>0pqnkb5bs;Zc#i4cNBA^`|8oKD8#@rUCWot@WbTS!|= zfY0Yk`Wlzp_1HMum{Wg@xc>(dG$}EJK%MDC<3H{OF|%ow1LGHyt-_)+BS1IZ$6RWB zkBTv)Qce#1mU7xbBGC^0QTySB4I36#R#t9LWg+C5PPa%-z8@gvCg37zhNH)h-&ROx zNQ-rVWr#muxVawFG_BA4xvN?5>aHmU<|F|!F@m$_hZj>c=_8L2FvoPjbBmXvHz%su z>?PpHMC7hS1lAz3iV+LSlFI@q>AQ~13BwnzMR6~LgpTkmLdK&o+K&%$j5Sohy3eCk}W)+5E z{X2_e?vh7b;9mj;<`e@?AAz^Ne&Mz7h^}X8078hX!^6XeTrSs^r}qdZ$^{|juzScy z9Q-K{LTl@ld$E{aF=a}9eSJ14XN3^eLI_0&!LzpsHl~gdAb7a{@Vm*+{==Mja!h*6 z68VHtO8MCSxNaT<-_yij^Y}l}2!-fqTX^MXUTe}3x`~<4300000 LNkvXXu0mjf)~s#U literal 0 HcmV?d00001 diff --git a/linux/icons/hicolor/72x72/apps/me.zevlee.Passphraser.png b/linux/icons/hicolor/72x72/apps/me.zevlee.Passphraser.png new file mode 100644 index 0000000000000000000000000000000000000000..988c4ec8ff00a7155174bd0ccd2feb43de0c7a64 GIT binary patch literal 2131 zcmV-Z2(0&sP)EX>4Tx04R}tkv&MmKpe$iQ;Sk64t7v+$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMxx6k5c1aNLh~_a1le0HIM~n$AQI0q!?cMvh^IGg zgY!Odl$B(a_?&pmqze*1a$WKGjdRgufoDd|OnRO;N-P#TSm|I^GBx5U;+U%GlrLmG zRyl8R)+#mDx+i~OB(JY5bDicel32tNB#2N@Lm3s=h|{W*Vj)fY2_OHE>zBx-kgE(v zjs;YqL3aJ%fAG6ot1vm?B}EcI=*4k9Mu6^JpjmgE?_rFBrGSN&B*`&22e>vK~#9!?V4R|6xSJspL1q* zy0kE~v+>n;G6apkyDg>028>72N|t>e>R&*30;pSmMqN9K@Gh}_`SE6-1W;YSu6o|(*iI)-HTGZWMSE<{4TWXa7CvuCsBe(EYH=rW_M2$z%`xVWaAi(K3 zMA@qEAOjn)J6j+XpHyhW1i<~6EtfVw+9dV7moB&#km2HUiK#$*-1g4W##i3brt~GK zzZ^!MJGlIh!?!yxYdXH#36d_CcttaDFMb5(lfe?>i&0R+T}Aqo0#VVBvjv$IUV{oR zSm&QFPVp5k63rjr_xp3Rp#1lkk^av;HQ=PuCCAC#g7WT_KJy#olC5(;0}WikdVluv zI&U1six)3)`SSdlObau_fWE#y_Uze%$K&C^fdia6b&3@$R&e9S4T8ZSfk1$+t}eE3 z-_DUEM<^*Np}D!4^XJdAdi83?#>Nmruwlan&YnF>C=}xO@#E~;wTpA-&Jm49*|B2> z$BrFi|Ni}K+O(-~(|jS?O{G#K5($#YB(1Hjba!{t-ri1qeLbg7pQg69mX3}Ny1Tov zEQ@$NPCOoG=gysUc6Kr_Fu=Zj`#5pp1b6P-p{J(@pU+2YYbzHnT);34Zr{Gm`t|Dz zM@}Iv2p|v$uy^lX8X6kdvSkb9<>f>o5n5VWsIIOi6bi9y*)rPN+St8&H+6M&n5N0f zl`An#6Q9q=;lqcC#bN}5LCVU?Xl!gG6bfg&$_gx1Usb73r~-F7AH!eJU#}XWYiG-Z(OD0x9x1o7tbfiMV+N_e8^A z2iF7En=wJjaDF=6L7tR2Kg`>W4P8S~JTN^kUi;CXe*3egZJXDvFUp8qNvb@a+(r7# z^T^=0KYP9Isn_4t;pta6ioP|=-?GDbamhF zj~@Ew_U}Err6@&22o`z0vl?PFZhme@-I|Sev?TxU5R(8KH*Sn;I__gZ4@cBF4%Yvn zAKkvptMh_6iiN=V&G+ESPYZsX(WW=4e*Bq?1<8lX-oG|dF1g24^xz_GS=O{Gn#Cj; zM*R!e-6xStwxULFBFgJg$zeq4VlX_Yp{uCazh}@Vs<;S37zj@lcx#XqYr#$+j3*|> zXao`5hTVN~?t|4i)A6CJQ1%!q{25O4Ul{c-qLM?X|6B&gn)!E2s>p_z8n`k&+PMCQ z%tutS@`H*N&g@=lt1JsjO^CLbw=vPG9}up3w&2&PoC-@E +image/svg+xmlpassphraser diff --git a/windows/passphraser.spec b/windows/passphraser.spec index b5dc9e7..51af705 100644 --- a/windows/passphraser.spec +++ b/windows/passphraser.spec @@ -10,7 +10,7 @@ a = Analysis( ('../gui', 'gui'), ('../lib', 'lib'), ('../wordlists', 'wordlists'), - ('../passphraser.svg', '.'), + ('../me.zevlee.Passphraser.svg', '.'), ('../LICENSE', '.'), ('../VERSION', '.') ],