diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index ae3acea76..d19bed2c2 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -2,15 +2,24 @@ Features/Enhancements: ---------------------- -#1186: Fixed several dialog boxes to use localized button text -#1170: Prevent Options window from showing up in taskbar +#1223: Open External Links in Default Web Browser #1141: 'Copy Hostname' option added to connection tree context menu #1129: Spanish translation improvements #1072: Russian translation improvements -#1064: "Esc" button does does not close some dialogs #1016: Chinese (simplified) translation improvements #951: Added property to Enable/Disable Clipboard Sharing for RDP connections #928: Add context menu items to 'Close all but this' and 'Close all tabs to the right' +#765: Port Scan Issues (single port scan option now available) + +Fixes: +------ +#1245: Options form takes nearly 3 seconds to appear when Theming is active +#1240: Theming problem with NGNumericUpDown +#1238: Connection panel not translated until opened for the first time +#1186: Fixed several dialog boxes to use localized button text +#1170: Prevent Options window from showing up in taskbar +#1064: "Esc" button does does not close some dialogs +#1044: Dragging (grabbing) the program window requires 2 clicks 1.76.12 (2018-11-08): diff --git a/CREDITS.TXT b/CREDITS.TXT index 082979afb..cfcf2deb1 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -16,7 +16,7 @@ github.com/peterchenadded Brandon Wulf (github.com/mrwulf) Pedro Rodrigues (github.com/pedro2555) github.com/dekelMP -github.com/farosch +Faryan Rezagholi (github.com/farosch) Bruce (github.com/brucetp) Camilo Alvarez (github.com/jotatsu) github.com/DamianBis @@ -105,7 +105,7 @@ Copyright http://www.codeproject.com/KB/selection/ADPickerCtrl.aspx DockPanel Suite -Copyright © 2016 @roken and @lextm (formerly Weifen Luo) +Copyright © 2018 @roken and @lextm (formerly Weifen Luo) MIT License https://github.com/dockpanelsuite/dockpanelsuite diff --git a/InstallerProjects/Installer/Fragments/MiscTextFilesFragment.wxs b/InstallerProjects/Installer/Fragments/MiscTextFilesFragment.wxs index 60e79336f..b5b84a537 100644 --- a/InstallerProjects/Installer/Fragments/MiscTextFilesFragment.wxs +++ b/InstallerProjects/Installer/Fragments/MiscTextFilesFragment.wxs @@ -14,6 +14,9 @@ + + + \ No newline at end of file diff --git a/InstallerProjects/Installer/Fragments/ShortcutFragment.wxs b/InstallerProjects/Installer/Fragments/ShortcutFragment.wxs index e31c802ee..a29e11e9d 100644 --- a/InstallerProjects/Installer/Fragments/ShortcutFragment.wxs +++ b/InstallerProjects/Installer/Fragments/ShortcutFragment.wxs @@ -5,14 +5,14 @@ - + - + diff --git a/InstallerProjects/Installer/Installer.wixproj b/InstallerProjects/Installer/Installer.wixproj index f22fa36cc..9bcbe6470 100644 --- a/InstallerProjects/Installer/Installer.wixproj +++ b/InstallerProjects/Installer/Installer.wixproj @@ -41,10 +41,10 @@ - + + + - - @@ -57,10 +57,6 @@ - - - - diff --git a/InstallerProjects/Installer/Localizations/cs-CZ.wxl b/InstallerProjects/Installer/Localizations/cs-CZ.wxl deleted file mode 100644 index 378cc301f..000000000 --- a/InstallerProjects/Installer/Localizations/cs-CZ.wxl +++ /dev/null @@ -1,26 +0,0 @@ - - - - - A newer version of [ProductName] is already installed. - You need to be an administrator to install this product. - mRemoteNG requires Microsoft .NET Framework $(var.RequiredDotNetFrameworkVersion). - mRemoteNG requires Windows 7 SP1 or higher to run. Please update your operating system and try again. - mRemoteNG requires RDP 8.0 or higher to run. Windows 7 users will need to install KB2592687 - For mRemoteNG to run on Windows 7, it requires Service Pack 1 to be installed. Please install Service Pack 1 and try again. - - - Desktop - Credits - License - Version History - - - Complete - Desktop Shortcut - Start menu shortcut - - - Launch [ProductName] Now - - \ No newline at end of file diff --git a/InstallerProjects/Installer/Localizations/de-DE.wxl b/InstallerProjects/Installer/Localizations/de-DE.wxl deleted file mode 100644 index 03947242b..000000000 --- a/InstallerProjects/Installer/Localizations/de-DE.wxl +++ /dev/null @@ -1,26 +0,0 @@ - - - - - A newer version of [ProductName] is already installed. - You need to be an administrator to install this product. - mRemoteNG requires Microsoft .NET Framework $(var.RequiredDotNetFrameworkVersion). - mRemoteNG requires Windows 7 SP1 or higher to run. Please update your operating system and try again. - mRemoteNG requires RDP 8.0 or higher to run. Windows 7 users will need to install KB2592687 - For mRemoteNG to run on Windows 7, it requires Service Pack 1 to be installed. Please install Service Pack 1 and try again. - - - Desktop - Credits - License - Version History - - - Complete - Desktop Shortcut - Start menu shortcut - - - mRemoteNG jetzt Starten - - \ No newline at end of file diff --git a/InstallerProjects/Installer/Localizations/en-US.wxl b/InstallerProjects/Installer/Localizations/en-US.wxl index eb4549722..9c0755923 100644 --- a/InstallerProjects/Installer/Localizations/en-US.wxl +++ b/InstallerProjects/Installer/Localizations/en-US.wxl @@ -22,6 +22,6 @@ Start menu shortcut - Launch mRemoteNG Now + Launch mRemoteNG now \ No newline at end of file diff --git a/InstallerProjects/Installer/Localizations/ja-JP.wxl b/InstallerProjects/Installer/Localizations/ja-JP.wxl deleted file mode 100644 index d4f583121..000000000 --- a/InstallerProjects/Installer/Localizations/ja-JP.wxl +++ /dev/null @@ -1,26 +0,0 @@ - - - - - A newer version of [ProductName] is already installed. - You need to be an administrator to install this product. - mRemoteNG requires Microsoft .NET Framework $(var.RequiredDotNetFrameworkVersion). - mRemoteNG requires Windows 7 SP1 or higher to run. Please update your operating system and try again. - mRemoteNG requires RDP 8.0 or higher to run. Windows 7 users will need to install KB2592687 - For mRemoteNG to run on Windows 7, it requires Service Pack 1 to be installed. Please install Service Pack 1 and try again. - - - Desktop - Credits - License - Version History - - - Complete - Desktop Shortcut - Start menu shortcut - - - Launch [ProductName] Now - - \ No newline at end of file diff --git a/InstallerProjects/Installer/Localizations/ru-RU.wxl b/InstallerProjects/Installer/Localizations/ru-RU.wxl deleted file mode 100644 index 7e8b091fa..000000000 --- a/InstallerProjects/Installer/Localizations/ru-RU.wxl +++ /dev/null @@ -1,26 +0,0 @@ - - - - - A newer version of [ProductName] is already installed. - You need to be an administrator to install this product. - mRemoteNG requires Microsoft .NET Framework $(var.RequiredDotNetFrameworkVersion). - mRemoteNG requires Windows 7 SP1 or higher to run. Please update your operating system and try again. - mRemoteNG requires RDP 8.0 or higher to run. Windows 7 users will need to install KB2592687 - For mRemoteNG to run on Windows 7, it requires Service Pack 1 to be installed. Please install Service Pack 1 and try again. - - - Desktop - Credits - License - Version History - - - Complete - Desktop Shortcut - Start menu shortcut - - - Launch [ProductName] Now - - \ No newline at end of file diff --git a/InstallerProjects/Installer/Resources/AppIcon.ico b/InstallerProjects/Installer/Resources/AppIcon.ico new file mode 100644 index 000000000..f3cc087a2 Binary files /dev/null and b/InstallerProjects/Installer/Resources/AppIcon.ico differ diff --git a/InstallerProjects/Installer/Resources/Installer_Header.png b/InstallerProjects/Installer/Resources/Installer_Header.png new file mode 100644 index 000000000..1b26685ea Binary files /dev/null and b/InstallerProjects/Installer/Resources/Installer_Header.png differ diff --git a/InstallerProjects/Installer/Resources/Installer_Side.png b/InstallerProjects/Installer/Resources/Installer_Side.png new file mode 100644 index 000000000..91addde88 Binary files /dev/null and b/InstallerProjects/Installer/Resources/Installer_Side.png differ diff --git a/InstallerProjects/Installer/Resources/License.rtf b/InstallerProjects/Installer/Resources/License.rtf new file mode 100644 index 000000000..e18780245 --- /dev/null +++ b/InstallerProjects/Installer/Resources/License.rtf @@ -0,0 +1,82 @@ +{\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 Courier;}} +{\colortbl;\red255\green0\blue0;\red0\green0\blue255;} +\widowctrl\hyphauto + +{\pard \ql \f0 \sa180 \li0 \fi0 \f1 GNU GENERAL PUBLIC LICENSE\line + Version 2, June 1991\par} +{\pard \ql \f0 \sa180 \li0 \fi0 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 \f1 Preamble\par} +{\pard \ql \f0 \sa180 \li0 \fi0 The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 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 this service 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.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. 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.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 The precise terms and conditions for copying, distribution and modification follow.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 \f1 GNU GENERAL PUBLIC LICENSE\par} +{\pard \ql \f0 \sa180 \li0 \fi0 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\par} +{\pard \ql \f0 \sa0 \li360 \fi-360 0.\tx360\tab This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".\sa180\par} +{\pard \ql \f0 \sa180 \li0 \fi0 Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.\par} +{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab You may copy and distribute 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 and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.\sa180\par} +{\pard \ql \f0 \sa180 \li0 \fi0 You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:\par} +{\pard \ql \f0 \sa180 \li720 \fi-360 a)\tx360\tab You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.\par} +{\pard \ql \f0 \sa180 \li720 \fi-360 b)\tx360\tab You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.\par} +{\pard \ql \f0 \sa180 \li720 \fi-360 c)\tx360\tab If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)\sa180\sa180\par} +{\pard \ql \f0 \sa180 \li0 \fi0 These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:\par} +{\pard \ql \f0 \sa180 \li720 \fi-360 a)\tx360\tab Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,\par} +{\pard \ql \f0 \sa180 \li720 \fi-360 b)\tx360\tab Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,\par} +{\pard \ql \f0 \sa180 \li720 \fi-360 c)\tx360\tab Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)\sa180\sa180\par} +{\pard \ql \f0 \sa180 \li0 \fi0 The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 4.\tx360\tab You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 5.\tx360\tab You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 6.\tx360\tab Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 7.\tx360\tab If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.\sa180\par} +{\pard \ql \f0 \sa180 \li0 \fi0 If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 8.\tx360\tab If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 9.\tx360\tab The Free Software Foundation may publish revised and/or new versions of the 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.\sa180\par} +{\pard \ql \f0 \sa180 \li0 \fi0 Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 10.\tx360\tab If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.\par} +{\pard \ql \f0 \sa180 \li360 \fi0 \f1 NO WARRANTY\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 11.\tx360\tab BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.\par} +{\pard \ql \f0 \sa180 \li360 \fi-360 12.\tx360\tab IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE 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.\par} +{\pard \ql \f0 \sa180 \li360 \fi0 \f1 END OF TERMS AND CONDITIONS\line +\line +How to Apply These Terms to Your New Programs\sa180\par} +{\pard \ql \f0 \sa180 \li0 \fi0 If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 \f1 \line +Copyright (C) \line +\line +This program is free software; you can redistribute it and/or modify\line +it under the terms of the GNU General Public License as published by\line +the Free Software Foundation; either version 2 of the License, or\line +(at your option) any later version.\line +\line +This program is distributed in the hope that it will be useful,\line +but WITHOUT ANY WARRANTY; without even the implied warranty of\line +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\line +GNU General Public License for more details.\line +\line +You should have received a copy of the GNU General Public License along\line +with this program; if not, write to the Free Software Foundation, Inc.,\line +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 Also add information on how to contact you by electronic and paper mail.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 If the program is interactive, make it output a short notice like this when it starts in an interactive mode:\par} +{\pard \ql \f0 \sa180 \li0 \fi0 \f1 Gnomovision version 69, Copyright (C) year name of author\line +Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\line +This is free software, and you are welcome to redistribute it\line +under certain conditions; type `show c' for details.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 The hypothetical commands {\f1 show w' and}show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than {\f1 show w' and}show c'; they could even be mouse-clicks or menu items--whatever suits your program.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:\par} +{\pard \ql \f0 \sa180 \li0 \fi0 Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker.\par} +{\pard \ql \f0 \sa180 \li0 \fi0 , 1 April 1989 Ty Coon, President of Vice\par} +{\pard \ql \f0 \sa180 \li0 \fi0 This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.\par} +} diff --git a/InstallerProjects/Installer/Resources/header.bmp b/InstallerProjects/Installer/Resources/header.bmp deleted file mode 100644 index 2d4ae1a4c..000000000 Binary files a/InstallerProjects/Installer/Resources/header.bmp and /dev/null differ diff --git a/InstallerProjects/Installer/Resources/mRemoteNG.ico b/InstallerProjects/Installer/Resources/mRemoteNG.ico deleted file mode 100644 index 700854c14..000000000 Binary files a/InstallerProjects/Installer/Resources/mRemoteNG.ico and /dev/null differ diff --git a/InstallerProjects/Installer/Resources/welcome.bmp b/InstallerProjects/Installer/Resources/welcome.bmp deleted file mode 100644 index 52cdb3805..000000000 Binary files a/InstallerProjects/Installer/Resources/welcome.bmp and /dev/null differ diff --git a/InstallerProjects/Installer/mRemoteNGV1.wxs b/InstallerProjects/Installer/mRemoteNGV1.wxs index f2ae4163a..030baec2e 100644 --- a/InstallerProjects/Installer/mRemoteNGV1.wxs +++ b/InstallerProjects/Installer/mRemoteNGV1.wxs @@ -11,7 +11,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -106,8 +106,8 @@ - - + + diff --git a/README.MD b/README.MD index 2f84aa7ee..d736c3c77 100644 --- a/README.MD +++ b/README.MD @@ -10,9 +10,9 @@ | Update Channel | Build Status | Downloads | | ---------------|--------------|-----------| -| Stable | [![Build status](https://ci.appveyor.com/api/projects/status/k0sdbxmq90fgdmj6/branch/master?svg=true)](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/master) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.75.7012/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75.7012) | -| Beta | | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.75.7012/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75.7012) | -| Development | [![Build status](https://ci.appveyor.com/api/projects/status/k0sdbxmq90fgdmj6/branch/develop?svg=true)](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/develop) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.76Alpha5/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76Alpha5) | +| Stable | [![Build status](https://ci.appveyor.com/api/projects/status/k0sdbxmq90fgdmj6/branch/master?svg=true)](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/master) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.76.11/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76.11) | +| Beta | | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.76.12/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76.12) | +| Development | [![Build status](https://ci.appveyor.com/api/projects/status/k0sdbxmq90fgdmj6/branch/develop?svg=true)](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/develop) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.76.12/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76.12) | mRemoteNG is the next generation of mRemote, a full-featured, multi-tab remote connections manager. diff --git a/Tools/CreateBulkConnections_ConfCons2_6.ps1 b/Tools/CreateBulkConnections_ConfCons2_6.ps1 index f0f92a041..b39a2598d 100644 --- a/Tools/CreateBulkConnections_ConfCons2_6.ps1 +++ b/Tools/CreateBulkConnections_ConfCons2_6.ps1 @@ -1,60 +1,208 @@ ##################################### -# Author: David Sparer -# Summary: +# Authors: David Sparer & Jack Denton +# Summary: # This is intended to be a template for creating connections in bulk. This uses the serializers directly from the mRemoteNG binaries. # You will still need to create the connection info objects, but the library will handle serialization. It is expected that you # are familiar with PowerShell. If this is not the case, reach out to the mRemoteNG community for help. # Usage: -# Replace or modify the examples that are shown toward the end of the script to create your own connection info objects. +# Replace or modify the examples that are shown toward the end of the script to create your own connection info objects. ##################################### -$EncryptionKey = (Get-Credential -Message "Enter the encryption key you would like to use. This must match the encryption key used by the rest of the confCons file." -UserName "DontNeedUsername").Password -$PathToMrngFolder = "" +foreach ($Path in 'HKLM:\SOFTWARE\WOW6432Node\mRemoteNG', 'HKLM:\SOFTWARE\mRemoteNG') { + Try { + $mRNGPath = (Get-ItemProperty -Path $Path -Name InstallDir -ErrorAction Stop).InstallDir + break + } + Catch { + continue + } +} +if (!$mRNGPath) { + Add-Type -AssemblyName System.Windows.Forms + $FolderBrowser = [System.Windows.Forms.FolderBrowserDialog]@{ + Description = 'Please select the folder which contains mRemoteNG.exe' + ShowNewFolderButton = $false + } + + $Response = $FolderBrowser.ShowDialog() + + if ($Response.value__ -eq 1) { + $mRNGPath = $FolderBrowser.SelectedPath + } + elseif ($Response.value__ -eq 2) { + Write-Warning 'A folder containing mRemoteNG.exe has not been selected' + return + } +} +$null = [System.Reflection.Assembly]::LoadFile((Join-Path -Path $mRNGPath -ChildPath "mRemoteNG.exe")) +Add-Type -Path (Join-Path -Path $mRNGPath -ChildPath "BouncyCastle.Crypto.dll") -if ($PathToMrngFolder -eq "") { - Write-Error -Message 'You must set the $PathToMrngFolder variable in this script to the folder which contains mRemoteNG.exe' + + +function ConvertTo-mRNGSerializedXml { + [CmdletBinding()] + Param ( + [Parameter(Mandatory)] + [mRemoteNG.Connection.ConnectionInfo[]] + $Xml +) + + function Get-ChildNodes { + Param ($Xml) + + $Xml + + if ($Xml -is [mRemoteNG.Container.ContainerInfo] -and $Xml.HasChildren()) { + foreach ($Node in $Xml.Children) { + Get-ChildNodes -Xml $Node + } + } + } + + $AllNodes = Get-ChildNodes -Xml $Xml + if ( + $AllNodes.Password -or + $AllNodes.RDGatewayPassword -or + $AllNodes.VNCProxyPassword + ) { + $Password = Read-Host -Message 'If you have password protected your ConfCons.xml please enter the password here otherwise just press enter' -AsSecureString + } + else { + $Password = [securestring]::new() + } + $CryptoProvider = [mRemoteNG.Security.SymmetricEncryption.AeadCryptographyProvider]::new() + $SaveFilter = [mRemoteNG.Security.SaveFilter]::new() + $ConnectionNodeSerializer = [mRemoteNG.Config.Serializers.Xml.XmlConnectionNodeSerializer26]::new($CryptoProvider, $Password, $SaveFilter) + $XmlSerializer = [mRemoteNG.Config.Serializers.Xml.XmlConnectionsSerializer]::new($CryptoProvider, $ConnectionNodeSerializer) + + $RootNode = [mRemoteNG.Tree.Root.RootNodeInfo]::new('Connection') + foreach ($Node in $Xml) { + $RootNode.AddChild($Node) + } + $XmlSerializer.Serialize($RootNode) } -$assembly = [System.Reflection.Assembly]::LoadFile((Join-Path -Path $PathToMrngFolder -ChildPath "mRemoteNG.exe")) -$assembly = [System.Reflection.Assembly]::LoadFile((Join-Path -Path $PathToMrngFolder -ChildPath "BouncyCastle.Crypto.dll")) +function New-mRNGConnection { + [CmdletBinding(DefaultParameterSetName = 'Credential')] + Param ( + [Parameter(Mandatory)] + [string] + $Name, -function New-mRemoteNGXmlSerializer { - [CmdletBinding()] - param ( - [SecureString] - $EncryptionKey + [Parameter(Mandatory)] + [string] + $Hostname, + + [Parameter(Mandatory)] + [mRemoteNG.Connection.Protocol.ProtocolType] + $Protocol, + + [Parameter(ParameterSetName = 'Credential')] + [pscredential] + $Credential, + + [Parameter(ParameterSetName = 'InheritCredential')] + [switch] + $InheritCredential, + + [Parameter()] + [mRemoteNG.Container.ContainerInfo] + $ParentContainer, + + [Parameter()] + [switch] + $PassThru ) - PROCESS { - $cryptoProvider = New-Object -TypeName mRemoteNG.Security.SymmetricEncryption.AeadCryptographyProvider - $saveFilter = New-Object -TypeName mRemoteNG.Security.SaveFilter -ArgumentList @($false) - $xmlSerializer = New-Object -TypeName mRemoteNG.Config.Serializers.XmlConnectionNodeSerializer -ArgumentList @($cryptoProvider, $encryptionKey, $saveFilter) - Write-Output $xmlSerializer + $Connection = [mRemoteNG.Connection.ConnectionInfo]@{ + Name = $Name + Hostname = $Hostname + Protocol = $Protocol + } + + if ($Credential) { + $Connection.Username = $Credential.GetNetworkCredential().UserName + $Connection.Domain = $Credential.GetNetworkCredential().Domain + $Connection.Password = $Credential.GetNetworkCredential().Password + } + + if ($InheritCredential) { + $Connection.Inheritance.Username = $true + $Connection.Inheritance.Domain = $true + $Connection.Inheritance.Password = $true + } + + if ($ParentContainer) { + $ParentContainer.AddChild($Connection) + + if ($PSBoundParameters.ContainsKey('PassThru')) { + $Connection + } + } + else { + $Connection } } -function New-mRemoteNGConnectionInfo { +function New-mRNGContainer { + [CmdletBinding(DefaultParameterSetName = 'Credential')] + Param ( + [Parameter(Mandatory)] + [string] + $Name, + + [Parameter(ParameterSetName = 'Credential')] + [pscredential] + $Credential, + + [Parameter(ParameterSetName = 'InheritCredential')] + [switch] + $InheritCredential, + + [Parameter()] + [mRemoteNG.Container.ContainerInfo] + $ParentContainer + ) + + $Container = [mRemoteNG.Container.ContainerInfo]@{ + Name = $Name + } + + if ($Credential) { + $Container.Username = $Credential.GetNetworkCredential().UserName + $Container.Domain = $Credential.GetNetworkCredential().Domain + $Container.Password = $Credential.GetNetworkCredential().Password + } + + if ($InheritCredential) { + $Container.Inheritance.Username = $true + $Container.Inheritance.Domain = $true + $Container.Inheritance.Password = $true + } + + if ($ParentContainer) { + $ParentContainer.AddChild($Container) + } + + $Container +} + +function Export-mRNGXml { [CmdletBinding()] - param () + param ( + [Parameter()] + [string] + $Path, - PROCESS { - $connectionInfo = New-Object -TypeName mRemoteNG.Connection.ConnectionInfo - Write-Output $connectionInfo - } + [Parameter()] + [string] + $SerializedXml + ) + + $FilePathProvider = [mRemoteNG.Config.DataProviders.FileDataProvider]::new($Path) + $filePathProvider.Save($SerializedXml) } -function New-mRemoteNGContainerInfo { - [CmdletBinding()] - param () - - PROCESS { - $connectionInfo = New-Object -TypeName mRemoteNG.Container.ContainerInfo - Write-Output $connectionInfo - } -} - -# Setup the services needed to do serialization -$xmlSerializer = New-mRemoteNGXmlSerializer -EncryptionKey $EncryptionKey @@ -62,53 +210,85 @@ $xmlSerializer = New-mRemoteNGXmlSerializer -EncryptionKey $EncryptionKey # Example 1: serialize many connections, no containers # Here you can define the number of connection info objects to create # You can also provide a list of desired hostnames and iterate over those -$xml = "" -foreach($i in 1..5) -{ - $connectionInfo = New-mRemoteNGConnectionInfo - # Set connection info properties - $connectionInfo.Name = "server-$i" - $connectionInfo.Hostname = "some-win-server-$i" - $connectionInfo.Protocol = [mRemoteNG.Connection.Protocol.ProtocolType]::RDP - $connectionInfo.Inheritance.Username = $true - $connectionInfo.Inheritance.Domain = $true - $connectionInfo.Inheritance.Password = $true - - $serializedConnection = $xmlSerializer.SerializeConnectionInfo($connectionInfo).ToString() - $xml += $serializedConnection + [System.Environment]::NewLine +$Connections = foreach ($i in 1..5) { + # Create new connection + $Splat = @{ + Name = 'Server-{0:D2}' -f $i + Hostname = 'Server-{0:D2}' -f $i + Protocol = 'RDP' + InheritCredential = $true + } + New-mRNGConnection @Splat } -Write-Output $xml +# Serialize the connections +$SerializedXml = ConvertTo-mRNGSerializedXml -Xml $Connections + +# Write the XML to a file ready to import into mRemoteNG +Export-mRNGXml -Path "$ENV:APPDATA\mRemoteNG\PowerShellGenerated.xml" -SerializedXml $SerializedXml + +# Now open up mRemoteNG and press Ctrl+O and open up the exported XML file #---------------------------------------------------------------- # Example 2: serialize a container which has connections -# You can also create containers and add connections to them, which will be nested correctly when serialized -$xml = "" -$container = New-mRemoteNGContainerInfo -$container.Name = "ProductionServers" -$serializedContainer = $xmlSerializer.SerializeConnectionInfo($container) +# You can also create containers and add connections and containers to them, which will be nested correctly when serialized +# If you specify the ParentContainer parameter for new connections then there will be no output unless the PassThru parameter is also used -foreach($i in 1..3) -{ - $connectionInfo = New-mRemoteNGConnectionInfo +$ProdServerCreds = Get-Credential +$ProdServers = New-mRNGContainer -Name 'ProdServers' -Credential $ProdServerCreds - # Set connection info properties - $connectionInfo.Name = "server-$i" - $connectionInfo.Hostname = "some-linux-server-$i" - $connectionInfo.Protocol = [mRemoteNG.Connection.Protocol.ProtocolType]::SSH2 - $connectionInfo.Inheritance.Username = $true - $connectionInfo.Inheritance.Domain = $true - $connectionInfo.Inheritance.Password = $true - - # serialize the connection - $serializedConnection = $xmlSerializer.SerializeConnectionInfo($connectionInfo) - # add the connection to the container - $serializedContainer.Add($serializedConnection) +foreach ($i in 1..3) { + # Create new connection + $Splat = @{ + Name = 'Server-{0:D2}' -f $i + Hostname = 'Server-{0:D2}' -f $i + Protocol = 'RDP' + InheritCredential = $true + ParentContainer = $ProdServers + } + New-mRNGConnection @Splat } -# Call ToString() on the top-level container to get the XML of it and all its children -Write-Output $serializedContainer.ToString() \ No newline at end of file +$ProdWebServers = New-mRNGContainer -Name 'WebServers' -ParentContainer $ProdServers -InheritCredential + +foreach ($i in 1..3) { + # Create new connection + $Splat = @{ + Name = 'WebServer-{0:D2}' -f $i + Hostname = 'WebServer-{0:D2}' -f $i + Protocol = 'SSH1' + InheritCredential = $true + ParentContainer = $ProdWebServers + } + New-mRNGConnection @Splat +} + +$DevServers = New-mRNGContainer -Name 'DevServers' + +foreach ($i in 1..3) { + # Create new connection + $Splat = @{ + Name = 'DevServer-{0:D2}' -f $i + Hostname = 'DevServer-{0:D2}' -f $i + Protocol = 'RDP' + InheritCredential = $true + ParentContainer = $DevServers + PassThru = $true + } + + # Specified the PassThru parameter in order to catch the connection and change a property + $Connection = New-mRNGConnection @Splat + $Connection.Resolution = 'FullScreen' +} + +# Serialize the container +$SerializedXml = ConvertTo-mRNGSerializedXml -Xml $ProdServers, $DevServers + +# Write the XML to a file ready to import into mRemoteNG +Export-mRNGXml -Path "$ENV:APPDATA\mRemoteNG\PowerShellGenerated.xml" -SerializedXml $SerializedXml + +# Now open up mRemoteNG and press Ctrl+O and open up the exported XML file diff --git a/Tools/appveyor_after_build.ps1 b/Tools/appveyor_after_build.ps1 new file mode 100644 index 000000000..ec81233cb --- /dev/null +++ b/Tools/appveyor_after_build.ps1 @@ -0,0 +1,73 @@ +if([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) { + Write-Output "NOT running via Appveyor - Exiting" + Exit +} + +$appvDir = $Env:APPVEYOR_BUILD_FOLDER + +Write-Output "Appveyor Build Dir: '$($appvDir)'" +$ConfigurationName = $Env:CONFIGURATION.Trim() +Write-Output "Config Name (tirmmed): '$($ConfigurationName)'" + + +$SIGCHECK="Tools\exes\sigcheck.exe" +$SEVENZIP="Tools\7zip\7za.exe" + +if ($ConfigurationName -eq "Release Portable") { + Write-Output "Packaging Release Portable ZIP" + + $version = & $SIGCHECK /accepteula -q -n "mRemoteV1\bin\$($ConfigurationName)\mRemoteNG.exe" + + Write-Output "Version is $($version)" + + $PortableZip="Release\mRemoteNG-Portable-$($version).zip" + + Remove-Item -Recurse "mRemoteV1\bin\package" -ErrorAction SilentlyContinue | Out-Null + New-Item "mRemoteV1\bin\package" -ItemType "directory" | Out-Null + + Copy-Item "mRemoteV1\Resources\PuTTYNG.exe" -Destination "mRemoteV1\bin\package" + + Copy-Item "mRemoteV1\bin\$ConfigurationName\*" -Destination "mRemoteV1\bin\package" -Recurse -Force + Copy-Item "*.txt" -Destination "mRemoteV1\bin\package" + + Write-Output "Creating portable ZIP file $($PortableZip)" + Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue + & $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip "mRemoteV1\bin\package\*.*" +} +else { + Write-Output "We will not zip anything - this isnt a portable release build." +} + +Write-Output "" +Write-Output "" + +if ($ConfigurationName -match "Release" -And $ConfigurationName -ne "Release Installer") { + Write-Output "Packaging debug symbols" + + $version = & $SIGCHECK /accepteula -q -n "mRemoteV1\bin\$($ConfigurationName)\mRemoteNG.exe" + + Write-Output "Version is $($version)" + + if ($ConfigurationName -match "Portable") { + $zipFilePrefix = "mRemoteNG-Portable-symbols" + } else { + $zipFilePrefix = "mRemoteNG-symbols" + } + + $outputZipPath="Release\$zipFilePrefix-$($version).zip" + + Write-Output "Creating debug symbols ZIP file $($outputZipPath)" + Remove-Item -Force $outputZipPath -ErrorAction SilentlyContinue + $SymPath = (Join-Path -Path mRemoteV1\bin\$($ConfigurationName) -ChildPath "*.pdb") + if(Test-Path "$SymPath") { + & $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $outputZipPath "$SymPath" + } else { + Write-Output "No Debugging Symbols Found..." + } + +} +else { + Write-Output "We will not package debug symbols for this configuration $($ConfigurationName)" +} + +Write-Output "" \ No newline at end of file diff --git a/Tools/copy_tiles.ps1 b/Tools/copy_tiles.ps1 new file mode 100644 index 000000000..52c73630d --- /dev/null +++ b/Tools/copy_tiles.ps1 @@ -0,0 +1,19 @@ +param ( + [string] + [Parameter(Mandatory=$true)] + $SolutionDir, + + [string] + [Parameter(Mandatory=$true)] + $TargetDir +) + +Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) =====" +Write-Output "Copying TILES folder to output" + +$sourceFiles = [io.path]::combine($SolutionDir , 'mRemoteV1\Resources\Tiles' ) +$DestinationDir = $TargetDir + +robocopy $sourceFiles $DestinationDir *.* + +Write-Output "" \ No newline at end of file diff --git a/Tools/postbuild_mremotev1.ps1 b/Tools/postbuild_mremotev1.ps1 index 7129950d1..a03c457bc 100644 --- a/Tools/postbuild_mremotev1.ps1 +++ b/Tools/postbuild_mremotev1.ps1 @@ -40,6 +40,7 @@ Format-Table -AutoSize -Wrap -InputObject @{ & "$PSScriptRoot\copy_puttyng.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir & "$PSScriptRoot\copy_themes.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir +& "$PSScriptRoot\copy_tiles.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir & "$PSScriptRoot\move_help_files.ps1" -TargetDir $TargetDir & "$PSScriptRoot\set_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName & "$PSScriptRoot\verify_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName diff --git a/Tools/tidy_files_for_release.ps1 b/Tools/tidy_files_for_release.ps1 index b56218fb1..543247c6e 100644 --- a/Tools/tidy_files_for_release.ps1 +++ b/Tools/tidy_files_for_release.ps1 @@ -21,7 +21,9 @@ if ($ConfigurationName -match "Release") { "*.log", "*vshost*", "*.tmp" - ) + ) -Exclude @( + "mRemoteNG.VisualElementsManifest.xml" + ) Remove-Item -Path $filesToDelete.FullName Write-Output $filesToDelete.FullName } diff --git a/Tools/zip_portable_files_appv.ps1 b/Tools/zip_portable_files_appv.ps1 deleted file mode 100644 index 52a72ce33..000000000 --- a/Tools/zip_portable_files_appv.ps1 +++ /dev/null @@ -1,39 +0,0 @@ -if([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) { - Write-Output "NOT running via Appveyor - Exiting" - Exit -} - -$appvDir = $Env:APPVEYOR_BUILD_FOLDER - -Write-Output "Appveyor Build Dir: '$($appvDir)'" -$ConfigurationName = $Env:CONFIGURATION.Trim() -Write-Output "Config Name (tirmmed): '$($ConfigurationName)'" - - -$SIGCHECK="$($SolutionDir)Tools\exes\sigcheck.exe" -$SEVENZIP="$($SolutionDir)Tools\7zip\7za.exe" - -if ($ConfigurationName -eq "Release Portable") { - Write-Output "Packaging Release Portable ZIP" - - $version = & $SIGCHECK /accepteula -q -n "$($SolutionDir)mRemoteV1\bin\$($ConfigurationName)\mRemoteNG.exe" - - Write-Output "Version is $($version)" - - $PortableZip="$($SolutionDir)Release\mRemoteNG-Portable-$($version).zip" - - Remove-Item -Recurse "$($SolutionDir)mRemoteV1\bin\package" -ErrorAction SilentlyContinue | Out-Null - New-Item "$($SolutionDir)mRemoteV1\bin\package" -ItemType "directory" | Out-Null - - Copy-Item "$($SolutionDir)mRemoteV1\Resources\PuTTYNG.exe" -Destination "$($SolutionDir)mRemoteV1\bin\package" - - Copy-Item "$($SolutionDir)mRemoteV1\bin\$ConfigurationName\*" -Destination "$($SolutionDir)mRemoteV1\bin\package" -Recurse -Force - Copy-Item "$($SolutionDir)*.txt" -Destination "$($SolutionDir)mRemoteV1\bin\package" - - Write-Output "Creating portable ZIP file $($PortableZip)" - Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue - & $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip "$($SolutionDir)mRemoteV1\bin\package\*.*" -} -else { - Write-Output "We will not zip anything - this isnt a portable release build." -} \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 1aa639bce..a8474cb14 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,16 +7,28 @@ configuration: - Release Portable - Release Installer platform: x86 +shallow_clone: true clone_depth: 1 install: -- ps: C:\projects\mremoteng\mRemoteV1\Resources\CitrixReceiver.exe DONOTSTARTCC=1 ENABLE_SSON="No" /silent | out-null +- ps: >- + date + + C:\projects\mremoteng\mRemoteV1\Resources\CitrixReceiver.exe ENABLE_SSON="No" /silent /noreboot /EnableCEIP=false /AutoUpdateCheck=disabled /EnableTracing=false | out-null + + date before_build: -- cmd: nuget restore +- cmd: >- + echo %TIME% + + nuget restore + + echo %TIME% build: project: mRemoteV1.sln + parallel: true verbosity: normal after_build: -- ps: "if([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {\n Write-Output \"NOT running via Appveyor - Exiting\"\n Exit\n}\n\n$appvDir = $Env:APPVEYOR_BUILD_FOLDER\n\nWrite-Output \"Appveyor Build Dir: '$($appvDir)'\"\n$ConfigurationName = $Env:CONFIGURATION.Trim()\nWrite-Output \"Config Name (tirmmed): '$($ConfigurationName)'\"\n\n\n$SIGCHECK=\"$($SolutionDir)Tools\\exes\\sigcheck.exe\"\n$SEVENZIP=\"$($SolutionDir)Tools\\7zip\\7za.exe\"\n\nif ($ConfigurationName -eq \"Release Portable\") {\n Write-Output \"Packaging Release Portable ZIP\"\n \n $version = & $SIGCHECK /accepteula -q -n \"$($SolutionDir)mRemoteV1\\bin\\$($ConfigurationName)\\mRemoteNG.exe\"\n\n Write-Output \"Version is $($version)\"\n\n $PortableZip=\"$($SolutionDir)Release\\mRemoteNG-Portable-$($version).zip\"\n\n Remove-Item -Recurse \"$($SolutionDir)mRemoteV1\\bin\\package\" -ErrorAction SilentlyContinue | Out-Null\n New-Item \"$($SolutionDir)mRemoteV1\\bin\\package\" -ItemType \"directory\" | Out-Null\n \n Copy-Item \"$($SolutionDir)mRemoteV1\\Resources\\PuTTYNG.exe\" -Destination \"$($SolutionDir)mRemoteV1\\bin\\package\"\n\n Copy-Item \"$($SolutionDir)mRemoteV1\\bin\\$ConfigurationName\\*\" -Destination \"$($SolutionDir)mRemoteV1\\bin\\package\" -Recurse -Force \n Copy-Item \"$($SolutionDir)*.txt\" -Destination \"$($SolutionDir)mRemoteV1\\bin\\package\"\n\n Write-Output \"Creating portable ZIP file $($PortableZip)\"\n Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue\n & $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip \"$($SolutionDir)mRemoteV1\\bin\\package\\*.*\"\n}\nelse {\n Write-Output \"We will not zip anything - this isnt a portable release build.\"\n}" +- ps: "if([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {\n Write-Output \"NOT running via Appveyor - Exiting\"\n Exit\n}\n\n$appvDir = $Env:APPVEYOR_BUILD_FOLDER\n\nWrite-Output \"Appveyor Build Dir: '$($appvDir)'\"\n$ConfigurationName = $Env:CONFIGURATION.Trim()\nWrite-Output \"Config Name (tirmmed): '$($ConfigurationName)'\"\n\n\n$SIGCHECK=\"Tools\\exes\\sigcheck.exe\"\n$SEVENZIP=\"Tools\\7zip\\7za.exe\"\n\nif ($ConfigurationName -eq \"Release Portable\") {\n Write-Output \"Packaging Release Portable ZIP\"\n \n $version = & $SIGCHECK /accepteula -q -n \"mRemoteV1\\bin\\$($ConfigurationName)\\mRemoteNG.exe\"\n\n Write-Output \"Version is $($version)\"\n\n $PortableZip=\"Release\\mRemoteNG-Portable-$($version).zip\"\n\n Remove-Item -Recurse \"mRemoteV1\\bin\\package\" -ErrorAction SilentlyContinue | Out-Null\n New-Item \"mRemoteV1\\bin\\package\" -ItemType \"directory\" | Out-Null\n \n Copy-Item \"mRemoteV1\\Resources\\PuTTYNG.exe\" -Destination \"mRemoteV1\\bin\\package\"\n\n Copy-Item \"mRemoteV1\\bin\\$ConfigurationName\\*\" -Destination \"mRemoteV1\\bin\\package\" -Recurse -Force \n Copy-Item \"*.txt\" -Destination \"mRemoteV1\\bin\\package\"\n\n Write-Output \"Creating portable ZIP file $($PortableZip)\"\n Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue\n & $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip \"mRemoteV1\\bin\\package\\*.*\"\n}\nelse {\n Write-Output \"We will not zip anything - this isnt a portable release build.\"\n}\n\nWrite-Output \"\"\nWrite-Output \"\"\n\nif ($ConfigurationName -match \"Release\" -And $ConfigurationName -ne \"Release Installer\") {\n Write-Output \"Packaging debug symbols\"\n \n $version = & $SIGCHECK /accepteula -q -n \"mRemoteV1\\bin\\$($ConfigurationName)\\mRemoteNG.exe\"\n\n Write-Output \"Version is $($version)\"\n\n if ($ConfigurationName -match \"Portable\") {\n $zipFilePrefix = \"mRemoteNG-Portable-symbols\"\n } else {\n $zipFilePrefix = \"mRemoteNG-symbols\"\n }\n\n $outputZipPath=\"Release\\$zipFilePrefix-$($version).zip\"\n\n Write-Output \"Creating debug symbols ZIP file $($outputZipPath)\"\n Remove-Item -Force $outputZipPath -ErrorAction SilentlyContinue\n $SymPath = (Join-Path -Path mRemoteV1\\bin\\$($ConfigurationName) -ChildPath \"*.pdb\")\n if(Test-Path \"$SymPath\") {\n & $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $outputZipPath \"$SymPath\"\n } else {\n Write-Output \"No Debugging Symbols Found...\"\n }\n \n}\nelse {\n Write-Output \"We will not package debug symbols for this configuration $($ConfigurationName)\"\n}\n\nWrite-Output \"\"" test: assemblies: only: @@ -24,5 +36,9 @@ test: artifacts: - path: Release\*.msi name: mRemoteNG-installer.msi -- path: Release\*.zip - name: mRemoteNG-portable.zip \ No newline at end of file +- path: Release\mRemoteNG-Portable-1.*.zip + name: mRemoteNG-portable.zip +- path: Release\mRemoteNG-Portable-symbols*.zip + name: mRemoteNG-Portable-symbols.zip +- path: Release\mRemoteNG-symbols*.zip + name: mRemoteNG-symbols.zip \ No newline at end of file diff --git a/mRemoteNGTests/Config/CredentialHarvesterTests.cs b/mRemoteNGTests/Config/CredentialHarvesterTests.cs index cfefafede..7132acea0 100644 --- a/mRemoteNGTests/Config/CredentialHarvesterTests.cs +++ b/mRemoteNGTests/Config/CredentialHarvesterTests.cs @@ -1,9 +1,4 @@ -using System; -using System.Linq; -using System.Security; -using System.Xml.Linq; -using mRemoteNG.Config; -using mRemoteNG.Config.Serializers; +using mRemoteNG.Config; using mRemoteNG.Config.Serializers.Xml; using mRemoteNG.Connection; using mRemoteNG.Container; @@ -11,6 +6,10 @@ using mRemoteNG.Security; using mRemoteNG.Security.Factories; using mRemoteNG.Tree.Root; using NUnit.Framework; +using System; +using System.Linq; +using System.Security; +using System.Xml.Linq; namespace mRemoteNGTests.Config @@ -122,7 +121,7 @@ namespace mRemoteNGTests.Config { var rootNode = new RootNodeInfo(RootNodeType.Connection) {PasswordString = _key.ConvertToUnsecureString()}; rootNode.AddChild(connectionInfo); - var nodeSerializer = new XmlConnectionNodeSerializer26(_cryptographyProvider, _key, new SaveFilter()); + var nodeSerializer = new XmlConnectionNodeSerializer27(_cryptographyProvider, _key, new SaveFilter()); var serializer = new XmlConnectionsSerializer(_cryptographyProvider, nodeSerializer); var serializedData = serializer.Serialize(rootNode); return XDocument.Parse(serializedData); diff --git a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/ValidateXmlSchemas.cs b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/ValidateXmlSchemas.cs index c0818b866..7a6d4f049 100644 --- a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/ValidateXmlSchemas.cs +++ b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/ValidateXmlSchemas.cs @@ -1,17 +1,16 @@ -using System; +using mRemoteNG.Config.Serializers.Xml; +using mRemoteNG.Connection; +using mRemoteNG.Security; +using mRemoteNG.Security.SymmetricEncryption; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using NUnit.Framework; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Xml; using System.Xml.Schema; -using mRemoteNG.Config.Serializers.Xml; -using mRemoteNG.Security; -using mRemoteNG.Security.SymmetricEncryption; -using mRemoteNG.Tree; -using mRemoteNG.Tree.Root; -using mRemoteNGTests.TestHelpers; -using NUnit.Framework; namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml { @@ -25,9 +24,13 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml [SetUp] public void Setup() { - _connectionTreeModel = new ConnectionTreeModelBuilder().Build(); + _connectionTreeModel = new ConnectionTreeModel(); + var root = new RootNodeInfo(RootNodeType.Connection); + root.AddChild(new ConnectionInfo()); + _connectionTreeModel.AddRootNode(root); + _cryptographyProvider = new AeadCryptographyProvider(); - var connectionNodeSerializer = new XmlConnectionNodeSerializer26( + var connectionNodeSerializer = new XmlConnectionNodeSerializer27( _cryptographyProvider, _connectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString(), new SaveFilter()); @@ -47,7 +50,8 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml var sb = new StringBuilder(); var xml = _serializer.Serialize(_connectionTreeModel); - var schemaFile = GetTargetPath("mremoteng_confcons_v2_6.xsd"); + var schemaFileName = $"mremoteng_confcons_v{_serializer.Version.Major}_{_serializer.Version.Minor}.xsd"; + var schemaFile = GetTargetPath(schemaFileName); _xmlReaderSettings.Schemas.Add("http://mremoteng.org", schemaFile); _xmlReaderSettings.ValidationEventHandler += (sender, args) => { diff --git a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentCompilerTests.cs b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentCompilerTests.cs index d932fa698..5935b9ea9 100644 --- a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentCompilerTests.cs +++ b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentCompilerTests.cs @@ -1,7 +1,4 @@ -using System.Linq; -using System.Xml.XPath; -using mRemoteNG.Config.Serializers; -using mRemoteNG.Config.Serializers.Xml; +using mRemoteNG.Config.Serializers.Xml; using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Security; @@ -9,10 +6,12 @@ using mRemoteNG.Security.Factories; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; using NUnit.Framework; +using System.Linq; +using System.Xml.XPath; namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml { - public class XmlConnectionsDocumentCompilerTests + public class XmlConnectionsDocumentCompilerTests { private XmlConnectionsDocumentCompiler _documentCompiler; private ConnectionTreeModel _connectionTreeModel; @@ -31,7 +30,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml { _connectionTreeModel = SetupConnectionTreeModel(); _cryptographyProvider = new CryptoProviderFactory(BlockCipherEngines.AES, BlockCipherModes.GCM).Build(); - var connectionNodeSerializer = new XmlConnectionNodeSerializer26( + var connectionNodeSerializer = new XmlConnectionNodeSerializer27( _cryptographyProvider, _connectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString(), new SaveFilter()); diff --git a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentEncryptorTests.cs b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentEncryptorTests.cs index 563eeef4a..517121cc3 100644 --- a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentEncryptorTests.cs +++ b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentEncryptorTests.cs @@ -1,7 +1,4 @@ -using System.Linq; -using System.Xml.Linq; -using mRemoteNG.Config.Serializers; -using mRemoteNG.Config.Serializers.Xml; +using mRemoteNG.Config.Serializers.Xml; using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Security; @@ -9,10 +6,12 @@ using mRemoteNG.Security.Factories; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; using NUnit.Framework; +using System.Linq; +using System.Xml.Linq; namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml { - public class XmlConnectionsDocumentEncryptorTests + public class XmlConnectionsDocumentEncryptorTests { private XmlConnectionsDocumentEncryptor _documentEncryptor; private XDocument _originalDocument; @@ -22,7 +21,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml { var connectionTreeModel = SetupConnectionTreeModel(); var cryptoProvider = new CryptoProviderFactory(BlockCipherEngines.AES, BlockCipherModes.GCM).Build(); - var connectionNodeSerializer = new XmlConnectionNodeSerializer26( + var connectionNodeSerializer = new XmlConnectionNodeSerializer27( cryptoProvider, connectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString(), new SaveFilter()); diff --git a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsSerializerTests.cs b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsSerializerTests.cs index a3b3310ad..f378ba987 100644 --- a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsSerializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsSerializerTests.cs @@ -1,8 +1,4 @@ -using System.Linq; -using System.Xml; -using System.Xml.Linq; -using mRemoteNG.Config.Serializers; -using mRemoteNG.Config.Serializers.Xml; +using mRemoteNG.Config.Serializers.Xml; using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Security; @@ -10,10 +6,13 @@ using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; using NUnit.Framework; +using System.Linq; +using System.Xml; +using System.Xml.Linq; namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml { - public class XmlConnectionsSerializerTests + public class XmlConnectionsSerializerTests { private XmlConnectionsSerializer _serializer; private ConnectionTreeModel _connectionTreeModel; @@ -25,7 +24,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml { _connectionTreeModel = SetupConnectionTreeModel(); _cryptographyProvider = new AeadCryptographyProvider(); - var connectionNodeSerializer = new XmlConnectionNodeSerializer26( + var connectionNodeSerializer = new XmlConnectionNodeSerializer27( _cryptographyProvider, _connectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString(), new SaveFilter()); @@ -59,7 +58,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml [TestCase("InheritAutomaticResize", "false")] public void SerializerRespectsSaveFilterSettings(string attributeName, string expectedValue) { - var connectionNodeSerializer = new XmlConnectionNodeSerializer26( + var connectionNodeSerializer = new XmlConnectionNodeSerializer27( _cryptographyProvider, _connectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString(), new SaveFilter(true)); diff --git a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlRootNodeSerializerTests.cs b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlRootNodeSerializerTests.cs index 8a04af9d2..8d81b6165 100644 --- a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlRootNodeSerializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlRootNodeSerializerTests.cs @@ -1,13 +1,12 @@ -using System; -using System.Collections; -using System.Xml.Linq; -using mRemoteNG.Config.Serializers; -using mRemoteNG.Config.Serializers.Xml; +using mRemoteNG.Config.Serializers.Xml; using mRemoteNG.Security; using mRemoteNG.Security.Factories; using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Tree.Root; using NUnit.Framework; +using System; +using System.Collections; +using System.Xml.Linq; namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml { @@ -16,6 +15,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml private XmlRootNodeSerializer _rootNodeSerializer; private ICryptographyProvider _cryptographyProvider; private RootNodeInfo _rootNodeInfo; + private Version _version; [SetUp] public void Setup() @@ -23,19 +23,20 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml _rootNodeSerializer = new XmlRootNodeSerializer(); _cryptographyProvider = new AeadCryptographyProvider(); _rootNodeInfo = new RootNodeInfo(RootNodeType.Connection); + _version = new Version(99, 1); } [Test] public void RootElementNamedConnections() { - var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider); + var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider, _version); Assert.That(element.Name.LocalName, Is.EqualTo("Connections")); } [Test] public void RootNodeInfoNameSerialized() { - var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider); + var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider, _version); var attributeValue = element.Attribute(XName.Get("Name"))?.Value; Assert.That(attributeValue, Is.EqualTo("Connections")); } @@ -44,7 +45,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml public void EncryptionEngineSerialized(BlockCipherEngines engine, BlockCipherModes mode) { var cryptoProvider = new CryptoProviderFactory(engine, mode).Build(); - var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, cryptoProvider); + var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, cryptoProvider, _version); var attributeValue = element.Attribute(XName.Get("EncryptionEngine"))?.Value; Assert.That(attributeValue, Is.EqualTo(engine.ToString())); } @@ -53,7 +54,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml public void EncryptionModeSerialized(BlockCipherEngines engine, BlockCipherModes mode) { var cryptoProvider = new CryptoProviderFactory(engine, mode).Build(); - var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, cryptoProvider); + var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, cryptoProvider, _version); var attributeValue = element.Attribute(XName.Get("BlockCipherMode"))?.Value; Assert.That(attributeValue, Is.EqualTo(mode.ToString())); } @@ -65,7 +66,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml public void KdfIterationsSerialized(int iterations) { _cryptographyProvider.KeyDerivationIterations = iterations; - var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider); + var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider, _version); var attributeValue = element.Attribute(XName.Get("KdfIterations"))?.Value; Assert.That(attributeValue, Is.EqualTo(iterations.ToString())); } @@ -74,7 +75,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml [TestCase(false)] public void FullFileEncryptionFlagSerialized(bool fullFileEncryption) { - var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider, fullFileEncryption); + var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider, _version, fullFileEncryption); var attributeValue = element.Attribute(XName.Get("FullFileEncryption"))?.Value; Assert.That(bool.Parse(attributeValue), Is.EqualTo(fullFileEncryption)); } @@ -86,7 +87,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml public void ProtectedStringSerialized(string customPassword, string expectedPlainText) { _rootNodeInfo.PasswordString = customPassword; - var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider); + var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider, _version); var attributeValue = element.Attribute(XName.Get("Protected"))?.Value; var attributeValuePlainText = _cryptographyProvider.Decrypt(attributeValue, _rootNodeInfo.PasswordString.ConvertToSecureString()); Assert.That(attributeValuePlainText, Is.EqualTo(expectedPlainText)); @@ -95,10 +96,10 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml [Test] public void ConfVersionSerialized() { - var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider); + var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider, _version); var attributeValue = element.Attribute(XName.Get("ConfVersion"))?.Value ?? ""; - var versionAsNumber = double.Parse(attributeValue); - Assert.That(versionAsNumber, Is.GreaterThan(0)); + var confVersion = Version.Parse(attributeValue); + Assert.That(confVersion, Is.EqualTo(_version)); } private class TestCaseSources diff --git a/mRemoteNGTests/Config/Serializers/CredentialSerializers/XmlCredentialSerializerTests.cs b/mRemoteNGTests/Config/Serializers/CredentialSerializers/XmlCredentialSerializerTests.cs index e916f65a0..a22646a45 100644 --- a/mRemoteNGTests/Config/Serializers/CredentialSerializers/XmlCredentialSerializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/CredentialSerializers/XmlCredentialSerializerTests.cs @@ -1,9 +1,10 @@ -using System.Linq; -using System.Xml.Linq; -using mRemoteNG.Config.Serializers.CredentialSerializer; +using mRemoteNG.Config.Serializers.CredentialSerializer; using mRemoteNG.Credential; using mRemoteNG.Security; using NUnit.Framework; +using System; +using System.Linq; +using System.Xml.Linq; namespace mRemoteNGTests.Config.Serializers.CredentialSerializers { @@ -41,7 +42,8 @@ namespace mRemoteNGTests.Config.Serializers.CredentialSerializers { var serialized = _serializer.Serialize(new[] { _cred1 }); var xdoc = XDocument.Parse(serialized); - Assert.That(xdoc.Root?.Attribute("SchemaVersion")?.Value, Is.EqualTo(_serializer.SchemaVersion)); + var version = Version.Parse(xdoc.Root?.Attribute("SchemaVersion")?.Value ?? ""); + Assert.That(version, Is.EqualTo(_serializer.Version)); } } } \ No newline at end of file diff --git a/mRemoteNGTests/Config/Serializers/MiscSerializers/RemoteDesktopConnectionDeserializerTests.cs b/mRemoteNGTests/Config/Serializers/MiscSerializers/RemoteDesktopConnectionDeserializerTests.cs index 5eb9561f2..a9900317c 100644 --- a/mRemoteNGTests/Config/Serializers/MiscSerializers/RemoteDesktopConnectionDeserializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/MiscSerializers/RemoteDesktopConnectionDeserializerTests.cs @@ -1,10 +1,10 @@ -using System.Linq; -using mRemoteNG.Config.Serializers; +using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol.RDP; using mRemoteNG.Tree; using mRemoteNGTests.Properties; using NUnit.Framework; +using System.Linq; namespace mRemoteNGTests.Config.Serializers.MiscSerializers { @@ -17,6 +17,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers private const string ExpectedUserName = "myusernamehere"; private const string ExpectedDomain = "myspecialdomain"; private const string ExpectedGatewayHostname = "gatewayhostname.domain.com"; + private const string ExpectedLoadBalanceInfo = "tsv://MS Terminal Services Plugin.1.RDS-NAME"; private const int ExpectedPort = 9933; private const RdpProtocol.RDPColors ExpectedColors = RdpProtocol.RDPColors.Colors24Bit; private const bool ExpectedBitmapCaching = false; @@ -166,6 +167,13 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers Assert.That(connectionInfo.RedirectSound, Is.EqualTo(ExpectedSoundRedirection)); } + [Test] + public void LoadBalanceInfoImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.LoadBalanceInfo, Is.EqualTo(ExpectedLoadBalanceInfo)); + } + //[Test] //public void GatewayHostnameImportedCorrectly() //{ diff --git a/mRemoteNGTests/IntegrationTests/XmlCredentialSerializerLifeCycleTests.cs b/mRemoteNGTests/IntegrationTests/XmlCredentialSerializerLifeCycleTests.cs index 2fffc446b..6f55a8231 100644 --- a/mRemoteNGTests/IntegrationTests/XmlCredentialSerializerLifeCycleTests.cs +++ b/mRemoteNGTests/IntegrationTests/XmlCredentialSerializerLifeCycleTests.cs @@ -1,14 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security; -using mRemoteNG.Config.Serializers; +using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers.CredentialSerializer; using mRemoteNG.Credential; using mRemoteNG.Security; using mRemoteNG.Security.Factories; using NSubstitute; using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; namespace mRemoteNGTests.IntegrationTests { diff --git a/mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs b/mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs index 4bcb698d9..6975b9750 100644 --- a/mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs +++ b/mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs @@ -1,20 +1,20 @@ -using System; -using System.Linq; -using System.Xml.Linq; -using mRemoteNG.Config.Serializers; -using mRemoteNG.Config.Serializers.Xml; +using mRemoteNG.Config.Serializers.Xml; using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Security; using mRemoteNG.Security.Factories; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; +using mRemoteNGTests.TestHelpers; using NUnit.Framework; +using System; +using System.Linq; +using System.Text; namespace mRemoteNGTests.IntegrationTests { - public class XmlSerializationLifeCycleTests + public class XmlSerializationLifeCycleTests { private XmlConnectionsSerializer _serializer; private XmlConnectionsDeserializer _deserializer; @@ -26,7 +26,7 @@ namespace mRemoteNGTests.IntegrationTests { _originalModel = SetupConnectionTreeModel(); var cryptoProvider = _cryptoFactory.Build(); - var nodeSerializer = new XmlConnectionNodeSerializer26( + var nodeSerializer = new XmlConnectionNodeSerializer27( cryptoProvider, _originalModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString(), new SaveFilter()); @@ -77,7 +77,7 @@ namespace mRemoteNGTests.IntegrationTests { var cryptoProvider = _cryptoFactory.Build(); cryptoProvider.KeyDerivationIterations = 5000; - var nodeSerializer = new XmlConnectionNodeSerializer26( + var nodeSerializer = new XmlConnectionNodeSerializer27( cryptoProvider, _originalModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString(), new SaveFilter()); @@ -103,6 +103,60 @@ namespace mRemoteNGTests.IntegrationTests Assert.That(Guid.TryParse(deserializedConnectionInfo.ConstantID, out var guid)); } + [Test] + public void AllPropertiesCorrectWhenSerializingThenDeserializing() + { + var originalConnectionInfo = new ConnectionInfo().RandomizeValues(); + originalConnectionInfo.Inheritance.TurnOffInheritanceCompletely(); + var serializedContent = _serializer.Serialize(originalConnectionInfo); + var deserializedModel = _deserializer.Deserialize(serializedContent); + var deserializedConnectionInfo = deserializedModel + .GetRecursiveChildList() + .First(info => info.GetTreeNodeType() == TreeNodeType.Connection); + + var sb = new StringBuilder(); + foreach (var property in originalConnectionInfo.GetSerializableProperties()) + { + var originalValue = property.GetValue(originalConnectionInfo); + var deserializedValue = property.GetValue(deserializedConnectionInfo); + if (originalValue.Equals(deserializedValue)) + continue; + + sb.AppendLine($"Property: {property.Name}"); + } + + Assert.That(sb.Length, Is.EqualTo(0), "Some properties are not being serialized properly:\n" + sb); + } + + [Test] + public void AllInheritanceCorrectWhenSerializingThenDeserializing() + { + var originalConnectionInfo = new ConnectionInfo(); + originalConnectionInfo.Inheritance.ToggleAllBooleanProperties(excludeProperties: nameof(ConnectionInfoInheritance.EverythingInherited)); + var container = new ContainerInfo(); + container.AddChild(originalConnectionInfo); + + var serializedContent = _serializer.Serialize(container); + var deserializedModel = _deserializer.Deserialize(serializedContent); + var deserializedConnectionInfo = deserializedModel + .GetRecursiveChildList() + .First(info => info.GetTreeNodeType() == TreeNodeType.Connection); + + var sb = new StringBuilder(); + foreach (var property in originalConnectionInfo.Inheritance.GetProperties()) + { + var originalValue = property.GetValue(originalConnectionInfo.Inheritance); + var deserializedValue = property.GetValue(deserializedConnectionInfo.Inheritance); + + if (originalValue.Equals(deserializedValue)) + continue; + + sb.AppendLine($"Property: Inheritance.{property.Name}"); + } + + Assert.That(sb.Length, Is.EqualTo(0), "Some properties are not being serialized properly:\n" + sb); + } + private ConnectionTreeModel SetupConnectionTreeModel() { diff --git a/mRemoteNGTests/Properties/Resources.Designer.cs b/mRemoteNGTests/Properties/Resources.Designer.cs index 2f7599682..48157bac3 100644 --- a/mRemoteNGTests/Properties/Resources.Designer.cs +++ b/mRemoteNGTests/Properties/Resources.Designer.cs @@ -329,6 +329,16 @@ namespace mRemoteNGTests.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap TestImage { + get { + object obj = ResourceManager.GetObject("TestImage", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized string similar to Version: 1.75.6164.27544 ///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi diff --git a/mRemoteNGTests/Properties/Resources.resx b/mRemoteNGTests/Properties/Resources.resx index 902712d20..93d4db1fa 100644 --- a/mRemoteNGTests/Properties/Resources.resx +++ b/mRemoteNGTests/Properties/Resources.resx @@ -154,6 +154,9 @@ ..\Resources\dev-update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\TestImage.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\test_puttyConnectionManager_database.dat;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16 diff --git a/mRemoteNGTests/Resources/TestImage.bmp b/mRemoteNGTests/Resources/TestImage.bmp new file mode 100644 index 000000000..745429ef2 Binary files /dev/null and b/mRemoteNGTests/Resources/TestImage.bmp differ diff --git a/mRemoteNGTests/Resources/test_remotedesktopconnection.rdp b/mRemoteNGTests/Resources/test_remotedesktopconnection.rdp index f144f9718..237a6ba8d 100644 Binary files a/mRemoteNGTests/Resources/test_remotedesktopconnection.rdp and b/mRemoteNGTests/Resources/test_remotedesktopconnection.rdp differ diff --git a/mRemoteNGTests/Security/AeadCryptographyProviderTests.cs b/mRemoteNGTests/Security/AeadCryptographyProviderTests.cs index 065f48d17..b74a09405 100644 --- a/mRemoteNGTests/Security/AeadCryptographyProviderTests.cs +++ b/mRemoteNGTests/Security/AeadCryptographyProviderTests.cs @@ -1,11 +1,11 @@ -using System; -using System.Collections; -using System.Security; -using mRemoteNG.Security; +using mRemoteNG.Security; using mRemoteNG.Security.Factories; using mRemoteNG.Security.SymmetricEncryption; using NUnit.Framework; using NUnit.Framework.Constraints; +using System; +using System.Collections; +using System.Security; namespace mRemoteNGTests.Security @@ -97,6 +97,12 @@ namespace mRemoteNGTests.Security Assert.That(cryptoProvider.CipherMode, Is.EqualTo(mode)); } + [Test] + public void ProvidingEmptyEncryptionKeyThrowsException() + { + Assert.Throws(() => _cryptographyProvider.Encrypt(_plainText, new SecureString())); + } + private class TestCaseSources { diff --git a/mRemoteNGTests/TestHelpers/Randomizer.cs b/mRemoteNGTests/TestHelpers/Randomizer.cs new file mode 100644 index 000000000..7286dee3b --- /dev/null +++ b/mRemoteNGTests/TestHelpers/Randomizer.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Enum = System.Enum; + +namespace mRemoteNGTests.TestHelpers +{ + internal static class Randomizer + { + private static readonly Random Random = new Random(); + + internal static string RandomString(params string[] excludedStrings) + { + return GetNonExcludedValue(() => Guid.NewGuid().ToString("N"), excludedStrings); + } + + internal static bool RandomBool(bool? excludedBool = null) + { + if (excludedBool.HasValue) + return !excludedBool.Value; + + return Random.Next() % 2 == 0; + } + + internal static int RandomInt(int minValue = int.MinValue, int maxValue = int.MaxValue, params int[] excludeInts) + { + return GetNonExcludedValue(() => Random.Next(minValue, maxValue), excludeInts); + } + + internal static DateTime RandomDateTime(params DateTime[] excludeTimes) + { + var date = GetNonExcludedValue(() => + new DateTime( + RandomInt(minValue: 1990, maxValue: 2019), + RandomInt(minValue: 1, maxValue: 13), + RandomInt(minValue: 1, maxValue: 29), + RandomInt(minValue: 0, maxValue: 24), + RandomInt(minValue: 0, maxValue: 60), + RandomInt(minValue: 0, maxValue: 60)), + excludeTimes); + + return date; + } + + internal static T RandomEnum(params object[] excludeValues) where T : struct, IConvertible + { + if (!typeof(T).IsEnum) + throw new ArgumentException("T must be an enum"); + + return (T)RandomEnum(typeof(T), excludeValues); + } + + internal static object RandomEnum(Type enumType, params object[] excludeValues) + { + if (!enumType.IsEnum) + throw new ArgumentException("enumType must be an enum"); + + var values = Enum.GetValues(enumType); + return GetNonExcludedValue(() => values.GetValue(Random.Next(values.Length)), excludeValues); + } + + private static T GetNonExcludedValue(Func builder, params object[] excludedValues) + { + do + { + var value = builder(); + if (!excludedValues.Contains(value)) + return value; + } while (true); + } + + /// + /// Randomizes the primitive-type settable properties of the given object. + /// Returns the same object instance to enable fluent method calls. It will + /// never choose the value that the property current holds. For booleans, this + /// means they will always be toggled rather than truly randomized. + /// + internal static T RandomizeValues(this T con) + where T : class + { + var opByType = new Dictionary> + { + { typeof(int), (p, c) => p.SetValue(c, RandomInt(minValue: 0, excludeInts:(int)p.GetValue(c))) }, + { typeof(bool), (p, c) => p.SetValue(c, !(bool)p.GetValue(c)) }, + { typeof(string), (p, c) => p.SetValue(c, RandomString((string)p.GetValue(c))) }, + { typeof(DateTime), (p, c) => p.SetValue(c, RandomDateTime((DateTime)p.GetValue(c))) }, + { typeof(Enum), (p, c) => p.SetValue(c, RandomEnum(p.PropertyType, p.GetValue(c))) }, + }; + + var settableProperties = con + .GetType() + .GetProperties() + .Where(p => p.GetSetMethod() != null); + + foreach (var property in settableProperties) + { + if (opByType.TryGetValue(property.PropertyType, out var mutator)) + mutator(property, con); + + else if (opByType.TryGetValue(property.PropertyType.BaseType, out var mutator2)) + mutator2(property, con); + } + + return con; + } + + /// + /// Toggles all settable properties + /// on the given object. + /// + /// + /// + /// + /// + internal static T ToggleAllBooleanProperties(this T obj, params string[] excludeProperties) + where T : class + { + var settableBooleanProperties = obj + .GetType() + .GetProperties() + .Where(p => + p.GetSetMethod() != null && + p.PropertyType == typeof(bool) && + !excludeProperties.Contains(p.Name)); + + foreach (var property in settableBooleanProperties) + { + var currentValue = (bool)property.GetValue(obj); + property.SetValue(obj, !currentValue); + } + + return obj; + } + } +} diff --git a/mRemoteNGTests/UI/Controls/SecureTextBoxTestForm.Designer.cs b/mRemoteNGTests/UI/Controls/SecureTextBoxTestForm.Designer.cs index abe3ec476..7e61eac6e 100644 --- a/mRemoteNGTests/UI/Controls/SecureTextBoxTestForm.Designer.cs +++ b/mRemoteNGTests/UI/Controls/SecureTextBoxTestForm.Designer.cs @@ -43,8 +43,8 @@ namespace mRemoteNGTests.UI.Controls // // SecureTextBoxTestForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.ClientSize = new System.Drawing.Size(256, 45); this.Controls.Add(this.secureTextBox1); this.Name = "SecureTextBoxTestForm"; diff --git a/mRemoteNGTests/UI/Controls/TestForm.Designer.cs b/mRemoteNGTests/UI/Controls/TestForm.Designer.cs index 3a5a7b7a8..f4341e91b 100644 --- a/mRemoteNGTests/UI/Controls/TestForm.Designer.cs +++ b/mRemoteNGTests/UI/Controls/TestForm.Designer.cs @@ -32,8 +32,8 @@ // // TestForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.ClientSize = new System.Drawing.Size(284, 262); this.Name = "TestForm"; this.Text = "TestForm"; diff --git a/mRemoteNGTests/UI/Controls/TextBoxExtensionsTestForm.Designer.cs b/mRemoteNGTests/UI/Controls/TextBoxExtensionsTestForm.Designer.cs index 346b31bf3..f97a3dfdf 100644 --- a/mRemoteNGTests/UI/Controls/TextBoxExtensionsTestForm.Designer.cs +++ b/mRemoteNGTests/UI/Controls/TextBoxExtensionsTestForm.Designer.cs @@ -40,8 +40,8 @@ // // TextBoxExtensionsTestForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.ClientSize = new System.Drawing.Size(220, 48); this.Controls.Add(this.textBox1); this.Name = "TextBoxExtensionsTestForm"; diff --git a/mRemoteNGTests/UI/DisplayPropertiesTests.cs b/mRemoteNGTests/UI/DisplayPropertiesTests.cs new file mode 100644 index 000000000..124fb0937 --- /dev/null +++ b/mRemoteNGTests/UI/DisplayPropertiesTests.cs @@ -0,0 +1,123 @@ +using System; +using System.Drawing; +using mRemoteNG.UI; +using mRemoteNG.UI.GraphicsUtilities; +using mRemoteNGTests.Properties; +using NSubstitute; +using NUnit.Framework; + +namespace mRemoteNGTests.UI +{ + public class DisplayPropertiesTests + { + [Test] + public void ScaleHeightReturnsValueScaledByHeightScalingFactor() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = 10; + var scaledValue = sut.ScaleHeight(initialValue); + + Assert.That(scaledValue, Is.EqualTo(sut.ResolutionScalingFactor.Height * initialValue)); + } + + [Test] + public void ScaleWidthReturnsValueScaledByWidthScalingFactor() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = 10; + var scaledValue = sut.ScaleWidth(initialValue); + + Assert.That(scaledValue, Is.EqualTo(sut.ResolutionScalingFactor.Width * initialValue)); + } + + [Test] + public void ScaleSizeReturnsNewSizeWithCorrectlyScaledHeight() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = new Size(12, 16); + var scaledValue = sut.ScaleSize(initialValue); + + Assert.That(scaledValue.Height, Is.EqualTo(sut.ResolutionScalingFactor.Height * initialValue.Height)); + } + + [Test] + public void ScaleSizeReturnsNewSizeWithCorrectlyScaledWidth() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = new Size(12, 16); + var scaledValue = sut.ScaleSize(initialValue); + + Assert.That(scaledValue.Width, Is.EqualTo(sut.ResolutionScalingFactor.Width * initialValue.Width)); + } + + [Test] + public void ScaleImageReturnsNewImageWithCorrectlyScaledHeight() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = Resources.TestImage; + var scaledValue = sut.ScaleImage(initialValue); + + Assert.That(scaledValue.Height, Is.EqualTo(sut.ResolutionScalingFactor.Height * initialValue.Height)); + } + + [Test] + public void ScaleImageReturnsNewImageWithCorrectlyScaledWidth() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = Resources.TestImage; + var scaledValue = sut.ScaleImage(initialValue); + + Assert.That(scaledValue.Width, Is.EqualTo(sut.ResolutionScalingFactor.Width * initialValue.Width)); + } + + [Test] + public void ResolutionScalingFactorAlwaysReturnsMostUpdatedValue() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 4)); + var sut = new DisplayProperties(graphics); + + graphics.GetResolutionScalingFactor().Returns(new SizeF(8, 8)); + Assert.That(sut.ResolutionScalingFactor.Width, Is.EqualTo(8)); + } + + [Test] + public void AttemptingToScaleANullImageWillThrowAnException() + { + var sut = new DisplayProperties(Substitute.For()); + Assert.Throws(() => sut.ScaleImage((Image)null)); + } + + [Test] + public void AttemptingToScaleANullIconWillThrowAnException() + { + var sut = new DisplayProperties(Substitute.For()); + Assert.Throws(() => sut.ScaleImage((Icon)null)); + } + + [Test] + public void AttemptingToCallConstructorWithNullGraphicsProviderWillThrow() + { + // ReSharper disable once ObjectCreationAsStatement + Assert.Throws(() => new DisplayProperties(null)); + } + } +} diff --git a/mRemoteNGTests/UI/Forms/OptionsFormSetupAndTeardown.cs b/mRemoteNGTests/UI/Forms/OptionsFormSetupAndTeardown.cs index 4a3ae7dc8..bbbeda0bd 100644 --- a/mRemoteNGTests/UI/Forms/OptionsFormSetupAndTeardown.cs +++ b/mRemoteNGTests/UI/Forms/OptionsFormSetupAndTeardown.cs @@ -5,7 +5,7 @@ namespace mRemoteNGTests.UI.Forms { public class OptionsFormSetupAndTeardown { - protected frmOptions _optionsForm; + protected FrmOptions _optionsForm; [OneTimeSetUp] public void OnetimeSetup() @@ -15,7 +15,7 @@ namespace mRemoteNGTests.UI.Forms [SetUp] public void Setup() { - _optionsForm = new frmOptions(); + _optionsForm = new FrmOptions(); _optionsForm.Show(); } diff --git a/mRemoteNGTests/app.config b/mRemoteNGTests/app.config index 3b40bcaad..9352c5e85 100644 --- a/mRemoteNGTests/app.config +++ b/mRemoteNGTests/app.config @@ -4,7 +4,7 @@ - + diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index bf8250062..6d36c97a3 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -88,8 +88,8 @@ - - ..\packages\DockPanelSuite.2.16.1\lib\net40\WeifenLuo.WinFormsUI.Docking.dll + + ..\packages\DockPanelSuite.3.0.6\lib\net40\WeifenLuo.WinFormsUI.Docking.dll @@ -174,6 +174,7 @@ + @@ -230,6 +231,7 @@ TextBoxExtensionsTestForm.cs + @@ -294,6 +296,7 @@ + diff --git a/mRemoteNGTests/packages.config b/mRemoteNGTests/packages.config index 2e6c2f63e..7906857fa 100644 --- a/mRemoteNGTests/packages.config +++ b/mRemoteNGTests/packages.config @@ -2,7 +2,7 @@ - + diff --git a/mRemoteV1.sln b/mRemoteV1.sln index 5466c8d33..b25b427f0 100644 --- a/mRemoteV1.sln +++ b/mRemoteV1.sln @@ -73,6 +73,7 @@ Global {1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.ActiveCfg = Release|x86 {1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.Build.0 = Release|x86 {5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.ActiveCfg = Debug|x86 + {5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.Build.0 = Debug|x86 {5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|x86.ActiveCfg = Debug|x86 {5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|Any CPU.ActiveCfg = Debug|x86 {5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x86.ActiveCfg = Debug|x86 @@ -87,6 +88,7 @@ Global {5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|Any CPU.Build.0 = Release|x86 {5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|x86.ActiveCfg = Release|x86 {F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86 + {F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|Any CPU.Build.0 = Debug Portable|x86 {F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|x86.ActiveCfg = Debug Portable|x86 {F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|Any CPU.ActiveCfg = Debug|x86 {F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x86.ActiveCfg = Debug|x86 diff --git a/mRemoteV1/App/Info/GeneralAppInfo.cs b/mRemoteV1/App/Info/GeneralAppInfo.cs index 727a33463..179773898 100644 --- a/mRemoteV1/App/Info/GeneralAppInfo.cs +++ b/mRemoteV1/App/Info/GeneralAppInfo.cs @@ -11,10 +11,10 @@ namespace mRemoteNG.App.Info { public static class GeneralAppInfo { - public const string UrlHome = "http://www.mremoteng.org/"; - public const string UrlDonate = "http://donate.mremoteng.org/"; + public const string UrlHome = "https://www.mremoteng.org/"; + public const string UrlDonate = "https://mremoteng.org/contribute/"; public const string UrlForum = "https://www.reddit.com/r/mRemoteNG/"; - public const string UrlBugs = "http://bugs.mremoteng.org/"; + public const string UrlBugs = "https://bugs.mremoteng.org/"; public static string ApplicationVersion = Application.ProductVersion; public static readonly string ProductName = Application.ProductName; public static readonly string Copyright = ((AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyCopyrightAttribute), false)).Copyright; diff --git a/mRemoteV1/App/ProgramRoot.cs b/mRemoteV1/App/ProgramRoot.cs index 23ac6a1f7..b2fcd4a73 100644 --- a/mRemoteV1/App/ProgramRoot.cs +++ b/mRemoteV1/App/ProgramRoot.cs @@ -24,8 +24,11 @@ namespace mRemoteNG.App private static void StartApplication() { + CatchAllUnhandledExceptions(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); + FrmSplashScreen frmSplashScreen = FrmSplashScreen.getInstance(); + frmSplashScreen.Show(); Application.Run(FrmMain.Default); } @@ -69,5 +72,24 @@ namespace mRemoteNG.App } return windowHandle; } + + private static void CatchAllUnhandledExceptions() + { + Application.ThreadException += ApplicationOnThreadException; + Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); + AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; + } + + private static void ApplicationOnThreadException(object sender, ThreadExceptionEventArgs e) + { + var window = new UnhandledExceptionWindow(e.Exception, false); + window.ShowDialog(FrmMain.Default); + } + + private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) + { + var window = new UnhandledExceptionWindow(e.ExceptionObject as Exception, e.IsTerminating); + window.ShowDialog(FrmMain.Default); + } } } \ No newline at end of file diff --git a/mRemoteV1/App/Runtime.cs b/mRemoteV1/App/Runtime.cs index f637a0013..0481796b9 100644 --- a/mRemoteV1/App/Runtime.cs +++ b/mRemoteV1/App/Runtime.cs @@ -32,6 +32,11 @@ namespace mRemoteNG.App } } + /// + /// Feature flag to enable the credential manager feature + /// + public static bool UseCredentialManager => false; + public static WindowList WindowList { get; set; } public static MessageCollector MessageCollector { get; } = new MessageCollector(); public static NotificationAreaIcon NotificationAreaIcon { get; set; } @@ -96,6 +101,8 @@ namespace mRemoteNG.App } catch (Exception ex) { + FrmSplashScreen.getInstance().Close(); + if (Settings.Default.UseSQLServer) { MessageCollector.AddExceptionMessage(Language.strLoadFromSqlFailed, ex); diff --git a/mRemoteV1/App/SupportedCultures.cs b/mRemoteV1/App/SupportedCultures.cs index 142c53af1..37ebc34a9 100644 --- a/mRemoteV1/App/SupportedCultures.cs +++ b/mRemoteV1/App/SupportedCultures.cs @@ -2,12 +2,14 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; +using System.Runtime.Serialization; + // ReSharper disable ArrangeAccessorOwnerBody namespace mRemoteNG.App { [Serializable] - public class SupportedCultures : Dictionary + public sealed class SupportedCultures : Dictionary { private static SupportedCultures _Instance; @@ -32,7 +34,13 @@ namespace mRemoteNG.App } } } - + + // fix CA2229 - https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2229-implement-serialization-constructors?view=vs-2017 + private SupportedCultures(SerializationInfo info, StreamingContext context) + { + throw new NotImplementedException(); + } + public static bool IsNameSupported(string CultureName) { return SingletonInstance.ContainsKey(CultureName); diff --git a/mRemoteV1/App/Windows.cs b/mRemoteV1/App/Windows.cs index 3ffc26a4c..6304b75b6 100644 --- a/mRemoteV1/App/Windows.cs +++ b/mRemoteV1/App/Windows.cs @@ -13,6 +13,7 @@ namespace mRemoteNG.App private static HelpWindow _helpForm; private static ExternalToolsWindow _externalappsForm; private static PortScanWindow _portscanForm; + private static ScreenshotManagerWindow _screenshotmanagerForm; private static UltraVNCWindow _ultravncscForm; private static ComponentsCheckWindow _componentscheckForm; private static ConnectionTreeWindow _treeForm; @@ -50,7 +51,7 @@ namespace mRemoteNG.App _adimportForm.Show(dockPanel); break; case WindowType.Options: - using (var optionsForm = new frmOptions()) + using (var optionsForm = new FrmOptions()) { optionsForm.ShowDialog(dockPanel); } @@ -79,6 +80,10 @@ namespace mRemoteNG.App _portscanForm = new PortScanWindow(); _portscanForm.Show(dockPanel); break; + case WindowType.ScreenshotManager: + _screenshotmanagerForm = new ScreenshotManagerWindow(); + _screenshotmanagerForm.Show(dockPanel); + break; case WindowType.UltraVNCSC: if (_ultravncscForm == null || _ultravncscForm.IsDisposed) _ultravncscForm = new UltraVNCWindow(); diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Csv/CsvConnectionsSerializerMremotengFormat.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Csv/CsvConnectionsSerializerMremotengFormat.cs index e8ecdd602..bd0a6f296 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/Csv/CsvConnectionsSerializerMremotengFormat.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Csv/CsvConnectionsSerializerMremotengFormat.cs @@ -1,21 +1,23 @@ -using System; -using System.Linq; -using System.Text; -using mRemoteNG.Connection; +using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Credential; using mRemoteNG.Security; using mRemoteNG.Tools; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; +using System; +using System.Linq; +using System.Text; namespace mRemoteNG.Config.Serializers.Csv { - public class CsvConnectionsSerializerMremotengFormat : ISerializer + public class CsvConnectionsSerializerMremotengFormat : ISerializer { private readonly SaveFilter _saveFilter; private readonly ICredentialRepositoryList _credentialRepositoryList; + public Version Version { get; } = new Version(2, 7); + public CsvConnectionsSerializerMremotengFormat(SaveFilter saveFilter, ICredentialRepositoryList credentialRepositoryList) { saveFilter.ThrowIfNull(nameof(saveFilter)); diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs index 1f93a773d..91f8a8f35 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs @@ -21,6 +21,8 @@ namespace mRemoteNG.Config.Serializers.MsSql private readonly SaveFilter _saveFilter; private int _currentNodeIndex; + public Version Version { get; } = new Version(2, 7); + public DataTableSerializer(SaveFilter saveFilter, ICryptographyProvider cryptographyProvider, SecureString encryptionKey) { _saveFilter = saveFilter.ThrowIfNull(nameof(saveFilter)); diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/LocalConnectionPropertiesXmlSerializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/LocalConnectionPropertiesXmlSerializer.cs index 78a82371c..da76a8dc6 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/LocalConnectionPropertiesXmlSerializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/LocalConnectionPropertiesXmlSerializer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -11,6 +12,8 @@ namespace mRemoteNG.Config.Serializers.MsSql ISerializer, string>, IDeserializer> { + public Version Version { get; } = new Version(1, 0); + public string Serialize(IEnumerable models) { var localConnections = models diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionNodeSerializer26.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionNodeSerializer26.cs index 15b012d24..f935ae418 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionNodeSerializer26.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionNodeSerializer26.cs @@ -1,19 +1,21 @@ -using System; -using System.Security; -using System.Xml.Linq; -using mRemoteNG.Connection; +using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Security; +using System; +using System.Security; +using System.Xml.Linq; namespace mRemoteNG.Config.Serializers.Xml { - // ReSharper disable once InconsistentNaming - public class XmlConnectionNodeSerializer26 : ISerializer + // ReSharper disable once InconsistentNaming + public class XmlConnectionNodeSerializer26 : ISerializer { private readonly ICryptographyProvider _cryptographyProvider; private readonly SecureString _encryptionKey; private readonly SaveFilter _saveFilter; + public Version Version { get; } = new Version(2, 6); + public XmlConnectionNodeSerializer26(ICryptographyProvider cryptographyProvider, SecureString encryptionKey, SaveFilter saveFilter) { if (cryptographyProvider == null) @@ -84,6 +86,7 @@ namespace mRemoteNG.Config.Serializers.Xml element.Add(new XAttribute("RedirectDiskDrives", connectionInfo.RedirectDiskDrives.ToString().ToLowerInvariant())); element.Add(new XAttribute("RedirectPorts", connectionInfo.RedirectPorts.ToString().ToLowerInvariant())); element.Add(new XAttribute("RedirectPrinters", connectionInfo.RedirectPrinters.ToString().ToLowerInvariant())); + element.Add(new XAttribute("RedirectClipboard", connectionInfo.RedirectClipboard.ToString().ToLowerInvariant())); element.Add(new XAttribute("RedirectSmartCards", connectionInfo.RedirectSmartCards.ToString().ToLowerInvariant())); element.Add(new XAttribute("RedirectSound", connectionInfo.RedirectSound.ToString())); element.Add(new XAttribute("SoundQuality", connectionInfo.SoundQuality.ToString())); diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionNodeSerializer27.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionNodeSerializer27.cs index 29c124929..1dac76ea0 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionNodeSerializer27.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionNodeSerializer27.cs @@ -1,19 +1,22 @@ -using System; -using System.Security; -using System.Xml.Linq; +using mRemoteNG.App; using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Security; +using System; +using System.Security; +using System.Xml.Linq; namespace mRemoteNG.Config.Serializers.Xml { - // ReSharper disable once InconsistentNaming - public class XmlConnectionNodeSerializer27 : ISerializer + // ReSharper disable once InconsistentNaming + public class XmlConnectionNodeSerializer27 : ISerializer { private readonly ICryptographyProvider _cryptographyProvider; private readonly SecureString _encryptionKey; private readonly SaveFilter _saveFilter; + public Version Version { get; } = new Version(2, 7); + public XmlConnectionNodeSerializer27(ICryptographyProvider cryptographyProvider, SecureString encryptionKey, SaveFilter saveFilter) { if (cryptographyProvider == null) @@ -48,18 +51,21 @@ namespace mRemoteNG.Config.Serializers.Xml element.Add(new XAttribute("Panel", connectionInfo.Panel)); element.Add(new XAttribute("Id", connectionInfo.ConstantID)); - element.Add(_saveFilter.SaveUsername - ? new XAttribute("Username", connectionInfo.Username) - : new XAttribute("Username", "")); + if (!Runtime.UseCredentialManager) + { + element.Add(_saveFilter.SaveUsername + ? new XAttribute("Username", connectionInfo.Username) + : new XAttribute("Username", "")); - element.Add(_saveFilter.SaveDomain - ? new XAttribute("Domain", connectionInfo.Domain) - : new XAttribute("Domain", "")); + element.Add(_saveFilter.SaveDomain + ? new XAttribute("Domain", connectionInfo.Domain) + : new XAttribute("Domain", "")); - if (_saveFilter.SavePassword && !connectionInfo.Inheritance.Password) - element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey))); - else - element.Add(new XAttribute("Password", "")); + if (_saveFilter.SavePassword && !connectionInfo.Inheritance.Password) + element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey))); + else + element.Add(new XAttribute("Password", "")); + } element.Add(new XAttribute("Hostname", connectionInfo.Hostname)); element.Add(new XAttribute("Protocol", connectionInfo.Protocol)); diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs index bb590cef0..2ddf4532d 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs @@ -1,9 +1,4 @@ -using System; -using System.Globalization; -using System.Security; -using System.Windows.Forms; -using System.Xml; -using mRemoteNG.App; +using mRemoteNG.App; using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol; using mRemoteNG.Connection.Protocol.Http; @@ -18,6 +13,12 @@ using mRemoteNG.Tree; using mRemoteNG.Tree.Root; using mRemoteNG.UI.Forms; using mRemoteNG.UI.TaskDialog; +using System; +using System.Globalization; +using System.Security; +using System.Windows.Forms; +using System.Xml; +using mRemoteNG.Config.Serializers.ConnectionSerializers.Xml; namespace mRemoteNG.Config.Serializers.Xml { @@ -67,8 +68,8 @@ namespace mRemoteNG.Config.Serializers.Xml if (_confVersion >= 2.6) { - var fullFileEncryptionValue = rootXmlElement?.Attributes["FullFileEncryption"].Value ?? ""; - if (bool.Parse(fullFileEncryptionValue)) + var fullFileEncryptionValue = rootXmlElement.GetAttributeAsBool("FullFileEncryption"); + if (fullFileEncryptionValue) { var decryptedContent = _decryptor.Decrypt(rootXmlElement.InnerText); rootXmlElement.InnerXml = decryptedContent; @@ -139,14 +140,9 @@ namespace mRemoteNG.Config.Serializers.Xml { if (_confVersion >= 2.6) { - BlockCipherEngines engine; - Enum.TryParse(connectionsRootElement?.Attributes["EncryptionEngine"].Value, true, out engine); - - BlockCipherModes mode; - Enum.TryParse(connectionsRootElement?.Attributes["BlockCipherMode"].Value, true, out mode); - - int keyDerivationIterations; - int.TryParse(connectionsRootElement?.Attributes["KdfIterations"].Value, out keyDerivationIterations); + var engine = connectionsRootElement.GetAttributeAsEnum("EncryptionEngine"); + var mode = connectionsRootElement.GetAttributeAsEnum("BlockCipherMode"); + var keyDerivationIterations = connectionsRootElement.GetAttributeAsInt("KdfIterations"); _decryptor = new XmlConnectionsDecryptor(engine, mode, rootNodeInfo) { @@ -167,8 +163,7 @@ namespace mRemoteNG.Config.Serializers.Xml if (!parentXmlNode.HasChildNodes) return; foreach (XmlNode xmlNode in parentXmlNode.ChildNodes) { - var treeNodeTypeString = xmlNode.Attributes?["Type"].Value ?? "connection"; - var nodeType = (TreeNodeType)Enum.Parse(typeof(TreeNodeType), treeNodeTypeString, true); + var nodeType = xmlNode.GetAttributeAsEnum("Type", TreeNodeType.Connection); // ReSharper disable once SwitchStatementMissingSomeCases switch (nodeType) @@ -184,8 +179,7 @@ namespace mRemoteNG.Config.Serializers.Xml containerInfo.CopyFrom(GetConnectionInfoFromXml(xmlNode)); if (_confVersion >= 0.8) { - var expandedValue = xmlNode.Attributes?["Expanded"].Value ?? ""; - containerInfo.IsExpanded = bool.Parse(expandedValue); + containerInfo.IsExpanded = xmlNode.GetAttributeAsBool("Expanded"); } parentContainer.AddChild(containerInfo); @@ -203,9 +197,10 @@ namespace mRemoteNG.Config.Serializers.Xml private ConnectionInfo GetConnectionInfoFromXml(XmlNode xmlnode) { - if (xmlnode.Attributes == null) return null; + if (xmlnode?.Attributes == null) + return null; - var connectionId = xmlnode.Attributes["Id"]?.Value; + var connectionId = xmlnode.GetAttributeAsString("Id"); if (string.IsNullOrWhiteSpace(connectionId)) connectionId = Guid.NewGuid().ToString(); var connectionInfo = new ConnectionInfo(connectionId); @@ -214,26 +209,26 @@ namespace mRemoteNG.Config.Serializers.Xml { if (_confVersion >= 0.2) { - connectionInfo.Name = xmlnode.Attributes["Name"].Value; - connectionInfo.Description = xmlnode.Attributes["Descr"].Value; - connectionInfo.Hostname = xmlnode.Attributes["Hostname"].Value; - connectionInfo.DisplayWallpaper = bool.Parse(xmlnode.Attributes["DisplayWallpaper"].Value); - connectionInfo.DisplayThemes = bool.Parse(xmlnode.Attributes["DisplayThemes"].Value); - connectionInfo.CacheBitmaps = bool.Parse(xmlnode.Attributes["CacheBitmaps"].Value); + connectionInfo.Name = xmlnode.GetAttributeAsString("Name"); + connectionInfo.Description = xmlnode.GetAttributeAsString("Descr"); + connectionInfo.Hostname = xmlnode.GetAttributeAsString("Hostname"); + connectionInfo.DisplayWallpaper = xmlnode.GetAttributeAsBool("DisplayWallpaper"); + connectionInfo.DisplayThemes = xmlnode.GetAttributeAsBool("DisplayThemes"); + connectionInfo.CacheBitmaps = xmlnode.GetAttributeAsBool("CacheBitmaps"); if (_confVersion < 1.1) //1.0 - 0.1 { - connectionInfo.Resolution = Convert.ToBoolean(xmlnode.Attributes["Fullscreen"].Value) + connectionInfo.Resolution = xmlnode.GetAttributeAsBool("Fullscreen") ? RdpProtocol.RDPResolutions.Fullscreen : RdpProtocol.RDPResolutions.FitToWindow; } - if (_confVersion <= 2.6) // 0.2 - 2.6 + if (!Runtime.UseCredentialManager || _confVersion <= 2.6) // 0.2 - 2.6 { #pragma warning disable 618 - connectionInfo.Username = xmlnode.Attributes["Username"].Value; - connectionInfo.Password = _decryptor.Decrypt(xmlnode.Attributes["Password"].Value); - connectionInfo.Domain = xmlnode.Attributes["Domain"].Value; + connectionInfo.Username = xmlnode.GetAttributeAsString("Username"); + connectionInfo.Password = _decryptor.Decrypt(xmlnode.GetAttributeAsString("Password")); + connectionInfo.Domain = xmlnode.GetAttributeAsString("Domain"); #pragma warning restore 618 } } @@ -242,10 +237,10 @@ namespace mRemoteNG.Config.Serializers.Xml { if (_confVersion < 0.7) { - if (Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value)) + if (xmlnode.GetAttributeAsBool("UseVNC")) { connectionInfo.Protocol = ProtocolType.VNC; - connectionInfo.Port = Convert.ToInt32(xmlnode.Attributes["VNCPort"].Value); + connectionInfo.Port = xmlnode.GetAttributeAsInt("VNCPort"); } else { @@ -263,18 +258,18 @@ namespace mRemoteNG.Config.Serializers.Xml { if (_confVersion < 0.7) { - connectionInfo.Port = Convert.ToInt32(Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value) - ? xmlnode.Attributes["VNCPort"].Value - : xmlnode.Attributes["RDPPort"].Value); + connectionInfo.Port = xmlnode.GetAttributeAsBool("UseVNC") + ? xmlnode.GetAttributeAsInt("VNCPort") + : xmlnode.GetAttributeAsInt("RDPPort"); } - connectionInfo.UseConsoleSession = bool.Parse(xmlnode.Attributes["ConnectToConsole"].Value); + connectionInfo.UseConsoleSession = xmlnode.GetAttributeAsBool("ConnectToConsole"); } else { if (_confVersion < 0.7) { - if (Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value)) + if (xmlnode.GetAttributeAsBool("UseVNC")) connectionInfo.Port = (int)ProtocolVNC.Defaults.Port; else connectionInfo.Port = (int)RdpProtocol.Defaults.Port; @@ -284,10 +279,10 @@ namespace mRemoteNG.Config.Serializers.Xml if (_confVersion >= 0.5) { - connectionInfo.RedirectDiskDrives = bool.Parse(xmlnode.Attributes["RedirectDiskDrives"].Value); - connectionInfo.RedirectPrinters = bool.Parse(xmlnode.Attributes["RedirectPrinters"].Value); - connectionInfo.RedirectPorts = bool.Parse(xmlnode.Attributes["RedirectPorts"].Value); - connectionInfo.RedirectSmartCards = bool.Parse(xmlnode.Attributes["RedirectSmartCards"].Value); + connectionInfo.RedirectDiskDrives = xmlnode.GetAttributeAsBool("RedirectDiskDrives"); + connectionInfo.RedirectPrinters = xmlnode.GetAttributeAsBool("RedirectPrinters"); + connectionInfo.RedirectPorts = xmlnode.GetAttributeAsBool("RedirectPorts"); + connectionInfo.RedirectSmartCards = xmlnode.GetAttributeAsBool("RedirectSmartCards"); } else { @@ -299,31 +294,29 @@ namespace mRemoteNG.Config.Serializers.Xml if (_confVersion >= 0.7) { - ProtocolType protocolType; - Enum.TryParse(xmlnode.Attributes["Protocol"].Value, true, out protocolType); - connectionInfo.Protocol = protocolType; - connectionInfo.Port = Convert.ToInt32(xmlnode.Attributes["Port"].Value); + connectionInfo.Protocol = xmlnode.GetAttributeAsEnum("Protocol"); + connectionInfo.Port = xmlnode.GetAttributeAsInt("Port"); } if (_confVersion >= 1.0) { - connectionInfo.RedirectKeys = bool.Parse(xmlnode.Attributes["RedirectKeys"].Value); + connectionInfo.RedirectKeys = xmlnode.GetAttributeAsBool("RedirectKeys"); } if (_confVersion >= 1.2) { - connectionInfo.PuttySession = xmlnode.Attributes["PuttySession"].Value; + connectionInfo.PuttySession = xmlnode.GetAttributeAsString("PuttySession"); } if (_confVersion >= 1.3) { - connectionInfo.Colors = (RdpProtocol.RDPColors)Enum.Parse(typeof(RdpProtocol.RDPColors), xmlnode.Attributes["Colors"].Value, true); - connectionInfo.Resolution = (RdpProtocol.RDPResolutions)Enum.Parse(typeof(RdpProtocol.RDPResolutions), xmlnode.Attributes["Resolution"].Value, true); - connectionInfo.RedirectSound = (RdpProtocol.RDPSounds)Enum.Parse(typeof(RdpProtocol.RDPSounds), xmlnode.Attributes["RedirectSound"].Value, true); + connectionInfo.Colors = xmlnode.GetAttributeAsEnum("Colors"); + connectionInfo.Resolution = xmlnode.GetAttributeAsEnum("Resolution"); + connectionInfo.RedirectSound = xmlnode.GetAttributeAsEnum("RedirectSound"); } else { - switch (Convert.ToInt32(xmlnode.Attributes["Colors"].Value)) + switch (xmlnode.GetAttributeAsInt("Colors")) { case 0: connectionInfo.Colors = RdpProtocol.RDPColors.Colors256; @@ -344,180 +337,178 @@ namespace mRemoteNG.Config.Serializers.Xml break; } - connectionInfo.RedirectSound = (RdpProtocol.RDPSounds)Convert.ToInt32(xmlnode.Attributes["RedirectSound"].Value); + connectionInfo.RedirectSound = xmlnode.GetAttributeAsEnum("RedirectSound"); } if (_confVersion >= 1.3) { - connectionInfo.Inheritance = new ConnectionInfoInheritance(connectionInfo) + connectionInfo.Inheritance.CacheBitmaps = xmlnode.GetAttributeAsBool("InheritCacheBitmaps"); + connectionInfo.Inheritance.Colors = xmlnode.GetAttributeAsBool("InheritColors"); + connectionInfo.Inheritance.Description = xmlnode.GetAttributeAsBool("InheritDescription"); + connectionInfo.Inheritance.DisplayThemes = xmlnode.GetAttributeAsBool("InheritDisplayThemes"); + connectionInfo.Inheritance.DisplayWallpaper = xmlnode.GetAttributeAsBool("InheritDisplayWallpaper"); + connectionInfo.Inheritance.Icon = xmlnode.GetAttributeAsBool("InheritIcon"); + connectionInfo.Inheritance.Panel = xmlnode.GetAttributeAsBool("InheritPanel"); + connectionInfo.Inheritance.Port = xmlnode.GetAttributeAsBool("InheritPort"); + connectionInfo.Inheritance.Protocol = xmlnode.GetAttributeAsBool("InheritProtocol"); + connectionInfo.Inheritance.PuttySession = xmlnode.GetAttributeAsBool("InheritPuttySession"); + connectionInfo.Inheritance.RedirectDiskDrives = xmlnode.GetAttributeAsBool("InheritRedirectDiskDrives"); + connectionInfo.Inheritance.RedirectKeys = xmlnode.GetAttributeAsBool("InheritRedirectKeys"); + connectionInfo.Inheritance.RedirectPorts = xmlnode.GetAttributeAsBool("InheritRedirectPorts"); + connectionInfo.Inheritance.RedirectPrinters = xmlnode.GetAttributeAsBool("InheritRedirectPrinters"); + connectionInfo.Inheritance.RedirectSmartCards = xmlnode.GetAttributeAsBool("InheritRedirectSmartCards"); + connectionInfo.Inheritance.RedirectSound = xmlnode.GetAttributeAsBool("InheritRedirectSound"); + connectionInfo.Inheritance.Resolution = xmlnode.GetAttributeAsBool("InheritResolution"); + connectionInfo.Inheritance.UseConsoleSession = xmlnode.GetAttributeAsBool("InheritUseConsoleSession"); + + if (!Runtime.UseCredentialManager || _confVersion <= 2.6) // 1.3 - 2.6 { - CacheBitmaps = bool.Parse(xmlnode.Attributes["InheritCacheBitmaps"].Value), - Colors = bool.Parse(xmlnode.Attributes["InheritColors"].Value), - Description = bool.Parse(xmlnode.Attributes["InheritDescription"].Value), - DisplayThemes = bool.Parse(xmlnode.Attributes["InheritDisplayThemes"].Value), - DisplayWallpaper = bool.Parse(xmlnode.Attributes["InheritDisplayWallpaper"].Value), - Icon = bool.Parse(xmlnode.Attributes["InheritIcon"].Value), - Panel = bool.Parse(xmlnode.Attributes["InheritPanel"].Value), - Port = bool.Parse(xmlnode.Attributes["InheritPort"].Value), - Protocol = bool.Parse(xmlnode.Attributes["InheritProtocol"].Value), - PuttySession = bool.Parse(xmlnode.Attributes["InheritPuttySession"].Value), - RedirectDiskDrives = bool.Parse(xmlnode.Attributes["InheritRedirectDiskDrives"].Value), - RedirectKeys = bool.Parse(xmlnode.Attributes["InheritRedirectKeys"].Value), - RedirectPorts = bool.Parse(xmlnode.Attributes["InheritRedirectPorts"].Value), - RedirectPrinters = bool.Parse(xmlnode.Attributes["InheritRedirectPrinters"].Value), - RedirectSmartCards = bool.Parse(xmlnode.Attributes["InheritRedirectSmartCards"].Value), - RedirectSound = bool.Parse(xmlnode.Attributes["InheritRedirectSound"].Value), - Resolution = bool.Parse(xmlnode.Attributes["InheritResolution"].Value), - UseConsoleSession = bool.Parse(xmlnode.Attributes["InheritUseConsoleSession"].Value), - }; - if (_confVersion <= 2.6) // 1.3 - 2.6 - { - connectionInfo.Inheritance.Domain = bool.Parse(xmlnode.Attributes["InheritDomain"].Value); - connectionInfo.Inheritance.Password = bool.Parse(xmlnode.Attributes["InheritPassword"].Value); - connectionInfo.Inheritance.Username = bool.Parse(xmlnode.Attributes["InheritUsername"].Value); + connectionInfo.Inheritance.Domain = xmlnode.GetAttributeAsBool("InheritDomain"); + connectionInfo.Inheritance.Password = xmlnode.GetAttributeAsBool("InheritPassword"); + connectionInfo.Inheritance.Username = xmlnode.GetAttributeAsBool("InheritUsername"); } - connectionInfo.Icon = xmlnode.Attributes["Icon"].Value; - connectionInfo.Panel = xmlnode.Attributes["Panel"].Value; + connectionInfo.Icon = xmlnode.GetAttributeAsString("Icon"); + connectionInfo.Panel = xmlnode.GetAttributeAsString("Panel"); } else { - connectionInfo.Inheritance = new ConnectionInfoInheritance(connectionInfo); - if (Convert.ToBoolean(xmlnode.Attributes["Inherit"].Value)) + if (xmlnode.GetAttributeAsBool("Inherit")) connectionInfo.Inheritance.TurnOnInheritanceCompletely(); - connectionInfo.Icon = Convert.ToString(xmlnode.Attributes["Icon"].Value.Replace(".ico", "")); + connectionInfo.Icon = xmlnode.GetAttributeAsString("Icon").Replace(".ico", ""); connectionInfo.Panel = Language.strGeneral; } if (_confVersion >= 1.5) { - connectionInfo.PleaseConnect = bool.Parse(xmlnode.Attributes["Connected"].Value); + connectionInfo.PleaseConnect = xmlnode.GetAttributeAsBool("Connected"); } if (_confVersion >= 1.6) { - connectionInfo.ICAEncryptionStrength = (IcaProtocol.EncryptionStrength)Enum.Parse(typeof(IcaProtocol.EncryptionStrength), xmlnode.Attributes["ICAEncryptionStrength"].Value, true); - connectionInfo.Inheritance.ICAEncryptionStrength = bool.Parse(xmlnode.Attributes["InheritICAEncryptionStrength"].Value); - connectionInfo.PreExtApp = xmlnode.Attributes["PreExtApp"].Value; - connectionInfo.PostExtApp = xmlnode.Attributes["PostExtApp"].Value; - connectionInfo.Inheritance.PreExtApp = bool.Parse(xmlnode.Attributes["InheritPreExtApp"].Value); - connectionInfo.Inheritance.PostExtApp = bool.Parse(xmlnode.Attributes["InheritPostExtApp"].Value); + connectionInfo.ICAEncryptionStrength = xmlnode.GetAttributeAsEnum("ICAEncryptionStrength"); + connectionInfo.Inheritance.ICAEncryptionStrength = xmlnode.GetAttributeAsBool("InheritICAEncryptionStrength"); + connectionInfo.PreExtApp = xmlnode.GetAttributeAsString("PreExtApp"); + connectionInfo.PostExtApp = xmlnode.GetAttributeAsString("PostExtApp"); + connectionInfo.Inheritance.PreExtApp = xmlnode.GetAttributeAsBool("InheritPreExtApp"); + connectionInfo.Inheritance.PostExtApp = xmlnode.GetAttributeAsBool("InheritPostExtApp"); } if (_confVersion >= 1.7) { - connectionInfo.VNCCompression = (ProtocolVNC.Compression)Enum.Parse(typeof(ProtocolVNC.Compression), xmlnode.Attributes["VNCCompression"].Value, true); - connectionInfo.VNCEncoding = (ProtocolVNC.Encoding)Enum.Parse(typeof(ProtocolVNC.Encoding), xmlnode.Attributes["VNCEncoding"].Value, true); - connectionInfo.VNCAuthMode = (ProtocolVNC.AuthMode)Enum.Parse(typeof(ProtocolVNC.AuthMode), xmlnode.Attributes["VNCAuthMode"].Value, true); - connectionInfo.VNCProxyType = (ProtocolVNC.ProxyType)Enum.Parse(typeof(ProtocolVNC.ProxyType), xmlnode.Attributes["VNCProxyType"].Value, true); - connectionInfo.VNCProxyIP = xmlnode.Attributes["VNCProxyIP"].Value; - connectionInfo.VNCProxyPort = Convert.ToInt32(xmlnode.Attributes["VNCProxyPort"].Value); - connectionInfo.VNCProxyUsername = xmlnode.Attributes["VNCProxyUsername"].Value; - connectionInfo.VNCProxyPassword = _decryptor.Decrypt(xmlnode.Attributes["VNCProxyPassword"].Value); - connectionInfo.VNCColors = (ProtocolVNC.Colors)Enum.Parse(typeof(ProtocolVNC.Colors), xmlnode.Attributes["VNCColors"].Value, true); - connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Enum.Parse(typeof(ProtocolVNC.SmartSizeMode), xmlnode.Attributes["VNCSmartSizeMode"].Value, true); - connectionInfo.VNCViewOnly = bool.Parse(xmlnode.Attributes["VNCViewOnly"].Value); - connectionInfo.Inheritance.VNCCompression = bool.Parse(xmlnode.Attributes["InheritVNCCompression"].Value); - connectionInfo.Inheritance.VNCEncoding = bool.Parse(xmlnode.Attributes["InheritVNCEncoding"].Value); - connectionInfo.Inheritance.VNCAuthMode = bool.Parse(xmlnode.Attributes["InheritVNCAuthMode"].Value); - connectionInfo.Inheritance.VNCProxyType = bool.Parse(xmlnode.Attributes["InheritVNCProxyType"].Value); - connectionInfo.Inheritance.VNCProxyIP = bool.Parse(xmlnode.Attributes["InheritVNCProxyIP"].Value); - connectionInfo.Inheritance.VNCProxyPort = bool.Parse(xmlnode.Attributes["InheritVNCProxyPort"].Value); - connectionInfo.Inheritance.VNCProxyUsername = bool.Parse(xmlnode.Attributes["InheritVNCProxyUsername"].Value); - connectionInfo.Inheritance.VNCProxyPassword = bool.Parse(xmlnode.Attributes["InheritVNCProxyPassword"].Value); - connectionInfo.Inheritance.VNCColors = bool.Parse(xmlnode.Attributes["InheritVNCColors"].Value); - connectionInfo.Inheritance.VNCSmartSizeMode = bool.Parse(xmlnode.Attributes["InheritVNCSmartSizeMode"].Value); - connectionInfo.Inheritance.VNCViewOnly = bool.Parse(xmlnode.Attributes["InheritVNCViewOnly"].Value); + connectionInfo.VNCCompression = xmlnode.GetAttributeAsEnum("VNCCompression"); + connectionInfo.VNCEncoding = xmlnode.GetAttributeAsEnum("VNCEncoding"); + connectionInfo.VNCAuthMode = xmlnode.GetAttributeAsEnum("VNCAuthMode"); + connectionInfo.VNCProxyType = xmlnode.GetAttributeAsEnum("VNCProxyType"); + connectionInfo.VNCProxyIP = xmlnode.GetAttributeAsString("VNCProxyIP"); + connectionInfo.VNCProxyPort = xmlnode.GetAttributeAsInt("VNCProxyPort"); + connectionInfo.VNCProxyUsername = xmlnode.GetAttributeAsString("VNCProxyUsername"); + connectionInfo.VNCProxyPassword = _decryptor.Decrypt(xmlnode.GetAttributeAsString("VNCProxyPassword")); + connectionInfo.VNCColors = xmlnode.GetAttributeAsEnum("VNCColors"); + connectionInfo.VNCSmartSizeMode = xmlnode.GetAttributeAsEnum("VNCSmartSizeMode"); + connectionInfo.VNCViewOnly = xmlnode.GetAttributeAsBool("VNCViewOnly"); + connectionInfo.Inheritance.VNCCompression = xmlnode.GetAttributeAsBool("InheritVNCCompression"); + connectionInfo.Inheritance.VNCEncoding = xmlnode.GetAttributeAsBool("InheritVNCEncoding"); + connectionInfo.Inheritance.VNCAuthMode = xmlnode.GetAttributeAsBool("InheritVNCAuthMode"); + connectionInfo.Inheritance.VNCProxyType = xmlnode.GetAttributeAsBool("InheritVNCProxyType"); + connectionInfo.Inheritance.VNCProxyIP = xmlnode.GetAttributeAsBool("InheritVNCProxyIP"); + connectionInfo.Inheritance.VNCProxyPort = xmlnode.GetAttributeAsBool("InheritVNCProxyPort"); + connectionInfo.Inheritance.VNCProxyUsername = xmlnode.GetAttributeAsBool("InheritVNCProxyUsername"); + connectionInfo.Inheritance.VNCProxyPassword = xmlnode.GetAttributeAsBool("InheritVNCProxyPassword"); + connectionInfo.Inheritance.VNCColors = xmlnode.GetAttributeAsBool("InheritVNCColors"); + connectionInfo.Inheritance.VNCSmartSizeMode = xmlnode.GetAttributeAsBool("InheritVNCSmartSizeMode"); + connectionInfo.Inheritance.VNCViewOnly = xmlnode.GetAttributeAsBool("InheritVNCViewOnly"); } if (_confVersion >= 1.8) { - connectionInfo.RDPAuthenticationLevel = (RdpProtocol.AuthenticationLevel)Enum.Parse(typeof(RdpProtocol.AuthenticationLevel), xmlnode.Attributes["RDPAuthenticationLevel"].Value, true); - connectionInfo.Inheritance.RDPAuthenticationLevel = bool.Parse(xmlnode.Attributes["InheritRDPAuthenticationLevel"].Value); + connectionInfo.RDPAuthenticationLevel = xmlnode.GetAttributeAsEnum("RDPAuthenticationLevel"); + connectionInfo.Inheritance.RDPAuthenticationLevel = xmlnode.GetAttributeAsBool("InheritRDPAuthenticationLevel"); } if (_confVersion >= 1.9) { - connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine), xmlnode.Attributes["RenderingEngine"].Value, true); - connectionInfo.MacAddress = xmlnode.Attributes["MacAddress"].Value; - connectionInfo.Inheritance.RenderingEngine = bool.Parse(xmlnode.Attributes["InheritRenderingEngine"].Value); - connectionInfo.Inheritance.MacAddress = bool.Parse(xmlnode.Attributes["InheritMacAddress"].Value); + connectionInfo.RenderingEngine = xmlnode.GetAttributeAsEnum("RenderingEngine"); + connectionInfo.MacAddress = xmlnode.GetAttributeAsString("MacAddress"); + connectionInfo.Inheritance.RenderingEngine = xmlnode.GetAttributeAsBool("InheritRenderingEngine"); + connectionInfo.Inheritance.MacAddress = xmlnode.GetAttributeAsBool("InheritMacAddress"); } if (_confVersion >= 2.0) { - connectionInfo.UserField = xmlnode.Attributes["UserField"].Value; - connectionInfo.Inheritance.UserField = bool.Parse(xmlnode.Attributes["InheritUserField"].Value); + connectionInfo.UserField = xmlnode.GetAttributeAsString("UserField"); + connectionInfo.Inheritance.UserField = xmlnode.GetAttributeAsBool("InheritUserField"); } if (_confVersion >= 2.1) { - connectionInfo.ExtApp = xmlnode.Attributes["ExtApp"].Value; - connectionInfo.Inheritance.ExtApp = bool.Parse(xmlnode.Attributes["InheritExtApp"].Value); + connectionInfo.ExtApp = xmlnode.GetAttributeAsString("ExtApp"); + connectionInfo.Inheritance.ExtApp = xmlnode.GetAttributeAsBool("InheritExtApp"); } if (_confVersion >= 2.2) { // Get settings - connectionInfo.RDGatewayUsageMethod = (RdpProtocol.RDGatewayUsageMethod)Enum.Parse(typeof(RdpProtocol.RDGatewayUsageMethod), xmlnode.Attributes["RDGatewayUsageMethod"].Value, true); - connectionInfo.RDGatewayHostname = xmlnode.Attributes["RDGatewayHostname"].Value; - connectionInfo.RDGatewayUseConnectionCredentials = (RdpProtocol.RDGatewayUseConnectionCredentials)Enum.Parse(typeof(RdpProtocol.RDGatewayUseConnectionCredentials), xmlnode.Attributes["RDGatewayUseConnectionCredentials"].Value, true); - connectionInfo.RDGatewayUsername = xmlnode.Attributes["RDGatewayUsername"].Value; - connectionInfo.RDGatewayPassword = _decryptor.Decrypt(Convert.ToString(xmlnode.Attributes["RDGatewayPassword"].Value)); - connectionInfo.RDGatewayDomain = xmlnode.Attributes["RDGatewayDomain"].Value; + connectionInfo.RDGatewayUsageMethod = xmlnode.GetAttributeAsEnum("RDGatewayUsageMethod"); + connectionInfo.RDGatewayHostname = xmlnode.GetAttributeAsString("RDGatewayHostname"); + connectionInfo.RDGatewayUseConnectionCredentials = xmlnode.GetAttributeAsEnum("RDGatewayUseConnectionCredentials"); + connectionInfo.RDGatewayUsername = xmlnode.GetAttributeAsString("RDGatewayUsername"); + connectionInfo.RDGatewayPassword = _decryptor.Decrypt(xmlnode.GetAttributeAsString("RDGatewayPassword")); + connectionInfo.RDGatewayDomain = xmlnode.GetAttributeAsString("RDGatewayDomain"); // Get inheritance settings - connectionInfo.Inheritance.RDGatewayUsageMethod = bool.Parse(xmlnode.Attributes["InheritRDGatewayUsageMethod"].Value); - connectionInfo.Inheritance.RDGatewayHostname = bool.Parse(xmlnode.Attributes["InheritRDGatewayHostname"].Value); - connectionInfo.Inheritance.RDGatewayUseConnectionCredentials = bool.Parse(xmlnode.Attributes["InheritRDGatewayUseConnectionCredentials"].Value); - connectionInfo.Inheritance.RDGatewayUsername = bool.Parse(xmlnode.Attributes["InheritRDGatewayUsername"].Value); - connectionInfo.Inheritance.RDGatewayPassword = bool.Parse(xmlnode.Attributes["InheritRDGatewayPassword"].Value); - connectionInfo.Inheritance.RDGatewayDomain = bool.Parse(xmlnode.Attributes["InheritRDGatewayDomain"].Value); + connectionInfo.Inheritance.RDGatewayUsageMethod = xmlnode.GetAttributeAsBool("InheritRDGatewayUsageMethod"); + connectionInfo.Inheritance.RDGatewayHostname = xmlnode.GetAttributeAsBool("InheritRDGatewayHostname"); + connectionInfo.Inheritance.RDGatewayUseConnectionCredentials = xmlnode.GetAttributeAsBool("InheritRDGatewayUseConnectionCredentials"); + connectionInfo.Inheritance.RDGatewayUsername = xmlnode.GetAttributeAsBool("InheritRDGatewayUsername"); + connectionInfo.Inheritance.RDGatewayPassword = xmlnode.GetAttributeAsBool("InheritRDGatewayPassword"); + connectionInfo.Inheritance.RDGatewayDomain = xmlnode.GetAttributeAsBool("InheritRDGatewayDomain"); } if (_confVersion >= 2.3) { // Get settings - connectionInfo.EnableFontSmoothing = bool.Parse(xmlnode.Attributes["EnableFontSmoothing"].Value); - connectionInfo.EnableDesktopComposition = bool.Parse(xmlnode.Attributes["EnableDesktopComposition"].Value); + connectionInfo.EnableFontSmoothing = xmlnode.GetAttributeAsBool("EnableFontSmoothing"); + connectionInfo.EnableDesktopComposition = xmlnode.GetAttributeAsBool("EnableDesktopComposition"); // Get inheritance settings - connectionInfo.Inheritance.EnableFontSmoothing = bool.Parse(xmlnode.Attributes["InheritEnableFontSmoothing"].Value); - connectionInfo.Inheritance.EnableDesktopComposition = bool.Parse(xmlnode.Attributes["InheritEnableDesktopComposition"].Value); + connectionInfo.Inheritance.EnableFontSmoothing = xmlnode.GetAttributeAsBool("InheritEnableFontSmoothing"); + connectionInfo.Inheritance.EnableDesktopComposition = xmlnode.GetAttributeAsBool("InheritEnableDesktopComposition"); } if (_confVersion >= 2.4) { - connectionInfo.UseCredSsp = bool.Parse(xmlnode.Attributes["UseCredSsp"].Value); - connectionInfo.Inheritance.UseCredSsp = bool.Parse(xmlnode.Attributes["InheritUseCredSsp"].Value); + connectionInfo.UseCredSsp = xmlnode.GetAttributeAsBool("UseCredSsp"); + connectionInfo.Inheritance.UseCredSsp = xmlnode.GetAttributeAsBool("InheritUseCredSsp"); } if (_confVersion >= 2.5) { - connectionInfo.LoadBalanceInfo = xmlnode.Attributes["LoadBalanceInfo"].Value; - connectionInfo.AutomaticResize = bool.Parse(xmlnode.Attributes["AutomaticResize"].Value); - connectionInfo.Inheritance.LoadBalanceInfo = bool.Parse(xmlnode.Attributes["InheritLoadBalanceInfo"].Value); - connectionInfo.Inheritance.AutomaticResize = bool.Parse(xmlnode.Attributes["InheritAutomaticResize"].Value); + connectionInfo.LoadBalanceInfo = xmlnode.GetAttributeAsString("LoadBalanceInfo"); + connectionInfo.AutomaticResize = xmlnode.GetAttributeAsBool("AutomaticResize"); + connectionInfo.Inheritance.LoadBalanceInfo = xmlnode.GetAttributeAsBool("InheritLoadBalanceInfo"); + connectionInfo.Inheritance.AutomaticResize = xmlnode.GetAttributeAsBool("InheritAutomaticResize"); } if (_confVersion >= 2.6) { - connectionInfo.SoundQuality = (RdpProtocol.RDPSoundQuality)Enum.Parse(typeof(RdpProtocol.RDPSoundQuality), xmlnode.Attributes["SoundQuality"].Value, true); - connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value); - connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"]?.Value ?? "0"); - connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"]?.Value ?? "False"); - connectionInfo.RDPAlertIdleTimeout = bool.Parse(xmlnode.Attributes["RDPAlertIdleTimeout"]?.Value ?? "False"); - connectionInfo.Inheritance.RDPAlertIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPAlertIdleTimeout"]?.Value ?? "False"); + connectionInfo.SoundQuality = xmlnode.GetAttributeAsEnum("SoundQuality"); + connectionInfo.Inheritance.SoundQuality = xmlnode.GetAttributeAsBool("InheritSoundQuality"); + connectionInfo.RDPMinutesToIdleTimeout = xmlnode.GetAttributeAsInt("RDPMinutesToIdleTimeout"); + connectionInfo.Inheritance.RDPMinutesToIdleTimeout = xmlnode.GetAttributeAsBool("InheritRDPMinutesToIdleTimeout"); + connectionInfo.RDPAlertIdleTimeout = xmlnode.GetAttributeAsBool("RDPAlertIdleTimeout"); + connectionInfo.Inheritance.RDPAlertIdleTimeout = xmlnode.GetAttributeAsBool("InheritRDPAlertIdleTimeout"); } if(_confVersion >= 2.7) { - connectionInfo.RedirectClipboard = bool.Parse(xmlnode.Attributes["RedirectClipboard"].Value); - connectionInfo.Inheritance.RedirectClipboard = bool.Parse(xmlnode.Attributes["InheritRedirectClipboard"].Value); + connectionInfo.RedirectClipboard = xmlnode.GetAttributeAsBool("RedirectClipboard"); + connectionInfo.Inheritance.RedirectClipboard = xmlnode.GetAttributeAsBool("InheritRedirectClipboard"); } } catch (Exception ex) { Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strGetConnectionInfoFromXmlFailed, connectionInfo.Name, ConnectionFileName, ex.Message)); } + return connectionInfo; } } diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentCompiler.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentCompiler.cs index 28fe8d747..95c35d4b4 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentCompiler.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDocumentCompiler.cs @@ -1,12 +1,12 @@ -using System; -using System.Linq; -using System.Security; -using System.Xml.Linq; -using mRemoteNG.Connection; +using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Security; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; +using System; +using System.Linq; +using System.Security; +using System.Xml.Linq; namespace mRemoteNG.Config.Serializers.Xml { @@ -79,7 +79,7 @@ namespace mRemoteNG.Config.Serializers.Xml private XElement CompileRootNode(RootNodeInfo rootNodeInfo, bool fullFileEncryption) { var rootNodeSerializer = new XmlRootNodeSerializer(); - return rootNodeSerializer.SerializeRootNodeInfo(rootNodeInfo, _cryptographyProvider, fullFileEncryption); + return rootNodeSerializer.SerializeRootNodeInfo(rootNodeInfo, _cryptographyProvider, _connectionNodeSerializer.Version, fullFileEncryption); } private XElement CompileConnectionInfoNode(ConnectionInfo connectionInfo) diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsSerializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsSerializer.cs index 94d9c7c16..d4e32d313 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsSerializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsSerializer.cs @@ -1,14 +1,14 @@ -using System; +using mRemoteNG.App; +using mRemoteNG.Connection; +using mRemoteNG.Security; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using System; using System.IO; using System.Linq; using System.Text; using System.Xml; using System.Xml.Linq; -using mRemoteNG.App; -using mRemoteNG.Connection; -using mRemoteNG.Security; -using mRemoteNG.Tree; -using mRemoteNG.Tree.Root; namespace mRemoteNG.Config.Serializers.Xml { @@ -17,6 +17,7 @@ namespace mRemoteNG.Config.Serializers.Xml private readonly ICryptographyProvider _cryptographyProvider; private readonly ISerializer _connectionNodeSerializer; + public Version Version => _connectionNodeSerializer.Version; public bool UseFullEncryption { get; set; } public XmlConnectionsSerializer(ICryptographyProvider cryptographyProvider, ISerializer connectionNodeSerializer) diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlExtensions.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlExtensions.cs new file mode 100644 index 000000000..71ecbff73 --- /dev/null +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlExtensions.cs @@ -0,0 +1,48 @@ +using System; +using System.Xml; + +namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml +{ + public static class XmlExtensions + { + public static string GetAttributeAsString(this XmlNode xmlNode, string attribute, string defaultValue = "") + { + var value = xmlNode?.Attributes?[attribute]?.Value; + return value ?? defaultValue; + } + + public static bool GetAttributeAsBool(this XmlNode xmlNode, string attribute, bool defaultValue = false) + { + var value = xmlNode?.Attributes?[attribute]?.Value; + if (string.IsNullOrWhiteSpace(value)) + return defaultValue; + + return bool.TryParse(value, out var valueAsBool) + ? valueAsBool + : defaultValue; + } + + public static int GetAttributeAsInt(this XmlNode xmlNode, string attribute, int defaultValue = 0) + { + var value = xmlNode?.Attributes?[attribute]?.Value; + if (string.IsNullOrWhiteSpace(value)) + return defaultValue; + + return int.TryParse(value, out var valueAsBool) + ? valueAsBool + : defaultValue; + } + + public static T GetAttributeAsEnum(this XmlNode xmlNode, string attribute, T defaultValue = default(T)) + where T : struct + { + var value = xmlNode?.Attributes?[attribute]?.Value; + if (string.IsNullOrWhiteSpace(value)) + return defaultValue; + + return Enum.TryParse(value, true, out var valueAsEnum) + ? valueAsEnum + : defaultValue; + } + } +} diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlRootNodeSerializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlRootNodeSerializer.cs index de69ba12e..9a9f9af93 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlRootNodeSerializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlRootNodeSerializer.cs @@ -1,12 +1,17 @@ -using System.Xml.Linq; -using mRemoteNG.Security; +using mRemoteNG.Security; using mRemoteNG.Tree.Root; +using System; +using System.Xml.Linq; namespace mRemoteNG.Config.Serializers.Xml { - public class XmlRootNodeSerializer + public class XmlRootNodeSerializer { - public XElement SerializeRootNodeInfo(RootNodeInfo rootNodeInfo, ICryptographyProvider cryptographyProvider, bool fullFileEncryption = false) + public XElement SerializeRootNodeInfo( + RootNodeInfo rootNodeInfo, + ICryptographyProvider cryptographyProvider, + Version version, + bool fullFileEncryption = false) { XNamespace xmlNamespace = "http://mremoteng.org"; var element = new XElement(xmlNamespace + "Connections"); @@ -18,7 +23,7 @@ namespace mRemoteNG.Config.Serializers.Xml element.Add(new XAttribute(XName.Get("KdfIterations"), cryptographyProvider.KeyDerivationIterations)); element.Add(new XAttribute(XName.Get("FullFileEncryption"), fullFileEncryption.ToString().ToLowerInvariant())); element.Add(CreateProtectedAttribute(rootNodeInfo, cryptographyProvider)); - element.Add(new XAttribute(XName.Get("ConfVersion"), "2.6")); + element.Add(new XAttribute(XName.Get("ConfVersion"), version.ToString(2))); return element; } diff --git a/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialRecordSerializer.cs b/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialRecordSerializer.cs index b3cc9db87..01d2e0e1c 100644 --- a/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialRecordSerializer.cs +++ b/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialRecordSerializer.cs @@ -1,21 +1,21 @@ -using System; +using mRemoteNG.Credential; +using mRemoteNG.Security; +using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; -using mRemoteNG.Credential; -using mRemoteNG.Security; namespace mRemoteNG.Config.Serializers.CredentialSerializer { public class XmlCredentialRecordSerializer : ISerializer, string> { - public string SchemaVersion { get; } = "1.0"; + public Version Version { get; } = new Version(1, 0); public string Serialize(IEnumerable credentialRecords) { var xdoc = new XDocument( new XElement("Credentials", - new XAttribute("SchemaVersion", SchemaVersion), + new XAttribute("SchemaVersion", Version.ToString(2)), from r in credentialRecords select new XElement("Credential", new XAttribute("Id", r.Id), diff --git a/mRemoteV1/Config/Serializers/ISerializer.cs b/mRemoteV1/Config/Serializers/ISerializer.cs index 94950b5bd..82e008e2e 100644 --- a/mRemoteV1/Config/Serializers/ISerializer.cs +++ b/mRemoteV1/Config/Serializers/ISerializer.cs @@ -1,7 +1,10 @@ -namespace mRemoteNG.Config.Serializers +using System; + +namespace mRemoteNG.Config.Serializers { public interface ISerializer { TOut Serialize(TIn model); + Version Version { get; } } } \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/MiscSerializers/RemoteDesktopConnectionDeserializer.cs b/mRemoteV1/Config/Serializers/MiscSerializers/RemoteDesktopConnectionDeserializer.cs index 2453a948d..d59bcbc3a 100644 --- a/mRemoteV1/Config/Serializers/MiscSerializers/RemoteDesktopConnectionDeserializer.cs +++ b/mRemoteV1/Config/Serializers/MiscSerializers/RemoteDesktopConnectionDeserializer.cs @@ -1,8 +1,8 @@ -using System; -using mRemoteNG.Connection; +using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol.RDP; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; +using System; namespace mRemoteNG.Config.Serializers { @@ -125,6 +125,9 @@ namespace mRemoteNG.Config.Serializers break; } break; + case "loadbalanceinfo": + connectionInfo.LoadBalanceInfo = value; + break; } } } diff --git a/mRemoteV1/Config/Settings/DockPanelLayoutSerializer.cs b/mRemoteV1/Config/Settings/DockPanelLayoutSerializer.cs index 3b55b3cac..0ee7d3c3c 100644 --- a/mRemoteV1/Config/Settings/DockPanelLayoutSerializer.cs +++ b/mRemoteV1/Config/Settings/DockPanelLayoutSerializer.cs @@ -1,14 +1,16 @@ -using System; +using mRemoteNG.Config.Serializers; +using System; using System.IO; using System.Text; using System.Xml.Linq; -using mRemoteNG.Config.Serializers; using WeifenLuo.WinFormsUI.Docking; namespace mRemoteNG.Config.Settings { public class DockPanelLayoutSerializer : ISerializer { + public Version Version { get; } = new Version(1, 0); + public string Serialize(DockPanel dockPanel) { if (dockPanel == null) diff --git a/mRemoteV1/Connection/ConnectionInitiator.cs b/mRemoteV1/Connection/ConnectionInitiator.cs index 86ae32439..77dccaac3 100644 --- a/mRemoteV1/Connection/ConnectionInitiator.cs +++ b/mRemoteV1/Connection/ConnectionInitiator.cs @@ -1,6 +1,5 @@ using mRemoteNG.App; using mRemoteNG.Connection.Protocol; -using mRemoteNG.Connection.Protocol.RDP; using mRemoteNG.Container; using mRemoteNG.Messages; using mRemoteNG.UI.Forms; @@ -135,10 +134,10 @@ namespace mRemoteNG.Connection private static string SetConnectionPanel(ConnectionInfo connectionInfo, ConnectionInfo.Force force) { - var connectionPanel = ""; + string connectionPanel; if (connectionInfo.Panel == "" || force.HasFlag(ConnectionInfo.Force.OverridePanel) || Settings.Default.AlwaysShowPanelSelectionDlg) { - var frmPnl = new frmChoosePanel(); + var frmPnl = new FrmChoosePanel(); if (frmPnl.ShowDialog() == DialogResult.OK) { connectionPanel = frmPnl.Panel; @@ -204,25 +203,27 @@ namespace mRemoteNG.Connection #endregion #region Event handlers - private static void Prot_Event_Disconnected(object sender, string disconnectedMessage) + private static void Prot_Event_Disconnected(object sender, string disconnectedMessage, int? reasonCode) { try { - if (sender is VncSharp.RemoteDesktop) + var prot = (ProtocolBase)sender; + var msgClass = MessageClass.InformationMsg; + + if (prot.InterfaceControl.Info.Protocol == ProtocolType.RDP) { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strProtocolEventDisconnected, @"VncSharp Disconnected."), true); - return; + if (reasonCode > 3) + { + msgClass = MessageClass.WarningMsg; + } } - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strProtocolEventDisconnected, disconnectedMessage), true); - - var prot = (ProtocolBase)sender; - if (prot.InterfaceControl.Info.Protocol != ProtocolType.RDP) return; - var reasonCode = disconnectedMessage.Split("\r\n".ToCharArray())[0]; - var desc = disconnectedMessage.Replace("\r\n", " "); - - if (Convert.ToInt32(reasonCode) > 3) - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strRdpDisconnected + Environment.NewLine + desc); + Runtime.MessageCollector.AddMessage(msgClass, + string.Format( + Language.strProtocolEventDisconnected, + disconnectedMessage, + prot.InterfaceControl.Info.Hostname, + prot.InterfaceControl.Info.Protocol.ToString())); } catch (Exception ex) { @@ -266,16 +267,18 @@ namespace mRemoteNG.Connection Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strConnectionEventConnectedDetail, prot.InterfaceControl.Info.Hostname, prot.InterfaceControl.Info.Protocol, Environment.UserName, prot.InterfaceControl.Info.Description, prot.InterfaceControl.Info.UserField)); } - private static void Prot_Event_ErrorOccured(object sender, string errorMessage) + private static void Prot_Event_ErrorOccured(object sender, string errorMessage, int? errorCode) { try { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnectionEventErrorOccured, true); - var prot = (ProtocolBase)sender; + var prot = (ProtocolBase) sender; - if (prot.InterfaceControl.Info.Protocol != ProtocolType.RDP) return; - if (Convert.ToInt32(errorMessage) > -1) - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, string.Format(Language.strConnectionRdpErrorDetail, errorMessage, RdpErrorCodes.GetError(errorMessage))); + var msg = string.Format( + Language.strConnectionEventErrorOccured, + errorMessage, + prot.InterfaceControl.Info.Hostname, + errorCode?.ToString() ?? "-"); + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, msg); } catch (Exception ex) { diff --git a/mRemoteV1/Connection/InterfaceControl.Designer.cs b/mRemoteV1/Connection/InterfaceControl.Designer.cs index f15e9a7d7..440fdce42 100644 --- a/mRemoteV1/Connection/InterfaceControl.Designer.cs +++ b/mRemoteV1/Connection/InterfaceControl.Designer.cs @@ -29,7 +29,6 @@ namespace mRemoteNG.Connection private void InitializeComponent() { components = new System.ComponentModel.Container(); - //Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font } } } diff --git a/mRemoteV1/Connection/Protocol/ICA/IcaProtocol.cs b/mRemoteV1/Connection/Protocol/ICA/IcaProtocol.cs index e28c21147..795e6494c 100644 --- a/mRemoteV1/Connection/Protocol/ICA/IcaProtocol.cs +++ b/mRemoteV1/Connection/Protocol/ICA/IcaProtocol.cs @@ -285,12 +285,12 @@ namespace mRemoteNG.Connection.Protocol.ICA private void ICAEvent_OnConnectFailed(object sender, EventArgs e) { - Event_ErrorOccured(this, e.ToString()); + Event_ErrorOccured(this, e.ToString(), null); } private void ICAEvent_OnDisconnect(object sender, EventArgs e) { - Event_Disconnected(this, e.ToString()); + Event_Disconnected(this, e.ToString(), null); if (Settings.Default.ReconnectOnDisconnect) { diff --git a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs index d3c27c0c8..0911dd519 100644 --- a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs +++ b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs @@ -115,8 +115,8 @@ namespace mRemoteNG.Connection.Protocol Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppFocusFailed, ex); } } - - public override void Resize(object sender, EventArgs e) + + protected override void Resize(object sender, EventArgs e) { try { diff --git a/mRemoteV1/Connection/Protocol/ProtocolBase.cs b/mRemoteV1/Connection/Protocol/ProtocolBase.cs index b9008b03c..1a90c77e5 100644 --- a/mRemoteV1/Connection/Protocol/ProtocolBase.cs +++ b/mRemoteV1/Connection/Protocol/ProtocolBase.cs @@ -1,13 +1,13 @@ +using mRemoteNG.App; +using mRemoteNG.Tools; using System; using System.Threading; using System.Windows.Forms; -using mRemoteNG.App; -using mRemoteNG.Tools; namespace mRemoteNG.Connection.Protocol { - public abstract class ProtocolBase + public abstract class ProtocolBase: IDisposable { #region Private Variables @@ -27,8 +27,8 @@ namespace mRemoteNG.Connection.Protocol protected UI.Window.ConnectionWindow ConnectionWindow { - get { return _connectionWindow; } - private set + get => _connectionWindow; + private set { _connectionWindow = value; _connectionWindow.ResizeBegin += ResizeBegin; @@ -39,8 +39,8 @@ namespace mRemoteNG.Connection.Protocol public InterfaceControl InterfaceControl { - get { return _interfaceControl; } - set + get => _interfaceControl; + set { _interfaceControl = value; ConnectionWindow = _interfaceControl.GetContainerControl() as UI.Window.ConnectionWindow; @@ -82,15 +82,15 @@ namespace mRemoteNG.Connection.Protocol } } - public virtual void ResizeBegin(object sender, EventArgs e) + protected virtual void ResizeBegin(object sender, EventArgs e) { } - public virtual void Resize(object sender, EventArgs e) + protected virtual void Resize(object sender, EventArgs e) { } - public virtual void ResizeEnd(object sender, EventArgs e) + protected virtual void ResizeEnd(object sender, EventArgs e) { } @@ -222,50 +222,64 @@ namespace mRemoteNG.Connection.Protocol Control.Dispose(); } } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + tmrReconnect.Dispose(); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } #endregion - + #region Events - public delegate void ConnectingEventHandler(object sender); + public delegate void ConnectingEventHandler(object sender); public event ConnectingEventHandler Connecting { - add { ConnectingEvent = (ConnectingEventHandler) Delegate.Combine(ConnectingEvent, value); } - remove { ConnectingEvent = (ConnectingEventHandler) Delegate.Remove(ConnectingEvent, value); } - } + add => ConnectingEvent = (ConnectingEventHandler) Delegate.Combine(ConnectingEvent, value); + remove => ConnectingEvent = (ConnectingEventHandler) Delegate.Remove(ConnectingEvent, value); + } public delegate void ConnectedEventHandler(object sender); public event ConnectedEventHandler Connected { - add { ConnectedEvent = (ConnectedEventHandler) Delegate.Combine(ConnectedEvent, value); } - remove { ConnectedEvent = (ConnectedEventHandler) Delegate.Remove(ConnectedEvent, value); } - } + add => ConnectedEvent = (ConnectedEventHandler) Delegate.Combine(ConnectedEvent, value); + remove => ConnectedEvent = (ConnectedEventHandler) Delegate.Remove(ConnectedEvent, value); + } - public delegate void DisconnectedEventHandler(object sender, string DisconnectedMessage); + public delegate void DisconnectedEventHandler(object sender, string disconnectedMessage, int? reasonCode); public event DisconnectedEventHandler Disconnected { - add { DisconnectedEvent = (DisconnectedEventHandler) Delegate.Combine(DisconnectedEvent, value); } - remove { DisconnectedEvent = (DisconnectedEventHandler) Delegate.Remove(DisconnectedEvent, value); } - } + add => DisconnectedEvent = (DisconnectedEventHandler) Delegate.Combine(DisconnectedEvent, value); + remove => DisconnectedEvent = (DisconnectedEventHandler) Delegate.Remove(DisconnectedEvent, value); + } - public delegate void ErrorOccuredEventHandler(object sender, string ErrorMessage); + public delegate void ErrorOccuredEventHandler(object sender, string errorMessage, int? errorCode); public event ErrorOccuredEventHandler ErrorOccured { - add { ErrorOccuredEvent = (ErrorOccuredEventHandler) Delegate.Combine(ErrorOccuredEvent, value); } - remove { ErrorOccuredEvent = (ErrorOccuredEventHandler) Delegate.Remove(ErrorOccuredEvent, value); } - } + add => ErrorOccuredEvent = (ErrorOccuredEventHandler) Delegate.Combine(ErrorOccuredEvent, value); + remove => ErrorOccuredEvent = (ErrorOccuredEventHandler) Delegate.Remove(ErrorOccuredEvent, value); + } public delegate void ClosingEventHandler(object sender); public event ClosingEventHandler Closing { - add { ClosingEvent = (ClosingEventHandler) Delegate.Combine(ClosingEvent, value); } - remove { ClosingEvent = (ClosingEventHandler) Delegate.Remove(ClosingEvent, value); } - } + add => ClosingEvent = (ClosingEventHandler) Delegate.Combine(ClosingEvent, value); + remove => ClosingEvent = (ClosingEventHandler) Delegate.Remove(ClosingEvent, value); + } public delegate void ClosedEventHandler(object sender); public event ClosedEventHandler Closed { - add { ClosedEvent = (ClosedEventHandler) Delegate.Combine(ClosedEvent, value); } - remove { ClosedEvent = (ClosedEventHandler) Delegate.Remove(ClosedEvent, value); } - } + add => ClosedEvent = (ClosedEventHandler) Delegate.Combine(ClosedEvent, value); + remove => ClosedEvent = (ClosedEventHandler) Delegate.Remove(ClosedEvent, value); + } public void Event_Closing(object sender) @@ -288,14 +302,14 @@ namespace mRemoteNG.Connection.Protocol ConnectedEvent?.Invoke(sender); } - protected void Event_Disconnected(object sender, string DisconnectedMessage) + protected void Event_Disconnected(object sender, string disconnectedMessage, int? reasonCode) { - DisconnectedEvent?.Invoke(sender, DisconnectedMessage); + DisconnectedEvent?.Invoke(sender, disconnectedMessage, reasonCode); } - protected void Event_ErrorOccured(object sender, string ErrorMsg) + protected void Event_ErrorOccured(object sender, string errorMsg, int? errorCode) { - ErrorOccuredEvent?.Invoke(sender, ErrorMsg); + ErrorOccuredEvent?.Invoke(sender, errorMsg, errorCode); } protected void Event_ReconnectGroupCloseClicked() diff --git a/mRemoteV1/Connection/Protocol/PuttyBase.cs b/mRemoteV1/Connection/Protocol/PuttyBase.cs index 665d75177..dc9805194 100644 --- a/mRemoteV1/Connection/Protocol/PuttyBase.cs +++ b/mRemoteV1/Connection/Protocol/PuttyBase.cs @@ -193,8 +193,8 @@ namespace mRemoteNG.Connection.Protocol Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyFocusFailed + Environment.NewLine + ex.Message, true); } } - - public override void Resize(object sender, EventArgs e) + + protected override void Resize(object sender, EventArgs e) { try { diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpErrorCodes.cs b/mRemoteV1/Connection/Protocol/RDP/RdpErrorCodes.cs index fa98147b6..aa963ffd2 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpErrorCodes.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpErrorCodes.cs @@ -1,6 +1,6 @@ +using mRemoteNG.App; using System; using System.Collections; -using mRemoteNG.App; namespace mRemoteNG.Connection.Protocol.RDP { @@ -12,19 +12,19 @@ namespace mRemoteNG.Connection.Protocol.RDP { _description = new Hashtable { - {"0", "Language.strRdpErrorUnknown"}, - {"1", "Language.strRdpErrorCode1"}, - {"2", "Language.strRdpErrorOutOfMemory"}, - {"3", "Language.strRdpErrorWindowCreation"}, - {"4", "Language.strRdpErrorCode2"}, - {"5", "Language.strRdpErrorCode3"}, - {"6", "Language.strRdpErrorCode4"}, - {"7", "Language.strRdpErrorConnection"}, - {"100", "Language.strRdpErrorWinsock"} + { 0, "Language.strRdpErrorUnknown"}, + { 1, "Language.strRdpErrorCode1"}, + { 2, "Language.strRdpErrorOutOfMemory"}, + { 3, "Language.strRdpErrorWindowCreation"}, + { 4, "Language.strRdpErrorCode2"}, + { 5, "Language.strRdpErrorCode3"}, + { 6, "Language.strRdpErrorCode4"}, + { 7, "Language.strRdpErrorConnection"}, + { 100, "Language.strRdpErrorWinsock"} }; } - public static string GetError(string id) + public static string GetError(int id) { try { diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs index 0feb886c6..a4e4a90d1 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs @@ -36,10 +36,7 @@ namespace mRemoteNG.Connection.Protocol.RDP #region Properties public bool SmartSize { - get - { - return _rdpClient.AdvancedSettings2.SmartSizing; - } + get => _rdpClient.AdvancedSettings2.SmartSizing; private set { _rdpClient.AdvancedSettings2.SmartSizing = value; @@ -49,10 +46,7 @@ namespace mRemoteNG.Connection.Protocol.RDP public bool Fullscreen { - get - { - return _rdpClient.FullScreen; - } + get => _rdpClient.FullScreen; private set { _rdpClient.FullScreen = value; @@ -251,12 +245,13 @@ namespace mRemoteNG.Connection.Protocol.RDP } private Size _controlBeginningSize; - public override void ResizeBegin(object sender, EventArgs e) + + protected override void ResizeBegin(object sender, EventArgs e) { _controlBeginningSize = Control.Size; } - - public override void Resize(object sender, EventArgs e) + + protected override void Resize(object sender, EventArgs e) { if (DoResize() && _controlBeginningSize.IsEmpty) { @@ -264,8 +259,8 @@ namespace mRemoteNG.Connection.Protocol.RDP } base.Resize(sender, e); } - - public override void ResizeEnd(object sender, EventArgs e) + + protected override void ResizeEnd(object sender, EventArgs e) { DoResize(); if (!(Control.Size == _controlBeginningSize)) @@ -680,18 +675,15 @@ namespace mRemoteNG.Connection.Protocol.RDP { Close(); //Simply close the RDP Session if the idle timeout has been triggered. - if (_alertOnIdleDisconnect) - { - string message = "The " + _connectionInfo.Name + " session was disconnected due to inactivity"; - const string caption = "Session Disconnected"; - MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Information); - } + if (!_alertOnIdleDisconnect) return; + MessageBox.Show($"The {_connectionInfo.Name} session was disconnected due to inactivity", "Session Disconnected", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void RDPEvent_OnFatalError(int errorCode) - { - Event_ErrorOccured(this, Convert.ToString(errorCode)); + { + var errorMsg = RdpErrorCodes.GetError(errorCode); + Event_ErrorOccured(this, errorMsg, errorCode); } private void RDPEvent_OnDisconnected(int discReason) @@ -700,7 +692,7 @@ namespace mRemoteNG.Connection.Protocol.RDP if (discReason != UI_ERR_NORMAL_DISCONNECT) { var reason = _rdpClient.GetErrorDescription((uint)discReason, (uint) _rdpClient.ExtendedDisconnectReason); - Event_Disconnected(this, discReason + "\r\n" + reason); + Event_Disconnected(this, reason, discReason); } if (Settings.Default.ReconnectOnDisconnect) @@ -747,15 +739,9 @@ namespace mRemoteNG.Connection.Protocol.RDP public event LeaveFullscreenEventHandler LeaveFullscreen { - add - { - _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Combine(_leaveFullscreenEvent, value); - } - remove - { - _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Remove(_leaveFullscreenEvent, value); - } - } + add => _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Combine(_leaveFullscreenEvent, value); + remove => _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Remove(_leaveFullscreenEvent, value); + } #endregion #region Enums @@ -925,15 +911,13 @@ namespace mRemoteNG.Connection.Protocol.RDP var srvReady = PortScanner.IsPortOpen(_connectionInfo.Hostname, Convert.ToString(_connectionInfo.Port)); ReconnectGroup.ServerReady = srvReady; - - if (ReconnectGroup.ReconnectWhenReady && srvReady) - { - tmrReconnect.Enabled = false; - ReconnectGroup.DisposeReconnectGroup(); - //SetProps() - _rdpClient.Connect(); - } - } + + if (!ReconnectGroup.ReconnectWhenReady || !srvReady) return; + tmrReconnect.Enabled = false; + ReconnectGroup.DisposeReconnectGroup(); + //SetProps() + _rdpClient.Connect(); + } catch (Exception ex) { Runtime.MessageCollector.AddExceptionMessage(string.Format(Language.AutomaticReconnectError, _connectionInfo.Hostname), diff --git a/mRemoteV1/Connection/Protocol/VNC/Connection.Protocol.VNC.cs b/mRemoteV1/Connection/Protocol/VNC/Connection.Protocol.VNC.cs index a405a5760..63db3a924 100644 --- a/mRemoteV1/Connection/Protocol/VNC/Connection.Protocol.VNC.cs +++ b/mRemoteV1/Connection/Protocol/VNC/Connection.Protocol.VNC.cs @@ -186,7 +186,7 @@ namespace mRemoteNG.Connection.Protocol.VNC private void VNCEvent_Disconnected(object sender, EventArgs e) { FrmMain.ClipboardChanged -= VNCEvent_ClipboardChanged; - Event_Disconnected(sender, e.ToString()); + Event_Disconnected(sender, @"VncSharp Disconnected.", null); Close(); } diff --git a/mRemoteV1/Connection/PuttySessionInfo.cs b/mRemoteV1/Connection/PuttySessionInfo.cs index 8edce2a38..4fd37e73f 100644 --- a/mRemoteV1/Connection/PuttySessionInfo.cs +++ b/mRemoteV1/Connection/PuttySessionInfo.cs @@ -10,7 +10,7 @@ using mRemoteNG.Tree.Root; namespace mRemoteNG.Connection { - public class PuttySessionInfo : ConnectionInfo, IComponent + public sealed class PuttySessionInfo : ConnectionInfo, IComponent { #region Properties [Browsable(false)] @@ -28,14 +28,14 @@ namespace mRemoteNG.Connection [ReadOnly(true), Browsable(false)] public override string Icon { - get { return "PuTTY"; } + get => "PuTTY"; set { } } [ReadOnly(true), Browsable(false)] public override string Panel { - get { return Parent?.Panel; } + get => Parent?.Panel; set { } } @@ -99,16 +99,16 @@ namespace mRemoteNG.Connection [Browsable(false)] public ISite Site { - get { return new PropertyGridCommandSite(this); } - set { throw (new NotImplementedException()); } - } - - public void Dispose() - { - Disposed?.Invoke(this, EventArgs.Empty); - } + get => new PropertyGridCommandSite(this); + set => throw (new NotImplementedException()); + } - public event EventHandler Disposed; + public void Dispose() + { + Disposed?.Invoke(this, EventArgs.Empty); + } + + public event EventHandler Disposed; #endregion } } \ No newline at end of file diff --git a/mRemoteV1/Icons/Apple.ico b/mRemoteV1/Icons/Apple.ico new file mode 100644 index 000000000..d3e843b91 Binary files /dev/null and b/mRemoteV1/Icons/Apple.ico differ diff --git a/mRemoteV1/Icons/mRemoteNG.ico b/mRemoteV1/Icons/mRemoteNG.ico index 08c1072aa..1c750daf4 100644 Binary files a/mRemoteV1/Icons/mRemoteNG.ico and b/mRemoteV1/Icons/mRemoteNG.ico differ diff --git a/mRemoteV1/Properties/Resources.Designer.cs b/mRemoteV1/Properties/Resources.Designer.cs index 1df379a6b..1b038fe66 100644 --- a/mRemoteV1/Properties/Resources.Designer.cs +++ b/mRemoteV1/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace mRemoteNG { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -230,6 +230,16 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon Comments_Icon { + get { + object obj = ResourceManager.GetObject("Comments_Icon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -343,9 +353,9 @@ namespace mRemoteNG { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon Connections_SaveAs_Icon { + internal static System.Drawing.Icon ConnectionsSaveAs_Icon { get { - object obj = ResourceManager.GetObject("Connections_SaveAs_Icon", resourceCulture); + object obj = ResourceManager.GetObject("ConnectionsSaveAs_Icon", resourceCulture); return ((System.Drawing.Icon)(obj)); } } @@ -370,6 +380,16 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon Database_Icon { + get { + object obj = ResourceManager.GetObject("Database_Icon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -390,6 +410,26 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon EditPage_Icon { + get { + object obj = ResourceManager.GetObject("EditPage_Icon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon Error_Icon { + get { + object obj = ResourceManager.GetObject("Error_Icon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -560,6 +600,16 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Header_dark { + get { + object obj = ResourceManager.GetObject("Header_dark", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -723,9 +773,9 @@ namespace mRemoteNG { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon key_Icon { + internal static System.Drawing.Icon Key_Icon { get { - object obj = ResourceManager.GetObject("key_Icon", resourceCulture); + object obj = ResourceManager.GetObject("Key_Icon", resourceCulture); return ((System.Drawing.Icon)(obj)); } } @@ -740,6 +790,16 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon Keyboard_Icon { + get { + object obj = ResourceManager.GetObject("Keyboard_Icon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -760,16 +820,6 @@ namespace mRemoteNG { } } - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap Logo { - get { - object obj = ResourceManager.GetObject("Logo", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -813,9 +863,9 @@ namespace mRemoteNG { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap mRemote { + internal static System.Drawing.Bitmap mRemoteNG { get { - object obj = ResourceManager.GetObject("mRemote", resourceCulture); + object obj = ResourceManager.GetObject("mRemoteNG", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -823,13 +873,30 @@ namespace mRemoteNG { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon mRemote_Icon { + internal static System.Drawing.Icon mRemoteNG_Icon { get { - object obj = ResourceManager.GetObject("mRemote_Icon", resourceCulture); + object obj = ResourceManager.GetObject("mRemoteNG_Icon", resourceCulture); return ((System.Drawing.Icon)(obj)); } } + /// + /// Looks up a localized string similar to <Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> + /// <VisualElements + /// BackgroundColor='#343A40' + /// ShowNameOnSquare150x150Logo='on' + /// ForegroundText='light' + /// Square150x150Logo='VisualElements_150.png' + /// Square70x70Logo='VisualElements_70.png'/> + ///</Application> + ///. + /// + internal static string mRemoteNG_VisualElementsManifest { + get { + return ResourceManager.GetString("mRemoteNG_VisualElementsManifest", resourceCulture); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -960,16 +1027,6 @@ namespace mRemoteNG { } } - /// - /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). - /// - internal static System.Drawing.Icon Play_Quick_Icon { - get { - object obj = ResourceManager.GetObject("Play_Quick_Icon", resourceCulture); - return ((System.Drawing.Icon)(obj)); - } - } - /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -1050,16 +1107,6 @@ namespace mRemoteNG { } } - /// - /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). - /// - internal static System.Drawing.Icon RDCMan_Icon { - get { - object obj = ResourceManager.GetObject("RDCMan_Icon", resourceCulture); - return ((System.Drawing.Icon)(obj)); - } - } - /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -1233,9 +1280,9 @@ namespace mRemoteNG { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon shield { + internal static System.Drawing.Icon Shield_Icon { get { - object obj = ResourceManager.GetObject("shield", resourceCulture); + object obj = ResourceManager.GetObject("Shield_Icon", resourceCulture); return ((System.Drawing.Icon)(obj)); } } @@ -1390,6 +1437,26 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap VisualElements_150 { + get { + object obj = ResourceManager.GetObject("VisualElements_150", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap VisualElements_70 { + get { + object obj = ResourceManager.GetObject("VisualElements_70", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/mRemoteV1/Properties/Resources.resx b/mRemoteV1/Properties/Resources.resx index df3319847..3289c14e0 100644 --- a/mRemoteV1/Properties/Resources.resx +++ b/mRemoteV1/Properties/Resources.resx @@ -157,30 +157,15 @@ ..\Resources\Images\Root.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\Root_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\Warning.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\Info_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Icons\mRemote_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\PuttyConfig.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Images\mRemote.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\Play_Quick.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\Play_Quick_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\Connections_Load.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -211,9 +196,6 @@ ..\Resources\Images\Config.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Config_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Copy.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -235,9 +217,6 @@ ..\Resources\Images\FamFamFam\Options.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Options_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Panels.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -253,9 +232,6 @@ ..\Resources\Images\FamFamFam\Save.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Save_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Screenshot.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -268,9 +244,6 @@ ..\Resources\Images\FamFamFam\Screenshot_Delete.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Screenshot_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Screenshot_Save.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -286,9 +259,6 @@ ..\Resources\Images\FamFamFam\Website.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Appearance_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Arrow_Down.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -298,9 +268,6 @@ ..\Resources\Images\FamFamFam\Bug.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\Connections_SaveAs_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Connection_Add.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -316,9 +283,6 @@ ..\Resources\Images\FamFamFam\ExtApp_Delete.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\ExtApp_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\ExtApp_Start.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -334,9 +298,6 @@ ..\Resources\Images\FamFamFam\Help.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Help_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Page.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -349,9 +310,6 @@ ..\Resources\Images\FamFamFam\PortScan.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\PortScan_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Properties.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -364,9 +322,6 @@ ..\Resources\Images\FamFamFam\Sessions.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Sessions_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Session_LogOff.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -376,24 +331,12 @@ ..\Resources\Images\FamFamFam\SSHTransfer.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\SSHTransfer_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Icons\FamFamFam\StartupExit_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Icons\FamFamFam\Tab_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Tools.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Images\FamFamFam\Update.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Update_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Console.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -403,15 +346,9 @@ ..\Resources\Images\FamFamFam\Chat.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\Panels_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\JumpTo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Images\Logo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\Monitor.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -421,27 +358,15 @@ ..\Resources\Images\UVNC_SC.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\UVNC_SC_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\Bad_Symbol.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Images\ComponentsCheck.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\ComponentsCheck_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\Good_Symbol.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\ActiveDirectory_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Icons\FamFamFam\News_Icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\News.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -475,9 +400,6 @@ ..\resources\Images\FamFamFam\page_copy.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\resources\icons\rdcman_icon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\resources\images\puttycm.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -487,18 +409,12 @@ ..\Resources\Images\green_arrow2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\shield.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\key.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Images\FamFamFam\key_add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\FamFamFam\key.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Images\FamFamFam\brick.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -529,4 +445,106 @@ ..\Resources\Images\loading_spinner.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Images\Header_dark.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Tiles\mRemoteNG.VisualElementsManifest.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\Tiles\VisualElements_150.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Tiles\VisualElements_70.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\ActiveDirectory_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Appearance_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Comments_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\ComponentsCheck_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Config_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\ConnectionsSaveAs_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Database_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\EditPage_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Error_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\ExtApp_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Help_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Info_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Keyboard_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Key_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\mRemoteNG_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\News_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Options_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Panels_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\PortScan_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Root_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Save_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Screenshot_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Sessions_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Shield_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\SSHTransfer_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\StartupExit_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Tab_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\Update_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\UVNC_SC_Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Images\mRemoteNG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/mRemoteV1/Properties/Settings.Designer.cs b/mRemoteV1/Properties/Settings.Designer.cs index 2375b7e49..147aadd77 100644 --- a/mRemoteV1/Properties/Settings.Designer.cs +++ b/mRemoteV1/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace mRemoteNG { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.1.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -2747,6 +2747,30 @@ namespace mRemoteNG { } } + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool TrackActiveConnectionInConnectionTree { + get { + return ((bool)(this["TrackActiveConnectionInConnectionTree"])); + } + set { + this["TrackActiveConnectionInConnectionTree"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool PlaceSearchBarAboveConnectionTree { + get { + return ((bool)(this["PlaceSearchBarAboveConnectionTree"])); + } + set { + this["PlaceSearchBarAboveConnectionTree"] = value; + } + } + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] diff --git a/mRemoteV1/Properties/Settings.settings b/mRemoteV1/Properties/Settings.settings index 7b8314d46..d0196826a 100644 --- a/mRemoteV1/Properties/Settings.settings +++ b/mRemoteV1/Properties/Settings.settings @@ -683,6 +683,12 @@ General + + False + + + False + True diff --git a/mRemoteV1/References/ADTree.dll b/mRemoteV1/References/ADTree.dll index 98e435b33..efef39efd 100644 Binary files a/mRemoteV1/References/ADTree.dll and b/mRemoteV1/References/ADTree.dll differ diff --git a/mRemoteV1/References/VncSharp.dll b/mRemoteV1/References/VncSharp.dll index 9ccd4e121..f9bd733ce 100644 Binary files a/mRemoteV1/References/VncSharp.dll and b/mRemoteV1/References/VncSharp.dll differ diff --git a/mRemoteV1/Resources/Other Graphics/HandelGotD.ttf b/mRemoteV1/Resources/Fonts/HandelGotD.ttf similarity index 100% rename from mRemoteV1/Resources/Other Graphics/HandelGotD.ttf rename to mRemoteV1/Resources/Fonts/HandelGotD.ttf diff --git a/mRemoteV1/Resources/Other Graphics/HandelGotDBol.ttf b/mRemoteV1/Resources/Fonts/HandelGotDBol.ttf similarity index 100% rename from mRemoteV1/Resources/Other Graphics/HandelGotDBol.ttf rename to mRemoteV1/Resources/Fonts/HandelGotDBol.ttf diff --git a/mRemoteV1/Resources/Other Graphics/HandelGotDLig.ttf b/mRemoteV1/Resources/Fonts/HandelGotDLig.ttf similarity index 100% rename from mRemoteV1/Resources/Other Graphics/HandelGotDLig.ttf rename to mRemoteV1/Resources/Fonts/HandelGotDLig.ttf diff --git a/mRemoteV1/Resources/Help/CMDSwitches.htm b/mRemoteV1/Resources/Help/CMDSwitches.htm deleted file mode 100644 index 842deea0b..000000000 --- a/mRemoteV1/Resources/Help/CMDSwitches.htm +++ /dev/null @@ -1,28 +0,0 @@ - - - - Command-Line Switches - - - - -

- The following is a list of command line switches supported by mRemote.

-
    -
  • /cons:PathToConnectionsFile or /c:PathToConnectionsFile
    - Loads the connections file from the given path
  • -
  • /reset
    - Resets window position, panels and toolbars
  • -
  • /resetpos or /rp
    - Resets the window position
  • -
  • /resetpanels or /rpnl
    - Resets all panel's positions
    - Use this if you have troubles with panel layouts
  • -
  • /resettoolbar or /rtbr
    -
    Resets the positions of all toolbars
  • -
  • /noreconnect or /norc
    Temporary disables reconnect to previously opened sessions
    Use this if you have problems opening mRemote after you enabled the setting and - restarted mRemote
  • -
- - - diff --git a/mRemoteV1/Resources/Help/Config.htm b/mRemoteV1/Resources/Help/Config.htm deleted file mode 100644 index ce9389855..000000000 --- a/mRemoteV1/Resources/Help/Config.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Config - - - - -

- Sorry, not yet...

- - - diff --git a/mRemoteV1/Resources/Help/Configuration.htm b/mRemoteV1/Resources/Help/Configuration.htm deleted file mode 100644 index b7e0d1101..000000000 --- a/mRemoteV1/Resources/Help/Configuration.htm +++ /dev/null @@ -1,163 +0,0 @@ - - - - Configuration - - - - -

- First start

-

- Once you got mRemote installed and run it for the first time you should see a - screen like on the following screenshot.

-

-

-

- The first thing that catches your attention will probably be the info box - popping up.
- Don't freak out just yet, this is not a error message and it's totally ok to - show up on the first run.
- It just tells you that the connections file could not be found at the default - location and that mRemote will create a new one for you at this location.
- If you click anywhere else in the application the panel will hide itself again. - (Tip: You can also hit Escape to hide the Errors and Infos panel)

-

-

-

- Now that we now about the Errors and Infos panel take a deep breath and just - stare at the gorgeous about screen for a few seconds. =)
- No, seriously, to create your first connection continue reading.

-

- Creating Connections

-

- Right click the root item (the blue ball labeled "Connections") in the - Connections panel and select "Add Connection".

-

-

-

- A new item shows up under the root item. You can give it a name now (or rename - it later). I just named mine "Test".

-

-

-

- Now have a look at the Config panel in the bottom left, just under the - Connections panel.

-

-

-

- As you may notice this is where you configure all the properties of connections - and folders.
- There are a lot of values that can be set but for our first connection we will - keep things simple.

-

- The most important things right now are that we tell the application which host - we want to connect to and which protocol we want to use.
- In this example I will use a Windows 2003 server that has RDP (Remote Desktop - Protocol) enabled.
- As RDP is the default protocol whenever you create a new connection I don't have - to change anything there.

-

- The next thing I'll do is to fill the Hostname/IP field with the hostname I - want to connect to.

-

-

-

- I'll also fill the Username and Password fields so I will be automatically - logged on to the server.

-

-

-

- Ok, that's it, we are ready for our first connection test.

-

- Opening and Closing Connections

-

- There are multiple ways to open a connection in mRemote, but the easiest is to - just double-click the connection in the Connections panel.

-

- If I do that now, a new panel named "General" with one tab inside named "Test" - will show up.

-

-

-

- Alright, mRemote is now trying to connect to the specified host.

-

- If it cannot connect you will see a message popping up like on the following - screenshot.

-

-

-

- This for example means the hostname cannot be resolved.

-

- Instead, if all goes well you should see the remote desktop.

-

-

-

- If you do not want to log off from the remote machine but just close it you can - do this by simply double-clicking the tab labeled "test" or just close the whole - "General" panel by clicking the small "x" in the upper right corner.

-

- Folders and Inheritance

-

- Folders in mRemote cannot only be used to categorize connections but also to - apply properties to the underlying connections.

-

- Example:
- You have 10 Remote Desktop enabled servers in one domain and 15 in another - domain.
- Normally you would spend a lot of time creating all those connections and - setting the individual properties like username, password, etc.
- In mRemote there is an easier way. You just create two folders, one for domain A - and one for domain B and set all properties there.
- Then create the Connections and let them inherit every property. The only - properties left to fill on Connection basis are the Connection's name and - hostname. Everything else will be inherited from the parent folder.

-

- "Sounds cool, but how to do it?"
- I'll show you how to do it!

-

- First add a new folder.

-

-

-

- Then give it a name and fill all the properties you need (just like you did with - the test Connection).

-

-

-

-

-

- When you're done setting the values you can either just drag the test Connection - inside the folder or create a new one.

-

-

-

- Right now nothing has changed and nothing will be inherited.
- To enable inheritance switch to the inheritance view by clicking the dedicated - button.

-

-

-

- The properties that show up now are almost the same as before, but you can only - select yes or no.

-

-

-

- When no is selected the property will not be inherited, yes indicates an - inherited property.
- For this test set "Inherit Everything" to Yes.

-

- Now if you switch back to the properties view (the button left of the - inheritance button) you should see that not much is left of all those - properties.

-

-

-

- Only the Name and Hostname/IP properties are left over, everything else will be - inherited from the parent folder.
- Of course you can also only let some of the properties be inherited.

-

- Just play around with this a bit and you'll get the hang of it.

- - - diff --git a/mRemoteV1/Resources/Help/ConfigurationSQL.htm b/mRemoteV1/Resources/Help/ConfigurationSQL.htm deleted file mode 100644 index 419ec236f..000000000 --- a/mRemoteV1/Resources/Help/ConfigurationSQL.htm +++ /dev/null @@ -1,49 +0,0 @@ - - - - SQL Configuration - - - - -

- Warning

-

- The SQL feature is in an early beta stage and not intended for use in an - productive environment!
- I recommend you to do a full backup of your connections and settings before - switching to SQL Server.

-

- Steps to configure your SQL Server

-
    -
  • Create a new Database called "mRemoteNG" on your SQL Server.
  • -
  • Run the SQL Script below on the newly created Database.
  • -
  • Give the users that you want to grant access to the mRemote Connections Database - Read/Write permissions on the Database.
  • -
-

- Steps to configure mRemoteNG for SQL

-
    -
  • Start mRemoteNG if it's not already running.
  • -
  • Go to Options - Connections.
  • -
  • Check the box that says "Use SQL Server to load & save connections".
  • -
  • Fill in your SQL Server hostname or ip address.
  • -
  • If you do not use your Windows logon info to authenticate against the SQL Server - fill in the correct Username and Password.
  • -
  • Click OK to apply the changes. The main window title should now change to - "mRemoteNG | SQL Server".
  • -
  • Now click on File - Save to update the tables on your SQL Server with the data - from the loaded connections xml file. (Do not click File - New, this doesn't - work yet)
  • -
  • You should now be able to do everything you were able to do with the XML storage - plus see the changes live on another mRemoteNG instance that is connected to the - same Database.
  • -
- -

- SQL Table creation Script

-

- Click here to view the SQL script

- - - diff --git a/mRemoteV1/Resources/Help/Connection.htm b/mRemoteV1/Resources/Help/Connection.htm deleted file mode 100644 index 22e2784eb..000000000 --- a/mRemoteV1/Resources/Help/Connection.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Connection - - - - -

- Sorry, not yet...

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/Connections.htm b/mRemoteV1/Resources/Help/Connections.htm deleted file mode 100644 index 6c2e919a8..000000000 --- a/mRemoteV1/Resources/Help/Connections.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Connections - - - - -

- Sorry, not yet...

- - - diff --git a/mRemoteV1/Resources/Help/ErrorsAndInfos.htm b/mRemoteV1/Resources/Help/ErrorsAndInfos.htm deleted file mode 100644 index 8659fe062..000000000 --- a/mRemoteV1/Resources/Help/ErrorsAndInfos.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Errors and Infos - - - - -

- Sorry, not yet...

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/ExternalTools.htm b/mRemoteV1/Resources/Help/ExternalTools.htm deleted file mode 100644 index 5f9a91af5..000000000 --- a/mRemoteV1/Resources/Help/ExternalTools.htm +++ /dev/null @@ -1,245 +0,0 @@ - - - - External Tools - - - - - -

- Introduction to External Tools

-

- External Tools can help you get things done that can't be done in - mRemoteNG.
- You can for example start a command prompt or launch your favorite FTP tool from - within mRemoteNG.
- This wouldn't make much sense by itself because you can already launch your - applications by using the Windows Start Menu, Quick Launch or whatever you - prefer to use - to start your apps.

-

- But there's more!

-

- In mRemoteNG, you can launch applications and tell them what to do with the use of - arguments (parameters) and variables of the currently selected Connection. - You can, for example, select your home router's SSH Connection entry and do a - traceroute (tracert) on that host. - This is much quicker and more powerful than opening the console and typing - "tracert yourhost".

-

- The external tools configuration is stored in %APPDATA%\mRemoteNG\extApps.xml

- -

- Variables -

- -

- Variables and arguments can be used to tell the external tool what to do.

-

- This is the list of variables supported by mRemoteNG: -

- -
    -
  • %NAME%
  • -
  • %HOSTNAME%
  • -
  • %PORT%
  • -
  • %USERNAME%
  • -
  • %PASSWORD%
  • -
  • %DOMAIN%
  • -
  • %DESCRIPTION%
  • -
  • %MACADDRESS%
  • -
  • %USERFIELD%
  • -
- -

- Variables always refer to the currently selected connection. Variable names are case-insensitive. - Variables can be used in both the Filename and Arguments fields.

- -

- mRemoteNG will also expand environment variables such as %PATH% and - %USERPROFILE%. - If you need to use an environment variable with the same name as an mRemoteNG - variable, use \% instead of %. The most common use of this is for the USERNAME - environment variable. %USERNAME% will be expanded to the username set in the - currently selected connection. \%USERNAME\% will be expanded to the value set in - the USERNAME environment variable.

- -

If you need to send a variable name to a program without mRemoteNG expanding it, - use ^% instead of %. mRemoteNG will remove the caret (^) and leave the rest - unchanged. For example, ^%USERNAME^% will be sent to the program as %USERNAME% - and will not be expanded.

- -

- Special Character Escaping -

- -

- Expanded variables will be escaped using the rules below. There are two levels - of escaping that are done. The first is escaping for standard argument splitting - (C/C++ argv, CommandLineToArgvW, etc). The second is escaping shell - metacharacters for ShellExecute.

-

- Argument splitting escaping:

- -
    -
  • Each quotation mark will be escaped by a backslash.
  • -
  • One or more backslashes (\) followed by a quotation mark ("): -
      -
    • Each backslash will be escaped by another backslash.
    • -
    • The quotation mark will be escaped by a backslash.
    • -      If the connection's user field contains - "This" is a \"test\".
      -      Then %USERFIELD% is replaced with - \"This\" is a \\\"test\\\". -
    -
  • -
  • A variable name followed by a quotation mark (for example, %USERFIELD%") with - a value ending in one or more backslashes: -
      -
    • Each backslash will be escaped by another backslash.
    • -
    • Example:
    • -      If the connection's user field contains c:\Example\
      -      Then "%USERFIELD%" is replaced with "c:\Example\\" -
    -
  • -
- -

- To disable - argument splitting escaping for a variable, precede its name with a minus (-) - sign. For example, %-USERFIELD%.

-

- Shell metacharacter escaping:

- -
    -
  • The shell metacharacters are ( ) % ! ^ " < > & |
  • -
  • Each shell metacharacter will be escaped by a caret (^).
  • -
-

- To disable both argument splitting and shell metacharacter escaping for a - variable, precede its name with an exclamation point (!). For example, - %!USERFIELD%. This is not recommended and may cause unexpected results.

-

- Only variables that have been expanded will be escaped. It is up to you to - escape the rest of the arguments.

- -

- Variable Examples

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArgumentsUser FieldResult
%USERFIELD%"Example" Text - \^"Example\^" Text
%-USERFIELD%"Example" Text - ^"Example^" Text
%!USERFIELD%"Example" Text - "Example" Text
^%USERFIELD^%"Example" Text%USERFIELD%
^^%USERFIELD^^%"Example" Text - ^%USERFIELD^%
-d "%USERFIELD%"c:\Example\-d "c:\Example\\"
-d "%-USERFIELD%"c:\Example\-d "c:\Example\"
-d "%USERFIELD%"Left - & Right-d "Left ^& Right"
-d "%!USERFIELD%"Left - & Right-d "Left & Right"
%WINDIR%N/Ac:\Windows\
\%WINDIR\%N/Ac:\Windows\
\^%WINDIR\^%N/A - \%WINDIR\%
\\%WINDIR\\%N/A\\%WINDIR\\%
- -

- Example

-

- First of all, start the external tools editor. To do this, click Tools in the main menu and - select External Tools.
- You will see a screen like on the following screenshot.

-

-

-

- The fields below the list are greyed out because you haven't created an external tool - entry yet.
- To create one, right click the blank area in the list and select Add, as in the - screenshot below.

-

-

-

- This is what you'll get:

-

-

-

- So the three fields are now available and need to be filled.
- The Display Name is simply the name you will see when you want to launch that - tool, so give it a descriptive name.
- I named mine Traceroute as I will create a external tool that will start the - tracert command in the console.

-

-

-

- Ok, the next thing we'll need is a filename. This is the program that we - want to be executed.
- I simply type in cmd for a Windows cmd console.

-

-

-

- Now the fun part comes in—the arguments.
- The Windows cmd has a command line argument that tells the console to launch the - command followed by that argument and stay open.
- It's /K. (There's also /C, this is useful when you want the console to close - after the command was executed)
- In this case, I'll use /K as I want to look through the result when the command - completes.
- After that, I just type tracert %HostName%. This tells the console to do a - traceroute on the hostname of the currently selected Connection.

-

-

-

- Alright! That's all we'll need.
- Now right click one of you connections, click Tools, External Tools - and select Traceroute.

-

-

-

- Voilà! A console window will popup and execute your tracert command.

-

-

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/ImportFromAD.htm b/mRemoteV1/Resources/Help/ImportFromAD.htm deleted file mode 100644 index fb9585b99..000000000 --- a/mRemoteV1/Resources/Help/ImportFromAD.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Import from Active Directory - - - - -

- Sorry, not yet...

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/Index.htm b/mRemoteV1/Resources/Help/Index.htm index 1f07e295a..cfa50ca0a 100644 --- a/mRemoteV1/Resources/Help/Index.htm +++ b/mRemoteV1/Resources/Help/Index.htm @@ -1,37 +1,48 @@ - - + + -mRemote Help - + + mRemoteNG Help + - -

Introduction

-

Getting started:

- -

User Interface:

- -

Quick Reference

+
+ Done from nmat, please remove this div after review. +
+

Welcome to mRemoteNG

+
+

+ This documentation is written and based on version 1.76 of mRemoteNG. If you find anything to improve or wrong with the documentation then please report it to github. + Also note that documentation can be found on github pages that are updated more frequently then information provided here. +

+

Getting Started

+ +

User Interface

+ +

Special Topics

+

Connections

+ diff --git a/mRemoteV1/Resources/Help/Installation.htm b/mRemoteV1/Resources/Help/Installation.htm deleted file mode 100644 index f9cd6feaa..000000000 --- a/mRemoteV1/Resources/Help/Installation.htm +++ /dev/null @@ -1,48 +0,0 @@ - - - - Installation - - - - -

- Downloads are provided in four different packages, the setup package, binary package, - portable package and - the source package. They are described below.

-

- Setup Package

-

- The setup package is the compiled version of mRemote which comes in the form of - a NSIS generated setup.
- The common way to get mRemote up and running

-

- Bin Package

-

- The binary package is a zip package and contains the same files as the setup - package but has no automated installer.

-

- Portable Package

-

- The portable package consists of the same files as the bin package but contains - an modified version of the executable which stores and loads all your settings - from files in the application's directory.
- This package can be used to run mRemote from an USB stick an preserve your - configuration wherever you go.

-

- Source Package

- -

- The source package is a zip package and contains the source code in form of a - Visual Studio 2008 solution.

-

-  

-

- Updating and Uninstalling

-

- mRemote can be updated without uninstalling it before.
- There are no user preferences stored in the application directory (except if you - put them there), so uninstalling doesn't wipe your settings.

- - - diff --git a/mRemoteV1/Resources/Help/Introduction.htm b/mRemoteV1/Resources/Help/Introduction.htm index 8fa9f8fe2..114ff60ba 100644 --- a/mRemoteV1/Resources/Help/Introduction.htm +++ b/mRemoteV1/Resources/Help/Introduction.htm @@ -1,45 +1,53 @@ - - + + - Introduction - + + Introduction + - -

- Introduction

-

- mRemote is a multi-protocol remote connections manager.
- As of Version 1.00 it supports the RDP, VNC, ICA, SSH, Telnet, RAW, Rlogin and HTTP/S protocols.
- The main goal is to minimize window clutter and to provide a easy gui for managing all your remote connections. -

-

- Features

-

- Free and Open Source, released under the GPL
- Panels and tabs allow to group certain connections together, dock them to any side of the window or completely undock them and move them to another screen for example
- Multiple supported protocols (RDP, VNC, ICA, SSH, Telnet, RAW, Rlogin and HTTP/S)
- Easy to organize and maintain list of connections
- Inheritance makes it possible to store properties on folder basis and let the underlying connections inherit this info
- Support for importing connections from Active Directory
- Allows creating nested containers (folders) to categorize connections
- "Quick Connect" feature to quickly open a connection without creating an entry
- "Quick Search" feature to quickly find a connection while typing
- Support for SCP/SFTP (SSH) file transfers
- Assign icons to connections to easily identify purpose
- Screenshot manager allows to collect multiple screenshots and save them all together or copy them to the clipboard
- View remote session info and log off sessions (RDP)
- Portable (with the use of command line switches)
- "Auto-Update" feature
- Show description tooltips when hoovering over connections
- System tray icon with connection menu
- Fullscreen (Kiosk) mode
- Assign global credentials to use when no information is provided on connection basis
- Host Up/Down (Ping) feature shows if the selected host answers to a ping

-

- License

-

- The application is released under the GPL (V2)
- Binary and source code packages are available for download.

+
+ Done from nmat, please remove this div after review. +
+

Introduction

+
+

+ mRemoteNG is a multi-protocol remote connections manager. +
+ As of Version 1.00 it supports the RDP, VNC, ICA, SSH, Telnet, RAW, Rlogin and HTTP/S protocols. +
+ The main goal is to minimize window clutter and to provide a easy gui for managing all your remote connections. +

+

Features

+
+
    +
  • Free and Open Source, released under the GPL
  • +
  • Panels and tabs allow to group certain connections together, dock them to any side of the window or completely undock them and move them to another screen for example
  • +
  • Multiple supported protocols (RDP, VNC, ICA, SSH, Telnet, RAW, Rlogin and HTTP/S)
  • +
  • Easy to organize and maintain list of connections
  • +
  • Inheritance makes it possible to store properties on folder basis and let the underlying connections inherit this info
  • +
  • Support for importing connections from Active Directory
  • +
  • Allows creating nested containers (folders) to categorize connections
  • +
  • "Quick Connect" feature to quickly open a connection without creating an entry
  • +
  • "Quick Search" feature to quickly find a connection while typing
  • +
  • Support for SCP/SFTP (SSH) file transfers
  • +
  • Assign icons to connections to easily identify purpose
  • +
  • Screenshot manager allows to collect multiple screenshots and save them all together or copy them to the clipboard
  • +
  • View remote session info and log off sessions (RDP)
  • +
  • Portable (with the use of command line switches)
  • +
  • "Auto-Update" feature
  • +
  • Show description tooltips when hoovering over connections
  • +
  • System tray icon with connection menu
  • +
  • Fullscreen (Kiosk) mode
  • +
  • Assign global credentials to use when no information is provided on connection basis
  • +
  • Host Up/Down (Ping) feature shows if the selected host answers to a ping
  • +
+

License

+
+

+ The application is released under the GPL (V2) +
+ Binary and source code packages are available for download. +

diff --git a/mRemoteV1/Resources/Help/Main.css b/mRemoteV1/Resources/Help/Main.css index 073f9cb0b..48c211da7 100644 --- a/mRemoteV1/Resources/Help/Main.css +++ b/mRemoteV1/Resources/Help/Main.css @@ -1,5 +1,4 @@ /* COMMON STUFF */ - body { background-color: #FFFFFF; @@ -7,85 +6,51 @@ body margin-top: 10px; margin-right: 10px; margin-bottom: 10px; -} - -body, td, th -{ - font-family: Verdana, Segoe UI, Segoe UI, Helvetica, sans-serif; - font-size: 11px; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + font-size: 0.75em; color: #333333; } -img -{ +img { border: none; } -ul -{ - list-style: square; +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0; } - - /* HEADINGS */ - -.heading1 -{ - font-family: Segoe UI, Verdana, Segoe UI, Helvetica, sans-serif; - font-size: 16px; - color: Black; -} -.heading1 a:link -{ - color: Black; - text-decoration: none; -} -.heading1 a:visited -{ - color: Black; - text-decoration: none; -} -.heading1 a:hover -{ - color: Black; - text-decoration: none; - border-bottom: 5px solid #e9e9e9; -} - -.heading2 -{ - font-family: Segoe UI, Verdana, Segoe UI, Helvetica, sans-serif; - font-size: 15px; - color: Black; +h1 { + font-size: 2.0em; + color: #000000; } -.heading3 -{ - font-family: Segoe UI, Verdana, Segoe UI, Helvetica, sans-serif; - font-size: 14px; - color: Black; +h2 { + font-size: 1.5em; + color: #000000; } -.heading4 -{ - font-family: Segoe UI, Verdana, Segoe UI, Helvetica, sans-serif; - font-size: 13px; - color: Black; +h3 { + font-size: 1.17em; + color: #000000; } -.heading5 -{ - font-family: Segoe UI, Verdana, Segoe UI, Helvetica, sans-serif; - font-size: 12px; - color: Black; +h4 { + font-size: 1em; + color: #000000; } - - +h5 { + font-size: .83em; + color: #000000; +} /* LINKS */ - a:link { color: #5d6b70; @@ -104,31 +69,24 @@ a:hover text-decoration: underline; } - - - /* TABLES */ - table { - border-collapse: collapse; + font-family: arial, sans-serif; + border-collapse: collapse; } -table, th, td { - border: 1px solid black; +td, th { + border: 1px solid #dddddd; + text-align: left; + padding: 8px; } -th,td { - padding: 5px; -} - -th { - background-color: lightgrey; - text-align: left; +tr:nth-child(even) { + background-color: #f2f2f2; } /* MISC STYLES */ - .Code { padding-right: 5px; @@ -146,3 +104,25 @@ th { .nowrap { white-space: nowrap } + +.isa_info, .isa_success, .isa_warning, .isa_error { + margin: 10px 0px; + padding:12px; + +} +.isa_info { + color: #00529B; + background-color: #BDE5F8; +} +.isa_success { + color: #4F8A10; + background-color: #DFF2BF; +} +.isa_warning { + color: #9F6000; + background-color: #FEEFB3; +} +.isa_error { + color: #D8000C; + background-color: #FFD2D2; +} diff --git a/mRemoteV1/Resources/Help/MainMenu.htm b/mRemoteV1/Resources/Help/MainMenu.htm deleted file mode 100644 index 1b8ac409a..000000000 --- a/mRemoteV1/Resources/Help/MainMenu.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Main Menu - - - - -

- Sorry, not yet...

- - - diff --git a/mRemoteV1/Resources/Help/Options.htm b/mRemoteV1/Resources/Help/Options.htm deleted file mode 100644 index 90535aa16..000000000 --- a/mRemoteV1/Resources/Help/Options.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Options - - - - -

- Sorry, not yet...

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/PortScan.htm b/mRemoteV1/Resources/Help/PortScan.htm deleted file mode 100644 index 5d96e08f4..000000000 --- a/mRemoteV1/Resources/Help/PortScan.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Port Scan - - - - -

- Sorry, not yet...

- - - diff --git a/mRemoteV1/Resources/Help/Prerequisites.htm b/mRemoteV1/Resources/Help/Prerequisites.htm deleted file mode 100644 index 00dbedc17..000000000 --- a/mRemoteV1/Resources/Help/Prerequisites.htm +++ /dev/null @@ -1,39 +0,0 @@ - - - - Prerequisites - - - - -

- Supported Operating Systems:

- -

- Prerequisites:

-
    -
  • Microsoft .NET Framework 4.0
  • -
  • Microsoft Terminal Services Client 8.0 or later.
    - Needed if you use RDP. mstscax.dll and/or msrdp.ocx must be registered.
    - Included with newer Windows versions. KB2592687 or KB2923545 is required for Windows 7/Windows Server 2008 R2. -
  • -
  • PuTTY
    - Needed if you use Telnet, SSH, Rlogin or RAW. Included in all packages.
    - An appropriate and integrated version is included with mRemoteNG. -
  • -
  • - Citrix ICA Client
    - Needed if you use ICA. wfica.ocx must be registered. -
  • -
- - - diff --git a/mRemoteV1/Resources/Help/QuickConnect.htm b/mRemoteV1/Resources/Help/QuickConnect.htm deleted file mode 100644 index 3f784d495..000000000 --- a/mRemoteV1/Resources/Help/QuickConnect.htm +++ /dev/null @@ -1,60 +0,0 @@ - - - - Quick Connect - - - - -

- The Quick Connect functionality of mRemoteNG allows you to quickly connect to a remote host using a variety of network protocols. -

- -

- Use Cases -

- -

- The primary use case for Quick Connect is to connect to remote hosts when you already remember the DNS hostname/IP address and the appropriate protocol for the connection. -
-
- An additional use case is to connect to remote hosts saved as a connection quickly. -

- -

- Prerequisites -

- -
    -
  • Knowledge of a DNS host name or IP address
  • -
  • Knowledge of an appropriate protocol to communicate with remote host
  • -
-

OR

-
    -
  • A predefined mRemoteNG connection
  • -
- -

- Using QuickConnect -

- -

- To use Quick Connect, ensure the Quick Connect toolbar is enabled by selecting View and then Quick Connect Toolbar. -
- Next, input a DNS host name or IP address into the box labeled "Connect". This box will also save previous entries during your session. -
- Quick Connect Toolbar -
-
- Quick Connect Toolbar -
-
- Select the appropriate network protocol by clicking the arrow next to the Connect box. -
- Quick Connect Toolbar -
-
- If you wish to use an existing connection, select the globe icon next to the protocol button and select the appropriate connection. -

- - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/QuickReference.htm b/mRemoteV1/Resources/Help/QuickReference.htm deleted file mode 100644 index c088ed03a..000000000 --- a/mRemoteV1/Resources/Help/QuickReference.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Quick Reference - - - - -

-

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/SaveAsExport.htm b/mRemoteV1/Resources/Help/SaveAsExport.htm deleted file mode 100644 index 6f0518181..000000000 --- a/mRemoteV1/Resources/Help/SaveAsExport.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Save As / Export - - - - -

- Sorry, not yet...

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/ScreenshotManager.htm b/mRemoteV1/Resources/Help/ScreenshotManager.htm deleted file mode 100644 index 9687ba0f2..000000000 --- a/mRemoteV1/Resources/Help/ScreenshotManager.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Screenshot Manager - - - - -

- Sorry, not yet...

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/Screenshots/CommonProblemsRDP/credssp-error.png b/mRemoteV1/Resources/Help/Screenshots/CommonProblemsRDP/credssp-error.png new file mode 100644 index 000000000..fc13abf4b Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/CommonProblemsRDP/credssp-error.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/CommonProblemsRDP/oracle_remediation_setting.png b/mRemoteV1/Resources/Help/Screenshots/CommonProblemsRDP/oracle_remediation_setting.png new file mode 100644 index 000000000..57c41d8fb Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/CommonProblemsRDP/oracle_remediation_setting.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Config/main_top_bar.png b/mRemoteV1/Resources/Help/Screenshots/Config/main_top_bar.png new file mode 100644 index 000000000..1f540c09b Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Config/main_top_bar.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Config/main_window.png b/mRemoteV1/Resources/Help/Screenshots/Config/main_window.png new file mode 100644 index 000000000..22ae8f3a0 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Config/main_window.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Connections/menu_top_bar.png b/mRemoteV1/Resources/Help/Screenshots/Connections/menu_top_bar.png new file mode 100644 index 000000000..15582b5ec Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Connections/menu_top_bar.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/ImportExport/export_dialog.png b/mRemoteV1/Resources/Help/Screenshots/ImportExport/export_dialog.png new file mode 100644 index 000000000..455b30548 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/ImportExport/export_dialog.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Main Menu/Main_Menu.png b/mRemoteV1/Resources/Help/Screenshots/Main Menu/Main_Menu.png new file mode 100644 index 000000000..22bf234ca Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Main Menu/Main_Menu.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Navigation/basic_panels.png b/mRemoteV1/Resources/Help/Screenshots/Navigation/basic_panels.png new file mode 100644 index 000000000..73f4b9d4b Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Navigation/basic_panels.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Navigation/panel_context_menu.png b/mRemoteV1/Resources/Help/Screenshots/Navigation/panel_context_menu.png new file mode 100644 index 000000000..990bbc20f Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Navigation/panel_context_menu.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Navigation/rdp_context_menu.png b/mRemoteV1/Resources/Help/Screenshots/Navigation/rdp_context_menu.png new file mode 100644 index 000000000..6a6da860a Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Navigation/rdp_context_menu.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Navigation/ssh_context_menu.png b/mRemoteV1/Resources/Help/Screenshots/Navigation/ssh_context_menu.png new file mode 100644 index 000000000..7f851f8bc Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Navigation/ssh_context_menu.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Navigation/view_menu.png b/mRemoteV1/Resources/Help/Screenshots/Navigation/view_menu.png new file mode 100644 index 000000000..71d9a1c52 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Navigation/view_menu.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Notifications/notification_warning.png b/mRemoteV1/Resources/Help/Screenshots/Notifications/notification_warning.png new file mode 100644 index 000000000..075e0d62f Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Notifications/notification_warning.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Notifications/popup_warning.png b/mRemoteV1/Resources/Help/Screenshots/Notifications/popup_warning.png new file mode 100644 index 000000000..288c5f461 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Notifications/popup_warning.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/01.png b/mRemoteV1/Resources/Help/Screenshots/Reference/01.png index 431af8282..50f2ee190 100644 Binary files a/mRemoteV1/Resources/Help/Screenshots/Reference/01.png and b/mRemoteV1/Resources/Help/Screenshots/Reference/01.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/add_new_folder.png b/mRemoteV1/Resources/Help/Screenshots/Reference/add_new_folder.png new file mode 100644 index 000000000..f41bd88b7 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/add_new_folder.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/config_panel_01.png b/mRemoteV1/Resources/Help/Screenshots/Reference/config_panel_01.png new file mode 100644 index 000000000..b348ac811 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/config_panel_01.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/config_panel_02.png b/mRemoteV1/Resources/Help/Screenshots/Reference/config_panel_02.png new file mode 100644 index 000000000..2622d2356 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/config_panel_02.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/example_01.png b/mRemoteV1/Resources/Help/Screenshots/Reference/example_01.png new file mode 100644 index 000000000..68413d735 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/example_01.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/example_02.png b/mRemoteV1/Resources/Help/Screenshots/Reference/example_02.png new file mode 100644 index 000000000..15c7ee3b8 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/example_02.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/example_03.png b/mRemoteV1/Resources/Help/Screenshots/Reference/example_03.png new file mode 100644 index 000000000..6f7caed54 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/example_03.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/example_04.png b/mRemoteV1/Resources/Help/Screenshots/Reference/example_04.png new file mode 100644 index 000000000..19de6c6be Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/example_04.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/example_05.png b/mRemoteV1/Resources/Help/Screenshots/Reference/example_05.png new file mode 100644 index 000000000..c2a684444 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/example_05.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/example_06.png b/mRemoteV1/Resources/Help/Screenshots/Reference/example_06.png new file mode 100644 index 000000000..29581dc9d Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/example_06.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/new_connection.png b/mRemoteV1/Resources/Help/Screenshots/Reference/new_connection.png new file mode 100644 index 000000000..574568eee Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/new_connection.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/new_connection_test_item.png b/mRemoteV1/Resources/Help/Screenshots/Reference/new_connection_test_item.png new file mode 100644 index 000000000..d03747ff3 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/new_connection_test_item.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/open_connection.png b/mRemoteV1/Resources/Help/Screenshots/Reference/open_connection.png new file mode 100644 index 000000000..62f7ac786 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/open_connection.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Reference/status_icon.png b/mRemoteV1/Resources/Help/Screenshots/Reference/status_icon.png new file mode 100644 index 000000000..efdfbfe91 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Reference/status_icon.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Screenshot Manager/rightclick_screenshot.png b/mRemoteV1/Resources/Help/Screenshots/Screenshot Manager/rightclick_screenshot.png new file mode 100644 index 000000000..f63cfc42d Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Screenshot Manager/rightclick_screenshot.png differ diff --git a/mRemoteV1/Resources/Help/Screenshots/Screenshot Manager/screenshot_manager.png b/mRemoteV1/Resources/Help/Screenshots/Screenshot Manager/screenshot_manager.png new file mode 100644 index 000000000..c1413c678 Binary files /dev/null and b/mRemoteV1/Resources/Help/Screenshots/Screenshot Manager/screenshot_manager.png differ diff --git a/mRemoteV1/Resources/Help/Update.htm b/mRemoteV1/Resources/Help/Update.htm deleted file mode 100644 index 339d3a563..000000000 --- a/mRemoteV1/Resources/Help/Update.htm +++ /dev/null @@ -1,13 +0,0 @@ - - - - Update - - - - -

- Sorry, not yet...

- - - \ No newline at end of file diff --git a/mRemoteV1/Resources/Help/gs_command_line_switches.htm b/mRemoteV1/Resources/Help/gs_command_line_switches.htm new file mode 100644 index 000000000..23c5fa119 --- /dev/null +++ b/mRemoteV1/Resources/Help/gs_command_line_switches.htm @@ -0,0 +1,78 @@ + + + + + Command-Line Switches + + + +
+ Complete from nmat updates, please remove this div after review. +
+

+ The following is a list of command line switches supported by mRemoteNG. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommandDescription
+ /cons:PathToConnectionsFile +

+ /c:PathToConnectionsFile +
+ Loads the connections file from the given path. +

+ This path can be a: +
    +
  • full file path
  • +
  • path relative to the current directory
  • +
  • path relative to the mRemoteNG application directory
  • +
  • path relative to the mRemoteNG default connection file directory
  • +
+
/resetResets window position, panels and toolbars
+ /resetpos +

+ /rp +
Reset the windows position
+ /resetpanels +

+ /rpnl +
Resets all panel's positions. Use this if you have troubles with panel layouts
+ /resettoolbar +

+ /rtbr +
Resets the positions of all toolbars
+ /noreconnect +

+ /norc +
Temporary disables reconnect to previously opened sessions. Use this if you have problems opening mRemoteNG after you enabled the setting and restarted mRemoteNG
+
+ + diff --git a/mRemoteV1/Resources/Help/gs_installation.htm b/mRemoteV1/Resources/Help/gs_installation.htm new file mode 100644 index 000000000..8526efb9c --- /dev/null +++ b/mRemoteV1/Resources/Help/gs_installation.htm @@ -0,0 +1,43 @@ + + + + + Installation + + + +
+ Done from nmat, remove this div after review. +
+

Information

+

+ Downloads are provided in four different packages, the setup package, binary package, + portable package and + the source package. They are described below. +

+

Setup Package

+

+ The setup package is the compiled version of mRemoteNG which comes in an MSI installer.
+ The common way to get mRemoteNG up and running +

+

Portable Package

+

+ The portable package consists of the same files as the bin package but contains + an modified version of the executable which stores and loads all your settings + from files in the application's directory.
+ This package can be used to run mRemoteNG from an USB stick an preserve your + configuration wherever you go. +

+

Source Package

+

+ The source package is a zip package and contains the source code in form of a + Visual Studio solution. +

+

Updating and Uninstalling

+

+ mRemoteNG can be updated without uninstalling it before.
+ For portable version of mRemoteNG stores all user data in same folder as + mRemoteNG.exe file. +

+ + diff --git a/mRemoteV1/Resources/Help/gs_prerequisites.htm b/mRemoteV1/Resources/Help/gs_prerequisites.htm new file mode 100644 index 000000000..414384104 --- /dev/null +++ b/mRemoteV1/Resources/Help/gs_prerequisites.htm @@ -0,0 +1,115 @@ + + + + + Prerequisites + + + +
+ Done from nmat, remove this div after review +
+ +

Supported Operating Systems:

+
+ +

Prerequisites:

+
+
    +
  • + Microsoft .NET Framework 4.0 +
  • +
  • + Microsoft Terminal Services Client 8.0 or later. +
      +
    • Needed if you use RDP. mstscax.dll and/or msrdp.ocx must be registered.
    • +
    • + Included with newer Windows versions. + KB2574819 AND either + KB2592687 or + KB2923545 + is required for Windows 7/Windows Server 2008 R2 +
    • +
    +
  • +
  • + PuTTY +
      +
    • Needed if you use Telnet, SSH, Rlogin or RAW. Included in all packages.
    • +
    • An appropriate and integrated version is included with mRemoteNG.
    • +
    +
  • +
  • + Citrix ICA Client +
      +
    • Needed if you use ICA. wfica.ocx must be registered.
    • +
    +
  • +
+ + +

Windows™ 7/Windows Server 2008 R2 clients (requirements)

+
+ TIP! You can use powershell to fetch if the hotfixes are installed. Try using example: +

+ Get-HotFix | where {$_.HotFixID -eq "KB2574819" -and $_.HotFixID -eq "KB2592687"} +
+

+ The following updates must be present on any Windows 7 or Server 2008 client that will be + running mRemoteNG. (They must have been installed in the order provided below): +

+ +

The following are suggested (but not required) for Windows 7 / Server 2008 clients:

+ + + + diff --git a/mRemoteV1/Resources/Help/gs_running_mremoteng.htm b/mRemoteV1/Resources/Help/gs_running_mremoteng.htm new file mode 100644 index 000000000..abf39373f --- /dev/null +++ b/mRemoteV1/Resources/Help/gs_running_mremoteng.htm @@ -0,0 +1,177 @@ + + + + + Running mRemoteNG + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

First Run

+
+

+ Here is a quick reference of the interface: +

+ +

+ The screenshot above explains the most basic of the interface. To understand it all + we are creating a small tutorial here. +

+ +

Creating a connection

+

+ Right click on the root item (the little blue globe named "Connections") in + the Connections panel and select "New Connection". Or use the keybinding + Ctrl+N if the Connections are selected. +

+ +

+ A new item shows up under the root item. You can give it a name now + (or rename it later). Here we just name it "Test". +

+ +

+ Now lets look at the Config panel in the bottom left, just under the + Connections panel. +

+ +

+ As you may notice this is where you configure all the properties of connections + and folders.
+ There are a lot of values that can be set but for our first connection we will + keep things simple. +

+

+ The most important things right now are that we tell the application which host + we want to connect to and which protocol we want to use.
+ In this example we will use a Windows 2012 R2 server that has RDP (Remote Desktop + Protocol) enabled.
+ As RDP is the default protocol whenever you create a new connection we don't have + to change anything there. +

+

+ The next thing we will do is to fill in the Hostname/IP field with the hostname + we want to connect to. Lets also fill in a username and password so that we login + automatically to the server. +

+ +

+ Lets now try to connect to the server. +

+
+ TIP! You can see an indicator in the properties window that is glowing green. + +

+ This icon does a ICMP ping on to check response from the server. If it glows green + it indicates a connection response can be made using ping to the host. + However this is turned off on windows by default. You have to enable ICMP and allow + the firewall access for it. +
+

Opening and Closing Connections

+

+ There are multiple ways to open a connection in mRemoteNG, but the easiest + way is to double click the connection in the Connections panel. +

+

+ If you double click the connection you will notice that the connection is going + to try and open in a new panel called  General  and under a tab + called  Test . +

+ +
+ NOTE! If the connection fails you will find out what the problem was + in the dialog notifications panel. +
+

+ If all goes well you should see the remote desktop without any problems. +

+

+ To close the connection you can do any of the following: +

    +
  • Log off in the start menu - Closes the connection and logs you out completely from RDP
  • +
  • Close the panel with the - Which leaves your session active on server but closes connection in mRemoteNG
  • +
  • Close the connection tab with - Also keeps your login active on server but closes RDP connection in mRemoteNG
  • +
  • Double click the connection tab - Same as above where the connection is active on server but closes RDP connection in mRemoteNG
  • +
+

+

Folders and Inheritance

+

+ Folders on mRemoteNG cannot only be used to categorize connections but also to + apply properties to the underlying connections. +

+

Example

+

+ You have 10 Remote Desktop enabled servers in one domain and 15 in another domain. +

+

+ Normally you would spend a lot of time creating all those connections and setting + the individual properties like username, password, etc. In mRemoteNG there is an + easier way. You just create two folders, one for domain A and one for domain B + and set all properties there. +

+

+ Then create the Connections and let them inherit every property. The only + properties left to fill on Connection basis are the Connections name and hostname. + Everything else will be inherited from the parent folder. +

+

+ Here is how you do this: +

+

1. Add the folder

+

+ This can be done with: +

    +
  • Right click on connections and click on New Folder
  • +
  • File > New Folder
  • +
  • Or with keybinding: Ctrl+Shift+N
  • +
+

+ +

+ Then give it a name and fill all the properties you need (like you did with + the test connection) +

+
+ +

+ When you have filled in the settings and values you can either just drag the test + Connection inside the folder or create a new one. +

+ +

+ Right now nothing has changed and nothing will be inherited.
+ To enable inheritance switch to the inheritance view by clicking the + dedicated button. (Marked with a red arrow below) +

+ +

+ The properties that show up now are almost the same as before, but you + only select yes or no to enable or disable a inheritance. +

+ +

+ When no is selected the property will not be inherited, yes indicates + an inherited property. +

+

+ For this test set Inherit Everything to Yes. +

+

+ Now if you switch back to the properties view (the button left + of the inheritance button) you should see that not much is left of all + those properties. +

+ +

+ Only the Name and Hostname/IP properties are left over, everything else will be + inherited from the parent folder. +

+

+ Of course you can also only let some of the properties be inherited. Just play + around with this a bit and you'll get the hang of it. +

+ + diff --git a/mRemoteV1/Resources/Help/st_common_problems_rdp.htm b/mRemoteV1/Resources/Help/st_common_problems_rdp.htm new file mode 100644 index 000000000..6a418d772 --- /dev/null +++ b/mRemoteV1/Resources/Help/st_common_problems_rdp.htm @@ -0,0 +1,66 @@ + + + + + Common Problems (RDP) + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

Introduction

+

+ Its hard to make a document on all problems that can occur with connections + but here at least we are trying to list some of the most common problems for RDP + that has been noticed. +

+ + +

Quick Reference

+ + + + +

CredSSP - CVE-2018-0886 - Authentication error

+

+ mRemoteNG uses the Microsoft Terminal Services Client (MSTSC) libraries in order + to make Remote Desktop connections. mRemoteNG has no control over the functionality + changes implemented by Microsoft. +

+

+ Relevant line of code that shows our + "RDP Client" connection "object": + + private MsRdpClient8NotSafeForScripting _rdpClient; +

+

+ Relevant MS documentation for this .NET class: + MsRdpClient8NotSafeForScripting class +

+

+ Please refer to + Microsoft's documentation + for full details regarding this problem. +

+

+ Patched clients attempting to connect to Unpatched servers will fail with the following error: +

+ +

+ The same error will occur with MSTSC directly on a + patched client attempting to connect to an unpatched server. +

+

Per the MS documentation, the only ways around this are to:

+
    +
  • Patch the servers
  • +
  • set the "Encryption Oracle Remediation" policy to "Vulnerable" - refer to the MS documentation above for details:
    +
  • +
  • Uninstall KB4103727
  • +
+ + + diff --git a/mRemoteV1/Resources/Help/ui_config.htm b/mRemoteV1/Resources/Help/ui_config.htm new file mode 100644 index 000000000..aed8bc99b --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_config.htm @@ -0,0 +1,67 @@ + + + + + Config + + + +
+ Complete from nmat updates, please remove this div after review. Need information in properties and inheritance. +
+ + +

Introduction

+
+ +

+ Config dialog to setup the connection specific properties. + This includes inheritance from other items before the item and more. Details below is about + how to work with this dialog to get the most out of connections and configuration. +

+

Quick Reference

+
    +
  • Top Bar - Main top bar information.
  • +
+ + + +

Top Bar

+
+

+ +

+ Red - Sort values Categories or Alphabetical.
+ Green - Show Properties, Inheritance values
+ Blue - Connection icon
+ Yellow - Host status (based on ICMP ping) +

+

+

Sort Values

+

+ Sorts the values in properties either by Categories or Alphabetically. +

+ Categories sort - Shows values in categories with expanding options.
+ Alphabetical sort - Expands everything and shows values in alphabetical order instead +

+

+

Properties and Inheritance

+

+ +

+

Icon

+

+ The icon indicates the visual identifier for the connection. Clicking the icon will let you set a different icon + for the connection. +

+
+ NOTE! Don't forget that mRemoteNG will save the change on exit auto unless you have unchecked this setting in options. +
+

Status

+

Is a indicator that will glow red or green depending on the status of the host. The status is based on ICMP ping to the host.

+
+ IMPORTANT! In order for this to work you have to open up ICMP. On windows servers this is also disabled in windows firewall. +
+ + + diff --git a/mRemoteV1/Resources/Help/ui_connections.htm b/mRemoteV1/Resources/Help/ui_connections.htm new file mode 100644 index 000000000..c67afec6d --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_connections.htm @@ -0,0 +1,86 @@ + + + + + Connections + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

Introduction

+
+

+ The connections dialog is the main collection of all connections that is added to mRemoteNG. This document will + explain the details of the connections dialog. +

+ + +

Top Menu Bar

+
+

+ +

+ Red - New Connection
+ Green - New Folder
+ Blue - View (Expand/Collapse all folders)
+ Yellow - Ascending sort +

+

+

Quick Reference

+ + + + +

New Connection

+
+

+ Creates a new connection item in the connections dialog after where cursor is present. +

+
+ TIP! You can also duplicate an already created connection if you want to follow + some sort of template of a connection. Just right click on folder or connection to + duplicate the item. The information is then carried over for editing. This can save a lot + of time when the connection list is large. +
+ + + +

New Folder

+
+

+ Creates a new folder in connections dialog after where cursor is present. +

+
+ TIP! Folders can help to make adding connections easier. By setting a folder with + some values that can be inheritaded down to the connections. Read more about this in + Configuration +
+ + + +

View

+
+

+ Collapses or expands all directories in the connection dialog. Useful when working with + a lot of connections sorted in different directories. +

+ + + +

Ascending

+
+

+ Works like a sort or a refresh to get connection in ascending order. (Descending order is + note supported yet) When you have been moving around in the tree of connections, just click + this item to refresh the list and get everything in ascending ordering. +

+ + + diff --git a/mRemoteV1/Resources/Help/ui_external_tools.htm b/mRemoteV1/Resources/Help/ui_external_tools.htm new file mode 100644 index 000000000..eafa63ba2 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_external_tools.htm @@ -0,0 +1,256 @@ + + + + + External Tools + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

Introduction to External Tools

+

+ External Tools can help you get things done that can't be done in mRemoteNG.
+ You can for example start a command prompt or launch your favorite FTP tool from within mRemoteNG.
+ This wouldn't make much sense by itself because you can already launch your + applications by using the Windows Start Menu, Quick Launch or whatever you + prefer to use to start your apps. +

+

+ But there's more! +

+

+ In mRemoteNG, you can launch applications and tell them what to do with the use of + arguments (parameters) and variables of the currently selected Connection. + You can, for example, select your home router's SSH Connection entry and do a + traceroute (tracert) on that host. This is much quicker and more powerful than + opening the console and typing "tracert yourhost". +

+

+ The external tools configuration is stored in %APPDATA%\mRemoteNG\extApps.xml +

+

Variables

+

+ Variables and arguments can be used to tell the external tool what to do. +

+

+ This is the list of variables supported by mRemoteNG: +

+
    +
  • %NAME%
  • +
  • %HOSTNAME%
  • +
  • %PORT%
  • +
  • %USERNAME%
  • +
  • %PASSWORD%
  • +
  • %DOMAIN%
  • +
  • %DESCRIPTION%
  • +
  • %MACADDRESS%
  • +
  • %USERFIELD%
  • +
+

+ Variables always refer to the currently selected connection. Variable names are case-insensitive. + Variables can be used in both the Filename and Arguments fields. +

+

+ mRemoteNG will also expand environment variables such as %PATH% and %USERPROFILE%. + If you need to use an environment variable with the same name as an mRemoteNG + variable, use \% instead of %. The most common use of this is for the USERNAME + environment variable. %USERNAME% will be expanded to the username set in the + currently selected connection. \%USERNAME\% will be expanded to the value set in + the USERNAME environment variable. +

+

+ If you need to send a variable name to a program without mRemoteNG expanding it, + use ^% instead of %. mRemoteNG will remove the caret (^) and leave the rest + unchanged. For example, ^%USERNAME^% will be sent to the program as %USERNAME% + and will not be expanded. +

+

Special Character Escaping

+

+ Expanded variables will be escaped using the rules below. There are two levels + of escaping that are done. The first is escaping for standard argument splitting + (C/C++ argv, CommandLineToArgvW, etc). The second is escaping shell + metacharacters for ShellExecute. +

+

Argument splitting escaping:

+
    +
  • Each quotation mark will be escaped by a backslash.
  • +
  • One or more backslashes (\) followed by a quotation mark ("): +
      +
    • Each backslash will be escaped by another backslash.
    • +
    • The quotation mark will be escaped by a backslash.
    • +      If the connection's user field contains + "This" is a \"test\".
      +      Then %USERFIELD% is replaced with + \"This\" is a \\\"test\\\". +
    +
  • +
  • A variable name followed by a quotation mark (for example, %USERFIELD%") with + a value ending in one or more backslashes: +
      +
    • Each backslash will be escaped by another backslash.
    • +
    • Example:
    • +      If the connection's user field contains c:\Example\
      +      Then "%USERFIELD%" is replaced with "c:\Example\\" +
    +
  • +
+

+ To disable + argument splitting escaping for a variable, precede its name with a minus (-) + sign. For example, %-USERFIELD%. +

+

Shell metacharacter escaping:

+
    +
  • The shell metacharacters are ( ) % ! ^ " < > & |
  • +
  • Each shell metacharacter will be escaped by a caret (^).
  • +
+

+ To disable both argument splitting and shell metacharacter escaping for a + variable, precede its name with an exclamation point (!). For example, + %!USERFIELD%. This is not recommended and may cause unexpected results. +

+

+ Only variables that have been expanded will be escaped. It is up to you to + escape the rest of the arguments. +

+ +

Variable Examples

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentsUser FieldResult
%USERFIELD%"Example" Text\^"Example\^" Text
%-USERFIELD%"Example" Text^"Example^" Text
%!USERFIELD%"Example" Text"Example" Text
^%USERFIELD^%"Example" Text%USERFIELD%
^^%USERFIELD^^%"Example" Text^%USERFIELD^%
-d "%USERFIELD%"c:\Example\-d "c:\Example\\"
-d "%-USERFIELD%"c:\Example\-d "c:\Example\"
-d "%USERFIELD%"Left & Right-d "Left ^& Right"
-d "%!USERFIELD%"Left & Right-d "Left & Right"
%WINDIR%N/Ac:\Windows\
\%WINDIR\%N/Ac:\Windows\
\^%WINDIR\^%N/A\%WINDIR\%
\\%WINDIR\\%N/A\\%WINDIR\\%
+

Example

+

+ First of all, start the external tools editor. To do this, click Tools in the main menu and + select External Tools.
+ You will see a screen like on the following screenshot. +

+

+ +

+

+ The fields below the list are greyed out because you haven't created an external tool + entry yet.
+ To create one, right click the blank area in the list and select Add, as in the + screenshot below. +

+

+ +

+

+ This is what you'll get: +

+

+ +

+

+ So the three fields are now available and need to be filled.
+ The Display Name is simply the name you will see when you want to launch that + tool, so give it a descriptive name.
+ I named mine Traceroute as I will create a external tool that will start the + tracert command in the console. +

+

+ +

+

+ Ok, the next thing we'll need is a filename. This is the program that we + want to be executed.
+ I simply type in cmd for a Windows cmd console. +

+

+ +

+

+ Now the fun part comes in—the arguments.
+ The Windows cmd has a command line argument that tells the console to launch the + command followed by that argument and stay open.
+ It's /K. (There's also /C, this is useful when you want the console to close + after the command was executed)
+ In this case, I'll use /K as I want to look through the result when the command + completes.
+ After that, I just type tracert %HostName%. This tells the console to do a + traceroute on the hostname of the currently selected Connection. +

+

+ +

+

+ Alright! That's all we'll need.
+ Now right click one of you connections, click Tools, External Tools + and select Traceroute. +

+

+ +

+

+ Voilà! A console window will popup and execute your tracert command. +

+

+ +

+ + diff --git a/mRemoteV1/Resources/Help/SSHFileTransfer.htm b/mRemoteV1/Resources/Help/ui_file_transfer.htm similarity index 58% rename from mRemoteV1/Resources/Help/SSHFileTransfer.htm rename to mRemoteV1/Resources/Help/ui_file_transfer.htm index 5ff2655e1..33adffbe7 100644 --- a/mRemoteV1/Resources/Help/SSHFileTransfer.htm +++ b/mRemoteV1/Resources/Help/ui_file_transfer.htm @@ -1,33 +1,42 @@ - - + + + SSH File Transfer - + +
+ Complete from nmat updates, please remove this div after review. +
-

- Introduction to SSH File Transfer -

+ +

Introduction

+

- SSH File Transfer functionality allows you to securely transfer files to a remote host over an encrypted tunnel using either SFTP or SCP. + SSH File Transfer functionality allows you to securely transfer files to a remote host over an encrypted tunnel using either SFTP or SCP.

+ -

- Use Cases -

-

- The primary use case is to upload individual files, such as configuration files, to a remote host. -

+ +

Use Cases

+
+

The primary use case is to upload individual files, such as configuration files, to a remote host.

+ -

Prerequisites

+ +

Prerequisites

+
  • SSH File Transfer requires an SSH service to listen on an available network port (default 22) on a remote host.
  • A username and password must be supplied to connect with the remote host.
  • The remote host must have a writeable folder on its filesystem to place the transferred files.
+ -

Configuration Options

+ +

Configuration Options

+
  • Host - The remote host you connect to. Can be DNS name or IP address.
  • Port - Remote network port listening for SSH/SFTP/SCP traffic.
  • @@ -35,43 +44,52 @@
  • Password - Password for account to log on to remote host.
  • Protocol - Choice of SCP or SFTP protocol used for communication.
  • Local File - Path of file to transfer from local host.
  • -
  • Remote File - Path where file will be transferred on remote host.
    - Example: /home/John/Documents
  • +
  • Remote File - Path where file will be transferred on remote host. +
      +
    • Example: /home/John/Documents
    • +
    +
+ -

Using SSH File Transfer

+

Using SSH File Transfer

+

- To begin, select Tools and then SSH File Transfer. The tool will fill the window and allow you to input the configuration options. Each piece of information is needed for a successful transfer. + To begin, select Tools and then SSH File Transfer. + The tool will fill the window and allow you to input the configuration options. + Each piece of information is needed for a successful transfer.

- To populate the Local File option, select the Browse button and navigate to the desired file on the local filesystem. To populate the Remote File option, manually type desired filesystem path, including the desired file name. + To populate the Local File option, select the Browse button and navigate to + the desired file on the local filesystem. To populate the Remote File option, + manually type desired filesystem path, including the desired file name.

- Once all options are populated, select Transfer and the progress bar at the bottom of the window will show the progress. + Once all options are populated, select Transfer and the progress bar at the bottom + of the window will show the progress.

-

Troubleshooting SSH File Transfer

+

Troubleshooting SSH File Transfer

+

To troubleshoot issues with SSH File Transfer, consult the log under %AppData%\mRemoteNG\mRemoteNG.log. This log provides verbose information about successful and failed connections. -
-
- - Common Issues - -
-
- ERROR- Please fill all fields
+

+

Common Issues

+

+ ERROR- Please fill all fields +
This issue was likely encountered because you did not provide all information needed to establish the connection. -
-
- System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it
- This issue was likely encountered because the local host could not contact the remote host specified on the remote port specified.
+

+ System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it +
+ This issue was likely encountered because the local host could not contact the remote host specified on the remote port specified. +
The issue may be caused by improperly configured firewall rules or a SSH service not listening properly on the remote host. -
-
- [14] ERROR- SSH background transfer failed!
+

+ [14] ERROR- SSH background transfer failed! +
This issue was likely encountered due to a permissions issue. Ensure you have appropriate access to write to the specified Remote File.

diff --git a/mRemoteV1/Resources/Help/ui_import_and_export.htm b/mRemoteV1/Resources/Help/ui_import_and_export.htm new file mode 100644 index 000000000..659c2b339 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_import_and_export.htm @@ -0,0 +1,48 @@ + + + + + Import/Export + + + +
+ Complete from nmat updates, please remove this div after review. +
+ + +

Introduction

+
+

+ Import/Export is for importing or exporting your configuration of connections. +

+ + + +

Import

+
+

Import from File...

+

+ Opens a normal file load dialog to open a exported xml or csv file for mRemoteNG. + See Export to file... further down this page for information on + exporting your connections. +

+

Import from Active Directory

+

+ If you have servers that is located in a domain. Then this option can be used to fetch + those servers to easily import them to mRemoteNG. +

+

Import from Port Scan

+ + + +

Export to file...

+
+

+ Here you can export your settings to a file to share or backup. The dialog shown below + is the dialog of which you chose the options to export. +

+ + + + diff --git a/mRemoteV1/Resources/Help/ui_keyboardshortcuts.htm b/mRemoteV1/Resources/Help/ui_keyboardshortcuts.htm new file mode 100644 index 000000000..bbe18af21 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_keyboardshortcuts.htm @@ -0,0 +1,106 @@ + + + + + Keyboardshortcuts + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

Keybindings

+

File

+ + + + + + + + + + + + + + + + + + + + + + + + + +
KeybindingAction
Ctrl+NNew Connection
Ctrl+Shift+NNew Folder
Ctrl+OOpen Connection File...
Ctrl+SSave Connection File
Ctrl+Shift+SSave Connection File As...
+ +

View

+ + + + + + + + + + + + + + + + + +
KeybindingAction
Ctrl+Alt+CJump to (Connections and Config)
Ctrl+Alt+EJump to (Notifications)
F11Fullscreen
+ +

Connections

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeybindingAction
Ctrl+Shift+CConnect
Ctrl+DDuplicate
F2Rename
DelDelete...
Ctrl+UpMove Up
Ctrl+DownMove Down
+ +

Help

+ + + + + + + + + +
KeybindingAction
F1mRemoteNG Help
+ + diff --git a/mRemoteV1/Resources/Help/ui_menus.htm b/mRemoteV1/Resources/Help/ui_menus.htm new file mode 100644 index 000000000..df4d7c8f4 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_menus.htm @@ -0,0 +1,224 @@ + + + + + Menus + + + +
+ Complete from nmat updates, please remove this div after review. +
+ + +

Introduction

+
+ +

+ In this section we are going to explain the menus located in mRemoteNG. The above screenshot shows the main menu with colors. Short color explanation: +

+ Red - Anchor to move menu around the interface
+ Green - The menu items +

+

+

Quick Reference

+
    +
  • File Menu - Contains standard commands for the application
  • +
  • View Menu - Menu for additional dialogs for mRemoteNG
  • +
  • Tools Menu - Additional tools that can be used and triggered in mRemoteNG
  • +
  • Help Menu - Get more information for the application
  • +
+ + + +

File Menu

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescription
New ConnectionWill add a new connection to the Connections dialog after where the cursor is positioned.
New FolderAdd a new folder in the Connections dialog tree where the cursor is positioned.
New Connection FileCreate a new connection file. Dialog will come up asking about: filename and where to place the new connection file.
Open Connection File + Open a connection file. Dialog comes up asking about which file to open. For security reasons, this also shows a dialog + to ask if you want to save the current file before continuing. +
Save Connection FileSaves the currently opened connection file. If you are using a SQL server connection instead it will send a save to the SQL server.
Save Connection File As...Saves the current connection file to a specific location on disk.
Delete...Delete currently selected item in connections dialog.
RenameRename current selected item in connections dialog.
DuplicateDuplicate current selected item in connections dialog.
Reconnect All Open ConnectionsSends a reconnect to all the open connections in mRemoteNG.
ExitExit mRemoteNG application
+ + + +

View Menu

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescription
Add Connection PanelCreate a new and empty panel.
Connection PanelsJump to panel.
ConnectionsShow connections dialog
ConfigShow config dialog
NotificationsShow notifications dialog
ScreenshotsOpen Screenshots panel (See: ScreenshotManager for more information)
Jump ToPlace focus on "Connections and Config" or "Notifications" panel based on selection.
Reset layoutResets the layout of panels and dialogs. Warning will come up about the action before continuing.
Lock toolbar positionsLocks the toolbars at the top of the application so you do not move around items by mistake.
Quick Connect ToolbarShow quick connect toolbar
External Tools ToolbarShow external tools toolbar
Multi SSH ToolbarShow multi ssh toolbar
FullscreenFullscreen mRemoteNG (will not fullscreen connection window but only the mRemoteNG application)
+ + + +

Tools Menu

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescription
SSH File TransferShow SSH file transer panel (See: SSH File Transfer for more details)
External ToolsShow external tools dialog (See: External Tools for more details)
Port ScanShow port scan dialog (See: Port Scan for more details)
Components CheckShow installed components requirements test
OptionsOpens mRemoteNG global settings and options dialog
+ + + +

Help Menu

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescription
mRemoteNG HelpShow help panel (this panel)
WebsiteGo to mRemoteNG website
DonateGo to mRemoteNG donation page. (Please help keep mRemoteNG awesome!)
Support ForumGo to mRemoteNG suport forum (Best place is still chat for fast answers)
Report a BugGo to github page to report a bug found
Check for UpdatesOpens dialog to check for any updates of mRemoteNG
AboutOpen about dialog for mRemoteNG (Shows contributors, changelog and more)
+ + + diff --git a/mRemoteV1/Resources/Help/ui_navigation.htm b/mRemoteV1/Resources/Help/ui_navigation.htm new file mode 100644 index 000000000..141adffb5 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_navigation.htm @@ -0,0 +1,134 @@ + + + + + Navigation + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

Introduction

+

+

+

Quick Reference

+ + + +

+

+ mRemoteNG is using panels and tabs to stay organized but also to create a better + view of all multitasking that is being done inside the application. Because + of that it can be good to know some more information on how to work with panels + and tabs to get the most out of those features. +

+

Panels

+

+ Panels are used to organize tabbed connections. This might seem + a bit confusing but its a great way to stay organized. Below is a few examples + of how to use panels to give you a hands on better view of them. +

+
    +
  • + Test and Production - You can add 2 panels where you have the test servers + are located and the other where production servers are running. +
  • +
  • + Datacenters - Maybe you divide them into datacenters. +
  • +
  • + Temp project - To see all servers you work on for a temporary project. +
  • +
  • + Home vs Work - Maybe you are sneaky at work and want to login at home to + check you machine at home for something while keeping work in its own panel. +
  • +
  • + ...and many more +
  • +
+

+ For this tutorial we will keep it simple with Domain A and Domain B. Where both + have their own panels. +

+ +

Creating panels

+

+ Usually panels are created using connections and folders to stay organized + automatic when making connections. However you can also create panels manually. + See below: +

+ +

+ Creating manual panels will make you able to organize tabs manually in mRemoteNG. + To then open a connection to the new panel then Right click on connection and use + "Connect (with options)" > Choose panel before connecting +

+

+ The other option in the menu named "Connection Panels" will list all panels + in open in the current running mRemoteNG window. +

+

More options

+

+ Right click menu for panels will give you a few more options for the panels: +

+ +
    +
  • Rename - Rename the panel
  • +
  • + Send To... - Send the whole panel to monitor/screen [number]. Note this + is not a real window but a detachable panel. So if you double click the title + the panel will go back to mRemoteNG and not fullscreen the window. +
  • +
+

Tabs

+

+ Speaking plain the tabs are also the connections that is open in mRemoteNG. + There are few tips and tricks regarding tabs and we will try to list them here. + In the below examples we will give you examples of RDP and SSH connections. +

+

Right click conext menu

+

+ The right click context menu allows you to trigger som additional actions on + tabs for example: Rename Tab, Duplicate Tab, Reconnect, Disconnect etc. Below + are the two context menus from RDP and SSH. +

+
+

RDP context menu

+ +
+
+

SSH context menu

+ +
+

+ If you check the difference between the menus you can see that there are some + actions that differ depending on the connection. This is intentional since its + specific for the type of connection. +

+

+ The default and always available menu items are: +

    +
  • Screenshot - Create a screenshot to Screenshot Manager
  • +
  • External Tools - Run external tool script/action
  • +
  • Rename Tab - Rename current tab
  • +
  • Duplicate Tab - Duplicate tab connection
  • +
  • Reconnect - Reconnect the current tab
  • +
  • + Disconnect - Disconnect the current tab (Double clicking the tab + will also disconnect the current tab. If you want to change this action then + go to Tools > Options > Tabs & Panels and uncheck + "Double click on tab closes it") +
  • +
+ Click around and try it out. You will get the hang of it. +

+ + + diff --git a/mRemoteV1/Resources/Help/ui_notifications.htm b/mRemoteV1/Resources/Help/ui_notifications.htm new file mode 100644 index 000000000..34aa16196 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_notifications.htm @@ -0,0 +1,82 @@ + + + + + Notifications + + + +
+ Complete from nmat updates, please remove this div after review. +
+ + +

Introduction

+
+

+ Notifications panel contains information for any errors or informational messages that + mRemoteNG triggers. Some example errors can be if there is a problem to connect, information + on lost connection and so much more. +

+

Settings for notifications

+
+

+ Notification settings can be found in (Tools > Options > Notifications) below we will explain what + can be set and how they do affect for various troubleshooting. +

+ + + +

Notifications general settings

+ notification warning +

+ This will tell mRemoteNG what type of messages and the level of messages to send to the panel. + It does not the level for the log that mRemoteNG has but only for panel output. +

+

There is also 2 different options mentioned below:

+
    +
  • + Show these message types - Level of messages to show in panel. + (default: Warnings and Errors) +
  • +
  • + Switch to Notifications panel on - If interface should switch to + the panel when a level of message occurs (default: all enabled) +
    + TIP! If you dont want the panel to show at all. Then unmark all options in + Switch to Notification panel on. Then the panel will not come up automatic. +
    +
  • +
+ + + +

Logging settings

+

+ Here you define the logging of messages. That is a continues log which can be used to backtrack + any error that has occurred. Good when for example reporting issues about mRemoteNG or to check + more details about problems. +

+
    +
  • + Log path - Choose where the log should recide + (default: Log to application directory) +
  • +
  • + Log these message types - Level of logging to logfile + (default: Informations, Warnings, Errors) +
  • +
+ + + +

Popups settings

+ popup warning +

+ When items are selected here you will recieve a popup on the error that occurrs based on level + chosen in settings here. This can be useful if you do not want to use the notification area and only + get a popup if error occurs. (default: all off) +

+ + + diff --git a/mRemoteV1/Resources/Help/ui_options.htm b/mRemoteV1/Resources/Help/ui_options.htm new file mode 100644 index 000000000..c4e6b78e3 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_options.htm @@ -0,0 +1,456 @@ + + + + + Options + + + +
+ Complete from nmat updates, please remove this div after review. Need help with missing information here. +
+ + +

Introduction

+
+

+ Options window which can also be named settings is the window where you can personalize + your options for all of mRemoteNG. This includes how to set logging, credentials and so on. + Continue reading for the details of the different options here. +

+

Quick Reference

+ + + + +

Startup/Exit

+

+ Options below are for the various settings for Startup/Exit of mRemoteNG. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
Save connection on exitOnSave to connection file/database on exit of mRemoteNG.
Reconnect to previously opened sessions on startupOff + This option will allow you to open the connection from which + you where connected to after last exit of application. +
Allow only a single instance of the application (mRemoteNG restart required)Off + Enforces and makes sure only a single instance of mRemoteNG is running on the + computer. +
Check proper installation of components at startupOffOpens the panel for Components Check on every startup.
+ + + +

Appearance

+

+ Various options for mRemoteNG appearance. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
Language(Automatically Detect)Which language to use for the interface of mRemoteNG.
Show description tooltips in connection treeOff + Holding mouse over a item in connection tree will show a popout from mouse + with information. +
Show full connections file path in window titleOff + Adds the complete path to the title of mRemoteNG to where the connection file is + located. +
Always show notification area iconOff + Adds mRemoteNG to the taskbar in the OS. +
Minimize to notification areaOff + Will place mRemoteNG in taskbar on minimize. +
+ + + +

Tabs & Panels

+

+ Various settings for how tabs & panels should work in mRemoteNG. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
Always show panel tabsOffWill always show the tabs & panels in mRemoteNG
Open new tab to the right of the currently selected tabOn + When active then open next tab on the right of the active selection in mRemoteNG. Turn + this off and next tab will open the next connection at the end of all tabs. +
Show logon information on tab namesOffShow your login in the connection tab.
Show protocols on tab namesOffWhen active then in the tab show what protocol is used for the connection.
Identify quick connect tabs by adding the prefix "Quick:"Off + When active shows Quick: before the connection name in the tab connection to easier + identify what is a quick connection and what is a non quick connection. +
Double click on tab closes itOn + When double clicking a tab it will close the connection but does not log you + out from the server. The connection in this case is active on the destination + server. +
Always show panel selection dialog when opening connectionsOff + Option to allow you to always select what panel to place the connection on. + If this is off it will create a General panel where the connection is placed + or use the connections set panel from the connection options. +
Create a empty panel when mRemoteNG startsOff + On startup if this is active mRemoteNG will create a panel mentioned under + Panel Name: +
+ + + +

Notifications

+ + + + +

Connections

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
Single click on connections opens itOff + In connection tree when this is active will try to connect on single click. By default + this is turned off to use double click to open connection. +
Single click on opened connection in Connection Tree switches to the opened Connection TabOff + Allows you to single click on a active connection in the connection tree to go to that + open connection in the tabs faster. +
Set hostname like display name when creating or renaming connectionsOff + Will make mRemoteNG try to use the remote host hostname to set the title of the tab + in mRemoteNG. +
Save connections after every exitOn + When active mRemoteNG will save the connection tree to the active config + after every exit. If inactive then you have to save using + File > Save Connection File or keyboard shortcut + Ctrl+S +
Filter search matches in connection treeOff + Allows you to filter out the connections to which does not match + your filter search in the connection tree. If not active the search + will only select the filter to which you do search. +
RDP Reconnect count5Value in seconds
+
RDP Connection Timeout20Value in seconds
+
Auto save time in minutes (0 means disabled)0Value in minutes
+
When closing connectionsWarn me when closing connections + Various options of how mRemoteNG should act when you close connections. + The different options are listed below: +
    +
  • Warn me when closing connections
  • +
  • Warn me only when closing multiple connections
  • +
  • Warn me only when exiting mRemoteNG
  • +
  • Do not warn me when closing connections
  • +
+ By default a warning will come up on closing a connection. Change this value + based on your prefered settings. +
+ + + +

Credentials

+

+ Options for credentials in mRemoteNG. The main purpose here + is that when you have empty username, password or domain field + then use below information. +

+ + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
NoneOnUse no specific settings on login
My Current credentials (Windows logon information)Off + This option will use the logon information for the OS. This is useful if you + are in a domain that uses specific credentials and want to login to servers + with those credentials. +
The following:Off + Use one or two of the options below for the empty login or all of them. + For example if you have a different domain that you login to the servers with. +
+ + + + +

SQL Server

+
+ NOTE! To understand more about SQL Server connection please + See here +
+ + + + + + + + + + + +
OptionDefaultDescription
Use SQL Server to load & save connectionsOffEnable to fetch connections from a database.
+ + + +

Updates

+

+ Options for how mRemoteNG should check for updates from the website. +

+ + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
Check for updates at startupOn (Every 14 days) + Here you can choose how often mRemoteNG checks for updates. + Standard is every 14 days +
Release Channel:Stable + The main channel to use for mRemoteNG. Note that the channels are described under + the selection. Stable is suggested for normal usage but its always good to get + feedback on upcoming releases. +
Use a proxy server to connectOff + Proxy to connect through to check for updates. This is not a proxy connection + for when you connect to a server but more to check for updates. +
+ + + + +

Theme

+

+ UI themes. This is not enabled by default but can be used + inside mRemoteNG. To enable themes you have to first + enable it in the checkbox at the bottom of the options. + Then restart mRemoteNG in order for it to work. +

+

+ Default theme is: vs2015light +

+
+ NOTE! To know more about themes and how to + create your own See Here +
+ + + + +

Security

+ + + + +

Advanced

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
Automatically get session informationOff
Automatically try to reconnect when disconnected from server (RDP & ICA only)Off +
Use UTF8 encoding for RDP "Load Balance info" propertyOff
Use custom PuTTY path:Off
To configure PuTTY sessions click this button:Launch PuTTYWill launch the putty agent so you can edit the sessions.
Maximum PuTTY and integrated external tools wait time:2 seconds
+ + + diff --git a/mRemoteV1/Resources/Help/ui_port_scan.htm b/mRemoteV1/Resources/Help/ui_port_scan.htm new file mode 100644 index 000000000..a11203707 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_port_scan.htm @@ -0,0 +1,57 @@ + + + + + Port Scan + + + +
+ Complete from nmat updates, please remove this div after review. +
+ + +

Introduction

+
+

+ The Port Scan feature (under Tools > Port Scan) is similar to a nmap port scan. + It will scan a range of IP addresses and to determine if specific mRemoteNG supported + protocols are active. Hosts can then be bulk imported into mRemoteNG. +

+ + + +

Use Case

+
+

+ You've just inherited a new network with little to no documentation. + Inputting a range of IP addresses and scanning your entire network + should give you a good idea of what is currently online. + Importing those devices will then give you a quick + (relatively, scanning a large subnet will take a while) way to get into those devices. +

+ + + +

How to use

+
+
    +
  1. Start the Port Scan feature by clicking Tools > Port Scan in the menu bar.
  2. +
  3. Input your Start IP and End IP of the range you'd like to scan.
  4. +
  5. Enter the Start Port and End Port that mRemoteNG should test for. +
    + TIP! If you leave this at the default of 0 & 0, + the test will be for the default protocol ports that mRemoteNG supports. +
    +
  6. +
  7. Click Scan
  8. +
  9. Wait. Possibly a long time.
  10. +
  11. + The table will populate, and eventually you'll get a notification that the scan has completed. + Alternatively, you can press Stop to end the scan at any time. +
  12. +
  13. Change the dropdown to the protocol you'd like to import and click Import.
  14. +
+ + + diff --git a/mRemoteV1/Resources/Help/ui_quick_connect.htm b/mRemoteV1/Resources/Help/ui_quick_connect.htm new file mode 100644 index 000000000..1123f6057 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_quick_connect.htm @@ -0,0 +1,54 @@ + + + + + Quick Connect + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

+ The Quick Connect functionality of mRemoteNG allows you to quickly connect to a remote host using a variety of network protocols. +

+

Use Cases

+

+ The primary use case for Quick Connect is to connect to remote hosts when you already remember the DNS hostname/IP address and the appropriate protocol for the connection. +

+ An additional use case is to connect to remote hosts saved as a connection quickly. +

+ +

Prerequisites

+
    +
  • Knowledge of a DNS host name or IP address
  • +
  • Knowledge of an appropriate protocol to communicate with remote host
  • +
+

OR

+
    +
  • A predefined mRemoteNG connection
  • +
+ +

Using QuickConnect

+ +

+ To use Quick Connect, ensure the Quick Connect toolbar is enabled by selecting View and then Quick Connect Toolbar. +
+ Next, input a DNS host name or IP address into the box labeled "Connect". This box will also save previous entries during your session. +
+ Quick Connect Toolbar +
+
+ Quick Connect Toolbar +
+
+ Select the appropriate network protocol by clicking the arrow next to the Connect box. +
+ Quick Connect Toolbar +
+
+ If you wish to use an existing connection, select the globe icon next to the protocol button and select the appropriate connection. +

+ + diff --git a/mRemoteV1/Resources/Help/ui_screenshot_manager.htm b/mRemoteV1/Resources/Help/ui_screenshot_manager.htm new file mode 100644 index 000000000..7d1db7cd7 --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_screenshot_manager.htm @@ -0,0 +1,62 @@ + + + + + Screenshot Manager + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

Introduction

+

+ The screenshot manager is a panel and tool that can be used to organize + and take screenshots inside mRemoteNG. +

+ + +

Take a screenshot

+

+ To take a screenshot of a instance its as easy as to right click on the + connection tab and press Screenshot and it will open the screenshot + manager. +

+ + +

+ On the left image you will see the right click menu for the connection tab. Clicking the + screenshot there will allow mRemoteNG to create a screenshot. +

+

+ The right image is where the screenshots are stored in mRemoteNG. Here you can store + and then decide what to do with the images after you are done taking screenshots. +

+ + + +

Editing

+

+ The manager is a simple tool for saving and deleting screenshots. If you need to do + more with the screenshots then the suggestion is to open them in a third party app. + Here is what the manager allows you to do: +

    +
  • Save
  • +
  • Save All
  • +
  • Delete
  • +
  • Delete All
  • +
+

+

+ Once you press save, a window to save the files will come up where you want to save + the screenshots. +

+

+ Short summary of screenshot manager is that you can sit and create screenshots without + having to open a different manager all the time and instead let mRemoteNG create the + main screenshot which can be edited later on. +

+ + + diff --git a/mRemoteV1/Resources/Help/ui_sql_configuration.htm b/mRemoteV1/Resources/Help/ui_sql_configuration.htm new file mode 100644 index 000000000..1c652c95b --- /dev/null +++ b/mRemoteV1/Resources/Help/ui_sql_configuration.htm @@ -0,0 +1,65 @@ + + + + + SQL Configuration + + + +
+ Complete from nmat updates, please remove this div after review. +
+ +

Warning!

+
+ The SQL feature is in an early beta stage and not intended for use in an productive environment! + I recommend you to do a full backup of your connections and settings before switching to SQL Server. +
+

Databases Supported

+
+

+ The list below are databases which have been tested on for support. Note that other databases may be supported in the future. +

+
    +
  • Microsoft™ SQL Server
  • + +
+

Steps to configure your SQL Server

+
+
    +
  1. Create a new Database called "mRemoteNG" on your SQL Server.
  2. +
  3. Run the SQL Script for your DB type listed below in topic (SQL Table creation Scripts) on the newly created Database.
  4. +
  5. Give the users that you want to grant access to the mRemoteNG Connections Database Read/Write permissions on the Database.
  6. +
+

Steps to configure mRemoteNG for SQL

+
+
    +
  1. Start mRemoteNG if it's not already running.
  2. +
  3. Go to Tools - Options - SQL Server
  4. +
  5. Check the box that says "Use SQL Server to load & save connections".
  6. +
  7. Fill in your SQL Server hostname or ip address.
  8. +
  9. If you do not use your Windows logon info to authenticate against the SQL Server fill in the correct Username and Password.
  10. +
  11. Click OK to apply the changes. The main window title should now change to "mRemoteNG | SQL Server".
  12. +
  13. Now click on File - Save to update the tables on your SQL Server with the data from the loaded connections xml file. (Do not click File - New, this doesn't work yet)
  14. +
  15. You should now be able to do everything you were able to do with the XML storage plus see the changes live on another mRemoteNG instance that is connected to the same Database.
  16. +
+

SQL Table creation Scripts

+
+
+ + + + + + + + + + +
Script (click on script below for your db type)Description
Microsoft™ SQL scriptMicrosoft™ SQL Server
+
+ + diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Appearance_Icon.ico b/mRemoteV1/Resources/Icons/Appearance_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/Appearance_Icon.ico rename to mRemoteV1/Resources/Icons/Appearance_Icon.ico diff --git a/mRemoteV1/Resources/Icons/FamFamFam/comments.ico b/mRemoteV1/Resources/Icons/Comments_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/comments.ico rename to mRemoteV1/Resources/Icons/Comments_Icon.ico diff --git a/mRemoteV1/Resources/Icons/Config_Icon.ico b/mRemoteV1/Resources/Icons/Config_Icon.ico index d3d035ab2..04736abcb 100644 Binary files a/mRemoteV1/Resources/Icons/Config_Icon.ico and b/mRemoteV1/Resources/Icons/Config_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/Connections_SaveAs_Icon.ico b/mRemoteV1/Resources/Icons/ConnectionsSaveAs_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/Connections_SaveAs_Icon.ico rename to mRemoteV1/Resources/Icons/ConnectionsSaveAs_Icon.ico diff --git a/mRemoteV1/Resources/Icons/FamFamFam/database.ico b/mRemoteV1/Resources/Icons/Database_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/database.ico rename to mRemoteV1/Resources/Icons/Database_Icon.ico diff --git a/mRemoteV1/Resources/Icons/FamFamFam/page_white_edit.ico b/mRemoteV1/Resources/Icons/EditPage_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/page_white_edit.ico rename to mRemoteV1/Resources/Icons/EditPage_Icon.ico diff --git a/mRemoteV1/Resources/Icons/FamFamFam/error.ico b/mRemoteV1/Resources/Icons/Error_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/error.ico rename to mRemoteV1/Resources/Icons/Error_Icon.ico diff --git a/mRemoteV1/Resources/Icons/ExtApp_Icon.ico b/mRemoteV1/Resources/Icons/ExtApp_Icon.ico index d551aa3aa..f8d9517b9 100644 Binary files a/mRemoteV1/Resources/Icons/ExtApp_Icon.ico and b/mRemoteV1/Resources/Icons/ExtApp_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Config_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/Config_Icon.ico deleted file mode 100644 index 04736abcb..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/Config_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/ExtApp_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/ExtApp_Icon.ico deleted file mode 100644 index f8d9517b9..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/ExtApp_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Help_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/Help_Icon.ico deleted file mode 100644 index 48f3c5289..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/Help_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Options_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/Options_Icon.ico deleted file mode 100644 index 75ea960da..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/Options_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/PortScan_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/PortScan_Icon.ico deleted file mode 100644 index 60f0200b9..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/PortScan_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/SSHTransfer_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/SSHTransfer_Icon.ico deleted file mode 100644 index 0d3f2527e..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/SSHTransfer_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Save_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/Save_Icon.ico deleted file mode 100644 index eb522217d..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/Save_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Screenshot_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/Screenshot_Icon.ico deleted file mode 100644 index 5f0da7ac6..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/Screenshot_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Sessions_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/Sessions_Icon.ico deleted file mode 100644 index 8b3d2c1ad..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/Sessions_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Update_Icon.ico b/mRemoteV1/Resources/Icons/FamFamFam/Update_Icon.ico deleted file mode 100644 index 57ea6cc8a..000000000 Binary files a/mRemoteV1/Resources/Icons/FamFamFam/Update_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/Help_Icon.ico b/mRemoteV1/Resources/Icons/Help_Icon.ico index 130a92039..48f3c5289 100644 Binary files a/mRemoteV1/Resources/Icons/Help_Icon.ico and b/mRemoteV1/Resources/Icons/Help_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/key.ico b/mRemoteV1/Resources/Icons/Key_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/key.ico rename to mRemoteV1/Resources/Icons/Key_Icon.ico diff --git a/mRemoteV1/Resources/Icons/FamFamFam/keyboard.ico b/mRemoteV1/Resources/Icons/Keyboard_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/keyboard.ico rename to mRemoteV1/Resources/Icons/Keyboard_Icon.ico diff --git a/mRemoteV1/Resources/Icons/FamFamFam/News_Icon.ico b/mRemoteV1/Resources/Icons/News_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/News_Icon.ico rename to mRemoteV1/Resources/Icons/News_Icon.ico diff --git a/mRemoteV1/Resources/Icons/Options_Icon.ico b/mRemoteV1/Resources/Icons/Options_Icon.ico index 5bcd27980..75ea960da 100644 Binary files a/mRemoteV1/Resources/Icons/Options_Icon.ico and b/mRemoteV1/Resources/Icons/Options_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Panels_Icon.ico b/mRemoteV1/Resources/Icons/Panels_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/Panels_Icon.ico rename to mRemoteV1/Resources/Icons/Panels_Icon.ico diff --git a/mRemoteV1/Resources/Icons/Play_Quick_Icon.ico b/mRemoteV1/Resources/Icons/Play_Quick_Icon.ico deleted file mode 100644 index 9fa978f4a..000000000 Binary files a/mRemoteV1/Resources/Icons/Play_Quick_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/PortScan_Icon.ico b/mRemoteV1/Resources/Icons/PortScan_Icon.ico index 5348d4cee..60f0200b9 100644 Binary files a/mRemoteV1/Resources/Icons/PortScan_Icon.ico and b/mRemoteV1/Resources/Icons/PortScan_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/RDCMan_Icon.ico b/mRemoteV1/Resources/Icons/RDCMan_Icon.ico deleted file mode 100644 index 788b50833..000000000 Binary files a/mRemoteV1/Resources/Icons/RDCMan_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Icons/SSHTransfer_Icon.ico b/mRemoteV1/Resources/Icons/SSHTransfer_Icon.ico index 7492c7471..0d3f2527e 100644 Binary files a/mRemoteV1/Resources/Icons/SSHTransfer_Icon.ico and b/mRemoteV1/Resources/Icons/SSHTransfer_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/Save_Icon.ico b/mRemoteV1/Resources/Icons/Save_Icon.ico index 187d6fec3..eb522217d 100644 Binary files a/mRemoteV1/Resources/Icons/Save_Icon.ico and b/mRemoteV1/Resources/Icons/Save_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/Screenshot_Icon.ico b/mRemoteV1/Resources/Icons/Screenshot_Icon.ico index 26151c401..5f0da7ac6 100644 Binary files a/mRemoteV1/Resources/Icons/Screenshot_Icon.ico and b/mRemoteV1/Resources/Icons/Screenshot_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/Sessions_Icon.ico b/mRemoteV1/Resources/Icons/Sessions_Icon.ico index c3244ee7c..8b3d2c1ad 100644 Binary files a/mRemoteV1/Resources/Icons/Sessions_Icon.ico and b/mRemoteV1/Resources/Icons/Sessions_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/FamFamFam/shield.ico b/mRemoteV1/Resources/Icons/Shield_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/shield.ico rename to mRemoteV1/Resources/Icons/Shield_Icon.ico diff --git a/mRemoteV1/Resources/Icons/FamFamFam/StartupExit_Icon.ico b/mRemoteV1/Resources/Icons/StartupExit_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/StartupExit_Icon.ico rename to mRemoteV1/Resources/Icons/StartupExit_Icon.ico diff --git a/mRemoteV1/Resources/Icons/FamFamFam/Tab_Icon.ico b/mRemoteV1/Resources/Icons/Tab_Icon.ico similarity index 100% rename from mRemoteV1/Resources/Icons/FamFamFam/Tab_Icon.ico rename to mRemoteV1/Resources/Icons/Tab_Icon.ico diff --git a/mRemoteV1/Resources/Icons/Update_Icon.ico b/mRemoteV1/Resources/Icons/Update_Icon.ico index e02ca8853..57ea6cc8a 100644 Binary files a/mRemoteV1/Resources/Icons/Update_Icon.ico and b/mRemoteV1/Resources/Icons/Update_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/mRemoteNG_Icon.ico b/mRemoteV1/Resources/Icons/mRemoteNG_Icon.ico new file mode 100644 index 000000000..1c750daf4 Binary files /dev/null and b/mRemoteV1/Resources/Icons/mRemoteNG_Icon.ico differ diff --git a/mRemoteV1/Resources/Icons/mRemote_Icon.ico b/mRemoteV1/Resources/Icons/mRemote_Icon.ico deleted file mode 100644 index 700854c14..000000000 Binary files a/mRemoteV1/Resources/Icons/mRemote_Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Images/Header_dark.png b/mRemoteV1/Resources/Images/Header_dark.png new file mode 100644 index 000000000..7cbd122ed Binary files /dev/null and b/mRemoteV1/Resources/Images/Header_dark.png differ diff --git a/mRemoteV1/Resources/Images/Logo.png b/mRemoteV1/Resources/Images/Logo.png deleted file mode 100644 index 8355b295d..000000000 Binary files a/mRemoteV1/Resources/Images/Logo.png and /dev/null differ diff --git a/mRemoteV1/Resources/Images/mRemote.png b/mRemoteV1/Resources/Images/mRemote.png deleted file mode 100644 index fe3f349e3..000000000 Binary files a/mRemoteV1/Resources/Images/mRemote.png and /dev/null differ diff --git a/mRemoteV1/Resources/Images/mRemoteNG.png b/mRemoteV1/Resources/Images/mRemoteNG.png new file mode 100644 index 000000000..56018bbbe Binary files /dev/null and b/mRemoteV1/Resources/Images/mRemoteNG.png differ diff --git a/mRemoteV1/Resources/Language/Language.Designer.cs b/mRemoteV1/Resources/Language/Language.Designer.cs index 561720df2..835359b95 100644 --- a/mRemoteV1/Resources/Language/Language.Designer.cs +++ b/mRemoteV1/Resources/Language/Language.Designer.cs @@ -159,6 +159,24 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to This exception will force mRemoteNG to close. + /// + internal static string ExceptionForcesmRemoteNGToClose { + get { + return ResourceManager.GetString("ExceptionForcesmRemoteNGToClose", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exception Message. + /// + internal static string ExceptionMessage { + get { + return ResourceManager.GetString("ExceptionMessage", resourceCulture); + } + } + /// /// Looks up a localized string similar to Filter search matches in connection tree. /// @@ -195,6 +213,24 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to mRemoteNG Unhandled Exception. + /// + internal static string mRemoteNGUnhandledException { + get { + return ResourceManager.GetString("mRemoteNGUnhandledException", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Place search bar above connection tree. + /// + internal static string PlaceSearchBarAboveConnectionTree { + get { + return ResourceManager.GetString("PlaceSearchBarAboveConnectionTree", resourceCulture); + } + } + /// /// Looks up a localized string similar to Prompt to unlock credential repositories on startup. /// @@ -249,6 +285,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to Stack trace. + /// + internal static string StackTrace { + get { + return ResourceManager.GetString("StackTrace", resourceCulture); + } + } + /// /// Looks up a localized string similar to About. /// @@ -1482,7 +1527,7 @@ namespace mRemoteNG { } /// - /// Looks up a localized string similar to Protocol Event ErrorOccured. + /// Looks up a localized string similar to A connection protocol error occurred. Host: "{1}"; Error code: "{2}"; Error Description: "{0}". /// internal static string strConnectionEventErrorOccured { get { @@ -1928,7 +1973,7 @@ namespace mRemoteNG { } /// - /// Looks up a localized string similar to End IP. + /// Looks up a localized string similar to Last IP. /// internal static string strEndIP { get { @@ -1937,7 +1982,7 @@ namespace mRemoteNG { } /// - /// Looks up a localized string similar to End Port. + /// Looks up a localized string similar to Last Port. /// internal static string strEndPort { get { @@ -4524,6 +4569,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to To scan a single port, select the "First Port" only.. + /// + internal static string strPortScanSinglePort { + get { + return ResourceManager.GetString("strPortScanSinglePort", resourceCulture); + } + } + /// /// Looks up a localized string similar to (These properties will only be saved if you select mRemote/mRemoteNG XML as output file format!). /// @@ -5560,9 +5614,7 @@ namespace mRemoteNG { } /// - /// Looks up a localized string similar to Protocol Event Disconnected. - ///Message: - ///{0}. + /// Looks up a localized string similar to Protocol Event Disconnected. Host: "{1}"; Protocol: "{2}" Message: "{0}". /// internal static string strProtocolEventDisconnected { get { @@ -6814,7 +6866,7 @@ namespace mRemoteNG { } /// - /// Looks up a localized string similar to Start IP. + /// Looks up a localized string similar to First IP. /// internal static string strStartIP { get { @@ -6823,7 +6875,7 @@ namespace mRemoteNG { } /// - /// Looks up a localized string similar to Start Port. + /// Looks up a localized string similar to First Port. /// internal static string strStartPort { get { @@ -7255,7 +7307,7 @@ namespace mRemoteNG { } /// - /// Looks up a localized string similar to Timeout (seconds). + /// Looks up a localized string similar to Timeout [seconds]. /// internal static string strTimeoutInSeconds { get { @@ -7326,6 +7378,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to Track active connection in the connection tree. + /// + internal static string strTrackActiveConnectionInConnectionTree { + get { + return ResourceManager.GetString("strTrackActiveConnectionInConnectionTree", resourceCulture); + } + } + /// /// Looks up a localized string similar to Transfer. /// @@ -7786,6 +7847,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to An unhandled exception has occurred. + /// + internal static string UnhandledExceptionOccured { + get { + return ResourceManager.GetString("UnhandledExceptionOccured", resourceCulture); + } + } + /// /// Looks up a localized string similar to Unlock. /// diff --git a/mRemoteV1/Resources/Language/Language.de.resx b/mRemoteV1/Resources/Language/Language.de.resx index 614a06530..45fb1bf60 100644 --- a/mRemoteV1/Resources/Language/Language.de.resx +++ b/mRemoteV1/Resources/Language/Language.de.resx @@ -1882,10 +1882,10 @@ Wenn Sie Fehler feststellen, dann sollten Sie eine neue Verbindungsdatei erstell SSH-Übertragung fehlgeschlagen. - Anfangs IP + Erste IP - Anfangs Port + Erster Port Anfang/Ende @@ -2183,31 +2183,31 @@ mRemoteNG wird nun geschlossen und die Installation gestartet. Ohne Anmeldedaten verbinden - Nicht zu Konsolensitzung verbinden + Keine Verbindung zur Konsolensitzung herstellen - PuTTY konnte nicht gestartet werden + PuTTY konnte nicht gestartet werden. - Export alles + Alles exportieren - Export Datei + Datei exportieren - Export Eigeschaften + Eigenschaften exportieren - Alle importierbaren Dateien + Alle wichtigen Dateien - Import fehlgeschlagen + Import-Vorgang fehlgeschlagen Von &Datei importieren - Wo sollen die importierten Objekte platziert werden? + Wo sollen die importierten Elemente abgelegt werden? Import Ziel @@ -2225,19 +2225,19 @@ mRemoteNG wird nun geschlossen und die Installation gestartet. Nächster Tab - Vorheriger Tab + Hotkeys ändern - Teste... + Testen... Tastatur - Überprüfung fehlgeschlagen + Prüfung fehlgeschlagen - Prüfe auf Updates... + Nach Updates suchen... Verschlüsselungs-Engine @@ -2255,7 +2255,7 @@ mRemoteNG wird nun geschlossen und die Installation gestartet. Mittel - Ton Qualität + Klangqualität Download abgeschlossen! @@ -2270,19 +2270,19 @@ mRemoteNG wird nun geschlossen und die Installation gestartet. Datei öffnen - Immer erlauben + Immer zulassen - Ein Mal erlauben + Einmal zulassen - Nie erlauben + Nicht erlauben Falsches Passwort - Qualle + Quelle Zurück @@ -2308,7 +2308,7 @@ Diese Seite führt Sie durch den Prozess der Aktualisierung Ihrer Verbindungsdat &Nochmal versuchen - Neues externes Programm + Neues externes Werkzeug Die Verbindungsinformationen konnten nicht vom SQL-Server geladen werden. @@ -2317,10 +2317,10 @@ Diese Seite führt Sie durch den Prozess der Aktualisierung Ihrer Verbindungsdat Vorheriger Tab - Tataturkürzel + Tastenkombinationen - Beide Passwörter müssen übereinstimmen + Die beide Passwörter müssen übereinstimmen. Das Passwort muss mindestens 3 Zeichen lang sein. @@ -2341,19 +2341,19 @@ Diese Seite führt Sie durch den Prozess der Aktualisierung Ihrer Verbindungsdat Passwort für {0} - RDP-Verbindungs-Timeout: + RDP-Verbindungs-Timeout - Dieser Knoten ist bereits im Verzeichnis + Dieser Knoten befindet sich bereits in diesem Ordner. - Knoten kann nicht auf sich selbst gezogen werden. + Der Knoten kann nicht auf sich selbst gezogen werden. - Elternknoten kann nicht auf Kindknoten gezogen werden. + Der übergeordnete Knoten kann nicht auf den untergeordneten Knoten gezogen werden. - Dieser Knoten ist nicht ziehbar. + Dieser Knoten ist nicht verschiebbar. Block Cipher-Modus @@ -2371,46 +2371,46 @@ Diese Seite führt Sie durch den Prozess der Aktualisierung Ihrer Verbindungsdat Verbindung erfolgreich - Datenbank '{0}' nicht verfügbar. + Datenbank '{0}' ist nicht verfügbar. - Verbindungen nach jeder Änderung speichern + Verbindungen nach jeder Bearbeitung speichern Suchergebnisse in Verbindungen filtern - Teste Verbindung + Verbindung testen - Time-Out (Sekunden) + Time-Out [Sekunden] &Alles zurücksetzen - Automatische Größenanpassung + Automatische Größenänderung PuTTY Sitzungseinstellungen - Auf der Toolbar anzeigen + In der Symbolleiste anzeigen Akzeptieren - Hinzufügen + Anmeldeinformationen Editor Zugewiesene Anmeldedaten - Unsichere Zertifikate erlauben? + Unsicheres Zertifikat zulassen? - Entsperren + Freischalten Themes aktivieren @@ -2419,13 +2419,13 @@ Diese Seite führt Sie durch den Prozess der Aktualisierung Ihrer Verbindungsdat Neuer Thema Name - Teste Verbindung + Verbindung testen In Datei &exportieren... - Ein Fehler ist während des Imports der Datei {0} aufgetreten. + Beim Importieren der Datei ist ein Fehler aufgetreten ("{0}"). Symbolleisten sperren @@ -2462,7 +2462,7 @@ Es werden keine Themes geladen, vergewissern Sie sich, dass das standard mremote Abrufen - Das Change-Log konnte nicht herunter geladen werden. + Der Changelog konnte nicht heruntergeladen werden. Wählen Sie die vom Protokoll bereitgestellte Klangqualität: Dynamisch, Mittel, Hoch @@ -2477,7 +2477,7 @@ Es werden keine Themes geladen, vergewissern Sie sich, dass das standard mremote Hinzufügen - Auswählen welche Anmeldeinformationen für diese Verbindung verwendet werden sollen. + Wählen Sie aus, welche Anmeldeinformationen für diese Verbindung verwendet werden sollen. Möchten Sie die Anmeldeinformationen {0} wirklich löschen? @@ -2513,10 +2513,10 @@ Die Passwortlänge muss zwischen {0} und {1} liegen Wählen Sie einen Pfad für die mRemoteNG-Protokolldatei - Protokollierungspfad + Pfad der Protokolldatei - Pfad wählen + Pfad auswählen Standard verwenden @@ -2534,7 +2534,7 @@ Wählen Sie einen Pfad für die mRemoteNG-Protokolldatei Das ausgewählte Repository ist entsperrt - Entsperren + Freischalten Entsperre Credential Repository @@ -2569,177 +2569,24 @@ Wählen Sie einen Pfad für die mRemoteNG-Protokolldatei Verwenden Sie die UTF8-Codierung für die RDP-Eigenschaft "Load Balance Info" - - Ohne Anmeldedaten verbinden - - - Alles exportieren - - - Datei exportieren - - - Eigenschaften exportieren - Die Aktuell gewählte Verbindung exportieren Den Aktuell gewählten Ordner exportieren - - Alle wichtigen Dateien - - - Import-Vorgang fehlgeschlagen - - - Wo sollen die importierten Elemente abgelegt werden? - - - Die Verbindungsinformationen konnten nicht vom SQL-Server geladen werden. - - - Testen... - - - Tastatur - - - Tastenkombinationen - - - Hotkeys ändern - - - Vorheriger Tab - - - Nächster Tab - - - Prüfung fehlgeschlagen - - - Nach Updates suchen... - - - Das Passwort muss mindestens 3 Zeichen lang sein. - - - Die beide Passwörter müssen übereinstimmen. - - - Port-Scan abgeschlossen. - - - Passwort für {0} - - - In der Symbolleiste anzeigen - - - Sicherheit - - - Zurück - - - Keine Verbindung zur Konsolensitzung herstellen - - - PuTTY Sitzungseinstellungen - - - Lastausgleichsinfo - - - Der Changelog konnte nicht heruntergeladen werden. - - - Hoch - - - Mittel - - - Akzeptieren - - - Hinzufügen - - - Anmeldeinformationen Editor - Anmeldeinformationen Manager - - Entfernen - - - Titel - - - Wählen Sie aus, welche Anmeldeinformationen für diese Verbindung verwendet werden sollen. - - - Pfad der Protokolldatei - - - Pfad auswählen - - - Datei öffnen - - - Standard verwenden - - - Protokollierung - Pop-ups - - Immer zulassen - - - Einmal zulassen - - - Nicht erlauben - - - Unsicheres Zertifikat zulassen? - - - Verbindung testen - - - Falsches Passwort - - - Quelle - - - Freischalten - - - Freischalten - http://www.famfamfam.com/ Element exportieren - - PuTTY konnte nicht gestartet werden. - - - Neues externes Werkzeug - HTTP @@ -2755,55 +2602,22 @@ Wählen Sie einen Pfad für die mRemoteNG-Protokolldatei ICA - - Beim Importieren der Datei ist ein Fehler aufgetreten ("{0}"). - Tabs - - Automatische Größenänderung - http://sourceforge.net/projects/dockpanelsuite/ - - RDP-Verbindungs-Timeout - - - Dieser Knoten befindet sich bereits in diesem Ordner. - - - Der Knoten kann nicht auf sich selbst gezogen werden. - - - Der übergeordnete Knoten kann nicht auf den untergeordneten Knoten gezogen werden. - - - Dieser Knoten ist nicht verschiebbar. - - - Download abgeschlossen! - Download ID - - Klangqualität - - - Verbindung testen - Die Konfigurationsdatei fehlt. - - Datenbank '{0}' ist nicht verfügbar. - - - Verbindungen nach jeder Bearbeitung speichern + + Suchleiste über den Verbindungen anzeigen \ No newline at end of file diff --git a/mRemoteV1/Resources/Language/Language.en-US.resx b/mRemoteV1/Resources/Language/Language.en-US.resx index 273d1b558..f2cf1535d 100644 --- a/mRemoteV1/Resources/Language/Language.en-US.resx +++ b/mRemoteV1/Resources/Language/Language.en-US.resx @@ -59,7 +59,7 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - + @@ -105,18 +105,21 @@ - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - text/microsoft-resx 2.0 - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Place search bar above connection tree + Select the color quality to be used. diff --git a/mRemoteV1/Resources/Language/Language.resx b/mRemoteV1/Resources/Language/Language.resx index 4b2faf183..882577451 100644 --- a/mRemoteV1/Resources/Language/Language.resx +++ b/mRemoteV1/Resources/Language/Language.resx @@ -508,7 +508,7 @@ VncSharp Control Version {0} Connection failed! - Protocol Event ErrorOccured + A connection protocol error occurred. Host: "{1}"; Error code: "{2}"; Error Description: "{0}" Opening connection failed! @@ -622,10 +622,10 @@ Starting with new connections file. Completely encrypt connection file - End IP + Last IP - End Port + Last Port AddExternalToolsToToolBar (frmMain) failed. {0} @@ -1683,9 +1683,7 @@ If you run into such an error, please create a new connection file! Proxy Username - Protocol Event Disconnected. -Message: -{0} + Protocol Event Disconnected. Host: "{1}"; Protocol: "{2}" Message: "{0}" Protocol Event Disconnected failed. @@ -2070,10 +2068,10 @@ Message: SSH transfer failed. - Start IP + First IP - Start Port + First Port Startup/Exit @@ -2638,7 +2636,7 @@ This page will walk you through the process of upgrading your connections file o Use UTF8 encoding for RDP "Load Balance Info" property - Timeout (seconds) + Timeout [seconds] Working directory: @@ -2718,9 +2716,33 @@ This page will walk you through the process of upgrading your connections file o An error occurred while trying to change the connection resolution to host '{0}' + + Stack trace + + + Exception Message + + + mRemoteNG Unhandled Exception + + + An unhandled exception has occurred + + + This exception will force mRemoteNG to close + Copy Hostname + + Place search bar above connection tree + + + To scan a single port, select the "First Port" only. + + + Track active connection in the connection tree + Always show connection tabs diff --git a/mRemoteV1/Resources/Other Graphics/Icon.psd b/mRemoteV1/Resources/Other Graphics/Icon.psd deleted file mode 100644 index de08291a9..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/Icon.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/LogoBig.psd b/mRemoteV1/Resources/Other Graphics/LogoBig.psd deleted file mode 100644 index 83451a900..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/LogoBig.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/header.bmp b/mRemoteV1/Resources/Other Graphics/header.bmp deleted file mode 100644 index 2d4ae1a4c..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/header.bmp and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/header.png b/mRemoteV1/Resources/Other Graphics/header.png deleted file mode 100644 index 427ec40e3..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/header.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16.ico b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16.ico deleted file mode 100644 index 08c1072aa..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x32.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x32.png deleted file mode 100644 index fe3f349e3..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x32.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x4.act b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x4.act deleted file mode 100644 index 3ed938266..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x4.act and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x4.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x4.png deleted file mode 100644 index 03c233b81..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 16x16x4.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 256x256.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 256x256.png deleted file mode 100644 index 028ef0c36..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 256x256.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 48x48.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 48x48.png deleted file mode 100644 index e96e1933d..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 48x48.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 70x70.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 70x70.png deleted file mode 100644 index e24a1fd58..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon - 70x70.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.ico b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.ico deleted file mode 100644 index 700854c14..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.ico and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.png deleted file mode 100644 index ca52e8bba..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.psd b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.psd deleted file mode 100644 index 2a4d435e9..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Icon.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Installer Sidebar.psd b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Installer Sidebar.psd deleted file mode 100644 index e91f5d662..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Installer Sidebar.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - 308x80.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - 308x80.png deleted file mode 100644 index 3cf83cbbf..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - 308x80.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - 492x128x32.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - 492x128x32.png deleted file mode 100644 index 8355b295d..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - 492x128x32.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black - 385x100.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black - 385x100.png deleted file mode 100644 index e9f660e03..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black - 385x100.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black.png deleted file mode 100644 index 11753d88d..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black.psd b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black.psd deleted file mode 100644 index cef5baf7c..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - Black.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet Mobile.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet Mobile.png deleted file mode 100644 index fc7dbc5a4..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet Mobile.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet Mobile.psd b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet Mobile.psd deleted file mode 100644 index 5bf141e86..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet Mobile.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet.png deleted file mode 100644 index 3203c1304..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet.psd b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet.psd deleted file mode 100644 index 51098e51a..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - StatusNet.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - present.ly.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - present.ly.png deleted file mode 100644 index 005e8d56e..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - present.ly.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - present.ly.psd b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - present.ly.psd deleted file mode 100644 index 5fbd470be..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo - present.ly.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo.psd b/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo.psd deleted file mode 100644 index 21fe5fcc2..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG - Logo.psd and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/mRemoteNG-phpBB.png b/mRemoteV1/Resources/Other Graphics/mRemoteNG-phpBB.png deleted file mode 100644 index e434d8ee0..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/mRemoteNG-phpBB.png and /dev/null differ diff --git a/mRemoteV1/Resources/Other Graphics/welcomefinish.bmp b/mRemoteV1/Resources/Other Graphics/welcomefinish.bmp deleted file mode 100644 index 16dd4c909..000000000 Binary files a/mRemoteV1/Resources/Other Graphics/welcomefinish.bmp and /dev/null differ diff --git a/mRemoteV1/Resources/Templates/AppIcon.psd b/mRemoteV1/Resources/Templates/AppIcon.psd new file mode 100644 index 000000000..237a7d9c5 Binary files /dev/null and b/mRemoteV1/Resources/Templates/AppIcon.psd differ diff --git a/mRemoteV1/Resources/Templates/Header_dark.psd b/mRemoteV1/Resources/Templates/Header_dark.psd new file mode 100644 index 000000000..98f397bad Binary files /dev/null and b/mRemoteV1/Resources/Templates/Header_dark.psd differ diff --git a/mRemoteV1/Resources/Templates/Header_light.psd b/mRemoteV1/Resources/Templates/Header_light.psd new file mode 100644 index 000000000..6d69f309f Binary files /dev/null and b/mRemoteV1/Resources/Templates/Header_light.psd differ diff --git a/mRemoteV1/Resources/Templates/Installer_Header.psd b/mRemoteV1/Resources/Templates/Installer_Header.psd new file mode 100644 index 000000000..75d03305e Binary files /dev/null and b/mRemoteV1/Resources/Templates/Installer_Header.psd differ diff --git a/mRemoteV1/Resources/Templates/Installer_Side.psd b/mRemoteV1/Resources/Templates/Installer_Side.psd new file mode 100644 index 000000000..37e3a5340 Binary files /dev/null and b/mRemoteV1/Resources/Templates/Installer_Side.psd differ diff --git a/mRemoteV1/Resources/Templates/VisualElements_150_dark.psd b/mRemoteV1/Resources/Templates/VisualElements_150_dark.psd new file mode 100644 index 000000000..3e130ebc2 Binary files /dev/null and b/mRemoteV1/Resources/Templates/VisualElements_150_dark.psd differ diff --git a/mRemoteV1/Resources/Templates/VisualElements_150_light.psd b/mRemoteV1/Resources/Templates/VisualElements_150_light.psd new file mode 100644 index 000000000..13743f12a Binary files /dev/null and b/mRemoteV1/Resources/Templates/VisualElements_150_light.psd differ diff --git a/mRemoteV1/Resources/Templates/VisualElements_70_dark.psd b/mRemoteV1/Resources/Templates/VisualElements_70_dark.psd new file mode 100644 index 000000000..61888f393 Binary files /dev/null and b/mRemoteV1/Resources/Templates/VisualElements_70_dark.psd differ diff --git a/mRemoteV1/Resources/Templates/VisualElements_70_light.psd b/mRemoteV1/Resources/Templates/VisualElements_70_light.psd new file mode 100644 index 000000000..66be17822 Binary files /dev/null and b/mRemoteV1/Resources/Templates/VisualElements_70_light.psd differ diff --git a/mRemoteV1/Resources/Tiles/VisualElements_150.png b/mRemoteV1/Resources/Tiles/VisualElements_150.png new file mode 100644 index 000000000..e48d125de Binary files /dev/null and b/mRemoteV1/Resources/Tiles/VisualElements_150.png differ diff --git a/mRemoteV1/Resources/Tiles/VisualElements_70.png b/mRemoteV1/Resources/Tiles/VisualElements_70.png new file mode 100644 index 000000000..ea86d91c7 Binary files /dev/null and b/mRemoteV1/Resources/Tiles/VisualElements_70.png differ diff --git a/mRemoteV1/Resources/Tiles/mRemoteNG.VisualElementsManifest.xml b/mRemoteV1/Resources/Tiles/mRemoteNG.VisualElementsManifest.xml new file mode 100644 index 000000000..1976da8a7 --- /dev/null +++ b/mRemoteV1/Resources/Tiles/mRemoteNG.VisualElementsManifest.xml @@ -0,0 +1,8 @@ + + + diff --git a/mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd b/mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd index 1ab3d981d..cb5905b1e 100644 --- a/mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd +++ b/mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd @@ -1,7 +1,7 @@  - + @@ -30,11 +30,18 @@ + + - + + + + + + @@ -45,6 +52,7 @@ + @@ -117,6 +125,7 @@ + diff --git a/mRemoteV1/Schemas/mremoteng_confcons_v2_8.xsd b/mRemoteV1/Schemas/mremoteng_confcons_v2_8.xsd deleted file mode 100644 index 1c08ef985..000000000 --- a/mRemoteV1/Schemas/mremoteng_confcons_v2_8.xsd +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mRemoteV1/Settings.cs b/mRemoteV1/Settings.cs index 3a481982c..53c713966 100644 --- a/mRemoteV1/Settings.cs +++ b/mRemoteV1/Settings.cs @@ -20,7 +20,7 @@ namespace mRemoteNG // this.SettingsSaving += this.SettingsSavingEventHandler; // } - + private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) { // Add code to handle the SettingChangingEvent event here. } diff --git a/mRemoteV1/Themes/ThemeManager.cs b/mRemoteV1/Themes/ThemeManager.cs index a3b9a2e23..0bddccfe6 100644 --- a/mRemoteV1/Themes/ThemeManager.cs +++ b/mRemoteV1/Themes/ThemeManager.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; +using System.Drawing; using System.IO; using System.Linq; using WeifenLuo.WinFormsUI.Docking; @@ -11,8 +12,8 @@ using WeifenLuo.WinFormsUI.Docking; namespace mRemoteNG.Themes { /// - /// Main class of the theming component. Centralices creation, loading and deletion of themes - /// Implmeented as a singleton + /// Main class of the theming component. Centralizes creation, loading and deletion of themes + /// Implemented as a singleton /// public class ThemeManager { @@ -24,7 +25,6 @@ namespace mRemoteNG.Themes private static ThemeManager themeInstance; #endregion - #region Constructors private ThemeManager() { @@ -232,6 +232,9 @@ namespace mRemoteNG.Themes NotifyThemeChanged(this, new PropertyChangedEventArgs("theme")); } } + + public int ThemesCount => themes.Count; + #endregion - } + } } \ No newline at end of file diff --git a/mRemoteV1/Tools/DisposableOptional.cs b/mRemoteV1/Tools/DisposableOptional.cs index 10fa2cf0c..ecc6bff64 100644 --- a/mRemoteV1/Tools/DisposableOptional.cs +++ b/mRemoteV1/Tools/DisposableOptional.cs @@ -6,11 +6,6 @@ namespace mRemoteNG.Tools public class DisposableOptional : Optional, IDisposable where T : IDisposable { - public DisposableOptional() - : base() - { - } - public DisposableOptional(T value) : base(value) { @@ -22,7 +17,7 @@ namespace mRemoteNG.Tools GC.SuppressFinalize(this); } - public void Dispose(bool disposing) + private void Dispose(bool disposing) { if (!disposing || !this.Any()) return; diff --git a/mRemoteV1/Tools/ExternalTool.cs b/mRemoteV1/Tools/ExternalTool.cs index 972862c58..5942b508f 100644 --- a/mRemoteV1/Tools/ExternalTool.cs +++ b/mRemoteV1/Tools/ExternalTool.cs @@ -90,12 +90,12 @@ namespace mRemoteNG.Tools public Icon Icon { - get { return File.Exists(FileName) ? MiscTools.GetIconFromFile(FileName) : Resources.mRemote_Icon; } + get { return File.Exists(FileName) ? MiscTools.GetIconFromFile(FileName) : Resources.mRemoteNG_Icon; } } public Image Image { - get { return Icon?.ToBitmap() ?? Resources.mRemote_Icon.ToBitmap(); } + get { return Icon?.ToBitmap() ?? Resources.mRemoteNG_Icon.ToBitmap(); } } #endregion diff --git a/mRemoteV1/Tools/MiscTools.cs b/mRemoteV1/Tools/MiscTools.cs index 03da94394..9cdf2ff2d 100644 --- a/mRemoteV1/Tools/MiscTools.cs +++ b/mRemoteV1/Tools/MiscTools.cs @@ -24,7 +24,7 @@ namespace mRemoteNG.Tools { Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "GetIconFromFile failed (Tools.Misc) - using default icon" + Environment.NewLine + AEx.Message, true); - return Resources.mRemote_Icon; + return Resources.mRemoteNG_Icon; } catch (Exception ex) diff --git a/mRemoteV1/Tools/MultiSSHController.cs b/mRemoteV1/Tools/MultiSSHController.cs index 25d2b08c8..ffc14cdbc 100644 --- a/mRemoteV1/Tools/MultiSSHController.cs +++ b/mRemoteV1/Tools/MultiSSHController.cs @@ -10,12 +10,12 @@ namespace mRemoteNG.Tools { public class MultiSSHController { - private ArrayList processHandlers = new ArrayList(); - private ArrayList quickConnectConnections = new ArrayList(); - private ArrayList previousCommands = new ArrayList(); - private int previousCommandIndex = 0; + private readonly ArrayList processHandlers = new ArrayList(); + private readonly ArrayList quickConnectConnections = new ArrayList(); + private readonly ArrayList previousCommands = new ArrayList(); + private int previousCommandIndex; - public int CommandHistoryLength { get; set; } = 100; + private int CommandHistoryLength { get; set; } = 100; public MultiSSHController(TextBox txtBox) { @@ -41,7 +41,7 @@ namespace mRemoteNG.Tools private ArrayList ProcessOpenConnections(ConnectionInfo connection) { - ArrayList handlers = new ArrayList(); + var handlers = new ArrayList(); foreach (ProtocolBase _base in connection.OpenConnections) { @@ -77,7 +77,7 @@ namespace mRemoteNG.Tools var connectionTreeConnections = Runtime.ConnectionsService.ConnectionTreeModel.GetRecursiveChildList().Where(item => item.OpenConnections.Count > 0); - foreach (ConnectionInfo connection in connectionTreeConnections) + foreach (var connection in connectionTreeConnections) { processHandlers.AddRange(ProcessOpenConnections(connection)); } @@ -85,8 +85,7 @@ namespace mRemoteNG.Tools private void processKeyPress(object sender, KeyEventArgs e) { - TextBox txtMultiSSH = sender as TextBox; - if (txtMultiSSH == null) return; + if (!(sender is TextBox txtMultiSSH)) return; if (processHandlers.Count == 0) { @@ -111,42 +110,37 @@ namespace mRemoteNG.Tools txtMultiSSH.Select(txtMultiSSH.TextLength, 0); } - if (e.Control == true && e.KeyCode != Keys.V && e.Alt == false) + if (e.Control && e.KeyCode != Keys.V && e.Alt == false) { SendAllKeystrokes(NativeMethods.WM_KEYDOWN, e.KeyValue); } - if (e.KeyCode == Keys.Enter) + if (e.KeyCode != Keys.Enter) return; + var strLine = txtMultiSSH.Text; + foreach (var chr1 in strLine) { - string strLine = txtMultiSSH.Text; - foreach (char chr1 in strLine) - { - SendAllKeystrokes(NativeMethods.WM_CHAR, Convert.ToByte(chr1)); - } - SendAllKeystrokes(NativeMethods.WM_KEYDOWN, 13); // Enter = char13 + SendAllKeystrokes(NativeMethods.WM_CHAR, Convert.ToByte(chr1)); } + SendAllKeystrokes(NativeMethods.WM_KEYDOWN, 13); // Enter = char13 } private void processKeyRelease(object sender, KeyEventArgs e) { - TextBox txtMultiSSH = sender as TextBox; - if (txtMultiSSH == null) return; + if (!(sender is TextBox txtMultiSSH)) return; - if (e.KeyCode == Keys.Enter) + if (e.KeyCode != Keys.Enter) return; + if (txtMultiSSH.Text.Trim() != "") { - if (txtMultiSSH.Text.Trim() != "") - { - previousCommands.Add(txtMultiSSH.Text.Trim()); - } - if (previousCommands.Count >= CommandHistoryLength) - { - previousCommands.RemoveAt(0); - } - - previousCommandIndex = previousCommands.Count - 1; - txtMultiSSH.Clear(); - } + previousCommands.Add(txtMultiSSH.Text.Trim()); } + if (previousCommands.Count >= CommandHistoryLength) + { + previousCommands.RemoveAt(0); + } + + previousCommandIndex = previousCommands.Count - 1; + txtMultiSSH.Clear(); + } #endregion } } diff --git a/mRemoteV1/Tools/NotificationAreaIcon.cs b/mRemoteV1/Tools/NotificationAreaIcon.cs index fa6927a90..d9d9b6e90 100644 --- a/mRemoteV1/Tools/NotificationAreaIcon.cs +++ b/mRemoteV1/Tools/NotificationAreaIcon.cs @@ -46,7 +46,7 @@ namespace mRemoteNG.Tools { Text = @"mRemoteNG", BalloonTipText = @"mRemoteNG", - Icon = Resources.mRemote_Icon, + Icon = Resources.mRemoteNG_Icon, ContextMenuStrip = _cMen, Visible = true }; diff --git a/mRemoteV1/Tools/PortScanner.cs b/mRemoteV1/Tools/PortScanner.cs index 2ee08ca67..3b213542f 100644 --- a/mRemoteV1/Tools/PortScanner.cs +++ b/mRemoteV1/Tools/PortScanner.cs @@ -18,10 +18,10 @@ namespace mRemoteNG.Tools private Thread _scanThread; private readonly List _scannedHosts = new List(); private readonly int _timeoutInMilliseconds; - + #region Public Methods - - public PortScanner(IPAddress ipAddress1, IPAddress ipAddress2, int port1, int port2, int timeoutInMilliseconds = 5000) + + public PortScanner(IPAddress ipAddress1, IPAddress ipAddress2, int port1, int port2, int timeoutInMilliseconds = 5000, bool checkDefaultPortsOnly = false) { var ipAddressStart = IpAddressMin(ipAddress1, ipAddress2); var ipAddressEnd = IpAddressMax(ipAddress1, ipAddress2); @@ -29,18 +29,25 @@ namespace mRemoteNG.Tools var portStart = Math.Min(port1, port2); var portEnd = Math.Max(port1, port2); + // if only one port was specified, just scan the one port... + if (portStart == 0) + portStart = portEnd; + if (timeoutInMilliseconds < 0) throw new ArgumentOutOfRangeException(nameof(timeoutInMilliseconds)); _timeoutInMilliseconds = timeoutInMilliseconds; - - _ports.Clear(); - for (var port = portStart; port <= portEnd; port++) - { - _ports.Add(port); - } - _ports.AddRange(new[] { ScanHost.SshPort, ScanHost.TelnetPort, ScanHost.HttpPort, ScanHost.HttpsPort, ScanHost.RloginPort, ScanHost.RdpPort, ScanHost.VncPort }); + + if (checkDefaultPortsOnly) + _ports.AddRange(new[] { ScanHost.SshPort, ScanHost.TelnetPort, ScanHost.HttpPort, ScanHost.HttpsPort, ScanHost.RloginPort, ScanHost.RdpPort, ScanHost.VncPort }); + else + { + for (var port = portStart; port <= portEnd; port++) + { + _ports.Add(port); + } + } _ipAddresses.Clear(); _ipAddresses.AddRange(IpAddressArrayFromRange(ipAddressStart, ipAddressEnd)); @@ -58,6 +65,10 @@ namespace mRemoteNG.Tools public void StopScan() { + foreach(var p in _pings) + { + p.SendAsyncCancel(); + } _scanThread.Abort(); } @@ -79,6 +90,7 @@ namespace mRemoteNG.Tools #region Private Methods private int _hostCount; + private readonly List _pings = new List(); private void ScanAsync() { try @@ -90,6 +102,7 @@ namespace mRemoteNG.Tools RaiseBeginHostScanEvent(ipAddress); var pingSender = new Ping(); + _pings.Add(pingSender); try { @@ -113,6 +126,9 @@ namespace mRemoteNG.Tools */ private void PingSender_PingCompleted(object sender, PingCompletedEventArgs e) { + // used for clean up later... + var p = (Ping)sender; + // UserState is the IP Address var ip = e.UserState.ToString(); var scanHost = new ScanHost(ip); @@ -120,6 +136,16 @@ namespace mRemoteNG.Tools Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Tools.PortScan: Scanning {_hostCount} of {_ipAddresses.Count} hosts: {scanHost.HostIp}", true); + + if (e.Cancelled) + { + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Tools.PortScan: CANCELLED host: {scanHost.HostIp}", true); + // cleanup + p.PingCompleted -= PingSender_PingCompleted; + p.Dispose(); + return; + } + if (e.Error != null) { Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Ping failed to {e.UserState} {Environment.NewLine} {e.Error.Message}", true); @@ -199,7 +225,6 @@ namespace mRemoteNG.Tools } // cleanup - var p = (Ping)sender; p.PingCompleted -= PingSender_PingCompleted; p.Dispose(); diff --git a/mRemoteV1/Tools/ReconnectGroup.Designer.cs b/mRemoteV1/Tools/ReconnectGroup.Designer.cs index 6e6e17994..4bbe7d77a 100644 --- a/mRemoteV1/Tools/ReconnectGroup.Designer.cs +++ b/mRemoteV1/Tools/ReconnectGroup.Designer.cs @@ -18,110 +18,111 @@ namespace mRemoteNG.Tools } } - //Required by the Windows Form Designer - private System.ComponentModel.Container components = null; - //NOTE: The following procedure is required by the Windows Form Designer //It can be modified using the Windows Form Designer. //Do not modify it using the code editor. [System.Diagnostics.DebuggerStepThrough()] private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.grpAutomaticReconnect = new System.Windows.Forms.GroupBox(); - this.lblAnimation = new UI.Controls.Base.NGLabel(); - this.btnClose = new UI.Controls.Base.NGButton(); - this.btnClose.Click += new System.EventHandler(this.btnClose_Click); - this.lblServerStatus = new UI.Controls.Base.NGLabel(); - this.chkReconnectWhenReady = new UI.Controls.Base.NGCheckBox(); - this.chkReconnectWhenReady.CheckedChanged += new System.EventHandler(this.chkReconnectWhenReady_CheckedChanged); - this.pbServerStatus = new System.Windows.Forms.PictureBox(); - this.tmrAnimation = new System.Windows.Forms.Timer(this.components); - this.tmrAnimation.Tick += new System.EventHandler(this.tmrAnimation_Tick); - this.grpAutomaticReconnect.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize) this.pbServerStatus).BeginInit(); - this.SuspendLayout(); - // - //grpAutomaticReconnect - // - this.grpAutomaticReconnect.BackColor = System.Drawing.Color.White; - this.grpAutomaticReconnect.Controls.Add(this.lblAnimation); - this.grpAutomaticReconnect.Controls.Add(this.btnClose); - this.grpAutomaticReconnect.Controls.Add(this.lblServerStatus); - this.grpAutomaticReconnect.Controls.Add(this.chkReconnectWhenReady); - this.grpAutomaticReconnect.Controls.Add(this.pbServerStatus); - this.grpAutomaticReconnect.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.grpAutomaticReconnect.Location = new System.Drawing.Point(3, 0); - this.grpAutomaticReconnect.Name = "grpAutomaticReconnect"; - this.grpAutomaticReconnect.Size = new System.Drawing.Size(171, 98); - this.grpAutomaticReconnect.TabIndex = 8; - this.grpAutomaticReconnect.TabStop = false; - this.grpAutomaticReconnect.Text = Language.strGroupboxAutomaticReconnect; - // - //lblAnimation - // - this.lblAnimation.Location = new System.Drawing.Point(124, 22); - this.lblAnimation.Name = "lblAnimation"; - this.lblAnimation.Size = new System.Drawing.Size(32, 17); - this.lblAnimation.TabIndex = 8; - // - //btnClose - // - this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.btnClose.Location = new System.Drawing.Point(6, 67); - this.btnClose.Name = "btnClose"; - this.btnClose.Size = new System.Drawing.Size(159, 23); - this.btnClose.TabIndex = 7; - this.btnClose.Text = Language.strButtonClose; - this.btnClose.UseVisualStyleBackColor = true; - // - //lblServerStatus - // - this.lblServerStatus.AutoSize = true; - this.lblServerStatus.Location = new System.Drawing.Point(15, 24); - this.lblServerStatus.Name = "lblServerStatus"; - this.lblServerStatus.Size = new System.Drawing.Size(74, 13); - this.lblServerStatus.TabIndex = 3; - this.lblServerStatus.Text = "Server Status:"; - // - //chkReconnectWhenReady - // - this.chkReconnectWhenReady.AutoSize = true; - this.chkReconnectWhenReady.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.chkReconnectWhenReady.Location = new System.Drawing.Point(18, 44); - this.chkReconnectWhenReady.Name = "chkReconnectWhenReady"; - this.chkReconnectWhenReady.Size = new System.Drawing.Size(129, 17); - this.chkReconnectWhenReady.TabIndex = 6; - this.chkReconnectWhenReady.Text = Language.strCheckboxReconnectWhenReady; - this.chkReconnectWhenReady.UseVisualStyleBackColor = true; - // - //pbServerStatus - // - this.pbServerStatus.Image = Resources.HostStatus_Check; - this.pbServerStatus.Location = new System.Drawing.Point(99, 23); - this.pbServerStatus.Name = "pbServerStatus"; - this.pbServerStatus.Size = new System.Drawing.Size(16, 16); - this.pbServerStatus.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.pbServerStatus.TabIndex = 5; - this.pbServerStatus.TabStop = false; - // - //tmrAnimation - // - this.tmrAnimation.Enabled = true; - this.tmrAnimation.Interval = 200; - // - //ReconnectGroup - // - this.AutoScaleDimensions = new System.Drawing.SizeF((float) (6.0F), (float) (13.0F)); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.Color.White; - this.Controls.Add(this.grpAutomaticReconnect); - this.Name = "ReconnectGroup"; - this.Size = new System.Drawing.Size(228, 138); - this.grpAutomaticReconnect.ResumeLayout(false); - this.grpAutomaticReconnect.PerformLayout(); - ((System.ComponentModel.ISupportInitialize) this.pbServerStatus).EndInit(); - this.ResumeLayout(false); + this.components = new System.ComponentModel.Container(); + this.grpAutomaticReconnect = new System.Windows.Forms.GroupBox(); + this.lblAnimation = new mRemoteNG.UI.Controls.Base.NGLabel(); + this.btnClose = new mRemoteNG.UI.Controls.Base.NGButton(); + this.lblServerStatus = new mRemoteNG.UI.Controls.Base.NGLabel(); + this.chkReconnectWhenReady = new mRemoteNG.UI.Controls.Base.NGCheckBox(); + this.pbServerStatus = new System.Windows.Forms.PictureBox(); + this.tmrAnimation = new System.Windows.Forms.Timer(this.components); + this.grpAutomaticReconnect.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbServerStatus)).BeginInit(); + this.SuspendLayout(); + // + // grpAutomaticReconnect + // + this.grpAutomaticReconnect.BackColor = System.Drawing.Color.White; + this.grpAutomaticReconnect.Controls.Add(this.lblAnimation); + this.grpAutomaticReconnect.Controls.Add(this.btnClose); + this.grpAutomaticReconnect.Controls.Add(this.lblServerStatus); + this.grpAutomaticReconnect.Controls.Add(this.chkReconnectWhenReady); + this.grpAutomaticReconnect.Controls.Add(this.pbServerStatus); + this.grpAutomaticReconnect.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.grpAutomaticReconnect.Location = new System.Drawing.Point(3, 0); + this.grpAutomaticReconnect.Name = "grpAutomaticReconnect"; + this.grpAutomaticReconnect.Size = new System.Drawing.Size(171, 98); + this.grpAutomaticReconnect.TabIndex = 8; + this.grpAutomaticReconnect.TabStop = false; + this.grpAutomaticReconnect.Text = "Automatic Reconnect"; + // + // lblAnimation + // + this.lblAnimation.Location = new System.Drawing.Point(124, 22); + this.lblAnimation.Name = "lblAnimation"; + this.lblAnimation.Size = new System.Drawing.Size(32, 17); + this.lblAnimation.TabIndex = 8; + // + // btnClose + // + this.btnClose._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER; + this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnClose.Location = new System.Drawing.Point(6, 67); + this.btnClose.Name = "btnClose"; + this.btnClose.Size = new System.Drawing.Size(159, 23); + this.btnClose.TabIndex = 7; + this.btnClose.Text = global::mRemoteNG.Language.strButtonClose; + this.btnClose.UseVisualStyleBackColor = true; + this.btnClose.Click += new System.EventHandler(this.btnClose_Click); + // + // lblServerStatus + // + this.lblServerStatus.AutoSize = true; + this.lblServerStatus.Location = new System.Drawing.Point(15, 24); + this.lblServerStatus.Name = "lblServerStatus"; + this.lblServerStatus.Size = new System.Drawing.Size(76, 13); + this.lblServerStatus.TabIndex = 3; + this.lblServerStatus.Text = "Server Status:"; + // + // chkReconnectWhenReady + // + this.chkReconnectWhenReady._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER; + this.chkReconnectWhenReady.AutoSize = true; + this.chkReconnectWhenReady.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.chkReconnectWhenReady.Location = new System.Drawing.Point(18, 44); + this.chkReconnectWhenReady.Name = "chkReconnectWhenReady"; + this.chkReconnectWhenReady.Size = new System.Drawing.Size(140, 17); + this.chkReconnectWhenReady.TabIndex = 6; + this.chkReconnectWhenReady.Text = global::mRemoteNG.Language.strCheckboxReconnectWhenReady; + this.chkReconnectWhenReady.UseVisualStyleBackColor = true; + this.chkReconnectWhenReady.CheckedChanged += new System.EventHandler(this.chkReconnectWhenReady_CheckedChanged); + // + // pbServerStatus + // + this.pbServerStatus.Image = global::mRemoteNG.Resources.HostStatus_Check; + this.pbServerStatus.Location = new System.Drawing.Point(99, 23); + this.pbServerStatus.Name = "pbServerStatus"; + this.pbServerStatus.Size = new System.Drawing.Size(16, 16); + this.pbServerStatus.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.pbServerStatus.TabIndex = 5; + this.pbServerStatus.TabStop = false; + // + // tmrAnimation + // + this.tmrAnimation.Enabled = true; + this.tmrAnimation.Interval = 200; + this.tmrAnimation.Tick += new System.EventHandler(this.tmrAnimation_Tick); + // + // ReconnectGroup + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.grpAutomaticReconnect); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Name = "ReconnectGroup"; + this.Size = new System.Drawing.Size(228, 138); + this.grpAutomaticReconnect.ResumeLayout(false); + this.grpAutomaticReconnect.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbServerStatus)).EndInit(); + this.ResumeLayout(false); + } internal System.Windows.Forms.GroupBox grpAutomaticReconnect; internal UI.Controls.Base.NGButton btnClose; @@ -130,5 +131,6 @@ namespace mRemoteNG.Tools internal System.Windows.Forms.PictureBox pbServerStatus; internal System.Windows.Forms.Timer tmrAnimation; internal UI.Controls.Base.NGLabel lblAnimation; - } + private System.ComponentModel.IContainer components; + } } \ No newline at end of file diff --git a/mRemoteV1/Tools/ReconnectGroup.cs b/mRemoteV1/Tools/ReconnectGroup.cs index bfc6510d5..d78361e24 100644 --- a/mRemoteV1/Tools/ReconnectGroup.cs +++ b/mRemoteV1/Tools/ReconnectGroup.cs @@ -12,11 +12,8 @@ namespace mRemoteNG.Tools private bool _ServerReady; public bool ServerReady { - get - { - return _ServerReady; - } - set + get => _ServerReady; + set { SetStatusImage(value ? Resources.HostStatus_On : Resources.HostStatus_Off); @@ -46,11 +43,8 @@ namespace mRemoteNG.Tools private bool _ReconnectWhenReady; public bool ReconnectWhenReady { - get - { - return _ReconnectWhenReady; - } - set + get => _ReconnectWhenReady; + set { _ReconnectWhenReady = value; SetCheckbox(value); @@ -76,15 +70,9 @@ namespace mRemoteNG.Tools public event CloseClickedEventHandler CloseClicked { - add - { - CloseClickedEvent = (CloseClickedEventHandler) Delegate.Combine(CloseClickedEvent, value); - } - remove - { - CloseClickedEvent = (CloseClickedEventHandler) Delegate.Remove(CloseClickedEvent, value); - } - } + add => CloseClickedEvent = (CloseClickedEventHandler) Delegate.Combine(CloseClickedEvent, value); + remove => CloseClickedEvent = (CloseClickedEventHandler) Delegate.Remove(CloseClickedEvent, value); + } private void btnClose_Click(object sender, EventArgs e) diff --git a/mRemoteV1/Tools/ReconnectGroup.resx b/mRemoteV1/Tools/ReconnectGroup.resx index 5a7628ea6..34ccac31d 100644 --- a/mRemoteV1/Tools/ReconnectGroup.resx +++ b/mRemoteV1/Tools/ReconnectGroup.resx @@ -112,15 +112,15 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + 18, 18 - + 60 \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGButton.cs b/mRemoteV1/UI/Controls/Base/NGButton.cs index 5403d93d5..c4f266a38 100644 --- a/mRemoteV1/UI/Controls/Base/NGButton.cs +++ b/mRemoteV1/UI/Controls/Base/NGButton.cs @@ -128,5 +128,16 @@ namespace mRemoteNG.UI.Controls.Base } TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, fore, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter); } + + private void InitializeComponent() + { + this.SuspendLayout(); + // + // NGButton + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGButton.resx b/mRemoteV1/UI/Controls/Base/NGButton.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGButton.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGCheckBox.cs b/mRemoteV1/UI/Controls/Base/NGCheckBox.cs index fb75a6511..3b1c81dee 100644 --- a/mRemoteV1/UI/Controls/Base/NGCheckBox.cs +++ b/mRemoteV1/UI/Controls/Base/NGCheckBox.cs @@ -5,13 +5,27 @@ using System.Windows.Forms; namespace mRemoteNG.UI.Controls.Base { //Extended CheckBox class, the NGCheckBox onPaint completely repaint the control + + // + // If this causes design issues in the future, may want to think about migrating to + // CheckBoxRenderer: + // https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.checkboxrenderer?view=netframework-4.6 + // public class NGCheckBox : CheckBox { private ThemeManager _themeManager; + private readonly Size _checkboxSize; + private readonly int _checkboxYCoord; + private readonly int _textXCoord; public NGCheckBox() { + InitializeComponent(); ThemeManager.getInstance().ThemeChanged += OnCreateControl; + var display = new DisplayProperties(); + _checkboxSize = new Size(display.ScaleWidth(11), display.ScaleHeight(11)); + _checkboxYCoord = (display.ScaleHeight(Height) - _checkboxSize.Height) / 2 - display.ScaleHeight(5); + _textXCoord = _checkboxSize.Width + display.ScaleWidth(2); } public enum MouseState @@ -100,22 +114,31 @@ namespace mRemoteNG.UI.Controls.Base using (var p = new Pen(checkBorder)) { - var boxRect = new Rectangle(0, Height / 2 - 7, 11, 11); + var boxRect = new Rectangle(0, _checkboxYCoord, _checkboxSize.Width, _checkboxSize.Height); e.Graphics.FillRectangle(new SolidBrush(back), boxRect); e.Graphics.DrawRectangle(p, boxRect); } if (Checked) { - e.Graphics.DrawString("\u2714", new Font(Font.FontFamily, 7f), new SolidBrush(glyph), -1, 1); + // | \uE001 |  | î€ | is the tick/check mark and it exists in Segoe UI Symbol at least... + e.Graphics.DrawString("\uE001", new Font("Segoe UI Symbol", 7.75f), new SolidBrush(glyph), -4, 0); } - var textRect = new Rectangle(16, 0, Width - 16, Height); + var textRect = new Rectangle(_textXCoord, 0, Width - 16, Height); TextRenderer.DrawText(e.Graphics, Text, Font, textRect, fore, Parent.BackColor, TextFormatFlags.PathEllipsis); - - } + private void InitializeComponent() + { + this.SuspendLayout(); + // + // NGCheckBox + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGCheckBox.resx b/mRemoteV1/UI/Controls/Base/NGCheckBox.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGCheckBox.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGComboBox.cs b/mRemoteV1/UI/Controls/Base/NGComboBox.cs index 4163aade9..43ff476e8 100644 --- a/mRemoteV1/UI/Controls/Base/NGComboBox.cs +++ b/mRemoteV1/UI/Controls/Base/NGComboBox.cs @@ -73,15 +73,21 @@ namespace mRemoteNG.UI.Controls.Base else e.Graphics.FillRectangle(new SolidBrush(_themeManager.ActiveTheme.ExtendedPalette.getColor("ComboBox_Background")), e.Bounds); - if(string.IsNullOrEmpty(DisplayMember)) - e.Graphics.DrawString(Items[index].ToString(), e.Font, itemBrush, e.Bounds, StringFormat.GenericDefault); - else + if (Items.Count > 0) { - if (Items[index].GetType().GetProperty(DisplayMember) != null) + if (string.IsNullOrEmpty(DisplayMember)) + e.Graphics.DrawString(Items[index].ToString(), e.Font, itemBrush, e.Bounds, StringFormat.GenericDefault); + else { - e.Graphics.DrawString(Items[index].GetType().GetProperty(DisplayMember)?.GetValue(Items[index],null).ToString(), e.Font, itemBrush, e.Bounds, StringFormat.GenericDefault); + if (Items[index].GetType().GetProperty(DisplayMember) != null) + { + e.Graphics.DrawString( + Items[index].GetType().GetProperty(DisplayMember)?.GetValue(Items[index], null).ToString(), + e.Font, itemBrush, e.Bounds, StringFormat.GenericDefault); + } } } + e.DrawFocusRectangle(); } @@ -135,5 +141,16 @@ namespace mRemoteNG.UI.Controls.Base var textRect = new Rectangle(2, 2, Width - 20, Height - 4); TextRenderer.DrawText(e.Graphics, Text, Font, textRect, Fore, Back, TextFormatFlags.Left | TextFormatFlags.VerticalCenter); } + + private void InitializeComponent() + { + this.SuspendLayout(); + // + // NGComboBox + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGComboBox.resx b/mRemoteV1/UI/Controls/Base/NGComboBox.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGComboBox.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGGroupBox.cs b/mRemoteV1/UI/Controls/Base/NGGroupBox.cs index 3d369529f..8b52dbb85 100644 --- a/mRemoteV1/UI/Controls/Base/NGGroupBox.cs +++ b/mRemoteV1/UI/Controls/Base/NGGroupBox.cs @@ -86,6 +86,17 @@ namespace mRemoteNG.UI.Controls.Base e.Graphics.DrawLine(pen, bounds.Width - Padding.Right, num - Padding.Top, bounds.Width - Padding.Right, bounds.Height - Padding.Bottom); } RaisePaintEvent(this, e); - } + } + + private void InitializeComponent() + { + this.SuspendLayout(); + // + // NGGroupBox + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGGroupBox.resx b/mRemoteV1/UI/Controls/Base/NGGroupBox.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGGroupBox.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGLabel.cs b/mRemoteV1/UI/Controls/Base/NGLabel.cs index 47bb5f526..987bc55d1 100644 --- a/mRemoteV1/UI/Controls/Base/NGLabel.cs +++ b/mRemoteV1/UI/Controls/Base/NGLabel.cs @@ -96,6 +96,17 @@ namespace mRemoteNG.UI.Controls.Base var disabledtextLabel = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Disabled_Foreground"); TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, disabledtextLabel, _textFormatFlags); } - } + } + + private void InitializeComponent() + { + this.SuspendLayout(); + // + // NGLabel + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGLabel.resx b/mRemoteV1/UI/Controls/Base/NGLabel.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGLabel.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGListView.cs b/mRemoteV1/UI/Controls/Base/NGListView.cs index 35c69c7a1..3c551d730 100644 --- a/mRemoteV1/UI/Controls/Base/NGListView.cs +++ b/mRemoteV1/UI/Controls/Base/NGListView.cs @@ -66,5 +66,18 @@ namespace mRemoteNG.UI.Controls.Base e.SubItem.Decoration = deco; } } + + private void InitializeComponent() + { + ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); + this.SuspendLayout(); + // + // NGListView + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGListView.resx b/mRemoteV1/UI/Controls/Base/NGListView.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGListView.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs b/mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs index 4b6cec616..532470e16 100644 --- a/mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs +++ b/mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs @@ -11,7 +11,7 @@ namespace mRemoteNG.UI.Controls.Base internal class NGNumericUpDown : NumericUpDown { - private ThemeManager _themeManager; + private readonly ThemeManager _themeManager; private NGButton Up; private NGButton Down; @@ -28,23 +28,42 @@ namespace mRemoteNG.UI.Controls.Base ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true); - //Hide those nonthemable butons + if (Controls.Count > 0) - Controls[0].Hide(); + { + for (var i = 0; i < Controls.Count; i++) + { + //Remove those non-themable buttons + if (Controls[i].GetType().ToString().Equals("System.Windows.Forms.UpDownBase+UpDownButtons")) + Controls.Remove(Controls[i]); + + /* This is a bit of a hack. + * But if we have the buttons that we created already, redraw/return and don't add any more... + * + * OptionsPages are an example where the control is potentially created twice: + * AddOptionsPagesToListView and then LstOptionPages_SelectedIndexChanged + */ + if (!(Controls[i] is NGButton)) continue; + if (!Controls[i].Text.Equals("\u25B2") && !Controls[i].Text.Equals("\u25BC")) continue; + Invalidate(); + return; + } + } + //Add new themable buttons Up = new NGButton { Text = "\u25B2", - Font = new Font(Font.FontFamily, 6f) + Font = new Font(Font.FontFamily, 5f) }; - Up.SetBounds(Width - 17, 1, 16, Height / 2 - 1); + Up.SetBounds(Controls.Owner.Width - 17, 2, 16, Controls.Owner.Height / 2 - 1); Up.Click += Up_Click; Down = new NGButton { Text = "\u25BC", - Font = new Font(Font.FontFamily, 6f) + Font = new Font(Font.FontFamily, 5f) }; - Down.SetBounds(Width - 17, Height/2, 16, Height / 2 - 1); + Down.SetBounds(Controls.Owner.Width - 17, Controls.Owner.Height /2 + 1, 16, Controls.Owner.Height / 2 - 1); Down.Click += Down_Click; Controls.Add(Up); Controls.Add(Down); @@ -91,6 +110,17 @@ namespace mRemoteNG.UI.Controls.Base e.Graphics.DrawRectangle(new Pen(_themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Border"), 1), 0, 0, Width - 1, Height - 1); } - + private void InitializeComponent() + { + ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); + this.SuspendLayout(); + // + // NGNumericUpDown + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGNumericUpDown.resx b/mRemoteV1/UI/Controls/Base/NGNumericUpDown.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGNumericUpDown.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGPictureBox.Designer.cs b/mRemoteV1/UI/Controls/Base/NGPictureBox.Designer.cs new file mode 100644 index 000000000..b467b1b1a --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGPictureBox.Designer.cs @@ -0,0 +1,36 @@ +namespace mRemoteNG.UI.Controls.Base +{ + partial class NGPictureBox + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/mRemoteV1/UI/Controls/Base/NGPictureBox.cs b/mRemoteV1/UI/Controls/Base/NGPictureBox.cs new file mode 100644 index 000000000..04a59b5c0 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGPictureBox.cs @@ -0,0 +1,34 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using mRemoteNG.Themes; + +namespace mRemoteNG.UI.Controls.Base +{ + public partial class NGPictureBox : PictureBox + { + private ThemeManager _themeManager; + + public NGPictureBox() + { + ThemeManager.getInstance().ThemeChanged += OnCreateControl; + } + + public NGPictureBox(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + + protected override void OnCreateControl() + { + base.OnCreateControl(); + _themeManager = ThemeManager.getInstance(); + if (!_themeManager.ThemingActive) return; + ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); + BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); + Invalidate(); + } + } +} diff --git a/mRemoteV1/UI/Controls/Base/NGRadioButton.cs b/mRemoteV1/UI/Controls/Base/NGRadioButton.cs index 6b480f5ea..fc16b226b 100644 --- a/mRemoteV1/UI/Controls/Base/NGRadioButton.cs +++ b/mRemoteV1/UI/Controls/Base/NGRadioButton.cs @@ -10,14 +10,18 @@ namespace mRemoteNG.UI.Controls.Base class NGRadioButton : RadioButton { private ThemeManager _themeManager; - private Rectangle circle; - private Rectangle circle_small; + private readonly Rectangle _circle; + private readonly Rectangle _circleSmall; + private readonly int _textXCoord; + // Constructor public NGRadioButton() { - // Init - circle_small = new Rectangle(4, 4, 6, 6 ); - circle = new Rectangle(1, 1, 12, 12 ); + var display = new DisplayProperties(); + + _circleSmall = new Rectangle(display.ScaleWidth(4), display.ScaleHeight(4), display.ScaleWidth(6), display.ScaleHeight(6)); + _circle = new Rectangle(display.ScaleWidth(1), display.ScaleHeight(1), display.ScaleWidth(12), display.ScaleHeight(12)); + _textXCoord = display.ScaleWidth(16); ThemeManager.getInstance().ThemeChanged += OnCreateControl; } @@ -88,8 +92,7 @@ namespace mRemoteNG.UI.Controls.Base e.Graphics.Clear(Parent.BackColor); if (Enabled) { - - if(Checked) + if (Checked) { center = _themeManager.ActiveTheme.ExtendedPalette.getColor("CheckBox_Glyph"); } @@ -109,14 +112,23 @@ namespace mRemoteNG.UI.Controls.Base fore = _themeManager.ActiveTheme.ExtendedPalette.getColor("CheckBox_Text_Disabled"); } - var textRect = new Rectangle(16, Padding.Top, Width - 16, Height); + var textRect = new Rectangle(_textXCoord, Padding.Top, Width - 16, Height); TextRenderer.DrawText(e.Graphics, Text, Font, textRect, fore, Parent.BackColor, TextFormatFlags.PathEllipsis); - g.FillEllipse(new SolidBrush(centerBack), circle); - g.FillEllipse(new SolidBrush(center), circle_small); - g.DrawEllipse(new Pen(outline), circle); - + g.FillEllipse(new SolidBrush(centerBack), _circle); + g.FillEllipse(new SolidBrush(center), _circleSmall); + g.DrawEllipse(new Pen(outline), _circle); } + private void InitializeComponent() + { + this.SuspendLayout(); + // + // NGRadioButton + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGRadioButton.resx b/mRemoteV1/UI/Controls/Base/NGRadioButton.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGRadioButton.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/Base/NGTextBox.cs b/mRemoteV1/UI/Controls/Base/NGTextBox.cs index 0d51c25e3..0356bf1de 100644 --- a/mRemoteV1/UI/Controls/Base/NGTextBox.cs +++ b/mRemoteV1/UI/Controls/Base/NGTextBox.cs @@ -50,6 +50,15 @@ namespace mRemoteNG.UI.Controls.Base Invalidate(); } - + private void InitializeComponent() + { + this.SuspendLayout(); + // + // NGTextBox + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + + } } } diff --git a/mRemoteV1/UI/Controls/Base/NGTextBox.resx b/mRemoteV1/UI/Controls/Base/NGTextBox.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/Base/NGTextBox.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.Designer.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.Designer.cs index 637ff1747..f8c8d7b0d 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.Designer.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.Designer.cs @@ -15,7 +15,15 @@ ///
private void InitializeComponent() { - components = new System.ComponentModel.Container(); + ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); + this.SuspendLayout(); + // + // ConnectionTree + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); + this.ResumeLayout(false); + } #endregion diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs index 14615af53..cfa2edb94 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs @@ -109,15 +109,13 @@ namespace mRemoteNG.UI.Controls { Collapsed += (sender, args) => { - var container = args.Model as ContainerInfo; - if (container == null) return; + if (!(args.Model is ContainerInfo container)) return; container.IsExpanded = false; AutoResizeColumn(Columns[0]); }; Expanded += (sender, args) => { - var container = args.Model as ContainerInfo; - if (container == null) return; + if (!(args.Model is ContainerInfo container)) return; container.IsExpanded = true; AutoResizeColumn(Columns[0]); }; @@ -204,8 +202,7 @@ namespace mRemoteNG.UI.Controls return; } - var senderAsConnectionInfo = sender as ConnectionInfo; - if (senderAsConnectionInfo == null) + if (!(sender is ConnectionInfo senderAsConnectionInfo)) return; RefreshObject(senderAsConnectionInfo); @@ -309,11 +306,9 @@ namespace mRemoteNG.UI.Controls public void RenameSelectedNode() { - if (SelectedItem != null) - { - _allowEdit = true; - SelectedItem.BeginEdit(); - } + if (SelectedItem == null) return; + _allowEdit = true; + SelectedItem.BeginEdit(); } public void DeleteSelectedNode() @@ -335,8 +330,7 @@ namespace mRemoteNG.UI.Controls Runtime.ConnectionsService.BeginBatchingSaves(); - var sortTargetAsContainer = sortTarget as ContainerInfo; - if (sortTargetAsContainer != null) + if (sortTarget is ContainerInfo sortTargetAsContainer) sortTargetAsContainer.SortRecursive(sortDirection); else SelectedNode.Parent.SortRecursive(sortDirection); @@ -389,12 +383,10 @@ namespace mRemoteNG.UI.Controls AutoResizeColumn(Columns[0]); // turn filtering back on - if (filteringEnabled) - { - ModelFilter = filter; - UpdateFiltering(); - } - } + if (!filteringEnabled) return; + ModelFilter = filter; + UpdateFiltering(); + } protected override void UpdateFiltering() { @@ -417,20 +409,20 @@ namespace mRemoteNG.UI.Controls private void OnMouse_DoubleClick(object sender, MouseEventArgs mouseEventArgs) { if (mouseEventArgs.Clicks < 2) return; + // ReSharper disable once NotAccessedVariable OLVColumn column; var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out column); - var clickedNode = listItem?.RowObject as ConnectionInfo; - if (clickedNode == null) return; + if (!(listItem?.RowObject is ConnectionInfo clickedNode)) return; DoubleClickHandler.Execute(clickedNode); } private void OnMouse_SingleClick(object sender, MouseEventArgs mouseEventArgs) { if (mouseEventArgs.Clicks > 1) return; + // ReSharper disable once NotAccessedVariable OLVColumn column; var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out column); - var clickedNode = listItem?.RowObject as ConnectionInfo; - if (clickedNode == null) return; + if (!(listItem?.RowObject is ConnectionInfo clickedNode)) return; SingleClickHandler.Execute(clickedNode); } diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.resx b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTreeSearchTextFilter.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTreeSearchTextFilter.cs index 82e388584..425c329db 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTreeSearchTextFilter.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTreeSearchTextFilter.cs @@ -17,8 +17,7 @@ namespace mRemoteNG.UI.Controls public bool Filter(object modelObject) { - var objectAsConnectionInfo = modelObject as ConnectionInfo; - if (objectAsConnectionInfo == null) + if (!(modelObject is ConnectionInfo objectAsConnectionInfo)) return false; if (SpecialInclusionList.Contains(objectAsConnectionInfo)) @@ -26,12 +25,9 @@ namespace mRemoteNG.UI.Controls var filterTextLower = FilterText.ToLowerInvariant(); - if (objectAsConnectionInfo.Name.ToLowerInvariant().Contains(filterTextLower) || - objectAsConnectionInfo.Hostname.ToLowerInvariant().Contains(filterTextLower) || - objectAsConnectionInfo.Description.ToLowerInvariant().Contains(filterTextLower)) - return true; - - return false; + return objectAsConnectionInfo.Name.ToLowerInvariant().Contains(filterTextLower) || + objectAsConnectionInfo.Hostname.ToLowerInvariant().Contains(filterTextLower) || + objectAsConnectionInfo.Description.ToLowerInvariant().Contains(filterTextLower); } } } diff --git a/mRemoteV1/UI/Controls/CredentialRecordComboBox.Designer.cs b/mRemoteV1/UI/Controls/CredentialRecordComboBox.Designer.cs index 2c9dbf369..3877645d5 100644 --- a/mRemoteV1/UI/Controls/CredentialRecordComboBox.Designer.cs +++ b/mRemoteV1/UI/Controls/CredentialRecordComboBox.Designer.cs @@ -28,7 +28,13 @@ /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); + this.SuspendLayout(); + // + // CredentialRecordComboBox + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + } #endregion diff --git a/mRemoteV1/UI/Controls/CredentialRecordComboBox.resx b/mRemoteV1/UI/Controls/CredentialRecordComboBox.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/CredentialRecordComboBox.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/CredentialRecordListBox.Designer.cs b/mRemoteV1/UI/Controls/CredentialRecordListBox.Designer.cs index 445bad9f4..645745053 100644 --- a/mRemoteV1/UI/Controls/CredentialRecordListBox.Designer.cs +++ b/mRemoteV1/UI/Controls/CredentialRecordListBox.Designer.cs @@ -28,7 +28,13 @@ /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); + this.SuspendLayout(); + // + // CredentialRecordListBox + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + } #endregion diff --git a/mRemoteV1/UI/Controls/CredentialRecordListBox.resx b/mRemoteV1/UI/Controls/CredentialRecordListBox.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/CredentialRecordListBox.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/CredentialRecordListView.Designer.cs b/mRemoteV1/UI/Controls/CredentialRecordListView.Designer.cs index 44e7d7857..af55e86e3 100644 --- a/mRemoteV1/UI/Controls/CredentialRecordListView.Designer.cs +++ b/mRemoteV1/UI/Controls/CredentialRecordListView.Designer.cs @@ -28,13 +28,13 @@ /// private void InitializeComponent() { - this.objectListView1 = new Base.NGListView(); - this.olvColumnCredentialId = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); + this.objectListView1 = new mRemoteNG.UI.Controls.Base.NGListView(); this.olvColumnTitle = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.olvColumnUsername = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.olvColumnDomain = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); - this.olvColumnRepositorySource = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); + this.olvColumnCredentialId = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.olvColumnRepositoryTitle = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); + this.olvColumnRepositorySource = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); ((System.ComponentModel.ISupportInitialize)(this.objectListView1)).BeginInit(); this.SuspendLayout(); // @@ -55,6 +55,7 @@ this.objectListView1.CopySelectionOnControlC = false; this.objectListView1.CopySelectionOnControlCUsesDragSource = false; this.objectListView1.Cursor = System.Windows.Forms.Cursors.Default; + this.objectListView1.DecorateLines = true; this.objectListView1.Dock = System.Windows.Forms.DockStyle.Fill; this.objectListView1.FullRowSelect = true; this.objectListView1.HideSelection = false; @@ -68,14 +69,6 @@ this.objectListView1.UseNotifyPropertyChanged = true; this.objectListView1.View = System.Windows.Forms.View.Details; // - // olvColumnCredentialId - // - this.olvColumnCredentialId.AspectName = ""; - this.olvColumnCredentialId.DisplayIndex = 0; - this.olvColumnCredentialId.IsEditable = false; - this.olvColumnCredentialId.IsVisible = false; - this.olvColumnCredentialId.Text = "Credential ID"; - // // olvColumnTitle // this.olvColumnTitle.AspectName = ""; @@ -92,21 +85,30 @@ this.olvColumnDomain.AspectName = ""; this.olvColumnDomain.Text = "Domain"; // + // olvColumnCredentialId + // + this.olvColumnCredentialId.AspectName = ""; + this.olvColumnCredentialId.DisplayIndex = 0; + this.olvColumnCredentialId.IsEditable = false; + this.olvColumnCredentialId.IsVisible = false; + this.olvColumnCredentialId.Text = "Credential ID"; + // + // olvColumnRepositoryTitle + // + this.olvColumnRepositoryTitle.Text = "Repository Title"; + // // olvColumnRepositorySource // this.olvColumnRepositorySource.DisplayIndex = 4; this.olvColumnRepositorySource.IsVisible = false; this.olvColumnRepositorySource.Text = "Source"; // - // olvColumnRepositoryTitle - // - this.olvColumnRepositoryTitle.Text = "Repository Title"; - // // CredentialRecordListView // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.Controls.Add(this.objectListView1); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Name = "CredentialRecordListView"; this.Size = new System.Drawing.Size(367, 204); ((System.ComponentModel.ISupportInitialize)(this.objectListView1)).EndInit(); diff --git a/mRemoteV1/UI/Controls/CredentialRepositoryListView.Designer.cs b/mRemoteV1/UI/Controls/CredentialRepositoryListView.Designer.cs index 175993320..c9312d156 100644 --- a/mRemoteV1/UI/Controls/CredentialRepositoryListView.Designer.cs +++ b/mRemoteV1/UI/Controls/CredentialRepositoryListView.Designer.cs @@ -15,12 +15,12 @@ /// private void InitializeComponent() { - this.objectListView1 = new Base.NGListView(); + this.objectListView1 = new mRemoteNG.UI.Controls.Base.NGListView(); this.olvColumnTitle = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.olvColumnProvider = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.olvColumnIsLoaded = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); - this.olvColumnId = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.olvColumnSource = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); + this.olvColumnId = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); ((System.ComponentModel.ISupportInitialize)(this.objectListView1)).BeginInit(); this.SuspendLayout(); // @@ -41,6 +41,7 @@ this.objectListView1.CopySelectionOnControlC = false; this.objectListView1.CopySelectionOnControlCUsesDragSource = false; this.objectListView1.Cursor = System.Windows.Forms.Cursors.Default; + this.objectListView1.DecorateLines = true; this.objectListView1.Dock = System.Windows.Forms.DockStyle.Fill; this.objectListView1.FullRowSelect = true; this.objectListView1.HideSelection = false; @@ -73,10 +74,6 @@ this.olvColumnIsLoaded.IsEditable = false; this.olvColumnIsLoaded.Text = "Loaded"; // - // olvColumnId - // - this.olvColumnId.Text = "ID"; - // // olvColumnSource // this.olvColumnSource.AspectName = ""; @@ -84,11 +81,16 @@ this.olvColumnSource.Groupable = false; this.olvColumnSource.Text = "Source"; // + // olvColumnId + // + this.olvColumnId.Text = "ID"; + // // CredentialRepositoryListView // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.Controls.Add(this.objectListView1); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Name = "CredentialRepositoryListView"; this.Size = new System.Drawing.Size(308, 171); ((System.ComponentModel.ISupportInitialize)(this.objectListView1)).EndInit(); diff --git a/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.cs b/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.cs index 127654ba5..57c745386 100644 --- a/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.cs +++ b/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.cs @@ -50,8 +50,8 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid public IEnumerable VisibleProperties => _propertyDescriptors.Select(p => p.Name); public new AttributeCollection BrowsableAttributes { - get { return _browsableAttributes; } - set { + get => _browsableAttributes; + set { if (_browsableAttributes == value) return; _hiddenAttributes = null; _browsableAttributes = value; @@ -63,8 +63,8 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid /// Get or set the categories to hide. /// public AttributeCollection HiddenAttributes { - get { return _hiddenAttributes; } - set { + get => _hiddenAttributes; + set { if (value == _hiddenAttributes) return; _hiddenAttributes = value; _browsableAttributes = null; @@ -77,8 +77,8 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid /// /// if one or several properties don't exist. public string[] BrowsableProperties { - get { return _mBrowsableProperties; } - set { + get => _mBrowsableProperties; + set { if (value == _mBrowsableProperties) return; _mBrowsableProperties = value; RefreshProperties(); @@ -87,8 +87,8 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid /// Get or set the properties to hide. public string[] HiddenProperties { - get { return _mHiddenProperties; } - set { + get => _mHiddenProperties; + set { if (value == _mHiddenProperties) return; _mHiddenProperties = value; RefreshProperties(); @@ -100,13 +100,11 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid /// /// The object passed to the base PropertyGrid is the wrapper. public new object SelectedObject { - get - { - return _mWrapper != null - ? ((ObjectWrapper)base.SelectedObject).SelectedObject - : null; - } - set { + get => + _mWrapper != null + ? ((ObjectWrapper)base.SelectedObject).SelectedObject + : null; + set { // Set the new object to the wrapper and create one if necessary. if(_mWrapper == null) { diff --git a/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.designer.cs b/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.designer.cs index 586b88139..1113c99d9 100644 --- a/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.designer.cs +++ b/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.designer.cs @@ -25,8 +25,13 @@ /// the contents of this method with the code editor. /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.SuspendLayout(); + // + // FilteredPropertyGrid + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + } #endregion diff --git a/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.resx b/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/FilteredPropertyGrid/FilteredPropertyGrid.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/HeadlessTabControl.cs b/mRemoteV1/UI/Controls/HeadlessTabControl.cs index dd960bec0..d9c821bae 100644 --- a/mRemoteV1/UI/Controls/HeadlessTabControl.cs +++ b/mRemoteV1/UI/Controls/HeadlessTabControl.cs @@ -14,5 +14,16 @@ namespace mRemoteNG.UI.Controls else base.WndProc(ref m); } + + private void InitializeComponent() + { + this.SuspendLayout(); + // + // HeadlessTabControl + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + + } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/HeadlessTabControl.resx b/mRemoteV1/UI/Controls/HeadlessTabControl.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/HeadlessTabControl.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/IPTextBox.cs b/mRemoteV1/UI/Controls/IPTextBox.cs index 7dad5a666..7fb4063bd 100644 --- a/mRemoteV1/UI/Controls/IPTextBox.cs +++ b/mRemoteV1/UI/Controls/IPTextBox.cs @@ -101,126 +101,127 @@ namespace mRemoteNG.UI.Controls /// the contents of this method with the code editor. private void InitializeComponent() { - components = new System.ComponentModel.Container(); - panel1 = new Panel(); - label3 = new Base.NGLabel(); - label2 = new Base.NGLabel(); - Octet4 = new Base.NGTextBox(); - Octet3 = new Base.NGTextBox(); - Octet2 = new Base.NGTextBox(); - label1 = new Base.NGLabel(); - Octet1 = new Base.NGTextBox(); - toolTip1 = new System.Windows.Forms.ToolTip(components); - panel1.SuspendLayout(); - SuspendLayout(); + this.components = new System.ComponentModel.Container(); + this.panel1 = new System.Windows.Forms.Panel(); + this.Octet4 = new mRemoteNG.UI.Controls.Base.NGTextBox(); + this.Octet3 = new mRemoteNG.UI.Controls.Base.NGTextBox(); + this.Octet2 = new mRemoteNG.UI.Controls.Base.NGTextBox(); + this.Octet1 = new mRemoteNG.UI.Controls.Base.NGTextBox(); + this.label2 = new mRemoteNG.UI.Controls.Base.NGLabel(); + this.label1 = new mRemoteNG.UI.Controls.Base.NGLabel(); + this.label3 = new mRemoteNG.UI.Controls.Base.NGLabel(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.panel1.SuspendLayout(); + this.SuspendLayout(); // // panel1 // - panel1.BackColor = System.Drawing.SystemColors.Window; - panel1.Controls.Add(Octet4); - panel1.Controls.Add(Octet3); - panel1.Controls.Add(Octet2); - panel1.Controls.Add(Octet1); - panel1.Controls.Add(label2); - panel1.Controls.Add(label1); - panel1.Controls.Add(label3); - panel1.Font = new System.Drawing.Font("Segoe UI", 9F); - panel1.Location = new System.Drawing.Point(0, 0); - panel1.Name = "panel1"; - panel1.Size = new System.Drawing.Size(124, 18); - panel1.TabIndex = 0; - // - // label3 - // - label3.Location = new System.Drawing.Point(23, 1); - label3.Name = "label3"; - label3.Size = new System.Drawing.Size(8, 13); - label3.TabIndex = 6; - label3.Text = "."; - // - // label2 - // - label2.Location = new System.Drawing.Point(86, 2); - label2.Name = "label2"; - label2.Size = new System.Drawing.Size(8, 13); - label2.TabIndex = 5; - label2.Text = "."; + this.panel1.BackColor = System.Drawing.SystemColors.Window; + this.panel1.Controls.Add(this.Octet4); + this.panel1.Controls.Add(this.Octet3); + this.panel1.Controls.Add(this.Octet2); + this.panel1.Controls.Add(this.Octet1); + this.panel1.Controls.Add(this.label2); + this.panel1.Controls.Add(this.label1); + this.panel1.Controls.Add(this.label3); + this.panel1.Font = new System.Drawing.Font("Segoe UI", 9F); + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(124, 18); + this.panel1.TabIndex = 0; // // Octet4 // - Octet4.BackColor = System.Drawing.SystemColors.Menu; - Octet4.BorderStyle = System.Windows.Forms.BorderStyle.None; - Octet4.Font = new System.Drawing.Font("Segoe UI", 9F); - Octet4.Location = new System.Drawing.Point(95, 1); - Octet4.MaxLength = 3; - Octet4.Name = "Octet4"; - Octet4.Size = new System.Drawing.Size(24, 16); - Octet4.TabIndex = 4; - Octet4.TabStop = false; - Octet4.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - Octet4.Enter += new System.EventHandler(Box_Enter); - Octet4.KeyPress += new System.Windows.Forms.KeyPressEventHandler(Box4_KeyPress); + this.Octet4.BackColor = System.Drawing.SystemColors.Menu; + this.Octet4.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.Octet4.Font = new System.Drawing.Font("Segoe UI", 9F); + this.Octet4.Location = new System.Drawing.Point(95, 1); + this.Octet4.MaxLength = 3; + this.Octet4.Name = "Octet4"; + this.Octet4.Size = new System.Drawing.Size(24, 16); + this.Octet4.TabIndex = 4; + this.Octet4.TabStop = false; + this.Octet4.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Octet4.Enter += new System.EventHandler(this.Box_Enter); + this.Octet4.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Box4_KeyPress); // // Octet3 // - Octet3.BackColor = System.Drawing.SystemColors.Menu; - Octet3.BorderStyle = System.Windows.Forms.BorderStyle.None; - Octet3.Font = new System.Drawing.Font("Segoe UI", 9F); - Octet3.Location = new System.Drawing.Point(63, 1); - Octet3.MaxLength = 3; - Octet3.Name = "Octet3"; - Octet3.Size = new System.Drawing.Size(24, 16); - Octet3.TabIndex = 3; - Octet3.TabStop = false; - Octet3.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - Octet3.Enter += new System.EventHandler(Box_Enter); - Octet3.KeyPress += new System.Windows.Forms.KeyPressEventHandler(Box3_KeyPress); + this.Octet3.BackColor = System.Drawing.SystemColors.Menu; + this.Octet3.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.Octet3.Font = new System.Drawing.Font("Segoe UI", 9F); + this.Octet3.Location = new System.Drawing.Point(63, 1); + this.Octet3.MaxLength = 3; + this.Octet3.Name = "Octet3"; + this.Octet3.Size = new System.Drawing.Size(24, 16); + this.Octet3.TabIndex = 3; + this.Octet3.TabStop = false; + this.Octet3.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Octet3.Enter += new System.EventHandler(this.Box_Enter); + this.Octet3.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Box3_KeyPress); // // Octet2 // - Octet2.BackColor = System.Drawing.SystemColors.Menu; - Octet2.BorderStyle = System.Windows.Forms.BorderStyle.None; - Octet2.Font = new System.Drawing.Font("Segoe UI", 9F); - Octet2.Location = new System.Drawing.Point(32, 1); - Octet2.MaxLength = 3; - Octet2.Name = "Octet2"; - Octet2.Size = new System.Drawing.Size(24, 16); - Octet2.TabIndex = 2; - Octet2.TabStop = false; - Octet2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - Octet2.Enter += new System.EventHandler(Box_Enter); - Octet2.KeyPress += new System.Windows.Forms.KeyPressEventHandler(Box2_KeyPress); - // - // label1 - // - label1.Location = new System.Drawing.Point(55, 2); - label1.Name = "label1"; - label1.Size = new System.Drawing.Size(8, 13); - label1.TabIndex = 1; - label1.Text = "."; + this.Octet2.BackColor = System.Drawing.SystemColors.Menu; + this.Octet2.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.Octet2.Font = new System.Drawing.Font("Segoe UI", 9F); + this.Octet2.Location = new System.Drawing.Point(32, 1); + this.Octet2.MaxLength = 3; + this.Octet2.Name = "Octet2"; + this.Octet2.Size = new System.Drawing.Size(24, 16); + this.Octet2.TabIndex = 2; + this.Octet2.TabStop = false; + this.Octet2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Octet2.Enter += new System.EventHandler(this.Box_Enter); + this.Octet2.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Box2_KeyPress); // // Octet1 // - Octet1.BackColor = System.Drawing.SystemColors.Menu; - Octet1.BorderStyle = System.Windows.Forms.BorderStyle.None; - Octet1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - Octet1.Location = new System.Drawing.Point(1, 1); - Octet1.MaxLength = 3; - Octet1.Name = "Octet1"; - Octet1.Size = new System.Drawing.Size(24, 16); - Octet1.TabIndex = 1; - Octet1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - Octet1.Enter += new System.EventHandler(Box_Enter); - Octet1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(Box1_KeyPress); + this.Octet1.BackColor = System.Drawing.SystemColors.Menu; + this.Octet1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.Octet1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Octet1.Location = new System.Drawing.Point(1, 1); + this.Octet1.MaxLength = 3; + this.Octet1.Name = "Octet1"; + this.Octet1.Size = new System.Drawing.Size(24, 16); + this.Octet1.TabIndex = 1; + this.Octet1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Octet1.Enter += new System.EventHandler(this.Box_Enter); + this.Octet1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Box1_KeyPress); + // + // label2 + // + this.label2.Location = new System.Drawing.Point(86, 2); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(8, 13); + this.label2.TabIndex = 5; + this.label2.Text = "."; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(55, 2); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(8, 13); + this.label1.TabIndex = 1; + this.label1.Text = "."; + // + // label3 + // + this.label3.Location = new System.Drawing.Point(23, 1); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(8, 13); + this.label3.TabIndex = 6; + this.label3.Text = "."; // // IPTextBox // - Controls.Add(panel1); - Name = "IPTextBox"; - Size = new System.Drawing.Size(124, 18); - panel1.ResumeLayout(false); - panel1.PerformLayout(); - ResumeLayout(false); + this.Controls.Add(this.panel1); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Name = "IPTextBox"; + this.Size = new System.Drawing.Size(124, 18); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ResumeLayout(false); } #endregion diff --git a/mRemoteV1/UI/Controls/MultiSshToolStrip.cs b/mRemoteV1/UI/Controls/MultiSshToolStrip.cs index 2e0de653c..4771d1e42 100644 --- a/mRemoteV1/UI/Controls/MultiSshToolStrip.cs +++ b/mRemoteV1/UI/Controls/MultiSshToolStrip.cs @@ -10,14 +10,13 @@ namespace mRemoteNG.UI.Controls private IContainer components; private ToolStripLabel _lblMultiSsh; private ToolStripTextBox _txtMultiSsh; - private MultiSSHController _multiSshController; - private readonly DisplayProperties _display; - private ThemeManager _themeManager; + // ReSharper disable once NotAccessedField.Local + private MultiSSHController _multiSshController; + private readonly ThemeManager _themeManager; public MultiSshToolStrip() { - _display = new DisplayProperties(); InitializeComponent(); _themeManager = ThemeManager.getInstance(); _themeManager.ThemeChanged += ApplyTheme; @@ -41,7 +40,7 @@ namespace mRemoteNG.UI.Controls // txtMultiSSH // _txtMultiSsh.Name = "_txtMultiSsh"; - _txtMultiSsh.Size = new System.Drawing.Size(_display.ScaleWidth(300), 25); + _txtMultiSsh.Size = new System.Drawing.Size(new DisplayProperties().ScaleWidth(300), 25); _txtMultiSsh.ToolTipText = "Press ENTER to send. Ctrl+C is sent immediately."; Items.AddRange(new ToolStripItem[] { diff --git a/mRemoteV1/UI/Controls/NewPasswordWithVerification.Designer.cs b/mRemoteV1/UI/Controls/NewPasswordWithVerification.Designer.cs index 58378b863..236631756 100644 --- a/mRemoteV1/UI/Controls/NewPasswordWithVerification.Designer.cs +++ b/mRemoteV1/UI/Controls/NewPasswordWithVerification.Designer.cs @@ -28,9 +28,9 @@ /// private void InitializeComponent() { - this.labelFirstPasswordBox = new Controls.Base.NGLabel(); - this.labelSecondPasswordBox = new Controls.Base.NGLabel(); - this.labelPasswordsDontMatch = new Controls.Base.NGLabel(); + this.labelFirstPasswordBox = new mRemoteNG.UI.Controls.Base.NGLabel(); + this.labelSecondPasswordBox = new mRemoteNG.UI.Controls.Base.NGLabel(); + this.labelPasswordsDontMatch = new mRemoteNG.UI.Controls.Base.NGLabel(); this.imgError = new System.Windows.Forms.PictureBox(); this.secureTextBox2 = new mRemoteNG.UI.Controls.SecureTextBox(); this.secureTextBox1 = new mRemoteNG.UI.Controls.SecureTextBox(); @@ -42,7 +42,7 @@ this.labelFirstPasswordBox.AutoSize = true; this.labelFirstPasswordBox.Location = new System.Drawing.Point(-3, 0); this.labelFirstPasswordBox.Name = "labelFirstPasswordBox"; - this.labelFirstPasswordBox.Size = new System.Drawing.Size(78, 13); + this.labelFirstPasswordBox.Size = new System.Drawing.Size(82, 13); this.labelFirstPasswordBox.TabIndex = 2; this.labelFirstPasswordBox.Text = "New Password"; // @@ -51,7 +51,7 @@ this.labelSecondPasswordBox.AutoSize = true; this.labelSecondPasswordBox.Location = new System.Drawing.Point(-3, 42); this.labelSecondPasswordBox.Name = "labelSecondPasswordBox"; - this.labelSecondPasswordBox.Size = new System.Drawing.Size(79, 13); + this.labelSecondPasswordBox.Size = new System.Drawing.Size(84, 13); this.labelSecondPasswordBox.TabIndex = 3; this.labelSecondPasswordBox.Text = "VerifyPassword"; // @@ -60,7 +60,7 @@ this.labelPasswordsDontMatch.AutoSize = true; this.labelPasswordsDontMatch.Location = new System.Drawing.Point(23, 83); this.labelPasswordsDontMatch.Name = "labelPasswordsDontMatch"; - this.labelPasswordsDontMatch.Size = new System.Drawing.Size(123, 13); + this.labelPasswordsDontMatch.Size = new System.Drawing.Size(133, 13); this.labelPasswordsDontMatch.TabIndex = 4; this.labelPasswordsDontMatch.Text = "Passwords do not match"; this.labelPasswordsDontMatch.Visible = false; @@ -81,7 +81,7 @@ | System.Windows.Forms.AnchorStyles.Right))); this.secureTextBox2.Location = new System.Drawing.Point(0, 58); this.secureTextBox2.Name = "secureTextBox2"; - this.secureTextBox2.Size = new System.Drawing.Size(193, 20); + this.secureTextBox2.Size = new System.Drawing.Size(193, 22); this.secureTextBox2.TabIndex = 1; // // secureTextBox1 @@ -90,19 +90,20 @@ | System.Windows.Forms.AnchorStyles.Right))); this.secureTextBox1.Location = new System.Drawing.Point(0, 16); this.secureTextBox1.Name = "secureTextBox1"; - this.secureTextBox1.Size = new System.Drawing.Size(193, 20); + this.secureTextBox1.Size = new System.Drawing.Size(193, 22); this.secureTextBox1.TabIndex = 0; // // NewPasswordWithVerification // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.Controls.Add(this.imgError); this.Controls.Add(this.labelPasswordsDontMatch); this.Controls.Add(this.labelSecondPasswordBox); this.Controls.Add(this.labelFirstPasswordBox); this.Controls.Add(this.secureTextBox2); this.Controls.Add(this.secureTextBox1); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.MinimumSize = new System.Drawing.Size(0, 100); this.Name = "NewPasswordWithVerification"; this.Size = new System.Drawing.Size(193, 100); diff --git a/mRemoteV1/UI/Controls/PageSequence/PageSequence.cs b/mRemoteV1/UI/Controls/PageSequence/PageSequence.cs index dca897c0f..2384518ec 100644 --- a/mRemoteV1/UI/Controls/PageSequence/PageSequence.cs +++ b/mRemoteV1/UI/Controls/PageSequence/PageSequence.cs @@ -19,12 +19,10 @@ namespace mRemoteNG.UI.Controls.PageSequence public PageSequence(Control pageContainer, params SequencedControl[] pages) { - if (pageContainer == null) - throw new ArgumentNullException(nameof(pageContainer)); if (pages == null) throw new ArgumentNullException(nameof(pages)); - _pageContainer = pageContainer; + _pageContainer = pageContainer ?? throw new ArgumentNullException(nameof(pageContainer)); foreach (var page in pages) { SubscribeToPageEvents(page); diff --git a/mRemoteV1/UI/Controls/PageSequence/SequencedControl.cs b/mRemoteV1/UI/Controls/PageSequence/SequencedControl.cs index 8a9111d0e..f503f997d 100644 --- a/mRemoteV1/UI/Controls/PageSequence/SequencedControl.cs +++ b/mRemoteV1/UI/Controls/PageSequence/SequencedControl.cs @@ -12,6 +12,7 @@ namespace mRemoteNG.UI.Controls.PageSequence public SequencedControl() { Themes.ThemeManager.getInstance().ThemeChanged += ApplyTheme; + InitializeComponent(); } protected virtual void RaiseNextPageEvent() @@ -35,5 +36,17 @@ namespace mRemoteNG.UI.Controls.PageSequence { PageReplacementRequested?.Invoke(this, new SequencedPageReplcementRequestArgs(control, pagetoReplace)); } + + private void InitializeComponent() + { + this.SuspendLayout(); + // + // SequencedControl + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Name = "SequencedControl"; + this.ResumeLayout(false); + + } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/Input/InputBox.resx b/mRemoteV1/UI/Controls/PageSequence/SequencedControl.resx similarity index 100% rename from mRemoteV1/UI/Forms/Input/InputBox.resx rename to mRemoteV1/UI/Controls/PageSequence/SequencedControl.resx diff --git a/mRemoteV1/UI/Controls/PageSequence/SequencedPageReplcementRequestArgs.cs b/mRemoteV1/UI/Controls/PageSequence/SequencedPageReplcementRequestArgs.cs index 5c5d4327f..4cd851089 100644 --- a/mRemoteV1/UI/Controls/PageSequence/SequencedPageReplcementRequestArgs.cs +++ b/mRemoteV1/UI/Controls/PageSequence/SequencedPageReplcementRequestArgs.cs @@ -18,9 +18,7 @@ namespace mRemoteNG.UI.Controls.PageSequence public SequencedPageReplcementRequestArgs(SequencedControl newControl, RelativePagePosition pageToReplace) { - if (newControl == null) - throw new ArgumentNullException(nameof(newControl)); - NewControl = newControl; + NewControl = newControl ?? throw new ArgumentNullException(nameof(newControl)); PagePosition = pageToReplace; } } diff --git a/mRemoteV1/UI/Controls/QuickConnectToolStrip.resx b/mRemoteV1/UI/Controls/QuickConnectToolStrip.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/QuickConnectToolStrip.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/SecureTextBox.Designer.cs b/mRemoteV1/UI/Controls/SecureTextBox.Designer.cs index c0e72fce8..5e7f73fa2 100644 --- a/mRemoteV1/UI/Controls/SecureTextBox.Designer.cs +++ b/mRemoteV1/UI/Controls/SecureTextBox.Designer.cs @@ -36,7 +36,13 @@ /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); + this.SuspendLayout(); + // + // SecureTextBox + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + } #endregion diff --git a/mRemoteV1/UI/Controls/SecureTextBox.resx b/mRemoteV1/UI/Controls/SecureTextBox.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/Controls/SecureTextBox.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/StatusImageList.cs b/mRemoteV1/UI/Controls/StatusImageList.cs index 4c20e8700..6211d581b 100644 --- a/mRemoteV1/UI/Controls/StatusImageList.cs +++ b/mRemoteV1/UI/Controls/StatusImageList.cs @@ -69,24 +69,21 @@ namespace mRemoteNG.UI.Controls var connected = connection.OpenConnections.Count > 0; var name = BuildConnectionIconName(connection.Icon, connected); - if (!ImageList.Images.ContainsKey(name)) + if (ImageList.Images.ContainsKey(name)) return name; + var image = ConnectionIcon.FromString(connection.Icon); + if (image == null) { - var image = ConnectionIcon.FromString(connection.Icon); - if (image == null) - { - return DefaultConnectionIcon; - } - - ImageList.Images.Add(BuildConnectionIconName(connection.Icon, false), image); - ImageList.Images.Add(BuildConnectionIconName(connection.Icon, true), Overlay(image, Resources.ConnectedOverlay)); - + return DefaultConnectionIcon; } + + ImageList.Images.Add(BuildConnectionIconName(connection.Icon, false), image); + ImageList.Images.Add(BuildConnectionIconName(connection.Icon, true), Overlay(image, Resources.ConnectedOverlay)); return name; } private static Bitmap Overlay(Icon background, Image foreground) { - var result = background.ToBitmap(); + var result = new Bitmap(background.ToBitmap(), new Size(16, 16)); using (var gr = Graphics.FromImage(result)) { gr.DrawImage(foreground, new Rectangle(0, 0, foreground.Width, foreground.Height)); @@ -110,7 +107,16 @@ namespace mRemoteNG.UI.Controls public void Dispose() { - ImageList?.Dispose(); + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + ImageList?.Dispose(); + } } } } \ No newline at end of file diff --git a/mRemoteV1/UI/DisplayProperties.cs b/mRemoteV1/UI/DisplayProperties.cs index 18cff4be2..dae5ee068 100644 --- a/mRemoteV1/UI/DisplayProperties.cs +++ b/mRemoteV1/UI/DisplayProperties.cs @@ -2,16 +2,35 @@ using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; -using System.Windows.Forms; +using mRemoteNG.Tools; +using mRemoteNG.UI.GraphicsUtilities; namespace mRemoteNG.UI { public class DisplayProperties { - // Dpi of a 'normal' definition screen - private const int BaselineDpi = 96; + private readonly IGraphicsProvider _graphicsProvider; - public SizeF ResolutionScalingFactor { get; } = GetResolutionScalingFactor(); + public SizeF ResolutionScalingFactor => _graphicsProvider.GetResolutionScalingFactor(); + + /// + /// Creates a new instance with the default + /// of type + /// + public DisplayProperties() + : this(new GdiPlusGraphicsProvider()) + { + } + + /// + /// Creates a new instance with the given + /// . + /// + /// + public DisplayProperties(IGraphicsProvider graphicsProvider) + { + _graphicsProvider = graphicsProvider.ThrowIfNull(nameof(graphicsProvider)); + } /// /// Scale the given nominal width value by the @@ -28,7 +47,7 @@ namespace mRemoteNG.UI /// public int ScaleHeight(float height) { - return CalculateScaledValue(height, ResolutionScalingFactor.Width); + return CalculateScaledValue(height, ResolutionScalingFactor.Height); } /// @@ -52,6 +71,9 @@ namespace mRemoteNG.UI /// public Bitmap ScaleImage(Image image) { + if (image == null) + throw new ArgumentNullException(nameof(image)); + var width = ScaleWidth(image.Width); var height = ScaleHeight(image.Height); var destRect = new Rectangle(0, 0, width, height); @@ -79,6 +101,9 @@ namespace mRemoteNG.UI public Bitmap ScaleImage(Icon icon) { + if (icon == null) + throw new ArgumentNullException(nameof(icon)); + return ScaleImage(icon.ToBitmap()); } @@ -90,13 +115,5 @@ namespace mRemoteNG.UI { return (int)Math.Round(value * scalingValue); } - - private static SizeF GetResolutionScalingFactor() - { - using (var g = new Form().CreateGraphics()) - { - return new SizeF(g.DpiX/BaselineDpi, g.DpiY / BaselineDpi); - } - } } } diff --git a/mRemoteV1/UI/Forms/ExportForm.Designer.cs b/mRemoteV1/UI/Forms/ExportForm.Designer.cs index 6e048a1bc..d70ac834e 100644 --- a/mRemoteV1/UI/Forms/ExportForm.Designer.cs +++ b/mRemoteV1/UI/Forms/ExportForm.Designer.cs @@ -63,7 +63,7 @@ namespace mRemoteNG.UI.Forms this.lblUncheckProperties.AutoSize = true; this.lblUncheckProperties.Location = new System.Drawing.Point(12, 134); this.lblUncheckProperties.Name = "lblUncheckProperties"; - this.lblUncheckProperties.Size = new System.Drawing.Size(244, 13); + this.lblUncheckProperties.Size = new System.Drawing.Size(264, 13); this.lblUncheckProperties.TabIndex = 4; this.lblUncheckProperties.Text = "Uncheck the properties you want not to be saved!"; // @@ -75,7 +75,7 @@ namespace mRemoteNG.UI.Forms this.chkUsername.CheckState = System.Windows.Forms.CheckState.Checked; this.chkUsername.Location = new System.Drawing.Point(15, 32); this.chkUsername.Name = "chkUsername"; - this.chkUsername.Size = new System.Drawing.Size(74, 17); + this.chkUsername.Size = new System.Drawing.Size(77, 17); this.chkUsername.TabIndex = 0; this.chkUsername.Text = "Username"; this.chkUsername.UseVisualStyleBackColor = true; @@ -88,7 +88,7 @@ namespace mRemoteNG.UI.Forms this.chkPassword.CheckState = System.Windows.Forms.CheckState.Checked; this.chkPassword.Location = new System.Drawing.Point(15, 55); this.chkPassword.Name = "chkPassword"; - this.chkPassword.Size = new System.Drawing.Size(72, 17); + this.chkPassword.Size = new System.Drawing.Size(75, 17); this.chkPassword.TabIndex = 1; this.chkPassword.Text = "Password"; this.chkPassword.UseVisualStyleBackColor = true; @@ -101,7 +101,7 @@ namespace mRemoteNG.UI.Forms this.chkDomain.CheckState = System.Windows.Forms.CheckState.Checked; this.chkDomain.Location = new System.Drawing.Point(15, 78); this.chkDomain.Name = "chkDomain"; - this.chkDomain.Size = new System.Drawing.Size(62, 17); + this.chkDomain.Size = new System.Drawing.Size(66, 17); this.chkDomain.TabIndex = 2; this.chkDomain.Text = "Domain"; this.chkDomain.UseVisualStyleBackColor = true; @@ -114,7 +114,7 @@ namespace mRemoteNG.UI.Forms this.chkInheritance.CheckState = System.Windows.Forms.CheckState.Checked; this.chkInheritance.Location = new System.Drawing.Point(15, 101); this.chkInheritance.Name = "chkInheritance"; - this.chkInheritance.Size = new System.Drawing.Size(79, 17); + this.chkInheritance.Size = new System.Drawing.Size(84, 17); this.chkInheritance.TabIndex = 3; this.chkInheritance.Text = "Inheritance"; this.chkInheritance.UseVisualStyleBackColor = true; @@ -124,7 +124,7 @@ namespace mRemoteNG.UI.Forms this.txtFileName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.txtFileName.Location = new System.Drawing.Point(15, 47); this.txtFileName.Name = "txtFileName"; - this.txtFileName.Size = new System.Drawing.Size(396, 20); + this.txtFileName.Size = new System.Drawing.Size(396, 22); this.txtFileName.TabIndex = 1; this.txtFileName.TextChanged += new System.EventHandler(this.txtFileName_TextChanged); // @@ -162,7 +162,7 @@ namespace mRemoteNG.UI.Forms this.chkAssignedCredential.CheckState = System.Windows.Forms.CheckState.Checked; this.chkAssignedCredential.Location = new System.Drawing.Point(143, 32); this.chkAssignedCredential.Name = "chkAssignedCredential"; - this.chkAssignedCredential.Size = new System.Drawing.Size(119, 17); + this.chkAssignedCredential.Size = new System.Drawing.Size(129, 17); this.chkAssignedCredential.TabIndex = 5; this.chkAssignedCredential.Text = "Assigned Credential"; this.chkAssignedCredential.UseVisualStyleBackColor = true; @@ -187,7 +187,7 @@ namespace mRemoteNG.UI.Forms this.lblFileFormat.AutoSize = true; this.lblFileFormat.Location = new System.Drawing.Point(12, 80); this.lblFileFormat.Name = "lblFileFormat"; - this.lblFileFormat.Size = new System.Drawing.Size(61, 13); + this.lblFileFormat.Size = new System.Drawing.Size(67, 13); this.lblFileFormat.TabIndex = 3; this.lblFileFormat.Text = "File &Format:"; // @@ -196,7 +196,7 @@ namespace mRemoteNG.UI.Forms this.lblFileName.AutoSize = true; this.lblFileName.Location = new System.Drawing.Point(12, 28); this.lblFileName.Name = "lblFileName"; - this.lblFileName.Size = new System.Drawing.Size(52, 13); + this.lblFileName.Size = new System.Drawing.Size(56, 13); this.lblFileName.TabIndex = 0; this.lblFileName.Text = "Filename:"; // @@ -230,7 +230,7 @@ namespace mRemoteNG.UI.Forms this.lblSelectedConnection.AutoSize = true; this.lblSelectedConnection.Location = new System.Drawing.Point(48, 111); this.lblSelectedConnection.Name = "lblSelectedConnection"; - this.lblSelectedConnection.Size = new System.Drawing.Size(92, 13); + this.lblSelectedConnection.Size = new System.Drawing.Size(99, 13); this.lblSelectedConnection.TabIndex = 4; this.lblSelectedConnection.Text = "Connection Name"; // @@ -239,7 +239,7 @@ namespace mRemoteNG.UI.Forms this.lblSelectedFolder.AutoSize = true; this.lblSelectedFolder.Location = new System.Drawing.Point(48, 75); this.lblSelectedFolder.Name = "lblSelectedFolder"; - this.lblSelectedFolder.Size = new System.Drawing.Size(67, 13); + this.lblSelectedFolder.Size = new System.Drawing.Size(72, 13); this.lblSelectedFolder.TabIndex = 3; this.lblSelectedFolder.Text = "Folder Name"; // @@ -249,7 +249,7 @@ namespace mRemoteNG.UI.Forms this.rdoExportSelectedConnection.BackColor = System.Drawing.Color.Transparent; this.rdoExportSelectedConnection.Location = new System.Drawing.Point(15, 91); this.rdoExportSelectedConnection.Name = "rdoExportSelectedConnection"; - this.rdoExportSelectedConnection.Size = new System.Drawing.Size(215, 17); + this.rdoExportSelectedConnection.Size = new System.Drawing.Size(232, 17); this.rdoExportSelectedConnection.TabIndex = 2; this.rdoExportSelectedConnection.TabStop = true; this.rdoExportSelectedConnection.Text = "Export the currently selected connection"; @@ -261,7 +261,7 @@ namespace mRemoteNG.UI.Forms this.rdoExportSelectedFolder.BackColor = System.Drawing.Color.Transparent; this.rdoExportSelectedFolder.Location = new System.Drawing.Point(15, 55); this.rdoExportSelectedFolder.Name = "rdoExportSelectedFolder"; - this.rdoExportSelectedFolder.Size = new System.Drawing.Size(188, 17); + this.rdoExportSelectedFolder.Size = new System.Drawing.Size(205, 17); this.rdoExportSelectedFolder.TabIndex = 1; this.rdoExportSelectedFolder.TabStop = true; this.rdoExportSelectedFolder.Text = "Export the currently selected folder"; @@ -274,7 +274,7 @@ namespace mRemoteNG.UI.Forms this.rdoExportEverything.Checked = true; this.rdoExportEverything.Location = new System.Drawing.Point(15, 32); this.rdoExportEverything.Name = "rdoExportEverything"; - this.rdoExportEverything.Size = new System.Drawing.Size(107, 17); + this.rdoExportEverything.Size = new System.Drawing.Size(115, 17); this.rdoExportEverything.TabIndex = 0; this.rdoExportEverything.TabStop = true; this.rdoExportEverything.Text = "Export everything"; @@ -292,8 +292,9 @@ namespace mRemoteNG.UI.Forms this.Controls.Add(this.grpProperties); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnOK); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Icon = global::mRemoteNG.Resources.Connections_SaveAs_Icon; + this.Icon = global::mRemoteNG.Resources.ConnectionsSaveAs_Icon; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ExportForm"; diff --git a/mRemoteV1/UI/Forms/ExportForm.cs b/mRemoteV1/UI/Forms/ExportForm.cs index 7daedde4a..d4396d8cf 100644 --- a/mRemoteV1/UI/Forms/ExportForm.cs +++ b/mRemoteV1/UI/Forms/ExportForm.cs @@ -16,15 +16,9 @@ namespace mRemoteNG.UI.Forms #region Public Properties public string FileName { - get - { - return txtFileName.Text; - } - set - { - txtFileName.Text = value; - } - } + get => txtFileName.Text; + set => txtFileName.Text = value; + } public SaveFormat SaveFormat { @@ -75,11 +69,8 @@ namespace mRemoteNG.UI.Forms private ContainerInfo _selectedFolder; public ContainerInfo SelectedFolder { - get - { - return _selectedFolder; - } - set + get => _selectedFolder; + set { _selectedFolder = value; lblSelectedFolder.Text = value?.Name; @@ -90,11 +81,8 @@ namespace mRemoteNG.UI.Forms private ConnectionInfo _selectedConnection; public ConnectionInfo SelectedConnection { - get - { - return _selectedConnection; - } - set + get => _selectedConnection; + set { _selectedConnection = value; lblSelectedConnection.Text = value?.Name; @@ -104,57 +92,33 @@ namespace mRemoteNG.UI.Forms public bool IncludeUsername { - get - { - return chkUsername.Checked; - } - set - { - chkUsername.Checked = value; - } - } + get => chkUsername.Checked; + set => chkUsername.Checked = value; + } public bool IncludePassword { - get - { - return chkPassword.Checked; - } - set - { - chkPassword.Checked = value; - } - } + get => chkPassword.Checked; + set => chkPassword.Checked = value; + } public bool IncludeDomain { - get - { - return chkDomain.Checked; - } - set - { - chkDomain.Checked = value; - } - } + get => chkDomain.Checked; + set => chkDomain.Checked = value; + } public bool IncludeAssignedCredential { - get { return chkAssignedCredential.Checked; } - set { chkAssignedCredential.Checked = value; } + get => chkAssignedCredential.Checked; + set => chkAssignedCredential.Checked = value; } public bool IncludeInheritance { - get - { - return chkInheritance.Checked; - } - set - { - chkInheritance.Checked = value; - } - } + get => chkInheritance.Checked; + set => chkInheritance.Checked = value; + } #endregion #region Constructors @@ -247,11 +211,9 @@ namespace mRemoteNG.UI.Forms private void ApplyTheme() { _themeManager = ThemeManager.getInstance(); - if(_themeManager.ThemingActive) - { - BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); - ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); - } + if (!_themeManager.ThemingActive) return; + BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); + ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); } diff --git a/mRemoteV1/UI/Forms/FrmSplashScreen.Designer.cs b/mRemoteV1/UI/Forms/FrmSplashScreen.Designer.cs new file mode 100644 index 000000000..53864ab58 --- /dev/null +++ b/mRemoteV1/UI/Forms/FrmSplashScreen.Designer.cs @@ -0,0 +1,60 @@ +namespace mRemoteNG.UI.Forms +{ + partial class FrmSplashScreen + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // FrmSplashScreen + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BackgroundImage = global::mRemoteNG.Resources.Header_dark; + this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.ClientSize = new System.Drawing.Size(450, 120); + this.ControlBox = false; + this.DoubleBuffered = true; + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Margin = new System.Windows.Forms.Padding(2); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(180, 60); + this.Name = "FrmSplashScreen"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "frmSplashScreen"; + this.TopMost = true; + this.ResumeLayout(false); + + } + + #endregion + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/FrmSplashScreen.cs b/mRemoteV1/UI/Forms/FrmSplashScreen.cs new file mode 100644 index 000000000..bf28eaca3 --- /dev/null +++ b/mRemoteV1/UI/Forms/FrmSplashScreen.cs @@ -0,0 +1,29 @@ +using System.Windows.Forms; + +namespace mRemoteNG.UI.Forms +{ + public partial class FrmSplashScreen : Form + { + static FrmSplashScreen instance = null; + + private FrmSplashScreen() => InitializeComponent(); + + public static FrmSplashScreen getInstance() + { + if (instance == null) + instance = new FrmSplashScreen(); + return instance; + } + + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + // turn on WS_EX_TOOLWINDOW style bit + cp.ExStyle |= 0x80; + return cp; + } + } + } +} diff --git a/mRemoteV1/UI/Forms/FrmSplashScreen.resx b/mRemoteV1/UI/Forms/FrmSplashScreen.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/mRemoteV1/UI/Forms/FrmSplashScreen.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/FullscreenHandler.cs b/mRemoteV1/UI/Forms/FullscreenHandler.cs index e85fd1555..b601a8e27 100644 --- a/mRemoteV1/UI/Forms/FullscreenHandler.cs +++ b/mRemoteV1/UI/Forms/FullscreenHandler.cs @@ -13,10 +13,7 @@ namespace mRemoteNG.UI.Forms public bool Value { - get - { - return _value; - } + get => _value; set { if (_value == value) return; diff --git a/mRemoteV1/UI/Forms/Input/InputBox.Designer.cs b/mRemoteV1/UI/Forms/Input/FrmInputBox.Designer.cs similarity index 83% rename from mRemoteV1/UI/Forms/Input/InputBox.Designer.cs rename to mRemoteV1/UI/Forms/Input/FrmInputBox.Designer.cs index e5704adb4..daf744f81 100644 --- a/mRemoteV1/UI/Forms/Input/InputBox.Designer.cs +++ b/mRemoteV1/UI/Forms/Input/FrmInputBox.Designer.cs @@ -1,6 +1,6 @@ namespace mRemoteNG.UI.Forms.Input { - partial class InputBox + partial class FrmInputBox { /// /// Required designer variable. @@ -50,9 +50,9 @@ this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.RowCount = 3; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); this.tableLayoutPanel1.Size = new System.Drawing.Size(284, 81); this.tableLayoutPanel1.TabIndex = 0; // @@ -66,6 +66,7 @@ this.buttonOk.TabIndex = 0; this.buttonOk.Text = "Ok"; this.buttonOk.UseVisualStyleBackColor = true; + this.buttonOk.Click += new System.EventHandler(this.buttonOk_Click); // // buttonCancel // @@ -78,42 +79,42 @@ this.buttonCancel.TabIndex = 1; this.buttonCancel.Text = "Cancel"; this.buttonCancel.UseVisualStyleBackColor = true; + this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); // // textBox // this.tableLayoutPanel1.SetColumnSpan(this.textBox, 3); this.textBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.textBox.Location = new System.Drawing.Point(10, 26); - this.textBox.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.textBox.Location = new System.Drawing.Point(3, 27); this.textBox.Name = "textBox"; - this.textBox.Size = new System.Drawing.Size(264, 20); + this.textBox.Size = new System.Drawing.Size(278, 22); this.textBox.TabIndex = 2; // // label // this.label.AutoSize = true; this.tableLayoutPanel1.SetColumnSpan(this.label, 3); - this.label.Dock = System.Windows.Forms.DockStyle.Left; - this.label.Location = new System.Drawing.Point(10, 10); - this.label.Margin = new System.Windows.Forms.Padding(10, 10, 3, 0); + this.label.Dock = System.Windows.Forms.DockStyle.Fill; + this.label.Location = new System.Drawing.Point(3, 0); this.label.Name = "label"; - this.label.Size = new System.Drawing.Size(33, 13); + this.label.Size = new System.Drawing.Size(278, 24); this.label.TabIndex = 3; this.label.Text = "Label"; + this.label.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // - // InputBox + // FrmInputBox // - this.AcceptButton = this.buttonOk; this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.CancelButton = this.buttonCancel; this.ClientSize = new System.Drawing.Size(284, 81); this.ControlBox = false; this.Controls.Add(this.tableLayoutPanel1); this.DoubleBuffered = true; + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; - this.Name = "InputBox"; + this.Name = "FrmInputBox"; this.ShowIcon = false; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; diff --git a/mRemoteV1/UI/Forms/Input/InputBox.cs b/mRemoteV1/UI/Forms/Input/FrmInputBox.cs similarity index 63% rename from mRemoteV1/UI/Forms/Input/InputBox.cs rename to mRemoteV1/UI/Forms/Input/FrmInputBox.cs index 9cffd3488..a0f1c6c63 100644 --- a/mRemoteV1/UI/Forms/Input/InputBox.cs +++ b/mRemoteV1/UI/Forms/Input/FrmInputBox.cs @@ -3,13 +3,18 @@ using mRemoteNG.Themes; namespace mRemoteNG.UI.Forms.Input { - public partial class InputBox : Form + public partial class FrmInputBox : Form { private readonly DisplayProperties _display = new DisplayProperties(); + internal string returnValue; - public InputBox() + public FrmInputBox(string title, string promptText, ref string value) { InitializeComponent(); + + Text = title; + label.Text = promptText; + textBox.Text = value; ApplyLanguage(); ApplyTheme(); } @@ -27,14 +32,17 @@ namespace mRemoteNG.UI.Forms.Input ForeColor = activeTheme.ExtendedPalette.getColor("Dialog_Foreground"); } - public DialogResult ShowAsDialog(string title, string promptText, ref string value) + private void buttonOk_Click(object sender, System.EventArgs e) { - Text = title; - label.Text = promptText; - textBox.Text = value; - var dialogResult = ShowDialog(); - value = textBox.Text; - return dialogResult; + DialogResult = DialogResult.OK; + returnValue = textBox.Text; + Close(); + } + + private void buttonCancel_Click(object sender, System.EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); } } } diff --git a/mRemoteV1/UI/Forms/Input/FrmInputBox.resx b/mRemoteV1/UI/Forms/Input/FrmInputBox.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/mRemoteV1/UI/Forms/Input/FrmInputBox.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.Designer.cs b/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.Designer.cs index 4a6a50180..9078921ec 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.Designer.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.Designer.cs @@ -30,7 +30,6 @@ namespace mRemoteNG.UI.Forms.OptionsPages [System.Diagnostics.DebuggerStepThrough()] private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AdvancedPage)); this.chkAutomaticallyGetSessionInfo = new mRemoteNG.UI.Controls.Base.NGCheckBox(); this.lblMaximumPuttyWaitTime = new mRemoteNG.UI.Controls.Base.NGLabel(); this.chkAutomaticReconnect = new mRemoteNG.UI.Controls.Base.NGCheckBox(); @@ -52,9 +51,10 @@ namespace mRemoteNG.UI.Forms.OptionsPages // this.chkAutomaticallyGetSessionInfo._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER; this.chkAutomaticallyGetSessionInfo.AutoSize = true; + this.chkAutomaticallyGetSessionInfo.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.chkAutomaticallyGetSessionInfo.Location = new System.Drawing.Point(3, 3); this.chkAutomaticallyGetSessionInfo.Name = "chkAutomaticallyGetSessionInfo"; - this.chkAutomaticallyGetSessionInfo.Size = new System.Drawing.Size(198, 17); + this.chkAutomaticallyGetSessionInfo.Size = new System.Drawing.Size(220, 17); this.chkAutomaticallyGetSessionInfo.TabIndex = 0; this.chkAutomaticallyGetSessionInfo.Text = "Automatically get session information"; this.chkAutomaticallyGetSessionInfo.UseVisualStyleBackColor = true; @@ -72,9 +72,10 @@ namespace mRemoteNG.UI.Forms.OptionsPages // this.chkAutomaticReconnect._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER; this.chkAutomaticReconnect.AutoSize = true; + this.chkAutomaticReconnect.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.chkAutomaticReconnect.Location = new System.Drawing.Point(3, 26); this.chkAutomaticReconnect.Name = "chkAutomaticReconnect"; - this.chkAutomaticReconnect.Size = new System.Drawing.Size(399, 17); + this.chkAutomaticReconnect.Size = new System.Drawing.Size(430, 17); this.chkAutomaticReconnect.TabIndex = 1; this.chkAutomaticReconnect.Text = "Automatically try to reconnect when disconnected from server (RDP && ICA only)"; this.chkAutomaticReconnect.UseVisualStyleBackColor = true; @@ -89,7 +90,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages 0, 0}); this.numPuttyWaitTime.Name = "numPuttyWaitTime"; - this.numPuttyWaitTime.Size = new System.Drawing.Size(49, 20); + this.numPuttyWaitTime.Size = new System.Drawing.Size(49, 22); this.numPuttyWaitTime.TabIndex = 7; this.numPuttyWaitTime.Value = new decimal(new int[] { 5, @@ -101,6 +102,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages // this.chkUseCustomPuttyPath._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER; this.chkUseCustomPuttyPath.AutoSize = true; + this.chkUseCustomPuttyPath.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.chkUseCustomPuttyPath.Location = new System.Drawing.Point(3, 72); this.chkUseCustomPuttyPath.Name = "chkUseCustomPuttyPath"; this.chkUseCustomPuttyPath.Size = new System.Drawing.Size(146, 17); @@ -128,7 +130,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages 0, 0}); this.numUVNCSCPort.Name = "numUVNCSCPort"; - this.numUVNCSCPort.Size = new System.Drawing.Size(72, 20); + this.numUVNCSCPort.Size = new System.Drawing.Size(72, 22); this.numUVNCSCPort.TabIndex = 8; this.numUVNCSCPort.Value = new decimal(new int[] { 5500, @@ -143,7 +145,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.txtCustomPuttyPath.Enabled = false; this.txtCustomPuttyPath.Location = new System.Drawing.Point(21, 95); this.txtCustomPuttyPath.Name = "txtCustomPuttyPath"; - this.txtCustomPuttyPath.Size = new System.Drawing.Size(346, 20); + this.txtCustomPuttyPath.Size = new System.Drawing.Size(346, 22); this.txtCustomPuttyPath.TabIndex = 4; this.txtCustomPuttyPath.TextChanged += new System.EventHandler(this.txtCustomPuttyPath_TextChanged); // @@ -176,7 +178,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.lblSeconds.AutoSize = true; this.lblSeconds.Location = new System.Drawing.Point(428, 175); this.lblSeconds.Name = "lblSeconds"; - this.lblSeconds.Size = new System.Drawing.Size(47, 13); + this.lblSeconds.Size = new System.Drawing.Size(49, 13); this.lblSeconds.TabIndex = 9; this.lblSeconds.Text = "seconds"; // @@ -196,17 +198,18 @@ namespace mRemoteNG.UI.Forms.OptionsPages // this.chkLoadBalanceInfoUseUtf8._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER; this.chkLoadBalanceInfoUseUtf8.AutoSize = true; + this.chkLoadBalanceInfoUseUtf8.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.chkLoadBalanceInfoUseUtf8.Location = new System.Drawing.Point(3, 49); this.chkLoadBalanceInfoUseUtf8.Name = "chkLoadBalanceInfoUseUtf8"; - this.chkLoadBalanceInfoUseUtf8.Size = new System.Drawing.Size(304, 17); + this.chkLoadBalanceInfoUseUtf8.Size = new System.Drawing.Size(317, 17); this.chkLoadBalanceInfoUseUtf8.TabIndex = 2; this.chkLoadBalanceInfoUseUtf8.Text = "Use UTF8 encoding for RDP \"Load Balance Info\" property"; this.chkLoadBalanceInfoUseUtf8.UseVisualStyleBackColor = true; // // AdvancedPage // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.Controls.Add(this.chkLoadBalanceInfoUseUtf8); this.Controls.Add(this.chkAutomaticallyGetSessionInfo); this.Controls.Add(this.lblMaximumPuttyWaitTime); @@ -220,9 +223,9 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.Controls.Add(this.lblUVNCSCPort); this.Controls.Add(this.lblSeconds); this.Controls.Add(this.btnBrowseCustomPuttyPath); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Name = "AdvancedPage"; - this.PageIcon = ((System.Drawing.Icon)(resources.GetObject("$this.PageIcon"))); - this.Size = new System.Drawing.Size(610, 489); + this.Size = new System.Drawing.Size(610, 490); ((System.ComponentModel.ISupportInitialize)(this.numPuttyWaitTime)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.numUVNCSCPort)).EndInit(); this.ResumeLayout(false); diff --git a/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.cs b/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.cs index af54298eb..466a83787 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.cs @@ -16,13 +16,13 @@ namespace mRemoteNG.UI.Forms.OptionsPages { InitializeComponent(); ApplyTheme(); + PageIcon = Resources.Config_Icon; var display = new DisplayProperties(); var img = display.ScaleImage(Resources.PuttyConfig); btnLaunchPutty.Image = img; } #region Public Methods - public override string PageName { get => Language.strTabAdvanced; diff --git a/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.resx b/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.resx index 479cdad2b..1af7de150 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.resx +++ b/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.resx @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/UnhandledExceptionWindow.Designer.cs b/mRemoteV1/UI/Forms/UnhandledExceptionWindow.Designer.cs new file mode 100644 index 000000000..ea19d834b --- /dev/null +++ b/mRemoteV1/UI/Forms/UnhandledExceptionWindow.Designer.cs @@ -0,0 +1,194 @@ +namespace mRemoteNG.UI.Forms +{ + partial class UnhandledExceptionWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.labelExceptionCaught = new System.Windows.Forms.Label(); + this.buttonClose = new System.Windows.Forms.Button(); + this.textBoxStackTrace = new System.Windows.Forms.TextBox(); + this.labelStackTraceHeader = new System.Windows.Forms.Label(); + this.labelExceptionMessageHeader = new System.Windows.Forms.Label(); + this.textBoxExceptionMessage = new System.Windows.Forms.TextBox(); + this.buttonCopyAll = new System.Windows.Forms.Button(); + this.labelExceptionIsFatalHeader = new System.Windows.Forms.Label(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 4; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30F)); + this.tableLayoutPanel1.Controls.Add(this.labelExceptionCaught, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.buttonClose, 2, 6); + this.tableLayoutPanel1.Controls.Add(this.textBoxStackTrace, 1, 5); + this.tableLayoutPanel1.Controls.Add(this.labelStackTraceHeader, 1, 4); + this.tableLayoutPanel1.Controls.Add(this.labelExceptionMessageHeader, 1, 2); + this.tableLayoutPanel1.Controls.Add(this.textBoxExceptionMessage, 1, 3); + this.tableLayoutPanel1.Controls.Add(this.buttonCopyAll, 1, 6); + this.tableLayoutPanel1.Controls.Add(this.labelExceptionIsFatalHeader, 1, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 7; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 80F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(534, 334); + this.tableLayoutPanel1.TabIndex = 0; + // + // labelExceptionCaught + // + this.labelExceptionCaught.AutoSize = true; + this.tableLayoutPanel1.SetColumnSpan(this.labelExceptionCaught, 2); + this.labelExceptionCaught.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelExceptionCaught.Location = new System.Drawing.Point(33, 0); + this.labelExceptionCaught.Name = "labelExceptionCaught"; + this.labelExceptionCaught.Size = new System.Drawing.Size(311, 20); + this.labelExceptionCaught.TabIndex = 3; + this.labelExceptionCaught.Text = "An unhandled exception has occurred"; + // + // buttonClose + // + this.buttonClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonClose.Dock = System.Windows.Forms.DockStyle.Right; + this.buttonClose.Location = new System.Drawing.Point(427, 306); + this.buttonClose.Name = "buttonClose"; + this.buttonClose.Size = new System.Drawing.Size(74, 25); + this.buttonClose.TabIndex = 1; + this.buttonClose.Text = "Close"; + this.buttonClose.UseVisualStyleBackColor = true; + this.buttonClose.Click += new System.EventHandler(this.buttonClose_Click); + // + // textBoxStackTrace + // + this.tableLayoutPanel1.SetColumnSpan(this.textBoxStackTrace, 2); + this.textBoxStackTrace.Dock = System.Windows.Forms.DockStyle.Fill; + this.textBoxStackTrace.Location = new System.Drawing.Point(33, 132); + this.textBoxStackTrace.Multiline = true; + this.textBoxStackTrace.Name = "textBoxStackTrace"; + this.textBoxStackTrace.ReadOnly = true; + this.textBoxStackTrace.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.textBoxStackTrace.Size = new System.Drawing.Size(468, 168); + this.textBoxStackTrace.TabIndex = 0; + // + // labelStackTraceHeader + // + this.labelStackTraceHeader.AutoSize = true; + this.labelStackTraceHeader.Dock = System.Windows.Forms.DockStyle.Bottom; + this.labelStackTraceHeader.Location = new System.Drawing.Point(33, 116); + this.labelStackTraceHeader.Name = "labelStackTraceHeader"; + this.labelStackTraceHeader.Size = new System.Drawing.Size(388, 13); + this.labelStackTraceHeader.TabIndex = 4; + this.labelStackTraceHeader.Text = "Stack trace"; + // + // labelExceptionMessageHeader + // + this.labelExceptionMessageHeader.AutoSize = true; + this.labelExceptionMessageHeader.Dock = System.Windows.Forms.DockStyle.Bottom; + this.labelExceptionMessageHeader.Location = new System.Drawing.Point(33, 53); + this.labelExceptionMessageHeader.Name = "labelExceptionMessageHeader"; + this.labelExceptionMessageHeader.Size = new System.Drawing.Size(388, 13); + this.labelExceptionMessageHeader.TabIndex = 5; + this.labelExceptionMessageHeader.Text = "Exception message"; + // + // textBoxExceptionMessage + // + this.tableLayoutPanel1.SetColumnSpan(this.textBoxExceptionMessage, 2); + this.textBoxExceptionMessage.Dock = System.Windows.Forms.DockStyle.Fill; + this.textBoxExceptionMessage.Location = new System.Drawing.Point(33, 69); + this.textBoxExceptionMessage.Multiline = true; + this.textBoxExceptionMessage.Name = "textBoxExceptionMessage"; + this.textBoxExceptionMessage.ReadOnly = true; + this.textBoxExceptionMessage.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.textBoxExceptionMessage.Size = new System.Drawing.Size(468, 37); + this.textBoxExceptionMessage.TabIndex = 6; + // + // buttonCopyAll + // + this.buttonCopyAll.Dock = System.Windows.Forms.DockStyle.Right; + this.buttonCopyAll.Location = new System.Drawing.Point(346, 306); + this.buttonCopyAll.Name = "buttonCopyAll"; + this.buttonCopyAll.Size = new System.Drawing.Size(75, 25); + this.buttonCopyAll.TabIndex = 7; + this.buttonCopyAll.Text = "Copy All"; + this.buttonCopyAll.UseVisualStyleBackColor = true; + this.buttonCopyAll.Click += new System.EventHandler(this.buttonCopyAll_Click); + // + // labelExceptionIsFatalHeader + // + this.labelExceptionIsFatalHeader.AutoSize = true; + this.tableLayoutPanel1.SetColumnSpan(this.labelExceptionIsFatalHeader, 2); + this.labelExceptionIsFatalHeader.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelExceptionIsFatalHeader.Location = new System.Drawing.Point(33, 30); + this.labelExceptionIsFatalHeader.Name = "labelExceptionIsFatalHeader"; + this.labelExceptionIsFatalHeader.Size = new System.Drawing.Size(281, 16); + this.labelExceptionIsFatalHeader.TabIndex = 8; + this.labelExceptionIsFatalHeader.Text = "This exception will force mRemoteNG to close"; + // + // UnhandledExceptionWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.CancelButton = this.buttonClose; + this.ClientSize = new System.Drawing.Size(534, 334); + this.ControlBox = false; + this.Controls.Add(this.tableLayoutPanel1); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.MinimumSize = new System.Drawing.Size(550, 350); + this.Name = "UnhandledExceptionWindow"; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "mRemoteNG Unhandled Exception"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.TextBox textBoxStackTrace; + private System.Windows.Forms.Button buttonClose; + private System.Windows.Forms.Label labelExceptionCaught; + private System.Windows.Forms.Label labelStackTraceHeader; + private System.Windows.Forms.Label labelExceptionMessageHeader; + private System.Windows.Forms.TextBox textBoxExceptionMessage; + private System.Windows.Forms.Button buttonCopyAll; + private System.Windows.Forms.Label labelExceptionIsFatalHeader; + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/UnhandledExceptionWindow.cs b/mRemoteV1/UI/Forms/UnhandledExceptionWindow.cs new file mode 100644 index 000000000..6147851ba --- /dev/null +++ b/mRemoteV1/UI/Forms/UnhandledExceptionWindow.cs @@ -0,0 +1,68 @@ +using System; +using System.Text; +using System.Windows.Forms; +using mRemoteNG.App; + +namespace mRemoteNG.UI.Forms +{ + public partial class UnhandledExceptionWindow : Form + { + private readonly bool _isFatal; + + public UnhandledExceptionWindow() + : this(null, false) + { + } + + public UnhandledExceptionWindow(Exception exception, bool isFatal) + { + _isFatal = isFatal; + InitializeComponent(); + SetLanguage(); + + if (exception == null) + return; + + textBoxExceptionMessage.Text = exception.Message; + textBoxStackTrace.Text = exception.StackTrace; + } + + private void SetLanguage() + { + Text = Language.mRemoteNGUnhandledException; + labelExceptionCaught.Text = Language.UnhandledExceptionOccured; + + labelExceptionIsFatalHeader.Text = _isFatal + ? Language.ExceptionForcesmRemoteNGToClose + : string.Empty; + + labelExceptionMessageHeader.Text = Language.ExceptionMessage; + labelStackTraceHeader.Text = Language.StackTrace; + buttonCopyAll.Text = Language.strMenuNotificationsCopyAll; + buttonClose.Text = _isFatal + ? Language.strMenuExit + : Language.strButtonClose; + } + + private void buttonCopyAll_Click(object sender, EventArgs e) + { + var text = new StringBuilder() + .AppendLine(labelExceptionMessageHeader.Text) + .AppendLine("\"" + textBoxExceptionMessage.Text + "\"") + .AppendLine() + .AppendLine(labelStackTraceHeader.Text) + .AppendLine(textBoxStackTrace.Text) + .ToString(); + + Clipboard.SetText(text); + } + + private void buttonClose_Click(object sender, EventArgs e) + { + if (_isFatal) + Shutdown.Quit(); + + Close(); + } + } +} diff --git a/mRemoteV1/UI/Forms/UnhandledExceptionWindow.resx b/mRemoteV1/UI/Forms/UnhandledExceptionWindow.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/mRemoteV1/UI/Forms/UnhandledExceptionWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/frmChoosePanel.Designer.cs b/mRemoteV1/UI/Forms/frmChoosePanel.Designer.cs index 66d789eaa..0665428f6 100644 --- a/mRemoteV1/UI/Forms/frmChoosePanel.Designer.cs +++ b/mRemoteV1/UI/Forms/frmChoosePanel.Designer.cs @@ -3,7 +3,7 @@ namespace mRemoteNG.UI.Forms { - public partial class frmChoosePanel : System.Windows.Forms.Form + public partial class FrmChoosePanel : System.Windows.Forms.Form { //Form overrides dispose to clean up the component list. [System.Diagnostics.DebuggerNonUserCode()]protected override void Dispose(bool disposing) @@ -50,7 +50,7 @@ namespace mRemoteNG.UI.Forms this.btnOK._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER; this.btnOK.Location = new System.Drawing.Point(167, 72); this.btnOK.Name = "btnOK"; - this.btnOK.Size = new System.Drawing.Size(69, 23); + this.btnOK.Size = new System.Drawing.Size(75, 24); this.btnOK.TabIndex = 20; this.btnOK.Text = global::mRemoteNG.Language.strButtonOK; this.btnOK.UseVisualStyleBackColor = true; @@ -70,30 +70,30 @@ namespace mRemoteNG.UI.Forms this.btnNew._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER; this.btnNew.Image = global::mRemoteNG.Resources.Panel_Add; this.btnNew.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnNew.Location = new System.Drawing.Point(101, 70); + this.btnNew.Location = new System.Drawing.Point(86, 72); this.btnNew.Name = "btnNew"; - this.btnNew.Size = new System.Drawing.Size(60, 27); + this.btnNew.Size = new System.Drawing.Size(75, 24); this.btnNew.TabIndex = 40; this.btnNew.Text = global::mRemoteNG.Language.strButtonNew; - this.btnNew.TextAlign = System.Drawing.ContentAlignment.MiddleRight; this.btnNew.UseVisualStyleBackColor = true; this.btnNew.Click += new System.EventHandler(this.btnNew_Click); // - // frmChoosePanel + // FrmChoosePanel // this.AcceptButton = this.btnOK; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.ClientSize = new System.Drawing.Size(245, 107); this.Controls.Add(this.lblDescription); this.Controls.Add(this.btnNew); this.Controls.Add(this.btnOK); this.Controls.Add(this.cbPanels); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Icon = global::mRemoteNG.Resources.Panels_Icon; this.MaximizeBox = false; this.MinimizeBox = false; - this.Name = "frmChoosePanel"; + this.Name = "FrmChoosePanel"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Select Panel"; diff --git a/mRemoteV1/UI/Forms/frmChoosePanel.cs b/mRemoteV1/UI/Forms/frmChoosePanel.cs index ddbc8ca0a..0f7f38a06 100644 --- a/mRemoteV1/UI/Forms/frmChoosePanel.cs +++ b/mRemoteV1/UI/Forms/frmChoosePanel.cs @@ -5,11 +5,11 @@ using mRemoteNG.UI.Panels; namespace mRemoteNG.UI.Forms { - public partial class frmChoosePanel + public partial class FrmChoosePanel { private readonly PanelAdder _panelAdder; - public frmChoosePanel() + public FrmChoosePanel() { InitializeComponent(); _panelAdder = new PanelAdder(); @@ -69,12 +69,15 @@ namespace mRemoteNG.UI.Forms private void btnNew_Click(object sender, System.EventArgs e) { var pnlName = Language.strNewPanel; - - if (new InputBox().ShowAsDialog(Language.strNewPanel, Language.strPanelName + ":", ref pnlName) != DialogResult.OK || string.IsNullOrEmpty(pnlName)) return; - _panelAdder.AddPanel(pnlName); - AddAvailablePanels(); - cbPanels.SelectedItem = pnlName; - cbPanels.Focus(); + using (var frmInputBox = new FrmInputBox(Language.strNewPanel, Language.strPanelName + ":", ref pnlName)) + { + var dr = frmInputBox.ShowDialog(); + if (dr != DialogResult.OK || string.IsNullOrEmpty(frmInputBox.returnValue)) return; + _panelAdder.AddPanel(frmInputBox.returnValue); + AddAvailablePanels(); + cbPanels.SelectedItem = frmInputBox.returnValue; + cbPanels.Focus(); + } } private void btnOK_Click(object sender, System.EventArgs e) diff --git a/mRemoteV1/UI/Forms/frmMain.Designer.cs b/mRemoteV1/UI/Forms/frmMain.Designer.cs index 9333e23dd..7fb17c4a0 100644 --- a/mRemoteV1/UI/Forms/frmMain.Designer.cs +++ b/mRemoteV1/UI/Forms/frmMain.Designer.cs @@ -28,6 +28,7 @@ namespace mRemoteNG.UI.Forms { this.components = new System.ComponentModel.Container(); mRemoteNG.Connection.ConnectionInitiator connectionInitiator1 = new mRemoteNG.Connection.ConnectionInitiator(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain)); this.pnlDock = new WeifenLuo.WinFormsUI.Docking.DockPanel(); this.msMain = new System.Windows.Forms.MenuStrip(); this.fileMenu = new mRemoteNG.UI.Menu.MainFileMenu(); @@ -56,7 +57,7 @@ namespace mRemoteNG.UI.Forms this.pnlDock.DocumentStyle = WeifenLuo.WinFormsUI.Docking.DocumentStyle.DockingSdi; this.pnlDock.Location = new System.Drawing.Point(0, 0); this.pnlDock.Name = "pnlDock"; - this.pnlDock.Size = new System.Drawing.Size(1129, 472); + this.pnlDock.Size = new System.Drawing.Size(1129, 471); this.pnlDock.TabIndex = 13; this.pnlDock.ActiveDocumentChanged += new System.EventHandler(this.pnlDock_ActiveDocumentChanged); // @@ -64,7 +65,7 @@ namespace mRemoteNG.UI.Forms // this.msMain.Anchor = System.Windows.Forms.AnchorStyles.Left; this.msMain.Dock = System.Windows.Forms.DockStyle.None; - this.msMain.GripMargin = new System.Windows.Forms.Padding(0); + this.msMain.GripMargin = new System.Windows.Forms.Padding(2); this.msMain.GripStyle = System.Windows.Forms.ToolStripGripStyle.Visible; this.msMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.fileMenu, @@ -73,8 +74,8 @@ namespace mRemoteNG.UI.Forms this.helpMenu}); this.msMain.Location = new System.Drawing.Point(3, 50); this.msMain.Name = "msMain"; - this.msMain.Padding = new System.Windows.Forms.Padding(2, 2, 0, 2); - this.msMain.Size = new System.Drawing.Size(181, 24); + this.msMain.Padding = new System.Windows.Forms.Padding(0, 0, 1, 0); + this.msMain.Size = new System.Drawing.Size(184, 25); this.msMain.Stretch = false; this.msMain.TabIndex = 0; this.msMain.Text = "Main Toolbar"; @@ -82,8 +83,9 @@ namespace mRemoteNG.UI.Forms // fileMenu // this.fileMenu.ConnectionInitiator = null; + this.fileMenu.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3); this.fileMenu.Name = "mMenFile"; - this.fileMenu.Size = new System.Drawing.Size(37, 20); + this.fileMenu.Size = new System.Drawing.Size(37, 19); this.fileMenu.Text = "&File"; this.fileMenu.TreeWindow = null; this.fileMenu.DropDownOpening += new System.EventHandler(this.mainFileMenu1_DropDownOpening); @@ -92,8 +94,9 @@ namespace mRemoteNG.UI.Forms // this.viewMenu.FullscreenHandler = null; this.viewMenu.MainForm = null; + this.viewMenu.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3); this.viewMenu.Name = "mMenView"; - this.viewMenu.Size = new System.Drawing.Size(44, 20); + this.viewMenu.Size = new System.Drawing.Size(44, 19); this.viewMenu.Text = "&View"; this.viewMenu.TsExternalTools = null; this.viewMenu.TsMultiSsh = null; @@ -104,14 +107,16 @@ namespace mRemoteNG.UI.Forms // this.toolsMenu.CredentialProviderCatalog = null; this.toolsMenu.MainForm = null; + this.toolsMenu.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3); this.toolsMenu.Name = "mMenTools"; - this.toolsMenu.Size = new System.Drawing.Size(47, 20); + this.toolsMenu.Size = new System.Drawing.Size(47, 19); this.toolsMenu.Text = "&Tools"; // // helpMenu // + this.helpMenu.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3); this.helpMenu.Name = "mMenInfo"; - this.helpMenu.Size = new System.Drawing.Size(44, 20); + this.helpMenu.Size = new System.Drawing.Size(44, 19); this.helpMenu.Text = "&Help"; this.helpMenu.TextDirection = System.Windows.Forms.ToolStripTextDirection.Horizontal; // @@ -126,7 +131,7 @@ namespace mRemoteNG.UI.Forms // tsContainer.ContentPanel // this.tsContainer.ContentPanel.Controls.Add(this.pnlDock); - this.tsContainer.ContentPanel.Size = new System.Drawing.Size(1129, 472); + this.tsContainer.ContentPanel.Size = new System.Drawing.Size(1129, 471); this.tsContainer.Dock = System.Windows.Forms.DockStyle.Fill; this.tsContainer.Location = new System.Drawing.Point(0, 0); this.tsContainer.Name = "tsContainer"; @@ -156,7 +161,6 @@ namespace mRemoteNG.UI.Forms // _multiSshToolStrip // this._multiSshToolStrip.Dock = System.Windows.Forms.DockStyle.None; - this._multiSshToolStrip.ImageScalingSize = new System.Drawing.Size(20, 20); this._multiSshToolStrip.Location = new System.Drawing.Point(3, 25); this._multiSshToolStrip.MinimumSize = new System.Drawing.Size(300, 0); this._multiSshToolStrip.Name = "_multiSshToolStrip"; @@ -168,7 +172,7 @@ namespace mRemoteNG.UI.Forms this._externalToolsToolStrip.BackColor = System.Drawing.SystemColors.Control; this._externalToolsToolStrip.Dock = System.Windows.Forms.DockStyle.None; this._externalToolsToolStrip.ForeColor = System.Drawing.SystemColors.ControlText; - this._externalToolsToolStrip.Location = new System.Drawing.Point(39, 74); + this._externalToolsToolStrip.Location = new System.Drawing.Point(3, 75); this._externalToolsToolStrip.Name = "_externalToolsToolStrip"; this._externalToolsToolStrip.Size = new System.Drawing.Size(111, 25); this._externalToolsToolStrip.TabIndex = 17; @@ -188,12 +192,13 @@ namespace mRemoteNG.UI.Forms this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.ClientSize = new System.Drawing.Size(1129, 571); this.Controls.Add(this.tsContainer); - this.Icon = global::mRemoteNG.Resources.mRemote_Icon; + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MainMenuStrip = this.msMain; this.MinimumSize = new System.Drawing.Size(400, 400); this.Name = "FrmMain"; this.Opacity = 0D; - this.Text = "mRemoteNG"; + this.Text = " "; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmMain_FormClosing); this.Load += new System.EventHandler(this.frmMain_Load); this.Shown += new System.EventHandler(this.frmMain_Shown); diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index a973e4c18..5db2bf799 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -1,13 +1,3 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.Globalization; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Windows.Forms; using Microsoft.Win32; using mRemoteNG.App; using mRemoteNG.App.Info; @@ -26,6 +16,16 @@ using mRemoteNG.UI.Menu; using mRemoteNG.UI.Panels; using mRemoteNG.UI.TaskDialog; using mRemoteNG.UI.Window; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; using WeifenLuo.WinFormsUI.Docking; using TabControl = Crownwood.Magic.Controls.TabControl; @@ -190,6 +190,9 @@ namespace mRemoteNG.UI.Forms if (!panelAdder.DoesPanelExist(panelName)) panelAdder.AddPanel(panelName); } + + FrmSplashScreen frmSplashScreen = FrmSplashScreen.getInstance(); + frmSplashScreen.Close(); } private void ApplyLanguage() @@ -309,7 +312,7 @@ namespace mRemoteNG.UI.Forms if (CTaskDialog.CommandButtonResult != 1) return; - using (var optionsForm = new frmOptions(Language.strTabUpdates)) + using (var optionsForm = new FrmOptions(Language.strTabUpdates)) { optionsForm.ShowDialog(this); } @@ -436,7 +439,8 @@ namespace mRemoteNG.UI.Forms { if (controlThatWasClicked is TreeView || controlThatWasClicked is ComboBox || - controlThatWasClicked is TextBox) + controlThatWasClicked is TextBox || + controlThatWasClicked is FrmMain) { controlThatWasClicked.Focus(); } @@ -560,6 +564,9 @@ namespace mRemoteNG.UI.Forms { titleBuilder.Append(separator); titleBuilder.Append(SelectedConnection.Name); + + if (Settings.Default.TrackActiveConnectionInConnectionTree) + Windows.TreeForm.JumpToNode(SelectedConnection); } Text = titleBuilder.ToString(); diff --git a/mRemoteV1/UI/Forms/frmMain.resx b/mRemoteV1/UI/Forms/frmMain.resx index f7a980287..e30234e9b 100644 --- a/mRemoteV1/UI/Forms/frmMain.resx +++ b/mRemoteV1/UI/Forms/frmMain.resx @@ -135,4 +135,1001 @@ 350, 17 + + + + AAABAA0AICAQAAEABADoAgAA1gAAABAQEAABAAQAKAEAAL4DAAAwMAAAAQAIAKgOAADmBAAAICAAAAEA + CACoCAAAjhMAABAQAAABAAgAaAUAADYcAAAAAAAAAQAgAEIfAACeIQAAQEAAAAEAIAAoQgAA4EAAADAw + AAABACAAqCUAAAiDAAAoKAAAAQAgAGgaAACwqAAAICAAAAEAIACoEAAAGMMAABgYAAABACAAiAkAAMDT + AAAUFAAAAQAgALgGAABI3QAAEBAAAAEAIABoBAAAAOQAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAA + AAAAAAAAEAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD/ + /wD/AAAA/wD/AP//AAD///8AAHd3ZWdHdHR3R3R2V2V4AAdCUGFhYWBwcENCUlJDQnCAcGFhYFJSQ0NC + UkNDQlJHcHBwcGUkNDQlJSUlBhYWF2FgcGElJSQWFgcHBhYWFgdwYWFhZSQ0NCUlBhYWBwYXcWFhYBYW + FgcHBhYWBwYWB3BgcGFkNCUlBhYWBwcHBwdxYSVhIWFhY0MGFhYHBwcHcAdGA0ZUBwRDRwQ0NDQkB3ZW + dWR2clZ3Z4c0NAd4dwdwdnRhaMNHzlj4BSQ3/3BWdF6EdH5wZ3do+GBwR/hyB3B2dHB3w0fOWPglNDj4 + YFd2V+VkfnBWh2iIQGB4+HIHcFblJX50J+x4+Hd3j4dBR2dIxyR8dFSGeP////93JwdwZ2dHaGcn50j4 + iIj4+EBHV0jIx8jHx+dY+FJSeI9zB3Bn5+fn5+dlaPhDQ0f/cHR0NHR0dHR0MGj4BlJH+HYHcFJSUkNH + RlZY+Hh3iPh0NXYWBwcDAwEhaPj4//+HFgdwBhYHRlZHRleIiIh3dDQ0dwcHAhIDAhIDAwMDBhYHB3BD + QlZWVlZWVlZHRlYWFgdyUlIDAhIDAhIDAhISQ0MHcBYHR0dHR0dHR0dHRlJDR3YHAwISAwISAwISAwMH + BgdyUlZHRlZHRlZHRlZHRhYYB0AwEhAwEhAwEhAwEhBwcAB3dHZWdHZWdHZWdHZWdwDAAAADgAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAAAAygA + AAAQAAAAIAAAAAEABAAAAAAAwAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAA + gACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AB3R1ZXR2V3BwYHBhYHByR3Fh + YWBwcEEHcGFgcHBwc2dWFlJWBwQEB3Z0dlZ4Q3hzR2VnSHhgeEd2dHZWeHeIJ1Z0dnd/iIhHdnZ2dnh0 + eHFnR0dGeHeIZ3AlZWV4iIdHVwISAwMHBwdwZWR0ZWQ0JXEhAwEhAwcHB2VnR2VnR3CAAQAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAKAAAADAA + AABgAAAAAQAIAAAAAACACgAAAAAAAAAAAAAAAQAAAAAAAAAAAABAOjQAQjw2AEU8NQBKPjUATT82AEM+ + OABFPjgATkA2AEZAOQBHQjwASUM9AEpEPgBSQjcAVkM3AGBHOABiSDkAZko5AG5NOgBwTjsAdlA8AHlS + PAB/VD0ATEZAAE5IQgBPSUQAUEpFAFRPSQBVUEoAV1JMAFhSTABZVE4AW1ZQAFxWUQBeWVQAYVxWAGRf + WwBkYFsAZWBcAGtlYABuaWQAcm1oAHRvagB1cGsAdnBsAHp1cAB+eXQAhFY+AIpZPgCMWj8AlF1AAKxn + QwCvaEMAtmtFALdsRQC9bkYAgHt2AIF8dwCCfnkAxHFHAMhzRwDLdEgAzHVIANR4SQDZekoA4n5LAOR/ + SwCEgHsA64JMAO6DTQDwhE0A9YVNAPmHTgD6iE4A/opPAImFgACMh4IAjIiDAIuIhACMiIUAkIuHAJGM + iACUj4oAmpWRAJ6alQCgnJcAop6aAKSgmwCloZ0AqaWhALKuqgCzr6wAtLCsAL66tgDBvroAxcK+AMjF + wQDMyMUAz8zIANHOygDX09AA19TQANrW0wDc2dYA3tvYAN/c2QDh3doA5OHeAObj4ADn5OAA6OXiAOrn + 5ADr6OUA7OnmAO7r6ADv7OkAdJAAAI6wAACpzwAAwvAAANH/EQDY/zEA3v9RAOP/cQDp/5EA7/+xAPb/ + 0QD///8AAAAAAC8mAABQQQAAcFsAAJB0AACwjgAAz6kAAPDDAAD/0hEA/9gxAP/dUQD/5HEA/+qRAP/w + sQD/9tEA////AAAAAAAvFAAAUCIAAHAwAACQPgAAsE0AAM9bAADwaQAA/3kRAP+KMQD/nVEA/69xAP/B + kQD/0rEA/+XRAP///wAAAAAALwMAAFAEAABwBgAAkAkAALAKAADPDAAA8A4AAP8gEgD/PjEA/1xRAP96 + cQD/l5EA/7axAP/U0QD///8AAAAAAC8ADgBQABcAcAAhAJAAKwCwADYAzwBAAPAASQD/EVoA/zFwAP9R + hgD/cZwA/5GyAP+xyAD/0d8A////AAAAAAAvACAAUAA2AHAATACQAGIAsAB4AM8AjgDwAKQA/xGzAP8x + vgD/UccA/3HRAP+R3AD/seUA/9HwAP///wAAAAAALAAvAEsAUABpAHAAhwCQAKUAsADEAM8A4QDwAPAR + /wDyMf8A9FH/APZx/wD3kf8A+bH/APvR/wD///8AAAAAABsALwAtAFAAPwBwAFIAkABjALAAdgDPAIgA + 8ACZEf8ApjH/ALRR/wDCcf8Az5H/ANyx/wDr0f8A////AAAAAAAIAC8ADgBQABUAcAAbAJAAIQCwACYA + zwAsAPAAPhH/AFgx/wBxUf8AjHH/AKaR/wC/sf8A2tH/AP///wAAAAAATyYfHh4eHh4eHh4eHh4eHh4e + Hh4eHh4eHh4eHh4eHh4eHh4eHh8mTwAAAAAAAAAaAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBARoAAAAAAAkBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEJ + AAAAGQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBGQBPAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAU8kAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBASYeAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAR8dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQICAgEBAQEBAQEBAQECAgEBAQEBAR4dAQEBFjMzMQMBAQEvMzMwAwEBARUz + MzIEIFRXVicBAQEBAQEBASJVV1YoAQEBAR4dAQEDO0pKQAUBAQQ+Sko/BAEBAjVKSkIOLnJzc1QBAQEB + AQEBAVJzc3JNAQEBAR4dAQEDO0pKQAUBAQM+Sko/BQEBATZKSkIOOHJzc1UBAQEBAQEBAlhzc3ArAQEB + AR4dAQEDO0pKQAUBAQQ+Sko/BAEBAjZKSkIOOHJzc1UBAQEBAQEBBlxzc20nAQEBAR4dAQEDO0pKQAUB + AQM+Sko/BQEBAjZKSkIOOHJzc1UBAQEBAQEBC19zc2ojAQEBAR4dAQEDO0pKQAgBAQQ+Sko/BQEBAjZK + SkIOOHJzc1UBAQEBAQEBIWdzc2UcAQEBAR4dAQEDO0pKQAUBAQM+Sko/BQEBAjZKSkIOOHJzc1UBAQEB + AQEGUXFzc14KAQEBAR4dAQEDO0pKQAgBAQQ+Sko/BAEBAjZKSkIOOHJzc1UBAQEBAhg5aHNzcEsBAQEB + AR4dAQEDO0pKQAUBAQM+Sko/BQEBATZKSkIOOHJzc15LS0xSWWBuc3NxWxgBAQEBAR4dAQEDO0pKQAgB + AQQ+Sko/BAEBAjZKSkIOOHJzc3NycnNzc3Nzc3NeHwEBAQEBAR4dAQEDO0pKQAgBAQM+Sko/BAEBAztK + SkENOXJzc3Nzc3Nzc3Nzc3NuXB4BAQEBAR4dAQEDO0pKQA4DBAg+SkpADQQEFURKSj8EOHJzc2hgYWBg + YGFlb3Nzc1sMAQEBAR4dAQEDO0pKRz4+PT5GSkpHPj4/RkpKSjQBOHJzc1gMFxcXFxccOmpzc2wpAQEB + AR4dAQEDO0pKSkpKSkpKSkpKSkpKSkpKQREBOHJzc1UBAQEBAQEBCVlzc3NTAQEBAR4dAQEDN0lJSUlJ + SUlJSUlJSUlISEU8EgEBOHFzc1UBAQEBAQEBAVFzc3NZAQEBAR4dAQEBDxUVFRUVFRUVFRUVFRUUExAE + AQEBOHJzc1QBAQEBAQEBAlhzc3NWAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBOHFzc1YLCwwM + DAwaLGZzc3E6AQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBOHFzc2dfX19fX2Bja3Nzc2IcAQEB + AR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBOHFzc3Nzc3Nzc3Nzc3NzaC0BAQEBAR4dAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBLnFzc3Nzc3Nzc3Jyb2ldKQYBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBG01RUVFRUVFRUExDKyILAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4eAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAR8kAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + ASVOAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAU8AGQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBGgAAAAcBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEJAAAAAAAZAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBARkAAAAAAAAATiUeHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR4lTwAA + AADwAAAAAA8AAOAAAAAABwAAwAAAAAADAACAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAB + AADAAAAAAAMAAOAAAAAABwAA8AAAAAAPAAAoAAAAIAAAAEAAAAABAAgAAAAAAIAEAAAAAAAAAAAAAAAB + AAAAAAAAAAAAAEA6NABCPDYARTw1AEo+NQBMPzYAQz44AEQ+OABHQTsASEM9AFVDNwBYRDgAXUY4AFVI + PgBgSDgAZUk5AGhLOgBtTToAdE87AHVQOwB9UzwATkhCAFNKQwBRTEYAXk9FAFdSTABYUkwAXFZRAGRS + RgBhXFcAZWBcAGhiXQBsZ2IAdXBrAHNwbAB1cWwAenVwAH55dACEVj4AklxAAJVdQACjZEIAqmZDAK9o + QwCvaEQAtmtFALltRQC+bkYAg356AMNxRgDEcUcA1XhJANh6SQDdfEoA4H1LAOR/SwCFgXwA6YFMAOyC + TADzhU0A9YVNAPmHTgD6iE4A/olPAIuHggCNiYQAlI+LAJWRjACcl5MAm5iVAJ2ZlgCgm5cAoJyXAKGd + mQCrp6MAramlALCsqAC2sq4AubWxALu3tADAvLkAyMTAAM/LyADQzMkA1NHNANjV0gDb2NQA3NjVAODd + 2QDi39wA5eLeAOfk4QDq5+QA6+jlAOzp5gDu6+gA7+zpABQvAAAiUAAAMHAAAD2QAABMsAAAWc8AAGfw + AAB4/xEAiv8xAJz/UQCu/3EAwP+RANL/sQDk/9EA////AAAAAAAmLwAAQFAAAFpwAAB0kAAAjrAAAKnP + AADC8AAA0f8RANj/MQDe/1EA4/9xAOn/kQDv/7EA9v/RAP///wAAAAAALyYAAFBBAABwWwAAkHQAALCO + AADPqQAA8MMAAP/SEQD/2DEA/91RAP/kcQD/6pEA//CxAP/20QD///8AAAAAAC8UAABQIgAAcDAAAJA+ + AACwTQAAz1sAAPBpAAD/eREA/4oxAP+dUQD/r3EA/8GRAP/SsQD/5dEA////AAAAAAAvAwAAUAQAAHAG + AACQCQAAsAoAAM8MAADwDgAA/yASAP8+MQD/XFEA/3pxAP+XkQD/trEA/9TRAP///wAAAAAALwAOAFAA + FwBwACEAkAArALAANgDPAEAA8ABJAP8RWgD/MXAA/1GGAP9xnAD/kbIA/7HIAP/R3wD///8AAAAAAC8A + IABQADYAcABMAJAAYgCwAHgAzwCOAPAApAD/EbMA/zG+AP9RxwD/cdEA/5HcAP+x5QD/0fAA////AAAA + AAAsAC8ASwBQAGkAcACHAJAApQCwAMQAzwDhAPAA8BH/APIx/wD0Uf8A9nH/APeR/wD5sf8A+9H/AP// + /wAAAAAAGwAvAC0AUAA/AHAAUgCQAGMAsAB2AM8AiADwAJkR/wCmMf8AtFH/AMJx/wDPkf8A3LH/AOvR + /wD///8AAAAAAAgALwAOAFAAFQBwABsAkAAhALAAJgDPACwA8AA+Ef8AWDH/AHFR/wCMcf8AppH/AL+x + /wDa0f8A////AAAARh4aGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhofRgAAACEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBIwBFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBRh4BAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEfGgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBARoZAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBGhkBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEaGQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBARoZAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBGhkB + AQMDAQEBAgMCAQEBAwIBBwcCAQEBAQECBwcCAQEaGQELLi8OAQQpMiYBARMxLA1HTkECAQEBAR1NTR8B + ARoZARA7PRMBBTQ/KgIBJz83HFNgTgYBAQEBMF9bIAEBGhkBEDs9EwEFND8qAQEnPzkcU2BNBgEBAQFD + YFkdAQEaGQEQOz0TAQU0PyoCASc/NxxTYE4GAQEBB0xgVRoBARoZARA7PRMBBTQ/KgEBJz83HFNgTgYB + AQIfVmBQCQEBGhkBEDs9EwEFND8qAgEnPzccU2BRIyMlRFRgWCQBAQEaGQEQOz4TAQU0PyoBASg/NxxT + YF5cXF5gYF9NFwEBARoZARA7PhQFCzQ/LAUKLz81GFNgW1NSUlNXX11LCQEBGhoBEDs/NjM0PT86NDY+ + Py0WU2BPFxUVFxtNYFogAQEaGQEPOTw8PDw8PDw8OzoyDBVTYE0GAQEBASVeYDgBARoaAQMQERERERER + EREQDgQBFVNgTgcBAgEHQ19eJQEBGhkBAQEBAQEBAQEBAQEBAQEVU2BUSUdHSExYYFUbAQEaGQEBAQEB + AQEBAQEBAQEBARVTYGBgYGBgYF9XMAIBARoZAQEBAQEBAQEBAQEBAQEBCENLTEtLS0pJQB0HAQEBGhkB + AQEBAQEBAQEBAQEBAQEBAQICAgICAQEBAQEBAQEaGQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + ARoZAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBGhoBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEaHgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR5FAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBRgAiAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBASMAAABFHhoZGRkZGRkZGRkZGRkZ + GRkZGRkZGRkZGh5GAADAAAADgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAAAABwAAAAygAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAA + AAAAAAAAQDo0AEI8NgBGPTUAST41AEQ+OABOQDYARkA6AEdCPABIQjwASUQ+AFNCNwBeRjgAYkg5AGZK + OQBsTToAcU47AHlSPABSTEcAV1JMAFhSTABbVU8AW1ZQAF5ZVABjXlkAbGdiAG1nZABtaWQAdG9qAHhz + bgB7dnEAfHdzAIZXPgCVXkAAnGBBAKNkQgCtZ0MArWhDALVrRAC6bUUAvG5FAIF8dwCDfnkA0ndJANp6 + SgDdfEoA435LAJCBdwDpgUwAkIuHAJaOiACempUAppSKAKqmogCsqKQAubWxAL25tQDCvroAxsK+AMnG + wgDLyMQAzcrGANHOygDU0c0A19PQANnW0gDc2dUA4N3aAOfk4AAAsDYAAM9AAADwSgAR/1sAMf9xAFH/ + hwBx/50Akf+yALH/yQDR/98A////AAAAAAACLwAABFAAAAZwAAAIkAAACrAAAAvPAAAO8AAAIP8SAD3/ + MQBb/1EAef9xAJj/kQC1/7EA1P/RAP///wAAAAAAFC8AACJQAAAwcAAAPZAAAEywAABZzwAAZ/AAAHj/ + EQCK/zEAnP9RAK7/cQDA/5EA0v+xAOT/0QD///8AAAAAACYvAABAUAAAWnAAAHSQAACOsAAAqc8AAMLw + AADR/xEA2P8xAN7/UQDj/3EA6f+RAO//sQD2/9EA////AAAAAAAvJgAAUEEAAHBbAACQdAAAsI4AAM+p + AADwwwAA/9IRAP/YMQD/3VEA/+RxAP/qkQD/8LEA//bRAP///wAAAAAALxQAAFAiAABwMAAAkD4AALBN + AADPWwAA8GkAAP95EQD/ijEA/51RAP+vcQD/wZEA/9KxAP/l0QD///8AAAAAAC8DAABQBAAAcAYAAJAJ + AACwCgAAzwwAAPAOAAD/IBIA/z4xAP9cUQD/enEA/5eRAP+2sQD/1NEA////AAAAAAAvAA4AUAAXAHAA + IQCQACsAsAA2AM8AQADwAEkA/xFaAP8xcAD/UYYA/3GcAP+RsgD/scgA/9HfAP///wAAAAAALwAgAFAA + NgBwAEwAkABiALAAeADPAI4A8ACkAP8RswD/Mb4A/1HHAP9x0QD/kdwA/7HlAP/R8AD///8AAAAAACwA + LwBLAFAAaQBwAIcAkAClALAAxADPAOEA8ADwEf8A8jH/APRR/wD2cf8A95H/APmx/wD70f8A////AAAA + AAAbAC8ALQBQAD8AcABSAJAAYwCwAHYAzwCIAPAAmRH/AKYx/wC0Uf8AwnH/AM+R/wDcsf8A69H/AP// + /wAAAAAACAAvAA4AUAAVAHAAGwCQACEAsAAmAM8ALADwAD4R/wBYMf8AcVH/AIxx/wCmkf8Av7H/ANrR + /wD///8AABoUFBQUFBQUFBQUFBQbABkBAQEBAQEBAQEBAQEBARsUAQEBAQEBAQEBAQEBAQEUEwEBAQEB + AQEBAQEBAQEBFBMDAwEEAgMEBwkCAQIKAhQUISIGJw8OKC82CQIXNxUUFCUmCywREC00PAoBHUAUFBQl + JgssERAtND4ZGzg3ChQUJSgNLSAgLTREPD1DNQgUFCMuKzAsLCQyPRYSKUIYFBMLDQ0NDQwEMT8fHDNB + FxQTAQEBAQEBAR86OTk3KgUUEwEBAQEBAQEFCgoKBwIBFBQBAQEBAQEBAQEBAQEBARQZAQEBAQEBAQEB + AQEBAQEaABkUExMTExMTExMTExQZAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACJUE5HDQoaCgAAAA1JSERSAAABAAAAAQAIBgAAAFxyqGYA + AB8JSURBVHja7Z0JfFXFoYf/c+7NDlmAsBYJCqIgUAUUEAlYfMYiap8PfSqibZ9at6r4FHGp5RUBQaUi + CLavz6JU1OAKKioWgwEqAdkE2RchLNlDEuAmuWfezIkUsJDcJOeek+T8P4m5OTn3ZGZ+d77ZZ8SB3MJM + A/iwTXLSFISJkSNH+jYfOBAfGfS1gRDdpDS7GDA6QaCdKc1kSCMBMGMAESEMYYQrHIS4jVQfePX/CsA4 + CmEWq497LiQOSGHuVtd2QMot5b7gofPatTucnp4eDHd4xKHc/LEwsa5Nm5aL7HywzvTbDhxo4ZO+HpDi + UhXJS4Q0u6tItoCBZuqWiHBHjpBGRIXKh6WqICwwhdhoCPG1FHJ5UAQ3dm3XriBcMhB2PzA1NTW6rBxd + VCYfpiL0cxOip8r8rQwD/vCnISFNA9NEpcqdeYaU69WPn6jXi+MisT0jI+OYnX/HNgF0Uhm/dQUukNIY + CSFHSNM8WxhGlOMpR0gTQ+WlgGo671CZdaEQSM+JwLd7bBJBvQWgSnx/qSrx1YNGSYgbpERnlvaE2I+u + FSgB7BKQb0tgbrOqGkFlfZ5ZHwGI7v37J8WKmGtNIe82IHurS5FuJxIhTR9ZrprW61TzYFbAF3x/Q2Zm + kb5YlyfVTQAjR/r67ss53wQeFFJcLwwk1PlZhJC6IKWJIinkuz7DmJbVvtVm1KGjsNaZtktaWlR88bFh + QuIJpZx+rO4T4h5WswDIgiEmFOdEfbF9+6JAbd5fKwF0T01tFhMwb4Hhe0y9sVNt308ICQtSFcZ7hDQn + HSkWb2zalFEa6htDzsB9hg1LEKUV90CYYyB8rdyOMSHkR5gyVwq8gLiIWasXLy4O5S0hCUBnfpRVPKTa + +w/AQKLb8SSEnAETRSqPTpOx/hdDkUCNAkhV1f6yStyPoHiUmZ+QRkBV5+CzRyMxY1NG9c2BagWQlpYW + lVt07HZ10x9U5k92O16EkBBRzQEI+WSrhNg5ixaduWPwjALQc/l37MtNEwIz1E0pbseHEFI7TIldQpj3 + XX3F0EXjx483T3fPmQQg+g5I1Yt4/qxK/kvA3n5CGiPShFzhE8adWcuWbMJpJgudNmP37/9vLcqNwFSY + YjTH+Qlp1FQEJebE+SofzczMLPzxL/9FAHpuf1k5blWl/wvs9COkCWCiUBhyTEqH1q//eFnxvwjgwksG + n28I4zVhoA9Y9SekKaCbAquExOjVKzI2n/yLUzL4D2v5n1RXH+HCHkKaErJcNemnxEXJZ07eU+AUAfQb + mNrXlOINIdDV7eASQuzFlHIrfMbN32QuWX382j8FoDf0SC43xpsy+LBhGD63A0sIsRdrlyFDPp+fjd/v + 2VNVC/inAPoOSL1AAm8JIbq7HVBCSHiQUm5SBfwNWcuWbNQ/WwLQk352Z+c+IE1zIriNFyFNF9MMSEOM + O7tD6+l6RMASwE8HDUr2B/1/Uzq4wu3wEULCS9CUn0l/cNTazMxcSwB9Lk0dIqWYZwBt3Q4cISS8mMBB + IeRNq5dlfCl09X9Xdu5Y08R4zvojpOmjOwMNn/hd5/atpoieg4YnRQbL5giBEW4HjBDiEKb4oCIq/nbR + Z0DqeRBigWoLdHE7TIQQZ5AS24QQI0TfgUOvkab8qzCQ5HagCCHOoPJ8oYDvNtFn4JAxqvSfDJ7VR4iX + qFASGCv6DhgyHQL3ux0aQoizBCGni4v6D55vGMb1bgeGEOIsEkgX/QYO/lLCSHU7MIQQhxFYIvr0H7xW + GEZvt8NCCHEWE1gjLhqQusUQ4ly3A0MIcZzNSgBDdhoCnd0OCSHEYUy5Q/QdOHg3YHRyOyyEEGextg2n + AAjxJhQAIR6GAiDEw1AAhHgYCoAQD0MBEOJhKABCPAwFQIiHoQAI8TAUACEehgIgxMNQAIR4GAqAEA9D + ARDiYSgAQjwMBUCIh6EACPEwFAAhHoYCIMTDUACEeBgKgBAPQwEQ4mEoAEI8DAVAiIehAAjxMBQAIR6G + AiDEw1AAhHgYCoAQD0MBkJCJjY1Fu7Zt4Pf73Q5KrZFSovhwCcoDgVOum+q6NE2o/yMYNK3XwWAQFZWV + 1nuaOhQACYnmzZvjumuvxtDU1EYrgPLyciuTn4y+duzYMVSqTF9WVqpeB1BSchi5ufkoKS1FaUkJCgoL + kZdfgICSh76/sgnJgQIgNRIXF4vrf3EdRoy4GrExMW4HxxF0BtcZXWf4o0ePKimUIr8gH3v37sOe7/fi + 4MGDyN6/H6WlZaioqGi0QqAASI306H4+xo19BElJSW4HxXWOi6G0rAw5OTnYvn0Hvt24yfqel59vCaMx + QQGQGvlp716WAJo1a+Z2UBocWgjHVNPg0MFDWLd+Pb5emYWt27ZbzYrGUCugAEiNUAChYZomiouL8c3a + tfjiiyXYsnWbJYKGDAVAaoQCqB265Ncdh5mZy/DJos+wLzu7wdYGKABSIxRA3dB9BVtVLeDNt9/G+vXf + WkOLDQ0KgNQIBVB3dMmvOwvT33kXS77MsIYZGxIUAKkRCqD+6L6B9z74EAs/+sQaVmwoUACkRigAeygp + KcH8d97Dgo8+tiYVNQQoAFIjFIB9FBYW4vW5b+CLJV9afQRuQwGQGqEA7CU7ez9mzpqN9Ru+dX10gAIg + NUIB2IvO9OvXb8D0GS/j4KFDroaFAiA1QgHYj14/8N77H+DNt9IRcHH6MAVAaoQCCA95eXmY9uJLWKdq + A241BSgAUiMUQHjQU4eXLV+OmbNesVYbuhIGCoDURDgEYP6w8YZb+Hw+GIbh2t8/jh4afHH6DPxjZZYr + tQAKgNSI3QLQH/SNGzdhaWYmpOlO1TcqKgoRkRGIi41FfHz8D1/NkRCfoOIZh5iYGEREREAIEdZw6LRY + +lUmZrw8C0eOOD9BiAIgNWK3AHTpv+jTzzD7T//rai1Ao2sCEX6/tcuRP8KPyMhItGvbFh06dMA5Z3dG + 9+7no327dmHdBSm/oACTJ0/Fps2bHY8/BUBqpCkLoDp0LaFtm9a4YtjPcPnQIUhISAjL39Fp8OZbb+Ot + 9HccTw8KgNSIVwVwnJiYaKRedhluuulGtGrZMix/Y/2GDZj87HMoPnzY0bhRAKRGvC4AjW4aDLt8KG4d + dbPVX2A3hUVFmDR5CjZu+s7ReFEApEYogCpioqNx6623YPhVabb3Ceh1Aa/8+S9Wuuj0cQoKgNQIBXCC + lE6dMPbRh3FWx462PlePBiz+4u94efafHN1YlAIgNUIBnECX/LePHoVrRlxtjSDYia7+/2HCROs8Aqeg + AEiNUAA/So9ePfGYSg99WIqdZGdnY8LEyfh+7z7H4uKQAIT65/6sq4aLVP+ca/fVFgrgVPTxaE8+/hhS + UlJsfW5RUREmOtwRGH4BCB8iEs9FZFIP6zU5DWY5zGN5qh14IjNIdQ2mPoLKhAweU18VkJVHYFYcVteD + Shmm9d2SR5ihAE5Fzw/47zEPYuCA/rY+V28VNnnKc1i1+hvH4hJeAahSP6plb8Rf8BtExJ8d9mmVjRUr + C1vzwE9kZmlWVGVwJQAzGFCvtQCOWgIwy4tRWXYQFYd3obJ0j3q935JDuGoRFMCp6Lb/Hb/+FYb/PM3W + 9QR6JGDKcy9g2fIVjsUlrALwxXVA0kXjENWiu5IBM799VDUZpBJEMFCkRLADgUNZCOSsQvDoAXXd3q2m + KIBT0Zn+phtH4oaR/2HrcKBOi6nPT8NXmcsci0tYBRCRdAFaXjIevugWjkXIm0iriVBZug9Hs79UX0tQ + eWS/bTUCCuBUtACuGfFz3D56tLVgyC4oAFJvtAh0jaBs5/s4eiBTNQ3K6v1MCuBUdFP2imGX4+677rRm + CNoFBUBsQsIsL8GRvYtRuv1t1SzIQX06CymAU9E1gKuHX4Vf3X6brTUA3QegBZC5bLljcaEAmjC6IzGQ + sxqHv/s/VSvY/kNHY+2hAE4lXH0A+iBRPQqQtWq1Y3GhAJo60kQgbx2KN85GRdE21KUmQAGcih4FuOuO + X+OqtCttHQU4fLhECWCqtUegU1AAXuC4BDbMVDWBnaitBCiAU4mNjcWj/z0G/fr2sfW5hw4dsiYCbd+x + 07G4UABeQQZxdH8mitbPgBnIq9VbKYBT6djxJ3jq8XHo0KG9rc/dvmMH/mfCROTnFzgWFwrAQ8hgACXb + 3kTptnnW61ChAE6gRwCGDL4M9917N6Kjo217rl4NuDJrlTURSPcFOAUF4DEqjxxC0TdTVJNgDUJtClAA + J4iLi8P9KvMPunSgrTNbdZq88+57mPvGm46eGUgBeA6JI3v/juL1f4RZEdqyUwqgCp3hL7m4H3573z22 + 7w94LBDAC9NexPIV/3B0e3AKwIOYgSIUrJ6EQM7KkO6nAKrQuwXr0r9Xr562r2vZty8bz0xydimwhgLw + JBKlOxfg8MaXQ+oLoACAFklJ1n6Aendgu7cD0yV+xtKv8NLMWY62/zUUgEepKNmLgpVPobJkT433elkA + uqRvnZyMkf9xvcr8qdZSYLvRmV5nfi0Bp08HajQCkJXHEMj/tmqdvM0I4UdEYhfbRFVZ8j0qSmtRlRM+ + GBHNYETGwxfZHMIfA2FEhnUFpU7PwnXTcHTvZzXe60UB+AwDcSq+53U711r227tXL1un/Z7M1m3bMOnZ + 55CTk+N4PBuNACqPHET+iscRPJZreyIY/mZI7P0QottebMvzSja/hpId6SHfL/R/vijry4hoDn9CV0Qm + nae+usHfrIO6bt9w0wlUM2DHuyje+CdrQ5LqaMoC0I71+fzW7D5dtY9v3hzt27ezNv/srdr6XbqcY20D + Hq69LPQx4W/MewvvvPe+K2nReARQth95mQ/9sLDFXnSmS7xoHGLaDbDleYc3/S9Ktv6tHk9QQjAi4ItJ + RlTrixHbKQ0RCeeoD6G9OyoFcteiIOv31gYj1REOAegx7w8XLHR0C+zj6BV8+kuX6PrQD13Fb9GiBVq3 + TkZL9T0xMdEa7gv34aG6ur9z1y5Mfe4F7N2X7Xg6aCgANEQBnIQwENGsE5qf/0tVQxmgfrSvA6qyLBv5 + yx9T36tvroTjdOBAIGBtgeUGuqQ/XuLr78dLd6d3rNLxn/P6XHz8yaeu1YQoADRwAfyAP+4nVjMlKvlC + 2/oGgoFiFKyagPLcVdXeFw4BeB1d81nxj68xc9YrKC4urv8D6xoOCqBxCEA3C6Lb9EfihY+o9Eyy5Ym6 + I7Bo3Ys4sndRtfdRAPaiq/7ff78X02fMxJat2xzv+T8ZCgCNRQBKARG6s3IMYn8yBNZW6/VFBq1OQL1p + SHVQAPZSWFiIv7w6B0u/ynS9E5QCQOMRgM70sWelIbHXbyH89owMlGyZi8ObX612/0AKwD5KSkrwVvp8 + q92v+0HchgJAYxIA4G+egpb9J8If186W55Xt/hjFG16yzh44ExSAPejMv2DhR3jv/Q9xxKUO0B9DAaBx + CcCITECLfk9XdQbawJHsDBSvmQqzms1DKYD6odv4utqvV/t9+vkXro1+nA4KAI1LAHpSUELP+xCXMtyW + 5x09+DWKVk+sOnHoDFAAdUf39u/atRvp77yLlVlZqtrv3Mm/IYWPAmhcAlChRfNuoxB//i9teRoFED7K + ysrw9cosvP/Bh9i1e48rk55qggJAYxMAENf5OlULuNeWSUGBvA0ozHoawUDhGe+hAGpHeXm5tb2Xnu78 + 9cpVlgjcHOqrDgoAjU8AsZ2GV40E+Op/KEV54RYUfP0Egsfyz3gPBRAaelXf7j17sHTpV1bGz8nNbZCl + /slQAKAAKID6k5+fjwUffYyvvlqG3Lw818f3Q4UCAAVAAdQfXe1fu26dau8vwKbvNlur/BoDFAAoAArA + HnQ7X6/p/2zxF/js88UoLCxqsG3/41AAoAAoAHvRM/y+WbMG6fPfxbbtOxp0PwAFAAqAArAfnel37tyF + uW/Mw5o1a1HZQPsEKABQAG4IQLeR6zMXvmodf9WGHXodv89nWBt4hHsTj9qgq/8HDhzEG/PetE78rXBw + v/9QoQBAATgtAJ0xVq1ebS2IqUv1WGf45s2bIcJftUefz+9DXGwsIiOjENcsDkkJCUhITEBiQiKaxzdH + THS0tfuP3bv5hsqhnBy8+tfXsHz5CgQbWHOAAgAF4LQAwrknoJZDdFSUtXuv/oqNi0XHn3RA+3bt0bFj + B5zVsSOSk5OtAz51LcIJtPD27tuHWbP/jA3fftugOgYpAFAATUkA1aGFkJAQb0mgR/fz0fOCHkoKHa39 + /8K9HZjO9N9u3IjpM17G/v0HHItzTVAAoAC8IoCT0dt+JyUloVu3rrhs0CDrtB+9I3A4RaDP/Fv48Sd4 + /fW/WUeBNQQoAFAAXhTAyegawAU9uuPnaVeiZ88LwnL4x3HyCwowbdqLWLNuvdvRtqAAQAF4XQAaXfLr + 47+uSrsCaVdeadUOwsHxY8BmvDy7QewLQAGAAqAATqA7EAcNuhQ33XgD2rZtE5a/oTcHmfr8NKxbv8Ht + 6FIAGgqAAjgZPVw4ZPBluG30rWjRwv6agI7/Rx9/Ym0M6vaaAQoAFAAF8K/ofoBrRwzHjTeMRHS0/Uez + 7d69G89MmoL9B9wdEaAAQAFQAKcnKSkRd991Jwb0v8T2GYZ674A/Tp9hzRDkuQAhQAGcgAJwBt0xqOcL + jHnoAbRp3drWZx9Pg1dUGri5ToACAAVAAZwZfYjoqFtuwnXXjLB95uCWLVvwzOQpyM8vcC1+FAAoAAqg + erp2OceKf5s29o4K6NGAPzwzyToezC0oAFAAFED16E7Au+74NYb97HJb+wL0CMCMl2fhi79/6Vo/AAUA + CoACqB7dF3Bxv754+KEHrFmDdqHT4cMFC/HqnNetacJuQAGAAqAAaqZlixZ4fNyjOK9bN9ueqUv9lVmr + MGXq866tDaAAQAFQADWjJwf98vbRuObq4bY2A3bt2oUJE5/FwUOHXIkXBQAKgAKoGd0M6H/JxVYzICYm + xrbn5uXlKQFMtvYOdAMKABQABRAanTqdhSfHPYb27e05mVmjFwQ9M+lZrFm7zpU4UQCgACiA0IiLi8XY + Rx7GRRdeaNu+Abrzb8bMWfhiyRKVLs6PBFAAoAAogNDQ/QC/+uVojBhuXz+Ajv+bb6XjrfT5rqQFBQAK + gAIIDZ3p/23Y5fjNXXdam4zamRav/PkvrgwFUgCgACiA0OnVsyeefHysbfMB9FDgsuUr8NwLf3RlaTAF + AAqAAgidzikpeOqJcWjTxr7FQd+sWWuNBNTnnIS6QgGAAqAAQqd1cjKeUDWALuecY9szN2/Zaq0JKCoq + cjw+FAAoAAogdPQcgMcfe8QaCbCLXbt3Y4ISwMFD9n+2a4ICAAVAAYSOHgnQk4EGXzbItmceOHjQEsDu + Pd87Hh8KABQABRA6fp8Pv7nzv5CWdqVtcwFyc3OtPoDtO3Y6Hh8KABQABRA6+hDSUTffhOv//Re2bRBS + XFxszQbcuOk7x+NDAYACoABCR88F0AuCbr/tVtvmApSWlWGiEoAb24RTAKAAKIDQ0dX+ywYNxEMP/Nba + LswOyssrMHHys8hatdrx+FAAoAAogNqhDxV9+qknbFsVqGcA/vHFl/Dl0q8c3xmIAgAFQAHUjnO7dsXv + f/cEEhISbHmeToNX57xm7Q4UDJqOxoUCAAVAAdSOlE6d8Lsnx9m2SahOj3feeQ9z581TtQFn04MCAAVA + AdSOdm3bWusBUlJSbEuPTz/73FoQ5PR6AAoAFAAFUDuSEhOt9OjRo7stz9Pt/uUr/mEtCCovL3c0LhQA + KAAKoHZERkTg0Uceto4Ms4tN332HP0yYhMMlJY7GhQIABUAB1A49Aej+e++2zgmwazZgTm4unpn4LLbv + cHZvQAoAFAAFUDv0ZKDRo27Gv//iOttmA1ZUVGLOa6/jw4UfOZomFAAoAAqgduhSf+iQwbjvnrutY8Tt + QPcDbNm6FVOmvoBDOc6tCqQAQAFQALWnamOQx2w9L7C0tBSTpzzn6A7BYRWAv1kKkvo9hciEs+v5JIlA + /rcoWPk0zECh7YkgfDGI7/EbNEsZrpKhflU6WXkUxRtmomzPR7aH8zjRbS9F0k8fhhGdVL8HSRNHD6xA + 0dopMMsPn/E2fTim7vRq386e7bD1zjd6E8z0+e9aMmiM6PMC77nrDgwdOsSWDUJ1DWD9+vV44cWXkJeX + X+/nhUpYBQDDrz6sg5DQ/Q4lA/3hqUuHiURF8U4Ub3wFgdzV1ofWfoQK31lI6HEXottcXGcJ6Mxftvsj + VfrPVRmqOAzh/CG0/jjEdb4OzbveACMyvm4PUelYXrBJpetsVQv4rtp0jYyMwJDBg3HLzTehVauW9Qq7 + HubKyFiKufPedPSDbje6GdDnogvx4G/vQ1JSPUWsOHy4BDNnzbaGA52UYngFoNESaDMAMe2HQKjXtUUG + AziydxECeWvDlPmPUyUBnbHq2mSpKN6hBPBBWDP/P0OrJBDb8UpEteqFuojVrCjFEVVLKS/aHFK66oUv + lw7sj0su7lf3ji8JZO/fj4UffYK8/Mab+Y+jawHXjhhetT1YfQYDVLrs2rMHH3ywAGVHjjgah/ALQCMM + Vc2ORp1SSX04ZfBYVSqFHVHVrha1F5WFWa6C69xMLqHDafUD1CVdg5Zca5OuuqobHRVV56Ev/ZcqKyus + 1W9NBV078vsj6pv/rQVBTk8C0jgjAEJIg4QCIMTDUACEeBgKgBAPQwEQ4mEoAEI8DAVAiIehAAjxMBQA + IR6GAiDEw1AAhHgYCoAQD0MBEOJhKABCPAwFQIiHoQAI8TAUACEehgIgxMNQAIR4GAqAEA9DARDiYSgA + QjwMBUCIh6EACPEwFAAhHoYCIMTDUACEeBgKgBAPQwEQ4mEoAEI8DAVAiIehAAjxMBQAIR6GAiDEw1AA + hHgYCoAQD0MBEOJhKABCPAwFQIiHoQAI8TAUACEehgIgxMNQAIR4GAqAEA9DARDiYSwBXDRgyE5DoLPb + gSGEOIwpdygBpG4xhDjX7bAQQhxns+jTf/BaYRi93Q4JIcRZTGCN6Ddw8JcSRqrbgSGEOIzAEnFR/8Hz + DcO43u2wEEKcRQLpou+AIdOVCe53OzCEEGcJQk4XfQYOGSOAyernCLcDRAhxjAppyrGi78Ch16gXfxUG + ktwOESHEGVSeLxSQt2kBdJOQC1UtoIvbgSKEOIOU2CaEGCF6DhqeFBksmyMERrgdKEKIQ5jig4qo+NvF + yJEjfbuyc8eaJsYbBvxuh4sQEl5UXq80fPJ3ndu3niL0hT6Xpg6RUswzgLZuB44QEl5M4KAq7P9zVeaX + GZYAfjpoULII+v7mE+IKtwNHCAkvQVN+ZkThltUZGXmWAKxmwP6c+xGUk2GoXxFCmiamGQDEY507tn4p + PT09KI5f73fp0B6mab4thOjudhgJIeFB5fGNPp/vxqxlSzbqn/8pgE6pqdHJ5RhvSjGGnYGEND105x8M + +Xx+Nn6/Z0/GMX1NnHxDv4GpfZUA3hACXd0OLCHEXkwpt8Jn3PxN5pLVx6+dIoBUVQsoqxBPAPJR9atI + twNMCLELWa7y9LNxEXJiRkZV6a8RP76tz4DU86QQrxlA39P9nhDS6JDqXxZgjF61fMmWk3/xLxlc1QL8 + ZeW4VUrxPNcHENL4kSYKDUOOSenQ+nXd83/y705bwg8aNDzpWLB0qinFbewQJKTxojv+pMBf43yVj2Zm + Zhb++PdnquKLvgNSe6hawJ9ULaA/2BQgpDGiCn+5wldh3JmVtWQTrKbAqZwxYz/99NPGws+XpkHKmUIg + xe2YEEJqh9TbfpvmvcPThn46fvx483T3VFuyp6WlReUVB25TT5oAA8luR4gQEhoSMscAnmwZH/PaokWL + Ame6r8aqfWpqarPScnGvkBgLdgoS0uDRnX4qr06uiIuYuf7zz8uquzektn2fPsMSRFTlAzDxICVASANG + ZX7hE9PMY77pq1cvLq7p9pA797QEEFlxt5BiDJsDhDRATORKgedR7p8dSubX1Kp3v7tqDsSWGzdLIcep + N3aq7fsJIWFBmhK7fUJOKivCvE2bMkpDfWOtM3CXLmlRCS0DP4Mwn5QQ/ThPgBD3+GGBz0ojKCcU5cf+ + ffv2M3f4nY46luAjff0uzTuv0pQPGhLXCwOJdX8WIaQOSGmiCAjON3z+F7OWDf4OOP1QX3XUJ9OKnoMG + JUaYvmvVy3sMyN5cQESIE+iFPVircvusCiP4wYbMzCKcZpJPKNS71NZrB0rL0UU9aJQK0EhIcTabBYTY + j1XdF3InhHjbgJjbuUOr7T+e219bbKu266XEJUGjhwrlSCExQkh5DrcXI8QGTDOgCtftEsYC4Rfz833m + xj0nLemtD7a327UIjlQa50iYVwSDuEoI0UtVTlqxVkBI6FSV9siTUq73CfGxMMTiWL+5I8OmjH+csHXc + 6Y1Gtx040MJf6e9u+sRAIxi8RBq6hoCWwkAz8CxCQk6mQpoohYF8YZobTYivVTV/eaW/clPXdu0K6lvV + PxOO9NxrGWw+cCA+MuhrI4RxrjTNc0wDKT6Idqp2kGxKPYpgxkAYkUJwNIE0XaTU0/TNcsA4aggUqU97 + rrqwXxWMe4RPbpem2FYZiYPntm5dEq5MfzL/DzhH5D/LFbPnAAAAAElFTkSuQmCCKAAAAEAAAACAAAAA + AQAgAAAAAAAAQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGODgSPzkzVEA5M59AODPL + Pjg03EA6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M98+ODTcQDgzy0A5M59AOjRTODg4EgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVVQNBOTU+ + Pzg0uT86NPVAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pzo09T46NLg+OjY9VVVVAwAAAAAAAAAA + AAAAAFVVVQM/OTNUPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz30A6NFNVVQADAAAAAAAAAABAODQ/Pjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjoyPQAAAABDNTUTPzg0uUA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z46NLg4ODgSPzkzVUA6MvZAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8/OjT1 + QDo0Uz86NKFAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5M58+OTTMQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AODPLPzgy3UA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pjg03D46NOBAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTg + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPf + Pjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP9NQDb/iVg+/5NdQP+TXUD/j1s//1lEN/9AOjT/QDo0/0A6NP9AOjT/QDo0/2ZKOf+SXD// + k11A/5NdQP+CVT3/Rz01/0A6NP9AOjT/QDo0/0A6NP9COzT/cE47/5NdQP+TXUD/k11A/3lSPP9EOzT/ + QTs1/2plX/+Mh4P/jIiD/4yIg/+Ggn3/UUxG/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/WVNO/4qGgf+MiIP/jIiD/4yIg/9qZWD/QTs1/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/dlE7//eHTv/+ik///opP//2JT/+YX0D/QDo0/0A6NP9AOjT/ + QDo0/0M8Nf+6bUX//opP//6KT//+ik//7YJM/2FIOf9AOjT/QDo0/0A6NP9AOjT/Sj42/9B2SP/+ik// + /opP//6KT//ffUr/U0I3/0dBPP++u7f/7uvo/+7r6P/u6+j/7Onm/4F9eP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QTs1/5uXk//u6+j/7uvo/+7r6P/u6+j/sq6q/0Q+OP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/3tTPP/6iE7//4pP//+KT///ik// + nmFB/0A6NP9AOjT/QDo0/0A6NP9EPDX/wXBG//+KT///ik///4pP//GETf9kSTn/QDo0/0A6NP9AOjT/ + QDo0/0s/Nv/WeUn//4pP//+KT///ik//5H9L/1VDN/9IQj3/xMG9/+/s6f/v7On/7+zp/+7r6P+Ggn3/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0Q+OP+3s6//7+zp/+/s6f/v7On/ + 7uvo/5GMiP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP97Uzz/ + +ohO//+KT///ik///4pP/55hQf9AOjT/QDo0/0A6NP9AOjT/RDw1/8FwRv//ik///4pP//+KT//xhE3/ + ZEk5/0A6NP9AOjT/QDo0/0A6NP9LPzb/1nlJ//+KT///ik///4pP/+R/S/9VQzf/SEI9/8TBvf/v7On/ + 7+zp/+/s6f/u6+j/hoJ9/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9IQjz/ + w8C8/+/s6f/v7On/7+zp/+3q5/9/enX/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/ + QDo0/0A6NP9AOjT/e1M8//qITv//ik///4pP//+KT/+eYUH/QDo0/0A6NP9AOjT/QDo0/0Q8Nf/BcEb/ + /4pP//+KT///ik//8YRN/2RJOf9AOjT/QDo0/0A6NP9AOjT/Sz82/9Z5Sf//ik///4pP//+KT//kf0v/ + VUM3/0hCPf/Ewb3/7+zp/+/s6f/v7On/7uvo/4aCff9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/TkhC/87Kx//v7On/7+zp/+/s6f/q5+T/dXBr/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/3tTPP/6iE7//4pP//+KT///ik//nmFB/0A6NP9AOjT/ + QDo0/0A6NP9EPDX/wXBG//+KT///ik///4pP//GETf9kSTn/QDo0/0A6NP9AOjT/QDo0/0s/Nv/WeUn/ + /4pP//+KT///ik//5H9L/1VDN/9IQj3/xMG9/+/s6f/v7On/7+zp/+7r6P+Ggn3/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/1dRS//Z1dL/7+zp/+/s6f/v7On/5+Th/2tmYf9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP97Uzz/+ohO//+KT///ik// + /4pP/55hQf9AOjT/QDo0/0A6NP9AOjT/RDw1/8FwRv//ik///4pP//+KT//xhE3/ZEk5/0A6NP9AOjT/ + QDo0/0A6NP9LPzb/1nlJ//+KT///ik///4pP/+R/S/9VQzf/SEI9/8TBvf/v7On/7+zp/+/s6f/u6+j/ + hoJ9/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9pZF7/5eLf/+/s6f/v7On/ + 7+zp/+Hd2v9gW1X/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/ + e1M8//qITv//ik///4pP//+KT/+eYUH/QDo0/0A6NP9AOjT/QDo0/0Q8Nf/BcEb//4pP//+KT///ik// + 8YRN/2RJOf9AOjT/QDo0/0A6NP9AOjT/Sz82/9Z5Sf//ik///4pP//+KT//kf0v/VUM3/0hCPf/Ewb3/ + 7+zp/+/s6f/v7On/7uvo/4aCff9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjX/ + joqF/+3q5//v7On/7+zp/+/s6f/U0c3/U01H/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTg + QDo0/0A6NP9AOjT/QDo0/3tTPP/6iE7//4pP//+KT///ik//nmFB/0A6NP9AOjT/QDo0/0A6NP9EPDX/ + wXBG//+KT///ik///4pP//GETf9kSTn/QDo0/0A6NP9AOjT/QDo0/0s/Nv/WeUn//4pP//+KT///ik// + 5H9L/1VDN/9IQj3/xMG9/+/s6f/v7On/7+zp/+7r6P+Ggn3/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/TklD/8bCv//v7On/7+zp/+/s6f/v7On/u7i0/0ZAOv9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP97Uzz/+ohO//+KT///ik///4pP/55hQf9AOjT/ + QDo0/0A6NP9AOjT/RDw1/8FwRv//ik///4pP//+KT//xhE3/ZEk5/0A6NP9AOjT/QDo0/0A6NP9LPzb/ + 1nlJ//+KT///ik///4pP/+R/S/9VQzf/SEI9/8TBvf/v7On/7+zp/+/s6f/u6+j/hoJ9/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/R0E8/5eSjv/q5+T/7+zp/+/s6f/v7On/7ern/42JhP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/e1M8//qITv//ik// + /4pP//+KT/+eYUH/QDo0/0A6NP9AOjT/QDo0/0Q8Nf/BcEb//4pP//+KT///ik//8YRN/2RJOf9AOjT/ + QDo0/0A6NP9AOjT/Sz82/9Z5Sf//ik///4pP//+KT//kf0v/VUM3/0hCPf/Ewb3/7+zp/+/s6f/v7On/ + 7uvo/4aCff9AOzX/QDs1/0E7Nf9BOzX/QTs2/0U/Of9PSUP/a2Zh/6yoo//n5OD/7+zp/+/s6f/v7On/ + 7+zp/87Lx/9XUUz/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/3tTPP/6iE7//4pP//+KT///ik//nmFB/0A6NP9AOjT/QDo0/0A6NP9EPDX/wXBG//+KT///ik// + /4pP//GETf9kSTn/QDo0/0A6NP9AOjT/QDo0/0s/Nv/WeUn//4pP//+KT///ik//5H9L/1VDN/9IQj3/ + xMG9/+/s6f/v7On/7+zp/+7r6P+/vLj/oJuX/6Cbl/+gm5f/o5+b/6qmov+5trL/zsvH/+Th3v/u6+j/ + 7+zp/+/s6f/v7On/7+zp/9fT0P9ybWj/QTs1/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPf + Pjo04EA6NP9AOjT/QDo0/0A6NP97Uzz/+ohO//+KT///ik///4pP/55hQf9AOjT/QDo0/0A6NP9AOjT/ + RDw1/8FwRv//ik///4pP//+KT//xhE3/ZEk5/0A6NP9AOjT/QDo0/0A6NP9LPzb/1nlJ//+KT///ik// + /4pP/+R/S/9VQzf/SEI9/8TBvf/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/9LPy/9sZ2H/Qjw2/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/e1M8//qITv//ik///4pP//+KT/+eYUH/ + QDo0/0A6NP9AOjT/QDo0/0Q8Nf/BcEb//4pP//+KT///ik//8YRN/2RJOf9AOjT/QDo0/0A6NP9AOjT/ + TkA2/9p6Sv//ik///4pP//+KT//ifkv/VEI3/0hCPf/Ewb3/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/j4N3/qqai/1pVT/9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/3tTPP/6iE7/ + /4pP//+KT///ik//nmFB/0A6NP9AOjT/QDo0/0A6NP9EPDX/wXBG//+KT///ik///4pP//GETf9kSTn/ + QDo0/0A6NP9AOjT/QDo0/2FIOf/rgkz//4pP//+KT///ik//23tK/09ANv9IQj3/xMG9/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+7r6P/IxcH/X1lU/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP97Uzz/+ohO//+KT///ik///4pP/6BiQf9EOzT/RDs0/0Q7NP9EOzT/SD01/8JwRv//ik// + /4pP//+KT//xhE3/Z0o5/0Q7NP9EOzT/Rjw1/1hEN/+xaUT//YlP//+KT///ik///4pP/8t0R/9IPTX/ + SEI9/8TBvf/v7On/7+zp/+/s6f/v7On/1NHO/8O/u//Dv7v/w7+7/8O/u//Dv7v/w7+7/8O/vP/HxMD/ + 08/M/+Th3v/u6+j/7+zp/+/s6f/v7On/7uvo/7i0sP9LRT//QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/e1M8//qITv//ik///4pP//+KT//ffEr/v29G/79vRv+/b0b/ + v29G/8FwRv/qgUz//4pP//+KT///ik//+ohO/8t0R/+/b0b/v29G/8dyR//ifkv//IhP//+KT///ik// + /4pP//6KT/+kZEL/QTo0/0hCPf/Ewb3/7+zp/+/s6f/v7On/7uvo/4uHgv9IQjz/SEI8/0hCPP9IQjz/ + SEI8/0hCPP9IQjz/SkQ+/1FMRv9sZmH/vbm1/+7r6P/v7On/7+zp/+/s6f/n5OH/dXBr/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/3tTPP/6iE7//4pP//+KT///ik// + /4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik// + /4pP//+KT///ik///4pP//+KT//pgUz/Zko5/0A6NP9IQj3/xMG9/+/s6f/v7On/7+zp/+7r6P+Ggn3/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/11YUv/X1ND/7+zp/+/s6f/v7On/ + 7+zp/6ahnf9CPDb/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP97Uzz/ + +ohO//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik// + /4pP//+KT///ik///4pP//+KT///ik///4pP//+KT//vg03/i1k+/0M7NP9AOjT/SEI9/8TBvf/v7On/ + 7+zp/+/s6f/u6+j/hoJ9/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9EPjj/ + tbGt/+/s6f/v7On/7+zp/+/s6f/AvLj/R0E7/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/ + QDo0/0A6NP9AOjT/dlE7//WGTf/9iU///YlP//2JT//9iU///YlP//2JT//9iU///YlP//2JT//9iU// + /YlP//2JT//9iU///YlP//2JT//9iU///YlP//yJT//7iE7/+IdO/++DTf/KdEf/eVI8/0Q8NP9AOjT/ + QDo0/0hCPf/Ewb3/7+zp/+/s6f/v7On/7uvo/4aCff9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QTs2/6qmov/v7On/7+zp/+/s6f/v7On/x8PA/0lEPv9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0w/Nv9/VD3/iFg+/4hYPv+IWD7/iFg+/4hYPv+IWD7/ + iFg+/4hYPv+IWD7/iFg+/4hYPv+IWD7/iFg+/4hYPv+IWD7/iFg+/4dYPv+CVj3/fVQ9/3VQO/9jSTn/ + Sz41/0A6NP9AOjT/QDo0/0A6NP9IQj3/xMG9/+/s6f/v7On/7+zp/+7r6P+Ggn3/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0ZAOv+6trL/7+zp/+/s6f/v7On/7+zp/8K+uv9HQjz/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/SEI9/8TBvf/v7On/7+zp/+/s6f/u6+j/ + hoJ9/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9nYlz/3NnW/+/s6f/v7On/ + 7+zp/+/s6f+qpqL/Qjw2/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0hCPf/Ewb3/ + 7+zp/+/s6f/v7On/7uvo/5iVkP9fWVT/X1lU/19ZVP9fWVT/X1lU/19ZVP9fWVT/YVxX/2xmYf+Ig37/ + zcnG/+7r6P/v7On/7+zp/+/s6f/q5uP/fHdy/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTg + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9IQj3/xMG9/+/s6f/v7On/7+zp/+/s6f/m4+D/4N3a/+Dd2v/g3dr/4N3a/+Dd2v/g3dr/ + 4N3a/+Lf2//n5OH/7ern/+/s6f/v7On/7+zp/+/s6f/v7On/xcG9/09KRP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/SEI9/8TBvf/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/29jU/29qZf9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0hCPf/Ewb3/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/t6uf/ + z8zI/3Vwa/9CPDb/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9GQDv/ + t7Sv/+rn5P/q5+T/6ufk/+rn5P/q5+T/6ufk/+rn5P/q5+T/6ufk/+rn5P/q5+T/6ufj/+nl4v/m4+D/ + 4d3a/9TRzv+8ubX/jomE/1dSTP9BOzX/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPf + Pjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/1pVT/91cGv/dXBr/3Vwa/91cGv/dXBr/3Vwa/91cGv/dXBr/3Vwa/91cGv/ + dXBr/3NtaP9vaWT/amVg/2BbVf9TTUj/R0E7/0A6Nf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98/ODLdQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODTcPjk0zEA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDgzyz86NKFAOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5M59COTNV + QDoy9kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/z86NPU/OTNUQzU1E0A5NLpAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8/ODS5ODg4EgAAAABAODQ/Pzg04UA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+OjTgQTk1PgAAAAAAAAAAVVVVAz85M1U/ODTh + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+OjTgPzkzVFVVAAMAAAAA + AAAAAAAAAABVVVUDQDg0P0A5NLpAOjL2QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6MvY/ODS5 + QTk1PlVVVQMAAAAAAAAAAPDw8BIAAAAAAAAAAAAAAABDNTUTPzkzVT86NKE+OTTMPzgy3T46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA/ODLd + Pjk0zD86NKE/OTNVQzU1EwAAAAAAAAAAAAAAAAAAAADwAAAAAAAAD8AAAAAAAAADgAAAAAAAAAGAAAAA + AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAYAAAAAAAAABwAAAAAAAAANwAAAA + AAAADygAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoqKgY9OTU+ + QDk0lz45M8w+ODTcQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3j44NNxAODPLQDk0lz46Mj0qKioGAAAAAAAAAAAAAAAA + Ojo6DUE7NX0/OjTpQDo0/kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/j86M+k/OTN8 + Ojo6DQAAAABVKioGQDg0fkA6MvZAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjL2PzkzfCoqKgZBOTU+QDg06kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pzoz6T46Nj0/OTSYQDo0/kA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/kA5NJc/OTTNQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A4M8s/ODLd + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/z44NNxAOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0E6NP9BOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QTo0/0E6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9BOjT/ + QTo0/0A6NP9AOjT/QDo0/0E7Nf9BOzX/QTs1/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9BOzX/QTs1/0E7Nf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9BOjT/ + f1Q9/6xnQ/+sZ0P/jFo//0Q8Nf9AOjT/QDo0/0I7NP+EVj7/rGdD/6xnQ/+KWT7/Qzw1/0A6NP9AOjT/ + QDo0/3dRPP+sZ0P/rGdD/5RdQP9IPTX/W1ZQ/5+alv+jn5v/op6Z/2tlYP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/15ZVP+gnJf/o5+b/6Oemv9uaWT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9FPDX/xHFH//+KT///ik//2HpK/00/Nv9AOjT/QDo0/0c9Nf/LdUj//4pP//+KT//UeEn/ + Sz82/0A6NP9AOjT/Qjs0/7ZrRf//ik///4pP/+N/S/9WQzf/f3p1/+3q5//v7On/7+zp/56alf9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/5KOif/u6+j/7+zp/+7r6P+MiIP/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/xXFH//+KT///ik//2XpK/00/Nv9AOjT/QDo0/0c9Nf/MdUj/ + /4pP//+KT//VeEn/Sz82/0A6NP9AOjT/Qjs0/7dsRf//ik///4pP/+R/S/9WQzf/gHt2/+3q5//v7On/ + 7+zp/5+blv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QTs1/6Whnf/v7On/7+zp/+rn5P90b2r/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/xXFH//+KT///ik//2XpK/00/Nv9AOjT/ + QDo0/0c9Nf/MdUj//4pP//+KT//VeEn/Sz82/0A6NP9AOjT/Qjs0/7dsRf//ik///4pP/+R/S/9WQzf/ + gHt2/+3q5//v7On/7+zp/5+blv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Qz03/7SwrP/v7On/ + 7+zp/+fk4P9rZWD/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/xXFH//+KT///ik// + 2XpK/00/Nv9AOjT/QDo0/0c9Nf/MdUj//4pP//+KT//VeEn/Sz82/0A6NP9AOjT/Qjs0/7dsRf//ik// + /4pP/+R/S/9WQzf/gHt2/+3q5//v7On/7+zp/5+blv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + SUM9/8XCvv/v7On/7+zp/+Lf2/9hXFb/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/ + xXFH//+KT///ik//2XpK/00/Nv9AOjT/QDo0/0c9Nf/MdUj//4pP//+KT//VeEn/Sz82/0A6NP9AOjT/ + Qjs0/7dsRf//ik///4pP/+R/S/9WQzf/gHt2/+3q5//v7On/7+zp/5+blv9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/XFZR/9zY1f/v7On/7+zp/9fU0P9VT0r/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9FPDX/xXFH//+KT///ik//2XpK/00/Nv9AOjT/QDo0/0c9Nf/MdUj//4pP//+KT//VeEn/ + Sz82/0A6NP9AOjT/Qjs0/7dsRf//ik///4pP/+R/S/9WQzf/gHt2/+3q5//v7On/7+zp/5+blv9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9CPDb/ko2J/+zp5v/v7On/7+zp/7+7t/9HQjz/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/xXFH//+KT///ik//2XpK/00/Nv9AOjT/QDo0/0c9Nf/MdUj/ + /4pP//+KT//VeEn/Sz82/0A6NP9AOjT/Qjs0/7dsRf//ik///4pP/+R/S/9WQzf/gHt2/+3q5//v7On/ + 7+zp/5+blv9AOjT/QDo0/0A6NP9AOjT/Qjw2/01HQf+BfHf/3drX/+/s6f/v7On/6+jl/4mFgP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/xXFH//+KT///ik//2XpK/00/Nv9AOjT/ + QDo0/0c9Nf/MdUj//4pP//+KT//VeEn/Sz82/0A6NP9AOjT/Qjs0/7dsRf//ik///4pP/+R/S/9WQzf/ + gHt2/+3q5//v7On/7+zp/8C9uf+JhYD/iYWA/4uHgv+Uj4r/qKSg/8nFwf/n5OH/7+zp/+/s6f/s6OX/ + sq6q/05IQv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/xXFH//+KT///ik// + 2XpK/00/Nv9AOjT/QDo0/0c9Nf/MdUj//4pP//+KT//VeEn/Sz82/0A6NP9AOjT/Qjs0/7dsRf//ik// + /4pP/+R/S/9WQzf/gHt2/+3q5//v7On/7+zp/+/s6f/u6+j/7uvo/+7r6P/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/Dv7v/WVRO/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/ + xXFH//+KT///ik//2XpK/00/Nv9AOjT/QDo0/0c9Nf/MdUj//4pP//+KT//VeEn/Sz82/0A6NP9AOjT/ + RTw1/8RxR///ik///4pP/+F9S/9TQjf/gHt2/+3q5//v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/o5eL/tbGt/1dSTP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9FPDX/xXFH//+KT///ik//2ntK/1NCN/9HPTX/Rz01/05ANv/Odkj//4pP//+KT//WeUn/ + UUI3/0c9Nf9LPzb/d1E8/+uCTP//ik///4pP/9V4Sf9LPzb/gHt2/+3q5//v7On/7+zp/97a1//JxsL/ + ycbC/8nGwv/JxsL/ycbC/8zIxf/X09D/6ebi/+/s6f/v7On/7uvo/7OvrP9KRD7/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/xXFH//+KT///ik//9YZO/892SP/LdEj/y3RI/811SP/xhE3/ + /4pP//+KT//0hU3/znVI/8t0SP/UeEn/8IRN//+KT///ik///opP/69oQ/9COzT/gHt2/+3q5//v7On/ + 7+zp/6Sgm/9LRT//S0U//0tFP/9LRT//S0U//0xGQP9VT0r/g396/+Dc2f/v7On/7+zp/+bj4P9ybWj/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9FPDX/xXFH//+KT///ik///4pP//+KT///ik// + /4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik//4n5L/2ZKOf9AOjT/ + gHt2/+3q5//v7On/7+zp/5+blv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Qz44/6uno//v7On/ + 7+zp/+/s6f+alZH/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9EPDX/vW5G//qITv/6iE7/ + +ohO//qITv/6iE7/+ohO//qITv/6iE7/+ohO//qITv/6iE7/+ohO//qITv/5h07/94ZO/+6DTf/Ic0f/ + bk06/0E7NP9AOjT/gHt2/+3q5//v7On/7+zp/5+blv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/5KOif/v7On/7+zp/+/s6f+ppaH/QTs1/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9BOjT/ + YEc4/3pSPP96Ujz/elI8/3pSPP96Ujz/elI8/3pSPP96Ujz/elI8/3pSPP96Ujz/elI8/3lSPP91UDz/ + cE47/2JIOf9KPjX/QDo0/0A6NP9AOjT/gHt2/+3q5//v7On/7+zp/5+blv9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/Qjw2/6Whnf/v7On/7+zp/+/s6f+jnpr/QTs1/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/gHt2/+3q5//v7On/7+zp/6Ofmv9JQz3/ + SUM9/0lDPf9JQz3/SUM9/0pEPv9QSkX/dnBs/9rW0//v7On/7+zp/+zp5v+CfXj/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/gHt2/+3q5//v7On/ + 7+zp/9zZ1v/Gwr//xsK//8bCv//Gwr//xsK//8jEwf/Rzsr/5OHe/+/s6f/v7On/7+zp/8/MyP9VUEr/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + gHt2/+3q5//v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 3tvY/3p1cP9BOzX/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/fnl0/+zp5v/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+7r6P/u6uf/ + 6ufk/9/c2f+9ubb/cm1o/0M9N/9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/VE9J/4yIg/+RjIj/kYyI/5GMiP+RjIj/kYyI/5GMiP+RjIj/ + kIuH/4yHgv+EgHv/dXBr/19aVP9JQz3/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt4/ODLd + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/z44NNw/OTTNQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/z45NMw/OjOZQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/kA5NJdAODQ/QDg06kA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pzo06T05NT5VKioGQDo0f0A4MvdAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjL2PjoyfioqKgYAAAAA + NjY2DkA6NH9AODTqQDo0/kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/kA4NOo+OjR+ + Ojo6DQAAAAD///8IAAAAAFUqKgZAODQ/PzozmT86NM0/ODLdQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz3z84Mt0/OjTN + Pzo0mEE5NT4qKioGAAAAAAAAAADAAAAAAAMAAIAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAQAAQAAAAAADAAAoAAAAKAAAAFAAAAABACAA + AAAAAEAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJCPDcuQDozjz45NMw/ODLdQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz3z84Mt1AODPLQDkzj0I3MS4AAAAC + AAAAAH8AAAI+OjROQDkz2kA6NP5AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP4/OTLZPzk1TH8AAAJBOzYvQDoz2kA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/z85MtlCNzEuPzo1kEA6NP5AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT+ + QDozjz45NMxAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A4M8tAOTLeQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8/OTLdPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/TD82/2ZKOf9nSjn/UUE2/0A6NP9AOjT/ + QTo0/1pFN/9oSjn/Y0k5/0Y9Nf9AOjT/QDo0/0M7NP9gRzj/aEo5/19HOP9DOzT/UkxG/2RfWf9kX1n/ + UUxG/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0E7Nf9YU03/ZF9a/2ReWf9OSEL/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/4lZP//xhE3/8oVN/59hQf9AOjT/QDo0/0c9Nf/EcUb/84VN/+iATP9oSzr/ + QDo0/0A6NP9XQzf/3HtK//OFTf/XeUn/VEM4/6GdmP/k4N3/5ODd/6Ccl/9BOzX/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9KRT//wLy4/+Th3f/i39v/gHt2/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP+TXUD/ + /opP//+KT/+qZkP/QDo0/0A6NP9JPjX/0ndI//+KT//2hk7/bk07/0A6NP9AOjT/W0U4/+qBTP//ik// + 5X9L/1dFOf+sqKT/7+zp/+/s6f+rp6P/QTs1/0A6NP9AOjT/QDo0/0A6NP9AOjT/VE9J/9fU0f/v7On/ + 6ebj/3BqZf9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/k11A//6KT///ik//qmZD/0A6NP9AOjT/ + ST41/9J3SP//ik//9oZO/25NO/9AOjT/QDo0/1tFOP/qgUz//4pP/+V/S/9XRTn/rKik/+/s6f/v7On/ + q6ej/0E7Nf9AOjT/QDo0/0A6NP9AOjT/QDo0/15YU//f3Nn/7+zp/+Xi3v9mYVv/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/5NdQP/+ik///4pP/6pmQ/9AOjT/QDo0/0k+Nf/Sd0j//4pP//aGTv9uTTv/ + QDo0/0A6NP9bRTj/6oFM//+KT//lf0v/V0U5/6yopP/v7On/7+zp/6uno/9BOzX/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9vamX/6OXi/+/s6f/e29j/XFdR/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP+TXUD/ + /opP//+KT/+qZkP/QDo0/0A6NP9JPjX/0ndI//+KT//2hk7/bk07/0A6NP9AOjT/W0U4/+qBTP//ik// + 5X9L/1dFOf+sqKT/7+zp/+/s6f+rp6P/QTs1/0A6NP9AOjT/QDo0/0A6NP9CPDb/m5eT/+7r6P/v7On/ + z8vI/09JQ/9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/k11A//6KT///ik//qmZD/0A6NP9AOjT/ + ST41/9J3SP//ik//9oZO/25NO/9AOjT/QDo0/1tFOP/qgUz//4pP/+V/S/9XRTn/rKik/+/s6f/v7On/ + q6ej/0E7Nf9AOjT/QDo0/0A6NP9FPzn/cWxn/9rX0//v7On/7uvo/6ejn/9DPTf/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/5NdQP/+ik///4pP/6pmQ/9AOjT/QDo0/0k+Nf/Sd0j//4pP//aGTv9uTTv/ + QDo0/0A6NP9bRTj/6oFM//+KT//lf0v/V0U5/6yopP/v7On/7+zp/8O/vP9/enX/fnl1/4N+ef+SjYn/ + tLCs/9/c2f/v7On/7uvo/87Kxv9gWlX/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP+TXUD/ + /opP//+KT/+qZkP/QDo0/0A6NP9JPjX/0ndI//+KT//2hk7/bk07/0A6NP9AOjT/XEU4/+qBTP//ik// + 5X9L/1dFOf+sqKT/7+zp/+/s6f/u6+j/7ern/+3q5//t6uf/7+zp/+/s6f/v7On/7+zp/+Pg3f+BfHf/ + Qz03/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/k11A//6KT///ik//qmZD/0A6NP9AOjT/ + ST41/9J3SP//ik//9oZO/25NO/9AOjT/QDo0/25NOv/zhU3//4pP/+B9Sv9TQzj/rKik/+/s6f/v7On/ + 7uvo/+3q5//t6uf/7ern/+3q5//u6+j/7+zp/+/s6f/u6+j/2tfU/314c/9CPDb/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/5NdQP/+ik///4pP/8VyR/9+VD3/flQ9/4RWPf/gfUr//4pP//mHTv+dYUH/ + flQ9/4tZP//Pdkj//opP//+KT//MdUj/Sj83/6yopP/v7On/7+zp/8XBvv+Dfnr/gn55/4J+ef+Cfnn/ + hYF8/5mVkP/PzMj/7uvo/+/s6f/V0c7/WlVP/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP+TXUD/ + /opP//+KT//9iU//+4hO//uITv/7iE7//opP//+KT///ik///IlP//uITv/9iU///4pP//+KT//3h07/ + jFo//0I7Nv+sqKT/7+zp/+/s6f+rp6P/QTs1/0A6NP9AOjT/QDo0/0A6NP9BOzX/aWRf/+Dd2v/v7On/ + 7enm/4N/ev9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/jVo///aHTv/4h07/+IdO//iHTv/4h07/ + +IdO//iHTv/4h07/+IdO//iHTv/4h07/94ZO//OFTf/ifkv/mF9A/0k+Nf9BOzb/rKik/+/s6f/v7On/ + q6ej/0E7Nf9AOjT/QDo0/0A6NP9AOjT/QDo0/05JQ//PzMj/7+zp/+/s6f+YlI//QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/1FBNv9yTzv/c087/3NPO/9zTzv/c087/3NPO/9zTzv/c087/3NPO/9zTzv/ + c087/29OO/9pSzr/VkM3/0M7NP9AOjT/QTs2/6yopP/v7On/7+zp/6uno/9BOzX/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9bVU//2tfT/+/s6f/u6+j/kYyH/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0E7Nv+sqKT/7+zp/+/s6f+7t7P/aWRf/2ljXv9pY17/aWNe/2plX/93cm3/tLCs/+3q5//v7On/ + 5eLf/25pY/9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9BOzb/rKik/+/s6f/v7On/ + 6+jl/+bj4P/m4+D/5uPg/+bj4P/n4+D/6ufk/+/s6f/v7On/7ern/7Gtqf9JQz3/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QTs2/6uno//v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/t6uf/4d3a/66qpv9VUEr/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6Nf9ybWj/n5uX/6Cbl/+gm5f/oJuX/6Cbl/+gm5f/n5uX/5yXk/+Uj4v/gXx3/2NeWP9HQTv/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz30A5Mt5AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z85Mt0/OjTNQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8+OTTMPzo0kUA6NP5AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT+ + QDozjz86NTBAOjTbQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz2kI8MS5/AAACQDozT0A6M9pAOjT+ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT+QDoz2kE6NE5/AAAC1NTUBgAAAAJBOzYvPzo0kT86NM1AOTLePjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04EA5Mt4/OTTNPzozkEE7Ni8AAAAC + AAAAAIAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAKAAAACAAAABAAAAAAQAgAAAAAACAEAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAA/NjYcQDo0g0A4M8s/ODLdQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3j84Mt1AOjLK + QDoxgj82NhwAAAAAPT00HUA5M7c+ODL8QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP8+ODL8QDkytj82Nhw/OTSEPjgy/EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODL8QDo0gj45NMxAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjLKQDky3kA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z84Mt1AOjPfQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDky3kA6M99AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOTLe + QDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDky3kA6M99AOjT/QDo0/0Q8Nf9EPDX/QTo0/0A6NP9AOjT/Qzs0/0Q8Nf9COzT/ + QDo0/0A6NP9BOjT/RDw1/0M7NP9AOjT/Qz03/0Q+OP9CPDb/QDo0/0A6NP9AOjT/QDo0/0A6NP9BOzX/ + RD44/0Q+OP9BOzX/QDo0/0A6NP9AOTLeQDoz30A6NP9YRDj/uW1F/75uRv9hSDj/QDo0/0c9Nf+jZEL/ + xHFH/4RWPv9AOjT/QDo0/3RPO//DcUb/r2hD/1VIPv+gm5f/ubWx/42JhP9CPDb/QDo0/0A6NP9AOjT/ + QDo0/2JcV/+1sa3/t7Ov/2hiXf9AOjT/QDo0/0A5Mt5AOjPfQDo0/2hLOv/zhU3/+YdO/3VQO/9AOjT/ + TD82/9Z5Sf//ik//qmZD/0A6NP9AOjT/klxA//6KT//lf0v/ZVJG/9DMyf/v7On/t7Ov/0M+OP9AOjT/ + QDo0/0A6NP9AOjT/g356/+3q5//n5OH/bGdi/0A6NP9AOjT/QDky3kA6M99AOjT/aEs6//OFTf/5h07/ + dVA7/0A6NP9MPzb/1nlJ//+KT/+qZkP/QDo0/0A6NP+SXED//opP/+V/S/9lUkb/0MzJ/+/s6f+3s6// + Qz44/0A6NP9AOjT/QDo0/0A6NP+Uj4v/7+zp/+Lf3P9hXFf/QDo0/0A6NP9AOTLeQDoz30A6NP9oSzr/ + 84VN//mHTv91UDv/QDo0/0w/Nv/WeUn//4pP/6pmQ/9AOjT/QDo0/5JcQP/+ik//5X9L/2VSRv/QzMn/ + 7+zp/7ezr/9DPjj/QDo0/0A6NP9AOjT/RD44/7CsqP/v7On/2dbT/1dSTP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/2hLOv/zhU3/+YdO/3VQO/9AOjT/TD82/9Z5Sf//ik//qmZD/0A6NP9AOjT/klxA//6KT//lf0v/ + ZVJG/9DMyf/v7On/t7Ov/0M+OP9AOjT/QDo0/0E7Nf9oYl3/29jU/+/s6f/AvLn/SEM9/0A6NP9AOjT/ + QDky3kA6M99AOjT/aEs6//OFTf/5h07/dVA7/0A6NP9MPzb/1nlJ//+KT/+qZkP/QDo0/0A6NP+SXED/ + /opP/+V/S/9lUkb/0MzJ/+/s6f/IxMD/dnJt/3Vwa/9+eXT/nJeT/9TQzf/u6+j/4N3Z/3p1cP9AOjT/ + QDo0/0A6NP9AOTLeQDoz30A6NP9oSzr/84VN//mHTv91UDv/QDo0/0w/Nv/WeUn//4pP/6pmQ/9AOjT/ + QDo0/5VdQP/+ik//5H9L/2RSRv/QzMn/7+zp/+3q5//q5+T/6+fk/+zp5v/v7On/7+zp/+7r6P+3s6// + UUxG/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/2hLOv/zhU3/+YdO/31TPP9LPzb/VkM3/9h6Sf//ik// + r2hE/0s/Nv9VQzf/vm5G//+KT//dfEr/Xk9F/9DMyf/v7On/5eLe/9DMyf/Py8j/z8vI/9DNyf/c2NX/ + 7ern/+vo5f+sqKT/SUM9/0A6NP9AOjT/QDky3kA6M99AOjT/aEs6//OFTf/+iU//4X1L/9V4Sf/Yekn/ + 9oZO//+KT//sgkz/1nlJ/+B9S//6iE7//opP/7ZrRf9TSkP/0MzJ/+/s6f+7t7T/UUxG/05IQv9OSEL/ + T0lD/1xXUf+1sa3/7+zp/+Xi3/9tZ2L/QDo0/0A6NP9AOTLeQDoz30A6NP9lSTn/6YFM//WGTv/1hk7/ + 9YZO//WGTv/1hk7/9YZO//WGTv/1hk7/9IVN/+2DTP/DcUb/XUY4/05IQ//QzMn/7+zp/7ezr/9DPjj/ + QDo0/0A6NP9AOjT/QDo0/396df/s6eb/7uvo/4WBfP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0c9Nf9oSzr/ + bU06/21NOv9tTTr/bU06/21NOv9tTTr/bU06/21NOv9qSzr/YEg5/0o+Nf9AOjT/TkhD/9DMyf/v7On/ + t7Ov/0M+OP9AOjT/QDo0/0A6NP9EPjj/lZCM/+7r6P/s6eb/fnl1/0A6NP9AOjT/QDky3kA6M99AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9OSEP/ + 0MzJ/+/s6f/V0s7/oJyY/5+alv+fmpb/oJyX/7Gtqf/g3dn/7+zp/9jU0f9cVlH/QDo0/0A6NP9AOTLe + QDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/05IQ//QzMn/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+7r6P/c2dX/g396/0I8Nv9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/R0E7/5aSjf+uqqb/rqqm/66qpv+uqqb/rqqm/6uno/+jn5v/i4eC/2JcV/9DPTf/ + QDo0/0A6NP9AOjT/QDky3kA6M99AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QTs1/0I8Nv9CPDb/Qjw2/0I8Nv9CPDb/QTs1/0E7Nf9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOTLeQDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDky3kA5Mt5AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8/ODLdPjk0zEA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A4M8s/OTSE + Pjgy/EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODL8 + QDo0gz09NB0+OjS4Pjgy/EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + Pjgy/EA6M7c/NjYc////Az09NB0/OTSEPjk0zEA5Mt5AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDky3j45NMxAOjSDPT00HQAAAACAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASgAAAAYAAAAMAAAAAEAIAAAAAAAYAkAAAAAAAAAAAAA + AAAAAAAAAABFLi4LPzszbD86NMlAOTLeQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A5Mt4+OTTIQDk0a0UuLgs/OjNtPzo09UA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/Pjk09EA5NGs/OjTJQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z45NMhAOjPf + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5M94+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQzs0/2xMOv9vTjv/RTw1/0M7NP9uTTr/b006/0Q8Nf9COzT/ + a0w6/3FPO/9RR0D/cm1o/2VgW/9CPDb/QDo0/0A6NP9BOzX/Y11Y/3Nuaf9OSUP/QDo0/0A6M98+OjTg + Sz82/9R3SP/be0r/UUE2/01ANv/XeUn/2npJ/09BNv9JPjX/z3VI/+F+Sv98al//4t7b/725tf9HQTv/ + QDo0/0A6NP9GQDr/vLi1/+He2/9nYVz/QDo0/0A6M98+OjTgTD82/9h5Sf/gfUv/UkE2/05ANv/be0r/ + 3nxK/1BBNv9KPjX/03dJ/+aAS/9/bGH/5uPg/8G9uf9HQTv/QDo0/0A6NP9NR0H/zcnG/9/c2P9dWFL/ + QDo0/0A6M98+OjTgTD82/9h5Sf/gfUv/UkE2/05ANv/be0r/3nxK/1BBNv9KPjX/03dJ/+aAS/9/bGH/ + 5uPg/8G9uf9HQTv/QDo0/0A6NP9oYl3/4d7b/9LOy/9RS0X/QDo0/0A6M98+OjTgTD82/9h5Sf/gfUv/ + UkE2/05ANv/be0r/3nxK/1BBNv9KPjX/03dJ/+aAS/9/bGH/5uPg/8zJxf9xa2b/bmlk/4R/ev/Hw8D/ + 6ebj/5qWkf9DPTf/QDo0/0A6M98+OjTgTD82/9h5Sf/gfUv/UkE2/05ANv/be0r/3nxK/1BBNv9MPzb/ + 13lJ/+V/S/9+bGH/5uPg/+3q5//n5OH/6OXi/+zp5v/v7On/39zY/3Zwa/9BOzX/QDo0/0A6M98+OjTg + TD82/9h5Sf/sgk3/lV1A/5NdQP/pgUz/64FM/5VdQP+lZEL/9IVN/9R4Sf91aF//5uPg/9XRzv+Piob/ + i4aC/42Ig/+opJ//5uLf/9HOyv9XUkz/QDo0/0A6M98+OjTgSz82/811SP/yhU3/8YRN//GETf/yhU3/ + 8oVN//GETf/whE3/4H1L/4JWPf9pY17/5uPg/8G9uf9HQTv/QDo0/0A6NP9JQz3/w8C8/+rn5P90b2r/ + QDo0/0A6M98+OjTgQjs0/15GOP9nSjn/Z0o5/2dKOf9nSjn/Z0o5/2dKOf9kSTn/VUM3/0I7NP9oY17/ + 5uPg/8XBvf9VT0n/TklD/09JQ/9iXFf/0c3K/+fk4f9uaGP/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9oY17/5uPg/+fk4P/Rzsr/0MzJ/9HNyv/c2NX/ + 7Onm/7u3tP9NR0L/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9aVU//tLCs/7y4tP+8uLT/vLi0/7q2sv+xran/kYyH/1VQSv9AOjT/QDo0/0A6M98+OjTg + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9BOzX/RD44/0U/Of9FPzn/ + RT85/0Q+Of9CPTf/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M99AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5M95AOjLKQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/z86NMlAOTJuPzo09UA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pzo09T87M2xiTk4N + QDkybkA6MspAOjPfPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04EA6M98/OjTJPzozbUVFLgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAoAAAAFAAAACgAAAABACAAAAAAAJAGAAAAAAAAAAAAAAAAAAAAAAAAPzc3ID85NJw+ODLY + QDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt4+ODLY + QDk0m0E5MR8/OjKdPzk0/UA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8/OTT9QDk0mz85MtlAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODLYQDoz30A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDky3kA6M99AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOTLeQDoz31pFOP+jY0L/ + Xkc4/0g9Nf+XXkD/fVM9/0A6NP91UDv/nGBB/2teVv+emZX/XllT/0A6NP9AOjT/SUM9/5KNif+BfHf/ + Qjw2/0A5Mt5AOjPfcU47//KFTf95Ujz/UEE2/918Sv+xaUT/QTo0/6JjQv/mf0v/kX5z/+nl4v95dG// + QDo0/0A6NP9YUk3/2tfT/6ijn/9BOzX/QDky3kA6M99xTjv/8oVN/3lSPP9QQTb/3XxK/7FpRP9BOjT/ + omNC/+Z/S/+RfnP/6eXi/3l0b/9AOjT/QDo0/21oY//l4t//lZCM/0A6NP9AOTLeQDoz33FOO//yhU3/ + eVI8/1BBNv/dfEr/sWlE/0E6NP+iY0L/5n9L/5F+c//p5uP/k4+K/2hjXv94dG7/wb25/9zY1f9oY17/ + QDo0/0A5Mt5AOjPfcU47//KFTf96Uzz/UkI2/918Sv+yaUT/RTw0/6xnQ//kfkv/j31z/+vo5f/i39z/ + 3drX/+Lf3P/r6OX/ysfD/1pUT/9AOjT/QDky3kA6M99xTjv/9YZO/851SP+/b0b/8oVN/+J+S/+/b0b/ + 7IJM/8hzR/+DeXH/6ebj/5WQjP9pZF//amVg/4yIg//k4d3/o5+a/0I8Nv9AOTLeQDoz31xGOP+uaET/ + tGpE/7RqRP+0akT/tGpE/7NqRP+iY0L/YUg5/3p1cP/p5eL/eXRv/0E7Nf9BOzX/WVNO/9nV0v+7t7P/ + RT85/0A5Mt5AOjPfQDo0/0E6NP9BOjT/QTo0/0E6NP9BOjT/QTo0/0A6NP9AOjT/enVw/+rn5P+9urb/ + pqGd/6einv+/u7f/5+Th/5KNif9BOzX/QDky3kA6M99AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9pZF//vru3/8G9uv/Bvbr/wLy5/7ezr/+OiYT/TEZA/0A6NP9AOTLeQDoz30A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0I8Nv9GQTv/R0E7/0dBO/9GQDv/RD44/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDky3j85MtlAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODLYQDoznj85NP1AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + Pzk0/T85NJxDPDwiQDoznj85MtlAOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz3z85Mtk/OjKdPzc3IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAABAAAAAgAAAA + AQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAD47M0VAODTCPzgy3UA5Mt5AOTLeQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3kA5Mt4/ODLdPzozwT84NERAOTTDQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8/OjPBQDkz3kA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pzky3UA6M99AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfRj01/0c9Nf9BOjT/ + ST41/0M7NP9DOzT/ST41/0Y/Of9IQj3/QDs1/0A6NP9CPDb/SUQ+/0I8Nv9AOTLeQToz35VeQP+cYEH/ + TkA2/7ltRf9sTTr/Zko5/7xuRf+QgXf/rKik/0hCPP9AOjT/X1pU/7i1sf9bVU//QDky3kE6M9+taEP/ + tWtE/1NCN//ae0r/eVI8/3FOO//efEr/p5WK/8nGwv9KRT//QDo0/3hzbv/X09D/WVNN/0A5Mt5BOjPf + rWhD/7VrRP9TQjf/2ntK/3lSPP9xTjv/3nxK/6eViv/Rzsr/bGdi/29qZf+9ubX/ubWx/0lDPf9AOTLe + QToz361oQ/+7bkX/Ykg5/918Sv+FVz7/h1c+/958Sv+klIr/5+Tg/8vIxP/Oysf/4N3a/6qmov9HQjz/ + QDky3kE6M9+jZEL/435L/9J3Sf/pgUz/2XpK/9t7Sv+tZ0P/lo6I/83Kxv9bVlD/UkxH/4F8d//c2dX/ + Y15Z/0A5Mt5AOjPfU0I3/2JIOf9iSDn/Ykg5/2JIOf9eRjj/ST41/5CLh//U0c3/e3Zx/3Rvav+empX/ + 2dbS/15ZVP9AOTLeQDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP98d3P/xsK+/8K/u//Cvrr/ + u7ez/4N+ef9EPjj/QDky3kA6M99AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/RD44/0lDPf9JQz3/ + SUM9/0ZAOv9BOzX/QDo0/0A5Mt5AOTPeQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8/OTLdQDk0w0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDgzwkA9NUdAOTTDQDky3kA6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOTLeQDk0wz47M0UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/frmOptions.Designer.cs b/mRemoteV1/UI/Forms/frmOptions.Designer.cs index 58848d97d..7371c779d 100644 --- a/mRemoteV1/UI/Forms/frmOptions.Designer.cs +++ b/mRemoteV1/UI/Forms/frmOptions.Designer.cs @@ -1,6 +1,6 @@ namespace mRemoteNG.UI.Forms { - partial class frmOptions + partial class FrmOptions { /// /// Required designer variable. @@ -28,7 +28,7 @@ /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmOptions)); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmOptions)); this.pnlBottom = new System.Windows.Forms.Panel(); this.btnCancel = new mRemoteNG.UI.Controls.Base.NGButton(); this.btnOK = new mRemoteNG.UI.Controls.Base.NGButton(); @@ -135,7 +135,7 @@ this.PageName.ImageAspectName = "IconImage"; this.PageName.IsEditable = false; // - // frmOptions + // FrmOptions // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; @@ -146,11 +146,12 @@ this.Controls.Add(this.lstOptionPages); this.Controls.Add(this.splitter1); this.Controls.Add(this.pnlBottom); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; - this.Name = "frmOptions"; + this.Name = "FrmOptions"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "mRemoteNG Options"; diff --git a/mRemoteV1/UI/Forms/frmOptions.cs b/mRemoteV1/UI/Forms/frmOptions.cs index 5eb407000..25c2522f8 100644 --- a/mRemoteV1/UI/Forms/frmOptions.cs +++ b/mRemoteV1/UI/Forms/frmOptions.cs @@ -2,29 +2,28 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Drawing; using System.Linq; using System.Windows.Forms; namespace mRemoteNG.UI.Forms { - public partial class frmOptions : Form + public partial class FrmOptions : Form { private Dictionary _pages; - private ImageList _pageIconImageList; private readonly string _pageName; private readonly DisplayProperties _display = new DisplayProperties(); - public frmOptions() + public FrmOptions(): this(Language.strStartupExit) { - InitializeComponent(); - _pageName = Language.strStartupExit; } - public frmOptions(string pn) + public FrmOptions(string pn) { + Cursor.Current = Cursors.WaitCursor; + Application.DoEvents(); InitializeComponent(); _pageName = pn; + Cursor.Current = Cursors.Default; } private void frmOptions_Load(object sender, EventArgs e) @@ -89,10 +88,7 @@ namespace mRemoteNG.UI.Forms private object ImageGetter(object rowobject) { var page = rowobject as OptionsPage; - if (page == null) - return Resources.Help; - - return _display.ScaleImage(page.PageIcon); + return page?.PageIcon == null ? _display.ScaleImage(Resources.Help) : _display.ScaleImage(page.PageIcon); } private void SetInitiallyActivatedPage() diff --git a/mRemoteV1/UI/GraphicsUtilities/GdiPlusGraphicsProvider.cs b/mRemoteV1/UI/GraphicsUtilities/GdiPlusGraphicsProvider.cs new file mode 100644 index 000000000..d6fdc4812 --- /dev/null +++ b/mRemoteV1/UI/GraphicsUtilities/GdiPlusGraphicsProvider.cs @@ -0,0 +1,22 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace mRemoteNG.UI.GraphicsUtilities +{ + /// + /// Gets environment graphics information using the Windows GDI+ API. + /// + public class GdiPlusGraphicsProvider : IGraphicsProvider + { + // Dpi of a 'normal' definition screen + private const int BaselineDpi = 96; + + public SizeF GetResolutionScalingFactor() + { + using (var g = new Form().CreateGraphics()) + { + return new SizeF(g.DpiX / BaselineDpi, g.DpiY / BaselineDpi); + } + } + } +} diff --git a/mRemoteV1/UI/GraphicsUtilities/IGraphicsProvider.cs b/mRemoteV1/UI/GraphicsUtilities/IGraphicsProvider.cs new file mode 100644 index 000000000..918a5b7e4 --- /dev/null +++ b/mRemoteV1/UI/GraphicsUtilities/IGraphicsProvider.cs @@ -0,0 +1,9 @@ +using System.Drawing; + +namespace mRemoteNG.UI.GraphicsUtilities +{ + public interface IGraphicsProvider + { + SizeF GetResolutionScalingFactor(); + } +} diff --git a/mRemoteV1/UI/Menu/HelpMenu.cs b/mRemoteV1/UI/Menu/HelpMenu.cs index c343c08c7..74db6e2f5 100644 --- a/mRemoteV1/UI/Menu/HelpMenu.cs +++ b/mRemoteV1/UI/Menu/HelpMenu.cs @@ -1,8 +1,8 @@ using System; +using System.Diagnostics; using System.Windows.Forms; using mRemoteNG.App; using mRemoteNG.App.Info; -using mRemoteNG.Connection; namespace mRemoteNG.UI.Menu { @@ -122,7 +122,7 @@ namespace mRemoteNG.UI.Menu // // mMenInfoAbout // - _mMenInfoAbout.Image = Resources.mRemote; + _mMenInfoAbout.Image = Resources.mRemoteNG; _mMenInfoAbout.Name = "mMenInfoAbout"; _mMenInfoAbout.Size = new System.Drawing.Size(190, 22); _mMenInfoAbout.Text = Language.strMenuAbout; @@ -142,39 +142,19 @@ namespace mRemoteNG.UI.Menu } #region Info - private void mMenToolsUpdate_Click(object sender, EventArgs e) - { - Windows.Show(WindowType.Update); - } - private void mMenInfoHelp_Click(object sender, EventArgs e) - { - Windows.Show(WindowType.Help); - } + private void mMenToolsUpdate_Click(object sender, EventArgs e) => Windows.Show(WindowType.Update); - private void mMenInfoForum_Click(object sender, EventArgs e) - { - WebHelper.GoToUrl(GeneralAppInfo.UrlForum); - } + private void mMenInfoHelp_Click(object sender, EventArgs e) => Windows.Show(WindowType.Help); - private void mMenInfoBugReport_Click(object sender, EventArgs e) - { - WebHelper.GoToUrl(GeneralAppInfo.UrlBugs); - } + private void mMenInfoForum_Click(object sender, EventArgs e) => Process.Start(GeneralAppInfo.UrlForum); - private void mMenInfoWebsite_Click(object sender, EventArgs e) - { - WebHelper.GoToUrl(GeneralAppInfo.UrlHome); - } + private void mMenInfoBugReport_Click(object sender, EventArgs e) => Process.Start(GeneralAppInfo.UrlBugs); - private void mMenInfoDonate_Click(object sender, EventArgs e) - { - WebHelper.GoToUrl(GeneralAppInfo.UrlDonate); - } + private void mMenInfoWebsite_Click(object sender, EventArgs e) => Process.Start(GeneralAppInfo.UrlHome); - private void mMenInfoAbout_Click(object sender, EventArgs e) - { - Windows.Show(WindowType.About); - } + private void mMenInfoDonate_Click(object sender, EventArgs e) => Process.Start(GeneralAppInfo.UrlDonate); + + private void mMenInfoAbout_Click(object sender, EventArgs e) => Windows.Show(WindowType.About); #endregion } } \ No newline at end of file diff --git a/mRemoteV1/UI/Menu/MainFileMenu.cs b/mRemoteV1/UI/Menu/MainFileMenu.cs index 85e08c88c..e656e95cc 100644 --- a/mRemoteV1/UI/Menu/MainFileMenu.cs +++ b/mRemoteV1/UI/Menu/MainFileMenu.cs @@ -445,15 +445,13 @@ namespace mRemoteNG.UI.Menu if (Runtime.WindowList == null || Runtime.WindowList.Count == 0) return; foreach (BaseWindow window in Runtime.WindowList) { - var connectionWindow = window as ConnectionWindow; - if (connectionWindow == null) + if (!(window is ConnectionWindow connectionWindow)) return; var icList = new List(); foreach (Crownwood.Magic.Controls.TabPage tab in connectionWindow.TabController.TabPages) { - var tag = tab.Tag as InterfaceControl; - if (tag != null) + if (tab.Tag is InterfaceControl tag) { icList.Add(tag); } diff --git a/mRemoteV1/UI/Menu/ToolsMenu.cs b/mRemoteV1/UI/Menu/ToolsMenu.cs index 69627dddf..fb02d0fec 100644 --- a/mRemoteV1/UI/Menu/ToolsMenu.cs +++ b/mRemoteV1/UI/Menu/ToolsMenu.cs @@ -14,6 +14,7 @@ namespace mRemoteNG.UI.Menu private ToolStripMenuItem _mMenToolsPortScan; private ToolStripMenuItem _mMenToolsUvncsc; private ToolStripMenuItem _mMenToolsComponentsCheck; + private ToolStripMenuItem _mMenViewScreenshotManager; public Form MainForm { get; set; } public ICredentialRepositoryList CredentialProviderCatalog { get; set; } @@ -32,7 +33,7 @@ namespace mRemoteNG.UI.Menu _mMenToolsSep1 = new ToolStripSeparator(); _mMenToolsComponentsCheck = new ToolStripMenuItem(); _mMenToolsOptions = new ToolStripMenuItem(); - + _mMenViewScreenshotManager = new ToolStripMenuItem(); // // mMenTools // @@ -41,6 +42,7 @@ namespace mRemoteNG.UI.Menu _mMenToolsUvncsc, _mMenToolsExternalApps, _mMenToolsPortScan, + _mMenViewScreenshotManager, _mMenToolsSep1, _mMenToolsComponentsCheck, _mMenToolsOptions}); @@ -81,6 +83,14 @@ namespace mRemoteNG.UI.Menu _mMenToolsPortScan.Text = Language.strMenuPortScan; _mMenToolsPortScan.Click += mMenToolsPortScan_Click; // + // mMenViewScreenshotManager + // + _mMenViewScreenshotManager.Image = Resources.Screenshot; + _mMenViewScreenshotManager.Name = "mMenViewScreenshotManager"; + _mMenViewScreenshotManager.Size = new System.Drawing.Size(228, 22); + _mMenViewScreenshotManager.Text = Language.strScreenshots; + _mMenViewScreenshotManager.Click += mMenViewScreenshotManager_Click; + // // mMenToolsSep1 // _mMenToolsSep1.Name = "mMenToolsSep1"; @@ -109,6 +119,7 @@ namespace mRemoteNG.UI.Menu _mMenToolsSshTransfer.Text = Language.strMenuSSHFileTransfer; _mMenToolsExternalApps.Text = Language.strMenuExternalTools; _mMenToolsPortScan.Text = Language.strMenuPortScan; + _mMenViewScreenshotManager.Text = Language.strScreenshots; _mMenToolsComponentsCheck.Text = Language.strComponentsCheck; _mMenToolsOptions.Text = Language.strMenuOptions; } @@ -134,6 +145,11 @@ namespace mRemoteNG.UI.Menu Windows.Show(WindowType.PortScan); } + private void mMenViewScreenshotManager_Click(object sender, EventArgs e) + { + Windows.Show(WindowType.ScreenshotManager); + } + private void mMenToolsComponentsCheck_Click(object sender, EventArgs e) { Windows.Show(WindowType.ComponentsCheck); diff --git a/mRemoteV1/UI/Menu/ViewMenu.cs b/mRemoteV1/UI/Menu/ViewMenu.cs index 43945783f..38b294d7b 100644 --- a/mRemoteV1/UI/Menu/ViewMenu.cs +++ b/mRemoteV1/UI/Menu/ViewMenu.cs @@ -14,7 +14,6 @@ namespace mRemoteNG.UI.Menu private ToolStripMenuItem _mMenViewConnections; private ToolStripMenuItem _mMenViewConfig; private ToolStripMenuItem _mMenViewErrorsAndInfos; - private ToolStripMenuItem _mMenViewScreenshotManager; private ToolStripMenuItem _mMenViewAddConnectionPanel; private ToolStripSeparator _mMenViewSep2; private ToolStripMenuItem _mMenViewFullscreen; @@ -52,7 +51,6 @@ namespace mRemoteNG.UI.Menu _mMenViewConnections = new ToolStripMenuItem(); _mMenViewConfig = new ToolStripMenuItem(); _mMenViewErrorsAndInfos = new ToolStripMenuItem(); - _mMenViewScreenshotManager = new ToolStripMenuItem(); _mMenViewJumpTo = new ToolStripMenuItem(); _mMenViewJumpToConnectionsConfig = new ToolStripMenuItem(); _mMenViewJumpToErrorsInfos = new ToolStripMenuItem(); @@ -76,7 +74,6 @@ namespace mRemoteNG.UI.Menu _mMenViewConnections, _mMenViewConfig, _mMenViewErrorsAndInfos, - _mMenViewScreenshotManager, _toolStripSeparator1, _mMenViewJumpTo, _mMenViewResetLayout, @@ -142,14 +139,6 @@ namespace mRemoteNG.UI.Menu _mMenViewErrorsAndInfos.Text = Language.strMenuNotifications; _mMenViewErrorsAndInfos.Click += mMenViewErrorsAndInfos_Click; // - // mMenViewScreenshotManager - // - _mMenViewScreenshotManager.Image = Resources.Screenshot; - _mMenViewScreenshotManager.Name = "mMenViewScreenshotManager"; - _mMenViewScreenshotManager.Size = new System.Drawing.Size(228, 22); - _mMenViewScreenshotManager.Text = Language.strScreenshots; - _mMenViewScreenshotManager.Click += mMenViewScreenshotManager_Click; - // // ToolStripSeparator1 // _toolStripSeparator1.Name = "ToolStripSeparator1"; @@ -169,8 +158,7 @@ namespace mRemoteNG.UI.Menu // _mMenViewJumpToConnectionsConfig.Image = Resources.Root; _mMenViewJumpToConnectionsConfig.Name = "mMenViewJumpToConnectionsConfig"; - _mMenViewJumpToConnectionsConfig.ShortcutKeys = ((Keys)(((Keys.Control | Keys.Alt) - | Keys.C))); + _mMenViewJumpToConnectionsConfig.ShortcutKeys = Keys.Control | Keys.Alt | Keys.C; _mMenViewJumpToConnectionsConfig.Size = new System.Drawing.Size(258, 22); _mMenViewJumpToConnectionsConfig.Text = Language.strMenuConnectionsAndConfig; _mMenViewJumpToConnectionsConfig.Click += mMenViewJumpToConnectionsConfig_Click; @@ -179,8 +167,7 @@ namespace mRemoteNG.UI.Menu // _mMenViewJumpToErrorsInfos.Image = Resources.InformationSmall; _mMenViewJumpToErrorsInfos.Name = "mMenViewJumpToErrorsInfos"; - _mMenViewJumpToErrorsInfos.ShortcutKeys = ((Keys)(((Keys.Control | Keys.Alt) - | Keys.E))); + _mMenViewJumpToErrorsInfos.ShortcutKeys = Keys.Control | Keys.Alt | Keys.E; _mMenViewJumpToErrorsInfos.Size = new System.Drawing.Size(258, 22); _mMenViewJumpToErrorsInfos.Text = Language.strMenuNotifications; _mMenViewJumpToErrorsInfos.Click += mMenViewJumpToErrorsInfos_Click; @@ -256,7 +243,6 @@ namespace mRemoteNG.UI.Menu _mMenViewConnections.Text = Language.strMenuConnections; _mMenViewConfig.Text = Language.strMenuConfig; _mMenViewErrorsAndInfos.Text = Language.strMenuNotifications; - _mMenViewScreenshotManager.Text = Language.strScreenshots; _mMenViewJumpTo.Text = Language.strMenuJumpTo; _mMenViewJumpToConnectionsConfig.Text = Language.strMenuConnectionsAndConfig; _mMenViewJumpToErrorsInfos.Text = Language.strMenuNotifications; @@ -274,7 +260,6 @@ namespace mRemoteNG.UI.Menu _mMenViewConnections.Checked = !Windows.TreeForm.IsHidden; _mMenViewConfig.Checked = !Windows.ConfigForm.IsHidden; _mMenViewErrorsAndInfos.Checked = !Windows.ErrorsForm.IsHidden; - _mMenViewScreenshotManager.Checked = !Windows.ScreenshotForm.IsHidden; _mMenViewLockToolbars.Checked = Settings.Default.LockToolbars; _mMenViewExtAppsToolbar.Checked = TsExternalTools.Visible; @@ -342,20 +327,6 @@ namespace mRemoteNG.UI.Menu } } - private void mMenViewScreenshotManager_Click(object sender, EventArgs e) - { - if (_mMenViewScreenshotManager.Checked == false) - { - Windows.ScreenshotForm.Show(MainForm.pnlDock); - _mMenViewScreenshotManager.Checked = true; - } - else - { - Windows.ScreenshotForm.Hide(); - _mMenViewScreenshotManager.Checked = false; - } - } - private void mMenViewJumpToConnectionsConfig_Click(object sender, EventArgs e) { if (MainForm.pnlDock.ActiveContent == Windows.TreeForm) diff --git a/mRemoteV1/UI/Panels/PanelAdder.cs b/mRemoteV1/UI/Panels/PanelAdder.cs index 30096bd31..238710299 100644 --- a/mRemoteV1/UI/Panels/PanelAdder.cs +++ b/mRemoteV1/UI/Panels/PanelAdder.cs @@ -96,13 +96,12 @@ namespace mRemoteNG.UI.Panels try { var conW = (ConnectionWindow)((ToolStripMenuItem)sender).Tag; - var nTitle = ""; - new InputBox().ShowAsDialog(Language.strNewTitle, Language.strNewTitle + ":", ref nTitle); - - if (!string.IsNullOrEmpty(nTitle)) + using (var frmInputBox = new FrmInputBox(Language.strNewTitle, Language.strNewTitle + ":", ref nTitle)) { - conW.SetFormText(nTitle.Replace("&", "&&")); + var dr = frmInputBox.ShowDialog(); + if (dr == DialogResult.OK && string.IsNullOrEmpty(frmInputBox.returnValue)) + conW.SetFormText(frmInputBox.returnValue); } } catch (Exception ex) @@ -147,8 +146,7 @@ namespace mRemoteNG.UI.Panels if (tagEnumeration == null) return; foreach (var obj in tagEnumeration) { - var screen1 = obj as Screen; - if (screen1 != null) + if (obj is Screen screen1) { screen = screen1; } diff --git a/mRemoteV1/UI/TaskDialog/CommandButton.designer.cs b/mRemoteV1/UI/TaskDialog/CommandButton.designer.cs index ea110afba..6aa327f75 100644 --- a/mRemoteV1/UI/TaskDialog/CommandButton.designer.cs +++ b/mRemoteV1/UI/TaskDialog/CommandButton.designer.cs @@ -28,7 +28,13 @@ namespace mRemoteNG.UI.TaskDialog /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); + this.SuspendLayout(); + // + // CommandButton + // + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ResumeLayout(false); + } #endregion diff --git a/mRemoteV1/UI/TaskDialog/CommandButton.resx b/mRemoteV1/UI/TaskDialog/CommandButton.resx new file mode 100644 index 000000000..e5858cc29 --- /dev/null +++ b/mRemoteV1/UI/TaskDialog/CommandButton.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/mRemoteV1/UI/TaskDialog/frmTaskDialog.cs b/mRemoteV1/UI/TaskDialog/frmTaskDialog.cs index ce31a7b6f..65096087c 100644 --- a/mRemoteV1/UI/TaskDialog/frmTaskDialog.cs +++ b/mRemoteV1/UI/TaskDialog/frmTaskDialog.cs @@ -32,11 +32,20 @@ namespace mRemoteNG.UI.TaskDialog public ESysIcons MainIcon { get; set; } = ESysIcons.Question; public ESysIcons FooterIcon { get; set; } = ESysIcons.Warning; - public string Title { get { return Text; } set { Text = value; } } - public string MainInstruction { get { return _mainInstruction; } set { _mainInstruction = value; Invalidate(); } } - public string Content { get { return lbContent.Text; } set { lbContent.Text = value; } } - public string ExpandedInfo { get { return lbExpandedInfo.Text; } set { lbExpandedInfo.Text = value; } } - public string Footer { get { return lbFooter.Text; } set { lbFooter.Text = value; } } + public string Title { get => Text; + set => Text = value; + } + public string MainInstruction { get => _mainInstruction; + set { _mainInstruction = value; Invalidate(); } } + public string Content { get => lbContent.Text; + set => lbContent.Text = value; + } + public string ExpandedInfo { get => lbExpandedInfo.Text; + set => lbExpandedInfo.Text = value; + } + public string Footer { get => lbFooter.Text; + set => lbFooter.Text = value; + } public int DefaultButtonIndex { get; set; } public string RadioButtons { get; set; } = ""; @@ -57,8 +66,12 @@ namespace mRemoteNG.UI.TaskDialog public ETaskDialogButtons Buttons { get; set; } = ETaskDialogButtons.YesNoCancel; - public string VerificationText { get { return cbVerify.Text; } set { cbVerify.Text = value; } } - public bool VerificationCheckBoxChecked { get { return cbVerify.Checked; } set { cbVerify.Checked = value; } } + public string VerificationText { get => cbVerify.Text; + set => cbVerify.Text = value; + } + public bool VerificationCheckBoxChecked { get => cbVerify.Checked; + set => cbVerify.Checked = value; + } private bool Expanded { get; set; } @@ -123,7 +136,7 @@ namespace mRemoteNG.UI.TaskDialog formHeight += pnlMainInstruction.Height; // Setup Content - pnlContent.Visible = (Content != ""); + pnlContent.Visible = Content != ""; if (Content != "") { AdjustLabelHeight(lbContent); @@ -131,7 +144,7 @@ namespace mRemoteNG.UI.TaskDialog formHeight += pnlContent.Height; } - var showVerifyCheckbox = (cbVerify.Text != ""); + var showVerifyCheckbox = cbVerify.Text != ""; cbVerify.Visible = showVerifyCheckbox; // Setup Expanded Info and Buttons panels @@ -147,8 +160,8 @@ namespace mRemoteNG.UI.TaskDialog AdjustLabelHeight(lbExpandedInfo); pnlExpandedInfo.Height = lbExpandedInfo.Height + _display.ScaleHeight(4); pnlExpandedInfo.Visible = Expanded; - lbShowHideDetails.Text = (Expanded ? " Hide details" : " Show details"); - lbShowHideDetails.ImageIndex = (Expanded ? 0 : 3); + lbShowHideDetails.Text = Expanded ? " Hide details" : " Show details"; + lbShowHideDetails.ImageIndex = Expanded ? 0 : 3; if (!showVerifyCheckbox) pnlButtons.Height = _display.ScaleHeight(40); if (Expanded) @@ -156,19 +169,18 @@ namespace mRemoteNG.UI.TaskDialog } // Setup RadioButtons - pnlRadioButtons.Visible = (RadioButtons != ""); + pnlRadioButtons.Visible = RadioButtons != ""; if (RadioButtons != "") { var arr = RadioButtons.Split('|'); var pnlHeight = _display.ScaleHeight(12); for (var i = 0; i < arr.Length; i++) { - var rb = new NGRadioButton(); - rb.Parent = pnlRadioButtons; - rb.Location = new Point(_display.ScaleWidth(60), _display.ScaleHeight(4) + (i * rb.Height)); + var rb = new NGRadioButton {Parent = pnlRadioButtons}; + rb.Location = new Point(_display.ScaleWidth(60), _display.ScaleHeight(4) + i * rb.Height); rb.Text = arr[i]; rb.Tag = i; - rb.Checked = (DefaultButtonIndex == i); + rb.Checked = DefaultButtonIndex == i; rb.Width = Width - rb.Left - _display.ScaleWidth(15); pnlHeight += rb.Height; _radioButtonCtrls.Add(rb); @@ -178,7 +190,7 @@ namespace mRemoteNG.UI.TaskDialog } // Setup CommandButtons - pnlCommandButtons.Visible = (CommandButtons != ""); + pnlCommandButtons.Visible = CommandButtons != ""; if (CommandButtons != "") { var arr = CommandButtons.Split('|'); @@ -186,9 +198,10 @@ namespace mRemoteNG.UI.TaskDialog var pnlHeight = _display.ScaleHeight(16); for (var i = 0; i < arr.Length; i++) { - var btn = new CommandButton(); - btn.Parent = pnlCommandButtons; - btn.Location = new Point(_display.ScaleWidth(50), t); + var btn = new CommandButton + { + Parent = pnlCommandButtons, Location = new Point(_display.ScaleWidth(50), t) + }; if (_isVista) // <- tweak font if vista btn.Font = new Font(btn.Font, FontStyle.Regular); btn.Text = arr[i]; @@ -266,17 +279,17 @@ namespace mRemoteNG.UI.TaskDialog throw new ArgumentOutOfRangeException(); } - ControlBox = (Buttons == ETaskDialogButtons.Cancel || - Buttons == ETaskDialogButtons.Close || - Buttons == ETaskDialogButtons.OkCancel || - Buttons == ETaskDialogButtons.YesNoCancel); + ControlBox = Buttons == ETaskDialogButtons.Cancel || + Buttons == ETaskDialogButtons.Close || + Buttons == ETaskDialogButtons.OkCancel || + Buttons == ETaskDialogButtons.YesNoCancel; if (!showVerifyCheckbox && ExpandedInfo == "" && Buttons == ETaskDialogButtons.None) pnlButtons.Visible = false; else formHeight += pnlButtons.Height; - pnlFooter.Visible = (Footer != ""); + pnlFooter.Visible = Footer != ""; if (Footer != "") { AdjustLabelHeight(lbFooter); @@ -392,25 +405,25 @@ namespace mRemoteNG.UI.TaskDialog //-------------------------------------------------------------------------------- private void lbDetails_MouseEnter(object sender, EventArgs e) { - lbShowHideDetails.ImageIndex = (Expanded ? 1 : 4); + lbShowHideDetails.ImageIndex = Expanded ? 1 : 4; } //-------------------------------------------------------------------------------- private void lbDetails_MouseLeave(object sender, EventArgs e) { - lbShowHideDetails.ImageIndex = (Expanded ? 0 : 3); + lbShowHideDetails.ImageIndex = Expanded ? 0 : 3; } //-------------------------------------------------------------------------------- private void lbDetails_MouseUp(object sender, MouseEventArgs e) { - lbShowHideDetails.ImageIndex = (Expanded ? 1 : 4); + lbShowHideDetails.ImageIndex = Expanded ? 1 : 4; } //-------------------------------------------------------------------------------- private void lbDetails_MouseDown(object sender, MouseEventArgs e) { - lbShowHideDetails.ImageIndex = (Expanded ? 2 : 5); + lbShowHideDetails.ImageIndex = Expanded ? 2 : 5; } //-------------------------------------------------------------------------------- @@ -418,7 +431,7 @@ namespace mRemoteNG.UI.TaskDialog { Expanded = !Expanded; pnlExpandedInfo.Visible = Expanded; - lbShowHideDetails.Text = (Expanded ? " Hide details" : " Show details"); + lbShowHideDetails.Text = Expanded ? " Hide details" : " Show details"; if (Expanded) Height += pnlExpandedInfo.Height; else diff --git a/mRemoteV1/UI/Window/AboutWindow.cs b/mRemoteV1/UI/Window/AboutWindow.cs index 6f21926d1..9f381e96c 100644 --- a/mRemoteV1/UI/Window/AboutWindow.cs +++ b/mRemoteV1/UI/Window/AboutWindow.cs @@ -3,10 +3,9 @@ using System.Windows.Forms; using WeifenLuo.WinFormsUI.Docking; using System.IO; using System.Text; +using System.Text.RegularExpressions; using mRemoteNG.App; using mRemoteNG.App.Info; -// ReSharper disable ArrangeRedundantParentheses -// ReSharper disable RedundantCast namespace mRemoteNG.UI.Window { @@ -22,15 +21,14 @@ namespace mRemoteNG.UI.Window internal Controls.Base.NGLabel lblChangeLog; internal Panel pnlBottom; internal PictureBox pbLogo; - internal Controls.Base.NGLabel lblEdition; internal Controls.Base.NGLabel lblCredits; internal Controls.Base.NGTextBox txtCredits; internal Panel pnlTop; - - private void InitializeComponent() + + private void InitializeComponent() { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutWindow)); this.pnlTop = new System.Windows.Forms.Panel(); - this.lblEdition = new mRemoteNG.UI.Controls.Base.NGLabel(); this.pbLogo = new System.Windows.Forms.PictureBox(); this.pnlBottom = new System.Windows.Forms.Panel(); this.lblCredits = new mRemoteNG.UI.Controls.Base.NGLabel(); @@ -48,46 +46,27 @@ namespace mRemoteNG.UI.Window // // pnlTop // - this.pnlTop.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.pnlTop.BackColor = System.Drawing.Color.Black; - this.pnlTop.Controls.Add(this.lblEdition); + this.pnlTop.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(52)))), ((int)(((byte)(58)))), ((int)(((byte)(64))))); this.pnlTop.Controls.Add(this.pbLogo); + this.pnlTop.Dock = System.Windows.Forms.DockStyle.Top; this.pnlTop.ForeColor = System.Drawing.Color.White; - this.pnlTop.Location = new System.Drawing.Point(-1, -1); + this.pnlTop.Location = new System.Drawing.Point(0, 0); this.pnlTop.Name = "pnlTop"; - this.pnlTop.Size = new System.Drawing.Size(1121, 145); + this.pnlTop.Size = new System.Drawing.Size(1117, 122); this.pnlTop.TabIndex = 0; // - // lblEdition - // - this.lblEdition.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.lblEdition.BackColor = System.Drawing.Color.Black; - this.lblEdition.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblEdition.ForeColor = System.Drawing.Color.White; - this.lblEdition.Location = new System.Drawing.Point(845, 112); - this.lblEdition.Name = "lblEdition"; - this.lblEdition.Size = new System.Drawing.Size(264, 24); - this.lblEdition.TabIndex = 0; - this.lblEdition.Text = "Edition"; - this.lblEdition.TextAlign = System.Drawing.ContentAlignment.BottomRight; - this.lblEdition.Visible = false; - // // pbLogo // - this.pbLogo.Image = global::mRemoteNG.Resources.Logo; - this.pbLogo.Location = new System.Drawing.Point(8, 8); + this.pbLogo.Image = global::mRemoteNG.Resources.Header_dark; + this.pbLogo.Location = new System.Drawing.Point(0, 0); this.pbLogo.Name = "pbLogo"; - this.pbLogo.Size = new System.Drawing.Size(492, 128); + this.pbLogo.Size = new System.Drawing.Size(450, 120); this.pbLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.pbLogo.TabIndex = 1; this.pbLogo.TabStop = false; // // pnlBottom // - this.pnlBottom.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.pnlBottom.BackColor = System.Drawing.SystemColors.Control; this.pnlBottom.Controls.Add(this.lblCredits); this.pnlBottom.Controls.Add(this.txtCredits); @@ -97,10 +76,11 @@ namespace mRemoteNG.UI.Window this.pnlBottom.Controls.Add(this.lblChangeLog); this.pnlBottom.Controls.Add(this.lblLicense); this.pnlBottom.Controls.Add(this.lblCopyright); + this.pnlBottom.Dock = System.Windows.Forms.DockStyle.Fill; this.pnlBottom.ForeColor = System.Drawing.SystemColors.ControlText; - this.pnlBottom.Location = new System.Drawing.Point(-1, 144); + this.pnlBottom.Location = new System.Drawing.Point(0, 122); this.pnlBottom.Name = "pnlBottom"; - this.pnlBottom.Size = new System.Drawing.Size(1121, 559); + this.pnlBottom.Size = new System.Drawing.Size(1117, 583); this.pnlBottom.TabIndex = 1; // // lblCredits @@ -108,7 +88,7 @@ namespace mRemoteNG.UI.Window this.lblCredits.AutoSize = true; this.lblCredits.Font = new System.Drawing.Font("Segoe UI", 11F); this.lblCredits.ForeColor = System.Drawing.SystemColors.ControlText; - this.lblCredits.Location = new System.Drawing.Point(8, 131); + this.lblCredits.Location = new System.Drawing.Point(3, 131); this.lblCredits.Name = "lblCredits"; this.lblCredits.Size = new System.Drawing.Size(55, 25); this.lblCredits.TabIndex = 11; @@ -130,7 +110,7 @@ namespace mRemoteNG.UI.Window this.txtCredits.Name = "txtCredits"; this.txtCredits.ReadOnly = true; this.txtCredits.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.txtCredits.Size = new System.Drawing.Size(400, 400); + this.txtCredits.Size = new System.Drawing.Size(400, 424); this.txtCredits.TabIndex = 7; this.txtCredits.TabStop = false; // @@ -150,7 +130,7 @@ namespace mRemoteNG.UI.Window this.txtChangeLog.Name = "txtChangeLog"; this.txtChangeLog.ReadOnly = true; this.txtChangeLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.txtChangeLog.Size = new System.Drawing.Size(700, 400); + this.txtChangeLog.Size = new System.Drawing.Size(696, 424); this.txtChangeLog.TabIndex = 10; this.txtChangeLog.TabStop = false; // @@ -159,7 +139,7 @@ namespace mRemoteNG.UI.Window this.lblTitle.AutoSize = true; this.lblTitle.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lblTitle.ForeColor = System.Drawing.SystemColors.ControlText; - this.lblTitle.Location = new System.Drawing.Point(8, 20); + this.lblTitle.Location = new System.Drawing.Point(3, 3); this.lblTitle.Name = "lblTitle"; this.lblTitle.Size = new System.Drawing.Size(126, 31); this.lblTitle.TabIndex = 0; @@ -171,7 +151,7 @@ namespace mRemoteNG.UI.Window this.lblVersion.AutoSize = true; this.lblVersion.Font = new System.Drawing.Font("Segoe UI", 11F); this.lblVersion.ForeColor = System.Drawing.SystemColors.ControlText; - this.lblVersion.Location = new System.Drawing.Point(8, 51); + this.lblVersion.Location = new System.Drawing.Point(3, 34); this.lblVersion.Name = "lblVersion"; this.lblVersion.Size = new System.Drawing.Size(55, 25); this.lblVersion.TabIndex = 1; @@ -195,7 +175,7 @@ namespace mRemoteNG.UI.Window this.lblLicense.AutoSize = true; this.lblLicense.Font = new System.Drawing.Font("Segoe UI", 11F); this.lblLicense.ForeColor = System.Drawing.SystemColors.ControlText; - this.lblLicense.Location = new System.Drawing.Point(8, 101); + this.lblLicense.Location = new System.Drawing.Point(3, 84); this.lblLicense.Name = "lblLicense"; this.lblLicense.Size = new System.Drawing.Size(54, 25); this.lblLicense.TabIndex = 5; @@ -207,7 +187,7 @@ namespace mRemoteNG.UI.Window this.lblCopyright.AutoSize = true; this.lblCopyright.Font = new System.Drawing.Font("Segoe UI", 11F); this.lblCopyright.ForeColor = System.Drawing.SystemColors.ControlText; - this.lblCopyright.Location = new System.Drawing.Point(8, 76); + this.lblCopyright.Location = new System.Drawing.Point(3, 59); this.lblCopyright.Name = "lblCopyright"; this.lblCopyright.Size = new System.Drawing.Size(71, 25); this.lblCopyright.TabIndex = 2; @@ -220,11 +200,11 @@ namespace mRemoteNG.UI.Window this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.BackColor = System.Drawing.SystemColors.Control; this.ClientSize = new System.Drawing.Size(1117, 705); - this.Controls.Add(this.pnlTop); this.Controls.Add(this.pnlBottom); + this.Controls.Add(this.pnlTop); this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.ForeColor = System.Drawing.SystemColors.ControlText; - this.Icon = global::mRemoteNG.Resources.mRemote_Icon; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximumSize = new System.Drawing.Size(20000, 10000); this.Name = "AboutWindow"; this.TabText = "About"; @@ -248,6 +228,7 @@ namespace mRemoteNG.UI.Window InitializeComponent(); FontOverrider.FontOverride(this); Themes.ThemeManager.getInstance().ThemeChanged += ApplyTheme; + ApplyLanguage(); } #endregion @@ -268,49 +249,45 @@ namespace mRemoteNG.UI.Window ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); pnlBottom.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); pnlBottom.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); - pnlTop.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); + pnlTop.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); pnlTop.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); - lblEdition.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); - lblEdition.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); } private void ApplyEditions() { #if PORTABLE - lblEdition.Text = Language.strLabelPortableEdition; - lblEdition.Visible = true; + lblTitle.Text += " " + Language.strLabelPortableEdition; #endif } -#if false - private void FillLinkLabel(LinkLabel llbl, string txt, string URL) - { - llbl.Links.Clear(); + #if false + private void FillLinkLabel(LinkLabel llbl, string txt, string URL) + { + llbl.Links.Clear(); - int Open = txt.IndexOf("["); - while (Open != -1) - { - txt = txt.Remove(Open, 1); - int Close = txt.IndexOf("]", Open); - if (Close == -1) - { - break; - } - txt = txt.Remove(Close, 1); - llbl.Links.Add(Open, Close - Open, URL); - Open = txt.IndexOf("[", Open); - } + int Open = txt.IndexOf("["); + while (Open != -1) + { + txt = txt.Remove(Open, 1); + int Close = txt.IndexOf("]", Open); + if (Close == -1) + { + break; + } + txt = txt.Remove(Close, 1); + llbl.Links.Add(Open, Close - Open, URL); + Open = txt.IndexOf("[", Open); + } - llbl.Text = txt; - } -#endif -#endregion + llbl.Text = txt; + } + #endif + #endregion #region Form Stuff private void About_Load(object sender, EventArgs e) { - ApplyLanguage(); ApplyTheme(); ApplyEditions(); @@ -320,17 +297,46 @@ namespace mRemoteNG.UI.Window lblVersion.Text = $@"Version {GeneralAppInfo.ApplicationVersion}"; - if (File.Exists(GeneralAppInfo.HomePath + "\\CHANGELOG.TXT")) + // AppVeyor seems to pull text files in UNIX format... This messes up the display on the about screen... + // + // This would be MUCH faster: + //var UnxEndRx = new Regex(@"(? System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + AAABAA0AICAQAAEABADoAgAA1gAAABAQEAABAAQAKAEAAL4DAAAwMAAAAQAIAKgOAADmBAAAICAAAAEA + CACoCAAAjhMAABAQAAABAAgAaAUAADYcAAAAAAAAAQAgAFofAACeIQAAQEAAAAEAIAAoQgAA+EAAADAw + AAABACAAqCUAACCDAAAoKAAAAQAgAGgaAADIqAAAICAAAAEAIACoEAAAMMMAABgYAAABACAAiAkAANjT + AAAUFAAAAQAgALgGAABg3QAAEBAAAAEAIABoBAAAGOQAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAA + AAAAAAAAEAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD/ + /wD/AAAA/wD/AP//AAD///8AAHdWVldHR2VnR0dWV2V4AAcWFhYWBwcHBwcHBhYHBnB2BwYWFhYHBhYH + BhYHBhYHcHBhYWBwcGFCUlJSUlJSV2UlJQYWBwcHBwYWBwYWFgdwJSQ0NDQHBwYWFhYHBwYXVwYWFgcH + BhYWFgcHBwYWB3BhYWBSQ0NCUlJSQ0JSUlZwUkNDQ0JSUkNDQ0JSUlIHcHJWBwdBJDRwQkJSUlJCV2VH + YWR2dDx0eIdSUkeIFgdwfnR0jkcH53+HJDQ4+AcHZ8dwdHdgfHZ/h1JQePhDB3B+dGXnRWfnf4dDQnj3 + Q0d0fnFkfnB8dn+HBDR/9wYHcHx2R35QdnZ/93d3/4Q0NWdoYWR2dF52eP///49yUgdwfHZWjlZnx3/4 + iIj/h0NHR2jOfIyMfnZ/h3B0ePgHB3B8hoyGhoZ0f4cGFjj4ZDRyVlZWVlZWFH/3UkB4+BYHcFJDQlJH + RlJ/iHh4iPcWF3YWFhYSEhIUf4+Pj/+GUgdwBhYHRlZHRniIiIh3UlJWdwcHAhIDAhIDAwMDBhYHB3BD + QlZWVlZWVlZHRlYWFgdyUlIDAhIDAhIDAhISQ0MHcBYHR0dHR0dHR0dHRlJDR3YHAwISAwISAwISAwMH + BgdyUlZHRlZHRlZHRlZHRhYYB0AwEhAwEhAwEhAwEhBwcAB3dHZWdHZWdHZWdHZWdwDAAAADgAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAAAAygA + AAAQAAAAIAAAAAEABAAAAAAAwAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAA + gACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AB2V2V2V0dHBwYWBwYWBwd3Bw + cENCUlIHcHBhY0NDQ0dSVhRFJSQlB3ZkdnaHQXgnV3R0dogkiAd2ZeVniGeHR1dl5WePiPcHdnZ2dohD + eHZnR0cGiHeIB3AlZWV4iIcHVwISA0MHBwdwZWR0ZWQ0JXEhAwEhAwcHB2VnR2VnR3CAAQAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAKAAAADAA + AABgAAAAAQAIAAAAAACACgAAAAAAAAAAAAAAAQAAAAAAAAAAAABAOjQAQjw2AEc9NQBIPTUARD44AEZA + OgBIQj0AS0U/AFFBNgBaRTgAXUY4AGBIOQBlSTkAaEs6AGpMOgBuTTsAck87AHNPPAB3UTwAeVI8AH1U + PQBLRUAATEZBAE5IQgBPSUQAUEtFAFROSgBWUEsAV1JMAFhSTABgW1UAZF9aAGRgWwBlYFwAaGJdAGtm + YQBybWgAdG9qAHZxbAB4c24AenVwAIZXPgCLWj8AjFo/AJVeQACaYEEAoGJBAKZkQgCoZUMArGdDAIB7 + dgDLdEgAz3ZIANd5SQDZekkA3HtKAON+SwDlf0sAhoF9AIiDfgDyhU0A9IVNAPiGTgD6iE4A/olOAImF + gACLiIQAjIiFAJCLhwCQjIcAkYyIAJWRjACcl5MAoJyXAKKemgCoo58As6+rALi0sAC8ubUAxcK+AMjF + wQDLyMQAzMnFANHOygDT0MwA1dLOANnW0wDa19QA29jUAN3a1wDf3NkA4+DdAOTg3QDm4+AA5+ThAOnm + 4wDq5+QA6+jlAO3p5gDu6+gA7+zpAFnPAABn8AAAeP8RAIr/MQCc/1EArv9xAMD/kQDS/7EA5P/RAP// + /wAAAAAAJi8AAEBQAABacAAAdJAAAI6wAACpzwAAwvAAANH/EQDY/zEA3v9RAOP/cQDp/5EA7/+xAPb/ + 0QD///8AAAAAAC8mAABQQQAAcFsAAJB0AACwjgAAz6kAAPDDAAD/0hEA/9gxAP/dUQD/5HEA/+qRAP/w + sQD/9tEA////AAAAAAAvFAAAUCIAAHAwAACQPgAAsE0AAM9bAADwaQAA/3kRAP+KMQD/nVEA/69xAP/B + kQD/0rEA/+XRAP///wAAAAAALwMAAFAEAABwBgAAkAkAALAKAADPDAAA8A4AAP8gEgD/PjEA/1xRAP96 + cQD/l5EA/7axAP/U0QD///8AAAAAAC8ADgBQABcAcAAhAJAAKwCwADYAzwBAAPAASQD/EVoA/zFwAP9R + hgD/cZwA/5GyAP+xyAD/0d8A////AAAAAAAvACAAUAA2AHAATACQAGIAsAB4AM8AjgDwAKQA/xGzAP8x + vgD/UccA/3HRAP+R3AD/seUA/9HwAP///wAAAAAALAAvAEsAUABpAHAAhwCQAKUAsADEAM8A4QDwAPAR + /wDyMf8A9FH/APZx/wD3kf8A+bH/APvR/wD///8AAAAAABsALwAtAFAAPwBwAFIAkABjALAAdgDPAIgA + 8ACZEf8ApjH/ALRR/wDCcf8Az5H/ANyx/wDr0f8A////AAAAAAAIAC8ADgBQABUAcAAbAJAAIQCwACYA + zwAsAPAAPhH/AFgx/wBxUf8AjHH/AKaR/wC/sf8A2tH/AP///wAAAAAARSIeHh4eHh4eHh4eHh4eHh4e + Hh4eHh4eHh4eHh4eHh4eHh4eHh4jRAAAAAAAAAAaAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQECAQEBAQEB + AQEBAQEBAQEBARkAAAAAAAYBAQEBAQEBAQECAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEG + AAAAGQEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBGQBEAQEBAQEBAQEB + AQECAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAUQgAQEBAQEBAQEBAQEBAQIBAQEBAQEB + AQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBASIeAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAgEBAQEBAQEB + AQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEB + AR4dAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEB + AQEBAQIBAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQECAQEBAQEBAQEB + AQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQECAQEBAQEB + AQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEB + AR4dAQEBAQEBAQEBAQEBAQIBAQEBAQEBAQECAQECAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAgECAQEB + AQECAgEBAQEBAQECAgEBAgIBAQEBAQEBAQEBAQECAgEBAQEBAR4dAQEMMTIwCQIBAQ0xMi8JAQEBCjAy + MQoWRktLPAUBAQEBAQEBFkhLS0MGAQEBAR4dAQIsQUE+EAEBAi5BQT0PAQEBFUFBQBUeWGVlUhcBAQEB + AQEBIFxlZU8GAQEBAR4dAQEsQUE/EAIBAS1BQT8PAQEBFUBBQBUeWmVlUxcBAQEBAQEBJWFlZUwCAQEB + AR4dAQIsQUE/EAEBAi5BQT4PAQECFUFBQRUeWWVlUxcBAQEBAQEBM2RlZUkBAQEBAR4dAQEsQUE/EAIB + AS1BQT8PAQEBFUBBQBUeWmVlUxcBAQEBAQEBSGVlZEUBAQEBAR4dAQIsQUE/EAEBAi5BQT4PAQECFUFB + QBUeWmVlUxcBAQEBAQIGTmVlYykBAQEBAR4dAQEsQUE/EAIBAS1BQT8PAQEBFUBBQBUeWmVlUxcBAQEB + AQEjW2VlWx8BAQEBAR4dAQIsQUE/EAEBAi5BQT4PAQECFUFBQRUeWWVlUxcBAQECByNQZGVlTgcBAQEB + AR4dAQEsQUE/EAIBAS1BQT8PAQEBFUBBQBUeWmVlWUZCQkVKT1tlZWVUIgEBAQEBAR4dAQEsQUE/EAEB + Ai5BQT4PAQECFUFBQBUeWmVlZWRkZGVlZWVlZVonAgEBAQEBAR4dAQEsQUE/EAIBAS1BQT8PAgECLEFB + QBQeWmVlZWVlZWVlZWVlZWRTJQIBAQEBAR4dAQEsQUE/EgMDAy5BQT4QBAQMNEFBPhAeWWVlX1NSUVJR + UlVdZGVlVh8BAQEBAR4dAQEsQUFBNzQ0NDpBQUE2NDU6QUFBOAkeWmVlUx0IFhYIFxokUWVlZEsCAQEB + AR4dAQEsQUFBQUFBQUFBQUFBQUFBQUE/LAIeWWVlUxcBAQEBAQEBKWFlZVEIAQEBAR4dAQEqP0BAQEBA + QEBAQEBAQEA/PTgsBAEeWmVlUxcBAQEBAQEBIF1lZVUaAQEBAR4dAQEJExQUFBQUFBQUFBQUFBMRDgkB + AQEeWWVlUxgBAQEBAQEBJmBlZVMYAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEeWWVlUxwHCAcI + BxgfT2VlZU0FAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEeWWVlX1FQUFBQUVNaZGVlXigBAQEB + AR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEeWWVlZWVlZWVlZWVlZWVhSwcBAQEBAR4dAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEdV2VlZWVlZWVlZWRjXVNECAEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEGM0dHR0dHR0dHRDwpIxkBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4dAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR4eAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAR4gAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + ASFDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAUQAGQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBGQAAAAUBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEGAAAAAAAZAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBARkAAAAAAAAAQyEeHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR4hRAAA + AADwAAAAAA8AAOAAAAAABwAAwAAAAAADAACAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAB + AADAAAAAAAMAAOAAAAAABwAA8AAAAAAPAAAoAAAAIAAAAEAAAAABAAgAAAAAAIAEAAAAAAAAAAAAAAAB + AAAAAAAAAAAAAEA6NABCPDYARDw1AEg+NQBMPzYARD44AE5ANgBGQTsAR0E8AEhCPABTQjYAVUM3AFdE + NwBjSTkAZko5AGxMOgBxTjsAdFA7AHxTPABOSEIAT0pEAFBKRQBRTEYAVU9KAFdSTABYUkwAXllTAGJc + VwBjXlgAZWBcAGhjXQBxbGYAdG9qAHNwbAB1cWwAeHNuAHp1cAB+enUAgVU9AIRWPQCIWD4AlV5AAJhf + QACfYUEApWRCAKhmQwCwaUQAt2xFAIB7dgCBfHcAwG9GAMRxRwDQdkgA1nhJANl6SgDdfEoA4n5LAIeD + fgDtgkwA8IRNAPWGTQD7iE4A/olPAJGMhwCWko0Am5eSAJuYlQCdmZUAoJyXAKGdmQCkn5sApKCcAKqm + ogCtqaUAsq6qALSvrAC1sa4AubWxAL26tgDCv7sAxcK+AM7KxwDPy8gAz8zIANHNygDT0MwA1NDNANjV + 0QDd2tcA39vYAODd2gDk4N0A5+PgAOnm4wDq5+QA6+jlAOzp5gDu6+gA7+zpAD2QAABMsAAAWc8AAGfw + AAB4/xEAiv8xAJz/UQCu/3EAwP+RANL/sQDk/9EA////AAAAAAAmLwAAQFAAAFpwAAB0kAAAjrAAAKnP + AADC8AAA0f8RANj/MQDe/1EA4/9xAOn/kQDv/7EA9v/RAP///wAAAAAALyYAAFBBAABwWwAAkHQAALCO + AADPqQAA8MMAAP/SEQD/2DEA/91RAP/kcQD/6pEA//CxAP/20QD///8AAAAAAC8UAABQIgAAcDAAAJA+ + AACwTQAAz1sAAPBpAAD/eREA/4oxAP+dUQD/r3EA/8GRAP/SsQD/5dEA////AAAAAAAvAwAAUAQAAHAG + AACQCQAAsAoAAM8MAADwDgAA/yASAP8+MQD/XFEA/3pxAP+XkQD/trEA/9TRAP///wAAAAAALwAOAFAA + FwBwACEAkAArALAANgDPAEAA8ABJAP8RWgD/MXAA/1GGAP9xnAD/kbIA/7HIAP/R3wD///8AAAAAAC8A + IABQADYAcABMAJAAYgCwAHgAzwCOAPAApAD/EbMA/zG+AP9RxwD/cdEA/5HcAP+x5QD/0fAA////AAAA + AAAsAC8ASwBQAGkAcACHAJAApQCwAMQAzwDhAPAA8BH/APIx/wD0Uf8A9nH/APeR/wD5sf8A+9H/AP// + /wAAAAAAGwAvAC0AUAA/AHAAUgCQAGMAsAB2AM8AiADwAJkR/wCmMf8AtFH/AMJx/wDPkf8A3LH/AOvR + /wD///8AAAAAAAgALwAOAFAAFQBwABsAkAAhALAAJgDPACwA8AA+Ef8AWDH/AHFR/wCMcf8AppH/AL+x + /wDa0f8A////AAAARB8aGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhofRAAAACMBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBIwBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBRB4BAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEfGgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBARoZAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBGhkBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEaGQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBARoZAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBGhkB + AwMDAQEBAwMBAQEDAwECBgYBAQEBAQECBgYBAQEaGgEpNCwDAQ8zMAwBBC40Jx9NTBsBAQEBBkBORQoB + ARoZAS8/NQQBEz48DgEHNz8uMWJeIAEBAQEKUWNPCgEBGhoCLz81BAETPjwOAQc3Py0xYV4gAQEBARZW + Y0sCAQEaGQEvPzUEARM+PA4BBzc/LjFiXiABAQEBHFtjRgIBARoaAi8/NQQBEz48DgEHNz8uMWJeIAEB + AQlEYmAxAQEBGhkBLz81BAETPjwOAQU3Py4xYmBBISQ6TF1hTxYBAQEaGgIvPzUEARM+PA4BBzg/LTFi + Y2FfYGJjY1wyAgEBARoZAS8/NgsFKD48EAUSPD8rMWJiWFNTVFddY1khAQEBGhoBLz89NzY5Pz84Njs/ + PRExYl8lFBQVFyRaY08JAQEaGQEuPT09PT09PT09PTkqAzFiXiABAQEBClBjVhcBARoZAQ0QEBAQEBAQ + EBAPDQMBMmJfIAEBAQEYVGNSFAEBGhkBAQEBAQEBAQEBAQEBAQExYWFNRUVESFFhYkcGAQEaGQEBAQEB + AQEBAQEBAQEBATJiY2NjY2NjY19PGgEBARoZAQEBAQEBAQEBAQEBAQEBHUlKSkpKSklCJRUBAQEBGhkB + AQEBAQEBAQEBAQEBAQEBAgICAgICAQEBAQEBAQEaGQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + ARoZAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBGhoBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEaHgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAR5DAQEBAQEBAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBRAAiAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBASMAAABDHhoZGRkZGRkZGRkZGRkZ + GRkZGRkZGRkZGh5EAADAAAADgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAAAABwAAAAygAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAA + AAAAAAAAQDo0AEI8NgBEPDUASD41AEQ+OABIPzgARkA6AEhCPABLRT8AVkM3AFlENwBaRTgAXUY4AGBH + OQBiSDkAaUs6AGxMOgB2UDwAfFM9AExGQQBPSUQAUk1HAFNOSABXUkwAWFJMAF5TTQBfVE0AYFRNAGVg + WgBsZ2MAbWdkAG1pZAB0b2oAdnFsAHhzbQB5dG8AgVU9AI1aPwCSXkIAlV1AAKhlQwCvakYAsGlEAL5v + RgDEcUYAynVKAM52SQDVeEkA3HtKAN18SgDhfUsA6oFMAI2IgwCUj4sAmJSPAJuWkgCempUAoJmTAKun + owCxrakAtLCsALqyrQC5tbEAv7u4AMG9ugDEwL0Ax8TAAMnGwgDOy8cAz8zIANHNygDg3doAMf9xAFH/ + hwBx/50Akf+yALH/yQDR/98A////AAAAAAACLwAABFAAAAZwAAAIkAAACrAAAAvPAAAO8AAAIP8SAD3/ + MQBb/1EAef9xAJj/kQC1/7EA1P/RAP///wAAAAAAFC8AACJQAAAwcAAAPZAAAEywAABZzwAAZ/AAAHj/ + EQCK/zEAnP9RAK7/cQDA/5EA0v+xAOT/0QD///8AAAAAACYvAABAUAAAWnAAAHSQAACOsAAAqc8AAMLw + AADR/xEA2P8xAN7/UQDj/3EA6f+RAO//sQD2/9EA////AAAAAAAvJgAAUEEAAHBbAACQdAAAsI4AAM+p + AADwwwAA/9IRAP/YMQD/3VEA/+RxAP/qkQD/8LEA//bRAP///wAAAAAALxQAAFAiAABwMAAAkD4AALBN + AADPWwAA8GkAAP95EQD/ijEA/51RAP+vcQD/wZEA/9KxAP/l0QD///8AAAAAAC8DAABQBAAAcAYAAJAJ + AACwCgAAzwwAAPAOAAD/IBIA/z4xAP9cUQD/enEA/5eRAP+2sQD/1NEA////AAAAAAAvAA4AUAAXAHAA + IQCQACsAsAA2AM8AQADwAEkA/xFaAP8xcAD/UYYA/3GcAP+RsgD/scgA/9HfAP///wAAAAAALwAgAFAA + NgBwAEwAkABiALAAeADPAI4A8ACkAP8RswD/Mb4A/1HHAP9x0QD/kdwA/7HlAP/R8AD///8AAAAAACwA + LwBLAFAAaQBwAIcAkAClALAAxADPAOEA8ADwEf8A8jH/APRR/wD2cf8A95H/APmx/wD70f8A////AAAA + AAAbAC8ALQBQAD8AcABSAJAAYwCwAHYAzwCIAPAAmRH/AKYx/wC0Uf8AwnH/AM+R/wDcsf8A69H/AP// + /wAAAAAACAAvAA4AUAAVAHAAGwCQACEAsAAmAM8ALADwAD4R/wBYMf8AcVH/AIxx/wCmkf8Av7H/ANrR + /wD///8AAB8ZGRkZGRkZGRkZGRkgAB4BAQEBAQEBAQEBAQEBASAZAQEBAQEBAQEBAQEBAQEZGAEBAQEB + AQEBAQEBAQEBGRgEAwMEAwUECAcBAQUIAhkaKxMPLAolKjk2AgEjPAkZHC8mEDMNKC8+OwICOEIIGRwv + JhEzDSgvPj8dJEc4AhkcLygSMxEpLj5IREdINQIZGy0xMDQwMic9PRYXOUYVGRkLDw8PDwwGPUAhIz1D + FBkYAQEBAQEBAjdCQUE9IAIZGAEBAQEBAQEHCAgIBQEBGRkBAQEBAQEBAQEBAQEBARkeAQEBAQEBAQEB + AQEBAQEeAB4ZGBgYGBgYGBgYGBkeAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACJUE5HDQoaCgAAAA1JSERSAAABAAAAAQAIBgAAAFxyqGYA + AB8hSURBVHja7d0JfFXFoQbwb87NHiCEhE3ZBVRQQRYF5BFw6cO1i4+61KrPp7ZaUYoVRHltqchatGLd + qyzu4A4iPESIBlR2oQSEsAtBQlayJ/fMmzkxQDgEktxzc25yvv+vNHBzOc65ZL4zM2dmjkjPyE4xgE9a + t4yfhiAZMWKEb1t6erMIv681hDhXSrOrAaMjBNqa0mwJacQBZjQgwoUhjGCVg8htUv3Aq/8vA4wiCDNX + /bhnQCJdCnOPem0npPy+1Of/8by2bfPmz5/vD3Z5xI8ZmWNh4rvWrRMWO3lgXel3pKe38ElfT0hxmTrJ + S4U0e6iTbAEDTdRbwoN9ckQNSJmqh/nqQphlCrHFEOJbKeQqv/Bv6da2bVawwkA4fcCkpKSoglJ0VZX8 + SnVC15gQF6rKn2gYCAv+Z0jUOJgmylXtPGJIuUn98TP1+89jI5CWnJxc7OR/x7EA6KgqfqsyXCClMQJC + Xi9Ns4swjMh6/+SIGhlVl0pU13mnqqwLhcD8w+H4916HgiDgAFBX/LB8dcVXB7pNQvxaSnTm1Z7IebpV + oAJgt4CcJ4E3mlS0CMoDOWYgASB6DBgQHyOif24KeZ8B2Uu9FOH2h0TU+MlS1bX+TnUPXijx+T/anJKS + o1+sy5HqFgAjRvj6/XD4fBMYJaS4URiIq/OxiKgupDSRI4X8wGcYT685K3Eb6jBQWOtK23X48MhmucVX + ConHVeT0Z3OfyD1WtwBYA0NMzD0cuSwtbXFJbf5+rQKgR1JSk+gS8zcwfI+qv9ixtn+fiIJCqovxXiHN + yYW54q3U1OT8mv7FGlfgvldeGSfyy+6HMEdD+BLdPmMiOokpM6TAU4gNf2Hd55/n1uSv1CgAdOVHQdkf + VX//IRho7vZ5ElE1TOSoOvq0jAl7piYhcMYASFLN/oJyjIRfjGHlJ2oAKgYHpxZF4J+pyafvDpw2AIYP + Hx6ZkVN8p3rTE6ryt3T7vIiohlR3AEKOT4yLmbN4cfUDg9UGgJ7Lv/OHjOFC4J/qTZ3cPh8iqh1TYrcQ + 5gPXXTVs8YQJE8xTvae6ABD9BibpRTyvqCv/peBoP1FDJE3Ir33CuHfNyuWpOMVkoVNW7AEDftai1CiZ + DlPczvv8RA1amV9iTqyvfExKSkr2yd+0BYCe219Qit+qq/9THPQjagRMZAtDju50dqvXT15WbAuAiy8d + cr4hjLnCQF+w6U/UGOiuwFohcfu6r5O3nfiNKhX8p7X849Wrj3BhD1FjIktVl35abKR88sQ9BaoEQP9B + Sf1MKd4SAt3cLi4ROcuUcjt8xq3rU5avq3ztWADoDT1alhoTTOl/2DAMn9uFJSJnWbsMGXJG5gH8de/e + ilbAsQDoNzDpAgm8K4To4XZBiSg4pJSp6gL/6zUrl2/Rf7YCQE/62XMg4yFpmpPAbbyIGi/TLJGGGNfl + 7FYz9R0BKwB6Dx7cMswf9qaKg6vcLh8RBZfflP8nw/y3bUxJybACoO9lSUOlFG8bQBu3C0dEwWUCh4SQ + t6xbmbxC6Ob/7gMZY00TEzjrj6jx04OBhk/8ufNZidPEhYOvjY/wF8wRAte7XTAiqiem+Lgsstmdou/A + pPMgxALVF+jqdpmIqH5IiR1CiOtFv0HDbpCmnC0MxLtdKCKqH6rOZwv47hB9Bw0dra7+U8Bn9RF5SZkK + gbGi38ChMyEw0u3SEFH98kPOFH0GDHnPMIwb3S4MEdUvCcwX/QcNWSFhJLldGCKqZwLLRd8BQzYKw+jl + dlmIqH6ZwAbRZ2DS94YQ3d0uDBHVu20qAIbuMgQ6u10SIqpnptwp+g0asgcwOrpdFiKqX9a24QwAIm9i + ABB5GAOAyMMYAEQexgAg8jAGAJGHMQCIPIwBQORhDAAiD2MAEHkYA4DIwxgARB7GACDyMAYAkYcxAIg8 + jAFA5GEMACIPYwAQeRgDgMjDGABEHsYAIPIwBgCRhzEAiDyMAUDkYQwAIg9jABB5GAOAyMMYAEQexgAg + 8jAGAFXL5/OhdetWaNqkidtFqZPi4mLkHc0HpDz2mv6daZrqJVnxVf3y+/0oV7/0V69hANAp6crfu9dF + uO3Wm5GQkOB2ceqkvLwcpaVlVV7zm34UFRZZXwvV1xIVEkfzjyInJxdZ2dnIzy9Abm4ujhzJxNGjR1Fm + HaPUCovGiAFANoZhWJX/7rvuRIcOHSCEcLtI9UK3AHRglJQUo6CgANk5Ofjxxx+xa/depKen4+DBdGRm + ZqK4pKTRBAIDgGxioqPxx1EjMXDAAM9U/tPRlb2oqAjZ2TnYt28ftqSmYtv27fhh/wEUqtcbchgwAMgm + NjYG48Y+got793a7KCFJdy1yVOsgLW0nvlm9Ghs3bkJWVpbqVjS8IGAAkA0DoGb0QKIeH9i5axeWr0jG + 6tVrkZWdpVoEMvCD1xMGANkwAGqvpKQEqVu3YuGnn2H9ho1WMDQEDACyYQDUjW4RZGdnY+Giz7BkyVLk + 5Oa6XaQzYgCQDQMgMMXFJUhZuRLvznsP6YcOWcEQqhgAZMMACJweKNRdgdlz5mLvvv1uF6daDACyYQA4 + Q88r2LDxO7z8r1dx4MBBt4tzSgwAsmEAOEe3BFauWoVXZ81BZmaW28WxYQCQDQPAWfoOwcefLMC789+3 + 1ieEEgYA2TAAnKcnDr3y6ix8+VVKSM0cZACQDQPAefpOwI4daXjqmWewf/8Bt4tzDAOAbBgAwaHHAxZ+ + ughzX38TJSEyUYgBQDYMgODJyMjAU/+Yic2b/41QmB3AACCbYASAbgLr22JuTYrRqxrDwsJc+W+fSPf/ + v1i+Ai++/C9rhaHbGABkE4wA0Jts6Oav3njDDYbPQEx0jBUC8fHN0SQ2Fs3imiEuLg5NmzS1zjkyMtLa + CyHYMjKOYOr0Gdi6bZsrn8WJGABkE4wA0Btq/OVvE12fEKNbAuHh4SoIfFYYhIeFI655HDq0a4f27duj + x/nnoUuXzmgSxG3QdEvoo48/wdw33rLGBdzEACCbxhwAp6O3QWvWrCku7tULN9xwHc7p0iVoLYIdaWl4 + cvI0a0zATQwAsvFqAFTSlb5L50644/bb0FuFQTBCQG859ven/oE1a9e5uliIAUA2Xg8ATXcVOnfqiN/d + ezd69ujh+NZouhuwcOGneG32XGtHYrcwAMiGAVBBV/qLe/fCqAcfCMrOyJs2bcbkadORl3fUtXNkAJAN + A+C4qMhIqytw3bXXON4VOHz4MJ54cjJ27d7j2vkxAMiGAVBVz549MPaRh5HQooWjx9ULg6ZM+7s1DuAW + BgDZMABO/jxiVQCMRt8+fRw9rr4FOGv2HHyycJFrC4SCFwBCN5e4p3y1pP4HD4XJoHYMgKr0fAH9hKQb + f/VLR7sButIvWLgQr86a69pjyYISAL7IFohsfSlEeDNXTir0SciSbJjlBSe8ZEL6Syq+p76a/jL1tQiy + 7GjF6/r70v9TcAQXA6AqPRg4aOAA/Gn0KERERDh2XH37T28n/syzz7k2IcjxADAiE9Ds3NsR0+EqCJ9z + H1ZjU3Hv94QWgBUAFSvEdIWXZlnF17J8mGV5KC86gvKj+1GetxPlBQfgL8lS/3rB+aFhANhd0LMHHh83 + Fs2aOXtR+3b1GkyeOh1lZWWBH6wOHA0AYYSjSffb0LTbTaryR7pyQo2W1QJQv8oLVQAcREnmJhQf+hpl + OTus15zsTjAA7Lqe0wXjH3sULVu2dPS4a9etx8RJUxpJAITFoHnvRxDTbqgrJ+MpqjvgL8lFScZ6FO5b + gtKsf6uXnNluigFg175dO4x//FG0O/tsR4/LAKDAqFaBvzgLRQdWoGDPJ6p18IPuXwR0SAaAXetWLVUA + jEOXzp0dPS4DgBwhzXKUZm/F0W2vozRzg/XnumIA2Okrv24B6JaAk1avWYtJU6YxAMgJUrUADuHo9rdQ + 9MPSn+4q1B4DwC4YYwB6IDj5y6/w9DPPNo67AAyA0KC7BHnfv46ifZ/VKQQYAHbBuAug5wEsXrIEL73y + GgOAnGWFwNbZKNq/RHUHarcBJQOgKj0PYNjQJDz4wP3WZiJO0ZX+nXfnYd789+FvDDMBGQChpbwgHbnf + zURxxupaTSBiAFQVHh6Gu+/6b1x7zdWOLgvWjxB/ZuY/kfxVimt7AjAAGjWJkswtyNkwDeX5NX9AJQOg + qpaJiXhs3Bh079bN0ePm5eVZqwFTt7q3NyADoJHTMwrzd36Ao9tm13ieAAPgOD33/z8uG4QH/nAfYmJi + HD32nj17MHHSVOsR4m5hAHhAeeFhZK99EqVZm2r0fgbAcS3i4zHqoQfQ5+KLHW3+6yb/qlVfW88IKC6p + 290aJzAAvED1/wt2L0Dulhdr1ApgAFSIjIjA9dddg1tuvhlRUc5Obdf3/WfPeR2fLPzU1WcFMgA8ojz/ + ALLW/BVluWlnfC8DANZo/2WDBuKuO+9AQoKzG4FoRzIz8eSkKdi+48z/HsHEAPAKs1y1AF5C/q4PrXUE + p+P1AIiKilKVfwBuuekmtG3bxvHj6+b/N99+q5r/z6KwsNDVcw3pACjL3an6rz8G5cTDolshPK6zKrQv + 4GOZZQWqf72lVtNvRVg0jIhm8Klf+nMTvigII/CyVE+iKH0lstdNgTxxH4JT8GIA6P69fjJQmzatMSxp + CK64/HLrCULBUFRcjBdefNl6RJibW4JrIRwAErmbn0fBvsVBOfGY9j9DXM97rIoXqLK83cj8Zry1br/G + n5URbi2Z1v/9sNh2iIg/V/3qoUKpixUMFTsqOassfz+yvvlf1R3Ye9r3NfYA8BkGfGFh1oNA9KafrVu3 + sub6673/9JOB2rRpE9TnCG7dug1Tps/AkSNH3P4oQjsAcjY+jYI9C4Jy4jEdr0Xzix5wJgBUS+XIyodh + lgbw3DtV4Y2IOBUA3RDT4T8R1foSGOHOPp5Kt1Sy101C8aFVp31fMAIgU/V5Z8153ZUfen0rLzo62qrw + +iqvr+z63n5iYoL6lWiN9OspvrrSO73//8n0A0H14N+ixUtcHfyrxAAIlQA4RlgVP6bDcDTpfgt8kfHO + nbQ0kbP5ORTs+kj9ofofvmAEgP5hz8/Pd+WHXldqvZWXDgJdySv39Qt2ZT+Zbu6vW7/e2gIsKyu73j+H + U2EAhFwAVNDdg9guN6LZubdZ4wXOkMjf+THy9O1As/p7z8EIAIL1HMBnn3tehcBGt4tyDAMgRANAMyJb + IP7iMYhqcwmc2mG5KH2V1Q043UAgA8B5RUXFmP/e+/jw40+sNQChggEQwgGgK310uysQ32sURHisI0cs + zUpF5jfjVFmrH7BkADhLr/rT6/5fnTUHublO/4wEhgEQ0gEA+GLaoEX/v1p3CZxQdnQPMleOgb+4+sdS + MwCco8c81q5bh3+9OgsHDqa7XRx7+RgAoR0AMMLR/MKRiO18HZzoBuh5FfpWYFnejmrfwwBwhn7Yx6bN + m60r/24Xn/93OgyAUA8AJbbLf/00ZyHw5yzojUKy1kxAaWb1C4MYAIHTc/31nv9vvPk2fjhwwPUJP9Vh + ADSAAIhsPRAt+j4GIyLweQG6jFlrn0TJ4TXVvocBEBi9zv/zZV9YC32OHMkM2cqvMQAaQACENzsHCYOm + whcV+DPqGQDBo5v8u3btxicLFuLrb7+1Rv5DHQOgAQSAL6YtEgdNQ1iTwLek1k8Rylo/FcUHv6z2PQyA + 2tEDfXqG41crV2Hp0mU4ePCga3v81brsDIAGEADRrZEwcLJqCQT+UAq9S3D2huko+mFZte9hANSMvuLr + Kc56lH9F8ldI27kLJS5u7lEXDAAGgA0D4MwqBvlWY8HCRVbFLy4O/eb+qTAAGAA2DIAz0wN7uqm/6LMl + 6ur/JXLzcgN9IpsrGAAMABsGQM3p1X0bNmy0pvhu37ED5eX+wA9ajxgADAAbBkDt6EHAA6o18JEKgS+/ + SkFhYZHbRap52RkADICTMQDqRt//112CjxcstH7fEDAAGAA2wdoPQA+U1XU/AL2Gv2Idv4Bexl/5Z/2r + vtf1n47e7mv58hV45935yMzKcrs4Z8QAYADYBCMAslRleOOtt5GZWbdKoTfqjImJ1tVf7+SBmOhoREZG + qNdi0bRpE8Q3b464uDg0bx5nPcBDbwCid/Z1Ixz0ct9ly77A62++jdwQbwkwABgANg1tT0Bd0fW+/ZER + kVZQtGyZiPbt2uGss85Cxw7t1de21pZf9RkIurXz4Uef4P0PPwzpGYEMAAaATUMLgOroPQB16yAxIQE9 + zj/f2vTz3O7dEB8fH9RNPyvl5ubhtdlzsHxFsjVpKBQxABgANo0lAE4kfuo2tGt3Ni695BIMGjjA2vM/ + 2EGwe88ezHj6GS4Hrj0GQCUGgLN0pdfbgF8+LAlDhvyH1UIIVtdAX/kXLlqE2XPeCKmtwCoxABgANo09 + ACrpgcKLe/fCr//rRnTr1tXqMgSD3gx06vQZ2Lrte7dP2YYBwACw8UoAaPo2YqeOHXDbb25B3z59gtIl + qGgFfIZZs+daawhCCQOAAWDjpQCopO8a/O6e/0GvXhcde26Ak/bv/wGTpkzDvv373T7VKhgADAAbLwaA + HgPQdwhGPnC/ahEEXBVs9DLhV1+bbT0RKJR2CGIAMABsvBgAmh4DuOLyYbj7rjvVZ+DMNuyVdKVPWbnK + eiqQXkAUKhgADAAbrwaA1rRpU6srMDRpiON3BvTy4b9NnIT9Pxxw+zSPYQAwAGy8HADaRRdegIdHj7Ju + DzpJzw7ULYCvUlaGTDeAAcAAsPF6AERHReF3996NK6+43NFWgF4I9eFHH1tPSWYAnBEDoBIDoH7pSn9J + /37440MjrS6Bk1avWYsZT/0D+QUFgR/MAQwABoCN1wNAax4Xh7FjHlbdgQsdPe6+ffvxxJOTcTA9NB4T + xgBgANgwACruCPzyFzfg9tt+4+gMwby8o9ZA4NZt29w+RQsDgAFgwwCocOEFPVUr4E/WXgNO0esBXnr5 + FSxZuiwkxgEYAAwAGwZABb25yOPjxlpLiZ2ipwW/9/4HeOOtd+q8O5KTGAAMABsGQAW9WOieu+7E1VcP + d+xugL7qL1u+AjOffS4k9ghgADAAbBgAFXSlv+LyoXjg/vus3YScsm79Bmt1YEEI3AlgADAAbBgAx13Q + s4f1WTR3cBwgLS0NT06ehsMZGW6fHgOAAWDHADiuTevW+PP4x9CxYwfHjqlvAT4xcXJIrAxkADAAbBgA + x+ltxB4bN9baOMQpOTk51meRlrbT7dNjADAA7BgAx+mBwPt+dw+uuvIKxwYCCwsLrc8iNXWr26fHAGAA + 2DEAjgsL81lbht1y802ObRSi9waY8fQ/sOrrb12fC8AAYADYMACO01f9YUOTMOrBBxybEagnA73w0stY + +vkXDIDqMQAqMQDc1b9fXzw65hHr4SNOKC8vt56S9P4HH7k+GYgBwACwYQBUpfcHeOzRMY6tDNQBMP+9 + 9/HWO/MYANVjAFRiALire7du1pTgxERnNgjRlf7TRZ/hlVdnuT4bkAHAALBhAFSldwwe//ij1sNEnKAD + YOnny/DcCy8xAKrHAKjEAHBXQot4/O/4x9Cta1fHjqm3BZs+42kGQPUYAJUYAO6Kioy0AqB3r4scO+ba + desxZar6dyh298nBDAAGgA0DoCo9GeiRh/+IgQMudWwy0Nat26wHhWRlZ7t6bgwABoANA6AqvRKwcjag + U5OB9uzZg4mTpiL90CFXz40BwACwYQBUpZ8X+Ntbb8GvfvULxwJAV3y9IGjvvn2unhsDgAFgwwCoyucz + cN011+B/7rrTsdmAekHQhCcmYfuOHa6eGwOAAWDDAKhKd/sHDhiAMX96WHUHnHl6sH5IyNRpM7B67VpX + z40BwACwYQDY6TsAejJQTEyMI8fTswHnzX8f78yb7+qtQAYAA8CGAWCnnxysAyDBwceFbdmyBVOmz0BW + lnt3AhgADAAbBoBdy8REjH/sUXTteo5jx9T7Arz40iv4YkWya6sCGQAMABsGgJ21Mcjv78VVDj4vsHJK + 8PMvvmx1CdzgbAAYEWh6/t1ocs4v1e8DGywxy/KRs+HvKDqYHJQTj2o9CPEXj4YRFWCTTiV38Y+rkbXu + Cciy4OzyakTGI77POES16lcxIhUAf3EmstdPRcnhNdV/NlGR+P299+DyYUMdGfXWV7fUrVsx7e9P4ciR + zKB8RsGmK/2ll/THqAf18wKbOHLMvKNH8dzzL2Dlqm8aRwtA88W2Q1yPexDVdlCdQ8BUFSl/5wco2DnP + CoJg0K2V2E4/R9PuN8GIiKvbQaSJ0uzvkfvv59XXLVYYBKewBiISLkJcz98jonn3OoeAWZKDvO1vo3Dv + Asjyour/c+r4nTp2wH/feTt69+oVUAjoH+y9e/fitdlzsWHjd64vfw2Efl7ggyP/YD04NNBWgP4cViR/ + iRdf/per24M7HgBamAqBmM6/QFh0yzr9/dLsVBTs/VRdUYNT+SvpEIhp/5+ITNQbPtb+H9QsL0ThnoUo + zUkNXuU/VlgVAvEXqK7L1TDC6jISrVoqGetRtH+p6gYUnfHd+ge8Y4f2uPaaq60n5NSV3v5q2Rcr8N2m + zQ268ld+JnpvgOE/uwphAd4OLCoqxoJPF2HHjjRXzykoAaArk+4OoK7dALNEXVzrqU8kwiB8EahLAOgW + gPTrxRz11XwTFWMWoi6z0aQqa6n6UvPPVf/A675vWAAtAFN9RsXFJa5vfeUUPRNQLw4KuAWgPhcdjqbZ + iLYEI6KGhQFA5GEMACIPYwAQeRgDgMjDGABEHsYAIPIwBgCRhzEAiDyMAUDkYQwAIg9jABB5GAOAyMMY + AEQexgAg8jAGAJGHMQCIPIwBQORhDAAiD2MAEHkYA4DIwxgARB7GACDyMAYAkYcxAIg8jAFA5GEMACIP + YwAQeRgDgMjDGABEHsYAIPIwBgCRhzEAiDyMAUDkYQwAIg9jABB5GAOAyMMYAEQexgAg8jAGAJGHMQCI + PIwBQORhDAAiD2MAEHkYA4DIw6wA6DNw6C5DoLPbhSGiembKnSoAkr43hOjudlmIqN5tE30HDNkoDKOX + 2yUhovplAhtE/0FDVkgYSW4XhojqmcBy0WfAkPcMw7jR7bIQUf2SwHzRb+DQmSoJRrpdGCKqX37ImaLv + oKGjBTBF/Tnc7QIRUb0pk6YcK/oNGnaD+s1sYSDe7RIRUf1QdT5bQN6hA+BcCblQtQK6ul0oIqofUmKH + EOJ6ceHga+Mj/AVzhMD1bheKiOqJKT4ui2x2pxgxYoRv94GMsaaJCYaBMLfLRUTBpep6ueGTf+58Vqtp + Qr/Q97KkoVKKtw2gjduFI6LgMoFD6mJ/89qUFclWAPQePLil8Pve9AlxlduFI6Lg8pvy/4xI/GZdcvIR + KwCsbsDBwyPhl1NgqG8RUeNkmiWAeLRz+1bPzp8/3y8qX+9/2bCepmnOE0L0cLuMRBQcqo5v8fl8N61Z + uXyL/vOxAOiYlBTVshQTTClGczCQqPHRg38w5IzMA/jr3r3Jxfo1ceIb+g9K6qcC4C0h0M3twhKRs0wp + t8Nn3Lo+Zfm6yteqBECSagUUlInHATlGfSvC7QITkVNkqarTU2PD5aTk5IqrvyZOflvfgUnnSSHmGkC/ + U32fiBocqf63BjBuX7tq+fcnfsNWwVUrIKygFL+VUszg+gCihk+ayDYMObrT2a1e1yP/J37vlFf4wYOv + jS/25083pbiDA4JEDZce+JMCs2N95WNSUlKyT/5+dU180W9gUk/VCnhZtQIGgF0BooZIXfzl174y4941 + a5anwuoKVFVtxf7LX/5iLFz65XBI+ZwQ6OT2mRBR7Ui97bdp/uHa4cOWTJgwwTzVe057ZR8+fHjkkdyS + O9SRJsJAS7dPiIhqRkIeNoDxCc2i5y5evLikuvedsWmflJTUJL9U/EFIjAUHBYlCnh70U3V1Slls+HOb + li4tON17a9S379v3yjgRWf4QTIxiCBCFMFX5hU88bRb7Zq5b93numd5e48E9HQKIKLtPSDGa3QGiEGQi + QwrMQGnYizWp/FqtRvd7qO5ATKlxqxRynPqLHWv794koKKQpsccn5OSCHLydmpqcX9O/WOsK3LXr8Mi4 + hJIrIMzxEqI/5wkQueenBT6rDb+cmJMZ80VaWvUDfqdSxyv4CF//y46cV27KUYbEjcJA87ofi4jqQEoT + OYD/PcMX9syalUO2Aqe+1Xc6gVRaceHgwc3DTd/P1W/vNyB7cQERUX3QC3uwUdX2F8oM/8ebU1JycIpJ + PjUR8FVbrx3IL0VXdaDbVIFGQIou7BYQOc9q7gu5C0LMMyDe6Hx2YtrJc/try7Fmu15KfNRv9FSlHCEk + rhdSnsPtxYgcYJol6uKaJmEsEGHivUyfuWXvCUt6A+F4v10HQWG5cY6EeZXfj6uFEBepxkkiWwVENVdx + tccRKeUmnxCLhCE+jwkzdyY7VPErBW3gTm80uiM9vUVYeVgP0ycGGX7/pdLQLQQkCANNwGcREp2oTJrI + h4FMYZpbTIhvVTN/VXlYeWq3tm2zAm3qV6deRu51GGxLT28W4fe1FsLoLk3zHNNAJx9EW9U6aGlKfRfB + jIYwIoTg3QRqvKTU0/TNUsAoMgRy1E97hnrhoLow7hU+mSZNsaM8Aoe6t2p1NFiV/kT/DzceTT8rx+sU + AAAAAElFTkSuQmCCKAAAAEAAAACAAAAAAQAgAAAAAAAAQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAABGODgSPzkzVEA5M59AODPLPjg03EA6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M98+ODTcQDgzy0A5M59AOjRTODg4EgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAFVVVQNBOTU+Pzg0uT86NPVAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + Pzo09T46NLg+OjY9VVVVAwAAAAAAAAAAAAAAAFVVVQM/OTNUPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz30A6NFNVVQADAAAAAAAAAABAODQ/Pjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjoyPQAAAABDNTUT + Pzg0uUA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/z46NLg4ODgSPzkzVUA6MvZAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8/OjT1QDo0Uz86NKFAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5M58+OTTMQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AODPL + Pzgy3UA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/Pjg03D46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTg + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0k+Nf+EVj7/k11A/5NdQP+RXD//YEc4/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/X0c4/5FcP/+TXUD/k11A/4dXPv9LPzX/QDo0/0A6NP9AOjT/QDo0/0E6NP9pSzr/ + klw//5NdQP+TXUD/f1Q9/0Y8Nf9AOjT/Y15Y/4uHgv+MiIP/jIiD/4mEf/9XUUz/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9TTUf/iIN//4yIg/+MiIP/jIiD/3FsZ/9CPDb/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9pSzn/8YRN//6KT//+ik// + /olP/6tmQ/9BOjT/QDo0/0A6NP9AOjT/QTo0/6llQ//+iU///opP//6KT//0hU3/bU06/0A6NP9AOjT/ + QDo0/0A6NP9FPDX/wnBG//6KT//+ik///opP/+mBS/9dRjj/Qz03/7Gtqf/u6+j/7uvo/+7r6P/t6uf/ + kY2J/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/i4eC/+zp5v/u6+j/ + 7uvo/+7r6P/AvLj/SEI8/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + bU06//WGTv//ik///4pP//+KT/+xaUT/QTo0/0A6NP9AOjT/QDo0/0E6NP+vaET//4pP//+KT///ik// + 94dO/3FPO/9AOjT/QDo0/0A6NP9AOjT/Rjw1/8hzR///ik///4pP//+KT//ug0z/YEc4/0Q+OP+3s6// + 7+zp/+/s6f/v7On/7+zp/5eTj/9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QTs1/6ejn//v7On/7+zp/+/s6f/v7On/op6Z/0E7Nf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPf + Pjo04EA6NP9AOjT/QDo0/21NOv/1hk7//4pP//+KT///ik//sWlE/0E6NP9AOjT/QDo0/0A6NP9BOjT/ + r2hE//+KT///ik///4pP//eHTv9xTzv/QDo0/0A6NP9AOjT/QDo0/0Y8Nf/Ic0f//4pP//+KT///ik// + 7oNM/2BHOP9EPjj/t7Ov/+/s6f/v7On/7+zp/+/s6f+Xk4//QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0Q+OP+2sq7/7+zp/+/s6f/v7On/7+zp/4+Lhv9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9tTTr/9YZO//+KT///ik///4pP/7FpRP9BOjT/ + QDo0/0A6NP9AOjT/QTo0/69oRP//ik///4pP//+KT//3h07/cU87/0A6NP9AOjT/QDo0/0A6NP9GPDX/ + yHNH//+KT///ik///4pP/+6DTP9gRzj/RD44/7ezr//v7On/7+zp/+/s6f/v7On/l5OP/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9IQjz/wr67/+/s6f/v7On/7+zp/+3q5/+Ef3v/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/bU06//WGTv//ik// + /4pP//+KT/+xaUT/QTo0/0A6NP9AOjT/QDo0/0E6NP+vaET//4pP//+KT///ik//94dO/3FPO/9AOjT/ + QDo0/0A6NP9AOjT/Rjw1/8hzR///ik///4pP//+KT//ug0z/YEc4/0Q+OP+3s6//7+zp/+/s6f/v7On/ + 7+zp/5eTj/9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/TklD/8/LyP/v7On/ + 7+zp/+/s6f/r6OX/eXRv/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/21NOv/1hk7//4pP//+KT///ik//sWlE/0E6NP9AOjT/QDo0/0A6NP9BOjT/r2hE//+KT///ik// + /4pP//eHTv9xTzv/QDo0/0A6NP9AOjT/QDo0/0Y8Nf/Ic0f//4pP//+KT///ik//7oNM/2BHOP9EPjj/ + t7Ov/+/s6f/v7On/7+zp/+/s6f+Xk4//QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/15YU//e29f/7+zp/+/s6f/v7On/5+Th/2xnYv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9tTTr/9YZO//+KT///ik///4pP/7FpRP9BOjT/QDo0/0A6NP9AOjT/ + QTo0/69oRP//ik///4pP//+KT//3h07/cU87/0A6NP9AOjT/QDo0/0A6NP9GPDX/yHNH//+KT///ik// + /4pP/+6DTP9gRzj/RD44/7ezr//v7On/7+zp/+/s6f/v7On/l5OP/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9/enX/6+jl/+/s6f/v7On/7+zp/93a1/9cVlH/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/bU06//WGTv//ik///4pP//+KT/+xaUT/ + QTo0/0A6NP9AOjT/QDo0/0E6NP+vaET//4pP//+KT///ik//94dO/3FPO/9AOjT/QDo0/0A6NP9AOjT/ + Rjw1/8hzR///ik///4pP//+KT//ug0z/YEc4/0Q+OP+3s6//7+zp/+/s6f/v7On/7+zp/5eTj/9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9JQz7/ubWx/+/s6f/v7On/7+zp/+/s6f/IxMH/ + TEZA/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/21NOv/1hk7/ + /4pP//+KT///ik//sWlE/0E6NP9AOjT/QDo0/0A6NP9BOjT/r2hE//+KT///ik///4pP//eHTv9xTzv/ + QDo0/0A6NP9AOjT/QDo0/0Y8Nf/Ic0f//4pP//+KT///ik//7oNM/2BHOP9EPjj/t7Ov/+/s6f/v7On/ + 7+zp/+/s6f+Xk4//QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9FPzn/ioWB/+fk4f/v7On/ + 7+zp/+/s6f/u6+j/nZiU/0I8Nv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/ + QDo0/0A6NP9tTTr/9YZO//+KT///ik///4pP/7FpRP9BOjT/QDo0/0A6NP9AOjT/QTo0/69oRP//ik// + /4pP//+KT//3h07/cU87/0A6NP9AOjT/QDo0/0A6NP9GPDX/yHNH//+KT///ik///4pP/+6DTP9gRzj/ + RD44/7ezr//v7On/7+zp/+/s6f/v7On/l5OP/0A7Nf9AOzX/QDs1/0E7Nf9BOzX/RD44/01IQv9nYVz/ + pJ+b/+Pg3f/v7On/7+zp/+/s6f/v7On/19TR/2BbVf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/bU06//WGTv//ik///4pP//+KT/+xaUT/QTo0/0A6NP9AOjT/ + QDo0/0E6NP+vaET//4pP//+KT///ik//94dO/3FPO/9AOjT/QDo0/0A6NP9AOjT/Rjw1/8hzR///ik// + /4pP//+KT//ug0z/YEc4/0Q+OP+3s6//7+zp/+/s6f/v7On/7+zp/8fEwP+gm5f/oJuX/6Cbl/+jn5r/ + qaWh/7i0sP/MycX/4t/c/+7r6P/v7On/7+zp/+/s6f/v7On/3dnW/314c/9CPDb/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/21NOv/1hk7//4pP//+KT///ik// + sWlE/0E6NP9AOjT/QDo0/0A6NP9BOjT/r2hE//+KT///ik///4pP//eHTv9xTzv/QDo0/0A6NP9AOjT/ + QDo0/0Y8Nf/Ic0f//4pP//+KT///ik//7oNM/2BHOP9EPjj/t7Ov/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/2tbT/3Vwa/9CPTf/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9tTTr/ + 9YZO//+KT///ik///4pP/7FpRP9BOjT/QDo0/0A6NP9AOjT/QTo0/69oRP//ik///4pP//+KT//3h07/ + cU87/0A6NP9AOjT/QDo0/0A6NP9IPTX/zHVI//+KT///ik///4pP/+yCTP9eRjj/RD44/7ezr//v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+bj4P+yrqr/YVtW/0E7Nf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTg + QDo0/0A6NP9AOjT/bU06//WGTv//ik///4pP//+KT/+xaUT/QTo0/0A6NP9AOjT/QDo0/0E6NP+vaET/ + /4pP//+KT///ik//94dO/3FPO/9AOjT/QDo0/0A6NP9AOjT/V0M3/+J+S///ik///4pP//+KT//mf0v/ + WEQ3/0Q+OP+3s6//7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7uvo/9HNyv9oY13/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/21NOv/1hk7//4pP//+KT///ik//smpE/0U7NP9EOzT/ + RDs0/0Q7NP9FOzT/sWlE//+KT///ik///4pP//eHTv90UDv/RDs0/0Q7NP9FPDX/VEI3/6RkQv/7iE7/ + /4pP//+KT///ik//2HpJ/05ANv9EPjj/t7Ov/+/s6f/v7On/7+zp/+/s6f/Z1dL/w7+7/8O/u//Dv7v/ + w7+7/8O/u//Dv7v/w7+8/8fDv//Rzsr/4t/c/+7r6P/v7On/7+zp/+/s6f/v7On/xMC8/1FLRf9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9tTTr/9YZO//+KT///ik// + /4pP/+V/S//Ab0b/v29G/79vRv+/b0b/wG9G/+R+S///ik///4pP//+KT//8iU//0HZI/79vRv+/b0b/ + xnJH/958Sv/6iE7//4pP//+KT///ik///4pP/7VrRP9DOzT/RD44/7ezr//v7On/7+zp/+/s6f/v7On/ + m5eT/0hCPP9IQjz/SEI8/0hCPP9IQjz/SEI8/0hCPP9JRD7/UEpF/2dhXP+zr6v/7Onm/+/s6f/v7On/ + 7+zp/+vo5f+Ef3r/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + bU06//WGTv//ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik// + /4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//CETf9zTzv/QDo0/0Q+OP+3s6// + 7+zp/+/s6f/v7On/7+zp/5eTj/9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + VU9J/87Kx//v7On/7+zp/+/s6f/v7On/tbGt/0Q+OP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPf + Pjo04EA6NP9AOjT/QDo0/21NOv/1hk7//4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik// + /4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//SFTf+YX0D/ + RTw1/0A6NP9EPjj/t7Ov/+/s6f/v7On/7+zp/+/s6f+Xk4//QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0E7Nf+loZ3/7+zp/+/s6f/v7On/7+zp/8zIxf9NR0H/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9pSzn/8IRN//2JT//9iU///YlP//2JT//9iU// + /YlP//2JT//9iU///YlP//2JT//9iU///YlP//2JT//9iU///YlP//2JT//9iU///IlP//uITv/4h07/ + 8IRN/9F2SP+CVT3/Rjw1/0A6NP9AOjT/RD44/7ezr//v7On/7+zp/+/s6f/v7On/l5OP/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/mZWQ/+/s6f/v7On/7+zp/+/s6f/Sz8v/ + UEpF/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/SD01/3xTPP+IWD7/ + iFg+/4hYPv+IWD7/iFg+/4hYPv+IWD7/iFg+/4hYPv+IWD7/iFg+/4hYPv+IWD7/iFg+/4hYPv+IWD7/ + iFg+/4NWPf9+VD3/dlA7/2VKOf9NPzb/QTo0/0A6NP9AOjT/QDo0/0Q+OP+3s6//7+zp/+/s6f/v7On/ + 7+zp/5eTj/9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Qjw2/6uno//v7On/ + 7+zp/+/s6f/v7On/zsrH/05IQv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9EPjj/ + t7Ov/+/s6f/v7On/7+zp/+/s6f+Xk4//QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/11YUv/U0c7/7+zp/+/s6f/v7On/7+zp/7m1sf9FPzn/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/RD44/7ezr//v7On/7+zp/+/s6f/v7On/pqOf/19ZVP9fWVT/X1lU/19ZVP9fWVT/ + X1lU/19ZVP9hW1b/amVg/4N+ef/Fwr7/7uvo/+/s6f/v7On/7+zp/+zp5v+Lh4L/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0Q+OP+3s6//7+zp/+/s6f/v7On/7+zp/+fk4f/g3dr/ + 4N3a/+Dd2v/g3dr/4N3a/+Dd2v/g3dr/4t7b/+bj4P/s6eb/7+zp/+/s6f/v7On/7+zp/+/s6f/PzMj/ + V1FL/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9EPjj/t7Ov/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/h3tr/e3Zx/0E7Nf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + RD44/7ezr//v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+3q5//V0s7/f3p1/0Q+OP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0M9N/+qpaH/6ufk/+rn5P/q5+T/6ufk/+rn5P/q5+T/6ufk/+rn5P/q5+T/ + 6ufk/+rn5P/q5+T/6ebi/+fk4P/i3tv/1tPP/8C8uP+Tj4r/XFZR/0I8Nv9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/VlBK/3Rvav91cGv/dXBr/3Vwa/91cGv/ + dXBr/3Vwa/91cGv/dXBr/3Vwa/91cGv/c25p/29qZf9rZmD/YVxX/1RPSf9IQjz/QTs1/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTg + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPf + Pjo04EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98/ODLdQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODTcPjk0zEA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDgzyz86NKFAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5M59COTNVQDoy9kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z86NPU/OTNUQzU1E0A5NLpAOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8/ODS5ODg4EgAAAABAODQ/ + Pzg04UA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+OjTg + QTk1PgAAAAAAAAAAVVVVAz85M1U/ODThQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP8+OjTgPzkzVFVVAAMAAAAAAAAAAAAAAABVVVUDQDg0P0A5NLpAOjL2QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6MvY/ODS5QTk1PlVVVQMAAAAAAAAAAPDw8BIAAAAAAAAAAAAAAABDNTUT + PzkzVT86NKE+OTTMPzgy3T46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA/ODLdPjk0zD86NKE/OTNVQzU1EwAAAAAAAAAAAAAAAAAAAADwAAAA + AAAAD8AAAAAAAAADgAAAAAAAAAGAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA + AAAAAYAAAAAAAAABwAAAAAAAAANwAAAAAAAADygAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACoqKgY9OTU+QDk0lz45M8w+ODTcQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3j44NNxAODPL + QDk0lz46Mj0qKioGAAAAAAAAAAAAAAAAOjo6DUE7NX0/OjTpQDo0/kA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/j86M+k/OTN8Ojo6DQAAAABVKioGQDg0fkA6MvZAOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjL2PzkzfCoqKgZBOTU+QDg06kA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pzoz6T46Nj0/OTSY + QDo0/kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/kA5NJc/OTTNQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A4M8s/ODLdQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z44NNxAOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9AOjT/QTo0/0E6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9BOjT/QTo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0E6NP9BOjT/QTo0/0A6NP9AOjT/QDo0/0E7Nf9BOzX/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9BOzX/QTs1/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9gSDn/qGVD/6xnQ/+hYkL/U0I3/0A6NP9AOjT/QDo0/2VJOf+pZkP/ + rGdD/6BiQf9RQTb/QDo0/0A6NP9AOjT/WkU4/6ZkQv+sZ0P/pmRC/1pFOP9JQz3/kIyH/6Ofm/+jn5v/ + hoF9/0Q+OP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/S0U//5OPi/+jn5v/o5+b/4qFgP9FPzn/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+LWj///olP//+KT//1hk7/bU07/0A6NP9AOjT/ + QDo0/5VeQP//ik///4pP//OFTf9pTDr/QDo0/0A6NP9AOjT/fVQ9//uITv//ik//+4hO/31UPf9YUkz/ + 2tfU/+/s6f/v7On/y8jE/0xGQf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ZF9a/+Pg3f/v7On/ + 7+zp/726tv9HQTv/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj///olP//+KT//2hk7/ + bk07/0A6NP9AOjT/QDo0/5ZeQP//ik///4pP//SFTf9qTDr/QDo0/0A6NP9AOjT/flQ9//uITv//ik// + +4hO/35UPf9YU03/29jV/+/s6f/v7On/zMnF/0xGQf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + cm1o/+rm4//v7On/7+zp/6ijn/9BOzX/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj// + /olP//+KT//2hk7/bk07/0A6NP9AOjT/QDo0/5ZeQP//ik///4pP//SFTf9qTDr/QDo0/0A6NP9AOjT/ + flQ9//uITv//ik//+4hO/35UPf9YU03/29jV/+/s6f/v7On/zMnF/0xGQf9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/gHt2/+3q5//v7On/7+zp/5yXk/9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP+MWj///olP//+KT//2hk7/bk07/0A6NP9AOjT/QDo0/5ZeQP//ik///4pP//SFTf9qTDr/ + QDo0/0A6NP9AOjT/flQ9//uITv//ik//+4hO/35UPf9YU03/29jV/+/s6f/v7On/zMnF/0xGQf9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/lZGM/+/s6f/v7On/7uvo/46Khf9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj///olP//+KT//2hk7/bk07/0A6NP9AOjT/QDo0/5ZeQP//ik// + /4pP//SFTf9qTDr/QDo0/0A6NP9AOjT/flQ9//uITv//ik//+4hO/35UPf9YU03/29jV/+/s6f/v7On/ + zMnF/0xGQf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9GQDr/uLSw/+/s6f/v7On/6+jl/3p1cP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj///olP//+KT//2hk7/bk07/0A6NP9AOjT/ + QDo0/5ZeQP//ik///4pP//SFTf9qTDr/QDo0/0A6NP9AOjT/flQ9//uITv//ik//+4hO/35UPf9YU03/ + 29jV/+/s6f/v7On/zMnF/0xGQf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9oY13/39zZ/+/s6f/v7On/ + 39zZ/2BbVf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj///olP//+KT//2hk7/ + bk07/0A6NP9AOjT/QDo0/5ZeQP//ik///4pP//SFTf9qTDr/QDo0/0A6NP9AOjT/flQ9//uITv//ik// + +4hO/35UPf9YU03/29jV/+/s6f/v7On/zMnF/0xGQf9AOjT/QDo0/0A6NP9BOzX/R0E7/2hiXf/Ewb3/ + 7uvo/+/s6f/v7On/uLSw/0hCPP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj// + /olP//+KT//2hk7/bk07/0A6NP9AOjT/QDo0/5ZeQP//ik///4pP//SFTf9qTDr/QDo0/0A6NP9AOjT/ + flQ9//uITv//ik//+4hO/35UPf9YU03/29jV/+/s6f/v7On/29jU/5CMh/+JhYD/ioaB/5CLh/+gnJf/ + vbm1/9/c2f/u6+j/7+zp/+7r6P/Qzcr/ZmBb/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP+MWj///olP//+KT//2hk7/bk07/0A6NP9AOjT/QDo0/5ZeQP//ik///4pP//SFTf9qTDr/ + QDo0/0A6NP9AOjT/flQ9//uITv//ik//+4hO/35UPf9YU03/29jV/+/s6f/v7On/7+zp/+7r6P/u6+j/ + 7uvo/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/93a1/92cWz/Qjw2/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj///olP//+KT//2hk7/bk07/0A6NP9AOjT/QDo0/5ZeQP//ik// + /4pP//SFTf9qTDr/QDo0/0A6NP9AOjT/jVo///2JT///ik//+YhO/3lSPP9YU03/29jV/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+3q5//Oysf/cm1o/0E7Nf9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj///olP//+KT//2hk7/c088/0c9Nf9HPTX/ + Rz01/5pgQf//ik///4pP//SFTf9vTjv/Rz01/0g9Nf9dRjj/y3RI//+KT///ik//9IVN/2tMOv9YU03/ + 29jV/+/s6f/v7On/5+Th/8zIxf/JxsL/ycbC/8nGwv/JxsL/ysfD/9LPy//j4N3/7uvo/+/s6f/v7On/ + 1dLO/2FbVv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj///olP//+KT//9iU// + 2HlJ/8t0SP/LdEj/y3RI/+N+S///ik///4pP//yJTv/XeUn/y3RI/892SP/lf0v//YlP//+KT///ik// + 3HtK/1NCN/9YU03/29jV/+/s6f/v7On/zsvH/1ZQS/9LRT//S0U//0tFP/9LRT//S0VA/1FLRf9rZmH/ + yMTA/+/s6f/v7On/7uvo/6Gdmf9CPDb/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP+MWj// + /olP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik///4pP//+KT///ik// + /4pP//+KT//1hk7/j1s//0I7NP9YU03/29jV/+/s6f/v7On/zMnF/0xGQf9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/enVw/+rn5P/v7On/7+zp/8jFwf9LRT//QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP+GVz7/+IZO//qITv/6iE7/+ohO//qITv/6iE7/+ohO//qITv/6iE7/+ohO//qITv/6iE7/ + +ohO//mITv/4h07/8oVN/9t7Sv+NWj//Rz01/0A6NP9YU03/29jV/+/s6f/v7On/zMnF/0xGQf9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ZF9a/+Tg3f/v7On/7+zp/9PQzP9QS0X/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9QQTb/d1E8/3pSPP96Ujz/elI8/3pSPP96Ujz/elI8/3pSPP96Ujz/ + elI8/3pSPP96Ujz/elI8/3dRPP9yTzv/aEs6/1JCN/9BOzT/QDo0/0A6NP9YU03/29jV/+/s6f/v7On/ + zMnF/0xGQf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/dG9q/+nm4//v7On/7+zp/87Lx/9OSEL/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9YU03/ + 29jV/+/s6f/v7On/zsvH/1ROSv9JQz3/SUM9/0lDPf9JQz3/SUM+/01HQf9hW1b/vLi0/+/s6f/v7On/ + 7+zp/7Ovq/9EPjj/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9YU03/29jV/+/s6f/v7On/5+Th/8nFwv/Gwr//xsK//8bCv//Gwr//x8O//83Kxv/e2tf/ + 7urn/+/s6f/v7On/5uPg/3hzbv9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9YU03/29jV/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/q5+T/op6Z/0dBO/9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9XUkz/2dbT/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+/s6f/v7On/7+zp/+7r6P/s6eb/5OHe/83Jxv+NiYT/S0U//0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9GQDr/gHt2/5GMiP+RjIj/ + kYyI/5GMiP+RjIj/kYyI/5GMiP+RjIj/jYiE/4iDfv97dnH/Z2Jc/09KRP9BOzX/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A5Mt4/ODLdQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z44NNw/OTTNQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z45NMw/OjOZQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/kA5NJdAODQ/ + QDg06kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + Pzo06T05NT5VKioGQDo0f0A4MvdAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjL2PjoyfioqKgYAAAAANjY2DkA6NH9AODTqQDo0/kA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/kA4NOo+OjR+Ojo6DQAAAAD///8IAAAAAFUqKgZAODQ/PzozmT86NM0/ODLd + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz3z84Mt0/OjTNPzo0mEE5NT4qKioGAAAAAAAAAADAAAAAAAMAAIAAAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAQAA + QAAAAAADAAAoAAAAKAAAAFAAAAABACAAAAAAAEAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJCPDcu + QDozjz45NMw/ODLdQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz3z84Mt1AODPLQDkzj0I3MS4AAAACAAAAAH8AAAI+OjROQDkz2kA6NP5AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP4/OTLZ + Pzk1TH8AAAJBOzYvQDoz2kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z85MtlCNzEuPzo1kEA6NP5AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT+QDozjz45NMxAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A4M8tAOTLeQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8/OTLdPjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9DOzT/ + X0c4/2hKOf9fRzj/Qzs0/0A6NP9AOjT/Sz41/2ZKOf9nSjn/VEI3/0A6NP9AOjT/QDo0/1JBNv9nSjn/ + Zko5/0w/Nv9GQDr/YFtV/2RfWv9eWFP/Qz04/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0pFP/9jXlj/ + ZF9a/1tWUP9CPDb/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/VEI3/9h5Sf/zhU3/2XpK/1RCN/9AOjT/ + QDo0/4BUPf/wg03/84VN/6tnQ/9COzT/QDo0/0E6NP+jY0L/8oVN//GETf+IWD7/ZF9Z/9nW0//k4d3/ + 0c7L/1hSTf9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP+Ef3r/4t/c/+Th3f+9urb/SUM9/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/1dEN//mf0v//4pP/+eATP9XRDf/QDo0/0A6NP+JWD7//YlP//+KT/+3bEX/ + Qjs0/0A6NP9BOjT/r2hE//+KT//+ik//kVw//2lkX//m4+D/7+zp/97b2P9cVlH/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/npqV/+/s6f/v7On/s6+r/0M9N/9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9XRDf/ + 5n9L//+KT//ngEz/V0Q3/0A6NP9AOjT/iVg+//2JT///ik//t2xF/0I7NP9AOjT/QTo0/69oRP//ik// + /opP/5FcP/9pZF//5uPg/+/s6f/e29j/XFZR/0A6NP9AOjT/QDo0/0A6NP9AOjT/Qjw2/62ppf/v7On/ + 7+zp/6ejn/9BOzX/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/V0Q3/+Z/S///ik//54BM/1dEN/9AOjT/ + QDo0/4lYPv/9iU///4pP/7dsRf9COzT/QDo0/0E6NP+vaET//4pP//6KT/+RXD//aWRf/+bj4P/v7On/ + 3tvY/1xWUf9AOjT/QDo0/0A6NP9AOjT/QDo0/0hCPP/Cv7v/7+zp/+/s6f+YlJD/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/1dEN//mf0v//4pP/+eATP9XRDf/QDo0/0A6NP+JWD7//YlP//+KT/+3bEX/ + Qjs0/0A6NP9BOjT/r2hE//+KT//+ik//kVw//2lkX//m4+D/7+zp/97b2P9cVlH/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9hXFb/3trX/+/s6f/s6eb/f3p1/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9XRDf/ + 5n9L//+KT//ngEz/V0Q3/0A6NP9AOjT/iVg+//2JT///ik//t2xF/0I7NP9AOjT/QTo0/69oRP//ik// + /opP/5FcP/9pZF//5uPg/+/s6f/e29j/XFZR/0A6NP9AOjT/QDo0/0E7Nf9TTUj/sKyo/+7r6P/v7On/ + 2tfU/1xXUf9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/V0Q3/+Z/S///ik//54BM/1dEN/9AOjT/ + QDo0/4lYPv/9iU///4pP/7dsRf9COzT/QDo0/0E6NP+vaET//4pP//6KT/+RXD//aWRf/+bj4P/v7On/ + 5OHe/5CLh/9+eXT/gHt2/4mEgP+inpr/zcrG/+zp5v/v7On/5uLf/5GMh/9DPTf/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/1dEN//mf0v//4pP/+eATP9XRDf/QDo0/0A6NP+JWD7//YlP//+KT/+3bEX/ + Qjs0/0A6NP9BOjT/sGlE//+KT//+ik//kFw//2lkX//m4+D/7+zp/+/s6f/t6uf/7ern/+3q5//u6+j/ + 7+zp/+/s6f/v7On/7uvo/7Wxrf9RS0b/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9XRDf/ + 5n9L//+KT//ngEz/V0Q3/0A6NP9AOjT/iVg+//2JT///ik//t2xF/0I7NP9AOjT/SD01/8ZyR///ik// + /YlP/4lZPv9pZF//5uPg/+/s6f/v7On/7uvo/+3q5//t6uf/7ern/+3q5//u6+j/7+zp/+/s6f/p5uP/ + rqqm/05IQv9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/V0Q3/+Z/S///ik//74NN/41aP/9+VD3/ + flQ9/69oQ//+iU///4pP/852SP9/VD3/gVU9/6pmQ//0hU3//4pP//aGTv9yTzv/aWRf/+bj4P/v7On/ + 5OHe/5SPi/+Cfnn/gn55/4J+ef+Dfnr/jYmE/7SwrP/o5eL/7+zp/+vo5f+Pi4b/QTs1/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/1dEN//mf0v//4pP//6KT//8iU7/+4hO//uITv/9iU///4pP//+KT//9iU// + +4hO//yJT//+ik///4pP//6KT//LdEj/T0A2/2lkX//m4+D/7+zp/97b2P9cVlH/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9JQz3/tLCs/+/s6f/v7On/xMC9/0lDPv9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9VQzf/ + 3nxK//iHTv/4h07/+IdO//iHTv/4h07/+IdO//iHTv/4h07/+IdO//iHTv/3h07/9YZO/+2CTP/CcEb/ + Ykg5/0A6NP9pZF//5uPg/+/s6f/e29j/XFZR/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/5GNiP/v7On/ + 7+zp/9PQzP9RS0b/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/RDw0/2lLOv9zTzv/c087/3NPO/9zTzv/ + c087/3NPO/9zTzv/c087/3NPO/9zTzv/cU87/2xNOv9gRzj/ST41/0A6NP9AOjT/aWRf/+bj4P/v7On/ + 3tvY/1xWUf9AOjT/QDo0/0A6NP9AOjT/QDo0/0M9N/+loZz/7+zp/+/s6f/Py8f/TkhD/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/2lkX//m4+D/7+zp/+Lf3P9+eXT/aWNe/2ljXv9pY17/ + aWNe/29pZP+QjIf/39vY/+/s6f/v7On/raml/0Q+OP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9pZF//5uPg/+/s6f/u6+j/5+Th/+bj4P/m4+D/5uPg/+bj4P/o5eL/7ern/+/s6f/v7On/ + 3NjV/2lkX/9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/aGNe/+bj4P/v7On/ + 7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/7+zp/+7r6P/o5eL/zMnF/3hzbv9CPDb/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/1FLRv+Xko7/oJuX/6Cbl/+gm5f/oJuX/6Cbl/+gm5f/ + npmV/5mUkP+LhoH/cWxn/1FMRv9BOzX/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz3z46NOBAOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjPfPjo04EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDoz30A5Mt5AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/z85Mt0/OjTNQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+OTTMPzo0kUA6NP5AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT+QDozjz86NTBAOjTbQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDoz2kI8MS5/AAACQDozT0A6M9pAOjT+QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT+QDoz2kE6NE5/AAAC1NTUBgAAAAJBOzYv + Pzo0kT86NM1AOTLePjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04EA5Mt4/OTTNPzozkEE7Ni8AAAACAAAAAIAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAKAAAACAAAABAAAAA + AQAgAAAAAACAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/NjYcQDo0g0A4M8s/ODLdQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3j84Mt1AOjLKQDoxgj82NhwAAAAAPT00HUA5M7c+ODL8QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODL8QDkytj82Nhw/OTSEPjgy/EA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODL8QDo0gj45NMxAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjLK + QDky3kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/z84Mt1AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDky3kA6M99AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOTLeQDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDky3kA6M99AOjT/Qjs0/0U8Nf9DOzT/ + QDo0/0A6NP9BOjT/RDw1/0Q8Nf9AOjT/QDo0/0A6NP9DOzT/RDw1/0I7NP9BOzX/RD44/0Q+OP9BOzX/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9CPDb/RD44/0M9N/9AOjT/QDo0/0A6NP9AOTLeQDoz30A6NP+IWD7/ + xHFH/59hQf9EPDX/QDo0/2VKOf/Ab0b/t2xF/1VDN/9AOjT/Rz01/6ZkQv/EcUf/gVU9/2hjXf+2sq// + s6+r/15ZU/9AOjT/QDo0/0A6NP9AOjT/Qz03/5GMh/+5tbH/oJyX/0hCPP9AOjT/QDo0/0A5Mt5AOjPf + QTo0/7BpRP//ik//0HZI/0g+Nf9AOjT/fFM8//uITv/whE3/Y0k5/0A6NP9NPzb/2XpK//+KT/+mZUL/ + gHt2/+3q5//p5uP/cWxm/0A6NP9AOjT/QDo0/0A6NP9JQz7/xsO//+/s6f+/u7f/RkE7/0A6NP9AOjT/ + QDky3kA6M99BOjT/sGlE//+KT//Qdkj/SD41/0A6NP98Uzz/+4hO//CETf9jSTn/QDo0/00/Nv/Zekr/ + /4pP/6ZlQv+Ae3b/7ern/+nm4/9xbGb/QDo0/0A6NP9AOjT/QDo0/1BKRf/Szsv/7+zp/7Kuqv9CPTf/ + QDo0/0A6NP9AOTLeQDoz30E6NP+waUT//4pP/9B2SP9IPjX/QDo0/3xTPP/7iE7/8IRN/2NJOf9AOjT/ + TT82/9l6Sv//ik//pmVC/4B7dv/t6uf/6ebj/3FsZv9AOjT/QDo0/0A6NP9AOjT/YlxX/+Dd2v/v7On/ + oZ2Z/0E7Nf9AOjT/QDo0/0A5Mt5AOjPfQTo0/7BpRP//ik//0HZI/0g+Nf9AOjT/fFM8//uITv/whE3/ + Y0k5/0A6NP9NPzb/2XpK//+KT/+mZUL/gHt2/+3q5//p5uP/cWxm/0A6NP9AOjT/QDo0/0dBO/+emZX/ + 7ern/+vo5f9+enX/QDo0/0A6NP9AOjT/QDky3kA6M99BOjT/sGlE//+KT//Qdkj/SD41/0A6NP98Uzz/ + +4hO//CETf9jSTn/QDo0/00/Nv/Zekr//4pP/6ZlQv+Ae3b/7ern/+vo5f+Wko3/dG9q/3dybf+Hg37/ + tK+s/+fj4P/t6uf/vbq2/1BLRf9AOjT/QDo0/0A6NP9AOTLeQDoz30E6NP+waUT//4pP/9B2SP9IPjX/ + QDo0/3xTPP/7iE7/8IRN/2NJOf9AOjT/TkA2/9t7Sv//ik//pWRC/4B7dv/t6uf/7+zp/+zp5f/q5+T/ + 6+jl/+7r6P/v7On/7+zp/+Tg3f+BfHf/Qz03/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQTo0/7BpRP//ik// + 03dI/1NCNv9LPzb/hFY9//uITv/xhE3/bE06/0w/Nv90UDv/7oNN//+KT/+YX0D/gHt2/+3q5//u6+j/ + 2NXR/8/LyP/Py8j/z8zI/9TQzf/l4d7/7+zp/93a1/90b2r/QDo0/0A6NP9AOjT/QDky3kA6M99BOjT/ + sGlE//+KT//1hk3/13lJ/9V4Sf/ifkv//opP//yJT//dfEr/13lJ/+2CTP/+ik//8oVN/3FOO/+Ae3b/ + 7ern/+nm4/97dnD/TkhC/05IQv9OSEL/UUxG/3hzbv/f29j/7+zp/7y4tP9HQTz/QDo0/0A6NP9AOTLe + QDoz30E6NP+oZkP/9YZO//WGTv/1hk7/9YZO//WGTv/1hk7/9YZO//WGTv/1hk7/8oVN/+N+S/+VXkD/ + Rjw1/4B7dv/t6uf/6ebj/3FsZv9AOjT/QDo0/0A6NP9AOjT/SEI8/8K/u//v7On/09DM/1FLRf9AOjT/ + QDo0/0A5Mt5AOjPfQDo0/1dEN/9tTTr/bU06/21NOv9tTTr/bU06/21NOv9tTTr/bU06/2xMOv9nSjn/ + V0Q3/0M7NP9AOjT/gHt2/+3q5//p5uP/cWxm/0A6NP9AOjT/QDo0/0E7Nf9VT0r/0MzJ/+/s6f/Oysf/ + TkhC/0A6NP9AOjT/QDky3kA6M99AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP+Ae3b/7ern/+zp5v+1sa3/n5qW/5+alv+fmpb/pKCc/8TBvf/s6eb/ + 7uvo/6Sfm/9DPTf/QDo0/0A6NP9AOTLeQDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/4B7dv/t6uf/7+zp/+/s6f/v7On/7+zp/+/s6f/v7On/ + 7+zp/+rn5P+/u7f/WFNN/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Y15Y/6uno/+uqqb/rqqm/66qpv+uqqb/ + raml/6mlof+bl5L/enVw/09KRP9AOjT/QDo0/0A6NP9AOjT/QDky3kA6M99AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Qjw2/0I8Nv9CPDb/ + Qjw2/0I8Nv9CPDb/QTs1/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOTLeQDoz30A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPf + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDky3kA5Mt5AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP8/ODLdPjk0zEA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A4M8s/OTSEPjgy/EA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP8+ODL8QDo0gz09NB0+OjS4Pjgy/EA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pjgy/EA6M7c/NjYc////Az09NB0/OTSEPjk0zEA5Mt5AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDky3j45NMxAOjSDPT00HQAAAACAAAABAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASgAAAAYAAAA + MAAAAAEAIAAAAAAAYAkAAAAAAAAAAAAAAAAAAAAAAABFLi4LPzszbD86NMlAOTLeQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A5Mt4+OTTI + QDk0a0UuLgs/OjNtPzo09UA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pjk09EA5NGs/OjTJQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/z45NMhAOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5M94+OjTg + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTgTD82/3dRPP9gRzj/ + QDo0/05ANv93UTz/X0c4/0A6NP9LPzb/dlA7/2NIOf9aVE7/dXBr/1VQSv9AOjT/QDo0/0A6NP9HQTv/ + b2lk/2xmYf9EPjj/QDo0/0A6M98+OjTgbEw6//GETf+tZ0P/QTo0/3BOO//zhU3/qmZD/0E6NP9nSjr/ + 74NM/7ZrRP+Zk47/6ufk/4qFgP9AOjT/QDo0/0A6NP9fWlT/3dnW/8XBvf9KRD7/QDo0/0A6M98+OjTg + bk06//aGTv+xaUT/QTo0/3JPO//4h07/rmhE/0E6NP9pSzr/9IVN/7ptRf+clpH/7+zp/42Ig/9AOjT/ + QDo0/0A6NP9taGP/5+Th/7y4tf9FPzn/QDo0/0A6M98+OjTgbk06//aGTv+xaUT/QTo0/3JPO//4h07/ + rmhE/0E6NP9pSzr/9IVN/7ptRf+clpH/7+zp/42Ig/9AOjT/QDo0/0I8Nv+Uj4v/7uvn/6ainv9BOzX/ + QDo0/0A6M98+OjTgbk06//aGTv+xaUT/QTo0/3JPO//4h07/rmhE/0E6NP9pSzr/9IVN/7ptRf+clpH/ + 7+zp/6WhnP9sZmH/cm1o/5WRjP/d2tb/3trX/29pZP9AOjT/QDo0/0A6M98+OjTgbk06//aGTv+xaUT/ + QTo0/3JPO//4h07/rmhE/0E6NP9uTTv/9YZN/7hsRf+clpH/7+zp/+rn5P/n5OH/6ebj/+7r6P/v7On/ + xMC9/1dSTP9AOjT/QDo0/0A6M98+OjTgbk06//aGTv/Pdkj/i1k+/6lmQ//7iE7/znVI/41aP//BcEb/ + /IlP/6FjQv+alpH/7+zp/7ezr/+LhoL/i4aC/5CMh/++urf/7Onm/6qmov9FPzn/QDo0/0A6M98+OjTg + aks6/+qBTP/yhU3/8YRN//KETf/zhU3/8oRN//GETf/ug03/y3RI/15HOP+alpH/7+zp/42Ig/9AOjT/ + QDo0/0A6NP9lX1r/49/c/9LPy/9QS0X/QDo0/0A6M98+OjTgSD01/2VJOf9nSjn/Z0o5/2dKOf9nSjn/ + Z0o5/2dKOf9hSDn/TT82/0A6NP+alpH/7+zp/5WQi/9OSUP/TklD/1BKRf+Ae3b/5+Th/8zJxf9OSEL/ + QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP+alpH/ + 7+zp/97a1//QzMn/0MzJ/9LPy//j4N3/6OXi/5GNiP9CPDb/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP98eHL/u7i0/7y4tP+8uLT/u7i0/7m1sf+qpqL/ + fXh0/0hCPP9AOjT/QDo0/0A6M98+OjTgQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9CPDb/RT85/0U/Of9FPzn/RT85/0Q+OP9CPDb/QDo0/0A6NP9AOjT/QDo0/0A6M98+OjTg + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6M99AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5M95AOjLKQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/z86NMlAOTJuPzo09UA6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/Pzo09T87M2xiTk4NQDkybkA6MspAOjPfPjo04D46NOA+OjTgPjo04D46NOA+OjTg + Pjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04D46NOA+OjTgPjo04EA6M98/OjTJPzozbUVFLgsAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAFAAAACgAAAABACAAAAAAAJAGAAAAAAAA + AAAAAAAAAAAAAAAAPzc3ID85NJw+ODLYQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLe + QDky3kA5Mt5AOTLeQDky3kA5Mt4+ODLYQDk0m0E5MR8/OjKdPzk0/UA6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8/OTT9QDk0mz85MtlAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP8+ODLYQDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDky3kA6M99AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOTLeQDoz33NPO/+cYUH/TD82/1hEN/+jY0L/Ykg5/0Q8NP+PWz//iFg+/3p0bv+Xko7/ + TUdB/0A6NP9AOjT/WFNN/52Zlf9oY13/QDo0/0A5Mt5AOjPfn2JB/+aATP9YRDf/bU06//KFTf9/VD3/ + SD41/9B2SP/Eckf/q6Wf/9zY1f9ZU07/QDo0/0A6NP93cm3/6OXi/3t2cf9AOjT/QDky3kA6M9+fYkH/ + 5oBM/1hEN/9tTTr/8oVN/39UPf9IPjX/0HZI/8RyR/+rpZ//3NjV/1lTTv9AOjT/QTs1/5WQjP/m49// + bGZh/0A6NP9AOTLeQDoz359iQf/mgEz/WEQ3/21NOv/yhU3/f1Q9/0g+Nf/Qdkj/xHJH/6uln//g3Nn/ + enVx/2plYP+GgX3/19PQ/8TAvf9QSkX/QDo0/0A5Mt5AOjPfn2JB/+aATP9aRTf/bk46//KFTf+AVD3/ + T0E2/9Z5Sf/BcUf/qqSf/+3q5//f3Nn/3tvX/+Th3v/r6OX/q6ej/0pEPv9AOjT/QDky3kA6M9+fYkH/ + 9oZO/8JwRv/KdEf/+ohO/9B2SP/Ic0f/9IVN/55iQv+oo5//4NzZ/3x3cv9pZF//bGdi/6ejn//n5OD/ + eXRv/0A6NP9AOTLeQDoz33hRPP+0akT/tGpE/7RqRP+0akT/tGpE/7FpRP+VXUD/UUE3/6ejn//c2NX/ + WVNO/0E7Nf9BOzX/eHNu/+rm4/+OioX/QDo0/0A5Mt5AOjPfQDo0/0E6NP9BOjT/QTo0/0E6NP9BOjT/ + QTo0/0A6NP9BOzX/p6Of/+fj4P+wrKj/pqGd/6mkoP/Oysf/4N3Z/2xnYf9AOjT/QDky3kA6M99AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0E7Nf+KhYH/wb26/8G9uv/Bvbr/v7u4/7GsqP95dG// + RD44/0A6NP9AOTLeQDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0M9N/9HQTv/ + R0E7/0dBO/9GQDr/Qz03/0A6NP9AOjT/QDo0/0A5Mt5AOjPfQDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDky3j85MtlAOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP8+ODLYQDoznj85NP1AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/Pzk0/T85NJxDPDwiQDoznj85MtlAOjPfQDoz30A6M99AOjPf + QDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz3z85Mtk/OjKdPzc3IAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAD47M0VAODTC + Pzgy3UA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt5AOTLeQDky3kA5Mt4/ODLdPzozwT84NERAOTTD + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8/OjPB + QDkz3kA6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + Pzky3UA6M99AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A5Mt5AOjPfSD41/0Q8Nf9COzT/Sj41/0I7NP9FPDX/SD41/0dBO/9GQDv/QDo0/0A6NP9EPjj/ + SUM9/0E7Nf9AOTLeSDs037BpRP98Uz3/YEc5/75vRv9WQzf/gVU9/69qRv+gmZP/lI+L/0E7Nf9AOjT/ + eHNt/7CsqP9LRT//QDky3ko8NN/Pdkj/jVo//2lLOv/gfUv/XUY4/5RdQP/Od0v/u7Ot/6uno/9BOzX/ + QTs1/5uWkv/EwLz/SEI8/0A5Mt5KPDTfz3ZI/41aP/9pSzr/4H1L/11GOP+UXUD/zndL/7uzrf+5tbH/ + ZWBa/3l0b//PzMj/m5eS/0I8Nv9AOTLeSjw03892SP+XXkD/dlA8/+N+S/9sTDr/qGVD/8p1Sv+6sq3/ + 4N3a/8nGwv/Rzcr/4d7b/42Ig/9CPDb/QDky3kk8NN/EcUb/3HtK/9Z5Sf/qgUz/1XhJ/918Sv+SXkL/ + tbCs/7Kuqv9STUf/U05I/56alf/Oy8f/T0lE/0A5Mt5BOjPfWUQ3/2JIOf9iSDn/Ykg5/2JIOf9aRTj/ + SD84/7SwrP+/u7j/dG9q/3ZxbP+1sa3/x8TA/0xGQf9AOTLeQDoz30A6NP9AOjT/QDo0/0A6NP9AOjT/ + QDo0/0I8Nv+YlI//xcG+/8K+u//Bvbr/tbGt/29qZP9BOzX/QDky3kA6M99AOjT/QDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/RkA6/0lDPf9JQz3/SEM9/0Q+OP9AOjT/QDo0/0A5Mt5AOTPeQDo0/0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP8/OTLdQDk0w0A6NP9AOjT/ + QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDo0/0A6NP9AOjT/QDgzwkA9NUdAOTTD + QDky3kA6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOjPfQDoz30A6M99AOTLeQDk0wz47M0UAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + \ No newline at end of file diff --git a/mRemoteV1/UI/Window/BaseWindow.cs b/mRemoteV1/UI/Window/BaseWindow.cs index fdf19d9dd..877456ebd 100644 --- a/mRemoteV1/UI/Window/BaseWindow.cs +++ b/mRemoteV1/UI/Window/BaseWindow.cs @@ -29,7 +29,7 @@ namespace mRemoteNG.UI.Window } #endregion - internal new void ApplyTheme() + internal void ApplyTheme() { _themeManager = ThemeManager.getInstance(); if (!_themeManager.ThemingActive) return; @@ -37,21 +37,34 @@ namespace mRemoteNG.UI.Window ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); } - + #region Private Methods -/* - private void Base_Load(object sender, EventArgs e) - { - FrmMain.Default.ShowHidePanelTabs(); - } -*/ - -/* - private void Base_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e) - { - FrmMain.Default.ShowHidePanelTabs(this); - } -*/ + /* + private void Base_Load(object sender, EventArgs e) + { + FrmMain.Default.ShowHidePanelTabs(); + } + */ + + /* + private void Base_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e) + { + FrmMain.Default.ShowHidePanelTabs(this); + } + */ #endregion - } + + private void InitializeComponent() + { + this.SuspendLayout(); + // + // BaseWindow + // + this.ClientSize = new System.Drawing.Size(284, 261); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Name = "BaseWindow"; + this.ResumeLayout(false); + + } + } } \ No newline at end of file diff --git a/mRemoteV1/UI/Window/BaseWindow.resx b/mRemoteV1/UI/Window/BaseWindow.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/mRemoteV1/UI/Window/BaseWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ComponentsCheckWindow.cs b/mRemoteV1/UI/Window/ComponentsCheckWindow.cs index 43c7efa78..9e70cde86 100644 --- a/mRemoteV1/UI/Window/ComponentsCheckWindow.cs +++ b/mRemoteV1/UI/Window/ComponentsCheckWindow.cs @@ -344,7 +344,7 @@ namespace mRemoteNG.UI.Window this.chkAlwaysShow.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.chkAlwaysShow.Location = new System.Drawing.Point(12, 814); this.chkAlwaysShow.Name = "chkAlwaysShow"; - this.chkAlwaysShow.Size = new System.Drawing.Size(185, 17); + this.chkAlwaysShow.Size = new System.Drawing.Size(200, 17); this.chkAlwaysShow.TabIndex = 51; this.chkAlwaysShow.Text = "Always show this screen at startup"; this.chkAlwaysShow.UseVisualStyleBackColor = true; @@ -374,6 +374,7 @@ namespace mRemoteNG.UI.Window this.Controls.Add(this.pnlChecks); this.Controls.Add(this.chkAlwaysShow); this.Controls.Add(this.btnCheckAgain); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Icon = global::mRemoteNG.Resources.ComponentsCheck_Icon; this.Name = "ComponentsCheckWindow"; this.TabText = "Components Check"; diff --git a/mRemoteV1/UI/Window/ConfigWindow.cs b/mRemoteV1/UI/Window/ConfigWindow.cs index eb3f2ca5a..cacf7cf16 100644 --- a/mRemoteV1/UI/Window/ConfigWindow.cs +++ b/mRemoteV1/UI/Window/ConfigWindow.cs @@ -46,7 +46,7 @@ namespace mRemoteNG.UI.Window private AbstractConnectionRecord _selectedTreeNode; public AbstractConnectionRecord SelectedTreeNode { - get { return _selectedTreeNode; } + get => _selectedTreeNode; set { _selectedTreeNode = value; @@ -207,11 +207,8 @@ namespace mRemoteNG.UI.Window #region Public Properties public bool PropertiesVisible { - get - { - return _btnShowProperties.Checked; - } - set + get => _btnShowProperties.Checked; + set { _btnShowProperties.Checked = value; if (!value) return; @@ -223,11 +220,8 @@ namespace mRemoteNG.UI.Window public bool InheritanceVisible { - get - { - return _btnShowInheritance.Checked; - } - set + get => _btnShowInheritance.Checked; + set { _btnShowInheritance.Checked = value; if (!value) return; @@ -239,11 +233,8 @@ namespace mRemoteNG.UI.Window public bool DefaultPropertiesVisible { - get - { - return _btnShowDefaultProperties.Checked; - } - set + get => _btnShowDefaultProperties.Checked; + set { _btnShowDefaultProperties.Checked = value; if (!value) return; @@ -255,8 +246,8 @@ namespace mRemoteNG.UI.Window public bool DefaultInheritanceVisible { - get { return _btnShowDefaultInheritance.Checked; } - set + get => _btnShowDefaultInheritance.Checked; + set { _btnShowDefaultInheritance.Checked = value; if (!value) return; @@ -283,6 +274,7 @@ namespace mRemoteNG.UI.Window WindowType = WindowType.Config; DockPnl = panel; InitializeComponent(); + ApplyLanguage(); } #endregion @@ -431,14 +423,11 @@ namespace mRemoteNG.UI.Window _btnIcon.Image = null; - var gridObjectAsConnectionInfo = propertyGridObject as ConnectionInfo; - if (gridObjectAsConnectionInfo != null) //CONNECTION INFO + if (propertyGridObject is ConnectionInfo gridObjectAsConnectionInfo) //CONNECTION INFO { - var gridObjectAsContainerInfo = propertyGridObject as ContainerInfo; - if (gridObjectAsContainerInfo != null) //CONTAINER + if (propertyGridObject is ContainerInfo gridObjectAsContainerInfo) //CONTAINER { - var gridObjectAsRootNodeInfo = propertyGridObject as RootNodeInfo; - if (gridObjectAsRootNodeInfo != null) // ROOT + if (propertyGridObject is RootNodeInfo gridObjectAsRootNodeInfo) // ROOT { // ReSharper disable once SwitchStatementMissingSomeCases switch (gridObjectAsRootNodeInfo.Type) @@ -616,20 +605,18 @@ namespace mRemoteNG.UI.Window private new void ApplyTheme() { - if (Themes.ThemeManager.getInstance().ThemingActive) - { - _pGrid.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); - _pGrid.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); - _pGrid.ViewBackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Background"); - _pGrid.ViewForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Foreground"); - _pGrid.LineColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Border"); - _pGrid.HelpBackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); - _pGrid.HelpForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); - _pGrid.CategoryForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Header_Foreground"); - _pGrid.CommandsDisabledLinkColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Disabled_Foreground"); - _pGrid.CommandsBackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Disabled_Background"); - _pGrid.CommandsForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Disabled_Foreground"); - } + if (!ThemeManager.getInstance().ThemingActive) return; + _pGrid.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); + _pGrid.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); + _pGrid.ViewBackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Background"); + _pGrid.ViewForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Foreground"); + _pGrid.LineColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Border"); + _pGrid.HelpBackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); + _pGrid.HelpForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); + _pGrid.CategoryForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Header_Foreground"); + _pGrid.CommandsDisabledLinkColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Disabled_Foreground"); + _pGrid.CommandsBackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Disabled_Background"); + _pGrid.CommandsForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("List_Item_Disabled_Foreground"); } private void AddToolStripItems() @@ -685,7 +672,6 @@ namespace mRemoteNG.UI.Window private void Config_Load(object sender, EventArgs e) { - ApplyLanguage(); _themeManager = ThemeManager.getInstance(); _themeManager.ThemeChanged += ApplyTheme; ApplyTheme(); @@ -716,8 +702,7 @@ namespace mRemoteNG.UI.Window private void UpdateConnectionInfoNode(PropertyValueChangedEventArgs e) { Debug.WriteLine("update config"); - var selectedGridObject = _pGrid.SelectedObject as ConnectionInfo; - if (selectedGridObject == null) return; + if (!(_pGrid.SelectedObject is ConnectionInfo selectedGridObject)) return; if (e.ChangedItem.Label == Language.strPropertyNameProtocol) { selectedGridObject.SetDefaultPort(); @@ -748,8 +733,7 @@ namespace mRemoteNG.UI.Window private void UpdateRootInfoNode(PropertyValueChangedEventArgs e) { - var rootInfo = _pGrid.SelectedObject as RootNodeInfo; - if (rootInfo == null) + if (!(_pGrid.SelectedObject is RootNodeInfo rootInfo)) return; if (e.ChangedItem.PropertyDescriptor?.Name != "Password") @@ -795,8 +779,7 @@ namespace mRemoteNG.UI.Window try { var strHide = new List(); - var o = _pGrid.SelectedObject as RootNodeInfo; - if (o != null) + if (_pGrid.SelectedObject is RootNodeInfo o) { var rootInfo = o; if (rootInfo.Type == RootNodeType.PuttySessions) @@ -1456,8 +1439,7 @@ namespace mRemoteNG.UI.Window private void btnShowProperties_Click(object sender, EventArgs e) { - var o = _pGrid.SelectedObject as ConnectionInfoInheritance; - if (o != null) + if (_pGrid.SelectedObject is ConnectionInfoInheritance o) { if (_pGrid.SelectedObject is DefaultConnectionInheritance) { @@ -1633,8 +1615,7 @@ namespace mRemoteNG.UI.Window { _btnHostStatus.Image = Resources.HostStatus_Check; // To check status, ConnectionInfo must be an mRemoteNG.Connection.Info that is not a container - var info = connectionInfo as ConnectionInfo; - if (info == null) return; + if (!(connectionInfo is ConnectionInfo info)) return; if (info.IsContainer) return; _btnHostStatus.Tag = "checking"; diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs index 2135b1efb..ded8c93e5 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs @@ -32,13 +32,13 @@ namespace mRemoteNG.UI.Window this.mMenViewCollapseAllFolders = new System.Windows.Forms.ToolStripMenuItem(); this.mMenSortAscending = new System.Windows.Forms.ToolStripMenuItem(); this.vsToolStripExtender = new WeifenLuo.WinFormsUI.Docking.VisualStudioToolStripExtender(this.components); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.PictureBoxSearch = new Controls.Base.NGPictureBox(); this.txtSearch = new mRemoteNG.UI.Controls.Base.NGTextBox(); - this.PictureBox1 = new System.Windows.Forms.PictureBox(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); ((System.ComponentModel.ISupportInitialize)(this.olvConnections)).BeginInit(); this.msMain.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.PictureBoxSearch)).BeginInit(); this.tableLayoutPanel1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.PictureBox1)).BeginInit(); this.SuspendLayout(); // // olvConnections @@ -46,7 +46,6 @@ namespace mRemoteNG.UI.Window this.olvConnections.AllowDrop = true; this.olvConnections.BorderStyle = System.Windows.Forms.BorderStyle.None; this.olvConnections.CellEditUseWholeCell = false; - this.tableLayoutPanel1.SetColumnSpan(this.olvConnections, 2); this.olvConnections.ConnectionTreeModel = connectionTreeModel1; this.olvConnections.Cursor = System.Windows.Forms.Cursors.Default; this.olvConnections.Dock = System.Windows.Forms.DockStyle.Fill; @@ -57,7 +56,7 @@ namespace mRemoteNG.UI.Window this.olvConnections.IsSimpleDragSource = true; this.olvConnections.IsSimpleDropSink = true; this.olvConnections.LabelEdit = true; - this.olvConnections.Location = new System.Drawing.Point(3, 3); + this.olvConnections.Location = new System.Drawing.Point(0, 24); this.olvConnections.MultiSelect = false; this.olvConnections.Name = "olvConnections"; this.olvConnections.NodeDeletionConfirmer = alwaysConfirmYes1; @@ -67,7 +66,7 @@ namespace mRemoteNG.UI.Window this.olvConnections.ShowGroups = false; treeNodeCompositeClickHandler2.ClickHandlers = new mRemoteNG.Tree.ITreeNodeClickHandler[0]; this.olvConnections.SingleClickHandler = treeNodeCompositeClickHandler2; - this.olvConnections.Size = new System.Drawing.Size(381, 365); + this.olvConnections.Size = new System.Drawing.Size(204, 366); this.olvConnections.TabIndex = 20; this.olvConnections.UnfocusedSelectedBackColor = System.Drawing.SystemColors.Highlight; this.olvConnections.UnfocusedSelectedForeColor = System.Drawing.SystemColors.HighlightText; @@ -86,7 +85,7 @@ namespace mRemoteNG.UI.Window this.mMenSortAscending}); this.msMain.Location = new System.Drawing.Point(0, 0); this.msMain.Name = "msMain"; - this.msMain.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; + this.msMain.Padding = new System.Windows.Forms.Padding(0, 2, 0, 2); this.msMain.ShowItemToolTips = true; this.msMain.Size = new System.Drawing.Size(204, 24); this.msMain.TabIndex = 10; @@ -97,7 +96,8 @@ namespace mRemoteNG.UI.Window this.mMenAddConnection.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.mMenAddConnection.Image = global::mRemoteNG.Resources.Connection_Add; this.mMenAddConnection.Name = "mMenAddConnection"; - this.mMenAddConnection.Size = new System.Drawing.Size(28, 20); + this.mMenAddConnection.Padding = new System.Windows.Forms.Padding(0, 0, 4, 0); + this.mMenAddConnection.Size = new System.Drawing.Size(24, 20); this.mMenAddConnection.Click += new System.EventHandler(this.cMenTreeAddConnection_Click); // // mMenAddFolder @@ -144,33 +144,27 @@ namespace mRemoteNG.UI.Window // this.vsToolStripExtender.DefaultRenderer = null; // - // tableLayoutPanel1 + // PictureBoxSearch // - this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel1.ColumnCount = 2; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.Controls.Add(this.olvConnections, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.PictureBox1, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.txtSearch, 1, 1); - this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 24); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 2; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(204, 387); - this.tableLayoutPanel1.TabIndex = 31; + this.PictureBoxSearch.Dock = System.Windows.Forms.DockStyle.Fill; + this.PictureBoxSearch.Image = global::mRemoteNG.Resources.Search; + this.PictureBoxSearch.Location = new System.Drawing.Point(0, 0); + this.PictureBoxSearch.Margin = new System.Windows.Forms.Padding(0); + this.PictureBoxSearch.Name = "PictureBoxSearch"; + this.PictureBoxSearch.Size = new System.Drawing.Size(26, 21); + this.PictureBoxSearch.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.PictureBoxSearch.TabIndex = 1; + this.PictureBoxSearch.TabStop = false; // // txtSearch // + this.txtSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.txtSearch.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.txtSearch.Dock = System.Windows.Forms.DockStyle.Fill; this.txtSearch.ForeColor = System.Drawing.SystemColors.GrayText; - this.txtSearch.Location = new System.Drawing.Point(16, 371); + this.txtSearch.Location = new System.Drawing.Point(26, 3); this.txtSearch.Margin = new System.Windows.Forms.Padding(0); this.txtSearch.Name = "txtSearch"; - this.txtSearch.Size = new System.Drawing.Size(371, 15); + this.txtSearch.Size = new System.Drawing.Size(178, 15); this.txtSearch.TabIndex = 30; this.txtSearch.TabStop = false; this.txtSearch.Text = "Search"; @@ -179,23 +173,28 @@ namespace mRemoteNG.UI.Window this.txtSearch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtSearch_KeyDown); this.txtSearch.LostFocus += new System.EventHandler(this.txtSearch_LostFocus); // - // PictureBox1 + // tableLayoutPanel1 // - this.PictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; - this.PictureBox1.Image = global::mRemoteNG.Resources.Search; - this.PictureBox1.Location = new System.Drawing.Point(0, 371); - this.PictureBox1.Margin = new System.Windows.Forms.Padding(0); - this.PictureBox1.Name = "PictureBox1"; - this.PictureBox1.Size = new System.Drawing.Size(16, 16); - this.PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.PictureBox1.TabIndex = 1; - this.PictureBox1.TabStop = false; + this.tableLayoutPanel1.BackColor = System.Drawing.SystemColors.Control; + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 26F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Controls.Add(this.PictureBoxSearch, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.txtSearch); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 390); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 1; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(204, 21); + this.tableLayoutPanel1.TabIndex = 32; // // ConnectionTreeWindow // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.ClientSize = new System.Drawing.Size(204, 411); + this.Controls.Add(this.olvConnections); this.Controls.Add(this.tableLayoutPanel1); this.Controls.Add(this.msMain); this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); @@ -208,9 +207,9 @@ namespace mRemoteNG.UI.Window ((System.ComponentModel.ISupportInitialize)(this.olvConnections)).EndInit(); this.msMain.ResumeLayout(false); this.msMain.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.PictureBoxSearch)).EndInit(); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.PictureBox1)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -220,8 +219,8 @@ namespace mRemoteNG.UI.Window private System.ComponentModel.IContainer components; private Controls.ConnectionTree olvConnections; private WeifenLuo.WinFormsUI.Docking.VisualStudioToolStripExtender vsToolStripExtender; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - internal System.Windows.Forms.PictureBox PictureBox1; + internal Controls.Base.NGPictureBox PictureBoxSearch; internal Controls.Base.NGTextBox txtSearch; + public System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; } } diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index cc8b6be6b..98d79f69b 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -42,6 +42,7 @@ namespace mRemoteNG.UI.Window SetMenuEventHandlers(); SetConnectionTreeEventHandlers(); Settings.Default.PropertyChanged += OnAppSettingsChanged; + ApplyLanguage(); } private void OnAppSettingsChanged(object o, PropertyChangedEventArgs propertyChangedEventArgs) @@ -51,13 +52,20 @@ namespace mRemoteNG.UI.Window ConnectionTree.UseFiltering = Settings.Default.UseFilterSearch; ApplyFiltering(); } - } + + PlaceSearchBar(Settings.Default.PlaceSearchBarAboveConnectionTree); + + } + + private void PlaceSearchBar(bool placeSearchBarAboveConnectionTree) + { + tableLayoutPanel1.Dock = placeSearchBarAboveConnectionTree ? DockStyle.Top : DockStyle.Bottom; + } #region Form Stuff private void Tree_Load(object sender, EventArgs e) { - ApplyLanguage(); //work on the theme change _themeManager = ThemeManager.getInstance(); _themeManager.ThemeChanged += ApplyTheme; @@ -208,29 +216,32 @@ namespace mRemoteNG.UI.Window private void txtSearch_KeyDown(object sender, KeyEventArgs e) { try - { - if (e.KeyCode == Keys.Escape) - { - e.Handled = true; - olvConnections.Focus(); - } - else if (e.KeyCode == Keys.Up) - { - var match = olvConnections.NodeSearcher.PreviousMatch(); - JumpToNode(match); - e.Handled = true; - } - else if (e.KeyCode == Keys.Down) - { - var match = olvConnections.NodeSearcher.NextMatch(); - JumpToNode(match); - e.Handled = true; - } - else - { - tvConnections_KeyDown(sender, e); - } - } + { + switch (e.KeyCode) + { + case Keys.Escape: + e.Handled = true; + olvConnections.Focus(); + break; + case Keys.Up: + { + var match = olvConnections.NodeSearcher.PreviousMatch(); + JumpToNode(match); + e.Handled = true; + break; + } + case Keys.Down: + { + var match = olvConnections.NodeSearcher.NextMatch(); + JumpToNode(match); + e.Handled = true; + break; + } + default: + tvConnections_KeyDown(sender, e); + break; + } + } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace("txtSearch_KeyDown (UI.Window.ConnectionTreeWindow) failed", ex); @@ -261,7 +272,7 @@ namespace mRemoteNG.UI.Window } } - private void JumpToNode(ConnectionInfo connectionInfo) + public void JumpToNode(ConnectionInfo connectionInfo) { if (connectionInfo == null) { diff --git a/mRemoteV1/UI/Window/ConnectionWindow.Designer.cs b/mRemoteV1/UI/Window/ConnectionWindow.Designer.cs index 8e097cbc0..5b4a97325 100644 --- a/mRemoteV1/UI/Window/ConnectionWindow.Designer.cs +++ b/mRemoteV1/UI/Window/ConnectionWindow.Designer.cs @@ -245,7 +245,7 @@ namespace mRemoteNG.UI.Window ClientSize = new Size(632, 453); Controls.Add(TabController); Font = new Font("Segoe UI", 8.25F, FontStyle.Regular, GraphicsUnit.Point, Convert.ToByte(0)); - Icon = Resources.mRemote_Icon; + Icon = Resources.mRemoteNG_Icon; Name = "Connection"; TabText = @"UI.Window.Connection"; Text = @"UI.Window.Connection"; diff --git a/mRemoteV1/UI/Window/ConnectionWindow.cs b/mRemoteV1/UI/Window/ConnectionWindow.cs index f5354b104..693eb9178 100644 --- a/mRemoteV1/UI/Window/ConnectionWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionWindow.cs @@ -18,7 +18,6 @@ using mRemoteNG.UI.Forms; using mRemoteNG.UI.Forms.Input; using mRemoteNG.UI.TaskDialog; using WeifenLuo.WinFormsUI.Docking; -using Message = System.Windows.Forms.Message; using TabControl = Crownwood.Magic.Controls.TabControl; using TabPage = Crownwood.Magic.Controls.TabPage; @@ -180,16 +179,16 @@ namespace mRemoteNG.UI.Window private new void ApplyTheme() { - if(ThemeManager.getInstance().ThemingActive) + if (!ThemeManager.getInstance().ThemingActive) return; + base.ApplyTheme(); + vsToolStripExtender = new VisualStudioToolStripExtender(components) { - base.ApplyTheme(); - this.vsToolStripExtender = new WeifenLuo.WinFormsUI.Docking.VisualStudioToolStripExtender(this.components); - vsToolStripExtender.DefaultRenderer = _toolStripProfessionalRenderer; - vsToolStripExtender.SetStyle(cmenTab, ThemeManager.getInstance().ActiveTheme.Version, ThemeManager.getInstance().ActiveTheme.Theme); - TabController.BackColor = ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Tab_Item_Background"); - TabController.TextColor = ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Tab_Item_Foreground"); - TabController.TextInactiveColor = ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Tab_Item_Disabled_Foreground"); - } + DefaultRenderer = _toolStripProfessionalRenderer + }; + vsToolStripExtender.SetStyle(cmenTab, ThemeManager.getInstance().ActiveTheme.Version, ThemeManager.getInstance().ActiveTheme.Theme); + TabController.BackColor = ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Tab_Item_Background"); + TabController.TextColor = ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Tab_Item_Foreground"); + TabController.TextInactiveColor = ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Tab_Item_Disabled_Foreground"); } private bool _documentHandlersAdded; @@ -424,14 +423,7 @@ namespace mRemoteNG.UI.Window cmenTabTransferFile.Visible = true; } - if (interfaceControl.Protocol is PuttyBase) - { - cmenTabPuttySettings.Visible = true; - } - else - { - cmenTabPuttySettings.Visible = false; - } + cmenTabPuttySettings.Visible = interfaceControl.Protocol is PuttyBase; AddExternalApps(); } @@ -450,8 +442,7 @@ namespace mRemoteNG.UI.Window if (!(TabController.SelectedTab?.Tag is InterfaceControl)) return; var interfaceControl = (InterfaceControl)TabController.SelectedTab?.Tag; - var protocol = interfaceControl.Protocol as RdpProtocol; - if (protocol != null) + if (interfaceControl.Protocol is RdpProtocol protocol) { var rdp = protocol; rdp.ToggleSmartSize(); @@ -472,8 +463,7 @@ namespace mRemoteNG.UI.Window { try { - var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; - if (interfaceControl == null) return; + if (!(TabController.SelectedTab?.Tag is InterfaceControl interfaceControl)) return; if (interfaceControl.Info.Protocol == ProtocolType.SSH1 | interfaceControl.Info.Protocol == ProtocolType.SSH2) SshTransferFile(); @@ -526,8 +516,7 @@ namespace mRemoteNG.UI.Window try { var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; - var vnc = interfaceControl?.Protocol as ProtocolVNC; - if (vnc == null) return; + if (!(interfaceControl?.Protocol is ProtocolVNC vnc)) return; cmenTabViewOnly.Checked = !cmenTabViewOnly.Checked; vnc.ToggleViewOnly(); } @@ -620,7 +609,7 @@ namespace mRemoteNG.UI.Window } //add ext apps - foreach (ExternalTool externalTool in Runtime.ExternalToolsService.ExternalTools) + foreach (var externalTool in Runtime.ExternalToolsService.ExternalTools) { var nItem = new ToolStripMenuItem { @@ -629,7 +618,7 @@ namespace mRemoteNG.UI.Window /* rare failure here. While ExternalTool.Image already tries to default this * try again so it's not null/doesn't crash. */ - Image = externalTool.Image ?? Resources.mRemote_Icon.ToBitmap() + Image = externalTool.Image ?? Resources.mRemoteNG_Icon.ToBitmap() }; nItem.Click += (sender, args) => StartExternalApp(((ToolStripMenuItem)sender).Tag as ExternalTool); @@ -758,8 +747,7 @@ namespace mRemoteNG.UI.Window { try { - var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; - if (interfaceControl == null) return; + if (!(TabController.SelectedTab?.Tag is InterfaceControl interfaceControl)) return; _connectionInitiator.OpenConnection(interfaceControl.Info, ConnectionInfo.Force.DoNotJump); _ignoreChangeSelectedTabClick = false; } @@ -773,8 +761,7 @@ namespace mRemoteNG.UI.Window { try { - var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; - if (interfaceControl == null) return; + if (!(TabController.SelectedTab?.Tag is InterfaceControl interfaceControl)) return; interfaceControl.Protocol.Close(); _connectionInitiator.OpenConnection(interfaceControl.Info, ConnectionInfo.Force.DoNotJump); } @@ -788,10 +775,13 @@ namespace mRemoteNG.UI.Window { try { - var newTitle = TabController.SelectedTab.Title; - if (new InputBox().ShowAsDialog(Language.strNewTitle, Language.strNewTitle + ":", ref newTitle) == DialogResult.OK && - !string.IsNullOrEmpty(newTitle)) - TabController.SelectedTab.Title = newTitle.Replace("&", "&&"); + var title = TabController.SelectedTab.Title; + using (var frmInputBox = new FrmInputBox(Language.strNewTitle, Language.strNewTitle + ":", ref title)) + { + var dr = frmInputBox.ShowDialog(); + if (dr == DialogResult.OK && !string.IsNullOrEmpty(frmInputBox.returnValue)) + TabController.SelectedTab.Title = frmInputBox.returnValue;// newTitle.Replace("&", "&&"); + } } catch (Exception ex) { @@ -811,8 +801,7 @@ namespace mRemoteNG.UI.Window public void Prot_Event_Closed(object sender) { var protocolBase = sender as ProtocolBase; - var tabPage = protocolBase?.InterfaceControl.Parent as TabPage; - if (tabPage != null) + if (protocolBase?.InterfaceControl.Parent is TabPage tabPage) CloseTab(tabPage); } #endregion diff --git a/mRemoteV1/UI/Window/ErrorAndInfoWindow.Designer.cs b/mRemoteV1/UI/Window/ErrorAndInfoWindow.Designer.cs index e354e56b6..e77d7c375 100644 --- a/mRemoteV1/UI/Window/ErrorAndInfoWindow.Designer.cs +++ b/mRemoteV1/UI/Window/ErrorAndInfoWindow.Designer.cs @@ -3,7 +3,7 @@ namespace mRemoteNG.UI.Window { public partial class ErrorAndInfoWindow { - internal System.Windows.Forms.PictureBox pbError; + internal Controls.Base.NGPictureBox pbError; internal System.Windows.Forms.ListView lvErrorCollector; internal System.Windows.Forms.ColumnHeader clmMessage; internal Controls.Base.NGTextBox txtMsgText; @@ -16,7 +16,7 @@ namespace mRemoteNG.UI.Window { this.components = new System.ComponentModel.Container(); this.txtMsgText = new mRemoteNG.UI.Controls.Base.NGTextBox(); - this.pbError = new System.Windows.Forms.PictureBox(); + this.pbError = new Controls.Base.NGPictureBox(); this.lvErrorCollector = new System.Windows.Forms.ListView(); this.clmMessage = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.cMenMC = new System.Windows.Forms.ContextMenuStrip(this.components); diff --git a/mRemoteV1/UI/Window/ErrorAndInfoWindow.cs b/mRemoteV1/UI/Window/ErrorAndInfoWindow.cs index 8fa17a8a3..4b7c2f3df 100644 --- a/mRemoteV1/UI/Window/ErrorAndInfoWindow.cs +++ b/mRemoteV1/UI/Window/ErrorAndInfoWindow.cs @@ -9,6 +9,7 @@ using mRemoteNG.App; using mRemoteNG.Messages; using mRemoteNG.UI.Forms; using mRemoteNG.Themes; +using Message = mRemoteNG.Messages.Message; namespace mRemoteNG.UI.Window { @@ -36,12 +37,12 @@ namespace mRemoteNG.UI.Window _themeManager.ThemeChanged += ApplyTheme; LayoutVertical(); FillImageList(); + ApplyLanguage(); } #region Form Stuff private void ErrorsAndInfos_Load(object sender, EventArgs e) { - ApplyLanguage(); } private void ApplyLanguage() @@ -60,6 +61,13 @@ namespace mRemoteNG.UI.Window if (!_themeManager.ThemingActive) return; lvErrorCollector.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); lvErrorCollector.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); + + pnlErrorMsg.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); + pnlErrorMsg.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); + txtMsgText.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); + txtMsgText.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); + lblMsgDate.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); + lblMsgDate.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground"); } private void FillImageList() @@ -143,11 +151,11 @@ namespace mRemoteNG.UI.Window { try { - pnlErrorMsg.BackColor = Color.FromKnownColor(KnownColor.Control); - pbError.Image = null; - txtMsgText.BackColor = Color.FromKnownColor(KnownColor.Control); - txtMsgText.Text = ""; - lblMsgDate.BackColor = Color.FromKnownColor(KnownColor.Control); + pnlErrorMsg.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); + pbError.Image = null; + txtMsgText.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); + txtMsgText.Text = ""; + lblMsgDate.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Background"); lblMsgDate.Text = ""; } catch (Exception ex) @@ -298,8 +306,7 @@ namespace mRemoteNG.UI.Window foreach (ListViewItem item in items) { - var message = item.Tag as Messages.Message; - if (message == null) + if (!(item.Tag is Message message)) { continue; } diff --git a/mRemoteV1/UI/Window/ExternalToolsWindow.cs b/mRemoteV1/UI/Window/ExternalToolsWindow.cs index 4ba070f94..3c96cd4ad 100644 --- a/mRemoteV1/UI/Window/ExternalToolsWindow.cs +++ b/mRemoteV1/UI/Window/ExternalToolsWindow.cs @@ -314,11 +314,10 @@ namespace mRemoteNG.UI.Window if (e.Column != WaitForExitColumnHeader) return; - var rowItemAsExternalTool = e.Model as ExternalTool; - if (rowItemAsExternalTool == null || !rowItemAsExternalTool.TryIntegrate) + if (!(e.Model is ExternalTool rowItemAsExternalTool) || !rowItemAsExternalTool.TryIntegrate) return; - e.Text = string.Format("'{0}' cannot be enabled if '{1}' is enabled", Language.strCheckboxWaitForExit, Language.strTryIntegrate); + e.Text = $"'{Language.strCheckboxWaitForExit}' cannot be enabled if '{Language.strTryIntegrate}' is enabled"; } #endregion } diff --git a/mRemoteV1/UI/Window/HelpWindow.cs b/mRemoteV1/UI/Window/HelpWindow.cs index 6310223cb..6396330b2 100644 --- a/mRemoteV1/UI/Window/HelpWindow.cs +++ b/mRemoteV1/UI/Window/HelpWindow.cs @@ -1,18 +1,18 @@ +using mRemoteNG.App.Info; using System; using System.Windows.Forms; -using mRemoteNG.App.Info; using WeifenLuo.WinFormsUI.Docking; namespace mRemoteNG.UI.Window { - public class HelpWindow : BaseWindow + public class HelpWindow : BaseWindow { #region Form Init private TreeView tvIndex; - internal ImageList imgListHelp; + private ImageList imgListHelp; private System.ComponentModel.Container components; private SplitContainer pnlSplitter; private Label lblDocName; @@ -23,31 +23,36 @@ namespace mRemoteNG.UI.Window components = new System.ComponentModel.Container(); Load += Help_Load; Shown += Help_Shown; - var TreeNode1 = new TreeNode("Introduction"); - var TreeNode2 = new TreeNode("Prerequisites"); - var TreeNode3 = new TreeNode("Installation"); - var TreeNode4 = new TreeNode("Configuration"); - var TreeNode5 = new TreeNode("SQL Configuration"); - var TreeNode6 = new TreeNode("Command-Line Switches"); - var TreeNode7 = new TreeNode("Getting Started", new[] {TreeNode2, TreeNode3, TreeNode4, TreeNode5, TreeNode6}); - var TreeNode8 = new TreeNode("Main Menu"); - var TreeNode9 = new TreeNode("Connections"); - var TreeNode10 = new TreeNode("Config"); - var TreeNode11 = new TreeNode("Errors and Infos"); - var TreeNode12 = new TreeNode("Save As / Export"); - var TreeNode14 = new TreeNode("Screenshot Manager"); - var TreeNode15 = new TreeNode("Connection"); - var TreeNode16 = new TreeNode("Options"); - var TreeNode17 = new TreeNode("Update"); - var TreeNode18 = new TreeNode("SSH File Transfer"); - var TreeNode19 = new TreeNode("Quick Connect"); - var TreeNode20 = new TreeNode("Import From Active Directory"); - var TreeNode21 = new TreeNode("External Applications"); - var TreeNode22 = new TreeNode("Port Scan"); - var TreeNode23 = new TreeNode("User Interface", new[] {TreeNode8, TreeNode9, TreeNode10, TreeNode11, TreeNode12, TreeNode14, TreeNode15, TreeNode16, TreeNode17, TreeNode18, TreeNode19, TreeNode20, TreeNode21, TreeNode22}); - var TreeNode24 = new TreeNode("Quick Reference"); - var TreeNode25 = new TreeNode("Help", new[] {TreeNode1, TreeNode7, TreeNode23, TreeNode24}); - wbHelp = new WebBrowser(); + var TreeNode1 = new TreeNode("Introduction"); + var TreeNode2 = new TreeNode("Prerequisites"); + var TreeNode3 = new TreeNode("Installation/Update"); + var TreeNode4 = new TreeNode("Running mRemoteNG"); + var TreeNode5 = new TreeNode("Command-Line Switches"); + var TreeNode6 = new TreeNode("Getting Started", new[] { TreeNode2, TreeNode3, TreeNode4, TreeNode5 }); + var TreeNode7 = new TreeNode("Menus"); + var TreeNode8 = new TreeNode("Connections"); + var TreeNode9 = new TreeNode("Config"); + var TreeNode10 = new TreeNode("Options"); + var TreeNode11 = new TreeNode("Navigation"); + var TreeNode12 = new TreeNode("Notifications"); + var TreeNode13 = new TreeNode("SQL Configuration"); + var TreeNode14 = new TreeNode("Screenshot Manager"); + var TreeNode15 = new TreeNode("SSH File Transfer"); + var TreeNode16 = new TreeNode("Quick Connect"); + var TreeNode17 = new TreeNode("Port Scan"); + var TreeNode18 = new TreeNode("External Tools"); + var TreeNode19 = new TreeNode("Import/Export"); + var TreeNode20 = new TreeNode("Keyboard Shortcuts"); + var TreeNode21 = new TreeNode("User Interface", new[] { + TreeNode7, TreeNode8, TreeNode9, TreeNode10, TreeNode11, TreeNode12, TreeNode13, TreeNode14, TreeNode15, + TreeNode16, TreeNode17, TreeNode18, TreeNode19, TreeNode20 + }); + var TreeNode22 = new TreeNode("Common Problems (RDP)"); + var TreeNode23 = new TreeNode("Special Topics", new[] { + TreeNode22 + }); + var TreeNode99 = new TreeNode("Help", new[] { TreeNode1, TreeNode6, TreeNode21, TreeNode23 }); + wbHelp = new WebBrowser(); wbHelp.DocumentTitleChanged += wbHelp_DocumentTitleChanged; tvIndex = new TreeView(); tvIndex.NodeMouseClick += tvIndex_NodeMouseClick; @@ -80,31 +85,30 @@ namespace mRemoteNG.UI.Window tvIndex.BorderStyle = BorderStyle.None; tvIndex.HideSelection = false; tvIndex.Location = new System.Drawing.Point(1, 1); - tvIndex.Name = "tvIndex"; + tvIndex.Name = "tvIndex"; TreeNode1.Tag = "Introduction"; - TreeNode2.Tag = "Prerequisites"; - TreeNode3.Tag = "Installation"; - TreeNode4.Tag = "Configuration"; - TreeNode5.Tag = "ConfigurationSQL"; - TreeNode6.Tag = "CMDSwitches"; - TreeNode8.Tag = "MainMenu"; - TreeNode9.Tag = "Connections"; - TreeNode10.Tag = "Config"; - TreeNode11.Tag = "ErrorsAndInfos"; - TreeNode12.Tag = "SaveAsExport"; - TreeNode14.Tag = "ScreenshotManager"; - TreeNode15.Tag = "Connection"; - TreeNode16.Tag = "Options"; - TreeNode17.Tag = "Update"; - TreeNode18.Tag = "SSHFileTransfer"; - TreeNode19.Tag = "QuickConnect"; - TreeNode20.Tag = "ImportFromAD"; - TreeNode21.Tag = "ExternalTools"; - TreeNode22.Tag = "PortScan"; - TreeNode24.Tag = "QuickReference"; - TreeNode25.Tag = "Index"; - tvIndex.Nodes.AddRange(new[] {TreeNode25}); - tvIndex.ShowRootLines = false; + TreeNode2.Tag = "gs_prerequisites"; + TreeNode3.Tag = "gs_installation"; + TreeNode4.Tag = "gs_running_mremoteng"; + TreeNode5.Tag = "gs_command_line_switches"; + TreeNode7.Tag = "ui_menus"; + TreeNode8.Tag = "ui_connections"; + TreeNode9.Tag = "ui_config"; + TreeNode10.Tag = "ui_options"; + TreeNode11.Tag = "ui_navigation"; + TreeNode12.Tag = "ui_notifications"; + TreeNode13.Tag = "ui_sql_configuration"; + TreeNode14.Tag = "ui_screenshot_manager"; + TreeNode15.Tag = "ui_file_transfer"; + TreeNode16.Tag = "ui_quick_connect"; + TreeNode17.Tag = "ui_port_scan"; + TreeNode18.Tag = "ui_external_tools"; + TreeNode19.Tag = "ui_import_and_export"; + TreeNode20.Tag = "ui_keyboardshortcuts"; + TreeNode22.Tag = "st_common_problems_rdp"; + TreeNode99.Tag = "Index"; + tvIndex.Nodes.AddRange(new[] {TreeNode99}); + tvIndex.ShowRootLines = false; tvIndex.Size = new System.Drawing.Size(207, 321); tvIndex.TabIndex = 0; // @@ -140,7 +144,7 @@ namespace mRemoteNG.UI.Window lblDocName.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; lblDocName.BackColor = System.Drawing.Color.DimGray; - lblDocName.Font = new System.Drawing.Font("Segoe UI", 12.0F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)); + lblDocName.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)); lblDocName.ForeColor = System.Drawing.Color.White; lblDocName.Location = new System.Drawing.Point(1, 1); lblDocName.Name = "lblDocName"; diff --git a/mRemoteV1/UI/Window/HelpWindow.resx b/mRemoteV1/UI/Window/HelpWindow.resx index 510497c37..ca620d883 100644 --- a/mRemoteV1/UI/Window/HelpWindow.resx +++ b/mRemoteV1/UI/Window/HelpWindow.resx @@ -112,15 +112,12 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 19, 14 - - + 48 \ No newline at end of file diff --git a/mRemoteV1/UI/Window/PortScanWindow.Designer.cs b/mRemoteV1/UI/Window/PortScanWindow.Designer.cs index aca666ef1..b691b1f09 100644 --- a/mRemoteV1/UI/Window/PortScanWindow.Designer.cs +++ b/mRemoteV1/UI/Window/PortScanWindow.Designer.cs @@ -10,7 +10,6 @@ namespace mRemoteNG.UI.Window internal Controls.Base.NGLabel lblEndIP; internal Controls.Base.NGLabel lblStartIP; - internal Controls.Base.NGButton btnScan; internal IPTextBox ipEnd; internal Controls.Base.NGListView olvHosts; internal BrightIdeasSoftware.OLVColumn clmHost; @@ -26,11 +25,8 @@ namespace mRemoteNG.UI.Window internal Controls.Base.NGProgressBar prgBar; internal Controls.Base.NGLabel lblOnlyImport; internal Controls.Base.NGComboBox cbProtocol; - internal System.Windows.Forms.Panel pnlScan; internal Controls.Base.NGNumericUpDown portEnd; internal Controls.Base.NGNumericUpDown portStart; - internal Controls.Base.NGLabel Label2; - internal Controls.Base.NGLabel Label1; internal Controls.Base.NGButton btnImport; internal IPTextBox ipStart; @@ -42,7 +38,6 @@ namespace mRemoteNG.UI.Window this.ipEnd = new mRemoteNG.UI.Controls.IPTextBox(); this.lblStartIP = new mRemoteNG.UI.Controls.Base.NGLabel(); this.lblEndIP = new mRemoteNG.UI.Controls.Base.NGLabel(); - this.btnScan = new mRemoteNG.UI.Controls.Base.NGButton(); this.olvHosts = new mRemoteNG.UI.Controls.Base.NGListView(); this.resultsMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); this.importHTTPToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -66,89 +61,82 @@ namespace mRemoteNG.UI.Window this.clmOpenPorts = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.clmClosedPorts = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.prgBar = new mRemoteNG.UI.Controls.Base.NGProgressBar(); - this.pnlScan = new System.Windows.Forms.Panel(); this.numericSelectorTimeout = new mRemoteNG.UI.Controls.Base.NGNumericUpDown(); this.lblTimeout = new System.Windows.Forms.Label(); this.portEnd = new mRemoteNG.UI.Controls.Base.NGNumericUpDown(); this.portStart = new mRemoteNG.UI.Controls.Base.NGNumericUpDown(); - this.Label2 = new mRemoteNG.UI.Controls.Base.NGLabel(); - this.Label1 = new mRemoteNG.UI.Controls.Base.NGLabel(); - this.pnlImport = new System.Windows.Forms.Panel(); + this.pnlIp = new System.Windows.Forms.TableLayoutPanel(); + this.btnScan = new mRemoteNG.UI.Controls.Base.NGButton(); + this.ngCheckFirstPort = new mRemoteNG.UI.Controls.Base.NGCheckBox(); + this.ngCheckLastPort = new mRemoteNG.UI.Controls.Base.NGCheckBox(); + this.pnlImport = new System.Windows.Forms.TableLayoutPanel(); + this.pnlMain = new System.Windows.Forms.TableLayoutPanel(); + this.portScanToolTip = new System.Windows.Forms.ToolTip(this.components); ((System.ComponentModel.ISupportInitialize)(this.olvHosts)).BeginInit(); this.resultsMenuStrip.SuspendLayout(); - this.pnlScan.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.numericSelectorTimeout)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.portEnd)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.portStart)).BeginInit(); + this.pnlIp.SuspendLayout(); this.pnlImport.SuspendLayout(); + this.pnlMain.SuspendLayout(); this.SuspendLayout(); // // ipStart // - this.ipStart.Location = new System.Drawing.Point(5, 19); + this.ipStart.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ipStart.Location = new System.Drawing.Point(133, 3); this.ipStart.Name = "ipStart"; - this.ipStart.Size = new System.Drawing.Size(130, 20); + this.ipStart.Size = new System.Drawing.Size(124, 18); this.ipStart.TabIndex = 1; this.ipStart.ToolTipText = ""; // // ipEnd // - this.ipEnd.Location = new System.Drawing.Point(155, 19); + this.ipEnd.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ipEnd.Location = new System.Drawing.Point(133, 27); this.ipEnd.Name = "ipEnd"; - this.ipEnd.Size = new System.Drawing.Size(130, 20); + this.ipEnd.Size = new System.Drawing.Size(124, 18); this.ipEnd.TabIndex = 2; this.ipEnd.ToolTipText = ""; // // lblStartIP // this.lblStartIP.AutoSize = true; - this.lblStartIP.Location = new System.Drawing.Point(3, 5); + this.lblStartIP.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblStartIP.Location = new System.Drawing.Point(3, 0); this.lblStartIP.Name = "lblStartIP"; - this.lblStartIP.Size = new System.Drawing.Size(46, 13); + this.lblStartIP.Size = new System.Drawing.Size(124, 24); this.lblStartIP.TabIndex = 0; - this.lblStartIP.Text = "Start IP:"; + this.lblStartIP.Text = "First IP"; + this.lblStartIP.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // lblEndIP // this.lblEndIP.AutoSize = true; - this.lblEndIP.Location = new System.Drawing.Point(152, 5); + this.lblEndIP.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblEndIP.Location = new System.Drawing.Point(3, 24); this.lblEndIP.Name = "lblEndIP"; - this.lblEndIP.Size = new System.Drawing.Size(42, 13); + this.lblEndIP.Size = new System.Drawing.Size(124, 24); this.lblEndIP.TabIndex = 5; - this.lblEndIP.Text = "End IP:"; - // - // btnScan - // - this.btnScan._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER; - this.btnScan.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnScan.Image = global::mRemoteNG.Resources.Search; - this.btnScan.ImageAlign = System.Drawing.ContentAlignment.MiddleRight; - this.btnScan.Location = new System.Drawing.Point(769, 5); - this.btnScan.Name = "btnScan"; - this.btnScan.Size = new System.Drawing.Size(110, 55); - this.btnScan.TabIndex = 6; - this.btnScan.Text = "&Scan"; - this.btnScan.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; - this.btnScan.UseVisualStyleBackColor = true; - this.btnScan.Click += new System.EventHandler(this.btnScan_Click); + this.lblEndIP.Text = "Last IP"; + this.lblEndIP.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // olvHosts // - this.olvHosts.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.olvHosts.CellEditUseWholeCell = false; this.olvHosts.ContextMenuStrip = this.resultsMenuStrip; this.olvHosts.Cursor = System.Windows.Forms.Cursors.Default; this.olvHosts.DecorateLines = true; + this.olvHosts.Dock = System.Windows.Forms.DockStyle.Fill; this.olvHosts.FullRowSelect = true; this.olvHosts.GridLines = true; this.olvHosts.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.olvHosts.HideSelection = false; - this.olvHosts.Location = new System.Drawing.Point(12, 73); + this.olvHosts.Location = new System.Drawing.Point(3, 168); this.olvHosts.Name = "olvHosts"; this.olvHosts.ShowGroups = false; - this.olvHosts.Size = new System.Drawing.Size(883, 290); + this.olvHosts.Size = new System.Drawing.Size(878, 230); this.olvHosts.TabIndex = 26; this.olvHosts.UseCompatibleStateImageBehavior = false; this.olvHosts.View = System.Windows.Forms.View.Details; @@ -218,10 +206,10 @@ namespace mRemoteNG.UI.Window // btnImport // this.btnImport._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER; - this.btnImport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnImport.Location = new System.Drawing.Point(800, 5); + this.btnImport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnImport.Location = new System.Drawing.Point(765, 27); this.btnImport.Name = "btnImport"; - this.btnImport.Size = new System.Drawing.Size(80, 40); + this.btnImport.Size = new System.Drawing.Size(110, 24); this.btnImport.TabIndex = 8; this.btnImport.Text = "&Import"; this.btnImport.UseVisualStyleBackColor = true; @@ -230,7 +218,7 @@ namespace mRemoteNG.UI.Window // cbProtocol // this.cbProtocol._mice = mRemoteNG.UI.Controls.Base.NGComboBox.MouseState.HOVER; - this.cbProtocol.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbProtocol.Dock = System.Windows.Forms.DockStyle.Fill; this.cbProtocol.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cbProtocol.FormattingEnabled = true; this.cbProtocol.Items.AddRange(new object[] { @@ -241,20 +229,21 @@ namespace mRemoteNG.UI.Window "Rlogin", "RDP", "VNC"}); - this.cbProtocol.Location = new System.Drawing.Point(5, 25); + this.cbProtocol.Location = new System.Drawing.Point(3, 27); this.cbProtocol.Name = "cbProtocol"; - this.cbProtocol.Size = new System.Drawing.Size(122, 21); + this.cbProtocol.Size = new System.Drawing.Size(144, 21); this.cbProtocol.TabIndex = 7; // // lblOnlyImport // - this.lblOnlyImport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.lblOnlyImport.AutoSize = true; - this.lblOnlyImport.Location = new System.Drawing.Point(2, 5); + this.lblOnlyImport.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblOnlyImport.Location = new System.Drawing.Point(3, 0); this.lblOnlyImport.Name = "lblOnlyImport"; - this.lblOnlyImport.Size = new System.Drawing.Size(104, 13); + this.lblOnlyImport.Size = new System.Drawing.Size(144, 24); this.lblOnlyImport.TabIndex = 1; - this.lblOnlyImport.Text = "Protocol to import:"; + this.lblOnlyImport.Text = "Protocol to import"; + this.lblOnlyImport.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // clmHost // @@ -321,38 +310,16 @@ namespace mRemoteNG.UI.Window // // prgBar // - this.prgBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.prgBar.Location = new System.Drawing.Point(5, 45); + this.prgBar.Dock = System.Windows.Forms.DockStyle.Fill; + this.prgBar.Location = new System.Drawing.Point(3, 138); this.prgBar.Name = "prgBar"; - this.prgBar.Size = new System.Drawing.Size(760, 15); + this.prgBar.Size = new System.Drawing.Size(878, 24); this.prgBar.Step = 1; this.prgBar.TabIndex = 28; // - // pnlScan - // - this.pnlScan.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.pnlScan.Controls.Add(this.numericSelectorTimeout); - this.pnlScan.Controls.Add(this.lblTimeout); - this.pnlScan.Controls.Add(this.portEnd); - this.pnlScan.Controls.Add(this.portStart); - this.pnlScan.Controls.Add(this.prgBar); - this.pnlScan.Controls.Add(this.Label2); - this.pnlScan.Controls.Add(this.lblStartIP); - this.pnlScan.Controls.Add(this.lblEndIP); - this.pnlScan.Controls.Add(this.ipStart); - this.pnlScan.Controls.Add(this.btnScan); - this.pnlScan.Controls.Add(this.Label1); - this.pnlScan.Controls.Add(this.ipEnd); - this.pnlScan.Location = new System.Drawing.Point(12, 5); - this.pnlScan.Name = "pnlScan"; - this.pnlScan.Size = new System.Drawing.Size(883, 65); - this.pnlScan.TabIndex = 18; - // // numericSelectorTimeout // - this.numericSelectorTimeout.Location = new System.Drawing.Point(600, 17); + this.numericSelectorTimeout.Location = new System.Drawing.Point(133, 99); this.numericSelectorTimeout.Maximum = new decimal(new int[] { 2147482, 0, @@ -361,19 +328,27 @@ namespace mRemoteNG.UI.Window this.numericSelectorTimeout.Name = "numericSelectorTimeout"; this.numericSelectorTimeout.Size = new System.Drawing.Size(67, 22); this.numericSelectorTimeout.TabIndex = 5; + this.numericSelectorTimeout.Value = new decimal(new int[] { + 5, + 0, + 0, + 0}); // // lblTimeout // this.lblTimeout.AutoSize = true; - this.lblTimeout.Location = new System.Drawing.Point(597, 1); + this.lblTimeout.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblTimeout.Location = new System.Drawing.Point(3, 96); this.lblTimeout.Name = "lblTimeout"; - this.lblTimeout.Size = new System.Drawing.Size(102, 13); + this.lblTimeout.Size = new System.Drawing.Size(124, 33); this.lblTimeout.TabIndex = 16; - this.lblTimeout.Text = "Timeout (seconds):"; + this.lblTimeout.Text = "Timeout [seconds]"; + this.lblTimeout.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // portEnd // - this.portEnd.Location = new System.Drawing.Point(490, 17); + this.portEnd.Enabled = false; + this.portEnd.Location = new System.Drawing.Point(133, 75); this.portEnd.Maximum = new decimal(new int[] { 65535, 0, @@ -382,11 +357,18 @@ namespace mRemoteNG.UI.Window this.portEnd.Name = "portEnd"; this.portEnd.Size = new System.Drawing.Size(67, 22); this.portEnd.TabIndex = 4; + this.portScanToolTip.SetToolTip(this.portEnd, global::mRemoteNG.Language.strPortScanSinglePort); + this.portEnd.Value = new decimal(new int[] { + 65535, + 0, + 0, + 0}); this.portEnd.Enter += new System.EventHandler(this.portEnd_Enter); // // portStart // - this.portStart.Location = new System.Drawing.Point(375, 17); + this.portStart.Enabled = false; + this.portStart.Location = new System.Drawing.Point(133, 51); this.portStart.Maximum = new decimal(new int[] { 65535, 0, @@ -395,37 +377,115 @@ namespace mRemoteNG.UI.Window this.portStart.Name = "portStart"; this.portStart.Size = new System.Drawing.Size(67, 22); this.portStart.TabIndex = 3; + this.portScanToolTip.SetToolTip(this.portStart, global::mRemoteNG.Language.strPortScanSinglePort); this.portStart.Enter += new System.EventHandler(this.portStart_Enter); // - // Label2 + // pnlIp // - this.Label2.AutoSize = true; - this.Label2.Location = new System.Drawing.Point(487, 1); - this.Label2.Name = "Label2"; - this.Label2.Size = new System.Drawing.Size(54, 13); - this.Label2.TabIndex = 10; - this.Label2.Text = "End Port:"; + this.pnlIp.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlIp.ColumnCount = 3; + this.pnlIp.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 130F)); + this.pnlIp.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 130F)); + this.pnlIp.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.pnlIp.Controls.Add(this.lblStartIP, 0, 0); + this.pnlIp.Controls.Add(this.ipEnd, 1, 1); + this.pnlIp.Controls.Add(this.ipStart, 1, 0); + this.pnlIp.Controls.Add(this.lblEndIP, 0, 1); + this.pnlIp.Controls.Add(this.portStart, 1, 2); + this.pnlIp.Controls.Add(this.portEnd, 1, 3); + this.pnlIp.Controls.Add(this.lblTimeout, 0, 4); + this.pnlIp.Controls.Add(this.numericSelectorTimeout, 1, 4); + this.pnlIp.Controls.Add(this.btnScan, 2, 4); + this.pnlIp.Controls.Add(this.ngCheckFirstPort, 0, 2); + this.pnlIp.Controls.Add(this.ngCheckLastPort, 0, 3); + this.pnlIp.Location = new System.Drawing.Point(3, 3); + this.pnlIp.Name = "pnlIp"; + this.pnlIp.RowCount = 5; + this.pnlIp.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.pnlIp.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.pnlIp.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.pnlIp.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.pnlIp.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.pnlIp.Size = new System.Drawing.Size(878, 129); + this.pnlIp.TabIndex = 103; // - // Label1 + // btnScan // - this.Label1.AutoSize = true; - this.Label1.Location = new System.Drawing.Point(372, 1); - this.Label1.Name = "Label1"; - this.Label1.Size = new System.Drawing.Size(58, 13); - this.Label1.TabIndex = 0; - this.Label1.Text = "Start Port:"; + this.btnScan._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER; + this.btnScan.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnScan.Image = global::mRemoteNG.Resources.Search; + this.btnScan.ImageAlign = System.Drawing.ContentAlignment.MiddleRight; + this.btnScan.Location = new System.Drawing.Point(765, 99); + this.btnScan.Name = "btnScan"; + this.btnScan.Size = new System.Drawing.Size(110, 24); + this.btnScan.TabIndex = 6; + this.btnScan.Text = "&Scan"; + this.btnScan.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.btnScan.UseVisualStyleBackColor = true; + this.btnScan.Click += new System.EventHandler(this.btnScan_Click); + // + // ngCheckFirstPort + // + this.ngCheckFirstPort._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER; + this.ngCheckFirstPort.AutoSize = true; + this.ngCheckFirstPort.Location = new System.Drawing.Point(3, 51); + this.ngCheckFirstPort.Name = "ngCheckFirstPort"; + this.ngCheckFirstPort.Size = new System.Drawing.Size(72, 17); + this.ngCheckFirstPort.TabIndex = 17; + this.ngCheckFirstPort.Text = "First Port"; + this.portScanToolTip.SetToolTip(this.ngCheckFirstPort, global::mRemoteNG.Language.strPortScanSinglePort); + this.ngCheckFirstPort.UseVisualStyleBackColor = true; + this.ngCheckFirstPort.CheckedChanged += new System.EventHandler(this.NgCheckFirstPort_CheckedChanged); + // + // ngCheckLastPort + // + this.ngCheckLastPort._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER; + this.ngCheckLastPort.AutoSize = true; + this.ngCheckLastPort.Location = new System.Drawing.Point(3, 75); + this.ngCheckLastPort.Name = "ngCheckLastPort"; + this.ngCheckLastPort.Size = new System.Drawing.Size(70, 17); + this.ngCheckLastPort.TabIndex = 18; + this.ngCheckLastPort.Text = "Last Port"; + this.portScanToolTip.SetToolTip(this.ngCheckLastPort, global::mRemoteNG.Language.strPortScanSinglePort); + this.ngCheckLastPort.UseVisualStyleBackColor = true; + this.ngCheckLastPort.CheckedChanged += new System.EventHandler(this.NgCheckLastPort_CheckedChanged); // // pnlImport // - this.pnlImport.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.pnlImport.Controls.Add(this.btnImport); - this.pnlImport.Controls.Add(this.lblOnlyImport); - this.pnlImport.Controls.Add(this.cbProtocol); - this.pnlImport.Location = new System.Drawing.Point(12, 364); + this.pnlImport.ColumnCount = 2; + this.pnlImport.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 150F)); + this.pnlImport.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.pnlImport.Controls.Add(this.lblOnlyImport, 0, 0); + this.pnlImport.Controls.Add(this.cbProtocol, 0, 1); + this.pnlImport.Controls.Add(this.btnImport, 1, 1); + this.pnlImport.Dock = System.Windows.Forms.DockStyle.Fill; + this.pnlImport.Location = new System.Drawing.Point(3, 404); this.pnlImport.Name = "pnlImport"; - this.pnlImport.Size = new System.Drawing.Size(883, 50); - this.pnlImport.TabIndex = 102; + this.pnlImport.RowCount = 2; + this.pnlImport.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.pnlImport.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.pnlImport.Size = new System.Drawing.Size(878, 54); + this.pnlImport.TabIndex = 104; + // + // pnlMain + // + this.pnlMain.ColumnCount = 1; + this.pnlMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.pnlMain.Controls.Add(this.pnlIp, 0, 0); + this.pnlMain.Controls.Add(this.prgBar, 0, 1); + this.pnlMain.Controls.Add(this.pnlImport, 0, 3); + this.pnlMain.Controls.Add(this.olvHosts, 0, 2); + this.pnlMain.Dock = System.Windows.Forms.DockStyle.Fill; + this.pnlMain.Location = new System.Drawing.Point(0, 0); + this.pnlMain.Name = "pnlMain"; + this.pnlMain.RowCount = 4; + this.pnlMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 135F)); + this.pnlMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30F)); + this.pnlMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.pnlMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 60F)); + this.pnlMain.Size = new System.Drawing.Size(884, 461); + this.pnlMain.TabIndex = 105; // // PortScanWindow // @@ -433,30 +493,27 @@ namespace mRemoteNG.UI.Window this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.AutoScroll = true; - this.ClientSize = new System.Drawing.Size(908, 421); - this.Controls.Add(this.pnlImport); - this.Controls.Add(this.olvHosts); - this.Controls.Add(this.pnlScan); + this.ClientSize = new System.Drawing.Size(884, 461); + this.Controls.Add(this.pnlMain); this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MinimumSize = new System.Drawing.Size(924, 460); this.Name = "PortScanWindow"; this.TabText = "Port Scan"; this.Text = "Port Scan"; this.Load += new System.EventHandler(this.PortScan_Load); ((System.ComponentModel.ISupportInitialize)(this.olvHosts)).EndInit(); this.resultsMenuStrip.ResumeLayout(false); - this.pnlScan.ResumeLayout(false); - this.pnlScan.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.numericSelectorTimeout)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.portEnd)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.portStart)).EndInit(); + this.pnlIp.ResumeLayout(false); + this.pnlIp.PerformLayout(); this.pnlImport.ResumeLayout(false); this.pnlImport.PerformLayout(); + this.pnlMain.ResumeLayout(false); this.ResumeLayout(false); } - internal System.Windows.Forms.Panel pnlImport; #endregion private System.Windows.Forms.ContextMenuStrip resultsMenuStrip; @@ -470,5 +527,12 @@ namespace mRemoteNG.UI.Window private System.Windows.Forms.ToolStripMenuItem importVNCToolStripMenuItem; private System.Windows.Forms.Label lblTimeout; private Controls.Base.NGNumericUpDown numericSelectorTimeout; - } + private System.Windows.Forms.TableLayoutPanel pnlIp; + private System.Windows.Forms.TableLayoutPanel pnlImport; + internal Controls.Base.NGButton btnScan; + private System.Windows.Forms.TableLayoutPanel pnlMain; + private Controls.Base.NGCheckBox ngCheckFirstPort; + private Controls.Base.NGCheckBox ngCheckLastPort; + private System.Windows.Forms.ToolTip portScanToolTip; + } } diff --git a/mRemoteV1/UI/Window/PortScanWindow.cs b/mRemoteV1/UI/Window/PortScanWindow.cs index 7037a9b7b..615755baa 100644 --- a/mRemoteV1/UI/Window/PortScanWindow.cs +++ b/mRemoteV1/UI/Window/PortScanWindow.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; +using System.Windows.Forms; using mRemoteNG.App; using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol; @@ -90,7 +92,7 @@ namespace mRemoteNG.UI.Window try { - olvHosts.Columns.AddRange(new[]{clmHost, clmSSH, clmTelnet, clmHTTP, clmHTTPS, clmRlogin, clmRDP, clmVNC, clmOpenPorts, clmClosedPorts}); + olvHosts.Columns.AddRange(new ColumnHeader[]{clmHost, clmSSH, clmTelnet, clmHTTP, clmHTTPS, clmRlogin, clmRDP, clmVNC, clmOpenPorts, clmClosedPorts}); ShowImportControls(true); cbProtocol.SelectedIndex = 0; numericSelectorTimeout.Value = 5; @@ -132,40 +134,35 @@ namespace mRemoteNG.UI.Window private void btnImport_Click(object sender, EventArgs e) { - ProtocolType protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), Convert.ToString(cbProtocol.SelectedItem), true); + var protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), Convert.ToString(cbProtocol.SelectedItem), true); importSelectedHosts(protocol); } #endregion private void ApplyLanguage() { - lblStartIP.Text = $"{Language.strStartIP}:"; - lblEndIP.Text = $"{Language.strEndIP}:"; + lblStartIP.Text = Language.strStartIP; + lblEndIP.Text = Language.strEndIP; btnScan.Text = Language.strButtonScan; btnImport.Text = Language.strButtonImport; - lblOnlyImport.Text = $"{Language.strProtocolToImport}:"; + lblOnlyImport.Text = Language.strProtocolToImport; clmHost.Text = Language.strColumnHostnameIP; clmOpenPorts.Text = Language.strOpenPorts; clmClosedPorts.Text = Language.strClosedPorts; - Label2.Text = $"{Language.strEndPort}:"; - Label1.Text = $"{Language.strStartPort}:"; - lblTimeout.Text = $"{Language.strTimeoutInSeconds}"; + ngCheckFirstPort.Text = Language.strStartPort; + ngCheckLastPort.Text = Language.strEndPort; + lblTimeout.Text = Language.strTimeoutInSeconds; TabText = Language.strMenuPortScan; Text = Language.strMenuPortScan; } private void ShowImportControls(bool controlsVisible) { - pnlScan.Visible = controlsVisible; pnlImport.Visible = controlsVisible; if (controlsVisible) - { olvHosts.Height = pnlImport.Top - olvHosts.Top; - } else - { olvHosts.Height = pnlImport.Bottom - olvHosts.Top; - } } private void StartScan() @@ -176,10 +173,13 @@ namespace mRemoteNG.UI.Window SwitchButtonText(); olvHosts.Items.Clear(); - System.Net.IPAddress ipAddressStart = System.Net.IPAddress.Parse(ipStart.Text); - System.Net.IPAddress ipAddressEnd = System.Net.IPAddress.Parse(ipEnd.Text); - - _portScanner = new PortScanner(ipAddressStart, ipAddressEnd, (int) portStart.Value, (int) portEnd.Value, ((int)numericSelectorTimeout.Value)*1000); + var ipAddressStart = IPAddress.Parse(ipStart.Text); + var ipAddressEnd = IPAddress.Parse(ipEnd.Text); + + if (!ngCheckFirstPort.Checked && !ngCheckLastPort.Checked) + _portScanner = new PortScanner(ipAddressStart, ipAddressEnd, (int)portStart.Value, (int)portEnd.Value, (int)numericSelectorTimeout.Value * 1000, true); + else + _portScanner = new PortScanner(ipAddressStart, ipAddressEnd, (int)portStart.Value, (int)portEnd.Value, (int)numericSelectorTimeout.Value*1000); _portScanner.BeginHostScan += PortScanner_BeginHostScan; _portScanner.HostScanned += PortScanner_HostScanned; @@ -194,8 +194,12 @@ namespace mRemoteNG.UI.Window } private void StopScan() - { - _portScanner?.StopScan(); + { + _portScanner.BeginHostScan -= PortScanner_BeginHostScan; + _portScanner.HostScanned -= PortScanner_HostScanned; + _portScanner.ScanComplete -= PortScanner_ScanComplete; + + _portScanner?.StopScan(); _scanning = false; SwitchButtonText(); } @@ -316,5 +320,17 @@ namespace mRemoteNG.UI.Window { importSelectedHosts(ProtocolType.HTTP); } + + private void NgCheckFirstPort_CheckedChanged(object sender, EventArgs e) + { + portStart.Enabled = ngCheckFirstPort.Checked; + } + + private void NgCheckLastPort_CheckedChanged(object sender, EventArgs e) + { + portEnd.Enabled = ngCheckLastPort.Checked; + + portEnd.Value = portEnd.Enabled ? 65535 : 0; + } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Window/PortScanWindow.resx b/mRemoteV1/UI/Window/PortScanWindow.resx index 641cc922d..19402096a 100644 --- a/mRemoteV1/UI/Window/PortScanWindow.resx +++ b/mRemoteV1/UI/Window/PortScanWindow.resx @@ -120,6 +120,9 @@ 17, 17 + + 161, 17 + diff --git a/mRemoteV1/UI/Window/SSHTransferWindow.cs b/mRemoteV1/UI/Window/SSHTransferWindow.cs index 65541e5ac..e19457a16 100644 --- a/mRemoteV1/UI/Window/SSHTransferWindow.cs +++ b/mRemoteV1/UI/Window/SSHTransferWindow.cs @@ -5,6 +5,7 @@ using System.Threading; using mRemoteNG.Tools; using WeifenLuo.WinFormsUI.Docking; using System.Windows.Forms; +using mRemoteNG.Messages; using mRemoteNG.UI.Forms; namespace mRemoteNG.UI.Window @@ -300,50 +301,26 @@ namespace mRemoteNG.UI.Window #region Public Properties public string Hostname { - get - { - return txtHost.Text; - } - set - { - txtHost.Text = value; - } + get => txtHost.Text; + set => txtHost.Text = value; } public string Port { - get - { - return txtPort.Text; - } - set - { - txtPort.Text = value; - } + get => txtPort.Text; + set => txtPort.Text = value; } public string Username { - get - { - return txtUser.Text; - } - set - { - txtUser.Text = value; - } + get => txtUser.Text; + set => txtUser.Text = value; } public string Password { - get - { - return txtPassword.Text; - } - set - { - txtPassword.Text = value; - } + get => txtPassword.Text; + set => txtPassword.Text = value; } #endregion @@ -380,13 +357,13 @@ namespace mRemoteNG.UI.Window { if (AllFieldsSet() == false) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, Language.strPleaseFillAllFields); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPleaseFillAllFields); return; } if (File.Exists(txtLocalFile.Text) == false) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.WarningMsg, Language.strLocalFileDoesNotExist); + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strLocalFileDoesNotExist); return; } @@ -397,14 +374,14 @@ namespace mRemoteNG.UI.Window // Connect creates the protocol objects and makes the initial connection. st.Connect(); - if (Protocol == SecureTransfer.SSHTransferProtocol.SCP) + switch (Protocol) { - st.ScpClt.Uploading += ScpClt_Uploading; - } - - if (Protocol == SecureTransfer.SSHTransferProtocol.SFTP) - { - st.asyncCallback = AsyncCallback; + case SecureTransfer.SSHTransferProtocol.SCP: + st.ScpClt.Uploading += ScpClt_Uploading; + break; + case SecureTransfer.SSHTransferProtocol.SFTP: + st.asyncCallback = AsyncCallback; + break; } var t = new Thread(StartTransferBG); @@ -422,7 +399,7 @@ namespace mRemoteNG.UI.Window private void AsyncCallback(IAsyncResult ar) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, $"SFTP AsyncCallback completed.", true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"SFTP AsyncCallback completed.", true); } private void ScpClt_Uploading(object sender, Renci.SshNet.Common.ScpUploadEventArgs e) @@ -441,7 +418,7 @@ namespace mRemoteNG.UI.Window try { DisableButtons(); - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, $"Transfer of {Path.GetFileName(st.SrcFile)} started.", true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Transfer of {Path.GetFileName(st.SrcFile)} started.", true); st.Upload(); // SftpClient is Asynchronous, so we need to wait here after the upload and handle the status directly since no status events are raised. @@ -458,14 +435,14 @@ namespace mRemoteNG.UI.Window } } - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, $"Transfer of {Path.GetFileName(st.SrcFile)} completed.", true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Transfer of {Path.GetFileName(st.SrcFile)} completed.", true); st.Disconnect(); st.Dispose(); EnableButtons(); } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionStackTrace(Language.strSSHStartTransferBG, ex); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strSSHStartTransferBG, ex, MessageClass.ErrorMsg, false); st?.Disconnect(); st?.Dispose(); } diff --git a/mRemoteV1/UI/Window/ScreenshotManagerWindow.cs b/mRemoteV1/UI/Window/ScreenshotManagerWindow.cs index 3293c9b0f..eab5589dc 100644 --- a/mRemoteV1/UI/Window/ScreenshotManagerWindow.cs +++ b/mRemoteV1/UI/Window/ScreenshotManagerWindow.cs @@ -23,127 +23,128 @@ namespace mRemoteNG.UI.Window internal SaveFileDialog dlgSaveSingleImage; internal FolderBrowserDialog dlgSaveAllImages; - internal FlowLayoutPanel flpScreenshots; - private WeifenLuo.WinFormsUI.Docking.VisualStudioToolStripExtender vsToolStripExtender; + private FlowLayoutPanel flpScreenshots; + private VisualStudioToolStripExtender vsToolStripExtender; private readonly ToolStripRenderer _toolStripProfessionalRenderer = new ToolStripProfessionalRenderer(); private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.flpScreenshots = new System.Windows.Forms.FlowLayoutPanel(); - this.msMain = new System.Windows.Forms.MenuStrip(); - this.mMenFile = new System.Windows.Forms.ToolStripMenuItem(); - this.mMenFileSaveAll = new System.Windows.Forms.ToolStripMenuItem(); - this.mMenFileRemoveAll = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenScreenshot = new System.Windows.Forms.ContextMenuStrip(this.components); - this.cMenScreenshotCopy = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenScreenshotSave = new System.Windows.Forms.ToolStripMenuItem(); - this.dlgSaveSingleImage = new System.Windows.Forms.SaveFileDialog(); - this.dlgSaveAllImages = new System.Windows.Forms.FolderBrowserDialog(); - this.msMain.SuspendLayout(); - this.cMenScreenshot.SuspendLayout(); - this.SuspendLayout(); + components = new System.ComponentModel.Container(); + flpScreenshots = new FlowLayoutPanel(); + msMain = new MenuStrip(); + mMenFile = new ToolStripMenuItem(); + mMenFileSaveAll = new ToolStripMenuItem(); + mMenFileRemoveAll = new ToolStripMenuItem(); + cMenScreenshot = new ContextMenuStrip(components); + cMenScreenshotCopy = new ToolStripMenuItem(); + cMenScreenshotSave = new ToolStripMenuItem(); + dlgSaveSingleImage = new SaveFileDialog(); + dlgSaveAllImages = new FolderBrowserDialog(); + msMain.SuspendLayout(); + cMenScreenshot.SuspendLayout(); + SuspendLayout(); // // flpScreenshots // - this.flpScreenshots.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.flpScreenshots.AutoScroll = true; - this.flpScreenshots.Location = new System.Drawing.Point(0, 26); - this.flpScreenshots.Name = "flpScreenshots"; - this.flpScreenshots.Size = new System.Drawing.Size(542, 296); - this.flpScreenshots.TabIndex = 0; + flpScreenshots.Anchor = AnchorStyles.Top | AnchorStyles.Bottom + | AnchorStyles.Left + | AnchorStyles.Right; + flpScreenshots.AutoScroll = true; + flpScreenshots.Location = new Point(0, 26); + flpScreenshots.Name = "flpScreenshots"; + flpScreenshots.Size = new Size(542, 296); + flpScreenshots.TabIndex = 0; // // msMain // - this.msMain.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.msMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mMenFile}); - this.msMain.Location = new System.Drawing.Point(0, 0); - this.msMain.Name = "msMain"; - this.msMain.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this.msMain.Size = new System.Drawing.Size(542, 24); - this.msMain.TabIndex = 1; - this.msMain.Text = "MenuStrip1"; + msMain.Font = new Font("Segoe UI", 8.25F, FontStyle.Regular, GraphicsUnit.Point, 0); + msMain.Items.AddRange(new ToolStripItem[] { + mMenFile}); + msMain.Location = new Point(0, 0); + msMain.Name = "msMain"; + msMain.RenderMode = ToolStripRenderMode.Professional; + msMain.Size = new Size(542, 24); + msMain.TabIndex = 1; + msMain.Text = "MenuStrip1"; // // mMenFile // - this.mMenFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mMenFileSaveAll, - this.mMenFileRemoveAll}); - this.mMenFile.Image = global::mRemoteNG.Resources.File; - this.mMenFile.Name = "mMenFile"; - this.mMenFile.Size = new System.Drawing.Size(53, 20); - this.mMenFile.Text = "&File"; - this.mMenFile.DropDownOpening += new System.EventHandler(this.mMenFile_DropDownOpening); + mMenFile.DropDownItems.AddRange(new ToolStripItem[] { + mMenFileSaveAll, + mMenFileRemoveAll}); + mMenFile.Image = Resources.File; + mMenFile.Name = "mMenFile"; + mMenFile.Size = new Size(53, 20); + mMenFile.Text = "&File"; + mMenFile.DropDownOpening += mMenFile_DropDownOpening; // // mMenFileSaveAll // - this.mMenFileSaveAll.Image = global::mRemoteNG.Resources.Screenshot_Save; - this.mMenFileSaveAll.Name = "mMenFileSaveAll"; - this.mMenFileSaveAll.Size = new System.Drawing.Size(130, 22); - this.mMenFileSaveAll.Text = "Save All"; - this.mMenFileSaveAll.Click += new System.EventHandler(this.mMenFileSaveAll_Click); + mMenFileSaveAll.Image = Resources.Screenshot_Save; + mMenFileSaveAll.Name = "mMenFileSaveAll"; + mMenFileSaveAll.Size = new Size(130, 22); + mMenFileSaveAll.Text = "Save All"; + mMenFileSaveAll.Click += mMenFileSaveAll_Click; // // mMenFileRemoveAll // - this.mMenFileRemoveAll.Image = global::mRemoteNG.Resources.Screenshot_Delete; - this.mMenFileRemoveAll.Name = "mMenFileRemoveAll"; - this.mMenFileRemoveAll.Size = new System.Drawing.Size(130, 22); - this.mMenFileRemoveAll.Text = "Remove All"; - this.mMenFileRemoveAll.Click += new System.EventHandler(this.mMenFileRemoveAll_Click); + mMenFileRemoveAll.Image = Resources.Screenshot_Delete; + mMenFileRemoveAll.Name = "mMenFileRemoveAll"; + mMenFileRemoveAll.Size = new Size(130, 22); + mMenFileRemoveAll.Text = "Remove All"; + mMenFileRemoveAll.Click += mMenFileRemoveAll_Click; // // cMenScreenshot // - this.cMenScreenshot.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.cMenScreenshotCopy, - this.cMenScreenshotSave}); - this.cMenScreenshot.Name = "cMenScreenshot"; - this.cMenScreenshot.Size = new System.Drawing.Size(103, 48); + cMenScreenshot.Items.AddRange(new ToolStripItem[] { + cMenScreenshotCopy, + cMenScreenshotSave}); + cMenScreenshot.Name = "cMenScreenshot"; + cMenScreenshot.Size = new Size(103, 48); // // cMenScreenshotCopy // - this.cMenScreenshotCopy.Image = global::mRemoteNG.Resources.Screenshot_Copy; - this.cMenScreenshotCopy.Name = "cMenScreenshotCopy"; - this.cMenScreenshotCopy.Size = new System.Drawing.Size(102, 22); - this.cMenScreenshotCopy.Text = "Copy"; - this.cMenScreenshotCopy.Click += new System.EventHandler(this.cMenScreenshotCopy_Click); + cMenScreenshotCopy.Image = Resources.Screenshot_Copy; + cMenScreenshotCopy.Name = "cMenScreenshotCopy"; + cMenScreenshotCopy.Size = new Size(102, 22); + cMenScreenshotCopy.Text = "Copy"; + cMenScreenshotCopy.Click += cMenScreenshotCopy_Click; // // cMenScreenshotSave // - this.cMenScreenshotSave.Image = global::mRemoteNG.Resources.Screenshot_Save; - this.cMenScreenshotSave.Name = "cMenScreenshotSave"; - this.cMenScreenshotSave.Size = new System.Drawing.Size(102, 22); - this.cMenScreenshotSave.Text = "Save"; - this.cMenScreenshotSave.Click += new System.EventHandler(this.cMenScreenshotSave_Click); + cMenScreenshotSave.Image = Resources.Screenshot_Save; + cMenScreenshotSave.Name = "cMenScreenshotSave"; + cMenScreenshotSave.Size = new Size(102, 22); + cMenScreenshotSave.Text = "Save"; + cMenScreenshotSave.Click += cMenScreenshotSave_Click; // // dlgSaveSingleImage // - this.dlgSaveSingleImage.Filter = "Graphics Interchange Format File (.gif)|*.gif|Joint Photographic Experts Group Fi" + + dlgSaveSingleImage.Filter = "Graphics Interchange Format File (.gif)|*.gif|Joint Photographic Experts Group Fi" + "le (.jpeg)|*.jpeg|Joint Photographic Experts Group File (.jpg)|*.jpg|Portable Ne" + "twork Graphics File (.png)|*.png"; - this.dlgSaveSingleImage.FilterIndex = 4; + dlgSaveSingleImage.FilterIndex = 4; // // ScreenshotManagerWindow // - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.ClientSize = new System.Drawing.Size(542, 323); - this.Controls.Add(this.flpScreenshots); - this.Controls.Add(this.msMain); - this.HideOnClose = true; - this.Icon = global::mRemoteNG.Resources.Screenshot_Icon; - this.MainMenuStrip = this.msMain; - this.Name = "ScreenshotManagerWindow"; - this.TabText = "Screenshots"; - this.Text = "Screenshots"; - this.Load += new System.EventHandler(this.ScreenshotManager_Load); - this.msMain.ResumeLayout(false); - this.msMain.PerformLayout(); - this.cMenScreenshot.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); + AutoScaleDimensions = new SizeF(96F, 96F); + AutoScaleMode = AutoScaleMode.Dpi; + ClientSize = new Size(542, 323); + Controls.Add(flpScreenshots); + Controls.Add(msMain); + Font = new Font("Segoe UI", 8.25F, FontStyle.Regular, GraphicsUnit.Point, 0); + HideOnClose = true; + Icon = Resources.Screenshot_Icon; + MainMenuStrip = msMain; + Name = "ScreenshotManagerWindow"; + TabText = "Screenshots"; + Text = "Screenshots"; + Load += ScreenshotManager_Load; + msMain.ResumeLayout(false); + msMain.PerformLayout(); + cMenScreenshot.ResumeLayout(false); + ResumeLayout(false); + PerformLayout(); } #endregion @@ -152,19 +153,19 @@ namespace mRemoteNG.UI.Window private void ScreenshotManager_Load(object sender, EventArgs e) { ApplyTheme(); - Themes.ThemeManager.getInstance().ThemeChanged += ApplyTheme; + ThemeManager.getInstance().ThemeChanged += ApplyTheme; ApplyLanguage(); } private new void ApplyTheme() { - if (ThemeManager.getInstance().ThemingActive) + if (!ThemeManager.getInstance().ThemingActive) return; + base.ApplyTheme(); + vsToolStripExtender = new VisualStudioToolStripExtender(components) { - base.ApplyTheme(); - this.vsToolStripExtender = new WeifenLuo.WinFormsUI.Docking.VisualStudioToolStripExtender(this.components); - vsToolStripExtender.DefaultRenderer = _toolStripProfessionalRenderer; - vsToolStripExtender.SetStyle(cMenScreenshot, ThemeManager.getInstance().ActiveTheme.Version, ThemeManager.getInstance().ActiveTheme.Theme); - } + DefaultRenderer = _toolStripProfessionalRenderer + }; + vsToolStripExtender.SetStyle(cMenScreenshot, ThemeManager.getInstance().ActiveTheme.Version, ThemeManager.getInstance().ActiveTheme.Theme); } private void ApplyLanguage() { diff --git a/mRemoteV1/UI/Window/UltraVNCWindow.cs b/mRemoteV1/UI/Window/UltraVNCWindow.cs index ae8d0b2d9..571cdb8ff 100644 --- a/mRemoteV1/UI/Window/UltraVNCWindow.cs +++ b/mRemoteV1/UI/Window/UltraVNCWindow.cs @@ -59,6 +59,7 @@ namespace mRemoteNG.UI.Window this.ClientSize = new System.Drawing.Size(446, 362); this.Controls.Add(this.pnlContainer); this.Controls.Add(this.tsMain); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Icon = global::mRemoteNG.Resources.UVNC_SC_Icon; this.Name = "UltraVNCWindow"; this.TabText = "UltraVNC SC"; diff --git a/mRemoteV1/app.config b/mRemoteV1/app.config index 12b1665b0..fd2909dbb 100644 --- a/mRemoteV1/app.config +++ b/mRemoteV1/app.config @@ -708,6 +708,12 @@ General + + False + + + False + True diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 79d4c26f1..61d5772e7 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -19,7 +19,7 @@ false Properties\app.manifest - Resources\Icons\mRemote_Icon.ico + Resources\Icons\mRemoteNG_Icon.ico Off B249710A6BB08171F8E75082CF2355AE2890911A mRemoteV1_TemporaryKey.pfx @@ -71,8 +71,8 @@ ..\packages\ObjectListView.Official.2.9.1\lib\net20\ObjectListView.dll - - ..\packages\SSH.NET.2016.0.0\lib\net40\Renci.SshNet.dll + + ..\packages\SSH.NET.2016.1.0\lib\net40\Renci.SshNet.dll @@ -89,20 +89,20 @@ False References\VncSharp.dll - - ..\packages\DockPanelSuite.2.16.1\lib\net40\WeifenLuo.WinFormsUI.Docking.dll + + ..\packages\DockPanelSuite.3.0.6\lib\net40\WeifenLuo.WinFormsUI.Docking.dll - - ..\packages\DockPanelSuite.ThemeVS2003.2.16.1\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2003.dll + + ..\packages\DockPanelSuite.ThemeVS2003.3.0.6\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2003.dll - - ..\packages\DockPanelSuite.ThemeVS2012.2.16.1\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2012.dll + + ..\packages\DockPanelSuite.ThemeVS2012.3.0.6\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2012.dll - - ..\packages\DockPanelSuite.ThemeVS2013.2.16.1\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2013.dll + + ..\packages\DockPanelSuite.ThemeVS2013.3.0.6\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2013.dll - - ..\packages\DockPanelSuite.ThemeVS2015.2.16.1\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll + + ..\packages\DockPanelSuite.ThemeVS2015.3.0.6\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll @@ -164,6 +164,7 @@ + @@ -254,6 +255,11 @@ + + True + True + Resources.resx + True True @@ -376,6 +382,12 @@ Component + + Component + + + NGPictureBox.cs + Component @@ -479,18 +491,24 @@ - + Form - - frmOptions.cs + + FrmOptions.cs + + + Form + + + FrmSplashScreen.cs - + Form - - InputBox.cs + + FrmInputBox.cs AdvancedPage.cs @@ -596,10 +614,10 @@ - - frmChoosePanel.cs + + FrmChoosePanel.cs - + Form @@ -621,11 +639,6 @@ - - True - True - Resources.resx - True True @@ -652,6 +665,14 @@ Component + + Form + + + UnhandledExceptionWindow.cs + + + Component @@ -766,31 +787,91 @@ ColorMapTheme.Designer.cs mRemoteNG + + NGButton.cs + + + NGCheckBox.cs + + + NGComboBox.cs + + + NGGroupBox.cs + + + NGLabel.cs + + + NGListView.cs + + + NGNumericUpDown.cs + + + NGRadioButton.cs + + + NGTextBox.cs + + + ConnectionTree.cs + + + CredentialRecordComboBox.cs + + + CredentialRecordListBox.cs + CredentialRecordListView.cs CredentialRepositoryListView.cs + + FilteredPropertyGrid.cs + + + HeadlessTabControl.cs + IPTextBox.cs NewPasswordWithVerification.cs - - frmChoosePanel.cs + + SequencedControl.cs + + + SecureTextBox.cs + + + FrmChoosePanel.cs Designer FrmMain.cs Designer - - frmOptions.cs + + FrmOptions.cs - - InputBox.cs + + FrmSplashScreen.cs + + + FrmInputBox.cs + + + AdvancedPage.cs + + + AppearancePage.cs + + + ConnectionsPage.cs CredentialsPage.cs @@ -804,19 +885,6 @@ SecurityPage.cs - - PasswordForm.cs - Designer - - - AdvancedPage.cs - - - AppearancePage.cs - - - ConnectionsPage.cs - SqlServerPage.cs @@ -832,6 +900,10 @@ UpdatesPage.cs + + PasswordForm.cs + Designer + Designer @@ -887,14 +959,23 @@ ResXFileCodeGenerator - Resources.Designer.cs mRemoteNG Designer + Resources.Designer.cs ReconnectGroup.cs Designer + + TextBox.cs + + + UnhandledExceptionWindow.cs + + + CommandButton.cs + frmTaskDialog.cs @@ -906,6 +987,9 @@ ActiveDirectoryImportWindow.cs Designer + + BaseWindow.cs + ComponentsCheckWindow.cs Designer @@ -963,6 +1047,14 @@ + + + + + + + + Always @@ -975,24 +1067,174 @@ Always + + + + Designer - - - Designer + PreserveNewest Designer + PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + Always + + + Always + + + Always + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Designer - Always + PreserveNewest Designer + PreserveNewest Designer + PreserveNewest @@ -1015,64 +1257,52 @@ - + PreserveNewest - + PreserveNewest - + PreserveNewest - - PreserveNewest - - - PreserveNewest - - + PreserveNewest PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - - PreserveNewest - - + PreserveNewest PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - - PreserveNewest - - + PreserveNewest @@ -1180,17 +1410,11 @@ PreserveNewest - + PreserveNewest - - PreserveNewest - - - - @@ -1222,10 +1446,7 @@ - - - @@ -1233,25 +1454,17 @@ - - - - - - - - @@ -1272,8 +1485,6 @@ - - @@ -1284,12 +1495,10 @@ - - @@ -1300,26 +1509,17 @@ - - - - - - - - - PreserveNewest @@ -1417,14 +1617,9 @@ - - - - - mRemoteNG SettingsSingleFileGenerator @@ -1434,13 +1629,6 @@ - - - - - - - @@ -1459,7 +1647,6 @@ - diff --git a/mRemoteV1/mRemoteV1.csproj.DotSettings b/mRemoteV1/mRemoteV1.csproj.DotSettings deleted file mode 100644 index f9340e335..000000000 --- a/mRemoteV1/mRemoteV1.csproj.DotSettings +++ /dev/null @@ -1,9 +0,0 @@ - - True - False - True - True - True - True - True - True \ No newline at end of file diff --git a/mRemoteV1/mRemoteV1.csproj.user b/mRemoteV1/mRemoteV1.csproj.user deleted file mode 100644 index 515c0163e..000000000 --- a/mRemoteV1/mRemoteV1.csproj.user +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - publish\ - - - - - - en-US - false - - - false - - \ No newline at end of file diff --git a/mRemoteV1/packages.config b/mRemoteV1/packages.config index de93aab2e..f64e2f546 100644 --- a/mRemoteV1/packages.config +++ b/mRemoteV1/packages.config @@ -1,13 +1,13 @@  - - - - - + + + + + - + \ No newline at end of file