From b5e3cee3e1686989f5a6cc9e171b92173766d51c Mon Sep 17 00:00:00 2001 From: Guenter Bailey Date: Thu, 19 Mar 2020 20:22:11 +0100 Subject: [PATCH] Rewrite to Python3.6 --- .editorconfig | 22 ++ .gitignore | 6 + LICENSE | 629 +-------------------------------------------- bin/__init__.py | 14 +- bin/findenv.py | 47 +--- bin/license.py | 15 ++ bin/update.py | 75 +++--- bin/version.py | 21 -- conf/__init__.py | 4 - conf/config.py | 44 ---- lang/__init__.py | 4 - lang/lang.py | 139 ---------- requirements.txt | 1 + setup-linux.sh | 51 ++-- setup-macosx.sh | 11 +- setup.py | 105 ++++---- support-client.ico | Bin 0 -> 360414 bytes support-client.py | 528 ++++++++++++++++++++++--------------- 18 files changed, 517 insertions(+), 1199 deletions(-) create mode 100644 .editorconfig create mode 100644 bin/license.py delete mode 100644 bin/version.py delete mode 100644 conf/__init__.py delete mode 100644 conf/config.py delete mode 100644 lang/__init__.py delete mode 100644 lang/lang.py create mode 100644 requirements.txt create mode 100644 support-client.ico diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e2f707a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# Set default charset +[*.{js,py,rst,json,yml,html,txt}] +charset = utf-8 + +[*.{py}] +indent_style = space +indent_size = 4 + +[*.{html,js,rst,scss}] +indent_style = tab +indent_size = 4 + +[*.{json,yml,css}] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index da04d96..3e495dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ # pyCharm .idea/ +venv/ +venv_python27/ + +#python +*.pyc +*.pyo diff --git a/LICENSE b/LICENSE index af7fb9a..7dcd04d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,623 +1,12 @@ -see under +Copyright 2020 Günter Bailey - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/bin/__init__.py b/bin/__init__.py index af6c4d3..d2d34e4 100644 --- a/bin/__init__.py +++ b/bin/__init__.py @@ -1,5 +1,11 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- +from gettext import gettext as _ +from datetime import datetime -from findenv import osenv -from version import version +__version__ = '1.0a' +ABOUTPROGRAM = _("Kleiner Helfer für den Telefonsupport") +ABOUTTXT = _(f""" +Mit dem Support-Client kann man einfach bei einem Telefonsupport die Anweisungen folgen und z.B.: die Fernwartung starten. +Ohne dabei mit dem Browser on sonst irgendeinem Tool nach dem Fernwartungsprogramm zu suchen und Herunterladen versuchen. + +MIT @ {datetime.now().year} Bailey Solution""") +PROGRAM_NAME = "Support Client" diff --git a/bin/findenv.py b/bin/findenv.py index c71b08a..2250b8f 100644 --- a/bin/findenv.py +++ b/bin/findenv.py @@ -1,38 +1,13 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -############################################################################################################################## -# Support-Client . # -# Copyright (C) [2015] [Guenter Bailey] # -# # -# 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 . # -############################################################################################################################## -from sys import platform as _platform +import platform -class osenv(object): - def __init__(self): - self.text="Text" - - def __new__(self): - env=() - if _platform == "linux" or _platform == "linux2": - env=("linux") - elif _platform == "darwin" or _platform == "mac": - env=("macos") - elif _platform == "win32" or _platform == "win64": - env=("nt") - elif _platform == "nt" or _platform == "win": - env=("nt") - else: - env=("linux") - return (env) +def get_osname(): + env = 'linux' + if platform.system(): + if platform.system().lower() in ['linux', 'linux2']: + env = 'linux' + elif platform.system().lower() in ['mac', 'darwin']: + env = 'mac' + elif platform.system().lower() in ['win32', 'win64', 'windows', 'win', 'nt']: + env = 'nt' + return env diff --git a/bin/license.py b/bin/license.py new file mode 100644 index 0000000..1e9be74 --- /dev/null +++ b/bin/license.py @@ -0,0 +1,15 @@ +information = """ +Copyright 2020 Günter Bailey + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. + +""" diff --git a/bin/update.py b/bin/update.py index db279d4..bbc644e 100644 --- a/bin/update.py +++ b/bin/update.py @@ -1,38 +1,16 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -############################################################################################################################## -# Support-Client . # -# Copyright (C) [2015] [Guenter Bailey] # -# # -# 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 os,zipfile,shutil +import os +import zipfile +import shutil from os import curdir,sep -from tkMessageBox import showinfo,showerror -from bin import osenv as _osenv -from lang import de_DE, en_EN -from conf import setlang -from conf import check as _check +from tkinter.messagebox import showinfo, showerror +from .findenv import get_osname as _osenv +from gettext import gettext as _ +from subprocess import Popen, PIPE support_cldir = "support-client" -ltrans = () -if setlang.langn == "de_DE": - ltrans = de_DE() -elif setlang.langn == "en_EN": - ltrans = en_EN() -else: - ltrans = de_DE() def chk_connection(): pingopt = '' @@ -52,6 +30,7 @@ def chk_connection(): stat = "Error" return stat + def forceMergeFlatDir(srcDir, dstDir): if not os.path.exists(dstDir): os.makedirs(dstDir) @@ -60,10 +39,12 @@ def forceMergeFlatDir(srcDir, dstDir): dstFile = os.path.join(dstDir, item) forceCopyFile(srcFile, dstFile) + def forceCopyFile (sfile, dfile): if os.path.isfile(sfile): shutil.copy2(sfile, dfile) + def isAFlatDir(sDir): for item in os.listdir(sDir): sItem = os.path.join(sDir, item) @@ -71,6 +52,7 @@ def isAFlatDir(sDir): return False return True + def copyTree(src, dst): for item in os.listdir(src): s = os.path.join(src, item) @@ -86,18 +68,21 @@ def copyTree(src, dst): else: forceMergeFlatDir(s, d) + def msdelupdate(srcDir): try: os.system("rmdir /s /q "+srcDir+sep) except: print("fehler bei update delete") + def mscopy(srcDir, dstDir): try: os.system("xcopy "+srcDir+sep+"*"+" "+dstDir+" /Y /E") except IOError: print("xcopy fehler") + def extract(fpath, fname): ext = (fpath+sep+fname) try: @@ -115,16 +100,12 @@ def extract(fpath, fname): class start_updater(): - def __init__(self): - if _osenv() == "nt": - updname = "scupdate_win.zip" - else: - updname = "scupdate_linux.zip" - - self.url = ("http://download.bailey-solution.com/Support-Client/"+updname) - self.dldir = (curdir+sep+"temp"+sep+"update") + def __init__(self, config): + self.cfg = config + self.url = f"{config['remote_app']['server']}/{config['remote_app'][_osenv()]}" + self.dldir = f"{config['tmpdir']}{sep}update" self.fname = self.url.split('/')[-1] - if chk_connection() == "OK": + if self.check_connection(): try: self.dlprogram() extract(self.dldir, self.fname) @@ -134,8 +115,26 @@ def __init__(self): else: showerror(ltrans.programm_name, ltrans.label_update_error) + def check_connection(self): + cmd = ['ping'] + if _osenv() == "nt": + cmd.append('-n') + elif _osenv() in ["linux", "macos"]: + cmd.append('-c') + else: + cmd.append('-c') + cmd.append(self.cfg['test']['ping']['repeat']) + cmd.append(self.cfg['test']['ping']['server']) + p1, error = Popen(cmd, stdout=PIPE) + if not error: + return True + else: + return False + def dlprogram(self): + import urllib import urllib2 + if not os.path.exists(self.dldir): os.makedirs(self.dldir) diff --git a/bin/version.py b/bin/version.py deleted file mode 100644 index b792379..0000000 --- a/bin/version.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -############################################################################################################################## -# Support-Client . # -# Copyright (C) [2015] [Guenter Bailey] # -# # -# 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 . # -############################################################################################################################## - -class version(): - versionnum = "0.9.5" diff --git a/conf/__init__.py b/conf/__init__.py deleted file mode 100644 index 25d9a8f..0000000 --- a/conf/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -from config import dlsource, setlang, check diff --git a/conf/config.py b/conf/config.py deleted file mode 100644 index 7295c98..0000000 --- a/conf/config.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -############################################################################################################################## -# Support-Client . # -# Copyright (C) [2015] [Guenter Bailey] # -# # -# 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 . # -############################################################################################################################## - - -class setlang(): - """ - langn="de_DE" oder "en_EN" - de_DE => Deutsch (German) - en_EN => Englisch (US) - """ - langn="de_DE" - -class dlsource(): - """ - Verschiedene downloads für verschiedene OS Systeme - """ - twclient_nt = "http://download.teamviewer.com/download/TeamViewerQS_de-hse.exe" - twsafe_nt = "teamviewer-quick-support.exe" - twclient_linux = "http://download.teamviewer.com/download/teamviewer_qs.tar.gz" - twsafe_linux = "teamviewer_qs.tar.gz" - twclient_macos = "http://download.teamviewer.com/download/TeamViewerQS.dmg" - twsafe_macos = "TeamViewerQS.dmg" - - -class check(): - # Minimal Ping bei Windows ab 1 - pingurl='www.google.at' - rate="2" diff --git a/lang/__init__.py b/lang/__init__.py deleted file mode 100644 index cdcea3b..0000000 --- a/lang/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -from lang import de_DE,en_EN \ No newline at end of file diff --git a/lang/lang.py b/lang/lang.py deleted file mode 100644 index b62a9d4..0000000 --- a/lang/lang.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -############################################################################################################################## -# Support-Client . # -# Copyright (C) [2015] [Guenter Bailey] # -# # -# 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 . # -############################################################################################################################## -from bin import version - -class de_DE(): - programm_name = ("Support Client v" + version.versionnum) - programm_shortdesc = """ -1. Prüfe Internet Verbindung -2. Download Teamviewer -3. Starte Teamviewer -""" - label_update_error = "Fehler, konnte nicht updaten" - programm_description = """Falls Sie das Programm noch nicht verwendet haben gehen Sie bitte folgende Punkte nach der -Reihe durch: - -1.) Prüfe Internet Verbindung -2.) Download Teamviewer -3.) Starte Teamviewer - -Falls Teamviewer schon Heruntergeladen wurde, können Sie auch gleich mit Punkt 3 beginnen.""" - - # Menu Datei - button_filemenu_label = "Datei" - button_filemenu_end = "Beenden" - - # Menu Konfiguration - button_config_label = "Konfiguration" - button_config_editconf = "Einstellungen" - - # Menu Support - button_support_label = "Support" - button_support_teamviewer_download = "Download Teamviewer" - label_shortdesc_teamviewer_download = """Lade Teamviewer herunter.\nDies kann eine kurze Zeit dauern. - -Während des Downloads kann man das Programm nicht verwenden. - -Mit OK schließen Sie das Fenster""" - label_shortdesc_teamviewer_download_fertig = "Download von Teamviewer Beendet.\nWeiter mit Punkt 3." - button_support_teamviewer_start = "Starte Teamviewer" - label_update = "Nach dem Bestätigen startet der Update Prozess" - label_update_finish = "Update Beendet, Bitte starten Sie das Programm neu" - - - # Menu Help - button_help_label = "Hilfe" - button_help_steps = "Abblauf" - button_help_online = "Online Hilfe" - button_help_aboutus = "Über Uns" - button_update = "Update" - button_to_update_url = "Update Webseite" - aboutprogram = (""" Support Client - -Dieses Programm wurde Entwickelt damit Kunden einfach zur Zeit ein Fernwartungstool downloaden können und falls es ist auch noch zu starten. - -Copyright © 2015 Günter Bailey -""") - - # Display - button_connection = "Prüfe Internet Verbindung" - display_connection = "Internet Verbindung ?" - display_connection_true = "Verbindung OK" - display_connection_false = "Keine Verbindung" - - -class en_EN(): - programm_name = de_DE.programm_name - programm_shortdesc = (""" - -Check Internet Connection -Download Teamviewer -Start Teamviewer -""") - - programm_description = ("""If you have not used the program, please go to the following points after the -Series by: - -1.) Check Internet connection -2.) Download TeamViewer -3.) Start TeamViewer - -If TeamViewer was already downloaded, you might as well start with step 3.""") - - # Menu Datei - button_filemenu_label = "File" - button_filemenu_end = "Quit" - - # Menu Konfiguration - button_config_label = "Configuration" - button_config_editconf = "Settings" - - # Menu Support - button_support_label = "Support" - button_support_teamviewer_download = "Download Teamviewer" - label_shortdesc_teamviewer_download = ("""Downloading Teamviewer.\nThis may take a while. - -During the download, you can not use the program. - -Click OK to close the window""") - label_shortdesc_teamviewer_download_fertig = "Download TeamViewer Completed.\nClick to Point 3" - label_update = "After Accepts starting the update progress" - button_support_teamviewer_start = "Start Teamviewer" - - label_update_error = "Error, update fails" - label_update_finish = "Update finish, please restart the program" - # Menu Help - button_help_label = "Help" - button_help_steps = "Proceeding" - button_help_online = "Online Help" - button_help_aboutus = "About Us" - button_update = "Update" - button_to_update_url = "update website" - aboutprogram = (""" Support client - -This program was developed so that customers can easily download at the time a remote maintenance tool and if it is yet to be launched. - -Copyright © 2015 Günter Bailey -""") - - # Display - button_connection = "Check Internet Connection" - display_connection = "I-Net connection is ?" - display_connection_true = "Connection OK" - display_connection_false = "Connection fails" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..783fed7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +cx_freeze>=5.1 diff --git a/setup-linux.sh b/setup-linux.sh index 4e065b0..3602e15 100644 --- a/setup-linux.sh +++ b/setup-linux.sh @@ -1,31 +1,32 @@ #!/usr/bin/env bash sfile="Support-Client.desktop" lsfile="start.sh" -ver="0.9.5" +ver="1.0a" echo """ ############################################################################################## # Support-Client setup v$ver # #--------------------------------------------------------------------------------------------# -# by BS @2015 # +# by BS @2020 # #--------------------------------------------------------------------------------------------# # this tool configure the $sfile for easy starting the program # ############################################################################################## - """ +""" + echo """ ########################################################################################### -# Support-Client v$ver Copyright (C) 2015 Guenter Bailey # +# Support-Client v$ver Copyright (C) 2020 Guenter Bailey # # This program comes with ABSOLUTELY NO WARRANTY. # # This is free software, and you are welcome to redistribute it under certain conditions. # ########################################################################################### - """ +""" if [ -f $sfile ]; then echo "Datei $sfile vorhanden" echo "file $sfile exists" else echo "Starte Installation von Abhaengigkeiten" - apt-get install python2.7 python python-tk + apt-get install python3.6 python3 python3-tk echo """ Erstelle die Desktop Datei $sfile Die Sie nachher auf den Desktop kopieren koennen. @@ -36,22 +37,22 @@ after then, you can copy this file to the desktop Support-Client Pfad $PWD Support-Client path $PWD - """ - echo "[Desktop Entry]" >> $sfile - echo "Version=1.0" >> $sfile - echo "Type=Application" >> $sfile - echo "Name=Support-Client" >> $sfile - echo "Comment=Dieses Programm wurde Entwickelt damit Kunden einfach zur Zeit ein Fernwartungstool downloaden koennen und falls es ist auch noch zu starten." >> $sfile - echo "Exec=python support-client.py" >> $sfile - echo "Icon=$PWD/bin/image/support-client.PNG" >> $sfile - echo "Path=$PWD/" >> $sfile - echo "Terminal=false" >> $sfile - echo "StartupNotify=true" >> $sfile - echo "GenericName=" >> $sfile - sleep 1 - chmod +x $PWD/$sfile - sleep 1 - echo """ +""" +echo "[Desktop Entry]" >> $sfile +echo "Version=1.0" >> $sfile +echo "Type=Application" >> $sfile +echo "Name=Support-Client" >> $sfile +echo "Comment=Dieses Programm wurde Entwickelt damit Kunden einfach zur Zeit ein Fernwartungstool downloaden koennen und falls es ist auch noch zu starten." >> $sfile +echo "Exec=python support-client.py" >> $sfile +echo "Icon=$PWD/bin/image/support-client.PNG" >> $sfile +echo "Path=$PWD/" >> $sfile +echo "Terminal=false" >> $sfile +echo "StartupNotify=true" >> $sfile +echo "GenericName=" >> $sfile +sleep 1 +chmod +x $PWD/$sfile +sleep 1 +echo """ Desktop Datei $sfile erstellt desktop file $sfile created @@ -59,7 +60,5 @@ desktop file $sfile created Konfiguration erfolgreich, Sie koennen nun das Programm mit klick auf $sfile starten. configuration successfull, you can now starting the program with double click. - - """ - -fi \ No newline at end of file +""" +fi diff --git a/setup-macosx.sh b/setup-macosx.sh index b93e038..9b6f268 100644 --- a/setup-macosx.sh +++ b/setup-macosx.sh @@ -1,12 +1,11 @@ #!/usr/bin/env bash - sfile="support-client.command" -ver="0.9.5" +ver="1.0a" sfcontent=""" ############################################################################################################################## # Support-Client . # -# Copyright (C) [2015] [Guenter Bailey] # +# Copyright @ 2020 [Guenter Bailey] # # # # This program is free software; # # you can redistribute it and/or modify it under the terms of the GNU General Public License # @@ -26,14 +25,14 @@ echo """ ############################################################################################## # Support-Client setup v$ver # #--------------------------------------------------------------------------------------------# -# by BS @2015 # +# by BS @2020 # #--------------------------------------------------------------------------------------------# # this tool configure the $sfile for easy starting the program # ############################################################################################## """ echo """ ########################################################################################### -# Support-Client v$ver Copyright (C) 2015 Guenter Bailey # +# Support-Client v$ver Copyright (C) 2020 Guenter Bailey # # This program comes with ABSOLUTELY NO WARRANTY. # # This is free software, and you are welcome to redistribute it under certain conditions. # ########################################################################################### @@ -73,4 +72,4 @@ configuration successfull, you can now starting the program with double click. """ -fi \ No newline at end of file +fi diff --git a/setup.py b/setup.py index 46577ea..d0d916e 100644 --- a/setup.py +++ b/setup.py @@ -1,53 +1,66 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- -############################################################################################################################## -# Support-Client . # -# Copyright (C) [2015] [Guenter Bailey] # -# # -# 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 . # -############################################################################################################################## -from distutils.core import setup -from lang import de_DE as ltrans -from bin import version import os -from os import curdir,sep -import py2exe +from cx_Freeze import * +from bin import __version__, ABOUTPROGRAM, PROGRAM_NAME +from bin.license import information +from os import curdir, sep -imgdir = (curdir+sep+"bin"+sep+"image"+sep) -excludes = ['email'] +app_title = PROGRAM_NAME +main_python_file = "support-client.py" +icon = curdir+sep+"bin"+sep+"image"+sep+"support-client.ico" +copyright = information -Mydata_files = [] -for files in os.listdir(imgdir): - f1 = imgdir + files - if os.path.isfile(f1): # skip directories - f2 = (curdir+sep+"bin"+sep+"image"), [f1] - Mydata_files.append(f2) +include_files = [r'C:\Python36\DLLs\tcl86t.dll', r'C:\Python36\DLLs\tk86t.dll', "bin", "support-client.ico", + "LICENSE.txt", "config.json"] +#excludes = ["backup", "temp", "html", "email", "http", "logging", "unittest", "urllib"] +excludes = [] +packages = [] + +# http://msdn.microsoft.com/en-us/library/windows/desktop/aa371847(v=vs.85).aspx +shortcut_table = [ + ("DesktopShortcut", # Shortcut + "DesktopFolder", # Directory_ + "Support Client", # Name + "TARGETDIR", # Component_ + "[TARGETDIR]support-client.exe", # Target + None, # Arguments + ABOUTPROGRAM, # Description + None, # Hotkey + "support-client.ico", # Icon + None, # IconIndex + None, # ShowCmd + 'TARGETDIR' # WkDir + ) +] + +msi_data = {'Shortcut': shortcut_table} +# bdist_msi_options = {'data': msi_data} +bdist_msi_options = { + 'upgrade_code': '{C1168458-7459-4B4F-85A7-8B4D0387D17C}', + 'data': msi_data +} + +# GUI applications require a different base on Windows (the default is for a +# console application). +base = None +if sys.platform == "win32": + base = "Win32GUI" + os.environ['TCL_LIBRARY'] = r'C:\Python36\tcl\tcl8.6' + os.environ['TK_LIBRARY'] = r'C:\Python36\tcl\tk8.6' +else: + base = None setup( - name='Support-Client', - version=str(version.versionnum), - packages=['bin', 'conf', 'lang'], - url='http://wiki.pratznschutz.com/index.php/Support-Client', - license='GPLv3', - author='guenter', - author_email='office@bailey-solution.com', - description=ltrans.aboutprogram, - data_files = Mydata_files, - options = {"py2exe": {"optimize": 2, - "packages": ['bin', 'lang', 'conf'], - "excludes": excludes, - } - }, - windows=['support-client.py'], - zipfile="sclib.zip", + name=app_title, + description=ABOUTPROGRAM, + version=__version__, + url="https://www.bailey-solution.com", + license='MIT', + author='Bailey Solution', + author_email='guenter.bailey@bailey-solution.com', + options={'build_exe': {'packages': packages, 'include_files': include_files, 'excludes': excludes, + 'include_msvcr': True, 'optimize': 2, 'includes': packages}, + 'bdist_msi': bdist_msi_options}, + executables=[Executable("support-client.py", base=base)] ) diff --git a/support-client.ico b/support-client.ico new file mode 100644 index 0000000000000000000000000000000000000000..9391997c401d14749d2ac9f11205be18ac8a08ff GIT binary patch literal 360414 zcmeEP2UwF=8x0_e;=sN4-m`Vrx>swpZfzZP)bYDVYpu1zy~VvJqBwBxRrlU|qCx;i ztG3muZO?z+n_LJqAliUH@;%Ra?w1e(`SP9fj{DyC8VpVbSA!f*h8%_hIT9F}@%;Pm z&5zxj4Bzp&4?i?Nu4XVSE8uF#k;C+Oxrf1Us++69gQNU@mjnjGz`?GD0(=iXVK6wG zo|lJ?!*K;1S3t2snDHiXTsFrQh`}oWsyIwW!2r2W9mktrf$;pMB@}BI0vDb~2FusV zdHDBpd@sBxj>8sL;BPmB;UQhNz!t&L%>UpuZX{hzlnc{=LCOdJVR}mXfWK*6V-ROgV$;92^SL*!t-Q=@H;(` znaD=uBILT|C-RyhkL5f!AwSPaWHlor#|%UoLi9kiK;B!lL~DTjP5t*}bR3Q=5XCD1 z-m4F4k<%;5`G*|I^8maaM!v@Q2eE|yf!w?HcxcX9+IO+j!cTWIgs+y6=f#eTMmP?~ z6?lhN;4$yRz)#5GQ$!RvAE7Qh) z5I{e|SUC27e#d|4xB~Wi1&s7P1M3pUU+?EfX!9fU7hX^URue@{SNOgoCbidF&GETo z;T3qmJd|+{xi9&>$awr8e`XXNSVxpFU4&qV4#dK{!SOHI(-nBdym3IcXtMhe=>>Hr zU?Wl5p#%1GuQ@(z?7IT@nX5P6iC()OVa&j}#DFct`wkt5eRqcAKZ@^H;5lu7U>71H zI~_yMtD1uC)PZsa!x_c|j<_Jc-+7MD7aOj?1J;)W-g-y2Kb*Fxyo1yl>>?@}498i+ z5-fErj>B;U99O{RS3v4~jGbZ!_buZC(E(LkxR?B|Y%m;SEsaA5Z2t8--q6mkfH5a| zc9XU?oE?rWkChIH7VPK$Sk+)S$=cQ+hd*HFcdg^&+u{m5k@@~FVxR4|rad9^k%!3t z>ITCJ)+sss0bAS!j`y(FD-e{O+`kq#_^&k~#2+|9f1tL(aGDwx%-FzjIIe)>3Pk-1 zNZcRT_TA_FHLu@v)c%0+1of+)!Elyy7!DnX`uFd6rF~z4`&>sFcsXv_erp<`bs*q0 zKMQ*hoaNdjhYr~Hz3uq)kzave+Ww%{ao6@oqys88I7=O9NFCsM+xxN(-f=jtfa3~; zxdH)M$dQZji~p9IpmadiFE%z9&U0OTfI|nueE*II_Im|neQywZc!l`Qv2@B;U?D+}=vqzutydCl1tZ&Av^mjz}*mK9B1NO`S`~B?Fvp1-z z{c&IW56b7cK^#1DOYL9F8ksFIV7E2Hx|MCy(zw|7$*<$`9P;wP~<8WMo_;>|^*lRj~{XF0G8eh%3 zSU37p8#~hiiKkv@i1m+;=M|iGANwj!z#quE2BJe(C4$ z;Jyw0pU1qO1LzNA=E#~t$KkjFvGoc(W-i-!(82$=viGmal^UP$x_(U^;5tgFDRdl; zD-fHm0HkkbO$Ya*gZp9L^Edhy-x>^lIaouGEH>Q%j{n7;ufRjrvl#c$|9_1g3v(|! zUi;Q_q-xLOq4WoGQwLaE>^K}(;9Xq-vHkbiE7KA8+c55rf;Ot_{hXTnBXuAz|2Auj z9f#uz#Pk&i_8|B7IBfsB@@+&1WRJsu5!8YFoHO9};W(mj1)QSr8plf_y#l||_6JpQ z*#39L{eS)4SNtwUQws{2))++kL;9kGH!F&{)5L>fryI-vtj@gJ#^~;J+oW;@Y`!7ImO3;{vWVvfD#?w2BTm zjwoLNvHkbocliCb=evuG?cXyB`I))Q<5ZwOzrU;BO9{=f|m+izR0 zCQ1~5a^)T%fBs-3N%Ai0D2)rK1Kj&u)*RZ+Aw5?dF+h~R?nku!M#he|z4z_?{hXcs zQM&Yf?A`kUSFXH7j~-7@pul~&yT`N+sG7nh)PWC~C*+#Lcz;N*6-NvZ<*zxAYfuAy z9lpP9_0Qcs07Hj9#lwgHKp*GMy+ofrPf)1PeI!j9(>frZ&*()Rs7`+%OO$Vqxc5R? zQ>|lwxcA@3_x!p^!oyRB%_am z|F-3S;=}2hjmX9e~yEC$NBn`?lr2*#1I=g0Xe$f3yA8 zbimK=6^0G_4du%}K&n*lLkc-C=C3 z;J^!X>hvozXAXj^t8M%N@xk-u3&y5RF=PAXv&cMQyLP{l`~L5k|5^)-`*~k=ra!=1 z(pYhDPZdKtLgoM*{8wMeL$Uqy?8Wx??)?~l{1IAvFGBD))AGOl_74sndVw#${1sWU z{C6Elm@q*3836$?WBdR7^B*i;{7h+B?BT!Gfq+B2$GQ>hN%T$+S>GUY0D2Dao&Gbi z(W5k&=FBRV{{bqeGI`I4N|KP}x7wFdQF|uU~g7ElF z^J((>Jb8k#VMEN>{_EFYp+kq*Wc#gsf5xM{&wB8F;-@4F|ucWGaV4k5I@7;KW1$I zix>Z3>C$J&npNWd*y8(J8(IdcXfQ6eKEn>!TSpF4LD z)~}B_+kf-sE0w>9Biy&JHO5oafqq1}7~+Q1|4Od|yXHT+UwzoH(MPLRJ<9LmUDS<) z*a3@sA^M&Z+uyC*ugbUA+ zC*I8VThj;8f#)>qr%%6B>vQww4T76nSbso#gtcp9#`eqqcto!x6LYrT+xr=EU0WP>$A5CaFu8we@7}$*bmVZF+KI;8ix-NgUn$B$3MeBZ&9D_7#eg$t|?-9y_SC+3L$vqmLLW>jf-&O}?Pc*xk|EJyWK6mb1+Wkw| zy?ZY{{q*dA=9T%oh}G{Sy*9u2;+Gh){V_^>{xPZZU$yF)nrE~#{+sVP<4x+oDBg#4 z4Tfj3mgh|lssFbN{?qoSojP@@-_fH-X$OzM$7d(kx!8xjaCbMVdfxbG`(?ea)Fs&` z_rt^qx2XeTc^y9D{GrtJM&*$8e|Ay-KViazW)kxY_cv|YjHXS+_Q(IcpV+R!2cvkjM%^bh4PbQlAAH{x1_E}>Wdt<->OdBqaQGtc|zs~f@F=a zwL@&b#0=3{XJqZ~#^`h7#*K4cwrttn-Me>V^XAQH*6a-LnfPDpC$|6d&*P`<|BGb> zzP``Yx?%_at@5Auxbkl=@m}vu4ajYUbdooW_xz{tpJVOXwZCuMwv9ReZM6OO^tIs_ z(Y1^F&r83ppMMtHAN_NFF=6j5|Awq3?$gI%`=fUM8Xr;v#VHepyQ_eajr&k1F@|>x_TW z4;V&2K-T`qA#uO>0P*@beE4u3$@{fxbuwQ2``Q;2+uyR~qj+iirOtTUw&y5ZIM~7e zH;!E;A7EsUi@-(}gpZE3MHX-W?oSUKI8blZs?F>Rf5$HPFMWJ>?u`20dX{l@Y(E#@ zUwRT%s`LP9)0%pfYTa{;+Rndr+)5un*8hwBkJq_>Q6I+rm3sC(^tZ|Pf93NCfdbYH+ehEuym{}YE?4f-gGjDPoVWSbKbybm$&oj2Fq$|2MXkq` zwR!Qe4mddYZ!BE+2kO;($e#a!=K3!C(R=IPe?*^Oe1O284Te*xsR4Fy1gB1s!jE&H z5nYe?{=C2H(ItI&n>Kx<*2_G57C&`B_7q>TiUj9baFQZYTN07c*vgb#9)d6qsKOmn|?_uD$ z4;24t|L<3^5B>+|<9B|Ic~8bY_Qv(dKCeIHWRnhj^2sCBH~-0#f8ym@A?ZaV{!Wu7 zk5rF9*_Xh+?*(H3*8~)>5B^KPG~*rz|0BBRO*$ZZdwl%yBei$dK!C|7}$qDpt%2v{9nobfywQJ{QQ`~Tn8QSn?nPlV%JPMAbV)lt^0`c z>(A64;ZjQ!-;O6w{#N@FwP^7O(kChYYk+)4qws&E{cvACX)yOYGwz80-)~g-9o5&E zbU^k1u2SUzcI@~wUgiiz(_}AHnJ0+<_lM&DOUC|%?Ti24v(7Q7Ccobsgd+}!G!6)_ z5B~7*2vm6i>9rl-4%sh!%$VQEeS7E!DH>x`SX7; zVS>HH{mS<53Cja}e&kIJypx6fk=xQ2@TLwp)(8Ac2mM(;|B(BI$IrO`#*J6(BVd!bwv9q7h;!i!o!9T1=C?S1FC z{k#5Z4ejyc@zeI-y!i@6iw4_4+%Na9+{Zy57z|JC(e_(%Ud}CeuX>+K|5Nf`P=I?O z{KVd(LQ|!g|D;su@_qV+r5%FI5t|7d4 zHAD765hOAgGI8IuFSs}2?ji=m^{xhkA9cY0mi_2}KkI%U;@Ghl@p8WZ)~#14UfiB+ ze{fYhiu+&3d$X;##(T9FD)RwqPvj&9L+YdkLqqP7yn#A!f&RcPi3{Sr4v6iaI5FmI z|MTZSaPVJhfAZ+AFM9FfA2pw0A926fe&Z24;r`q3p0-}>z2d#>l`0_b4a@}?$bEzC zlR%`PFHn)|2fRuc3}-sfA6U)U{t2&bJggt`NA21VRgdlH=Aw=(#Lwu`$r1BY6h^Mmn@ z|I!a+{P^GT`|mLm_sicIJ^DA*ha^RcKyvc|1`mFUvu9s&&vM)9fY|<7vwpXuoS*SH zZGU{_eoXLQ_DB#g1~5pkR6!c~h4{_+wix}$>eE9GSRIBz7 zvRARmC-+B+6h@RRc^`uYJ;mwMFV#Lqw(tk;-1!S-%G|dD{_A-wS@V7&KJq^@?purR zt@-)l<6HXqmiAtAUh|%uH_+}YaQ(oUpU8dgrKYd5H7>=y=cMVvHD(*i;+b>**Pe)|D zmz=(QUdw#GHQtAh@2&CP!q#if8)WZfA_;pYoft}6#WmFN=|1vD_396C@LkC|lMW=r8p0-}`J_ARA^h?WRFkGBV?z4xAwR<*hJ|}x4jT!S) z<=}N*E;>i4E0Fp-sWE*0bqv)3soCk<_X+cpFI7*XsO)7TwtxP7yR!Xf42Hjj2l3&E z3ird?d_9L}EuSA5@3oI_w)K{r7v2jp(KooWK7R4vA62V9#Qyy;XZw#Ie}P)HBD4M0 zbkw8+Ns}7Y{=dC@KT-b5g9m>{ny--k!poPp2iq^#O!@u|xV|ku*#3yPZ_VcGc|6Vi zsQUSl*?P$XB(7b%Zo={7Cnq3WOP4;AEm5MoYsvq=UT?Ro-NUi(IcMhpj2iV+&AUaX z&DZZOwf9ngCux~;(bK^zUKbh*n92c%UoaL;>AmZaGiWlLZl^%5p{_6-+nvq2M>=M4{iUwy{miE zU-kC;`R70X#U0I8TaU7yQ1L0fb=IRP#_rHyFbRyKfhotQK$|C2L6SL746CP z2R1Sou8Dn&t4BoKm(Qf_zWDp*THWw9dm(i@k@@*j*W;EYOIFuz-FhgyPHrbAQWN=! zs>EkRe`3lOOlMYB+ zA^t%7_P?S;3970x9LGt7` z$yHm~uRz89&pz{I9n5a_puP~}^(n=R-^aJ#KEFI&?tS-X}|Dt7{h# zhfO*lwT!m&F(Ud~vE_N=6@%e7$$7=aBP!evZ}a7`_yo@3xGuIm4IwdmeWD}rJ-IxG zHhdqs{(wCGTX-&<)_k8ZVT$7V`0<|VIof}&6PeAvmvb<4=3E6i@6%@u`Fg{KwmOix z?Bf_VYzBr8pN@_lS5OCbaSxvJF&JZ*_)@IceSH1(6Kvf0Cyd6w)joi>)B&mGll{e_ z$M(k-9=?nJLv${%1^FKrZND|{%jdAP`-yy;;;@b(%1gVU7FZ_p9g0QO$Q(o+lzw5IKn|L`$MCF^+s* zN1osC^qlrWbKAuADT?!aO$fKdzH7b{sF!4WB1LiWfw4U|p zx5$56-N%9KJ%5_Ef11*xv12E4E^ZtjkH!x_c;d@1m!nqgJ;;^o0`2BKo9a%)zOhLM z3Kurj+^t>v9QW@11=;)KZT$h+Uq|*3u%BF9OmJWRhU)Fb^=Lt2BjeIx$$bMks=2Oh zyUe|1CCU+viT@F!CQS5PPX3-D-=B)_uI;+;UC#L$6|akJH~I3@IM+Nw*>~ZziSLUr zZ(c-L$e)??Kwdj%PN+X1I`G|hD>!fMXHy<#&3caU_Y9>=v-vl-Y~6t)Cr;t`xeGXT z{sMOHJc`jj?n1K~n^7>+5hQT7t^e^l9Vl4PRCDL+t99Vb*5%0@{OsAka}Oa~X=Y4u zE4Kd~xt_+GwEZ&I6{imJ)Y6X^u1kKd6rp4G@5tx*G}&*HPcJrI^L_q&;rSAUg$tLE`x>GHrswr*MF&h8V0zCV ze_U>J|G#v}>+l>r3sXC_$MAB+F(REiCMPjqc0vQzB{yJiIs*=7G~iGc0}c@D(kI4G z9_7&}aUbMMu!@VkVpa$8<_$*Ao=>oH<#YJ?MXm#{Uj4)C_Xkp@bl85|@?Y8h+Xlm* zGS?mJ4su%TyTt60pUXphNVFiNre-2Jy_SCb6{)F_c%0l1W7kbQx8!^%&&A$r&TCDW zIMI{&C5hKf{<_KLoBVj;vbOEQdlTQ6V$mWK7BBWPpX<@|8j~-e{Q-He1#KdFARU<3zoX&&7xSfXqvZt$tg364l=``2)Fg2jhSLdx8}!p5xXn>pCF)e3~>7+aJ~U zcDycX-=FY5s6Bhq$$WRLImm6X_2SQ$px@q$;|SVzZ`RP9qFsL)IoCsD_sJ8d!gJDe z$T;3?`!(k+N6mkkuM3Uu#n(6a`zBj&vg?Z$E#V%vULjbrWEqw&{Wq2@@q$3~K{P;k zFLQsAM+mL|vE6-|$z?x0Q|85rGzQF1Y2vuzIXOOwn2^*2IrpSKOfh2`$LZ99Ny*&M zFKJnP;?@%d60AVN7}kMYxq{KP>tlF(KgZ3Re}(K5_}5>u?(PrHm)gU=+P1qNUeAB! zOWidXUP^sitU84MeiMWy_XBAkWFq6Z`Ljm28LpsD;vyL9?u7B=y6{{u*#e&Ax#s;;o(t~-pg)i!M-b;L9`iar=e*(Hs+V8$=D)DFS4?ul z9{!fH{hbVk8?nmvix3I_X@@hA|Nqdp5Ao@R|2jV(p7Z*#a9nKtn28h6c3Mw->H9st z@tuG%GdwY2oTu{nLwO&n9ilbDSFzLD?u*^lyce4vmh&c?ul;_>{aM1>dj&Rc*@{C) zj^fOP3%Gjc4sQ7S!_PkehmV{??%Y>x=>G?@VDmOUcWX%QCkVrN&411PspR=IOYRHr z&6rL8&q?Wwd1+iRCw+1ZO;;H$Quag9#G(V&V_XNsACR7&j+}pV=#lJI_ej>Q#>!*U zrY&yt#~(>eo$y{GD*T^Fo(~!KBR*Nw2~GD8M%&%rW6e&XTCd;vAg#FWz;c%w)f#j;kDTLp`(68 zo0S96>Fii^JTwA>rVqn}F`ECOc7MWz$!cwm$?nTsUg#X2Xo2|cbLPxbycgeoi`eu- zhjHoBB?JZqA%M6=yMFM*Nz9o$7e5Udf?myVU%oz{n?=kP-V>4+oR`WO3(~k?QHDfV zn#CQ9py2VyIS;`0AxG#U(#WzBl5J%sR4UuyZHU9 zSNme$zWq4M`kC8z@51=tA#Mc(;Ow<)*sx;<>jlQ3*B4)){Rb7%K6h61NbZWEgD!UHH$fU{D-w28G`9Fkk zpXb`w7w#*Y&r!H9Im7v>ov|=&0xZtx2CuA1u{>95tjwPts|sesnj%@?TP!P97tM}w zd1|3UrU7^_Id#D0N(}h}ahY$i>3^5|&GzlhSaXU|-iYm;@fOGyD#~@ z8Rq}#UpC*&ebJ`{z{w`1!~YEL-D? zk)ubWW2=^EQT~0j$)6j&Gp58)@_ab$`nUw-5xFZ|UqD{ZBEP3{oJfo!$A|N0!gJyG zj{-B-<*__(iN>x?k=St2ruN_6={)+nm*)JwQ>e|?xqb3q`}$({=UMWe++Uc=35&@8 zr5O@pS(YSNk;4P4Y5Ug}&7yd}p;S(6ER*|R*ibq*JPXx9muz35LdxYxmf(^@2W+V6 zw$&|V`+IZWnONW3OZdNW`87w*4YZz z_wPT5lc!GOA~}BL)-7DRbsNX%&o5lO7(Wahicam?p<$&8Xqqz%+N4g(+Be#Ea$Ra= zr<2#h^J#?m?ou-|hR=;K+jgIuK&ynm7qe_!JL zf5rLXxzEQ-QafQO`R|>{4L;eDVO5^gwEdZ|fxfi*-74m2Ka@{{YT&ZvD);b2!YneTk0`Mo*fAZ<&Md-MJHb)vbk|rHkQz zxwD{qs>J9`{th9R#aH*_xhKbo#5h81x;!tjy0-1M;<`0$80zMRLe6tIZ!hccY?lMf z!W_VeWSLc-Py73lkFfOjLv22JpUMQUG|pI-&IK#7B*v@BeslQ( z*ixY&wi4Sa7R2^Sg*ck9o#T#5g|V}8VeAroP#C*8&MQ?Pee!&T57T%fWrz+q=JH}* z3zY4Dz_>q4tT+4?{~-CFgg*Q))22yoem40(Tk&7k(%hgwzjgaI^r8RWvUxMqDpwXC z=gfv?Dc#Z8-35b~mmAKtFXM@cJQto%B*({^xjsCJ6Nd5pCytuuGFszmbUpV$g2Co` z`#06`h+c0*Qm1q1?fwB~C3gv#*R$sDFE;ajDMv5PPb^F84Da+V@X4A4t8;l^ZNc=| zz+9i$eBu5!@_T#bB4JUfD0WmXid|KTVz&kMd{_*7s}{%4#6Dv2`yXRK{;yCy-7=(3 zc%J@%Xr4m{VonEy|3L$|&QJQ<$C*R;zhcFzn^KcMV}|t4nr9y8;>K-1%%9?kCT_0i zmDmN}le?pc@yxl6BhSascOS`7ApX1Nu<(7DyEBF}&JO_}4^w(z`k6Y9W-XAIqj{o6 z%mH4uq5T(KFrum3m#pz~3!T@q@b?#)d9UsMGT}bqP5Zw*LjtVI=8iSFQ(|r542=78 zk^A)Ph5H{A#r7)2u%k-x5bXT0ICfVpf!)8p7?bB<4JzF;Z&u57;WUUA_QrKOi6!w_0m*daGzM7@6-;4vbO5tEl zqE=}fs$E9mFh{}iN)0i%$k(Wo$qVV+96Dg@??3GODgF;4|KpVH7YQK$6RlsrY3ag+ zOIdTfP(jwx3;*}-JBVGIH{sh9i7<@*{cCwiE(^y;dL+Uq<^o2gPGTBUx?vO{&kIIS z8x%wns09M83F0?|Xu*Hb0qvKJqK}ftWx0)WfB|alUT614tmjRr^7~@*L;QX6J=Es2 zHi_#6m!~!JKT|@iX6(PNKw4}nnT@f20mXgA`5L9Mr)C-Ksb#{?wcmqaAF%5PHb>GJ!GmdaPQm-tI)-R`UoTFfMl}|CW_#k|g#S0k{pMk5h!ygFC-M7>K(DzVr z|F87@bH+8>Z|1-2jvYI`l{Gd}m#cej$h!P3+jd~z-n|%@K81?&U&nv3>6-ha)3}@X zFB+hAKs4cXI$(|&{)-NXk0SgR?vLgiL$!oo+q@1)Vu1Hu*$XU1I>mqO>xk_mbCweS+HWV}G5pI8e77xo*Otx@B>QJU?8& zJdS*1#>eGx)Qn>sk2k1*6K0(JqykP6YpZ{XA4`3M2HBP(qeBO5><hf z+JEOGM~>E&b$6zo8`5jTi?#TRv1ZLWuB|(Qp4l?0+MEdaPoG_JpLSiiK00kuj7gUa zV`L;m3qtfjG{CF_q6HzofcONKF@mKIh))njUm!g9$B_SR-Ri-^>6neb^8loDI)QJJ zmBk{i=M(-*p3f@x760k`GxxVTs~gtkNr{a`Gh$1bT-d>we>b_mmt5aluN?N(E3dGh z;{oCzd4A}l3JQlg9{D&FM;lbcu}@4m&QWlJIN7igPByBHQ=f*#X+GXqy9tKB_YE55 zSc)v}r;*V4Hm{2#KM-oq-_##4J~kL0=8kj3H~+)rzf*8ZGJz*s`gO`sN-^&lcG7%6^%)&s2r995pcoGS?N z2_nz}OP^ot{#arheSq)X(?RNXqvJmRAmIee@bCzY^@Z!^-@@|D%dH@Np#^Y*1O@Fh{|WPXr&}Xu}V1tdR-FIi4U+ep*H0 z6vxwq8XNPRIMd`qg|i$r&Nr=!^UbPZYrSR|U3M@U=Mo(_41(A$p3%E2bMVk>VVP!D>;IQxG!r1qz6}7*KzE>C${cQ^*!>}Cw01rfyt`U z{jw+xy}YEq&I$$5gQJ`S_@Q%0400m>Iqw&S z`?SN7w-bL}?EAQksW3isYK3u`Qiah0@dw5-k02VMe1UNBfyxnt%M)lV2+0+iwLtp> z+8+q-^NZ~lyDt##3tA*qDrC(n3XEERlBda&)nZC=Kj}k?$0-S zQfy-EzpYG8Rm1Z${eBbotKe{>4{_vE6OJ~niepWxDIDjhaiVE;oFq;Wrv=Tb;|#fd zrg;sVZDGPWj_1v|(6S~jw5o}VW~lSleEeB$g-aX-yBfB_gi1ruBCi*6Bs=NQf!Epz zW&3}k?=Sn>#o5Em|706BY`P-;{<3903f|s6Dh@b&>;xwL@ICs8{SU`~;i2MwT5_L! zpO7srCS)}uOPUZZ7;mWs^beF4C_M))+TQ(g*WXB{S#x>F;CRuDOP|%jrO)dU9NW~vYsAzynyi zXd!F(IZtOX2PpIQ!bh>^V)G|vPmf7COpx;l+0t3nf)KyJA~p!g6^Kt@Ek3Zw8EP#M zpI}r9SBy?U|0B7x%JU2NwcWSmzV6Re)z#Mh07CD}49@#8G(}le<73JFRrLQ?(f<1~ z_FtDZAvWetfgL5XV0Xm=*vI+&!xG!mz8`H?6USQA#&O~VagsRIvNle)s-tj*GNh>;3&9AE?;U}U*WRFc)4ADTyFOft`Ju(aIO8vxNZeEIyAt(=4~;p`cQmc z$P0NqPEZGKIdmYzCs1>KBboD$)3#qr0Qt{3z@0N!tXQphFFGI)e_+RsUD&v36S`$c zi4m*;QvSb1%&)jFyw8=u-i$TroUk^d3)W|I z!{)pxv4gSy-pYk=kn?><=<^Hr74KWt#mUxnamtL-9M80_hqIs6!@181^7||y&fK)6Xs*TAxqfSQU)%rj$rGcb>rAc(vSm-euo}=X@i$nIDy8E7YWn`N zCxCByC#)m?H!}CXHD4<1elI8Xe^?X;Io~Hf|M3=eaDqHP^?7}qZu61C8IEU(a{_Yu zycrib3NE&9pm2%fWizgDyh2V3u9|U;D>@w6&c!v6~wE|g!hX05XOD_5?;s#R;0 z25i`{1?RZVw|j;6@uLO*CGH=eITiVy8J>BwhC>#U9+)aTE>t@{Gc!ONN(WMD)THqGXZ*^^g z+g+O~_;J*@)4dt)3c7{j-v658-v3(QFDNKXw&%ltzM7sY)&&lkQQ zzu11wed*0RE|~{PCYY^ydE1KfVc*Ayl+LH{WwJJ``AvfLb%E!JBYkbWPx z*jN9D-aRqEJO>z_|5FR(gvONoIl^jz**BO>oiN1+j1!b!VCfT>bRZ;OKwrRGu3$WK z1rsxQU_z!8n2^C8<5MRjpTpXI?d$7N_vh7pxusuE8~OmroX$jB9zgD~+zGa#fAUY5 z3rLKO8Jw|&xxa0>l3`b|jM!hfpsLkB(X^WK_0P6%NZx-+zBj?e&P{N^3^~6f__8T3 zcWFwVn?YV*C7%V?%(%``aHCrbg_|62c5gw>x4>=k+0O!Zc&^a174DjGkE02#$#tT4 zC<6MlMnIp>5YU&9(E?|`?1IG&hoSp>OHnM{QO+AiUu^Z?x%)PJ5A!?EIp0_ObzF*T zKR4U|?xTU2dfpuG1l&$qVF%h{`pSA`DVD#r5P@EZH`OCWeZ#(m#>n?*DP@Te=TwS zf30vM3|iu5kJh-=(*!?`e&q5ULGRBL?s62|GsC~n=MV&F^lbxUKP%|p7RCYXBE-e+ zT`{8CbYxF)j@K`~))N~iv%g2Yv;Cr1)PN*gw{Abl7(j7fMvaS?E;AS4gKq5QC365e z|0nVPl>FH-t#BSpE0Q-9@>pvEwP2cs9)#Bdtpmz85G@ejAS8Ea&J{3Dn4E(>ceAI3 zXSUSjzXvAK{~ynJKOOUHd#}fcxG(&do;|&iROMX2p=jj4Xo?XTTn?gB@~-UnnH@Xx zd0=0eY&gPoyC+!JcZPZW3*`RAt}Sq}drMsE-U^q==PPDh?a>O?$Y%v|`I;FwINt2_ z8Sy!8S)%vnxZS4>{K#R!9W(CsYYV|WGyFOF_iKlM{zMo~w})|{6@2vt0<9qE>kbh3 z5A29t?FOS^fvs>$5MS-T@lUStFBR8pdsP2l@;@Qx`qr#lw^8w5?7l!W;Ka$3*s*61 zI&mG)2=?fex;vSNml$36Ec~BQET6*kqWK_DdcYpuN*hEEtm;5^`T-`tU~(S%0~S7k znnMsR;2gqa?vLY1OvyeCj2+k(Dr$#;UB7Th83688lC+bj5U)Cd^R9svWtfRUUI19I7Dfk2)Ie%%p4 zgF0D29(P3WH=S{xxZbxX7B(J_k{M-vmFyoHUH(*b_-JqPo`F+oC1d3t-cjXvWUnLt zUH0z%d4%Nqg!2;jix!9m96Weftpoa^U>*#YIRFd(i+?YCpHZTK3B~hchJbo7T@a!L zVSNH?@qsCC7#bUhPvA*R$(<2Xb7wFiM_NqD#CgZmi7=7#e%83JZU1y?faN}1x>uj> z)7LL)6=ZbY%X{`s?t`~|tr6vudSgZr&Z*a{sA~AmGlzePcK@>QzE>Mu?cEmFi0c~U z_Km*n6mD|VxYf5kZuc|6kGvM#5e)bOcZqvu_;d6hDE8Te0FD7)3CBCaNDiw}&NT*g zMj$yY2qJ{z!GpgH!F`@9eA@-aZ@S`Kum0#+!3XJ+UNiGPK5}0^lktVYaKB7s{E6#7 zBmbR`9XsA+!-ma@|LfOpglK_iz^+|;xZmDQ^sHMOLuC#?*4MNCZd|66jPrAl?*%Zc zWFgEdRajvr&u5k>Xx0Ri9+Gz*FqJlQTE5IgCKIyL{xkNU zl+sn%e(mq;(K6R>jr)2Z9@VqQ!+=&vIw85!*%;6OBV3(sqiC}27*zZRY;W9}F@IBB z>G3(P_Gyo6bir^t8+~=t9T{qmfzyqEOg1_qy-!@~>s>Ej2 z1;$r@U+cW^KX3+ndV9omjz{+YlmAZs{sB2QZrrSFzHnc(K={wR0IuJ@jlo<8^tE{% z;7Hcq$~r&czi@pP_uLEv(E`x{1+x~IeFN4kG) zMq&CFg|cHNHDD%VfoWMh;K_ME@%=ULWem@K@%@GSI^QS#`E`$8&3)ak>-*%Tk;7$c zjNiir(wxBfdY(AVxz+3B_DynIaErJ-s7na^crLh0PAibh_jv9v;JN>hZsc|-0%@QB zg`xjLkbpcE1Pgu;^uT@MfhB(IiH8=r|9wyRf7cfaTTDa!f_srX(XAN2RxuN!h1V8k z`)6~$KUI9;cx0c0{P&=(|3&kDz9N zR3XfHzc}WUD}gy>2|0hSc&HwPXaRi$r3c~{Pzwa22P$7+&KaouVP4EEmIpJ7=HWgU zxiPC~F3c&E1G89PJe9uxBYW1jT84n zVke1X!`}nZ|F~r4qnO)l0xk{cfm?&S;Wpv-ZFhw`Jio*9yFD~ zfk5&)1mE{S5V;&Aqxn4ehn@%~pM!tuh5HtG@KbL*43A-b@W_mZKlQ=Ap#!j^>u3zD zwhF1;ufLP)^De#<^WXf7+^-NBXX4Y($p563KD(%jd*`lN5i)RdV~ zKH-dLtP6adju`P?HtIkNPh9@GFZ_n|#GN5MaF_hPH?$}2(FO-tAdu&QKlD-v;u!QJ zK`sZ8yCEQdgZcRWu)YcpI0_yP7xcrU@EFk_zl`k9pY_L`9|q%4pOF|`Yb6S#Xa8Vl zsqKrI_~;$--9q0~Tr=Nb_|-0KzvvkG@3wR2?tPm#Z&REX?#sE1hYlYh4x?X|v}z7O z*8h%4msHjI&MM7)Xv&wu{EB6W($oL}wSdow7R;eGXy0JASqCIuP+Fk%z#J#crY|wO zR6)!sRRD8K7r?xd`N{vhn9CSoMs~*jV*AN?4ej?^*7sTZ{5s~>+}FMNExE7zb&d7N z&pE-x)PU%o6O2p?j3}D%B*r(Ki#^?c#M!R~;r7se@c*F?j6e2P2>h`R0)OgDo|_QN zF_@eVCZ8>FpL`ZPFykS|hvfI8Q3FgE$ZzS)}oB8l= zc< zgz`VFyQ=?F{3q|{SAHM!D+%5+YeAV1pFs3Ld<2a-Wf>!AEwJzl=Dt@1bKj$$yjO^0 zArwEPvHTT8-t6YD$d4A1(%Y2{i(`&6yr}XLXpS&)zx$KsE z&cYT%#@FckS5&839K(%Uz zkuv426a0Vt3D)35-}N@Vw|s7?V+fqboPX-qaV9?focwoU4L~o+_etz8IPo!~F6@xuRH5wg?uKp$0GqFgs5MOiPzI#O`aqUt<1gOG9|ZrA-@r%&jrtnF#Dg(|@Nn!PHOl$@(cj?ym~Rj~`dhwk z2<{B~4yOl=#`d1v^SSv_G%UUkdD32jEA4Ic^Xv7W*O{?KrcBq+uirZEMYkB;x^0uP+o->>byHNW4I`_iv#Nh)`=Nz#RThf6K{yS9U& zd~tCWpTr1{#J5o?_fga?bP(M?+=vNHmttCrMcDE`PweS43CF%3gVTdYV|Sm)*h!AB z>@*uIJI}_f){F6NJzvx-au7u_okLpcipkGW_kFD3zUWWEf)~)Y?`Fsz6!YiLXJ7gS ztN6K-5bqH^hz)$*J&rc^2h?@ALBGF$e6913Ob3MjM0#@nZ%h8m{J-E7{r}<38{<3j zU;2QI^l($P`ilRw^NXrg41q}pD$pmOCJ>?r$}h0=4J1x5#|jH7mBxaKrLeG4Nh~53 zS0tzd!vDE4_s^O?Pxktl%)Wk_`#R>=bA7tLPuqUYeQo=f{UBaM28`*nuvG88=|9I$q8^m7QM%Lm5bSKskwADtg%L~=XH$M;2 zzbEwjxsTVAG@*abe$LGNPetzkA^exvUwFTb`v8d#aN_Ja4DZqzU&}gR&41SCOa5N` z{KYjYV-cao>XooaVAh0%)x-LwVNr`4j2C{GP zrC4Jd-~8VGFT9Ak-*s~GN5zUa$o(~n`{DTS_iq*kaj!jpuEz=NLjJEI_?oxX0mXm% z6M=MXA7uRZ-?E=)r~&TG_Xo<{UwHl>Id&W)27QgbtN~UvKwJYP>vd;v-cIqq<_B0@ ztBMJ7u3<$Jw0|JJ!QyH})pA%;tsIte^r99l`|y2uRW5}Eoco`dne&XPOnHAj*C#Q* zp68c*f5=>4IPUAYK5O|t(SeA#zgGHonDIr@uG9eO86@{f%yGhA{#K$y0jOH_9(jM6 z_I|;?_|F)Cb~&QsK_c?D1izav35gSK6VIZ4?WC8V@eI+A+)o$LU$K|x$^S&m|DBN> zpw9n^{TDyrz`-LJGkiF@aSfoU1~4HeaGk!?|1V&CzohnuSX!s5f}9H?(gWoi&_7sQ zy&{&>sDPzrcu@nE5#CkHVrfO@0t&GHpLst|bG@(dU)T9aFArVkqwGHG`Ni&Qzh84- z+x_tSbI86tx<|L})hYeDH1{{8H((R7B5ew^N!kB$T@glbb!4%f;y4QONevCFVq3%^8z@R7oy#N^RaOLA#tAP z?Bg3)-C%f{H1hYikDrqNE?c*5Tc_v##qZbt|DL`3xG(T5boNNB`T)p&eG{^#;ab1^ zivLUNRKwDG)kC4RpiVd~5FbJL29>e2mI+?9Dq&g8O7N~(5zA|oH}RkI0CTwRPv!ks z?$@gjQYrkLH{f%b+Z_Z%AYW5!Nn5-)`;E2Ny zu#pC&O68AMt!}Z`)MZ?}cnNpdXKLxvr7G@Uv}lnf|3wEfMU8h;l*?I@CxkD9DnJky{G-Wiu`xpy?f7C@%_dA>-b;t|EvwbnhhJ#K6_@> z2SE1UkRBj2ShFkkU%2n}QB8Q&*QmkgYQT$FT9>*|m-;|WSRzoqLKS#X8@%gO!Lr&P zV7VD9YEc8||1W0k&rGTJm$;w)zHndX{Iu=Y+_x6JroepSpzj0?hr*XU(6Q^EY!p#P2uH^@rs9-_Y-WUCeKd``gL? z9mE!Dz}QrkP&dg0q~Y9vQ!JMC=0Dc} zORul_mESY*zhPZ?e7OySV8#Iucol7epT|nB9_wkpPMHm zrf{v_6wQB*)^dJf{C>v&V)ykt|1#Qk%Y1)$zh8RvTZ{Q6?iasbY`<_{u*;0ynHW!` z&w_Tz`Y|4`{l4OHhtF@OJ84q+p;~o+_L#qhOP4Ou=Qr_QkN57~!@hm{IPX74@jsmX zr!Vg~qWcO6|B003|0~G>hUfo@GiTAObt`;r=D+mkpIR^{`CmrydU>PzFrglnHzXR> zgSVw7P!EQk#|lDgf;Tn6hnnEi zs4iB1N;Im2RSj!njY2J~{-_$f#rMyjMa}sO_jS%M{9J!T>-r+f_ebRSTg&%}-PhdT zN#2X?*WBMr?(ZY^XEESFW+$x9kOjRxIv}6xR`c2+M_$0>!x)j+^$u#~*^ha3$Kc@H zdAN4l4_B{V#pTPF|D^#pZ{Ec5~?%WXjZxI6=bnr7~t^oO;i2T2;>wYEfH}QWb z&YU|BPft&Dba%x_)&Px>H9+j~FZKM2|4kcUg+>#eH~E;b)P(x*Xw({3w)^stC9U< zezE;J=GT6|*nLaxA0+<;hq5w1$bAWhr~Vk#63^!TALr~oFOY=m_A+_g#DE%`*uU^w zJn!EUrxr}djl1{$#eazf1lO)zQ@(-t{la@an&baFF?07j{tEf;Lf`+O@Ln`PxG(#F z%HxwKPhqLIH`=C4iIIs6+>eWOdE5g`*7XVheVTF4i)IZKe42g&6B=+Ns0S;Xeyp&n z*+*F2v_95Q2YiXOGLru*YgfiXuJ@68-zh0wLgxB)+^_5W^xD3t&h>|{@3qYL>v?|d z_gjnkh5G`r`+@@&+!y{IA&wHh8MC8J@^6tb!EyE$jvec1Vm6=PkMt>Sqerd%IQZ>i zVEPZh=-znsRclcPfck4DONUbWP&{3T<{52w-7Xd zZ!;6tHvbsws0V8q1IWDJT+aDVvUFD`?pe>xlI&2=d>T`9H6+MLFlsoMKAnH;emO<6|x7r~Q7N^IL76>(}|d z@N<1S=9he*wU|G=-9K!$`(pcr`^U37;Z#l+oGIXri)AukZP|}eE88X{bcxQrhTfgN zxHtzOdE&b$mHR3tbl8gze;E z>T{U`T)%$3$^l3WATay?G8T>MJ?wbhf4c%ljvTElbATrQ-^73E0dn~8QJiJYwqt{j z@D1kxMyVRWwCwd+*u?)9jj_5_Q><=Ha9q_&v_Q_AU`?yW@NL}$zMnP5x>lbOjj+CT zBWw^2X!;RW)%gI6*z03@`ozliPYpNUr+fKX#{Ig+SI_r_uk#DZ`H}Zh=d;F~@7Fm$ zmG5V+Pkerz^9#>??e|N*PsjWR$@PD8-++@joNzjK0-P(96qm|o#K&Y+MR#SOTnD2&|b0_{;O; z27Y9JQ}!Y8r~SWq>sFW?fF=L^sSmq$?NW09n*SCW(D1+A)sEke>J@nW_;D)k0rHQY z`xpDaZ{L0#I&=i*S*zK*R#b?d2`m<*6{anx# zYuhx#x;9O*{<9|7Ky0KIY;650^M7@e?>|ra{HJyewf*$v|>cC%%7p z?uWPiy1v)a_Un9KcIC_6D|?v3VJFz^nnQX9G(n0yDk`Ms~;Tk^LY!en0y7I@hPUFTTH=3;z!sIDpx+ zXDiz;+&9+&{6qWCnq9{c6IXySKr-$D@Td6xk_XtmdoRD2L)gFnATC|L%KEL5=$M#2 zfRZ|M9{>-v&yUpkitq2+rUlW`0xhtvEzwTU92?pSnqiZGTCkBmz#7i`FJZ5rSy?^8 z#Qm1se_hVca;{%}U$4`;uE{f&6 zhE^Y*f$w)a5$H|cZ(CsVVAh@Xf z`F`EkL)Z9g{_9#F%R0aCwm-bzA6dR%&-LjVKh6D+xjyFo^gN%X?bqCwxc`)JpEyhY zpU;;FmrJF^_38z1yTylUf35oyzr(|M6Y#6|Y&==L5Kny<6H9P=kvFyt-+)=YcA|Ne zQ^=6&HWDYi`%e7=lb!dce{vV8lHEa#lCvCX|mnjaA z9KigMz{COYAKDp5_U=Yta4@bj2cY?{xi6!v0hCdAFPsm@|2;8r?>qj6>ILkwapUHT zyLRm*|Hbz|sQ52Fz=;#5u-w-dZL(&-DDDL?CT&tx1GuDiRTb~AZPyy>+JC07_KVh7 z-=Q@&2+049#3o{khWG@W`&-7IKXY=YXWlN~zW>>r&bW}@4OidGfE%@o;7*&GY7d?V zQ-8uQi#+kfXP)By)3rDzG4HR|_R{_f_jRq0)cWbUe$D-e za(>$P*ZjAZ^V4y^w*8v>+V)3vt}lf9V*APe^SNAbsh~TqRmh544NBu)rv|DY|0DYT zkG*E#>6%64(=zfX*q&cuEO5&Tj2f8PJH*-VN@@95yf*~L#EWX z;YOY&NyOgRuKpp~VA2QC2+1XAn6yHklb?%@Bw&xvgs%L3w|hvL^d53&yoGWFucA?< z^BD5^ad>~b4|lvb;pGl;eh+hcdt@|YFUP%WUjx2ow`c=3U>oCrwVVg=n!p^u5Ii2% z4F}h)Lg4)eivN-W5FbEzFQY)7)9Zk(@c*}%x%(Y|MfksE%hm}J`%B*cz=2Tvujc?e zSFV5`nFAc1nl(V|11vo~B;UW5{NK>I9eLjt8#@zUw#B9|+hB9&HrQguR_ehv(SpyL zUyc5&M(C8*ZF?>_m(w2 z+V9ugSAM_ZKW)G8zi={K`yiK!{qJ>e%D%f_;g|Un@npqZJYBbxTwj4dHW8bB@SON_ z%L@Ftc?Di<@xjZjK6pj^Mf^>?+`JNhZd!%s8&}ge*oz zO+Pq~kIP>mkFTLpk*g?{>$*bD47b$yL9wg&sQg7V`|v#4);^0KpPs^m?uW5?H1~B~ zycGd!HsRIob-+GyTjKy9hXH>kj}L~!q4hu*$nVMfPy==|4%osRz?#Xxq95?*-!x?bYB7CKllA@E$e_K?{8`UWe)J< z`3v}}>8BXNUSOllH9*qiPv-f>?r;3EJvMeRVH3yAUD{!b;LCQ{N-ye**?wK;NB-;i zKJop9{{r#(1!sx##Km0BxRNIUZWi~zy&Cxt)Upa5^=XBt6NliBB~$U|>IHbY(c8rF zZ7cB?@wbNf*Om}J+M0j8i#FMezjyL{w=Z>M9iD7lk4Nh_;FkAh1g_qMON+MQ?#eC1 zX1v<97JqDCkLNqq<7IfB?TbAdCwU;}iO>t0PIa?}txc<8X~ z#T=mKU+aFY{}}@?ZQ3;D19V{nJb9e_H^t6$i05a|E#*u_YG=G$ZvHZwPg-uZo}GmhDB`&h0I5PFdufoT=)Q| zBj#^RB|PU7bN*gS&VBGZHGsI zHB%ySPFVszwJgOkWf@paOOh~7wu9}m5-Ek}D?<`x6^^aKK4CfUf#U$o1_Uj`D;^JjL7$^UF44~QPIr*QBXU%aAzy<#wc=&Wr3BU%(GiA!O8}$7xS)$or zq51&w@7?tuX@zHj^kfWR$s%eGP{#Wz{(q}0a~nZ^x63>nhe8(Md;!w=923;|3V#1r z5bulqeG6qtGVa&0zIu(H(*2G#K6)Q-tL`^r{H^nSjPo^Zf4#P6G1l{Pj*s@e(&=D* z132GAeGbOS`4(`#ovcH4L-s=Uf%*Mlp4?O7p2{SL!2gj7IpxGFMdi$w&&#=npUH*J zzsaSMedG#s|Fw__cJ{&cb;u1!0`xIOOj!(87vmZw9LHKBaI7T~j8T?YWGVPuifdYy z;atmd9GkKN?3%I?{(Z_SL!#!2P*yoapGVEZbwgI;SP5UxK7rrMzKU@H@BvKeE8^Eu z*86mnO=vr@m;vCapve9-@M8r74zjqA(2CJ?0af3GJC8rvldeLyJ2 z|MdF@;yE9_kLDLI#QH10pTp;`{eGtHuj76Ayk7eKP5!mdF9=3S}BJPA93=pxo67$U=PLy^XJc3F+c|Qx)1Q| z1K_5v3H)c7I(5cD&H>te|0`7dKmC8Jqhn+g?6cT;papK>M8TdoCXpS>S*laG)aCdT2So+(ibs6e4Z!w|Cm(|zCAMEyrG0b7Bp=L z_8Z8;W_Af{R0lCX|CI^Y-+u&be;?ZZc&>+D->>KUUG3?~XLL@YjtA!)-|JXj>Ugf* zQOrB^Jh|6ndUFn6$L^B-HPHRqho|j+t@}0mYMgJdzt5rf4}yEL9}hVK`~TR}+2zFZ z1?2R5kIUKG@5%YU>&T@c9p!4!2<6Yej`92rFn%L)j*}6fPE8v zl<)xr`-lW|l*2>*kd+HVWKkxQ_lqc5d#ns z$QWR||Bw2g{I9|~;MFn}{^r_`m5}a?0VvGU{^|GQd_Q$Q?S1FIePCbj*GD}+2i$Wme;%0E zHol(6({Vf;->cYt@UG|aoO5{4`Sj~KefTbPKlQ%W{bXPBuh~D0YezBmKUOh^oO-E{ zoc_4HoNMr@T>PhzT=DH8*QSrL`}?T(Bj-xOl6gvGDOg?xeoa|Uroql~2vg@V^eWjl zWfiVziNY~uHP~|{AMgT_iM<^X8tYyP$F*ZePEzC0!Uf7(sW|Gxhk@{jeut+@t}{B!M( z$^Y#63*^UgPe?aM4B)V5%d0&;6MvpZp&ymqkug$}Oi}c}Pxw_Kcjz*#A6I*)O_4(IE@swwMnZi-@=d`Bji zO}Msci6K1K*Z6uzKftj7#{kPX4>$&U0-!JSh5aAkjTnGKYM##=1L(ehb^)*R86eyX z(852@OS!4}-}hew8z4_m&{P%wmz4h~S+;7G{PgK3(i;5tLJSbs08M~hKMQfawEGwS z*+dq$Y9fn~MnJ+_!VW+z!0a#HmvQADk&)2-e(?M2xL)q#qhor_m_9YHXXt(%%f~Ul zisN(G{#MjWGb+2aNo?umRq?@4<9a0f7G;lP6ER8X39Nu>Gn3A*wen( zdcMyb_aA%8!GFcgCBQy}-YB*^=rxUcp$?$1#6I zo8}U!1^h3D?LQZLeFVMojQBsCN9lgOrqA5NPmlX)1CW0m%g;G|?e8~je;vzX9rtU$ zpSJzUK6U>Z2z~zK-|F+{xZjoT*Zgy?U(NT?=SSTS{!f&H{;!l1WB&)`%*W;AV!aRL za<7(hb@Twaj_ z`7y4?YWvggr(^lG?x*cf{jc}yQ?WhJ^;-Ya_UE`?+y3U7U2DA0X2a*Nb$^mrKZowu zK0h_zN1q?qKTg}fd}cXOCAXY;qqv;=qKaH@{H0tS)K0EV9IDpvB+$~h(T^3D5%Bk!^ZS~AQ}>&5emb6y{F8k>_IIWG zwe4@t`Dxv+<9#^aM=|aGw0!y$2cuuh&8^JILD$WE(7;~Hd_LzvJ0fS*enfMWp81JDOJshb@4?zj>w}SkMKA?pxYEn;vvB%$p=gW$J@x03CuXX>}6#V|C?QgE(SGpg4 zfT{bfw!b;&r~Q6q%j9PxZn81E~cPR7A;YNA*Ns~Zg2h-0nK&D6@c=6nnIHO0xi3)VH; z)>P?pat@A_@R)qBwWmDR!fU%7!ejj!eg^%5>*4R@7+_HV)&caAGow4m!pQ+@FJQ*{ znEaD{p2uN*!20#;RSbX&``_~{5I6FVeL!mQS%69P|7!ItkmXUUGxCf{jmG3G5tEGSKIy^ z`usajah ze^Nm%A@1)=mqv0u&`WO24Z?gsVti=tllk@FSc~EtoNjQ)Mx>NYE@U&VZKf`D$QGn2 z$yPE>-RnZOA+4s1J89#i&cS&w5ad<}%3!7+py1E3rt zCt`2#{&Hz-2U#{{EclOupFfd*%|7SC8|5hsf z9|h(qYt}@|8jJyI|M0!EE|5jMA1NSXUVK_+eD$#`gs)HWk3Jv*aR76^|6C@#SWf)0 z)@KCP`P25-^L{GE&%wWQ>4`+e@wobdt4`hRcpUd%^!f74JixPa*rX3F!Z)4Zs)x z7yKunU+_E#XD=Kv>7nsP(i|0e(I@hp($O`A%i0+|1MIG>Dqt}LGA`MxY{To<~Z zwtq`mjJW@q*yD?H{(e~N!?C}%{q?+`+Q$!mKFzo{M|`D@*;{eFz~bNc+L`|0!HnBML}c0zBbCYp1mWHgCr zy{>h+MZfPQ=PsDvzez+3`vJa={R4dg^aFAXz&HTR0VIt7M>bCImMw?@I0zen%xfY0 znt#p#j2}N?wcFozp0o40I}&Rx1l&4Rha zyJ&71Rrv`#$NL@O8Xq;kNlH;ik|Z~eSglFAJ_qA zyubGQG2S<&Ie(7*weEMd&QH(znYO>HIX`pU&pE$jx*z*QQBk5uV(GHhkt;9T?0^uXps(bw4z@O$Y8WIQ3`0OpOrULaj%JN5?)jC{JZO!=sqEWjF{$TojSIO2fjRR2Q8W37*0v0O47 z@qXlA+y0#Q*U#;<>VC%j=skSs_h-Dn8S}$AKdawQ#r!zN{@U-S=KLM&{9M`oTKBt( z_c3+9^7(VVpSqty-Cr@AoP8m`T)@2l<@z7V)qj4I>tp)E_Me9K4xLBcznMCatb~bMV_(nd@t&H!Xo$laU>2>g`Y{u&3+~=p#FKY*+gLXy$cF_BsAP zdGe%M2go@97yLJMQ}e&?zlQuzpD}yY5)}i8wZ9Jb$^ZKG8)P!p2Yg%MDH&7$QE__E-F;VEbFw`09N-_1NF!U+>+e z=lnJQ^!uCfe%3Yqob%UyKefLP*7xhNKlQ%W{mS;&>?1u%{xSAH|8gO@^hIU4(&S6I z*1Lt=z`VcE_UD`*bw8Qk3Z_ljM#jm8Rd9U=u2IOgQ)o*YvJ1zGd!)NviGyt?-v;N( zHn*_uWIPqlHQy@T2G$|5E=0eMeE`P_yV(E12f#Q0t_7anSK`KXmn|FCt9<~-J4Ne# zvd^(U`R5#EhIqf4nDc+*c^QedKGglzJw05l_fdX7#{E(ML+4ZX>v@0cT0b4{ zqv!n1m>>H6wC|5|etMm+bwGemQ*SvS*UoRf7j4wjM$uI~ZMT9@loGoD1RlX-_; zXR7tNGo{XkDBVsS?hx`E3nA}XVz=X(3yI@3{W`pdHURw#oClx}Fk*sQ2XJg$R}{-? zIey}#()DCs>wV4ti4!N#&Q_}!0ImNW{Id_3?WX2`-+vAHpBK8I!-B9y%Kxv~XBrc; zPFA9hzW?w8>0U6KjCkxJ8ULSWCAj*RG9Na;%rD-Pz-OP35%Bw|=XW}Mf7Jat=GTn* zGyQ(r_eb{CT7QS%U(frSy5IEs>AiY2`=;NIF+b+GU)%nA&YydEYWB75ui|~+`*Y6u zQTHS6?=;5#XEFA_fVjWQKfW$k+t-mB82d|bpncAtK7Z=|ZD4eVMVyRNKe`gIy4xa( zbMUmsB71SZ54QPUhwxZ&j?~Gvi{oTAyyji=3zn6RM@p{acBCLXaor*DNaG!^WBm>)CVm;7tpZ?*l&zp4AJ{OdWtqvo6+ z`G@cC3~c{%i2J$p-eYp5?)!4Bds9gmI{^E5PqoMUaNNHgZGR^?Rsv3$?lJ|}cBdeF zz^o~nZ!=Y_lXpX`%q!oVq1Uy2?zH2{ImFcGighyWU|DfZwym-Y*C2-|yY0erC3r3S z59J3$Ke!p=p%v2+2RuS9P3(bX$f0uVb&$Rtbzdy(RntxX@KU()&*ZJyke=@&6_&-%XlboxR!#?)^ z=qb6<=)ZEk-(Qk2(Fgn8%(naesQY(Nw}WpjyTK`Cmm?+nCgbL@$+`7-A9!{OK1(r= zYfk%J^UjpEyB4k69jTLfa2{*wcg?wG*+>=ZI5(L;4E7K2vCAQ(`Zer7cyAm7Y(Xrr ziUanSt5f>m@d80|_}B@x4v_kutW(H7AWJx%$UJ{mB=EWSjQQiZpSqviCu82hzR5a|_kvYZoP6WD^?1L-R##(m zuzbJ}Jw|txl6S4slceCCHhdEOPUamtUF&w0l5dA-<`3@$`wlt6)RE86)pjQLG%k1yK(<~o1t*kAkot-7CMe;w~@U+0(T`#VM3A8UTj zVeEhL%}3<&H!sTdcD1p$MQ@C4;osuCALsOTI@sR}R`)nW@r`3%v&ueP+Xs&KryvJ7 zo;En=Iqi0>81jp4{#J9 z=RP2`0m!|*4_GTPm;;zSFI1X8RZ6_DkFVE*Ik2a9ZW)F+f1d|3JD=leKFfoCf9t$I z$NwqC{Boa9bC18&__xOUr^LUG`O&(cV}Bj<{1H^{&55Lf{bWbv+I9T(EQL@1x#VjHCVUbqM)3Wj`2ABFN{tV%?G|&cX6QEy#DW z?qEEL4UcPD$1CO?oa^zqX}^ zr9o;hkeDeWWz*K}a_ZD6W#^N7lYR1k?%X--J+)N4y}cFt2LJQ{)^$_!zwf_>{Er?z zwkOsCBt%6;DZAg^2Y`Rf0W8Ma;AYR1l_9xoGWdZk;st-7H^%(>d0y22Y4LB`{v7+$ z{@3$p6ez_b2}@ZGZ587I8o4t76{&qq1_f_PcVu zPfI-OdIa{l3AT^@sr&cPZr9v{)qN1M%~T(!#Jb|2+(4YX8^^J*t6hoJhIjhqHTz(k zHoeoX2cNX%sna#vM{w@c?fSZ@3#Xka0cMXR7Uf`u~}?63?1u41m`E^aFr>N}u~4Og9#QzyFv9^XARJwh}SG z9QRXb1H@n-pa|>@^v7#2%K+>JJP0{l^U5f2y1fw!hu?cj2|7a^;I>v#c|Jer^{LgY@^S|%E3jBXKYgX`Ot^?HkGiCimqEBf0`6to~`hN)c_qqxG zt+sy>-yi1w$-i}vUvu7{G5D-MUrz|2YS!Z2*V<_rw6Wu~!;5ZhRR$5AY)Q0i@p7eE|0XS`MFJ z(;7cWmpowK;Geo*@9VGE{LuHG+M1svG5;9%n=$_!_glyQrte?#ul@e!9)BkP*0Dd? zrq}T>twQJlkdvY=6xA#bB*3=lrPqt?X;&$+&r} znUABMG=%3A&ABs$?v8he*6G&N>9>Q9C*Ox1VzN%%?$qnxROxf3`j~p&!Ld%YZddx9 zc~I`((D$CtzYKMC7k&HIsmtogb8F~Gvc1igECJkm6vTd~2>%N;Xmu&A3hvf#rCIB;g&`n5S)dotmsWkHNN+ zdDD)!aIX3S%QcgI#eXX7(++U*&)}{Ss-rene20b6l-R{k88;$NcN{zNYVwy5C&y>m2(V>;1^Tsr${CU-ECp{E>e>?`Mtq z(Oj0R$}Nv%u{8f7o7)W-g5k3Wn9bj)9p^*)UGdm8*>ukVZS{ayXOs$6eX zT@t)I!k>k>cCPo?4jY%_elj1M66fF|-XVvOrY2U_t>;eO@i|G3Gs?e%U1xuRbA7DG z1^Qf#8_e&+@69p z$-d^FV*>K7`DY(s>;?SVeGjG^3&7uhtUvbx<{W_5|BC;OTckhs0_Q#eWIv<)tNlK( z=Ffb-UrPGl%D>*{*Npj3i+?lbU(fq7?oa#uQ|2GGKlb{*^kxaU`ZLD@V^Cpv8-={Nm+6v}p=wr<{`ZVfuC*Sy;PR=pj zQLzZ{d#YGt==%dG3v$nWhPa~nwG z_ovtVrl$WD|A_z5{JUE7r=IOyJaLbIt^ZTv-;DWpj{P6AkNvGNzh>NzTJMK(K+^So znD?XpN8Hba=kwZqfAv0)8;JXnaRU+4GS|M=k8ys~{fc?87jMWR99!iuu4PETr0xe& zWM6Y@q}0oNpL!3D_58l}6DofK^)^Ju0jiiG*fP#Fz4&b^-WY6iU9Z|J1ojRY=iHv! zR}6EX-1CpTGv1f`er#A|kNe}iUpUrA&K-tl0rrv`qyCiT{{18h?dQ^^%TAl0dY|)t z9Q%`h_5;(VO;hWDHUD}J5dA{W`yNU+7Qo1nV}9mdz*hdb4?rl^2Y*rZMd^dMpJDI; zSozm$ezosk@AsqQ{!)9!7kz(L{?$Ie82{`2K4|-E-yijVdiXcT{$|W?l0AOm|D*5! zEcwTpzY8xFgzvAMTyOfNB=rBw9{0nTU)uir$P0D93)VBtzQH=#RlWdyP3vSws`)kN z0(C5aiV=W*rVm~T$0xAM)jEAJ&9OOcbj`Hd^NUPlyv~>%?&HhneJG|^qMuuC=bHL_ zV>sfS7Gmr(-_CgS9Q*iw6r6*EYXqU-N(E$`us@%osq;KgR-KKOrC>z|W1%|Gxh!Kfh70OrJh8f&6p-Kf4VO zgR#ImS&IF^zQR5LU9b;GM))_!{*3$AzCUx#e|q^h`&j{<^NWa>)7uj!K)+ovlxSzU--2c^GClw`M0v3(z#XlYun$M^0OSG<^dc! zTFnL0{bo?!Jc2;MJ9AqI{(VhCUSmY zJvq{|riArsB>@5BR15(1JVo=l&V@L;kJ%{khWr zY4K0rzje)zj{8ZC|I_sSbKVbeKNnsrB3HhCUd{U_3`e`>njh}*&6q!q{b~EB#Jlr4 zUt>r-7mANlK+VlCrVIIkgpq?|9$^esFzHmM~^#U-wQZOv2W*} zvA}Dk#h-slgJK0_xPyPa?oW^X&1ZdR`#&xI^?pBQ+>hSxOOO4{xE~$+<4XU#+V4Y; z{q^&GlI`>9jQhzd=bz7K_x;uQkKFjDA)aU1-@e}m_xI-5U-NJJ{Adq21-=2!_p7-< zu&tOT*RaVM^RL$a;d9hlKyb~yeYo!r_x<92e`?=P2h*lK&gb@S1kW47?fQBx^>rxr zAe;+*9b#X1&;7T#2S4}ViI`}&%NN3SS>O+St(o?Q&K?Y=@w>23rv!C_-tG(^2lg}{ z^S4|b)ke;bY$Heg+slEGon+_8E)wI{Q%@3Gw%mS)+%^jIn+)d&(r4 zhZvtlix5O$t;jy?`F|i5YyA&njX&1-aK2yr`nAn}>Cz=3`?US9U%#%N1wz}O zK0w<39REZ2-v|o}d-=YH(v1aR=YQ-*&H?H;Kyt750_ui+0BV#hD!!NlVB8;le`)Rc z!!^HV?5|b-XO#bp?)Rhlr|&=69{-N9KjZ$?y#GrN$mMrS$+cQ<$&H>(MY!f~A?#qr z{cydHTCW5Btzv$df^iiG2*#PG*7`wrt95~RJ^AK7U)&RjdxCL~U+(G8{r$J%Gx;tZGuQLWfS3_S< z>8*6N1a`n!yp71{zeN17cd2hPQTDlaV>#m0T=sgkl5Kr z0!RAFxY46zEY^Kbnleph&7CLn7lq3bj0^W2z#d*;n|u46ISZTq`~@|>C(oC`GZ{C9 zx?Z32nCw%?zUH561L*T7|J4256C^x5JRWgqIo;U&@B6PJ|Cj@q!a2a@81FLkN2Bjks&Wz^h%M)>Evzn=TozJImn5A6S2;orL7k2UVky5=`k{+~hI&&%-ryS0ck{Vke6Am# z>$?s*JO(;E8jMH5r?v|EdnNSuGBCabj7Pv0Uku$HHV%4wlwEJn@pZ60P(5EuFt5%% z_62sh1hfa+twsD>i41Qp;)7?C4QVKs2R4v%{p-u&z71q|zu#qZzh<&xKx+vd)LCW@ z>L!z6p9c&dDx>{J$`~*nG!=}`nJe=bE|zUOcFMl}2P7VQbsWRoJoPu@bvSk>$Bf-) z9G_10u^HE=<9l3<_qE<9`&X}CRrWvU1<60zXAB_c12F&Wf8PV?<^mx9zP=-S&YvHq zo(D)DApHPKmo8WRzy#=mub!`hIlxRA(*IWe&2@jSe1F!tKhyp<^?zFYn`3`H_iy$6 z+2ekp|FPfKg;xs6buIG^>wxB&GW zU+^6RzN4YTSCenp=qteYve{r8d`E!qMbO_1FxC#mSbGli_iXslW2YZ}s z!zLfs5nQ(w8Tlu;#(nrShA*-)o;}n^E)M)nPW5jjhr#v!-oMG#UX5g3kKbi=&t|f; zUt3u)xQop7=`F#2UNR$KluQenB-5u)msufmBqVf!tlzj=IKF5siX_=OplXV6^+`3s|ybsfr0)usB>keY2YM#2f(k`%AC= ze>41>`~8uB?fbjk{L}Y$hHL&RlYhkhl7H&|ZjHeoc$^MBym%JoyI_;A3l3&lkf!SU3e-gY9`>I|R1*tdW>E0NYbB-VTD^o&cLXpa+g&m39UrMb-P`j<@Z*+ByO_mq)? z`^(6o-Vy*idD^t;GMl;^b+a7(^*%gzI}Y}F{E?$_m@Gp$4yP_Bt9l<^y)VC+a(`aE zKeyhm&)l<1ui-V<@=$l1aXsezKJ5i<^IP>k+2`1w{PTFuoH?BH<1<0FM@L6j^1yg^ zO2Efw_@`5+PQOl_zj9?1*k2}*cm@FH1j3Pi_tjU@33C8`4*tz&ed>LG%sv0qo?jOG zKRxc6BAX-LJBsePfy4sTI_JI~m=ly9^)LUq%drjSl;K^0XPwG5F5i zd*lEZk3Ymcwd_8&jN-S3Kht@lm- zUD^ERc%ORT{yZ=~7fgM30`B3`rcIl+Em*K%64-zA?zDW*x3UBV5B4cPe*C0M)c+K+ z9}%%c`2%=fuYP@LStPIcV-CQK{WJIc)4qSEcZz@Oo!6qLKpW0~H10%bGZRl~IcF^C*8vs4t2ev{_Fy6JET0#}PxYw?z%v(yErMZCy{o+c%L}|NJFEUBP&-t}?7&Zy7PvN5+gBCqdNX zb3w*KYXG$@n3)f3C98p})yD8Q#5ncQWBRI*QISkM%X(2Wa-K&*U=q=Xa&| z`TeeJem&mT^Lx8+|NKs*H;`V%_g>n)d(Ro%)4uK7cf>&N_lLB=-2eB`|F1!cpbzl) z`tE@)2>!o(qehK8x^(FZu)kFC&pv=-fYocFrFHubQm1$!#lL>mC+GiC;@|ZB>)4;$ zq5sq3-}L?Ib$@#9&(!~C)VjY+auKn=mk|4V?X`#G`bSTS)Obat{s$t>zLJE$YRJ_# zKg-27HRVj}pC$gUTC)AG+On=yZCTo~j?DeDq0DU4M5eWGC6l_elSzGh$W))fFd4?m zycyGEE}nBaf58G-7!fI3ckGny;A0PUAMI`Kiw|9{>~z@bns4&EbLUR=j0`>}gTl4) zO!al9rtm#lH1j&;=Ti5l#J+WZem&l|>iw--xA8s_wr$&f8OO)BY}vX4YsXjOS#cq2 z*Tw{{Sra`HHh*=ACR3GvU1xj)SR>1Tasgnzx?zmEN}#{Sa(mzMpX5&pU6m%jhwNKatTuTzlI z4mpeT9OO)SMArOFf`9#9CN`}rWBzO`BmQnBUR^tj zH|%rHRR>I%AX8?}mSC)#*aEiqVt#Btx#oWNu+KRLKMebswmR);lV9?zW!tuG;!1Qr zQ{4~f^k&&l&F1GbUpH;qOt}WRv~lCcgJ3%b`#>&&KPU(`e|6aVZ$ci2-p_;azGsbo zYC!$V^2q0ut1#`-_R4DUm_1Lx}=&mzm7$|3X07m!Jni;2%GWu?#iRi*2f zA4%t$Kgd5VnoFM^-Bn!L*ue2Jb#}1CfQ_xtx%>DWYlrSWWbAECM!BDrmMvShNNS>A zr&BBcDY0*I&tt9gnQDEnQ&aDAFINipbOX}~>(;Hm3^@b1;d5KNEGlaCEc8*$q5D6E z-md~F0-Ha_zpM#+Zub^Tz}wq*@LY^V?c7H=`R81~Dx~R5A&4>#5}CTekU7YdN`HwXE>_hqeryA0t@$b^%@4uyYpFT2tq`w3P zO_5ol3uN=oU9tsZ@9lf`%C3F;WG~`eG~*nHYi?olV$Ji0G=;A-MfU?bHTwvYea*d2 zO}%gGeADI!%W6Ir>1D_nFuf0ZXRm=zHUz$z0K{w!hR%NpQUsC@k`v>7k8S?{h)Z|< z6wCqqIC=8a%hdnmUkiPJVYt@#+plE+?EjIN159iD&*%Md-9PvJWb9us(z!_ILBg>A z-y)=oacvQ=<2?A`Ofs!_RvGtbE*V_r0qIt@n6!DOv^0OYk~Dnhb@}D9kL1^%f0X9U zno8@x+e^28{bk6=Q8H%IWLbl~$~VFO-iG)V`p_BUvX`7Y1anJR%Y;46xu;o7j1tY3Y5c}-2%QNQSOtW z`|CpQe*}3Pk`LnXrMU};`|NuL4f1{?AYj5N%|D(CA{5R8F2NX}b;AbI%fUZ=|7y=) z>;X0&$3c*3km-=Al){Mp#q)rIAQN#MfNOk@AI=9pl1I9gc}Ut=bxo%v*z*_<{P^98zA2PV-SCiy-6{C-30r4D{S%Y@P%s|7(A$0CB`kU zSfOPlcv_`m7`eub`sU;o$ zXeK>6b&!62`^q41AMu8b?l*pd+Gjj!E%fq+jk0+Q^*DUq%D=T6^IW@BOfttHd}b8a zj3YCQO0J#h~iTm3Eo|nOIIt$~bK$P1E z*#6%`K7!7#3V9k*5|SUxXT1li+j9$^5=c@4{rU~cHf-34Et~_O-Y5Io23Uo?fqV7r zDgS-6sMIJ`Oui~xMm~MvS^41g*W|-@-<5B_`(Ela{7ss)ZY%A&_mqLdhRf&)lVn=( z99f6hb7h}%4jcX|vh5ViopJAB=tJda;8?@t+ddD;cmyq)f4+{gOubk0&v-?$uld)y zpQ)+)wXLsHtG&!on5}hRy#Pq%_9+c_AL1ouoB+PX3K0 z;N#=Fc)@}&C-++aQ~z?_yH@>QrSYGwr9-#wGROyOHUq{>6xo7(&N*c0H%Q`q*yhb! zl^-!8g8oD;iSY&Gn;hG9yJlLaOK_c{&+WXEc`cgLeN)(;+wT+b-cA zPT*d)gY8KC<{7Z}n?OE+JPo_QAjC5t_HS&^o_o$v31AE`f^&dc?=MwEFoU1qy#rp=>?4j_nQ`m2C4I%du#=ROj8TifsU)Z|?2a`L}?Irk!2p~m!y*U9@b{rOkW$D9faTeu6h_!^|M z(f5oC4V^z2cK*xo^%a8T#c@uI`8{0!e`~0o-*ZPw0Q$ellqu5^sH^Sl+x-AMCf}NQ z+6WZzrmkDrPt^OIKcLRHv!AH%^|;;6I9aE!oZrLuLbwmqMMx~z-h|JOKtB_N?;M7B zq>r#S$&>KA<->U2<4e0EEy44l_hShR9O(7s`0*33li5W6?R^0_RJxwy01E8^a&Kop z49qTq-9RDp;fi_ccg;3+x?^l`1FyY`&%1>8oV2Cw<-F8FCbL|11A+n zo@ag7{n!vazxl3|K>z-OpB*zM;2QNc#?8)gJM975^BmvX$M|8w{(!vmbri6i0R4O= zBxLTXkdQgsgM;TR4+@$Z92hupBGwj-M6$wx-o{dIcG4joPV|LW}7A(tSB5i7i5^5kiY0|F+_ z0OS6{hK+o;SFeF(+qLWZVEgvnJ^u2fMe8~9l)%5D1V)V-8%eu7I5=eYtXZ>H;@JQp zV0=9I{%PRAp|5u6(Eagt?Yb3%YcP5R`>Qo@r7bMuSq?&)-W=l2yvdva4wHKVW*;2iMeYVtZ0Qsrj zKsfSKy8-5>b_1P|pIQkpKeZcRc4{}E@>9Nn1eKri4cPNjz5!GZ|57XgM}CSofa>F4 ziZ|fMPw@s&z3MNe8_@YF-M~J_`%}6BouASTggf4!QVBToQ@DXn`u!=~fHOaZ8_;i0 zsR|PFUEYABdig4sH(=zuya7k`s&8>s1!jH@N&cs+mmiQRdA6AOwvNePpsQEiK&dqH zUEIJv^+v}(7dMb3-^C4toA0+Jzk#Ir$#0-jlJ_USfu#A#Zy?FrZOL!Il5f2MvwHbb z>kU}*tv6s+ulg!W2_(z6+(44*b#Vj9@+~)zr21XlK=S;gH?U8=$NZPH1d`_`y@7D^ zt@h(2CEy}I$qjT${{AF4kUZOF-axYI;p>eXNM3x%H*UaXzHtM|i;rK>QS{$Fo+kTC z>}bN1s_v7_n4mnZ+LroX>a@;qK~-hk`u#2ZK<-&q1F}K*E zZA*QNtM|Jze_!&Smt^>TC-R+@ixP14`R>ejsUTI&*#F&;{EmrV;PUftW4=oTW_Ae7`EJJuH05kH zLM@f_ElJLxAXCf6`>Q2+z4au~)U)Pz&hK^!ltbI^#P*LTNM^E?=F$J-zrEPc|3D#| z?Q}t;*gsV6<>zMd-Z;*qa34f1`r5sG@3`H2>F-bxn=S5tHd}0e$aI@6ej3ibAa!v5 z6xspH^ltyLKDie?_pZ(hc>q!v@}MDTyS4%l=JR!YJ@4Jq7ElPT{|;9|9s8lK4}( z?^fAQQvZ&ABla5Ve?30Ci_NzG1)FUX?Q_rHJyim6uc7bXiaN?*U!S4ZqaDO;KwIdJ z?|RYG4(^o(K%ZV*U&t-${q(j4hN}a4%-2JP_aX7Hu|H) z(+=)PBcKgVd;E6P*`4?dwu9JRxIb^3ZQnZ>FL3_O^LJZHKrja9c${PNJ5hJH^D{Z` z7`GeuIt=N1Hrv*Gx1|W~>ko;49%Z@i-miPJ9jW=}y=Vs`U>|&FvmMWmD)h|dX1E>G z{}xA|?7x70v;Ot5Y6tsaEBZq|#<&qNANO=jQif~j&c1=Zc>3jadH!2dr56t1cZ^0` z{tRQsf}VDeR?FcWOne8F8Rus1A)EhJ?nU(nv1kM1@SFY%-GF$nyV@Vz!#e3;Wz;|B zW^bju-Sgh8S>q&2mJEMa9NIx3e&7Ef58kDAaF50o3g+Qs+d=Mm_OoV;HXgRYM99}@?+>}T9b`c-d@sbtT9mi z(K2-J>&bq-dMD-BvFpxd9;Z*=kg%}J(x}lXdGg7dX$NtK(FUgAxBpGJEz#xp5=GS^xUr%$XaqXwhY9-1xMVEqg?= zWy^5eJc93-hH|KZ@j`L*2X~?!u>KKCcdz&+7?&OQC*+=IKTDQasZ-~q96g%IzOH*S zJ$v?sgoj_2X3b7ZxpFtt4q}g?JZ8c^_!;pBC2n&&VE_I2Is^xCxq@%KM34?cKP_3vmiu_w?DLLhZ)wmqe8aV-n$oomq858Tzif(3WO z=8s?QZuWoq<)oZEc|+;&sZr%NfC!UBJl{xdl>$jm?(p|P>JvjIx>L$^C zqbG#s5laA@xCVu|;#7(h3e*6U~UYzXTmil-6&e&7#xa^OP1X1)_$K1vK~*IxS_k}Bq`ej`-M4kE~zn|_U*9EOr4rB z_W8kaao6Pg?{6FXF4}nPX|NN9w$KQE%U{ijzt0k1BZ_u9eK5K<-IQ2v#Z~Bd#;iFAAdZd`uQZ# zr*gt}z%l*d!`EGo_fvVR#K&Kk>eWxcp17U;ep+P_dlvN{fp*Xw?V(&MYnm9t>hAi_ zG?y0iYB?St)L38aP1 zwyy&E1FNl{9rbU$mRf&t%Xz(e^~x6<92_`qT%^tk;DBIX`=m(ZT;9rX^i*}%WKGY94Gj_P?b^!JtpEWCZUBiY^ZfCz(v3S^T z7c$(3-%L9o`?M8lGqT;G?C$|#JBX$K;62A!f$c!Ig`2L^jJ$Eij2SNvAHLvF#fsb9 zTpqFV-FL^+^x57_UAuY@ZH1aO?*;a)?M|(0qiygO>WyOnirfBzgXg{a>#tFVbL4QZ z-Y--rUPg{Q?-urHFK*m;Ro;L9nB>S|E&qGrT(yBf_>Qo5mV5tNwp?1Ja^{DE)E__l^5q0szWj=`ZF@$lR5>C!bKVQ}uJ1v`B*sDyyzk!Hx7kXU z-deUmfqgsfhCbxH9moDPYMfNMnf95h`PMPQ*;~9D3g(H$H zmuB&Du)SVnYt!jdH-80pktb{l}Ph#=FMR2E5CCfY~1G?VxDUc%gZjUKd$@<%K%9!t;5hN>)jMDR zoM#LRyQJcXsgK;)A6|v-M~wYV#SPr12D7&`es4d>LHzc6Mi(%ifA8LFDrQ47dZ$vx z2mb#1$-ChnUTd>)@8rAv$F(m95aX(1p5yO!J1AT@UWN~MANz|IU6LoBaJPS$>uI^R z?ryTL+MUDq_zmWuR$@%Bt0rPt5c|$GG49&q%ha>6^6|&VW%q9Pu+Ny#CQVM=4fbPD z##Qbj`Hp&5^A4PQ;v5v(KqbT?%zVOTTVD&Yjc5l4*&n#gHlTla*szSVf8|PoiVL8< zklrx^^?rExC3)&8ceAhd(CO^{F`sH})_Ui>GwNN%A21Gqu_*a$wvvcR8&KY6TZeey zgGbO8xSpU1o>g9D#wr#s6Y!7L*gY)Nas8}NUBk}v(DeLil z&!L>%`IpXmS8EZlM}mq;M_h8q7qATuxubjv7K|4kpYy8jGGgm7HmqsWQ!0L~K!G@U z=bd9RXwW&?vgK-u?SO5DYXR(Iez(>?^!~xFsl)=^i8jHy=lrtK&s%v{^$zA$y~7@~ zaZUpxcBd+(U+*l{!LUoz^Ebr~!9^T)|sZyl8Z1J22&O;^=Ckl7!Q z{T3}wVXd%R>z?m97CbqFdgUc7kW*I)nO;e7dG zTA}{W-|6~);DLAl%=FLyJSlefB2l?{FNwsQ6rElMJYA%@bfn{_LJ z_gw@4mYjW23ZVMDpg{4W3p@ z!Ghb-4$^+T*`Lto`pPRu)p{PT=VHv3*;ku&ZXPohnDv;xxOICw$eTA#Dpx)tMT*eo zcc;y#Vm*4@;eE`lb)WUqPe0Awym|9NSmW_nj~;#A=+$e$5B&!Y>e8>@z)Ai34O%{6 zz>tIe`wuxYaG=-K!Gnh;czF$j4dx3OE`taA$=h!)Nf*~8N^F8HJz8qlo+vNB93h1Y zZBJLb(RIKzJzUR88=mXB7!#0MJJ9x9#fqu1@2Y<7?LdF8`%>@FkdT4YtRit`{TS)3@*7Q>gDNsPBZqgMGx?+ZW?)Klt1H zWyFY4N_gz+>j!=8kNRJl?)vZAEl~VNjg#TNlcjCb8S-A05Gj^(H5^>~(#e{A?uTpp zYSy&JhA?j5RXd>1_Rl|0-=lF|$=V&))b+icbNt_Y^Gz14-^kskPoE;adk?IHdj6ze zzX459$HQtQKlWz?v# z>e$b3v}y-FKBEvjmp=ZVcx<~2Z8KD+{n=b5fA?RRRJEdvE?H7K=6_S(%h6SeWR66z zGuuIWbgsP}FlP6spH8aSeZ~ancA)LIN|iFoezJN=XS=-B_wiX7+_V1H|4`@I`}Fa8 z1NB|w!!-U_~Rw%>c>lD3zzOitH`KAS!DDBHYI*YhZe9&?|cQMaqidT&Fue3 z(aaI(54hGS{q2D3HmX-Ysn&?c#$FfN{B7F&Ti91~YW;85^9s;^mqXvZnmQYGevS2N zO3!|MrL|u-`Db{4>4Q9b8yJXj@DSC{vtC)hX1xaljF$-$CSiTtWSOWWNTyDnA~S=g zNv-dfV2qr$Jy#&pYH6P9IT@JOCIj=?WiZkq`EBA2844Ltpn$Y2P)$C_(@lzJi_CC4 zV9X$6#kzDkD-|mqaTB|@%08cwwg2^7C*S@F0|pE&J!p{67WU=n=N0E zb*BC;EhhGm-hKN!+QuO0@}cO{{Z-wQ@$sndsne!Q$eg({Z(gW`%$y~YMhq9fc5TJ$ zrys=k!?(r1Y8CmVcmv5{OM8t#ZrdiQoAX^&|AUNr_d&f6gA7MM;8!Sk!)-|INj?Z;K90L?%ipL`ql&?1TZ%qFD7xO0_URmBDF-Rr^PLRm~0Wx#cD49HF_P}u)?YK!nQ?Q@POqm)qS;qPLidWk<(zE)v z(&e?6q-Xgu(*My1rElRp(9Kz-S1z0Mg!F)PhjfK>q2#p5ui2lK2W%_SQC991ly$Of%BO%Ndp#uv*jlgm6HGb=wT!7n{2Ayv!DT*$mv%1J0>=F88?ph{m$^%8yM z@jMZdJ@f8#eeZ2zH63j{L;cP!tm}E}cGf*VOGGk_8#kdf#_ZR8d`7@mGE;_jXfLg* zz96m2l#q5s3P_jyIiy?e%+ihZoI8_rN4ZA7S1FSi|3GOPdy0c%gEgSRFKfuE6V&go{&C>nkseBQVk zZPs14d|9PCxrcPmpG|n)EpHa-nkRFT_F%pz`EeHcAlq-S)v23PZ~vKX`{kqTZNPs{ zJM*af0CHd0CKDdaB$G?zl9?5X$y~6$;LXYs_Rh1i=-uaJ@w?AU#Cy+6BxK3^FUYbF zUXbOGMen^XBVVZ@b)V=jp&H2lGhJ!nvg@QTKt)y0^)sBAH}rsXP)~xrE|<(fcn-_=hh`d(vPaj zvX86E@=vPDicepWm7l#Tt01dCe^u7}_dl}q)3;^Zn?Fl~@&lz}!3fEfWf$%xJ^q8# z+iP0w`R4K&D;4XDePgk{;?DfdnKP#X?D@T8#|C1&K1KZ6w3beJvnSR+>Xr4~yJ&vt zQ?!8eE|O1rJ(Snp7T697=5)4&ZtNFypJ28h*a@ur-WbpSo%<0flX*(I%ADhXuX8q* z(S@?h1jRk-{z02eE}BJVl*upi(D#$~C7--1%RYZimjCy4Spix3#Tyd!zc*wxB>Ky0 zvi7Stm8|>vO%JH2zAvO#-W>9Fwzlx!rf-j+QdvT!eg3Md{#o}ykg3J8$m}Nz zN!Y7pWy!~{$nyWaDJ#EvOICgTwygf<9a#g3{`MVN``x<|16lw5yRzYj_hchvQ}y>{ za}CIk@5`1SKaiLoK9^}9*O%s1hRCxIMM$1|rX48u{T$C4x?@csEG(?()Tz@KO_&e_ zpWPIhG;*YLD)q49pLN+6^*x|e5lB(#U-BX8SK`6Mwt#lgJ4v75&<&10p+|vi(i3BN zUHAPR{=9~{UYCNIR;Eh_WU?KQ*Rl_ip#_V{WYql>$c*CIWNw8b68`2hvf_(s67}8t zvgZ2_B>D%`XY~(dU5yWA{f{5YhMzu?jX!-Xn<+Ivku8v|wLXz;wLX>YzfeAt9gv;1 zKa-6$zmnPiYb32+^p+QjMo8Xlce_7`-H-A9hj*;v9Ur`A&6?b>`~6w>lP6D=nef&A zQ@Mg-pKK2(T}%c&{)h~GytoW3^RNtftQf8(wgvVHY$Li)=!HIkc0w=M3BBR}>6JgT z^g+Grx~D&{Ti!zQTvi{{f7;^!>djoXt@3@Y#xk~WKAB#`CbLWAkOh?=k)^QjqP}}i zqJR2CVrqUS>mVCyp)PBEE}MS&TsGJKuWW&At@B^mR_6=ZUiW{p1G2N;|72JFFO}^6 z^-J0F>sPY3!B?`c!Pm0A-VZYGyQb3S)uHlI@kq&+{cf}a6(j9$vz_E#&Uf?=W5CSV zyQkaa$5~-P`@SnWT2E&m~``m~{04Yy*Wdua??*>dHj4uQ{c1$>JAE zE8A`@>VAFg|H+2BU&=mik}GR>(HiXM=BK2hyDlzm;8(-M@V+dm4Qwdm;ON z|4#P*{=Jd|jen4XP3#iew7Ts6y{3fy)I!?7;VUmc0)JxW{pr5fo3r(j*q2yGdGM1v zTJeq#rw<@Fcuvb{(`H_UVC~u>8BqN@`3Lpi3-v$vsgmMd;c@YTpU~27 zw$Kl4VZfvC{XSAa`W4RMqV8?Vr`IdrL-Jx)Z!8==knVDQFmsgrlCP0WDP2OAy!xc9 z`T8x{PzQD1;5*sU@O#<%+xM~!vc1s{vg7w3WM|{*va4|o*^P8}lNz$O>5sCn*^jcn z*-vr+a9U$d9o=xpY`oi=_&Df<|*;6_@sD0{e)@@L)aD^ z{Q~=lfz%Pu4};1SlfjP_kwGOMkp2a;!G~*~zcc4?^c+s3+#g8cOzH6lC$jNC=5_L2 zp{_FV<&R`-^^asT>%Ga3vc2g~vV+p>XW7~OXW7-frtJBHQcL!>s3rSb{vrn;2Pv&; zODrVr&pHzKR~?C`w5}_M+ED7r;kI^J*SLlJ{pM&XQ*gbT>R$cMShTax+*0w5FG2lR zoi!^YZsyF{5;{Lj#`fwZ9Up){A9|eJ4|}$PlA%?~i%;dUiEY8rFX*-~!}jr z{lvpExOjfd(Pmcjw`SdQ?w0d+oWt=ckVihr(FOsm)UkL5ieJk;V)KFZG!D#*mLL`&@cE_DJR3LJS8J4 zJt4y$hYl#1RoQxE-wVuh9#7Xj=kPd>LtlOXeEEOm{Xibcyy&L-Sk_V5hhn7Rt5YPX zW^Y;7>Mz;Xp_#;WYAW%ao64bon#o~G*XDA#OLIBW^$$7P?GHHyIo`bm(w1_tb8Crg z(o?#B8X&KiSs{6{r_VQGt!KuzWXrZ6YjPN$o6$Z)>HYC|FV{@C^>4|NB?afqnKv^e zWG?nc50%hav!!RH3d*m?`XBk9=f(f^myo`oj{RPJ4sGFC8SZEc!(V(x{9ddmBVVi_ zBP%~CLrWHtLHRQ|Y<+v(Q|EK;-dXpkfBJOk*Be(jyVT9|BW!`Fo9=5fqaBngxJf>% zxKKKN7${Tf43t$ZyU4co?PPD~wi4T|wZwIABL};-mHl1X$(Ht=C9+u`@vH79^+Exql4>mhez{r>0fW}giWK7ee9 z+Zh-fJU2nrf5;r^{mM(2A9w$%p>0z3%|8s%YN73BC8; z5fB6wML>#z2#N@Z2o_KgP*fDrPeu7GAVqpFfdohak`N%h_k{FD0wKLOdT)Uw_x-ya z4U3>}wvyM!o@Ei~Px?W@N&a@mZ8|OcX#Vy?=78k=U)<^a12EgjY=dgPS$BD<=VPjK%kNhrjU)A@- ze^bR?UB?sb6?;C*gQVTf8ewYPx$Fa?Z{N;i_jgaXm#7-|orsJOl0I^O&$|6L)u~f} zapO|B7w91UAT8(vy)$Xou3a5;`>~5UQLp)s_;c@jA@zF6eXQtse7_>^c`ZJD1wYZ& z*Wzyn-r$8E9^Rj^4_sHqe|Oq|-g*;@>k~)Xe9VUr!tT*8VfU-UVfD%|SdDs7*B?d> zh1JL**fVl4_KtWSdj>y^ZF%Aebrx2(f3rjPux|xFZO(UV(&!k zT}ke(G_>*7$9E0iM$hUlTqpWl?QVC~-^5?EW5+!1`OQF3&@t`_PGs!Sg9`rS{S#(p zWht#GL&>;`BaTf3Dl#dG~j?4%mnCKS%KQ@$rM{qDA+!F`dfY3dQLq^|61HPshTZEUu#fof?9~yQnpC?@-&f_ns_#{h`<1ZwY^{M$ z8x1_^-?gFHK)h0C1MS3#{}@?Nvsx~OJbi@zlIe(v(P5vIl*GKDF7%rdpXgl|C<7+l zeartd{?o(5qci6KNuHj>pEkffCMNi~Z8NUXx4%;`!U?0iu&DU_? z&Cxjc#w)NH)?bnRn;ID@bN$=&{VL?XjQNhl--UedM!xqT_TI$aj}*{WgWz`jymc#l z)#zh%ui^DSl?B4{otmZMtHF-&{Mi&qM-mwmA_>Qi9Yb<*GX35?Rr!Bo$BrFy{u!v= z{jYFxa%x514-))k4Zv}q9e(Q3nQOgGmGOVyPeX;RXrSDfB^Sy|@FZte|d>=&IRqP`=Xb?q;?QD$DKAo|B&>Xzk z#|y0+r=yyZf9bE#5p{D0!F|kgM_@L`4>@MG(C#w#Gj>E?i5ODF@h{{BJi&p}u;b~KjJ*Gud^``>*F_8+_h`}g00 z!v}A}@q@{5{$LVZ*a!B#^gOn;Z*&{)t2Vy93~u<8^CQ3V80XCxeRAF{EYO&F-T2KRmK3pKQ=a&`yOS_>n`Dc=dD|} zO8lEg>R=v^@4UQxOM-$9;n1N_teProi+crscy$wI9fc}joK&GV&CR82Cb3*L?D z<)TOX42*mJC>Bo(N6;ECoS`ptnfC#}M`%CbwGVKy0(P&(`3*lIH8Pa3#nKfSAow3W zdKA{y)`|{D{G+#T-`?ht0-ryY`rlOQ{+EM;Ll7Dk4wE0}VNvt?*iQTIfvJ<=H1h*E zfARrbNp2s%504pBU_X8&%pPlrEsc%JZ9OvXtMfgbzjj4Ck0Y@coloX^mF2$5`{i<< z*vEI$;8@Q($atkUisntnIrH_n1w4JkdEF&vsA63r{6u^uS}7@mf3<&y2+0UxE?6-5aO4{&~~S5eRZ1 z>C0f2LP7TI2b2Q`HskWPUyu^whxCjLMfMB+q6df#KrjE($^Ts+J^a0&C;mmk`(a@b z*t2>S7PV>ulV^J2z!b{*Pd|d|XVc+M^5nS(Wq|EV17Om+ZuvefS=*C+I_kLphdLj5 zU*>xLB+>On<_qr8#Qd=EJaJF%tU>x?M#z1t0ZvXFfQyU2!Zq9NxZ!S#n_dS{N)kTR zdLM+=hvaLI5^o1w_i)5{7iXNXcSVk^JJR-gAbGbJviEtQ$iW?_T-> z2qA^)Da-{B3Kwz(B1mEUESR#u%@o(n7b4Z)6`5IC${3)I1N*sdM&6e`P{=vJbB`MS z_V)IVQUA+O@jqZ{ibd^OaJ|2~g1_7Bneh1HV|bFhXU~A^)VE;Sw;Q%_&M$UeS>IE2 zep%bA%=@a`7hPX)7kMvwp6GXi_fg?<;+@ikn3J*|(;$yj*uxm7`!~bI4@cnIx}R{v z(F!F#_9!KvI;KrWCNMrxY%)Eua%mLYc3jXW^=SgoqYWQ;}rbEBjB)m4;FT9 zOCOLfiq7vbXBND^`V>AS!QYIW_vnKxgsP`#ze3{>ql=+>0Ua#`H z=yoFC1^Xlw`>w>EluPUjx@mBtXEmH1+6I?qkH_`x%TVI652XRlC<}CjHi$R|6Gx## zLc}SA6so5%;utPO93zChh_3-fc@txme1I5ItdOs+jAJPj%m0bu^8@yxWZ!aRI_^Ri z@lQ)jQ%Gb0=g=zu7Zd+49yR=#!?OwXf0y9kP|jx};C$d9e(u#xSp(Sr&IEYQCHCLU zhVM6@!)w-uu%^A=q(v=-_eJij`kpOuSNyc8=Lznj-&dI1>2-VIdqua?^L-L|K8?6% zl5&WBKCwSeI{idVoPW71uFU&@ytfG@zU2F056W%g8A2>WNnt7xr*PsIL5kE<6w4@L z7_FxmmO=`~e#BSEA2_V1_y9mC!GPlVSq$HCXg|vA*CJ=%W@MzLDmtL_0nr7ymqx|E zjAOvhj~e~~0Rh$N1F}9i_z>}rga_Aw=MQ*Bu>srB-s4T&{l1$6|NqQ}`}-4N*|QzY zniwl<`XcYuv0ik1)wUx#Ub$U|vffa?tBUtCRNg1I<%0QDCzU>B&hP12PrtGpGx){Z#ocmpQ)5`?8*+&h5pnBXfHh?`2+J znfH_L#QTpM;cUN#xb)8RDCXE-!g04O%m>;iVi`poqYWsQ_^A{}ybkLro;V66=;;W{ zBO%0DPl+srjtPb8D2ZiKn2wUefn=UbUx?vY;9qH;lK$Lwoagy}`vrpk`ycpx_96Xm zdt*nl>N?(+@t)YLwp|(XWqvO#P5injuJbeL<2fTOq2Aa;42tM04YL|Kx&kZ z(xL&ORFZstnDWJc56;=FL{d~Jva+)k{G}hn#l@*MVB!A|t^>Au*!cX_&vSBe8%w@F zC-_H1Mq&LA-{bd=&9IN_ybAvFzk%C3<6zmn6?QaX3?5=H_T9>|U*`9!o-e!~K>S7a zi#=a#da?TXo#^|@xKIASZQSpn!PzIO;o|TPxc2pAl-Qb}ER^GWoZw6>g%b31g!l;^ zB_#?GE1_e0N@AHrT$A;bLVSf3ob~t$&gn6vSRfV|t?a*I6ia*$b`6 z`y<5iC~*`@B!)uA^pwOhNqALHDa1^rRGtflX~b7BR!PNLaL$a^Qv#4h%06<7e;d;xDp4+d$_(MZNDV@ju_U zF0M{~4ma1#)6MmT=M#zTG2$qcL>!a#l)_RdmAtD`8Zi}0*HZ>dp~^UyV|^6J5lRGd zk5!~>-WM4W>xr8#TaXjzg1o#u6jCaAGF3`a8qd>JBJXDCDU+p2 zSqA(pcnZ!cDR?IVd8GVgJ*BV|;e*#*@1_V(E=^MAqL-_IYvz0BAteY(K$%~xT=SgdAT>k)rW!?C}z-Y>o! zify-&-Y>GhvaL_$ebM`hNW%Lf`_FUizdW=xZp@v8GLHR-;n*vTn3in$EV7E!!{WFNAN|`**B$iov%4Vrjj$llDRZ_6l<1JVh2J)#c&-rf6`of4TESc8ZNXZP_i=*o1n@?4GzdGkv zWIy@;d`}H7_iu#a_lKfv$8zf2{yLt|CayUmhe^3Y#3N6L=Ss=*d_4(I7l_;@iToB) z@h(#N+5l_8S4hE}c%RBOpgi5V$bf8)KQZn&N&K^E13q=?ltO3DoKgG%%*`eCy_xg_ zZ%a$dzkNT~gZ7cVd-wM9_4UgW{*Mv-mo8zPpStD#J$D-W#pWwEKNmuh{xk+5dzwt_*33o3qD3Yqy;`7w3F}eJ(K+$|L0qiA*-20-hJDM2rPzl~n#d zuE$xynmC^{#9DABomMHI=PL1@$Oh3P4*TGYmle_z6L6Zi3-;&Eol|T9#9Y+@j&M&1 z{k>mE*o@^HJ9M495P8y{qHe%big&e;Tx0?^E=W0h3C zHpE*nKdJJ!9&^Fn5PS7nE#*5hP6+?UdE1HeahA9X_7^T(Q09T+2gW@h!v9$n z_kuhc{b1`>tCrjg5EM!KpWts}VS!(}w!v2J<=syCZ>al~+kDCUhPt1j&DU`3mw8_z zZGM%<{_?dR^8Y!?{!35Q!u4@|P`dmZXt~~l4C-?E#JrHWs#L`D%2bXyu{xnA1#7|E zkchp4zrnroej@#c?-CMuuj>AyKMMA;77*@$D^8nm?2r%6p4DN0>Cz=d52XB5@aOn{ zg7`nQcP#nXU?95 zV1MPx750U*%3dJqePRQ;NEtBc@51e2y=TFKfa>=4&Z{~1)5`eo!1xma@}7)?-#pIxPk6xh`-^yU&j7Z>e%1Q2v-I)!HrK|g?7(IoxNA&z9II? zxdHzdifj<#|B2qG==?GVAkWHpEw&!9`H8Jp#a7n$1Y23xr94Np8`pQ~PZYv6eqvnW zYlRzJ>$~o@4Og8vr}s{}zpVHEncb(N z?pF<0Y4<7ldJ?n;chcTMo1dcZ5nt&CaxS`l4)M(MWyq7Pai z+Qk;}zOGyj4xo8Cl0(rE5DozkVG;vKK`7pW{F(_XR%vu=w)te9oRd zHdFll122gVa3~}c%RZllwcOWTdG05=pP}9NHoG5rU-9V_yN|(ouh{%m-B0{{4DCJ_ z`%w3LsXa=*pQ6M6FtJP_?+S^%Kap}-)^_8#-Y-5q;@@@1k-k}W^v~N(A5Al8owlI# zz*^j}S&pl_7vrMEZ#cd4R}`83f_&3ok+X9#(k)lw=$;LTwlzhRqcx)F4;mHZhq$N+ zB+;KclNgI_zmWEwlP6C>=Jz7s&!0b!ix)4J%Y5N`!M(V+m^nvpFehXb^B`H?q(7BO zNJz;4WKaKt_7w|@Jui8C`<@I94Oj4A$GGsz8P}mI{44u=sB=F<-Cwc$5&z0|Kk@TY zbbqn=itZ?`8!!5Z`^9P_}y&N_H;7jcq^S>ZW-( zx9&eETJsGu*L;Vh_5VfOmc?rw>Z0o@mp5^h^$pVAa&J`NL&9ak~b~JvF)o6Z@vjJw&sX* zv_qJ?3&I2a$-|LIJaPm{^vl)x=Vg@p>BxG$`0S{DJL>wqtltU03;y~(pk*H@rCtAe zVPVmEp68JgY3~gqdGfvm%k{jsh%}e>--(nDgSigejlN*q>;32+9KYH)Ik`m0KCobp z|9ffESoC;D?Bw`=U-(o0Cy@V-QU4d)kI4V@E=I_B%ov&7t0SXlEu{3RkN9VrA#89b z1dksGzgcg?cfoh?-@F<@))okMvPYfr`0ZaAKZ^% zKVL+0PvzmmhjD~saUy+d#J@%*iMgPXdQbLZ8jzOfrAbN2#fgc>E*w3Yn9u*`u$~ys zy;`pE@$u{V?4L+qlV_}e3z6@X zeRe$8^1Os}jpvv7zb6hKj?X7$@ELs6VR!oCZ6l8^h>ni_GAb%|BLBBvL_|cFfPl!> zK0ZFph->x#tJvO6XO?x#J$tO@(-+{T;7?r;i{G7upSrbEY(WcN8iL>69E;^MKERgm zzQOM0OL1`9Rygjqg3Eye@MM4S@$p4qP>`ZOiZ7`U*Oe7N*$~bt#9x+}P+yK#d<|p| zt@u!~)Uqri6_YM-4q8YoQ+Pjuc)C-+-WVAf`9o-E#4PT+ewX)#^YdqUuLqymj?|R0 zy7s^L-VM@s{-2#YEv9on$Q6J80LFyygT*d$?AW%QK5n*fVvIm9ZyyARen9M7vyj!nG(ZAq&cCXp_7Pre^OWK zR0{7BYso|Z@9`J60Q13(b8~Y)C-{qB3uS?xeBtFKae{o6ej%SThA1gmNK1^%*cWc_ z{37Q-MbsZsc^(xI5a>w^xA^%5%x8>&PXhviC(%~&4DWSj{Hb<=ukbFZ&ZFoz@fXAK zw?CeFy$3QkKp}C15b@V?e_$Ec28(%qnX!WNNyj)ggb_a<-m~#!97*a7zwzGJj4S;% zF@2t~k-9U!P#b4w=jPO_WKYchNuBC%2k-%3Xkud0nYlq+sV^NSuD5qY z-m|veKhVz3sf)x8qOG&}jvbB-$hS5B<=qEt_b!3 zI#s%s^^jY~1x>{VT+nES-TIXNIT}r)O4rp4uLId)m9K{x+*ruZ4Id!ah7aIng$F3t zw;rHXu5Ud+cYW&tOv)ff`3v>eiz~EZ>1?tb0FUSK7 zujK)T*U}FRujPUFaxMMl&;H-=_sR1OujTy)_0uT*QhvDpP%0d#Ug;aa;DyTP1`p`O z=NUe*^7XJvpDWh}&s)IH4ccGfBZJpV`x?AW0c_!|Ungv2@GzRk=woW|vEcQG*Q|bp z&nsWEx;ci=t9;$5(&v@0hgJH#^7VpBpI5#{rTSI6uG||cU;kO}67+AipV2}=_f~H) z%IQ?`x_DT{YhG3O|3A6bvFokpSAA^&xAMHd@Opu~z@Yd2-Pgn9{fx4z9)HjELiKfe zae3$K1@iMy{<*^Yx2}gNpO#-Q&|m8Rzx-0iVCsh~1Nr`2pUSm#+gnGVu3wbj2r57O zJ5GA?*9|8vBpGQs^Y8!SNNKLoWHX0#-VDaz9jnWG@xZ<^vUX6NB=NOt>q*uF|6x8j zlINpfE$f`e@-pcJ+rgdrfIeaFkIozd?)Udf{lx|=Z6GA)_xmh<^{+T&eK!AV*7+Rk zPsyN?lJki7@;ynPYBafB>1qD|p*^{f>{k#(qEuGvZdfYqaGq`8%|0<(qe<_^{_y`v zJAi$%P_VyLb=_}k2aeqNzHEmtS$5au&H5|)u0w_jlVC z^8I{{8TrBFi|^PcdjIp=LF88fW8M~!pYOJwfA)V$e~@+vVLQyzXfmH<4y}J^Oie~B z*5vyN*aqQz$9&2M?kP&E_0M4n1^ds5JIA!De*gX5t5Ks6wQC!GS80c< zY~x6_#m_AJ{xjM^^q2y#hl#zhaRJ7UKaHP$x`080PN7~s!*-DKf@`EG(ywguXDKU1 z7rvK6^hluxJVcKzn#JGo5V0>n`}ReQr6&8T%INcZlle6-Vd&6Ps9(RxK%Z3FMA{*S zeDNFQ@t%=dec?os9!plQ=0v}{=fBcqDg3ieZ{o?%Rx zlJcqIjT>6}yWhmBRhQ7S=ZVT~ApPMw`#~J*zl1d4F4{r#%?FYp{rYXMVQifH8Q)z= z&#zdYs$@c)I)(V}e=jg+$`wqRau)5{9fz^8?t5+99>@OuS5a1`Ew8_vXnC2PU4mC% zJ$+l78N7q-P!P}h|IR+~Jn!Er{*KiDZu`n@;ESKrM<2OPZrCs__I|MM-~S~2-ESy$ zJaM9wd&aLZm*`pMl{~Jr$MNI0uvZ(Qv{Xyq+bd|@T6o~kavc@WLRD~tZLmV4$r+-{ zJz1d|(*N&OW~dJ^vb3}vGj(dz;d=FQ@3G(OWcs2-7Zu)C>n2#AI#tR%de^uop!hcI z<^PI`O7PA*XNdiu)xARhV>{$0l2%bZFc!l}bzhdqzWdTGxi_l$h7H~}{rjhs{W%U5 zev5+JbI+ZmkNXYw=ZgJX>L~Xr_j|c7_xA0(iZ*TT2K&nIl>NTB}we7A&}cYuC!8T6cY%JXwnO-#>e=*t6cZwFTQDpK>zy zL)sqhOP8EJJ>uyeJyO!|9s5E>=C4?Bkud{GtHimg29a(e|37cu1w8iH2~@9sTb-(^ z=O5gYu_`~5ZNPcOy&v`Kr#(@h!WZYxmC^6~ zIzIpWJi2vz(00f_O}R*$7HeuuFZ7$1x1d({q`A-fmgY&yi^(As>0v! zp0vaH^JVnCzmD0n&!Jhf+w`G7z}*n9fVsDiB`h6ej+(Gmww!ypX3x}q0Y|UpI z+;u+??8l8ejhvj@v6u1Q-TfM7&OFOFLYEm|zC>vwX$Qf6_3De93*8CdKe{irIkD5+ zm%UkZCffKEy^;0SG-}(nZLG6vAt9ciz{yieQcJ8bi`_rdOF=NJA zj&(9mD#VyErx{b_GWYD4a6WhgFT8NS*ys6cG#TCb+wb)-?$)hat)W9-Z!&G#w9fP9 z%^R>_!JU++I3jJ zelz1*?t+!YZdhCGf%T3Zuw1bm=G_1L?dYXwP%F6t{!NX-@t?ZSU=!m8ZYFJNPy>q^ z_rjDWbJ44=GwK-M-VS~Ho)Za*~9gjT43UCmKU zuRTVoyTnbD*a^Ga)P`-(4$P@H3?H}u0Z%n>LETF2aJ#H{(6*5E=e%$4W(`5|7Mqxu zI+$+Xq1`ZV9#&3z6Kh5e$BJirV`-;WSkkl(me#L^C3Q4dTw9|ndH!v!_ULHjV9>7% zIlyFNbj|M>H?XEIUbN%{>{uTz&vt>w;9hVa{1nWe8;v>Le#Wy++)%H&VSjkgI;-DT zbiG5Adr$ls_VPLRDApxkZ?iPrS+n{S z9-gbVlEEVK4EjI;dQ`K+@&=u;oADBDnj68PdsBG5&+dq%=H)WYjEzeWvBh5-*0Dm>A*#%{(B8;;BqV)087ZH?jkMYCAmfX7k@e+!$eHsVa=)5_{JB$+GxtM;%=j9!`q`jC&Gbs` zs`B@pO2Ixag7tsuZg4mJA15dG=NbDb$9nZ@tmx7fn|gL(4%{Bt+`F4{zOhF~wnaN^ z=+X-7TGYWhWo*+ZvC$XQ?}^9B^Oa?|u_hON>bhWY|NkQVyy*U2m^K)ZBT<{O?!D|8)+E7LXRsMd8A4kTU;AIL=sw zPX{@mQ{%)cp2M-FTAr3RD6#d^25VSvIakK}NRIbhAH4U2ar;`kx_bCJ?%u0i+wUoC zeX0j`zR({#hCTukCYV}xE}9v~REeLiU8u{m zj&*Bhqhak#)UTC=n$>bCFDmQ(Y8w`yNt1l8j~v5>4F_&AKEcAqjTuo)llLy`Y{_Sa zv2^EHKZj+rdq-aP4c5OF^PsMAc5o_LKYk3hGWPMF*GKAT%m`SI9tKP1L)y$dI1&?C z$$iV1$V$#*)?M-+x-cHr{uYh!b;GH6yt*rOp^9^Zs`|wr-IG4ky?qMieV+zDzj&^X z?Js3);f?0z=Cna9pgkhD3G3a3)P}g%xZk?V_qf-)8tea^hnr`y$;@fk+_x8OCX9jY zTVrAO))?$(-sfFUbX4*|h+Zr4prqfcd4DAqm^)*E`ARIXHZ`!dd4G(rzZxxT9nstG z?}V?4vs%(V$iC2`VHVyU7z(>@teNgFT8RV2J?WBPV;|RI8a+r|@AO^9KcC{`<#%Bh zb6;$H<_YYZ{04KNzXgXWZ({#z!?C@6UQ$bak#(BM%*0W?<6Lcvybxivm+CT-vpUp^GDw z7-;OHTH^1&dGqGhcdEmK+^75->E{=4!glp4Y~(y=|9cbRG-C=}ro97e=7KY6R-;_z zNge<-*SGY0FXjO7XMT5y{T#vguW^j|m-2jj9AEeqaxL~CXpIXt%nrhgS7Y(=Gl}Te zBL#iBq~V$FsTkHb2~$TUVA-s2_^k28@q^AN^*zWKpnGw}dIK_|LX;dEj5i|j^%EGQ z;(ly7f7&!`-=`S&D%Ej^88$utEDlbc1ozLT!{viXFlXPFJSZabM6Xx-z2rQV_;2y{SW`(7}$yUN4oB{#)hE- zVE_JPcrpLG!-Q90%DlhIT$XjWqr4Y>_ax>4#5|0c$FjdmoL7nQnBA4J-Fwx*g()wf z*m^5U1DLa2;`tw9%-#@Em?!HAUDzkh&}hl8Vb{itEA|69y^KMVVY^u^Am)fC*N&kMgx-KD=v zZexjaFL5rDJL}>b7cjo54pqpl&&cFfYzjhou0=rt(R`eXZ)=FMd#xR!{^^$`ii}9|Ne1(i% z&-|3yI3Ju2Jc#U!G(`sN+qbWT{eLCL>-*C4{;0#qJecvDK4YA=t5);pVK?)??(O>+ zb~5L$|mE4VL&PF9yBV)Ep z-1bc7?^E+K8s^@V*!_~5L2@)OKcAMlxi1`YKz>%bl5dwfKpE?A$uUs%>G-26-ScOR zS@k;OU!U5)Vi~se>Ikz|brfAk#yg35E`48eT&jIPPA~VQ?{jrYiD`cRN#-$`JsxF2 zl;x7UPIA?$`RXKgeGW+-jp%+cj(k&<~FE=9OA#X~CN zv7c0PEk-lP3iaNHe=wKpV~krD=fZqG>$w_bm3)EcMot+?O_y{4>G_X;HWmv>%1Z2}-^p#+H{n zQ)$$Jo__eX*J!M)4z^_6H!n}>+UuX~rNn+0eMfj-a(zjDZ$sXf+#V_VF<FCw-drlDaFon^-T&(0efve#z zxI+EsqMtR2oJ^6E5T(T5mw2Jn0rNNy;2QM9Klt1RjALi%>)~0p@ny!o)$4neWuNHy zlG9jZpXfXi)Bc2vdrwry^{LEX$8lfDU&TDdTIMI$a;z_l@I(o778LvM!xiQ%xaeVl zb8fqE#&s8pTrH48eK*sGV;%LK%&0@iJrYBaaEvLfGH~YfDJ^pjlu-}7$$Zm3qz75c zzGK75xWakBa&Is1k}YpfV9sZq>{oR@(RC%qSLJbEWZ&`bMmXK47S2=lU)=l~&h0bB z>3!RAig{d*lX7^TcF-KjuKSSa>p~UBpDDY;n9es=o0^!QWo-V^tjx?Cxw$!)DeF!# z&UzMO@E>Lj{vgI!cV?XZUD?^$3n>GK%Y5~Ym3V*;WDIn0aGm4r<#TPvXCK3ixi8Dd zzLrLCZ(9xCood3jdwm2v*#be&cR|Q2eGxTzIAUi`K-9N05ViU@#M3hsPE6* z1l<^)zAek9jH6f|c(8f?-87Az-N8wW@p#U1!OsvGU^2Kb%*PCe-PAW>KYKdt=YIpo z6^r4veG5FT_h|iHoXSG|d~QaD94d~EjJO;d6LXq;n$4KZ@g!f8b!_b6EsX2Cm^7Ey zZ!@0jOHonreHiPtlf?g&oEgNnw&-B2<3rbN@21}B|1hrMFi%gf0%yuV+nu|#j<$BC zo-QuM)Qhh&H}ZMLHa*VRrzwGf!I1$0LC!39@b@ofUA|*oW>QZd%hugh56&@qaW3rW<>eK~d=Pe|jqdKAKQa#Jr_2*Si8}HKnJbeInKRI{ zDgUn?^^qFFlmBb%9!A4TJ*a1P=9)-bo;NZ#52!8oL^eE(=l}bRe_P;x*#hKI{h`&z zMbHZ0@+j4)SRaa~SQkA;0&XbxSt|dKqmQz}Qh7okt0n&+Wha&kS=Q2*Ml5+L z0Tj4e!K0HtJW4HnSxsLW-B#-UpAS&J$2TpM6P7tr@&#(SP_7&4ovFi4Bh{!KQmnaIsNyQuitOEpuAbs=DE94*R0a2Y!0QsLOqPj z+Bky2w9sYb{4vlVdki_TsGM9@e2%?8SLVze)Vk z^PTywJFJN+dq5KP*u1FGBsX|SFXm&U?gi8M?9;dEuCC)4mP&iv;QuADt=6#|PXFPC z5B@vy+w)nDRoA`3`_ZY>aqg)+scq7vNPb5OX(MR_vANH+B+&)(>HnI4>h`)9D88EF z>ni*F#Mf`(!V6r(xvBWG4jFQa``!w~Z#0$P-^|}IiagV}QhV_EcRq#<3+Y?EdJfk; zZ^vEyXT^tj*RIQW@4d5l?X}a2uci2#Ub<9@FTXrT|J3sK;qNF&CoU$WS9NQO<@{OY z4_Li=Z}U;3V$HZF%|2fK9EvSDFW^3nqWYKb|M8;KU?uBcW}6h?%i+g zJFMdO%kN-6&7M+a<$1Ga&5Z8G#`*L$kbZr8{l#}#_ITLZUSWGny>+r!euwP&aCE$; z>}$Gxf3Ny1X^XsNcY41@6Hl2Yd*h`aEB#2{_T}GK))`-Z`4nx&x;A0V=vd9!^gAl`t$!eG^%Tvy5AsszUI$A&-}PL+_SQ7!p-ff zvghI4xl+uXdrtB5uA==Y$MT){ybhJ$FE;=0zyH3$+_`f*&!0bk$hY6Fn%<#9Y=FF< zz9DGXAdNmVvOi7s5+CQ@xhqP)ll{a?mtLd{DB`}0)A->B*-LaMUt5u7+0%8hP4^3y zELqd;_up5HUAk)3H!D}J*-k%bzinGh(>AQ$es;+7hi=N6Zp%gqnA&SGUT(Mot&Iaw zr&bO|j5vi&n=Zl0=_&>e)cLN<|JJRm;#9d5Ue0&XXvDukcW};8ef8=MvsSNKo4@?` zCD+z2_@#8q_upx^&6T1C6Y@f>SRj*|X%bRJqM}$4s$ZVV0^iAJ=cWL?a{jj`eXZ+r#36?glg++C%V_fz3 zX^=>x4`2$W)P5fpO{>GPcUw3Q9f(c+Kfu(kTku%JaMUoa${${Ruax=Zr2;p$eP^}q zYRUQd7}Kxko?PCpIaaoAjOFyh`A^sFKs^^gx zbNSv(`c=fi>N{6N_=IRVzYkfzetkzB-lD(W`Jk<%mWQ+R^4(v4R&szo5w(+-{gWIbG7{1r+A zT~QY5g_1BI+zj_aX|x~h&;DF%_Q#D-M`T3>%Q{m2z2vEF=gJxfN!B`;ms~5v+~j3k_b5q?#u>Iv{NcD8TyOt*)~s1~<+pY4 zpnH2~bMqjxe!aA^7AfnHvIZ&ZkLhgtlfAj-`0FgTZx~9BMd3z52(EF>;c|>0E=2ok z&qVoZPsat9o<4l&#>u3(YiX$|Cl4Gr@U7VG{{K($g)VE(O%UbhuNsgz(^&CH!iy8jzr&A93}jY<_xT7V1xZbp0E6?q@QqY zaG0aL<7dte&To0TdcNf470{QqPv#d4XfF0^mWrK_a`c{_UHM&ix|ZK?xBc}_&$yTS zxX#f(M`##LIy4mpDyA2)Hw@!IBKDPPBqNfB*G9ZARE?8@YB{va=&2D)p-v>IL<^E) zO{!Q{!v$J%)T5_HqmfBbXVSgdDP(SzOWibg7snU+g-UF-dxI6RJ(S;fB2i8xRZ}|$Bsw38X4u< z^S#ssxtFBJalHQeX?*wHdHR1|(Q@u|iT8u~4({)eJr1{GV@;lHSFK&UI9*JS;xG7=s5ZdMF`N#{CeEyVKdc`opeTjT)I#`P(!3xmI-5C!ahH zXXmTTb1wUGOSnJk5?ZuS=MB<6dE4a6?3a=Qs`*DBZ6DmZQ`DYn)v~YEtC57(t@2@I zb(#4AuPggk=gc{0u#ZvND0>ROS9|&5->0wm_CNOPzxd+t)WK^`x2=0fJE76{c(wT^ zOnv>Kz3 zHof=_-sxqFrnMFQN9s<>KS_FD{Afi6TFjfbVDq4UH#R=j2Fn{Y!>F1I(6f#kzVE*l z){}n4;t^Z%c=H%-lg62sjg9lN_}#sv_WHUT+bml)%VOfV%e$WL2J@!IFlo{W?>AqJ zew||RREGrg?Q#^8N5p9t{1_ZRXiy~e9qE(GJX;>2*}r-78@4mvKfR|{dqt-R=eU+M zVI;!WJHvHtD1uBwkmKToI6tpsjvG%aUo!aPY`J5Q?bJ!xw(aV{pW|Z6W7TnS{tT2I z4uO{bM%wf^+)R$5i&by|W%+P}uPUc*mXzSt7OIsFcixZ z_x8+)z(tv{VPEDRjejRQJ$*Rkq_A~`gMFa7?e^`@+O1nT$koiOm;3JB?PYC=^13c% te@)7SJK96aD13?+kUD8J7iy8nfn-{x4CMJjYPEqvwDeRUen*V2{|~hl@#_Ep literal 0 HcmV?d00001 diff --git a/support-client.py b/support-client.py index 7176990..9f1922b 100644 --- a/support-client.py +++ b/support-client.py @@ -1,213 +1,319 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- -####################################################################################################################### -# Support-Client . # -# Copyright (C) [2015] [Guenter Bailey] # -# # -# 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 os -import Tkinter as tk -from os import curdir, sep +############################################ +# MIT License Copyright 2020 Günter Bailey # +############################################ +import tkinter as tk +from tkinter import Menu +from tkinter.ttk import Progressbar +from tkinter import messagebox as mbox +from gettext import gettext as _ +from bin import __version__, ABOUTPROGRAM, ABOUTTXT, PROGRAM_NAME +from bin.findenv import get_osname as _osenv +from bin.license import information +from os import curdir, sep, path, mkdir +import threading from subprocess import Popen, PIPE -from tkMessageBox import showinfo -from lang import de_DE, en_EN -from conf import setlang, dlsource -from conf import check as _check -from bin import osenv as _osenv - -# set language -ltrans = () -if setlang.langn == "de_DE": - ltrans = de_DE() -elif setlang.langn == "en_EN": - ltrans = en_EN() -else: - ltrans = de_DE() - -programmtxt = ltrans.programm_name -savfilent = (curdir + sep + "temp" + sep + dlsource.twsafe_nt) -savfilelinux = (curdir + sep + "temp" + sep + dlsource.twsafe_linux) -savfilemacos = (curdir + sep + "temp" + sep + dlsource.twsafe_macos) -twstart_linux = (curdir + sep + "temp" + sep + "teamviewerqs" + sep + "teamviewer") - -def update_program(): - from bin import update - update.start_updater() - ende() - -def editconfiguration(): - editor = '' - if _osenv() == "nt": - editor = 'notepad' - elif _osenv() == "linux": - editor = 'notepad' - elif _osenv == "macos": - editor = 'notepad' - else: - editor = 'notepad' - - confopen = [editor, 'conf/config.py'] - p7 = Popen(confopen, stdout=PIPE) - cmdt = p7.communicate()[0] - -def aboutprogram(): - uebertxt = ltrans.aboutprogram - showinfo(programmtxt, uebertxt) - -def onlinehelp(): - import webbrowser - - webbrowser.open("http://wiki.pratznschutz.com/index.php/Support-Client") - -def updwebsite(): - import webbrowser - webbrowser.open("http://download.bailey-solution.com/Support-Client") - -def dlfernwartung(): - import urllib - - tempdir = (curdir + sep + "temp") - if not os.path.exists(tempdir): - os.makedirs(tempdir) - - if _osenv() == "nt": - showinfo(ltrans.button_support_teamviewer_download, ltrans.label_shortdesc_teamviewer_download) - urllib.urlretrieve(dlsource.twclient_nt, savfilent) - showinfo(ltrans.button_support_teamviewer_download, ltrans.label_shortdesc_teamviewer_download_fertig) - elif _osenv() == "linux": - showinfo(ltrans.button_support_teamviewer_download, ltrans.label_shortdesc_teamviewer_download) - urllib.urlretrieve(dlsource.twclient_linux, savfilelinux) - os.system("tar xfz " + savfilelinux + " -C " + curdir + sep + "temp" + sep) - showinfo(ltrans.button_support_teamviewer_download, ltrans.label_shortdesc_teamviewer_download_fertig) - elif _osenv() == "macos": - showinfo(ltrans.button_support_teamviewer_download, ltrans.label_shortdesc_teamviewer_download) - urllib.urlretrieve(dlsource.twclient_macos, savfilemacos) - showinfo(ltrans.button_support_teamviewer_download, ltrans.label_shortdesc_teamviewer_download_fertig) - return 0 - -def twstart(): - if _osenv() == "nt": - # appstart = [savfilent] - p1 = Popen(savfilent) - - elif _osenv() == "linux": - # appstart = twstart_linux - p1 = Popen(twstart_linux) - - elif _osenv() == "macos": - appstart = ['open', savfilemacos] - p1 = Popen(appstart) - return 0 - -def ende(): - main.destroy() - -def inetcon(): - pingopt = '' - - if _osenv() == "nt": - pingopt = '-n' - elif _osenv() == "linux": - pingopt = '-c' - elif _osenv() == "macos": - pingopt = '-c' - else: - pingopt = '-c' - - if os.system("ping " + pingopt + " " + _check.rate + " " + _check.pingurl) == 0: - lb2["text"] = ltrans.display_connection_true - lb2["bg"] = "#00FF00" - else: - lb2["text"] = ltrans.display_connection_false - lb2["bg"] = "#FF0000" - return 0 - -def helpsteps(): - showinfo(ltrans.button_help_steps, ltrans.programm_description) - - -# Main Window -main = tk.Tk() -# window Title -main.wm_title(ltrans.programm_name) - -main.grid_columnconfigure(0, weight=1) -main.resizable(True, True) - -# dropdown Menu -menu = tk.Menu(main) -main.config(menu=menu) -dateimenu = tk.Menu(menu) -menu.add_cascade(label=ltrans.button_filemenu_label, menu=dateimenu) - -if _osenv() != 'nt': - dateimenu.add_command(label=ltrans.button_config_editconf, command=editconfiguration) - -dateimenu.add_separator() -dateimenu.add_command(label=ltrans.button_filemenu_end, command=ende) - -toolmenu = tk.Menu(menu) -menu.add_cascade(label=ltrans.button_support_label, menu=toolmenu) -toolmenu.add_command(label=ltrans.button_connection, command=inetcon) -toolmenu.add_separator() -toolmenu.add_command(label=ltrans.button_support_teamviewer_download, command=dlfernwartung) -toolmenu.add_command(label=ltrans.button_support_teamviewer_start, command=twstart) - -hilfemenu = tk.Menu(menu) -menu.add_cascade(label=ltrans.button_help_label, menu=hilfemenu) -hilfemenu.add_command(label=ltrans.button_help_steps, command=helpsteps) -hilfemenu.add_command(label=ltrans.button_help_online, command=onlinehelp) -hilfemenu.add_command(label=ltrans.button_update, command=update_program) -hilfemenu.add_separator() -hilfemenu.add_command(label=ltrans.button_help_aboutus, command=aboutprogram) -hilfemenu.add_command(label=ltrans.button_to_update_url, command=updwebsite) - -#Image -imglogo = tk.PhotoImage(file=curdir + sep + "bin" + sep + "image" + sep + "support-client.gif") - -# Label -lbapp = tk.Label(main, text=programmtxt) -lbapp["font"] = "Courier 14 italic" -lbapp["height"] = 1 -lbapp["width"] = 25 -lbapp["borderwidth"] = 2 -lbapp["relief"] = "ridge" -lbapp["fg"] = "#000000" -lbapp["anchor"] = "center" -lbapp.grid(column=0, row=0, columnspan=6) - -lbspace = tk.Label(main, compound=tk.TOP, text=ltrans.programm_shortdesc, font="Courier 12", anchor="center", - fg="#000000", image=imglogo).grid(column=0, row=3, columnspan=6) - -lb2 = tk.Label(main) -lb2["text"] = ltrans.display_connection -lb2["bg"] = "#ffa500" -lb2["font"] = "Courier 12" -lb2["height"] = 2 -lb2["width"] = 22 -lb2["relief"] = "ridge" -lb2["fg"] = "#000000" -lb2["anchor"] = "center" -lb2.grid(column=0, row=6, columnspan=6) - -b_ende = tk.Button(main, text=ltrans.button_filemenu_end, command=ende, height=3, width=12).grid(column=0, row=12, - columnspan=6) -b_chkdb = tk.Button(main, text=ltrans.button_connection, command=inetcon, height=3, width=25).grid(column=0, row=7, - columnspan=6) -b_dlremotecontrol = tk.Button(main, text=ltrans.button_support_teamviewer_download, command=dlfernwartung, height=3, - width=25).grid(column=0, row=9, columnspan=6) -b_startremotecontrol = tk.Button(main, text=ltrans.button_support_teamviewer_start, command=twstart, height=3, - width=25).grid(column=0, row=11, columnspan=6) - -main.mainloop() +import json +from datetime import datetime + +try: + from urllib import urlretrieve +except ImportError: + from urllib.request import urlretrieve + +# +# def onlinehelp(): +# import webbrowser +# webbrowser.open("http://wiki.pratznschutz.com/index.php/Support-Client") +# +# +# def updwebsite(): +# import webbrowser +# webbrowser.open("http://download.bailey-solution.com/Support-Client") +# + +class App(tk.Tk): + def __init__(self, *args, **kwargs): + tk.Tk.__init__(self, *args, **kwargs) + self.wm_title(f"{PROGRAM_NAME} {__version__}") + self.grid_columnconfigure(0, weight=1) + self.resizable(True, True) + self.config = dict({'version': __version__, 'tmpdir': curdir + sep + 'tmp', + 'email': 'office@bailey-solution.com', 'phone': '+43(0)720/517219', + 'webpage': 'https://www.bailey-solution.com', + 'remote_app': dict({'server': 'https://download.b2go.cloud/Support-Client/bin/', + 'nt': 'TVQS.exe', 'macos': 'TVQS.dmg', 'linux': 'TVQS.exe'}), + 'test': dict({'ping': dict({'server': 'google.com', 'repeat': 4, 'result': 'no result', + 'ip': '8.8.8.8'}) + }) + }) + + self.setup(load=True) + self.check_folder() + self.child = None + # configuration + self.tmpdir = None + self.test_ping_server = None + self.test_ping_ip = None + self.test_ping_repeat = None + # start UI + self.initUI() + + def save_edit_configuration(self): + self.config.update({'tmpdir': self.tmpdir.get()}) + self.config['test']['ping'].update({'server': self.test_ping_server.get(), + 'repeat': int(self.test_ping_repeat.get()), + 'ip': self.test_ping_ip.get()}) + + if self.setup(write=True): + mbox.showinfo(title=f"{PROGRAM_NAME} {__version__}", message=_("Configuration saved")) + self.child.destroy() + + def edit_configuration(self): + win = tk.Toplevel() + win.wm_title(_(f"{PROGRAM_NAME} {__version__} Edit Configuration")) + win.grid_columnconfigure(0, weight=1) + win.resizable(True, True) + tk.Label(win, text=f"Version {self.config['version']}").grid(row=0, column=0, columnspan=6) + + self.child = win + self.tmpdir = tk.StringVar(value=self.config['tmpdir']) + tk.Label(win, text=_("Download Directory")).grid(row=1, column=0) + tk.Entry(win, bd=2, textvariable=self.tmpdir).grid(row=1, column=1) + + tk.Label(win, text=_("Connection Check Settings")).grid(row=2, column=1, columnspan=6) + + self.test_ping_server = tk.StringVar(value=self.config['test']['ping']['server']) + tk.Label(win, text=_("Server")).grid(row=5, column=0) + tk.Entry(win, bd=2, textvariable=self.test_ping_server).grid(row=5, column=1) + + self.test_ping_ip = tk.StringVar(value=self.config['test']['ping']['ip']) + tk.Label(win, text=_("IP")).grid(row=10, column=0) + tk.Entry(win, bd=2, textvariable=self.test_ping_ip).grid(row=10, column=1) + + self.test_ping_repeat = tk.IntVar(value=self.config['test']['ping']['repeat']) + tk.Label(win, text=_("Ping Repeat min. 2")).grid(row=20, column=0) + tk.Entry(win, bd=2, textvariable=self.test_ping_repeat).grid(row=20, column=1) + + remote_app_server_url = tk.StringVar(value=self.config['remote_app']['server']) + remote_app_tv = tk.StringVar(value=self.config['remote_app'][_osenv()]) + tk.Label(win, text=_("Remote Server")).grid(row=30, column=0) + tk.Entry(win, bd=2, state="readonly", textvariable=remote_app_server_url).grid(row=30, column=1) + + tk.Label(win, text=_("Program")).grid(row=40, column=0) + tk.Entry(win, bd=2, state="readonly", textvariable=remote_app_tv).grid(row=40, column=1) + + tk.Button(win, width=20, height=2, text=_("Close"), command=win.destroy).grid(row=50, column=0) + tk.Button(win, width=20, height=2, text=_("Save"), command=self.save_edit_configuration).grid(row=50, column=1) + + def check_folder(self): + if not path.exists(self.config['tmpdir']): + mkdir(self.config['tmpdir']) + + def setup(self, load=False, write=False): + jsonfile = curdir + sep + "config.json" + if not path.isfile(jsonfile): + with open(jsonfile, "w") as f: + f.write(json.dumps(self.config)) + + if load: + with open(jsonfile, "r") as f: + cfg = json.loads(f.read()) + if self.config['version'] > cfg.get('version', '0.1a'): + with open(jsonfile, "w") as f: + f.write(json.dumps(self.config)) + else: + self.config.update(cfg) + elif write: + with open(jsonfile, "w") as f: + f.write(json.dumps(self.config)) + return True + + def initUI(self): + self.windows = [] + label = tk.Label(self, text=PROGRAM_NAME) + label["font"] = "Courier 14 italic" + label["height"] = 1 + label["width"] = 25 + label["borderwidth"] = 2 + label["relief"] = "ridge" + label["fg"] = "#000000" + label["anchor"] = "center" + label.grid(row=0, column=0, columnspan=6) + + self.logo = tk.PhotoImage(file=curdir + sep + "bin" + sep + "image" + sep + "support-client.gif") + self.Artwork = tk.Label(self, compound=tk.TOP, + text=_("press the button \nstart remote support and \ntell the support the" + " \nTeamviewer ID and Password.\n"), font="Courier 12", anchor="center", + fg="#000000", image=self.logo).grid(row=1, column=0, columnspan=5, sticky="N", + rowspan=2) + tk.Label(self, text=_(f"Tech Support \n Phone: {self.config['phone']}\n E-Mail: {self.config['email']}"), + font="Courier 12", anchor="center", fg="#000000").grid(row=4, column=0, columnspan=5, sticky="N") + + menubar = Menu(self.master) + dateimenu = Menu(menubar) + supportmenu = Menu(menubar) + helpmenu = Menu(menubar) + self.configure(menu=menubar) + + menubar.add_cascade(label=_("File"), menu=dateimenu) + dateimenu.add_command(label=_("Edit Configuration"), command=self.edit_configuration) + dateimenu.add_command(label=_("Close"), command=self.quit) + + menubar.add_cascade(label=_("Support"), menu=supportmenu) + supportmenu.add_command(label=_("Check Internet Connection"), command=self.ping_tool) + supportmenu.add_command(label=_("Start Remotesupport"), command=self.tw_start) + supportmenu.add_command(label=_("Download Remotetool"), command=self.download_supporttool) + supportmenu.add_separator() + + menubar.add_cascade(label=_("Help"), menu=helpmenu) + helpmenu.add_command(label=_(f"About {PROGRAM_NAME}"), command=self.about_program) + helpmenu.add_separator() + helpmenu.add_command(label=_("License"), command=self.show_license) + helpmenu.add_command(label=_("Manual"), command=self.manual) + helpmenu.add_command(label=_("Update"), command=self.update_program) + + tk.Label(self, text='').grid(row=5, column=0) + + self.conntestlb = tk.Label(self) + self.conntestlb["text"] = _("Internet Connection ?") + self.conntestlb["bg"] = "#ffa500" + self.conntestlb["font"] = "Courier 12" + self.conntestlb["height"] = 2 + self.conntestlb["width"] = 22 + self.conntestlb["relief"] = "ridge" + self.conntestlb["fg"] = "#000000" + self.conntestlb["anchor"] = "center" + self.conntestlb.grid(column=0, row=6, columnspan=6) + + tk.Label(self, text='').grid(row=15, column=0) + self.progressbar = Progressbar(self, orient='horizontal', length=260, mode='indeterminate') + self.progressbar.grid(row=18, column=0, columnspan=3) + self.progressbar.grid_forget() + + tk.Label(self, text='').grid(row=20, column=0) + tk.Button(self, width=20, height=2, text=_("Start Remotesupport"), command=self.tw_start).grid(row=25, column=0) + tk.Label(self, text='').grid(row=30, column=0) + tk.Button(self, width=20, height=2, text=_("Close"), command=self.quit).grid(row=50, column=0) + tk.Label(self, text='').grid(row=60, column=0) + + tk.Label(self, text=f"Bailey-Solution @{datetime.now().year}").grid(row=70, column=0, columnspan=2) + + def download_supporttool(self, parentprocess=True): + def download(): + if parentprocess: + self.progressbar.grid(row=18, column=0, columnspan=3) + self.progressbar.start() + try: + self.check_folder() + urlretrieve(url=f"{self.config['remote_app']['server']}{self.config['remote_app'][_osenv()]}", + filename=f"{self.config['tmpdir']}{sep}{self.config['remote_app'][_osenv()]}") + if parentprocess: + mbox.showinfo(title=_("Download"), message=_(f"Image {self.config['remote_app'][_osenv()]} downloaded")) + except Exception as exp: + print("exception = ", exp) + mbox.showwarning(title=_("Download Error"), message=exp) + if parentprocess: + self.progressbar.stop() + self.progressbar.grid_forget() + return True + if parentprocess: + threading.Thread(target=download).start() + else: + download() + return True + + def tw_start(self): + def start(): + self.progressbar.grid(row=18, column=0, columnspan=3) + self.progressbar.start() + try: + fpath = self.config.get('tmpdir', curdir+sep+'tmp') + if not path.isfile(f"{fpath}{sep}{self.config['remote_app'][_osenv()]}"): + self.download_supporttool(parentprocess=False) + appstart = None + if _osenv() == "nt": + appstart = [fpath+sep+self.config['remote_app'][_osenv()]] + elif _osenv() == "macos": + appstart = ['open', fpath+sep+self.config['remote_app'][_osenv()]] + + if appstart: + Popen(appstart) + else: + mbox.showwarning(title=_("Start Remotesupport"), message=_("Programm not found")) + except Exception as exp: + print("error = ", exp) + mbox.showwarning(title=_("Start Remotesupport"), message=str(exp)) + self.progressbar.stop() + self.progressbar.grid_forget() + return True + threading.Thread(target=start).start() + return True + + def ping_tool(self): + def ping(): + self.progressbar.grid(row=18, column=0, columnspan=3) + self.progressbar.start() + try: + self.conntestlb["bg"] = "#00FF00" + self.conntestlb["text"] = _("Check Running...") + cmd = ['ping'] + if _osenv() == "nt": + cmd.append('-n') + elif _osenv() in ["linux", "macos"]: + cmd.append('-c') + else: + cmd.append('-c') + + cmd1 = cmd + cmd1.append(str(self.config['test']['ping']['repeat'])) + cmd1.append(self.config['test']['ping']['ip']) + p1 = Popen(cmd1, stdout=PIPE) + result, error = p1.communicate() + if error: + self.conntestlb["bg"] = "#FF0000" + self.conntestlb["text"] = _("DNS error") + + cmd2 = cmd + cmd2.append(str(self.config['test']['ping']['repeat'])) + cmd2.append(self.config['test']['ping']['server']) + p2 = Popen(cmd2, stdout=PIPE) + result2, error2 = p2.communicate() + if error2: + self.conntestlb["bg"] = "#FF0000" + self.conntestlb["text"] = _("no connection") + + if error or error2: + mbox.showwarning(title=_("Ping Error"), message=f"{error}\n{error2}") + else: + self.conntestlb["bg"] = "#00FF00" + self.conntestlb["text"] = _("connection OK") + mbox.showinfo(title=_("Ping Successful"), message=_("Ping Successful")) + except Exception as exp: + print("exception = ", exp) + mbox.showwarning(title=_("Error on PING Command"), message=exp) + self.progressbar.stop() + self.progressbar.grid_forget() + return True + threading.Thread(target=ping).start() + + def manual(self): + desc = _("To start the Remoteconnection for Tech Support, klick on Start Remotesupport.") + mbox.showinfo(title=_("Manual"), message=desc) + + def show_license(self): + mbox.showinfo(title=_("License"), message=information) + + def about_program(self): + mbox.showinfo(title=_(f"About {PROGRAM_NAME}"), message=ABOUTPROGRAM) + + def update_program(self): + # from bin import update + # update.start_updater() + mbox.showinfo(title=f"Update {PROGRAM_NAME} {__version__}", message=_("feature is comming soon.")) + + +if __name__ == "__main__": + app = App() + app.mainloop()