From 6c601cd5453be96c4690e02ceb2107bbc34ffff5 Mon Sep 17 00:00:00 2001 From: ProxySU <proxysetuptools@gmail.com> Date: Fri, 28 Aug 2020 09:03:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=8B=B1=E6=96=87=E7=89=88?= =?UTF-8?q?=E7=95=8C=E9=9D=A201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProxySU/App.xaml | 7 +- ProxySU/MainWindow.xaml | 97 +- ProxySU/MainWindow.xaml.cs | 1949 ++++++++++------------- ProxySU/ProofreadTimeWindow.xaml.cs | 21 +- ProxySU/ProxySU.csproj | 9 + ProxySU/ResultClientInformation.xaml | 2 +- ProxySU/ResultClientInformation.xaml.cs | 16 +- ProxySU/Translations/ProxySU.en-US.xaml | 136 ++ ProxySU/Translations/ProxySU.zh-CN.xaml | 141 ++ ProxySU/TrojanGoTemplateWindow.xaml | 32 +- ProxySU/V2RayTemplateWindow.xaml | 188 +-- ProxySU/bin/Beta/Beta.zip | Bin 497468 -> 505312 bytes 12 files changed, 1327 insertions(+), 1271 deletions(-) create mode 100644 ProxySU/Translations/ProxySU.en-US.xaml create mode 100644 ProxySU/Translations/ProxySU.zh-CN.xaml diff --git a/ProxySU/App.xaml b/ProxySU/App.xaml index 332218e..727c569 100644 --- a/ProxySU/App.xaml +++ b/ProxySU/App.xaml @@ -4,6 +4,11 @@ xmlns:local="clr-namespace:ProxySU" StartupUri="MainWindow.xaml"> <Application.Resources> - + <ResourceDictionary> + <ResourceDictionary.MergedDictionaries> + <ResourceDictionary Source="Translations\ProxySU.zh-CN.xaml" /> + <ResourceDictionary Source="Translations\ProxySU.en-US.xaml" /> + </ResourceDictionary.MergedDictionaries> + </ResourceDictionary> </Application.Resources> </Application> diff --git a/ProxySU/MainWindow.xaml b/ProxySU/MainWindow.xaml index 36ff75f..ba714a7 100644 --- a/ProxySU/MainWindow.xaml +++ b/ProxySU/MainWindow.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ProxySU" mc:Ignorable="d" - Title="ProxySU - v1.8.5" Height="600" Width="530"> + Title="ProxySU - v1.8.6" Height="600" Width="530"> <!--以下样式参考自:https://yq.aliyun.com/articles/331878 https://docs.microsoft.com/en-us/dotnet/desktop-wpf/fundamentals/styles-templates-overview--> <Window.Resources> @@ -38,7 +38,7 @@ </Grid> </TabItem>--> - <TabItem Header="应用布署" Width="110" Height="30"> + <TabItem Header="{DynamicResource TabItemHeaderAppDeployment}" Width="110" Height="30"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="80"></ColumnDefinition> @@ -60,12 +60,12 @@ <RowDefinition ></RowDefinition> <RowDefinition Height="60"></RowDefinition> </Grid.RowDefinitions> - <TextBlock Text="主机名:" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="5" Grid.Column="0" Grid.Row="0"></TextBlock> - <TextBlock Text="端口:" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="5" Grid.Column="2" Grid.Row="0"></TextBlock> - <TextBox x:Name="TextBoxHost" Text="" Style="{StaticResource TitleText}" Tag="IP或域名(不可为空)" Margin="5" Grid.Column="1" Grid.Row="0"></TextBox> + <TextBlock Text="{DynamicResource TextBlockHostName}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5" Grid.Column="0" Grid.Row="0"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockHostPart}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5" Grid.Column="2" Grid.Row="0"></TextBlock> + <TextBox x:Name="TextBoxHost" Text="" Style="{StaticResource TitleText}" Tag="{DynamicResource TextBoxHostNamePrompt}" Margin="5" Grid.Column="1" Grid.Row="0"></TextBox> <TextBox x:Name="TextBoxPort" CommandManager.PreviewExecuted="TextBoxPort_PreviewExecuted" Text="22" Margin="5" Grid.Column="3" Grid.Row="0" PreviewTextInput="TextBoxPort_PreviewTextInput"/> - <TextBlock Text="用户名:" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="5" Grid.Column="0" Grid.Row="1"></TextBlock> - <TextBlock x:Name="TextBlockPassword" Text="密码:" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="5" Grid.Column="2" Grid.Row="1"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockHostUser}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5" Grid.Column="0" Grid.Row="1"></TextBlock> + <TextBlock x:Name="TextBlockPassword" Text="{DynamicResource TextBlockHostPassword}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5" Grid.Column="2" Grid.Row="1"></TextBlock> <TextBox x:Name="TextBoxUserName" Text="root" Margin="5" Grid.Column="1" Grid.Row="1"></TextBox> <PasswordBox x:Name="PasswordBoxHostPassword" Password="" Margin="5" Grid.Column="3" Grid.Row="1"></PasswordBox> <RadioButton x:Name="RadioButtonPasswordLogin" GroupName="CertIsYesNo" Content="密码登录" Visibility="Hidden" Grid.Column="0" Grid.Row="2" Checked="RadioButtonPasswordLogin_Checked"></RadioButton> @@ -103,11 +103,11 @@ <PasswordBox x:Name="PasswordBoxProxyPassword" IsEnabled="False" Password="" Margin="5" Grid.Column="3" Grid.Row="6" Visibility="Collapsed"></PasswordBox> <!--<StatusBar x:Name="StatusBarStatusMonitoring" Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="4"></StatusBar>--> - <TextBlock x:Name="TextBlockSetUpProcessing" Text="等待安装布署" Foreground="Blue" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="4"></TextBlock> + <TextBlock x:Name="TextBlockSetUpProcessing" Text="{DynamicResource TextBlockSetUpProcessing}" Foreground="Blue" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="4"></TextBlock> <ProgressBar x:Name="ProgressBarSetUpProcessing" Minimum="0" Maximum="100" Value="0" IsIndeterminate="False" Margin="7" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="4"></ProgressBar> <TextBox x:Name="TextBoxMonitorCommandResults" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="4" Grid.RowSpan="5" Margin="30,0,30,10"></TextBox> <TabControl Grid.Column="0" Grid.Row="9" Grid.ColumnSpan="4" Grid.RowSpan="3"> - <TabItem Header="V2ray" Width="100" Height="30"> + <TabItem Header="V2Ray" Width="100" Height="30"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> @@ -122,7 +122,7 @@ <!--<Button x:Name="ButtonGuideConfiguration" Visibility="Visible" Content="启用向导" Grid.Column="0" Grid.Row="0" Click="ButtonGuideConfiguration_Click"></Button> <TextBlock Text="通过向导生成配置文件" Visibility="Visible" Grid.Column="0" Grid.Row="1" Grid.RowSpan="2" HorizontalAlignment="Center"></TextBlock>--> - <Button x:Name="ButtonTemplateConfiguration" Content="V2ray模板库" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonTemplateConfiguration_Click"></Button> + <Button x:Name="ButtonTemplateConfiguration" Content="{DynamicResource ButtonV2RayTemplateConfiguration}" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonTemplateConfiguration_Click"></Button> <!--<TextBlock Text="模板库" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" HorizontalAlignment="Center"></TextBlock>--> <!--<Button x:Name="ButtonAdvancedConfiguration" Visibility="Visible" Content="配置编辑器" Grid.Column="2" Grid.Row="0" Click="ButtonAdvancedConfiguration_Click"></Button> <TextBlock Text="配置文件高级生成器
(有经验用户可以使用)" Visibility="Visible" Grid.Column="2" Grid.Row="1" Grid.RowSpan="2" HorizontalAlignment="Center"></TextBlock>--> @@ -131,9 +131,9 @@ <RadioButton x:Name="RadioButtonAdvancedConfiguration" Content="高级配置" Grid.Column="0" Grid.Row="2"></RadioButton> <TextBox x:Name="TextBoxJsonPath" Margin="10" Grid.Column="1" Grid.Row="1"></TextBox> <Button x:Name="ButtonSetConfiguration" Margin="6" Content="配置" Grid.Column="2" Grid.Row="2" Click="ButtonSetConfiguration_Click"></Button>--> - <Button x:Name="Button_Login" Content="V2ray一键安装" Margin="10" Grid.Column="0" Grid.Row="2" Click="Button_Login_Click"></Button> - <Button x:Name="ButtonUpdateV2ray" Content="检测/升级V2Ray" Margin="10" Grid.Column="1" Grid.Row="2" Click="ButtonUpdateV2ray_Click"></Button> - <Button x:Name="Button_canel" Content="取消" Margin="10" Grid.Column="2" Grid.Row="2" Click="Button_canel_Click"></Button> + <Button x:Name="Button_Login" Content="{DynamicResource ButtonV2RayOneKeyInstall}" Margin="10" Grid.Column="0" Grid.Row="2" Click="Button_Login_Click"></Button> + <Button x:Name="ButtonUpdateV2ray" Content="{DynamicResource ButtonUpdateV2ray}" Margin="10" Grid.Column="1" Grid.Row="2" Click="ButtonUpdateV2ray_Click"></Button> + <Button x:Name="Button_canel" Content="{DynamicResource Button_canel}" Margin="10" Grid.Column="2" Grid.Row="2" Click="Button_canel_Click"></Button> </Grid> </TabItem> <TabItem Header="Trojan-Go" Width="100" Height="30"> @@ -153,11 +153,11 @@ <!--<Button x:Name="ButtonTrojanTemplate" Content="Trojan参数设置" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonTrojanTemplate_Click"/>--> <!--<TextBlock Text="Trojan参数设置" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" HorizontalAlignment="Center"></TextBlock>--> - <Button x:Name="ButtonTrojanGoTemplate" Content="Trojan-Go参数设置" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonTrojanGoTemplate_Click"/> + <Button x:Name="ButtonTrojanGoTemplate" Content="{DynamicResource ButtonTrojanGoTemplate}" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonTrojanGoTemplate_Click"/> - <Button x:Name="ButtonTrojanGoSetUp" Content="Trojan-Go一键安装" Margin="10" Grid.Column="0" Grid.Row="2" Click="ButtonTrojanGoSetUp_Click"/> - <Button x:Name="ButtonUpdateTrojanGo" Content="检测/升级Trojan-Go" Margin="10" Grid.Column="1" Grid.Row="2" Click="ButtonUpdateTrojanGo_Click"></Button> - <Button x:Name="ButtonTrojanGoCancel" Content="取消" Margin="10" Grid.Column="2" Grid.Row="2" Click="Button_canel_Click"></Button> + <Button x:Name="ButtonTrojanGoSetUp" Content="{DynamicResource ButtonTrojanGoSetUp}" Margin="10" Grid.Column="0" Grid.Row="2" Click="ButtonTrojanGoSetUp_Click"/> + <Button x:Name="ButtonUpdateTrojanGo" Content="{DynamicResource ButtonUpdateTrojanGo}" Margin="10" Grid.Column="1" Grid.Row="2" Click="ButtonUpdateTrojanGo_Click"></Button> + <Button x:Name="ButtonTrojanGoCancel" Content="{DynamicResource ButtonTrojanGoCancel}" Margin="10" Grid.Column="2" Grid.Row="2" Click="Button_canel_Click"></Button> </Grid> </TabItem> <TabItem Header="Trojan" Width="100" Height="30"> @@ -174,7 +174,7 @@ <RowDefinition Height="60"></RowDefinition> </Grid.RowDefinitions> - <GroupBox Header="参数设置" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="2"> + <GroupBox Header="{DynamicResource GroupBoxHeaderParameterTrojan}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="2"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="0.4*"></ColumnDefinition> @@ -189,16 +189,16 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <TextBlock Text="模式:Trojan+TLS+Caddy" Grid.Column="1" Grid.Row="0"></TextBlock> - <TextBlock Text="服务器地址(域名):" Grid.Column="0" Grid.Row="1"></TextBlock> - <TextBox x:Name="TextBoxTrojanHostDomain" Style="{StaticResource TitleText}" Tag="域名不可为空" Grid.Column="1" Grid.Row="1" Margin="3"></TextBox> - <TextBlock Text="端口:443" Grid.Column="2" Grid.Row="1"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockTrojanTemplateExplanation}" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockTrojanServerDomain}" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5"></TextBlock> + <TextBox x:Name="TextBoxTrojanHostDomain" Style="{StaticResource TitleText}" Tag="{DynamicResource TextBoxDomainPrompt}" Grid.Column="1" Grid.Row="1" Margin="3"></TextBox> + <TextBlock Text="{DynamicResource TextBlockTrojanPort}" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> <!--<TextBlock Text="用户名:" Grid.Column="0" Grid.Row="2"></TextBlock> <TextBox x:Name="TextBoxUser" Grid.Column="1" Grid.Row="2" Margin="3"></TextBox> <Button x:Name="ButtonNaiveUser" Content="随机" Grid.Column="2" Grid.Row="2" Margin="2" Click="ButtonNaiveUser_Click"></Button>--> - <TextBlock Text="密码:" Grid.Column="0" Grid.Row="2"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockTrojanHostPassword}" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="TextBoxTrojanPassword" Grid.Column="1" Grid.Row="2" Margin="3"></TextBox> - <Button x:Name="ButtonTrojanPassword" Content="更新" Grid.Column="2" Grid.Row="2" Margin="2" Click="ButtonTrojanPassword_Click" ></Button> + <Button x:Name="ButtonTrojanPassword" Content="{DynamicResource ButtonTrojanChangePassword}" Grid.Column="2" Grid.Row="2" Margin="2" Click="ButtonTrojanPassword_Click" ></Button> <TextBlock Text="伪装网站:" Grid.Column="0" Grid.Row="3" Visibility="Collapsed"></TextBlock> <TextBox x:Name="TextBoxTrojanSites" Style="{StaticResource TitleText}" Tag="可以增加代理的隐蔽(可为空)" Grid.Column="1" Grid.Row="3" Margin="3" Visibility="Collapsed"></TextBox> @@ -211,9 +211,9 @@ <!--<Button x:Name="ButtonTrojanGoTemplate" Content="Trojan-Go参数设置" Grid.Column="2" Grid.Row="0" Margin="5" Click="ButtonTrojanGoTemplate_Click"/>--> - <Button x:Name="ButtonTrojanSetUp" Content="Trojan一键安装" Grid.Column="0" Grid.Row="2" Margin="10" Click="ButtonTrojanSetUp_Click"/> - <Button x:Name="ButtonUpdateTrojan" Content="检测/升级Trojan" Grid.Column="1" Grid.Row="2" Margin="10" Click="ButtonUpdateTrojan_Click"></Button> - <Button x:Name="ButtonTrojanCancel" Content="取消" Grid.Column="2" Grid.Row="2" Margin="10" Click="Button_canel_Click"></Button> + <Button x:Name="ButtonTrojanSetUp" Content="{DynamicResource ButtonTrojanSetUp}" Grid.Column="0" Grid.Row="2" Margin="10" Click="ButtonTrojanSetUp_Click"/> + <Button x:Name="ButtonUpdateTrojan" Content="{DynamicResource ButtonUpdateTrojan}" Grid.Column="1" Grid.Row="2" Margin="10" Click="ButtonUpdateTrojan_Click"></Button> + <Button x:Name="ButtonTrojanCancel" Content="{DynamicResource ButtonTrojanCancel}" Grid.Column="2" Grid.Row="2" Margin="10" Click="Button_canel_Click"></Button> </Grid> </TabItem> <TabItem x:Name="TabItemNaiveProxy" Header="NaiveProxy" Width="100" Height="30"> @@ -228,7 +228,7 @@ <RowDefinition></RowDefinition> <RowDefinition Height="60"></RowDefinition> </Grid.RowDefinitions> - <GroupBox Header="参数设置" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="2"> + <GroupBox Header="{DynamicResource GroupBoxHeaderParameterTrojan}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="2"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="0.4*"></ColumnDefinition> @@ -243,16 +243,16 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <TextBlock Text="模式:NaiveProxy+TLS+Caddy" Grid.Column="1" Grid.Row="0"></TextBlock> - <TextBlock Text="服务器地址(域名):" Grid.Column="0" Grid.Row="1"></TextBlock> - <TextBox x:Name="TextBoxNaiveHostDomain" Style="{StaticResource TitleText}" Tag="域名不可为空" Grid.Column="1" Grid.Row="1" Margin="3"></TextBox> - <TextBlock Text="端口:443" Grid.Column="2" Grid.Row="1"></TextBlock> - <TextBlock Text="用户名:" Grid.Column="0" Grid.Row="2"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockNaiveProxyTemplateExplanation}" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockTrojanServerDomain}" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> + <TextBox x:Name="TextBoxNaiveHostDomain" Style="{StaticResource TitleText}" Tag="{DynamicResource TextBoxDomainPrompt}" Grid.Column="1" Grid.Row="1" Margin="3"></TextBox> + <TextBlock Text="{DynamicResource TextBlockTrojanPort}" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockHostUser}" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="TextBoxNaiveUser" Grid.Column="1" Grid.Row="2" Margin="3"></TextBox> - <Button x:Name="ButtonNaiveUser" Content="随机" Grid.Column="2" Grid.Row="2" Margin="2" Click="ButtonNaiveUser_Click"></Button> - <TextBlock Text="密码:" Grid.Column="0" Grid.Row="3"></TextBlock> + <Button x:Name="ButtonNaiveUser" Content="{DynamicResource ButtonNaiveProxyChangeUser}" Grid.Column="2" Grid.Row="2" Margin="2" Click="ButtonNaiveUser_Click"></Button> + <TextBlock Text="{DynamicResource TextBlockTrojanHostPassword}" Grid.Column="0" Grid.Row="3" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="TextBoxNaivePassword" Grid.Column="1" Grid.Row="3" Margin="3"></TextBox> - <Button x:Name="ButtonNaivePassword" Content="更新" Grid.Column="2" Grid.Row="3" Margin="2" Click="ButtonNaivePassword_Click"></Button> + <Button x:Name="ButtonNaivePassword" Content="{DynamicResource ButtonTrojanChangePassword}" Grid.Column="2" Grid.Row="3" Margin="2" Click="ButtonNaivePassword_Click"></Button> <TextBlock Text="伪装网站:" Grid.Column="0" Grid.Row="4" Visibility="Collapsed"></TextBlock> <TextBox x:Name="TextBoxNaiveSites" Style="{StaticResource TitleText}" Tag="可以增加代理的隐蔽(可为空)" Grid.Column="1" Grid.Row="4" Margin="3" Visibility="Collapsed"></TextBox> @@ -261,8 +261,8 @@ <!--<Button x:Name="ButtonNaiveTemplate" Content="Naive设置" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonTrojanTemplate_Click"/> <TextBlock Text="Naive参数设置" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" HorizontalAlignment="Center"></TextBlock>--> - <Button x:Name="ButtonNavieSetUp" Content="NaiveProxy一键安装" Grid.ColumnSpan="1" Margin="10" Grid.Column="0" Grid.Row="2" Click="ButtonNavieSetUp_Click"/> - <Button x:Name="ButtonNaiveCancel" Content="取消" Grid.ColumnSpan="1" Margin="10" Grid.Column="2" Grid.Row="2" Click="Button_canel_Click"></Button> + <Button x:Name="ButtonNavieSetUp" Content="{DynamicResource ButtonNavieSetUp}" Grid.ColumnSpan="1" Margin="10" Grid.Column="0" Grid.Row="2" Click="ButtonNavieSetUp_Click"/> + <Button x:Name="ButtonNaiveCancel" Content="{DynamicResource ButtonNaiveCancel}" Grid.ColumnSpan="1" Margin="10" Grid.Column="2" Grid.Row="2" Click="Button_canel_Click"></Button> </Grid> </TabItem> <TabItem Header="三合一" Width="100" Height="30" Visibility="Collapsed"> @@ -334,8 +334,8 @@ <Button x:Name="Button_canel3in1" Content="取消" Grid.ColumnSpan="1" Margin="10" Grid.Column="2" Grid.Row="2" Click="Button_canel_Click"></Button> </Grid> </TabItem> - - <TabItem Header="系统工具" Width="100" Height="30"> + + <TabItem Header="{DynamicResource TabItemHeaderSysTools}" Width="100" Height="30"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> @@ -348,9 +348,10 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <Button x:Name="ButtonProofreadTime" Content="校对时间" Grid.Column="0" Grid.Row="0" Margin="5" Click="ButtonProofreadTime_Click"/> - <Button x:Name="ButtonClearOccupiedPorts" Content="释放80/443端口" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonClearOccupiedPorts_Click"></Button> - <Button x:Name="ButtonTestAndEnableBBR" Content="检测/启用BBR" Grid.Column="2" Grid.Row="0" Margin="5" Click="ButtonTestAndEnableBBR_Click"></Button> + <Button x:Name="ButtonProofreadTime" Content="{DynamicResource ButtonProofreadTime}" Grid.Column="0" Grid.Row="0" Margin="5" Click="ButtonProofreadTime_Click"/> + <Button x:Name="ButtonClearOccupiedPorts" Content="{DynamicResource ButtonClearOccupiedPorts}" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonClearOccupiedPorts_Click"></Button> + <Button x:Name="ButtonTestAndEnableBBR" Content="{DynamicResource ButtonTestAndEnableBBR}" Grid.Column="2" Grid.Row="0" Margin="5" Click="ButtonTestAndEnableBBR_Click"></Button> + </Grid> </TabItem> @@ -377,7 +378,7 @@ </Grid> </TabItem> - <TabItem Header="资源工具" Width="110" Height="30"> + <TabItem Header="{DynamicResource TabItemHeaderResourceTools}" Width="110" Height="30"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> @@ -406,10 +407,10 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <Button x:Name="ButtonWebBrowserHomePage" Content="主页" Grid.Column="0" Grid.Row="0" Margin="5" Click="ButtonWebBrowserHomePage_Click"></Button> - <Button x:Name="ButtonWebBrowserForward" Content="前进" Grid.Column="2" Grid.Row="0" Margin="5" Click="ButtonWebBrowserForward_Click"></Button> - <Button x:Name="ButtonWebBrowserBack" Content="后退" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonWebBrowserBack_Click"/> - <TextBlock Text="由于众所周知的原因,在某些时候,加载缓慢,请耐心等待一下" Grid.Column="4" Grid.Row="0" Grid.ColumnSpan="4" Margin="5"></TextBlock> + <Button x:Name="ButtonWebBrowserHomePage" Content="{DynamicResource ButtonWebBrowserHomePage}" Grid.Column="0" Grid.Row="0" Margin="5" Click="ButtonWebBrowserHomePage_Click"></Button> + <Button x:Name="ButtonWebBrowserForward" Content="{DynamicResource ButtonWebBrowserForward}" Grid.Column="2" Grid.Row="0" Margin="5" Click="ButtonWebBrowserForward_Click"></Button> + <Button x:Name="ButtonWebBrowserBack" Content="{DynamicResource ButtonWebBrowserBack}" Grid.Column="1" Grid.Row="0" Margin="5" Click="ButtonWebBrowserBack_Click"/> + <TextBlock Text="{DynamicResource TextBlockWebExplain}" TextWrapping="Wrap" Grid.Column="4" Grid.Row="0" Grid.ColumnSpan="4"></TextBlock> <!--<TextBox x:Name="TextBoxWebBrowserProxyUrl" Style="{StaticResource TitleText}" Tag="粘贴被墙的网址到这里点击 GO(下面被墙网址右击==复制快捷方式)" Grid.Column="3" Grid.Row="0" Grid.ColumnSpan="5" Margin="5"></TextBox> <Button x:Name="ButtonWebBrowserProxyGo" Content="Go" Grid.Column="8" Grid.Row="0" Margin="5" Click="ButtonWebBrowserProxyGo_Click"></Button>--> <WebBrowser x:Name="WebBrowserResourcesAndTools" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="9" Grid.RowSpan="13" Source="https://github.com/proxysu/windows/wiki/ResourcesAndTools" /> diff --git a/ProxySU/MainWindow.xaml.cs b/ProxySU/MainWindow.xaml.cs index c3c5288..4114859 100644 --- a/ProxySU/MainWindow.xaml.cs +++ b/ProxySU/MainWindow.xaml.cs @@ -51,9 +51,13 @@ namespace ProxySU static string sshCmdUpdate; //保存软件安装所用更新软件库命令 static string sshCmdInstall; //保存软件安装所用命令格式 + //****** ****** + // Application.Current.FindResource("").ToString() public MainWindow() { + InitializeComponent(); + ResourcesLoad(); //初始化选定密码登录 RadioButtonPasswordLogin.IsChecked = true; //初始化选定无代理 @@ -118,6 +122,29 @@ namespace ProxySU #endregion #region 主界面控件的有效无效控制代码块 + //加载语言资源文件 + private void ResourcesLoad() + { + string Culture = System.Globalization.CultureInfo.InstalledUICulture.Name; + List<ResourceDictionary> dictionaryList = new List<ResourceDictionary>(); + foreach (ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries) + { + dictionaryList.Add(dictionary); + } + string requestedCulture = string.Format(@"Translations\ProxySU.{0}.xaml", Culture); + //string requestedCulture = string.Format(@"Translations\ProxySU.{0}.xaml", "default"); + ResourceDictionary resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString.Equals(requestedCulture)); + if (resourceDictionary == null) + { + requestedCulture = @"Translations\ProxySU.en-US.xaml"; + resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString.Equals(requestedCulture)); + } + if (resourceDictionary != null) + { + Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary); + Application.Current.Resources.MergedDictionaries.Add(resourceDictionary); + } + } private void RadioButtonNoProxy_Checked(object sender, RoutedEventArgs e) { TextBlockProxyHost.IsEnabled = false; @@ -186,7 +213,7 @@ namespace ProxySU ButtonOpenFileDialog.Visibility = Visibility.Collapsed; TextBoxCertFilePath.IsEnabled = false; TextBoxCertFilePath.Visibility = Visibility.Collapsed; - TextBlockPassword.Text = "密码:"; + //TextBlockPassword.Text = "密码:"; //TextBlockPassword.Visibility = Visibility.Visible; PasswordBoxHostPassword.IsEnabled = true; PasswordBoxHostPassword.Visibility = Visibility.Visible; @@ -194,7 +221,7 @@ namespace ProxySU private void RadioButtonCertLogin_Checked(object sender, RoutedEventArgs e) { - TextBlockPassword.Text = "密钥:"; + //TextBlockPassword.Text = "密钥:"; //TextBlockPassword.Visibility = Visibility.Collapsed; PasswordBoxHostPassword.IsEnabled = false; PasswordBoxHostPassword.Visibility = Visibility.Collapsed; @@ -237,7 +264,8 @@ namespace ProxySU #region 检测输入的内空是否有错,并读取内容 if (string.IsNullOrEmpty(TextBoxHost.Text) == true || string.IsNullOrEmpty(TextBoxPort.Text) == true || string.IsNullOrEmpty(TextBoxUserName.Text) == true) { - MessageBox.Show("主机地址、主机端口、用户名为必填项,不能为空"); + //******"主机地址、主机端口、用户名为必填项,不能为空"****** + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorHostPortUserNotEmpty").ToString()); return connectionInfo = null; } @@ -247,13 +275,15 @@ namespace ProxySU if (RadioButtonPasswordLogin.IsChecked == true && string.IsNullOrEmpty(PasswordBoxHostPassword.Password) == true) { - MessageBox.Show("登录密码为必填项,不能为空"); + //****** "登录密码为必填项,不能为空!!" ****** + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorHostPasswordNotEmpty").ToString()); return connectionInfo = null; } string sshPassword = PasswordBoxHostPassword.Password.ToString(); if (RadioButtonCertLogin.IsChecked == true && string.IsNullOrEmpty(TextBoxCertFilePath.Text) == true) { - MessageBox.Show("密钥文件为必填项,不能为空"); + //****** "密钥文件为必填项,不能为空!" ****** + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorHostKeyNotEmpty").ToString()); return connectionInfo = null; } string sshPrivateKey = TextBoxCertFilePath.Text.ToString(); @@ -280,14 +310,16 @@ namespace ProxySU //MessageBox.Show(proxyTypes.ToString()); if (RadioButtonNoProxy.IsChecked == false && (string.IsNullOrEmpty(TextBoxProxyHost.Text) == true || string.IsNullOrEmpty(TextBoxProxyPort.Text) == true)) { - MessageBox.Show("如果选择了代理,则代理地址与端口不能为空"); + //****** "如果选择了代理,则代理地址与端口不能为空!" ****** + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorProxyAddressPortNotEmpty").ToString()); return connectionInfo = null; } string sshProxyHost = TextBoxProxyHost.Text.ToString(); int sshProxyPort = int.Parse(TextBoxProxyPort.Text.ToString()); if (RadioButtonNoProxy.IsChecked==false && RadiobuttonProxyYesLogin.IsChecked == true && (string.IsNullOrEmpty(TextBoxProxyUserName.Text) == true || string.IsNullOrEmpty(PasswordBoxProxyPassword.Password) == true)) { - MessageBox.Show("如果代理需要登录,则代理登录的用户名与密码不能为空"); + //****** "如果代理需要登录,则代理登录的用户名与密码不能为空!" ****** + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorProxyUserPasswordNotEmpty").ToString()); return connectionInfo = null; } string sshProxyUser = TextBoxProxyUserName.Text.ToString(); @@ -352,7 +384,7 @@ namespace ProxySU ConnectionInfo connectionInfo = GenerateConnectionInfo(); if(connectionInfo==null) { - MessageBox.Show("远程主机连接信息有误,请检查"); + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorHostConnection").ToString()); //远程主机连接信息有误,请检查 return; } @@ -370,7 +402,8 @@ namespace ProxySU //选择模板 if (String.IsNullOrEmpty(ReceiveConfigurationParameters[0]) == true) { - MessageBox.Show("请先选择配置模板!"); + //"请先选择配置模板!" + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ChooseTemplate").ToString()); return; } else if (String.Equals(ReceiveConfigurationParameters[0], "TCP")) @@ -473,7 +506,9 @@ namespace ProxySU //登录远程主机布署V2ray程序 private void StartSetUpV2ray(ConnectionInfo connectionInfo,TextBlock textBlockName, ProgressBar progressBar, string serverConfig,string clientConfig,string upLoadPath) { - string currentStatus = "正在登录远程主机......"; + + //"正在登录远程主机......" + string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -513,14 +548,18 @@ namespace ProxySU client.Connect(); if (client.IsConnected == true) { - currentStatus = "主机登录成功"; + //"主机登录成功" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 Thread.Sleep(1000); } - //检测是否运行在root权限下 - currentShellCommandResult = "检测是否运行在root权限下..."; + + //"检测是否运行在root权限下..." + currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"id -u"; @@ -531,32 +570,29 @@ namespace ProxySU string testRootAuthority = currentShellCommandResult; if (testRootAuthority.Equals("0\n") == false) { - MessageBox.Show("请使用具有root权限的账户登录主机!!"); + //"请使用具有root权限的账户登录主机!!" + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); client.Disconnect(); return; } else { - currentShellCommandResult = "检测结果:OK!"; + //"检测结果:OK!" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRoot_OK").ToString(); + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - //string testRootAuthority = client.RunCommand(@"id -u").Result; - //if (testRootAuthority.Equals("0\n")==false) - //{ - // MessageBox.Show("请使用具有root权限的账户登录主机!!"); - // client.Disconnect(); - // return; - //} - //检测是否安装有V2ray - currentStatus = "检测系统是否已经安装V2ray......"; + + //"检测系统是否已经安装V2ray......" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistV2Ray").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //string cmdTestV2rayInstalled = @"find / -name v2ray"; sshShellCommand = @"find / -name v2ray"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -565,10 +601,12 @@ namespace ProxySU string resultCmdTestV2rayInstalled = currentShellCommandResult; if (resultCmdTestV2rayInstalled.Contains("/usr/bin/v2ray") == true || resultCmdTestV2rayInstalled.Contains("/usr/local/bin/v2ray") == true) { - MessageBoxResult messageBoxResult = MessageBox.Show("远程主机已安装V2ray,是否强制重新安装?", "", MessageBoxButton.YesNo, MessageBoxImage.Question); + //"远程主机已安装V2ray,是否强制重新安装?" + MessageBoxResult messageBoxResult = MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ExistedV2Ray").ToString(), "", MessageBoxButton.YesNo, MessageBoxImage.Question); if (messageBoxResult==MessageBoxResult.No) { - currentStatus = "安装取消,退出"; + //"安装取消,退出" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstallationCanceledExit").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -579,7 +617,8 @@ namespace ProxySU } else { - currentStatus = "已选择强制安装V2Ray!"; + //"已选择强制安装V2Ray!" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_ForceInstallV2Ray").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -588,34 +627,40 @@ namespace ProxySU } else { - currentStatus = "检测结果:未安装V2Ray!"; + //"检测结果:未安装V2Ray!" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledV2Ray").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - //检测远程主机系统环境是否符合要求 - currentStatus = "检测系统是否符合安装要求......"; + //"检测系统是否符合安装要求......" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_CheckSystemRequirements").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //string result = client.RunCommand("uname -r").Result; sshShellCommand = @"uname -r"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + string result = currentShellCommandResult; string[] linuxKernelVerStr= result.Split('-'); - bool detectResult = DetectKernelVersion(linuxKernelVerStr[0]); if (detectResult == false) { - MessageBox.Show($"当前系统内核版本为{linuxKernelVerStr[0]},V2ray要求内核为2.6.23及以上。请升级内核再安装!"); - currentStatus = "系统内核版本不符合要求,安装失败!!"; + //$"当前系统内核版本为{linuxKernelVerStr[0]},V2ray要求内核为2.6.23及以上。请升级内核再安装!" + MessageBox.Show( + Application.Current.FindResource("MessageBoxShow_CurrentKernelVersion").ToString() + + $"{linuxKernelVerStr[0]}" + + Application.Current.FindResource("MessageBoxShow_RequiredKernelVersionExplain").ToString() + ); + //"系统内核版本不符合要求,安装失败!!" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_KernelVersionNotMatch").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -625,12 +670,6 @@ namespace ProxySU //检测系统是否支持yum 或 apt-get或zypper,且支持Systemd //如果不存在组件,则命令结果为空,string.IsNullOrEmpty值为真, - //bool getApt = String.IsNullOrEmpty(client.RunCommand("command -v apt").Result); - //bool getDnf = String.IsNullOrEmpty(client.RunCommand("command -v dnf").Result); - //bool getYum = String.IsNullOrEmpty(client.RunCommand("command -v yum").Result); - //bool getZypper = String.IsNullOrEmpty(client.RunCommand("command -v zypper").Result); - //bool getSystemd = String.IsNullOrEmpty(client.RunCommand("command -v systemctl").Result); - //bool getGetenforce = String.IsNullOrEmpty(client.RunCommand("command -v getenforce").Result); sshShellCommand = @"command -v apt"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 @@ -673,19 +712,23 @@ namespace ProxySU //也就是apt ,dnf\yum, zypper必须安装其中之一,且必须安装Systemd的系统才能安装。 if ((getApt && getDnf && getYum && getZypper) || getSystemd) { - MessageBox.Show($"系统缺乏必要的安装组件如:apt||dnf||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本"); - currentStatus = "系统环境不满足要求,安装失败!!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + //"系统缺乏必要的安装组件如:apt||dnf||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本" + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_MissingSystemComponents").ToString()); + //"系统环境不满足要求,安装失败!!" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_MissingSystemComponents").ToString(); + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); client.Disconnect(); return; } else { - currentStatus = "检测结果:OK!"; + //"检测结果:OK!" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_SystemRequirementsOK").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -695,29 +738,21 @@ namespace ProxySU //设置安装软件所用的命令格式 if (getApt == false) { - //client.RunCommand("apt -qq update"); - //client.RunCommand("apt -y -qq install curl"); sshCmdUpdate = @"apt -qq update"; sshCmdInstall = @"apt -y -qq install "; } else if (getDnf == false) { - //client.RunCommand("dnf -q makecache"); - //client.RunCommand("dnf -y -q install curl"); sshCmdUpdate = @"dnf -q makecache"; sshCmdInstall = @"dnf -y -q install "; } else if (getYum == false) { - //client.RunCommand("yum -q makecache"); - //client.RunCommand("yum -y -q install curl"); sshCmdUpdate = @"yum -q makecache"; sshCmdInstall = @"yum -y -q install "; } else if (getZypper == false) { - //client.RunCommand("zypper ref"); - //client.RunCommand("zypper -y install curl"); sshCmdUpdate = @"zypper ref"; sshCmdInstall = @"zypper -y install "; } @@ -725,7 +760,6 @@ namespace ProxySU //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 if (getGetenforce == false) { - //string testSELinux = client.RunCommand("getenforce").Result; sshShellCommand = @"getenforce"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -735,24 +769,23 @@ namespace ProxySU if (testSELinux.Contains("Enforcing") == true) { - currentStatus = "检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中..."; + //"检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中......" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableSELinux").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //MessageBox.Show("Enforcing"); - //client.RunCommand("setenforce 0");//不重启改为Permissive模式 - //client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 sshShellCommand = @"setenforce 0"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = @"sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - currentStatus = "修改完毕!"; + //"修改完毕!" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_SELinuxModifyOK").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -773,67 +806,10 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //为假则表示系统有相应的组件。 - //if (getApt == false) - //{ - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install curl"); - //} - //else if (getDnf == false) - //{ - // client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install curl"); - //} - //else if (getYum == false) - //{ - // client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install curl"); - //} - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install curl"); - //} } - ////在相应系统内安装curl(如果没有安装curl) - //if (string.IsNullOrEmpty(client.RunCommand("command -v curl").Result) == true) - //{ - // //为假则表示系统有相应的组件。 - // if (getApt == false) - // { - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install curl"); - // } - // else if (getDnf == false) - // { - // client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install curl"); - // } - // else if (getYum == false) - // { - // client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install curl"); - // } - // //else if (getZypper == false) - // //{ - // // client.RunCommand("zypper ref"); - // // client.RunCommand("zypper -y install curl"); - // //} - //} - ////判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 - //if (getGetenforce == false) - //{ - // string testSELinux = client.RunCommand("getenforce").Result; - // if (testSELinux.Contains("Enforcing")==true) - // { - // client.RunCommand("setenforce 0");//不重启改为Permissive模式 - // client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 - // } - //} - - //校对时间 - currentStatus = "校对时间......"; + //"校对时间......" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_ProofreadingTime").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -847,9 +823,10 @@ namespace ProxySU long timeStampLocal = Convert.ToInt64(ts.TotalSeconds); if (Math.Abs(timeStampLocal - timeStampVPS) >= 90) { - - MessageBox.Show("本地时间与远程主机时间相差超过限制(90秒),请先用\"系统工具-->时间校对\"校对时间后再设置"); - currentStatus = "时间较对失败......"; + //"本地时间与远程主机时间相差超过限制(90秒),请先用 '系统工具-->时间校对' 校对时间后再设置" + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_TimeError").ToString()); + //"时间较对失败......" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_TimeError").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -858,7 +835,8 @@ namespace ProxySU client.Disconnect(); return; } - currentStatus = "时间差符合要求,OK!"; + //"时间差符合要求,OK!" + currentStatus = Application.Current.FindResource("DisplayInstallInfo_TimeOK").ToString(); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -874,22 +852,16 @@ namespace ProxySU Thread.Sleep(1000); - //string nativeIp = client.RunCommand("curl -4 ip.sb").Result.ToString(); - //string testDomainCmd = "ping " + ReceiveConfigurationParameters[4] + " -c 1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; - //string resultCmd = client.RunCommand(testDomainCmd).Result.ToString(); - sshShellCommand = @"curl -4 ip.sb"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - string nativeIp = currentShellCommandResult; sshShellCommand = "ping " + ReceiveConfigurationParameters[4] + " -c 1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - string resultTestDomainCmd = currentShellCommandResult; if (String.Equals(nativeIp, resultTestDomainCmd) == true) @@ -927,27 +899,6 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //为假则表示系统有相应的组件。 - //if (getApt == false) - // { - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install lsof"); - // } - // else if (getDnf == false) - // { - // client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install lsof"); - // } - // else if (getYum == false) - // { - // client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install lsof"); - // } - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install lsof"); - //} } currentStatus = "正在检测端口占用情况......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -991,15 +942,9 @@ namespace ProxySU Thread.Sleep(1000); - //string cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; - //string cmdResult = client.RunCommand(cmdTestPort).Result; - if (String.IsNullOrEmpty(testPort443) == false) { string[] cmdResultArry443 = testPort443.Split(' '); - //client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); - //client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); - //client.RunCommand($"kill -9 {cmdResultArry443[3]}"); sshShellCommand = $"systemctl stop {cmdResultArry443[0]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1017,14 +962,9 @@ namespace ProxySU } - //cmdTestPort = @"lsof -n -P -i :80 | grep LISTEN"; - //cmdResult = client.RunCommand(cmdTestPort).Result; if (String.IsNullOrEmpty(testPort80) == false) { string[] cmdResultArry80 = testPort80.Split(' '); - //client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); - //client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); - //client.RunCommand($"kill -9 {cmdResultArry80[3]}"); sshShellCommand = $"systemctl stop {cmdResultArry80[0]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1057,48 +997,6 @@ namespace ProxySU } - //if (String.IsNullOrEmpty(client.RunCommand(@"lsof -n -P -i :80 | grep LISTEN").Result) == false || String.IsNullOrEmpty(client.RunCommand(@"lsof -n -P -i :443 | grep LISTEN").Result) == false) - //{ - // //MessageBox.Show("80/443端口之一,或全部被占用,请先用系统工具中的“释放80/443端口”工具,释放出,再重新安装"); - // MessageBoxResult dialogResult = MessageBox.Show("80/443端口之一,或全部被占用,将强制停止占用80/443端口的程序?", "Stop application", MessageBoxButton.YesNo); - // if (dialogResult == MessageBoxResult.No) - // { - // currentStatus = "端口被占用,安装失败......"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // Thread.Sleep(1000); - // client.Disconnect(); - // return; - // } - - // currentStatus = "正在释放80/443端口......"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // Thread.Sleep(1000); - - // string cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; - // string cmdResult = client.RunCommand(cmdTestPort).Result; - // if (String.IsNullOrEmpty(cmdResult) == false) - // { - // string[] cmdResultArry443 = cmdResult.Split(' '); - // client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); - // client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); - // client.RunCommand($"kill -9 {cmdResultArry443[3]}"); - // } - - // cmdTestPort = @"lsof -n -P -i :80 | grep LISTEN"; - // cmdResult = client.RunCommand(cmdTestPort).Result; - // if (String.IsNullOrEmpty(cmdResult) == false) - // { - // string[] cmdResultArry80 = cmdResult.Split(' '); - // client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); - // client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); - // client.RunCommand($"kill -9 {cmdResultArry80[3]}"); - // } - // currentStatus = "80/443端口释放完毕!"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // Thread.Sleep(1000); - - //} - } currentStatus = "系统环境检测完毕,符合安装要求,开始布署......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -1118,10 +1016,6 @@ namespace ProxySU { if (String.Equals(openFireWallPort, "443")) { - //client.RunCommand("firewall-cmd --zone=public --add-port=80/tcp --permanent"); - //client.RunCommand("firewall-cmd --zone=public --add-port=443/tcp --permanent"); - //client.RunCommand("firewall-cmd --reload"); - sshShellCommand = @"firewall-cmd --zone=public --add-port=80/tcp --permanent"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1139,10 +1033,6 @@ namespace ProxySU } else { - //client.RunCommand($"firewall-cmd --zone=public --add-port={openFireWallPort}/tcp --permanent"); - //client.RunCommand($"firewall-cmd --zone=public --add-port={openFireWallPort}/udp --permanent"); - //client.RunCommand("firewall-cmd --reload"); - sshShellCommand = $"firewall-cmd --zone=public --add-port={openFireWallPort}/tcp --permanent"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1164,10 +1054,6 @@ namespace ProxySU { if (String.Equals(openFireWallPort, "443")) { - //client.RunCommand("ufw allow 80"); - //client.RunCommand("ufw allow 443"); - //client.RunCommand("yes | ufw reload"); - sshShellCommand = @"ufw allow 80"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1186,9 +1072,6 @@ namespace ProxySU } else { - //client.RunCommand($"ufw allow {openFireWallPort}/tcp"); - //client.RunCommand($"ufw allow {openFireWallPort}/udp"); - //client.RunCommand("yes | ufw reload"); sshShellCommand = $"ufw allow {openFireWallPort}/tcp"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1215,9 +1098,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand("curl -o /tmp/go.sh https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh"); - //client.RunCommand("yes | bash /tmp/go.sh -f"); - //string installResult = client.RunCommand("find / -name v2ray").Result.ToString(); sshShellCommand = @"curl -o /tmp/go.sh https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1255,7 +1135,7 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //client.RunCommand("systemctl enable v2ray; systemctl start v2ray"); + sshShellCommand = @"systemctl enable v2ray"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1263,7 +1143,6 @@ namespace ProxySU } - //client.RunCommand("mv /usr/local/etc/v2ray/config.json /usr/local/etc/v2ray/config.json.1"); sshShellCommand = @"mv /usr/local/etc/v2ray/config.json /usr/local/etc/v2ray/config.json.1"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1359,34 +1238,31 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //if (getApt == false) - //{ - // //client.RunCommand("apt-get -qq update"); - // client.RunCommand("apt -y -qq install socat"); - //} - //else if (getDnf == false) - //{ - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("dnf -y -q install socat"); - //} - //else if (getYum == false) - //{ - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install socat"); - //} - //if (getZypper == false) - //{ - // // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install socat"); - //} - //client.RunCommand("curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"); - //client.RunCommand("cd ~/.acme.sh/"); - //client.RunCommand("alias acme.sh=~/.acme.sh/acme.sh"); + sshShellCommand = @"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("Install success") == true) + { + currentStatus = "acme.sh安装成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "acme.sh安装失败!原因未知,请向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + return; + } + sshShellCommand = @"cd ~/.acme.sh/"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1405,20 +1281,29 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand("mkdir -p /etc/v2ray/ssl"); - //client.RunCommand($"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"); sshShellCommand = $"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("Cert success") == true) + { + currentStatus = "证书申请成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //currentStatus = "申请域名证书......"; - //textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - //Thread.Sleep(1000); + Thread.Sleep(1000); + } + else + { + currentStatus = "证书申请失败!原因未知,请向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //client.RunCommand("mkdir -p /usr/local/etc/v2ray/ssl"); - //client.RunCommand($"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"); + return; + } currentStatus = "安装证书到V2ray......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -1432,12 +1317,33 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - // client.RunCommand($"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/v2ray/ssl/v2ray_ssl.crt --keypath /usr/local/etc/v2ray/ssl/v2ray_ssl.key --capath /usr/local/etc/v2ray/ssl/v2ray_ssl.crt --reloadcmd \"systemctl restart v2ray\""); sshShellCommand = $"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/v2ray/ssl/v2ray_ssl.crt --keypath /usr/local/etc/v2ray/ssl/v2ray_ssl.key --capath /usr/local/etc/v2ray/ssl/v2ray_ssl.crt --reloadcmd \"systemctl restart v2ray\""; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = @"if [ ! -f ""/usr/local/etc/v2ray/ssl/v2ray_ssl.key"" ]; then echo ""0""; else echo ""1""; fi | head -n 1"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + if (currentShellCommandResult.Contains("1") == true) + { + currentStatus = "证书安装到V2ray,成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } + else + { + currentStatus = "证书安装到V2ray失败,原因未知,可以向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + return; + } + //设置私钥权限 sshShellCommand = @"chmod 644 /usr/local/etc/v2ray/ssl/v2ray_ssl.key"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 @@ -1460,10 +1366,7 @@ namespace ProxySU //为假则表示系统有相应的组件。 if (getApt == false) { - //client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); - //client.RunCommand("apt install -y apt-transport-https"); - //client.RunCommand("apt -qq update"); - //client.RunCommand("apt -y -qq install caddy"); + sshShellCommand = @"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1487,10 +1390,7 @@ namespace ProxySU } else if (getDnf == false) { - //client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); - //client.RunCommand(@"dnf copr enable @caddy/caddy -y"); - ////client.RunCommand("dnf -q makecache"); - //client.RunCommand("dnf -y -q install caddy"); + sshShellCommand = @"dnf install 'dnf-command(copr)' -y"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1506,6 +1406,7 @@ namespace ProxySU //currentShellCommandResult = client.RunCommand(sshShellCommand).Result; //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = @"dnf -y -q install caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1514,10 +1415,7 @@ namespace ProxySU } else if (getYum == false) { - //client.RunCommand(@"yum install yum-plugin-copr -y"); - //client.RunCommand(@"yum copr enable @caddy/caddy -y"); - ////client.RunCommand("yum -q makecache"); - //client.RunCommand("yum -y -q install caddy"); + sshShellCommand = @"yum install yum-plugin-copr -y"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1539,32 +1437,6 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - //if (getApt == false) - //{ - // client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); - // client.RunCommand("apt install -y apt-transport-https"); - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install caddy"); - //} - //else if (getDnf == false) - //{ - // client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); - // client.RunCommand(@"dnf copr enable @caddy/caddy -y"); - // //client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install caddy"); - //} - //else if (getYum == false) - //{ - // client.RunCommand(@"yum install yum-plugin-copr -y"); - // client.RunCommand(@"yum copr enable @caddy/caddy -y"); - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install caddy"); - //} - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install curl"); - //} sshShellCommand = @"find / -name caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 @@ -1592,55 +1464,12 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //client.RunCommand("systemctl enable caddy"); + sshShellCommand = @"systemctl enable caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //if (getApt == false) - //{ - // client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); - // client.RunCommand("apt install -y apt-transport-https"); - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install caddy"); - //} - //else if (getDnf == false) - //{ - // client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); - // client.RunCommand(@"dnf copr enable @caddy/caddy -y"); - // //client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install caddy"); - //} - //else if (getYum == false) - //{ - // client.RunCommand(@"yum install yum-plugin-copr -y"); - // client.RunCommand(@"yum copr enable @caddy/caddy -y"); - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install caddy"); - //} - ////else if (getZypper == false) - ////{ - //// client.RunCommand("zypper ref"); - //// client.RunCommand("zypper -y install curl"); - ////} - //installResult = client.RunCommand("find / -name caddy").Result.ToString(); - - //if (!installResult.Contains("/usr/bin/caddy")) - //{ - // MessageBox.Show("安装Caddy失败!"); - - // currentStatus = "安装Caddy失败!"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // client.Disconnect(); - // return; - //} - //else { - // currentStatus = "Caddy安装成功!"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // Thread.Sleep(1000); - // client.RunCommand("systemctl enable caddy"); - //} //在Caddy 2还未推出2.2.0的正式版之前,先用测试版替代 if (String.Equals(ReceiveConfigurationParameters[0], "http2Web")) { @@ -1651,12 +1480,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand(@"curl -o /tmp/caddy.zip https://raw.githubusercontent.com/proxysu/Resources/master/Caddy2/caddy.zip"); - //client.RunCommand(@"unzip /tmp/caddy.zip"); - //client.RunCommand(@"chmod +x caddy"); - //client.RunCommand(@"systemctl stop caddy;rm -f /usr/bin/caddy"); - //client.RunCommand(@"cp /root/caddy /usr/bin/"); - sshShellCommand = @"curl -o /tmp/caddy.zip https://raw.githubusercontent.com/proxysu/Resources/master/Caddy2/caddy.zip"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1713,23 +1536,15 @@ namespace ProxySU UploadConfig(connectionInfo, serverConfig, upLoadPath); //设置Caddyfile文件中的tls 邮箱,在caddy2中已经不需要设置。 - //string sshCmdEmail = $"email={ReceiveConfigurationParameters[4]};email=${{email/./@}};echo $email";//结尾有回车符 - //string email = client.RunCommand(sshCmdEmail).Result.Replace("\n", "");//删除结尾的回车符 - //string email = $"user@{ReceiveConfigurationParameters[4]}"; - //string sshCmd = $"sed -i 's/off/{email}/' {upLoadPath}";//设置Caddyfile中的邮箱 - //client.RunCommand(sshCmd); //设置域名 - //string sshCmd = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; - //client.RunCommand(sshCmd); + sshShellCommand = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 //设置Path - //sshCmd = $"sed -i 's/##path##/\\{ReceiveConfigurationParameters[3]}/' {upLoadPath}"; - //client.RunCommand(sshCmd); sshShellCommand = $"sed -i 's/##path##/\\{ReceiveConfigurationParameters[3]}/' {upLoadPath}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1738,9 +1553,7 @@ namespace ProxySU //设置伪装网站 if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7])==false) { - //sshCmd = $"sed -i 's/##sites##/reverse_proxy {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; - //client.RunCommand(sshCmd); - sshShellCommand = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; + sshShellCommand = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -1754,28 +1567,81 @@ namespace ProxySU Thread.Sleep(1000); //启动Caddy服务 - //client.RunCommand("systemctl restart caddy"); + currentStatus = "正在启动Caddy......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - // Thread.Sleep(1000); //启动Caddy服务 sshShellCommand = @"systemctl restart caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - currentStatus = "Caddy启动成功!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(1000); - } + if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) + { + //运行成功 + currentStatus = "Caddy启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + Thread.Sleep(1000); + } + else + { + //运行失败 + currentStatus = "Caddy启动失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + currentStatus = "正在启动Caddy(第二次尝试)!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + sshShellCommand = @"systemctl restart caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) + { + currentStatus = "Caddy启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "Caddy启动失败(第二次)!退出安装!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + MessageBox.Show("Caddy启动失败,原因未知!请向开发者问询!"); + return; + } + } + + } currentStatus = "正在启动V2ray......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -1784,20 +1650,74 @@ namespace ProxySU Thread.Sleep(1000); //启动V2ray服务 - //client.RunCommand("systemctl restart v2ray"); sshShellCommand = @"systemctl restart v2ray"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); - currentStatus = "V2ray启动成功!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; + sshShellCommand = @"ps aux | grep v2ray"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(1000); + if (currentShellCommandResult.Contains("/usr/local/bin/v2ray") == true) + { + //运行成功 + currentStatus = "V2ray启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + } + else + { + //运行失败 + currentStatus = "V2ray启动失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + currentStatus = "正在启动V2ray(第二次尝试)!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + sshShellCommand = @"systemctl restart v2ray"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep v2ray"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("/usr/local/bin/v2ray") == true) + { + currentStatus = "V2ray启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "V2ray启动失败(第二次)!退出安装!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + MessageBox.Show("V2Ray启动失败,原因未知!请向开发者问询!"); + return; + } + } + + //测试BBR条件,若满足提示是否启用 currentStatus = "BBR测试......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -1806,7 +1726,6 @@ namespace ProxySU Thread.Sleep(1000); - //var result = client.RunCommand("uname -r"); sshShellCommand = @"uname -r"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1815,7 +1734,7 @@ namespace ProxySU string[] linuxKernelVerStrBBR = currentShellCommandResult.Split('-'); bool detectResultBBR = DetectKernelVersionBBR(linuxKernelVerStrBBR[0]); - //client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; + sshShellCommand = @"sysctl net.ipv4.tcp_congestion_control | grep bbr"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1831,9 +1750,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - //client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - //client.RunCommand(@"sysctl -p"); sshShellCommand = @"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -1867,20 +1783,7 @@ namespace ProxySU } client.Disconnect();//断开服务器ssh连接 - //result = client.RunCommand("uname -r").Result; - ////var result = client.RunCommand("cat /root/test.ver"); - //linuxKernelVerStr = result.Split('-'); - - //detectResult = DetectKernelVersionBBR(linuxKernelVerStr[0]); - //string resultCmdTestBBR = client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; - ////如果内核满足大于等于4.9,且还未启用BBR,则启用BBR - //if (detectResult == true && resultCmdTestBBR.Contains("bbr") == false) - //{ - // client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - // client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - // client.RunCommand(@"sysctl -p"); - //} - + //生成客户端配置 currentStatus = "生成客户端配置......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -1892,7 +1795,7 @@ namespace ProxySU { Directory.CreateDirectory("v2ray_config");//创建该文件夹 } - //string clientConfig = "TemplateConfg\\tcp_client_config.json"; + using (StreamReader reader = File.OpenText(clientConfig)) { JObject clientJson = (JObject)JToken.ReadFrom(new JsonTextReader(reader)); @@ -1936,8 +1839,6 @@ namespace ProxySU } } - //client.Disconnect(); - currentStatus = "V2Ray安装成功,祝你玩的愉快!!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -1989,7 +1890,6 @@ namespace ProxySU } #endregion - } //检测升级远程主机端的V2Ray版本 @@ -2466,7 +2366,9 @@ namespace ProxySU } //检测是否运行在root权限下 - currentShellCommandResult = "检测是否运行在root权限下..."; + currentStatus = "检测是否运行在root权限下..."; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"id -u"; @@ -2483,7 +2385,9 @@ namespace ProxySU } else { - currentShellCommandResult = "检测结果:OK!"; + currentStatus = "检测结果:OK!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } @@ -2617,29 +2521,21 @@ namespace ProxySU if (getApt == false) { - //client.RunCommand("apt -qq update"); - //client.RunCommand("apt -y -qq install curl"); sshCmdUpdate = @"apt -qq update"; sshCmdInstall = @"apt -y -qq install "; } else if (getDnf == false) { - //client.RunCommand("dnf -q makecache"); - //client.RunCommand("dnf -y -q install curl"); sshCmdUpdate = @"dnf -q makecache"; sshCmdInstall = @"dnf -y -q install "; } else if (getYum == false) { - //client.RunCommand("yum -q makecache"); - //client.RunCommand("yum -y -q install curl"); sshCmdUpdate = @"yum -q makecache"; sshCmdInstall = @"yum -y -q install "; } else if (getZypper == false) { - //client.RunCommand("zypper ref"); - //client.RunCommand("zypper -y install curl"); sshCmdUpdate = @"zypper ref"; sshCmdInstall = @"zypper -y install "; } @@ -2647,14 +2543,13 @@ namespace ProxySU //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 if (getGetenforce == false) { - // string testSELinux = client.RunCommand("getenforce").Result; sshShellCommand = @"getenforce"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 string testSELinux = currentShellCommandResult; - //MessageBox.Show(testSELinux); + if (testSELinux.Contains("Enforcing") == true) { currentStatus = "检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中..."; @@ -2662,10 +2557,7 @@ namespace ProxySU currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //MessageBox.Show("Enforcing"); - // client.RunCommand("setenforce 0");//不重启改为Permissive模式 - // client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 - sshShellCommand = @"setenforce 0"; + sshShellCommand = @"setenforce 0"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -2705,27 +2597,6 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - ////为假则表示系统有相应的组件。 - //if (getApt == false) - //{ - // client.RunCommand("apt-get -qq update"); - // client.RunCommand("apt-get -y -qq install curl"); - //} - //else if (getDnf == false) - //{ - // client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install curl"); - //} - //else if (getYum == false) - //{ - // client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install curl"); - //} - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install curl"); - //} } sshShellCommand = @"curl -4 ip.sb"; @@ -2740,7 +2611,6 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //string testDomainCmd = "ping " + ReceiveConfigurationParameters[4] + " -c 1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; string resultTestDomainCmd = currentShellCommandResult; if (String.Equals(nativeIp, resultTestDomainCmd) == true) @@ -2778,27 +2648,7 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //为假则表示系统有相应的组件。 - //if (getApt == false) - //{ - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install lsof"); - //} - //else if (getDnf == false) - //{ - // client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install lsof"); - //} - //else if (getYum == false) - //{ - // client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install lsof"); - //} - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install lsof"); - //} + } currentStatus = "正在检测端口占用情况......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -2806,8 +2656,7 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //MessageBox.Show(@"lsof -n -P -i :80 | grep LISTEN"); - //MessageBox.Show(client.RunCommand(@"lsof -n -P -i :80 | grep LISTEN").Result); + sshShellCommand = @"lsof -n -P -i :80 | grep LISTEN"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -2842,15 +2691,10 @@ namespace ProxySU Thread.Sleep(1000); - //string cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; - //string cmdResult = client.RunCommand(cmdTestPort).Result; - if (String.IsNullOrEmpty(testPort443) == false) { string[] cmdResultArry443 = testPort443.Split(' '); - //client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); - //client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); - //client.RunCommand($"kill -9 {cmdResultArry443[3]}"); + sshShellCommand = $"systemctl stop {cmdResultArry443[0]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -2868,14 +2712,11 @@ namespace ProxySU } - //cmdTestPort = @"lsof -n -P -i :80 | grep LISTEN"; - //cmdResult = client.RunCommand(cmdTestPort).Result; + if (String.IsNullOrEmpty(testPort80) == false) { string[] cmdResultArry80 = testPort80.Split(' '); - //client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); - //client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); - //client.RunCommand($"kill -9 {cmdResultArry80[3]}"); + sshShellCommand = $"systemctl stop {cmdResultArry80[0]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -2924,9 +2765,6 @@ namespace ProxySU if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) { - //client.RunCommand("firewall-cmd --zone=public --add-port=80/tcp --permanent"); - //client.RunCommand("firewall-cmd --zone=public --add-port=443/tcp --permanent"); - //client.RunCommand("firewall-cmd --reload"); sshShellCommand = @"firewall-cmd --zone=public --add-port=80/tcp --permanent"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -2945,9 +2783,6 @@ namespace ProxySU } if (String.IsNullOrEmpty(client.RunCommand("command -v ufw").Result) == false) { - //client.RunCommand("ufw allow 80"); - //client.RunCommand("ufw allow 443"); - //client.RunCommand("yes | ufw reload"); sshShellCommand = @"ufw allow 80"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 @@ -2974,9 +2809,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand("curl -o /tmp/trojan-go.sh https://raw.githubusercontent.com/proxysu/shellscript/master/trojan-go.sh"); - //client.RunCommand("yes | bash /tmp/trojan-go.sh -f"); - sshShellCommand = @"curl -o /tmp/trojan-go.sh https://raw.githubusercontent.com/proxysu/shellscript/master/trojan-go.sh"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3014,14 +2846,14 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //client.RunCommand("systemctl enable trojan-go"); + sshShellCommand = @"systemctl enable trojan-go"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - //client.RunCommand("mv /etc/trojan-go/config.json /etc/trojan-go/config.json.1"); + sshShellCommand = @"mv /etc/trojan-go/config.json /etc/trojan-go/config.json.1"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3068,6 +2900,7 @@ namespace ProxySU File.Delete(@"config.json"); + //安装acme.sh currentStatus = "正在安装acme.sh......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -3086,35 +2919,30 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //if (getApt == false) - //{ - // //client.RunCommand("apt-get -qq update"); - // client.RunCommand("apt-get -y -qq install socat"); - //} - //else if (getDnf == false) - //{ - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("dnf -y -q install socat"); - //} - //else if (getYum == false) - //{ - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install socat"); - //} - //else if (getZypper == false) - //{ - // // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install socat"); - //} - //client.RunCommand("curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"); - //client.RunCommand("cd ~/.acme.sh/"); - //client.RunCommand("alias acme.sh=~/.acme.sh/acme.sh"); - sshShellCommand = @"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("Install success") == true) + { + currentStatus = "acme.sh安装成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "acme.sh安装失败!原因未知,请向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + return; + } + sshShellCommand = @"cd ~/.acme.sh/"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3133,25 +2961,64 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand("mkdir -p /etc/v2ray/ssl"); - //client.RunCommand($"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"); - sshShellCommand = $"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"; + sshShellCommand = $"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("Cert success") == true) + { + currentStatus = "证书申请成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "证书申请失败!原因未知,请向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + return; + } + + currentStatus = "安装证书到Trojan-Go......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //client.RunCommand($"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/trojan-go/trojan-go.crt --keypath /usr/local/etc/trojan-go/trojan-go.key --capath /usr/local/etc/trojan-go/trojan-go.crt --reloadcmd \"systemctl restart trojan-go\""); - sshShellCommand = $"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/trojan-go/trojan-go.crt --keypath /usr/local/etc/trojan-go/trojan-go.key --capath /usr/local/etc/trojan-go/trojan-go.crt --reloadcmd \"systemctl restart trojan-go\""; + sshShellCommand = $"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/trojan-go/trojan-go.crt --keypath /usr/local/etc/trojan-go/trojan-go.key --capath /usr/local/etc/trojan-go/trojan-go.crt --reloadcmd \"systemctl restart trojan-go\""; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = @"if [ ! -f ""/usr/local/etc/trojan-go/trojan-go.key"" ]; then echo ""0""; else echo ""1""; fi | head -n 1"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + if (currentShellCommandResult.Contains("1") == true) + { + currentStatus = "证书安装到Trojan-go,成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } + else + { + currentStatus = "证书安装到Trojan-go失败,原因未知,可以向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + return; + } + //设置证书权限 sshShellCommand = @"chmod 644 /usr/local/etc/trojan-go/trojan-go.key"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 @@ -3170,10 +3037,6 @@ namespace ProxySU //为假则表示系统有相应的组件。 if (getApt == false) { - //client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); - //client.RunCommand("apt install -y apt-transport-https"); - //client.RunCommand("apt -qq update"); - //client.RunCommand("apt -y -qq install caddy"); sshShellCommand = @"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3197,10 +3060,6 @@ namespace ProxySU } else if (getDnf == false) { - //client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); - //client.RunCommand(@"dnf copr enable @caddy/caddy -y"); - ////client.RunCommand("dnf -q makecache"); - //client.RunCommand("dnf -y -q install caddy"); sshShellCommand = @"dnf install 'dnf-command(copr)' -y"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3224,10 +3083,6 @@ namespace ProxySU } else if (getYum == false) { - //client.RunCommand(@"yum install yum-plugin-copr -y"); - //client.RunCommand(@"yum copr enable @caddy/caddy -y"); - ////client.RunCommand("yum -q makecache"); - //client.RunCommand("yum -y -q install caddy"); sshShellCommand = @"yum install yum-plugin-copr -y"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3276,7 +3131,7 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - // client.RunCommand("systemctl enable caddy"); + sshShellCommand = @"systemctl enable caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3291,7 +3146,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand("mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak");//备份原文件 sshShellCommand = @"mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3307,7 +3161,6 @@ namespace ProxySU //string email = $"user@{ReceiveConfigurationParameters[4]}"; //设置域名 - //string sshCmd = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; sshShellCommand = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3317,8 +3170,6 @@ namespace ProxySU //设置伪装网站 if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) { - // sshCmd = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; - //client.RunCommand(sshCmd); sshShellCommand = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3331,9 +3182,6 @@ namespace ProxySU Thread.Sleep(1000); - //安装Caddy服务 - //sshCmd = $"caddy -service install -agree -conf /etc/caddy/Caddyfile -email {email}"; - //client.RunCommand(sshCmd); //启动Caddy服务 currentStatus = "正在启动Caddy......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -3342,19 +3190,71 @@ namespace ProxySU Thread.Sleep(1000); //启动Caddy服务 - //client.RunCommand("systemctl restart caddy"); - sshShellCommand = @"systemctl restart caddy"; + sshShellCommand = @"systemctl restart caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) + { + //运行成功 + currentStatus = "Caddy启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - currentStatus = "Caddy启动成功!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + } + else + { + //运行失败 + currentStatus = "Caddy启动失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + currentStatus = "正在启动Caddy(第二次尝试)!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + sshShellCommand = @"systemctl restart caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(1000); + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) + { + currentStatus = "Caddy启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "Caddy启动失败(第二次)!退出安装!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + MessageBox.Show("Caddy启动失败,原因未知!请向开发者问询!"); + return; + } + } currentStatus = "正在启动Trojan-Go......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -3363,19 +3263,74 @@ namespace ProxySU Thread.Sleep(1000); //启动Trojan-go服务 - //client.RunCommand("systemctl restart trojan-go"); + sshShellCommand = @"systemctl restart trojan-go"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); - currentStatus = "Trojan-go启动成功!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; + sshShellCommand = @"ps aux | grep trojan-go"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(1000); + if (currentShellCommandResult.Contains("/usr/local/bin/trojan-go") == true) + { + //运行成功 + currentStatus = "Trojan-go启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + //运行失败 + currentStatus = "Trojan-go启动失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + currentStatus = "正在启动Trojan-go(第二次尝试)!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + sshShellCommand = @"systemctl restart trojan-go"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep trojan-go"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("usr/local/bin/trojan-go") == true) + { + currentStatus = "Trojan-go启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "Trojan-go启动失败(第二次)!退出安装!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + MessageBox.Show("Trojan-go启动失败,原因未知!请向开发者问询!"); + return; + } + } + //测试BBR条件,若满足提示是否启用 currentStatus = "BBR测试......"; @@ -3385,7 +3340,6 @@ namespace ProxySU Thread.Sleep(1000); - //var result = client.RunCommand("uname -r"); sshShellCommand = @"uname -r"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3394,7 +3348,7 @@ namespace ProxySU string[] linuxKernelVerStr = currentShellCommandResult.Split('-'); bool detectResult = DetectKernelVersionBBR(linuxKernelVerStr[0]); - //client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; + sshShellCommand = @"sysctl net.ipv4.tcp_congestion_control | grep bbr"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3410,9 +3364,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - //client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - //client.RunCommand(@"sysctl -p"); sshShellCommand = @"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -3448,21 +3399,7 @@ namespace ProxySU client.Disconnect();//断开服务器ssh连接 - ////测试BBR条件,若满足提示是否启用 - //var result = client.RunCommand("uname -r"); - ////var result = client.RunCommand("cat /root/test.ver"); - //string[] linuxKernelVerStr = result.Result.Split('-'); - - //bool detectResult = DetectKernelVersionBBR(linuxKernelVerStr[0]); - //string resultCmdTestBBR = client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; - ////如果内核满足大于等于4.9,且还未启用BBR,则启用BBR - //if (detectResult == true && resultCmdTestBBR.Contains("bbr") == false) - //{ - // client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - // client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - // client.RunCommand(@"sysctl -p"); - //} - + //生成客户端配置 currentStatus = "生成客户端配置......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -3498,8 +3435,6 @@ namespace ProxySU } } - - currentStatus = "Trojan-go安装成功,祝你玩的愉快!!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -3508,10 +3443,9 @@ namespace ProxySU Thread.Sleep(1000); //显示服务端连接参数 - //MessageBox.Show("用于Trojan官方客户端的配置文件已保存在config文件夹中"); + proxyType = "TrojanGo"; - //TrojanGoResultClientInfoWindow resultClientInformation = new TrojanGoResultClientInfoWindow(); - //resultClientInformation.ShowDialog(); + ResultClientInformation resultClientInformation = new ResultClientInformation(); resultClientInformation.ShowDialog(); return; @@ -3520,7 +3454,7 @@ namespace ProxySU catch (Exception ex1)//例外处理 #region 例外处理 { - //MessageBox.Show(ex1.Message); + if (ex1.Message.Contains("连接尝试失败") == true) { MessageBox.Show($"{ex1.Message}\n请检查主机地址及端口是否正确,如果通过代理,请检查代理是否正常工作"); @@ -3835,18 +3769,6 @@ namespace ProxySU #region Trojan相关 - //打开Trojan参数设置界面 - //private void ButtonTrojanTemplate_Click(object sender, RoutedEventArgs e) - //{ - // for (int i = 0; i != ReceiveConfigurationParameters.Length; i++) - - // { - // ReceiveConfigurationParameters[i] = ""; - // } - // TrojanTemplateWindow windowTrojanTemplateConfiguration = new TrojanTemplateWindow(); - // windowTrojanTemplateConfiguration.ShowDialog(); - //} - //Trojan参数传递 private void ButtonTrojanSetUp_Click(object sender, RoutedEventArgs e) { @@ -3968,7 +3890,9 @@ namespace ProxySU Thread.Sleep(1000); } //检测是否运行在root权限下 - currentShellCommandResult = "检测是否运行在root权限下..."; + currentStatus = "检测是否运行在root权限下..."; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"id -u"; @@ -3985,19 +3909,13 @@ namespace ProxySU } else { - currentShellCommandResult = "检测结果:OK!"; + currentStatus = "检测结果:OK!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - ////检测是否运行在root权限下 - //string testRootAuthority = client.RunCommand(@"id -u").Result; - //if (testRootAuthority.Equals("0\n") == false) - //{ - // MessageBox.Show("请使用具有root权限的账户登录主机!!"); - // client.Disconnect(); - // return; - //} - + //检测是否安装有Trojan currentStatus = "检测系统是否已经安装Trojan......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -4006,7 +3924,6 @@ namespace ProxySU Thread.Sleep(1000); - //string resultCmdTestTrojanInstalled = client.RunCommand(@"find / -name trojan").Result; sshShellCommand = @"find / -name trojan"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4053,7 +3970,6 @@ namespace ProxySU Thread.Sleep(1000); - //string resultCmd = client.RunCommand("uname -m").Result; sshShellCommand = @"uname -m"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4146,29 +4062,21 @@ namespace ProxySU if (getApt == false) { - //client.RunCommand("apt -qq update"); - //client.RunCommand("apt -y -qq install curl"); sshCmdUpdate = @"apt -qq update"; sshCmdInstall = @"apt -y -qq install "; } else if (getDnf == false) { - //client.RunCommand("dnf -q makecache"); - //client.RunCommand("dnf -y -q install curl"); sshCmdUpdate = @"dnf -q makecache"; sshCmdInstall = @"dnf -y -q install "; } else if (getYum == false) { - //client.RunCommand("yum -q makecache"); - //client.RunCommand("yum -y -q install curl"); sshCmdUpdate = @"yum -q makecache"; sshCmdInstall = @"yum -y -q install "; } else if (getZypper == false) { - //client.RunCommand("zypper ref"); - //client.RunCommand("zypper -y install curl"); sshCmdUpdate = @"zypper ref"; sshCmdInstall = @"zypper -y install "; } @@ -4176,7 +4084,6 @@ namespace ProxySU //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 if (getGetenforce == false) { - //string testSELinux = client.RunCommand("getenforce").Result; sshShellCommand = @"getenforce"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4191,9 +4098,6 @@ namespace ProxySU currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //MessageBox.Show("Enforcing"); - //client.RunCommand("setenforce 0");//不重启改为Permissive模式 - //client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 sshShellCommand = @"setenforce 0"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4233,35 +4137,8 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //为假则表示系统有相应的组件。 - //if (getApt == false) - //{ - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install curl"); - //} - //else if (getDnf == false) - //{ - // client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install curl"); - //} - //else if (getYum == false) - //{ - // client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install curl"); - //} - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install curl"); - //} } //检测域名是否解析正确 - //currentStatus = "正在检测域名是否解析到当前VPS的IP上......"; - //textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - //Thread.Sleep(1000); - //string nativeIp = client.RunCommand("curl -4 ip.sb").Result.ToString(); - //string testDomainCmd = "ping " + ReceiveConfigurationParameters[4] + " -c 1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; - //string resultTestDomainCmd = client.RunCommand(testDomainCmd).Result.ToString(); sshShellCommand = @"curl -4 ip.sb"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4274,7 +4151,6 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //string testDomainCmd = "ping " + ReceiveConfigurationParameters[4] + " -c 1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; string resultTestDomainCmd = currentShellCommandResult; if (String.Equals(nativeIp, resultTestDomainCmd) == true) { @@ -4311,27 +4187,6 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //为假则表示系统有相应的组件。 - //if (getApt == false) - //{ - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install lsof"); - //} - //else if (getDnf == false) - //{ - // client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install lsof"); - //} - //else if (getYum == false) - //{ - // client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install lsof"); - //} - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install lsof"); - //} } currentStatus = "正在检测端口占用情况......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -4375,15 +4230,10 @@ namespace ProxySU Thread.Sleep(1000); - //string cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; - //string cmdResult = client.RunCommand(cmdTestPort).Result; - if (String.IsNullOrEmpty(testPort443) == false) { string[] cmdResultArry443 = testPort443.Split(' '); - //client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); - //client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); - //client.RunCommand($"kill -9 {cmdResultArry443[3]}"); + sshShellCommand = $"systemctl stop {cmdResultArry443[0]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4401,14 +4251,10 @@ namespace ProxySU } - //cmdTestPort = @"lsof -n -P -i :80 | grep LISTEN"; - //cmdResult = client.RunCommand(cmdTestPort).Result; if (String.IsNullOrEmpty(testPort80) == false) { string[] cmdResultArry80 = testPort80.Split(' '); - //client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); - //client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); - //client.RunCommand($"kill -9 {cmdResultArry80[3]}"); + sshShellCommand = $"systemctl stop {cmdResultArry80[0]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4440,27 +4286,7 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - //if (String.IsNullOrEmpty() == false) - // { - // string[] cmdResultArry443 = cmdResult.Split(' '); - // client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); - // client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); - // client.RunCommand($"kill -9 {cmdResultArry443[3]}"); - // } - - // cmdTestPort = @"lsof -n -P -i :80 | grep LISTEN"; - // cmdResult = client.RunCommand(cmdTestPort).Result; - // if (String.IsNullOrEmpty(cmdResult) == false) - // { - // string[] cmdResultArry80 = cmdResult.Split(' '); - // client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); - // client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); - // client.RunCommand($"kill -9 {cmdResultArry80[3]}"); - // } - // currentStatus = "80/443端口释放完毕!"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // Thread.Sleep(1000); - //} + currentStatus = "系统环境检测完毕,符合安装要求,开始布署......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -4478,9 +4304,6 @@ namespace ProxySU if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) { - //client.RunCommand("firewall-cmd --zone=public --add-port=80/tcp --permanent"); - //client.RunCommand("firewall-cmd --zone=public --add-port=443/tcp --permanent"); - //client.RunCommand("firewall-cmd --reload"); sshShellCommand = @"firewall-cmd --zone=public --add-port=80/tcp --permanent"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4499,10 +4322,6 @@ namespace ProxySU } if (String.IsNullOrEmpty(client.RunCommand("command -v ufw").Result) == false) { - //client.RunCommand("ufw allow 80"); - //client.RunCommand("ufw allow 443"); - //client.RunCommand("yes | ufw reload"); - sshShellCommand = @"ufw allow 80"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4531,28 +4350,6 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //if (getApt == false) - //{ - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install xz-utils"); - //} - //else if (getDnf == false) - //{ - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("dnf -y -q install xz-utils"); - //} - //else if (getYum == false) - //{ - // client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install xz-utils"); - //} - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install xz-utils"); - //} - - //下载安装脚本安装 currentStatus = "正在安装Trojan......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -4561,8 +4358,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand("curl -o /tmp/trojan-quickstart.sh https://raw.githubusercontent.com/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"); - //client.RunCommand("yes | bash /tmp/trojan-quickstart.sh"); sshShellCommand = @"curl -o /tmp/trojan-quickstart.sh https://raw.githubusercontent.com/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4580,8 +4375,6 @@ namespace ProxySU string installResult = currentShellCommandResult; - //string installResult = client.RunCommand("find / -name trojan").Result.ToString(); - if (!installResult.Contains("/usr/local/bin/trojan")) { MessageBox.Show("安装Trojan失败(官方脚本运行出错!"); @@ -4602,14 +4395,13 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //client.RunCommand("systemctl enable trojan"); + sshShellCommand = @"systemctl enable trojan"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - //client.RunCommand("mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.1"); sshShellCommand = @"mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.1"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4641,39 +4433,6 @@ namespace ProxySU File.Delete(@"config.json"); - ////打开防火墙端口 - //string openFireWallPort = ReceiveConfigurationParameters[1]; - //if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) - //{ - // if (String.Equals(openFireWallPort, "443")) - // { - // client.RunCommand("firewall-cmd --zone=public --add-port=80/tcp --permanent"); - // client.RunCommand("firewall-cmd --zone=public --add-port=443/tcp --permanent"); - // client.RunCommand("firewall-cmd --reload"); - // } - // else - // { - // client.RunCommand($"firewall-cmd --zone=public --add-port={openFireWallPort}/tcp --permanent"); - // client.RunCommand($"firewall-cmd --zone=public --add-port={openFireWallPort}/udp --permanent"); - // client.RunCommand("firewall-cmd --reload"); - // } - //} - //if (String.IsNullOrEmpty(client.RunCommand("command -v ufw").Result) == false) - //{ - // if (String.Equals(openFireWallPort, "443")) - // { - // client.RunCommand("ufw allow 80"); - // client.RunCommand("ufw allow 443"); - // client.RunCommand("yes | ufw reload"); - // } - // else - // { - // client.RunCommand($"ufw allow {openFireWallPort}/tcp"); - // client.RunCommand($"ufw allow {openFireWallPort}/udp"); - // client.RunCommand("yes | ufw reload"); - // } - //} - currentStatus = "正在安装acme.sh......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -4692,34 +4451,30 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //if (getApt == false) - //{ - // //client.RunCommand("apt-get -qq update"); - // client.RunCommand("apt-get -y -qq install socat"); - //} - //else if (getDnf == false) - //{ - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("dnf -y -q install socat"); - //} - //else if (getYum == false) - //{ - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install socat"); - //} - //else if (getZypper == false) - //{ - // // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install socat"); - //} - //client.RunCommand("curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"); - //client.RunCommand("cd ~/.acme.sh/"); - //client.RunCommand("alias acme.sh=~/.acme.sh/acme.sh"); sshShellCommand = @"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("Install success") == true) + { + currentStatus = "acme.sh安装成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "acme.sh安装失败!原因未知,请向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + return; + } + sshShellCommand = @"cd ~/.acme.sh/"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4738,13 +4493,30 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand("mkdir -p /etc/v2ray/ssl"); - //client.RunCommand($"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"); - sshShellCommand = $"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"; + sshShellCommand = $"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("Cert success") == true) + { + currentStatus = "证书申请成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "证书申请失败!原因未知,请向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + return; + } + currentStatus = "安装证书到Trojan......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -4752,21 +4524,39 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand($"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/trojan/trojan_ssl.crt --keypath /usr/local/etc/trojan/trojan_ssl.key --capath /usr/local/etc/trojan/trojan_ssl.crt --reloadcmd \"systemctl restart trojan\""); sshShellCommand = $"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/trojan/trojan_ssl.crt --keypath /usr/local/etc/trojan/trojan_ssl.key --capath /usr/local/etc/trojan/trojan_ssl.crt --reloadcmd \"systemctl restart trojan\""; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //currentStatus = "正在启动Trojan......"; - //textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - //Thread.Sleep(1000); + sshShellCommand = @"if [ ! -f ""/usr/local/etc/trojan/trojan_ssl.key"" ]; then echo ""0""; else echo ""1""; fi | head -n 1"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //client.RunCommand("systemctl restart trojan"); + if (currentShellCommandResult.Contains("1") == true) + { + currentStatus = "证书安装到Trojan,成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } + else + { + currentStatus = "证书安装到Trojan-go失败,原因未知,可以向开发者提问!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + return; + } + + //设置证书权限 + sshShellCommand = @"chmod 644 /usr/local/etc/trojan/trojan_ssl.key"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //currentStatus = "Trojan启动成功!"; - //textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - //Thread.Sleep(1000); currentStatus = "正在安装Caddy"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -4775,19 +4565,10 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand("curl https://getcaddy.com -o getcaddy"); - //client.RunCommand("bash getcaddy personal hook.service"); - //client.RunCommand("mkdir -p /etc/caddy"); - //client.RunCommand("mkdir -p /var/www"); - //安装Caddy //为假则表示系统有相应的组件。 if (getApt == false) { - //client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); - //client.RunCommand("apt install -y apt-transport-https"); - //client.RunCommand("apt -qq update"); - //client.RunCommand("apt -y -qq install caddy"); sshShellCommand = @"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4811,10 +4592,7 @@ namespace ProxySU } else if (getDnf == false) { - //client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); - //client.RunCommand(@"dnf copr enable @caddy/caddy -y"); - ////client.RunCommand("dnf -q makecache"); - //client.RunCommand("dnf -y -q install caddy"); + sshShellCommand = @"dnf install 'dnf-command(copr)' -y"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4838,10 +4616,6 @@ namespace ProxySU } else if (getYum == false) { - //client.RunCommand(@"yum install yum-plugin-copr -y"); - //client.RunCommand(@"yum copr enable @caddy/caddy -y"); - ////client.RunCommand("yum -q makecache"); - //client.RunCommand("yum -y -q install caddy"); sshShellCommand = @"yum install yum-plugin-copr -y"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4863,33 +4637,7 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - //if (getApt == false) - //{ - // client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); - // client.RunCommand("apt install -y apt-transport-https"); - // client.RunCommand("apt -qq update"); - // client.RunCommand("apt -y -qq install caddy"); - //} - //else if (getDnf == false) - //{ - // client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); - // client.RunCommand(@"dnf copr enable @caddy/caddy -y"); - // //client.RunCommand("dnf -q makecache"); - // client.RunCommand("dnf -y -q install caddy"); - //} - //else if (getYum == false) - //{ - // client.RunCommand(@"yum install yum-plugin-copr -y"); - // client.RunCommand(@"yum copr enable @caddy/caddy -y"); - // //client.RunCommand("yum -q makecache"); - // client.RunCommand("yum -y -q install caddy"); - //} - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install curl"); - //} - + sshShellCommand = @"find / -name caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4916,29 +4664,12 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //client.RunCommand("systemctl enable caddy"); + sshShellCommand = @"systemctl enable caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - - //if (!installResult.Contains("/usr/bin/caddy")) - //{ - // MessageBox.Show("安装Caddy失败!"); - // currentStatus = "安装Caddy失败!"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // client.Disconnect(); - // return; - //} - //else - //{ - // currentStatus = "Caddy安装成功!"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // Thread.Sleep(1000); - // client.RunCommand("systemctl enable caddy"); - //} - + currentStatus = "上传Caddy配置文件......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -4953,16 +4684,12 @@ namespace ProxySU string caddyConfig = "TemplateConfg\\trojan_caddy_config.caddyfile"; upLoadPath = "/etc/caddy/Caddyfile"; - //client.RunCommand("mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak"); + UploadConfig(connectionInfo, caddyConfig, upLoadPath); - ////设置Caddyfile文件中的tls 邮箱 - - //string email = $"user@{ReceiveConfigurationParameters[4]}"; - //string sshCmd; + //设置域名 - //string sshCmd = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; - //client.RunCommand(sshCmd); + sshShellCommand = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4971,8 +4698,6 @@ namespace ProxySU //设置伪装网站 if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) { - //sshCmd = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; - //client.RunCommand(sshCmd); sshShellCommand = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -4985,13 +4710,7 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - // Thread.Sleep(2000); - - //安装Caddy服务 - //sshCmd = $"caddy -service install -agree -conf /etc/caddy/Caddyfile -email {email}"; - //MessageBox.Show(sshCmd); - //client.RunCommand(sshCmd); - + currentStatus = "正在启动Caddy......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -5004,12 +4723,67 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - currentStatus = "Caddy启动成功!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(1000); + if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) + { + //运行成功 + currentStatus = "Caddy启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + //运行失败 + currentStatus = "Caddy启动失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + currentStatus = "正在启动Caddy(第二次尝试)!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + sshShellCommand = @"systemctl restart caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) + { + currentStatus = "Caddy启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "Caddy启动失败(第二次)!退出安装!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + MessageBox.Show("Caddy启动失败,原因未知!请向开发者问询!"); + return; + } + } currentStatus = "正在启动Trojan......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -5018,19 +4792,72 @@ namespace ProxySU Thread.Sleep(1000); //启动Trojan-go服务 - //client.RunCommand("systemctl restart trojan-go"); sshShellCommand = @"systemctl restart trojan"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); - currentStatus = "Trojan启动成功!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; + sshShellCommand = @"ps aux | grep trojan"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("/usr/local/bin/trojan") == true) + { + currentStatus = "Trojan启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + + //运行失败 + currentStatus = "Trojan启动失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + currentStatus = "正在启动Trojan(第二次尝试)!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(3000); + sshShellCommand = @"systemctl restart trojan"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep trojan"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("usr/local/bin/trojan-go") == true) + { + currentStatus = "Trojan启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "Trojan启动失败(第二次)!退出安装!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + MessageBox.Show("Trojan启动失败,原因未知!请向开发者问询!"); + return; + } + } - Thread.Sleep(1000); //测试BBR条件,若满足提示是否启用 currentStatus = "BBR测试......"; @@ -5040,7 +4867,6 @@ namespace ProxySU Thread.Sleep(1000); - //var result = client.RunCommand("uname -r"); sshShellCommand = @"uname -r"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -5049,7 +4875,7 @@ namespace ProxySU string[] linuxKernelVerStr = currentShellCommandResult.Split('-'); bool detectResult = DetectKernelVersionBBR(linuxKernelVerStr[0]); - //client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; + sshShellCommand = @"sysctl net.ipv4.tcp_congestion_control | grep bbr"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -5065,9 +4891,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - //client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - //client.RunCommand(@"sysctl -p"); sshShellCommand = @"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -5101,18 +4924,7 @@ namespace ProxySU } client.Disconnect();//断开服务器ssh连接 - //var result = client.RunCommand("uname -r"); - //string[] linuxKernelVerStr = result.Result.Split('-'); - - //bool detectResult = DetectKernelVersionBBR(linuxKernelVerStr[0]); - //string resultCmdTestBBR = client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; - ////如果内核满足大于等于4.9,且还未启用BBR,则启用BBR - //if (detectResult == true && resultCmdTestBBR.Contains("bbr") == false) - //{ - // client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - // client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - // client.RunCommand(@"sysctl -p"); - //} + //生成客户端配置 currentStatus = "生成客户端配置......"; @@ -5141,8 +4953,6 @@ namespace ProxySU } } - //client.Disconnect(); - currentStatus = "Trojan安装成功,祝你玩的愉快!!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -5152,8 +4962,7 @@ namespace ProxySU //显示服务端连接参数 proxyType = "Trojan"; - //TrojanResultClientInfoWindow resultClientInformation = new TrojanResultClientInfoWindow(); - //resultClientInformation.ShowDialog(); + ResultClientInformation resultClientInformation = new ResultClientInformation(); resultClientInformation.ShowDialog(); return; @@ -5162,7 +4971,7 @@ namespace ProxySU catch (Exception ex1)//例外处理 #region 例外处理 { - //MessageBox.Show(ex1.Message); + if (ex1.Message.Contains("连接尝试失败") == true) { MessageBox.Show($"{ex1.Message}\n请检查主机地址及端口是否正确,如果通过代理,请检查代理是否正常工作"); @@ -5605,7 +5414,9 @@ namespace ProxySU Thread.Sleep(1000); } //检测是否运行在root权限下 - currentShellCommandResult = "检测是否运行在root权限下..."; + currentStatus = "检测是否运行在root权限下..."; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"id -u"; @@ -5622,7 +5433,9 @@ namespace ProxySU } else { - currentShellCommandResult = "检测结果:OK!"; + currentStatus = "检测结果:OK!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } @@ -5666,21 +5479,14 @@ namespace ProxySU } else { - currentShellCommandResult = "检测结果:未安装Caddy!"; + currentStatus = "检测结果:未安装Caddy!"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } - //MessageBoxResult messageBoxResult1 = MessageBox.Show("远程主机已安装Caddy,但不确定是否支持forward proxy,是否强制重新安装?", "", MessageBoxButton.YesNo, MessageBoxImage.Question); - //if (messageBoxResult1 == MessageBoxResult.No) - //{ - // currentStatus = "安装取消,退出"; - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // Thread.Sleep(1000); - // client.Disconnect(); - // return; - //} - + //检测远程主机系统环境是否符合要求 currentStatus = "检测系统是否符合安装要求......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); @@ -5771,29 +5577,22 @@ namespace ProxySU //为假则表示系统有相应的组件。 if (getApt == false) { - //client.RunCommand("apt -qq update"); - //client.RunCommand("apt -y -qq install curl"); sshCmdUpdate = @"apt -qq update"; sshCmdInstall = @"apt -y -qq install "; } else if (getDnf == false) { - //client.RunCommand("dnf -q makecache"); - //client.RunCommand("dnf -y -q install curl"); sshCmdUpdate = @"dnf -q makecache"; sshCmdInstall = @"dnf -y -q install "; } else if (getYum == false) { - //client.RunCommand("yum -q makecache"); - //client.RunCommand("yum -y -q install curl"); sshCmdUpdate = @"yum -q makecache"; sshCmdInstall = @"yum -y -q install "; } else if (getZypper == false) { - //client.RunCommand("zypper ref"); - //client.RunCommand("zypper -y install curl"); + sshCmdUpdate = @"zypper ref"; sshCmdInstall = @"zypper -y install "; } @@ -5814,8 +5613,6 @@ namespace ProxySU currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //client.RunCommand("setenforce 0");//不重启改为Permissive模式 - //client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 sshShellCommand = @"setenforce 0"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -5849,66 +5646,7 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //if (getApt == false) - //{ - // //client.RunCommand("apt -qq update"); - // //client.RunCommand("apt -y -qq install curl libnss3 xz-utils lsof unzip"); - // sshShellCommand = @"apt -qq update"; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - // currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - // sshShellCommand = @"apt -y -qq install curl libnss3 xz-utils lsof unzip"; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - // currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //} - //else if (getDnf == false) - //{ - // //client.RunCommand("dnf -q makecache"); - // //client.RunCommand("dnf -y -q install curl nss xz lsof unzip"); - // sshShellCommand = @"dnf -q makecache"; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - // currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - // sshShellCommand = @"dnf -y -q install curl nss xz lsof unzip"; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - // currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //} - //else if (getYum == false) - //{ - // //client.RunCommand("yum -q makecache"); - // //client.RunCommand("yum -y -q install curl nss xz lsof unzip"); - // sshShellCommand = @"yum -q makecache"; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - // currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - // sshShellCommand = @"yum -y -q install curl nss xz lsof unzip"; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - // currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //} - //else if (getZypper == false) - //{ - // //client.RunCommand("zypper ref"); - // //client.RunCommand("zypper -y install curl nss xz lsof unzip"); - // sshShellCommand = @"zypper ref"; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - // currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - // sshShellCommand = @"zypper -y install curl nss xz lsof unzip"; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - // currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //} + currentStatus = "安装完毕!OK!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; @@ -5999,9 +5737,7 @@ namespace ProxySU if (String.IsNullOrEmpty(testPort443) == false) { string[] cmdResultArry443 = testPort443.Split(' '); - //client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); - //client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); - //client.RunCommand($"kill -9 {cmdResultArry443[3]}"); + sshShellCommand = $"systemctl stop {cmdResultArry443[0]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6022,9 +5758,7 @@ namespace ProxySU if (String.IsNullOrEmpty(testPort80) == false) { string[] cmdResultArry80 = testPort80.Split(' '); - //client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); - //client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); - //client.RunCommand($"kill -9 {cmdResultArry80[3]}"); + sshShellCommand = $"systemctl stop {cmdResultArry80[0]}"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6072,10 +5806,6 @@ namespace ProxySU if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) { - - //client.RunCommand("firewall-cmd --zone=public --add-port=80/tcp --permanent"); - //client.RunCommand("firewall-cmd --zone=public --add-port=443/tcp --permanent"); - //client.RunCommand("firewall-cmd --reload"); sshShellCommand = @"firewall-cmd --zone=public --add-port=80/tcp --permanent"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6094,9 +5824,6 @@ namespace ProxySU } if (String.IsNullOrEmpty(client.RunCommand("command -v ufw").Result) == false) { - //client.RunCommand("ufw allow 80"); - //client.RunCommand("ufw allow 443"); - //client.RunCommand("yes | ufw reload"); sshShellCommand = @"ufw allow 80"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 @@ -6126,10 +5853,7 @@ namespace ProxySU //为假则表示系统有相应的组件。 if (getApt == false) { - //client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); - //client.RunCommand("apt install -y apt-transport-https"); - //client.RunCommand("apt -qq update"); - //client.RunCommand("apt -y -qq install caddy"); + sshShellCommand = @"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6153,10 +5877,7 @@ namespace ProxySU } else if (getDnf == false) { - //client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); - //client.RunCommand(@"dnf copr enable @caddy/caddy -y"); - ////client.RunCommand("dnf -q makecache"); - //client.RunCommand("dnf -y -q install caddy"); + sshShellCommand = @"dnf install 'dnf-command(copr)' -y"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6180,10 +5901,7 @@ namespace ProxySU } else if (getYum == false) { - //client.RunCommand(@"yum install yum-plugin-copr -y"); - //client.RunCommand(@"yum copr enable @caddy/caddy -y"); - ////client.RunCommand("yum -q makecache"); - //client.RunCommand("yum -y -q install caddy"); + sshShellCommand = @"yum install yum-plugin-copr -y"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6237,7 +5955,7 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - //client.RunCommand("systemctl enable caddy"); + sshShellCommand = @"systemctl enable caddy"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6253,11 +5971,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand(@"curl -o /tmp/caddy.zip https://raw.githubusercontent.com/proxysu/Resources/master/Caddy2/caddy20200816.zip"); - //client.RunCommand(@"unzip /tmp/caddy.zip"); //解压到当前目录 ~/ - //client.RunCommand(@"chmod +x caddy"); - //client.RunCommand(@"systemctl stop caddy;rm -f /usr/bin/caddy"); - //client.RunCommand(@"cp ./caddy /usr/bin/"); sshShellCommand = @"curl -o /tmp/caddy.zip https://raw.githubusercontent.com/proxysu/Resources/master/Caddy2/caddy20200816.zip"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6298,7 +6011,6 @@ namespace ProxySU //生成服务端配置 - //string email = $"user@{ReceiveConfigurationParameters[4]}";//生成Caddyfile文件中的tls 邮箱 string caddyConfig = "TemplateConfg\\Naiveproxy_server_config.json"; using (StreamReader reader = File.OpenText(caddyConfig)) { @@ -6335,9 +6047,6 @@ namespace ProxySU currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //client.RunCommand(@"sed -i 's/Caddyfile/config.json/' /lib/systemd/system/caddy.service"); - //client.RunCommand("systemctl daemon-reload"); - //client.RunCommand("systemctl restart caddy"); //启动Caddy服务 sshShellCommand = @"sed -i 's/Caddyfile/config.json/' /lib/systemd/system/caddy.service"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6348,7 +6057,7 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - currentStatus = "设置完毕,正在重启Caddy......"; + currentStatus = "设置完毕,正在启动Caddy......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); currentShellCommandResult = currentStatus; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -6359,11 +6068,69 @@ namespace ProxySU currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - currentStatus = "重启Caddy完毕,OK!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) + { + //运行成功 + currentStatus = "Caddy启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + //运行失败 + currentStatus = "Caddy启动失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + currentStatus = "正在启动Caddy(第二次尝试)!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + sshShellCommand = @"systemctl restart caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(3000); + + sshShellCommand = @"ps aux | grep caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) + { + currentStatus = "Caddy启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + } + else + { + currentStatus = "Caddy启动失败(第二次)!退出安装!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + MessageBox.Show("Caddy启动失败,原因未知!请向开发者问询!"); + return; + } + } + + ////设置伪装网站 //if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) //{ @@ -6382,115 +6149,96 @@ namespace ProxySU //优化网络参数 sshShellCommand = @"bash -c 'echo ""fs.file-max = 51200"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.core.rmem_max = 67108864"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.core.wmem_max = 67108864"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.core.rmem_default = 65536"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.core.wmem_default = 65536"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.core.netdev_max_backlog = 4096"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.core.somaxconn = 4096"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_syncookies = 1"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_tw_reuse = 1"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_tw_recycle = 0"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_fin_timeout = 30"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_keepalive_time = 1200"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.ip_local_port_range = 10000 65000"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_max_syn_backlog = 4096"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_max_tw_buckets = 5000"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_rmem = 4096 87380 67108864"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_wmem = 4096 65536 67108864"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_mtu_probing = 1"" >> /etc/sysctl.conf'"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"sysctl -p"; - //client.RunCommand(sshShellCommand); TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 @@ -6511,7 +6259,6 @@ namespace ProxySU Thread.Sleep(1000); - //var result = client.RunCommand("uname -r"); sshShellCommand = @"uname -r"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6520,7 +6267,6 @@ namespace ProxySU string[] linuxKernelVerStr = currentShellCommandResult.Split('-'); bool detectResult = DetectKernelVersionBBR(linuxKernelVerStr[0]); - //client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; sshShellCommand = @"sysctl net.ipv4.tcp_congestion_control | grep bbr"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6536,9 +6282,6 @@ namespace ProxySU Thread.Sleep(1000); - //client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - //client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - //client.RunCommand(@"sysctl -p"); sshShellCommand = @"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 currentShellCommandResult = client.RunCommand(sshShellCommand).Result; @@ -6605,8 +6348,6 @@ namespace ProxySU //显示服务端连接参数 proxyType = "NaiveProxy"; - //NaiveProxyResultInfoWindow resultClientInformation = new NaiveProxyResultInfoWindow(); - //resultClientInformation.ShowDialog(); ResultClientInformation resultClientInformation = new ResultClientInformation(); resultClientInformation.ShowDialog(); return; @@ -6862,12 +6603,11 @@ namespace ProxySU string cmdResult; cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; cmdResult = client.RunCommand(cmdTestPort).Result; - //MessageBox.Show(cmdTestPort); + if (String.IsNullOrEmpty(cmdResult) == false) { - //MessageBox.Show(cmdResult); + string[] cmdResultArry443 = cmdResult.Split(' '); - //MessageBox.Show(cmdResultArry443[3]); client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); client.RunCommand($"kill -9 {cmdResultArry443[3]}"); @@ -6910,8 +6650,9 @@ namespace ProxySU private void StartTestAndEnableBBR(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) { string currentStatus = "正在登录远程主机......"; - Action<TextBlock, ProgressBar, string> updateAction = new Action<TextBlock, ProgressBar, string>(UpdateTextBlock); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 try { @@ -6950,84 +6691,102 @@ namespace ProxySU { currentStatus = "主机登录成功"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 Thread.Sleep(1000); } //检测是否运行在root权限下 - string testRootAuthority = client.RunCommand(@"id -u").Result; + currentStatus = "检测是否运行在root权限下..."; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"id -u"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + string testRootAuthority = currentShellCommandResult; if (testRootAuthority.Equals("0\n") == false) { MessageBox.Show("请使用具有root权限的账户登录主机!!"); client.Disconnect(); return; } + else + { + currentStatus = "检测结果:OK!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } //检测远程主机系统环境是否符合要求 currentStatus = "检测系统内核版本是否符合要求......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); - var result = client.RunCommand("uname -r"); - //var result = client.RunCommand("cat /root/test.ver"); - string[] linuxKernelVerStr = result.Result.Split('-'); + sshShellCommand = @"uname -r"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - bool detectResult = DetectKernelVersionBBR(linuxKernelVerStr[0]); - if (detectResult == false) + string[] linuxKernelVerStrBBR = currentShellCommandResult.Split('-'); + + bool detectResultBBR = DetectKernelVersionBBR(linuxKernelVerStrBBR[0]); + + sshShellCommand = @"sysctl net.ipv4.tcp_congestion_control | grep bbr"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + string resultCmdTestBBR = currentShellCommandResult; + //如果内核满足大于等于4.9,且还未启用BBR,则启用BBR + if (detectResultBBR == true && resultCmdTestBBR.Contains("bbr") == false) { - MessageBox.Show($"当前系统内核版本为{linuxKernelVerStr[0]},启用BBR要求内核为4.9及以上。请升级内核再安装!或更换系统为CentOS8/Debian9/10/Ubuntu18.04及以上"); - currentStatus = "系统内核版本不符合要求,安装失败!!"; + currentStatus = "正在启用BBR......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); - client.Disconnect(); - return; + + sshShellCommand = @"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"sysctl -p"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } - //检测是否安装有NaiveProxy - currentStatus = "检测系统是否已经启用BBR......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - Thread.Sleep(1000); - - string resultCmdTestBBR = client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; - - if (resultCmdTestBBR.Contains("bbr") == true) + else if (resultCmdTestBBR.Contains("bbr") == true) { - MessageBoxResult messageBoxResult = MessageBox.Show("远程主机已启用BBR!"); - - currentStatus = "远程主机已启用BBR!退出!"; + currentStatus = "BBR已经启用了!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - Thread.Sleep(1000); - client.Disconnect(); - return; - } + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - currentStatus = "内核符合要求,启用中......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - Thread.Sleep(1000); - - //启用BBR - - client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - client.RunCommand(@"sysctl -p"); - - resultCmdTestBBR = client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; - //resultCmdTestBBR = client.RunCommand(@"sysctl -n net.ipv4.tcp_congestion_control").Result; - if (resultCmdTestBBR.Contains("bbr") == true) - { - MessageBoxResult messageBoxResult = MessageBox.Show("远程主机已成功启用BBR!"); - - currentStatus = "远程主机已启用BBR!成功!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - Thread.Sleep(1000); } else { - MessageBoxResult messageBoxResult = MessageBox.Show("BBR启用失败!原因未知,请重试或更换系统为CentOS8/Debian9/10/Ubuntu18.04及以上"); - - currentStatus = "BBR启用失败!"; + currentStatus = "系统不满足启用BBR的条件,启用失败!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - Thread.Sleep(1000); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } + client.Disconnect();//断开服务器ssh连接 - client.Disconnect(); return; } } @@ -7063,6 +6822,8 @@ namespace ProxySU } currentStatus = "主机登录失败"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } #endregion @@ -8117,9 +7878,13 @@ namespace ProxySU } + #endregion - + private void Button_Click(object sender, RoutedEventArgs e) + { + MessageBox.Show(System.Globalization.CultureInfo.InstalledUICulture.Name); + } } } diff --git a/ProxySU/ProofreadTimeWindow.xaml.cs b/ProxySU/ProofreadTimeWindow.xaml.cs index 44eb5d3..cabbba4 100644 --- a/ProxySU/ProofreadTimeWindow.xaml.cs +++ b/ProxySU/ProofreadTimeWindow.xaml.cs @@ -52,7 +52,7 @@ namespace ProxySU client.RunCommand("ln -s /usr/share/zoneinfo/UTC /etc/localtime"); //获取远程主机的时间戳 long timeStampVPS = Convert.ToInt64(client.RunCommand("date +%s").Result.ToString()); - //MessageBox.Show(timesStampVPS.ToString()); + //获取本地时间戳 TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0); long timeStampLocal = Convert.ToInt64(ts.TotalSeconds); @@ -61,9 +61,7 @@ namespace ProxySU { MessageBox.Show("本地时间与远程主机时间相差超过限制(90秒),V2ray无法建立连接"); - //currentStatus = "时间较对失败......"; - //textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - //Thread.Sleep(1000); + return; } else @@ -107,11 +105,9 @@ namespace ProxySU //获取本地时间戳 TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0); long timeStampLocal = Convert.ToInt64(ts.TotalSeconds); - //string stampTime = timeStampLocal.ToString(); + string sshCmd = $"date --set=\"$(date \"+%Y-%m-%d %H:%M:%S\" -d @{timeStampLocal.ToString()})\""; - //MessageBox.Show(sshCmd); - //string sshCmd = $"date --set=\"$(date \"+%Y-%m-%d %H:%M:%S\" -d @1489739011)\""; - //MessageBox.Show(sshCmd); + client.RunCommand(sshCmd); MessageBox.Show("同步本地时间校时完毕"); @@ -124,17 +120,12 @@ namespace ProxySU long timeStampVPS = Convert.ToInt64(utcTS.TotalSeconds); if (timeStampVPS!=0) { - //MessageBox.Show(timeStampVPS.ToString()); + string sshCmd = $"date --set=\"$(date \"+%Y-%m-%d %H:%M:%S\" -d @{timeStampVPS.ToString()})\""; - //MessageBox.Show(sshCmd); + client.RunCommand(sshCmd); MessageBox.Show("同步网络时间校时完毕"); } - //else - //{ - // MessageBox.Show(timeStampVPS.ToString()); - // MessageBox.Show("同步网络时间失败"); - //} } client.Disconnect(); diff --git a/ProxySU/ProxySU.csproj b/ProxySU/ProxySU.csproj index ec40860..fb08767 100644 --- a/ProxySU/ProxySU.csproj +++ b/ProxySU/ProxySU.csproj @@ -113,6 +113,14 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Translations\ProxySU.zh-CN.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Translations\ProxySU.en-US.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="V2RayTemplateWindow.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -155,6 +163,7 @@ <ItemGroup> <Resource Include="ProxySU.ico" /> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <PropertyGroup> <PostBuildEvent>del "$(TargetDir)*.xml" diff --git a/ProxySU/ResultClientInformation.xaml b/ProxySU/ResultClientInformation.xaml index 7c21433..cfaabf0 100644 --- a/ProxySU/ResultClientInformation.xaml +++ b/ProxySU/ResultClientInformation.xaml @@ -197,7 +197,7 @@ <ColumnDefinition></ColumnDefinition> <ColumnDefinition Width="0.6*"></ColumnDefinition> </Grid.ColumnDefinitions> - <TextBlock x:Name="TextBlockQrURLexplain" Text="二维码和URL链接可用于
v2rayN(windows)
Trojan-QT5(windows)
Qv2ray(windows)
Shadowrocket(ios)
v2rayNG(Android)
导入v2ray节点
注意:Vless协议需要手动输入配置参数,二维码和URL无效" TextWrapping="Wrap" Grid.Column="0"></TextBlock> + <TextBlock x:Name="TextBlockQrURLexplain" Text="二维码和URL链接可用于
v2rayN(windows)
Trojan-QT5(windows)
Qv2ray(windows)
Shadowrocket(ios)
v2rayNG(Android)
导入v2ray节点

注意:Vless协议需要手动输入配置参数,二维码和URL无效" TextWrapping="Wrap" Grid.Column="0"></TextBlock> <Image x:Name="ImageShareQRcode" Grid.Column="1"></Image> <TextBox x:Name="TextBoxURL" TextWrapping="Wrap" Grid.Column="2"></TextBox> </Grid> diff --git a/ProxySU/ResultClientInformation.xaml.cs b/ProxySU/ResultClientInformation.xaml.cs index ceaa0ae..c7a32f2 100644 --- a/ProxySU/ResultClientInformation.xaml.cs +++ b/ProxySU/ResultClientInformation.xaml.cs @@ -109,6 +109,8 @@ namespace ProxySU HideAlterId(); HidePath(); HideQuicKey(); + ImageShareQRcode.Visibility = Visibility.Collapsed; + TextBoxURL.Visibility = Visibility.Collapsed; } else if (String.Equals(MainWindow.ReceiveConfigurationParameters[0], "webSocket")) { @@ -444,15 +446,21 @@ namespace ProxySU num++; } CheckDir(@"v2ray_config\" + saveFileFolder); - //MessageBox.Show(v2rayNjsonObject.ToString()); + //生成二维码与URL,跳过VlessTcpTlsWeb暂时未有URL标准 string vmessUrl = "vmess://" + ToBase64Encode(v2rayNjsonObject.ToString()); TextBoxURL.Text = vmessUrl; using (StreamWriter sw = new StreamWriter($"v2ray_config\\{saveFileFolder}\\url.txt")) { - sw.WriteLine(vmessUrl); - + if (String.Equals(MainWindow.ReceiveConfigurationParameters[0], "VlessTcpTlsWeb") == false) + { + sw.WriteLine(vmessUrl); + } } - CreateQRCode(vmessUrl,"v2ray_config"); + if (String.Equals(MainWindow.ReceiveConfigurationParameters[0], "VlessTcpTlsWeb") == false) + { + CreateQRCode(vmessUrl, "v2ray_config"); + } + if (File.Exists(@"v2ray_config\config.json")) { diff --git a/ProxySU/Translations/ProxySU.en-US.xaml b/ProxySU/Translations/ProxySU.en-US.xaml new file mode 100644 index 0000000..b145274 --- /dev/null +++ b/ProxySU/Translations/ProxySU.en-US.xaml @@ -0,0 +1,136 @@ +<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:ProxySU.Translations" + xmlns:sys="clr-namespace:System;assembly=mscorlib"> + <sys:String x:Key="TabItemHeaderAppDeployment">Deployment</sys:String> + <sys:String x:Key="TabItemHeaderResourceTools">Resource Tools</sys:String> + <sys:String x:Key="TextBlockHostName">Host:</sys:String> + <sys:String x:Key="TextBoxHostNamePrompt">IP or Domain (Not empty)</sys:String> + <sys:String x:Key="TextBlockHostPart">Port:</sys:String> + <sys:String x:Key="TextBlockHostUser">User:</sys:String> + <sys:String x:Key="TextBlockHostPassword">Password:</sys:String> + <sys:String x:Key="TextBlockSetUpProcessing">Waiting for Deployment</sys:String> + <sys:String x:Key="TabItemHeaderSysTools">Tools</sys:String> + <sys:String x:Key="ButtonV2RayTemplateConfiguration">V2Ray Templates</sys:String> + <sys:String x:Key="ButtonV2RayOneKeyInstall">Install V2ray</sys:String> + <sys:String x:Key="ButtonUpdateV2ray">Upgrade V2Ray</sys:String> + <sys:String x:Key="Button_canel">Canel</sys:String> + <sys:String x:Key="ButtonTrojanGoTemplate">Trojan-Go Templates</sys:String> + <sys:String x:Key="ButtonTrojanGoSetUp">Install Trojan-Go</sys:String> + <sys:String x:Key="ButtonUpdateTrojanGo">Upgrade Trojan-Go</sys:String> + <sys:String x:Key="ButtonTrojanGoCancel">Canel</sys:String> + <sys:String x:Key="GroupBoxHeaderParameterTrojan">Parameter</sys:String> + <sys:String x:Key="TextBlockTrojanTemplateExplanation">Plan: Trojan+TLS+Caddy</sys:String> + <sys:String x:Key="TextBlockTrojanServerDomain">Server Domain:</sys:String> + <sys:String x:Key="TextBlockTrojanPort">Port: 443</sys:String> + <sys:String x:Key="TextBoxDomainPrompt">Domain name cannot be empty</sys:String> + <sys:String x:Key="TextBlockTrojanHostPassword">Password:</sys:String> + <sys:String x:Key="ButtonTrojanChangePassword">Change</sys:String> + <sys:String x:Key="ButtonTrojanSetUp">Install Trojan</sys:String> + <sys:String x:Key="ButtonUpdateTrojan">Upgrade Trojan</sys:String> + <sys:String x:Key="ButtonTrojanCancel">Cancel</sys:String> + <sys:String x:Key="TextBlockNaiveProxyTemplateExplanation">Plan: NaiveProxy+TLS+Caddy</sys:String> + <sys:String x:Key="ButtonNaiveProxyChangeUser">Change</sys:String> + <sys:String x:Key="ButtonNavieSetUp">Install NaiveProxy</sys:String> + <sys:String x:Key="ButtonNaiveCancel">Cancel</sys:String> + <sys:String x:Key="ButtonProofreadTime">Proofread Time</sys:String> + <sys:String x:Key="ButtonClearOccupiedPorts">Release Port 80/443</sys:String> + <sys:String x:Key="ButtonTestAndEnableBBR">Turn on BBR</sys:String> + <sys:String x:Key="ButtonWebBrowserHomePage">Home</sys:String> + <sys:String x:Key="ButtonWebBrowserForward">Forward</sys:String> + <sys:String x:Key="ButtonWebBrowserBack">Back</sys:String> + <sys:String x:Key="TextBlockWebExplain">Due to well-known reasons, loading is slow at certain times, please be patient</sys:String> + <sys:String x:Key="GroupBoxHeaderTrojanGoTemplates">Trojan-go Templates</sys:String> + <sys:String x:Key="TextBlockTrojanGoTLSwebPlan">HTTP/2 transmission, Caddy2 camouflage website, anti-identification, does not support CloudFlare CDN temporarily</sys:String> + <sys:String x:Key="TextBlockTrojanGoWebSocketTLSwebPlan">Use WebSocket transmission, Caddy2 camouflage website, anti-identification, support CloudFlare CDN</sys:String> + <sys:String x:Key="GroupBoxHeaderParameterTrojanGo">Parameter</sys:String> + <sys:String x:Key="TextBlockTrojanGoDomain">Domain:</sys:String> + <sys:String x:Key="TextBlockTrojanGoPort">Port: 443</sys:String> + <sys:String x:Key="TextBlockTrojanGoPassword">Password: </sys:String> + <sys:String x:Key="TextBlockTrojanGoPasswordExplain">Use the existing password and paste it directly into the box</sys:String> + <sys:String x:Key="TextBlockTrojanGoWebSocketPath">WebSocket Path: </sys:String> + <sys:String x:Key="ButtonTrojanGoTemplateOK">OK</sys:String> + <sys:String x:Key="ButtonTrojanGoTemplateCancel">Cancel</sys:String> + <sys:String x:Key="GroupBoxHeaderV2RayTemplates">V2Ray Templates</sys:String> + <sys:String x:Key="TabItemHeaderV2RayHotPlan">Hot Plan</sys:String> + <sys:String x:Key="TabItemHeaderV2RayTcpProtocol">TCP</sys:String> + <sys:String x:Key="TabItemHeaderV2RayWebSocketProtocol">WebSocket</sys:String> + <sys:String x:Key="TabItemHeaderV2RayHttp2Protocol">Http/2</sys:String> + <sys:String x:Key="TabItemHeaderV2RayMkcpProtocol">mKCP</sys:String> + <sys:String x:Key="TabItemHeaderV2RayQuicProtocol">QUIC</sys:String> + <sys:String x:Key="GroupBoxHeaderParameterV2Ray">Parameter</sys:String> + <sys:String x:Key="TextBlockV2RayServerPort">Port: </sys:String> + <sys:String x:Key="ButtonV2RayServerPortChange">Change</sys:String> + <sys:String x:Key="TextBlockV2RayServerPortExplain">TLS encryption, keep port 443</sys:String> + <sys:String x:Key="TextBlockV2RayUUIDExplain">Use the existing UUID and paste it directly into the box</sys:String> + <sys:String x:Key="TextBlockV2RayQuicUUID">mKCP/QUIC Key</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpExplain">Enable mKCP key to enhance anti-recognition, Blank to disabled, 4.24.2+ required, V2rayN not support</sys:String> + <sys:String x:Key="TextBlockV2RayPath">Path: </sys:String> + <sys:String x:Key="TextBlockV2RayDomain">Domain: </sys:String> + <sys:String x:Key="TextBlockV2RayMaskSites">Shield Websites: </sys:String> + <sys:String x:Key="TextBoxV2RayMaskSitesTag">Increase the concealment of the agent (can be empty)</sys:String> + <sys:String x:Key="TextBlockV2RayWebSocketTlsWebExplain">Strong stability, Caddy2 is front-facing, hidden proxy features, it is recognized as https traffic visiting the website, the strongest anti-blocking recognition, domain name is required, CDN support</sys:String> + <sys:String x:Key="TextBlockV2RayHttp2TlsWebExplain">Based on HTTP/2 transmission. Completely implemented in accordance with the HTTP/2 standard, with Caddy2 as the front end, hidden proxy features, H2C protocol forwarding to V2Ray, domain name is required, and CloudFlare CDN is not supported temporarily</sys:String> + <sys:String x:Key="TextBlockV2RayTcpExplain">Encrypted data transmission will be recognized as unknown tcp traffic</sys:String> + <sys:String x:Key="RadioButtonV2RayTcpHttp">TCP+Http(Disguise)</sys:String> + <sys:String x:Key="TextBlockV2RayTcpHttpExplain">Encrypted transmission of data and http disguise will be recognized as http traffic, but not real http access</sys:String> + <sys:String x:Key="TextBlockV2RayTcpTlsExplain">Encrypted data transmission, the transmission protocol uses TLS, it will be recognized as TLS traffic, not equivalent to https traffic characteristics (domain name required)</sys:String> + <sys:String x:Key="RadioButtonV2RayTcpTlsSelfSigned">TCP+TLS(Self-signed)</sys:String> + <sys:String x:Key="TextBlockV2RayTcpTlsSelfSignedExplain">Encrypted data transmission, the transmission protocol uses TLS, it will be recognized as TLS traffic, not equivalent to https traffic characteristics (no domain name required)</sys:String> + <sys:String x:Key="TextBlockV2RaySelfSignedShadowrocketExplain">Shadowrocket (ios) needs to manually turn on the "Allow Insecure" option</sys:String> + <sys:String x:Key="TextBlockV2RayVlessTcpTlsWebExplain">Lightweight protocol VLESS, occupies less host resources, data TLS encrypted transmission, and Caddy2 is used as a disguised website on the node. Suitable for low-configuration VPS, or multiple people sharing nodes, the server client version requires 4.27+ (domain name required)</sys:String> + <sys:String x:Key="TextBlockV2RayWebSocketExplain">Data is encrypted for transmission. The transmission protocol uses WebSocket. If TLS is not enabled, it will be recognized as WebSocket traffic.</sys:String> + <sys:String x:Key="TextBlockV2RayWebSocketTlsExplain">Data is encrypted for transmission, the transmission protocol uses WebSocket, and TLS is enabled, it will be recognized as TLS traffic. (Domain name required)</sys:String> + <sys:String x:Key="RadioButtonV2RayWebSocketTlsSelfSigned">WebSocket+TLS (Self-signed)</sys:String> + <sys:String x:Key="TextBlockV2RayWebSocketTlsSelfSignedExplain">Data is encrypted for transmission, the transmission protocol uses WebSocket, and TLS is enabled, it will be recognized as TLS traffic. (No domain name required)</sys:String> + <sys:String x:Key="TextBlockV2RayHttp2Explain">Transmission method based on HTTP/2. It is fully implemented in accordance with the HTTP/2 standard and requires a domain name</sys:String> + <sys:String x:Key="RadioButtonV2RayHttp2SelfSigned">HTTP2 (Self-signed)</sys:String> + <sys:String x:Key="TextBlockV2RayHttp2SelfSignedExplain">Transmission method based on HTTP/2. It is fully implemented in accordance with the HTTP/2 standard, uses a self-signed certificate, and does not require a domain name</sys:String> + <sys:String x:Key="RadioButtonV2RayMkcpNone">mKCP(No disguise)</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpNoneExplain">Data encrypted transmission to increase bandwidth usage and reduce delay, udp protocol, no camouflage, will be recognized as udp traffic</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpSRTPExplain">Same as mKCP (no camouflage), adding a packet disguised as SRTP will be recognized as video call data (such as FaceTime)</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpuTPExplain">Same as mKCP (without camouflage), add disguised as uTP data packet, it will be recognized as BT download data</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpWeChatExplain">Same as mKCP (no camouflage), adding data packets disguised as WeChat video calls</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpDTLSExplain">Same as mKCP (no masquerading), adding masquerading as DTLS 1.2 packets</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpWireGuardExplain">Same as mKCP (without camouflage), adding a pretend to be a WireGuard packet. (Not a real WireGuard protocol)</sys:String> + <sys:String x:Key="TextBlockV2RayQuicShadowrocketExplain">Reminder: Shadowrocket currently does not support QUIC transmission mode.</sys:String> + <sys:String x:Key="RadioButtonV2RayQuicNone">QUIC(No disguise)</sys:String> + <sys:String x:Key="TextBlockV2RayQuicNoneExplain">Encrypted data transmission, no pretense will be recognized as udp traffic, produced by Google, advantages: reduced delay, multiplexing, connection migration</sys:String> + <sys:String x:Key="TextBlockV2RayQuicSRTPExplain">Same as QUIC (no camouflage), adding a packet disguised as SRTP will be recognized as video call data (such as FaceTime)</sys:String> + <sys:String x:Key="TextBlockV2RayQuicuTPExplain">Same as QUIC (no camouflage), adding a packet disguised as uTP, it will be recognized as BT download data</sys:String> + <sys:String x:Key="TextBlockV2RayQuicWeChatExplain">Same as QUIC (no camouflage), adding data packets disguised as WeChat video calls</sys:String> + <sys:String x:Key="TextBlockV2RayQuicDTLSExplain">Same as QUIC (no masquerading), adding masquerading as DTLS 1.2 packets</sys:String> + <sys:String x:Key="TextBlockV2RayQuicWireGuardExplain">Same as QUIC (without camouflage), adding a packet disguised as WireGuard. (Not a real WireGuard protocol)</sys:String> + <!--以下为程序内的--> + <sys:String x:Key="MessageBoxShow_ErrorHostConnection">The remote host connection information is wrong, please check</sys:String> + <sys:String x:Key="MessageBoxShow_ChooseTemplate">Please select a configuration template first!</sys:String> + <sys:String x:Key="DisplayInstallInfo_Login">Logging in to the remote host......</sys:String> + <sys:String x:Key="DisplayInstallInfo_LoginSuccessful">Host login is successful!</sys:String> + <sys:String x:Key="DisplayInstallInfo_DetectionRootPermission">Check whether it is running under root privileges...</sys:String> + <sys:String x:Key="MessageBoxShow_ErrorRootPermission">Please log in to the host with an account with root privileges!</sys:String> + <sys:String x:Key="DisplayInstallInfo_DetectionRoot_OK">Test result: OK!</sys:String> + <sys:String x:Key="DisplayInstallInfo_TestExistV2Ray">Check whether the system has installed V2ray....</sys:String> + <sys:String x:Key="MessageBoxShow_ExistedV2Ray">V2ray has been installed on the remote host, do you force it to reinstall?</sys:String> + <sys:String x:Key="DisplayInstallInfo_InstallationCanceledExit">Installation canceled, exit</sys:String> + <sys:String x:Key="DisplayInstallInfo_ForceInstallV2Ray">You have chosen to install V2Ray forcefully!</sys:String> + <sys:String x:Key="DisplayInstallInfo_NoInstalledV2Ray">Test result: V2Ray is not installed!</sys:String> + + + <!--<sys:String x:Key="BtnOK">OK</sys:String> + <sys:String x:Key="HdNo">No.</sys:String> + <sys:String x:Key="HdName">Name</sys:String> + <sys:String x:Key="HdGender">Gender</sys:String> + <sys:String x:Key="HdDept">Dept</sys:String> + <sys:String x:Key="HdEmail">Email</sys:String> + <sys:String x:Key="HdTel">Tel</sys:String> + <sys:String x:Key="MsgShowTime">Now</sys:String> + <sys:String x:Key="BtnOK1">OK</sys:String> + <sys:String x:Key="HdNo1">No.</sys:String> + <sys:String x:Key="HdName1">Name</sys:String> + <sys:String x:Key="HdGender1">Gender</sys:String> + <sys:String x:Key="HdDept1">Dept</sys:String> + <sys:String x:Key="HdEmail1">Email</sys:String> + <sys:String x:Key="HdTel1">Tel</sys:String> + <sys:String x:Key="MsgShowTime1">Now</sys:String>--> + +</ResourceDictionary> \ No newline at end of file diff --git a/ProxySU/Translations/ProxySU.zh-CN.xaml b/ProxySU/Translations/ProxySU.zh-CN.xaml new file mode 100644 index 0000000..4d53401 --- /dev/null +++ b/ProxySU/Translations/ProxySU.zh-CN.xaml @@ -0,0 +1,141 @@ +<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:ProxySU.Translations" + xmlns:sys="clr-namespace:System;assembly=mscorlib"> + <sys:String x:Key="TabItemHeaderAppDeployment">应用布署</sys:String> + <sys:String x:Key="TabItemHeaderResourceTools">资源工具</sys:String> + <sys:String x:Key="TextBlockHostName">主机:</sys:String> + <sys:String x:Key="TextBoxHostNamePrompt">IP或域名(不可为空)</sys:String> + <sys:String x:Key="TextBlockHostPart">端口:</sys:String> + <sys:String x:Key="TextBlockHostUser">用户名:</sys:String> + <sys:String x:Key="TextBlockHostPassword">密码:</sys:String> + <sys:String x:Key="TextBlockSetUpProcessing">等待安装布署</sys:String> + <sys:String x:Key="TabItemHeaderSysTools">系统工具</sys:String> + <sys:String x:Key="ButtonV2RayTemplateConfiguration">V2Ray模板库</sys:String> + <sys:String x:Key="ButtonV2RayOneKeyInstall">V2ray一键安装</sys:String> + <sys:String x:Key="ButtonUpdateV2ray">升级V2Ray</sys:String> + <sys:String x:Key="Button_canel">取消</sys:String> + <sys:String x:Key="ButtonTrojanGoTemplate">Trojan-Go参数设置</sys:String> + <sys:String x:Key="ButtonTrojanGoSetUp">Trojan-Go一键安装</sys:String> + <sys:String x:Key="ButtonUpdateTrojanGo">升级Trojan-Go</sys:String> + <sys:String x:Key="ButtonTrojanGoCancel">取消</sys:String> + <sys:String x:Key="GroupBoxHeaderParameterTrojan">参数设置</sys:String> + <sys:String x:Key="TextBlockTrojanTemplateExplanation">模式:Trojan+TLS+Caddy</sys:String> + <sys:String x:Key="TextBlockTrojanServerDomain">服务器地址(域名):</sys:String> + <sys:String x:Key="TextBlockTrojanPort">端口:443</sys:String> + <sys:String x:Key="TextBoxDomainPrompt">域名不可为空</sys:String> + <sys:String x:Key="TextBlockTrojanHostPassword">密码:</sys:String> + <sys:String x:Key="ButtonTrojanChangePassword">更新</sys:String> + <sys:String x:Key="ButtonTrojanSetUp">Trojan一键安装</sys:String> + <sys:String x:Key="ButtonUpdateTrojan">升级Trojan</sys:String> + <sys:String x:Key="ButtonTrojanCancel">取消</sys:String> + <sys:String x:Key="TextBlockNaiveProxyTemplateExplanation">模式:NaiveProxy+TLS+Caddy</sys:String> + <sys:String x:Key="ButtonNaiveProxyChangeUser">随机</sys:String> + <sys:String x:Key="ButtonNavieSetUp">NaiveProxy一键安装</sys:String> + <sys:String x:Key="ButtonNaiveCancel">取消</sys:String> + <sys:String x:Key="ButtonProofreadTime">校对时间</sys:String> + <sys:String x:Key="ButtonClearOccupiedPorts">释放80/443端口</sys:String> + <sys:String x:Key="ButtonTestAndEnableBBR">启用BBR</sys:String> + <sys:String x:Key="ButtonWebBrowserHomePage">主页</sys:String> + <sys:String x:Key="ButtonWebBrowserForward">前进</sys:String> + <sys:String x:Key="ButtonWebBrowserBack">后退</sys:String> + <sys:String x:Key="TextBlockWebExplain">由于众所周知的原因,在某些时候,加载缓慢,请耐心等待一下</sys:String> + <sys:String x:Key="GroupBoxHeaderTrojanGoTemplates">Trojan-go 模板库</sys:String> + <sys:String x:Key="TextBlockTrojanGoTLSwebPlan">http/2传输,Caddy2伪装网站,抗识别,暂不支持CloudFlare的CDN</sys:String> + <sys:String x:Key="TextBlockTrojanGoWebSocketTLSwebPlan">使用WebSocket传输,Caddy2伪装网站,抗识别,支持CloudFlare的CDN</sys:String> + <sys:String x:Key="GroupBoxHeaderParameterTrojanGo">参数设置</sys:String> + <sys:String x:Key="TextBlockTrojanGoDomain">域名:</sys:String> + <sys:String x:Key="TextBlockTrojanGoPort">端口:443</sys:String> + <sys:String x:Key="TextBlockTrojanGoPassword">密码:</sys:String> + <sys:String x:Key="TextBlockTrojanGoPasswordExplain">使用已有密码,直接粘贴到框中</sys:String> + <sys:String x:Key="TextBlockTrojanGoWebSocketPath">WebSocket路径:</sys:String> + <sys:String x:Key="ButtonTrojanGoTemplateOK">确定</sys:String> + <sys:String x:Key="ButtonTrojanGoTemplateCancel">取消</sys:String> + <sys:String x:Key="GroupBoxHeaderV2RayTemplates">V2Ray 模板库</sys:String> + <sys:String x:Key="TabItemHeaderV2RayHotPlan">热门方案</sys:String> + <sys:String x:Key="TabItemHeaderV2RayTcpProtocol">TCP传输协议</sys:String> + <sys:String x:Key="TabItemHeaderV2RayWebSocketProtocol">WebSocket传输协议</sys:String> + <sys:String x:Key="TabItemHeaderV2RayHttp2Protocol">Http/2传输协议</sys:String> + <sys:String x:Key="TabItemHeaderV2RayMkcpProtocol">mKCP传输协议</sys:String> + <sys:String x:Key="TabItemHeaderV2RayQuicProtocol">QUIC传输协议</sys:String> + <sys:String x:Key="GroupBoxHeaderParameterV2Ray">参数设置</sys:String> + <sys:String x:Key="TextBlockV2RayServerPort">服务器端口:</sys:String> + <sys:String x:Key="ButtonV2RayServerPortChange">随机选择</sys:String> + <sys:String x:Key="TextBlockV2RayServerPortExplain">若使用TLS加密,请保持默认的443端口</sys:String> + <sys:String x:Key="TextBlockV2RayUUIDExplain">使用已有UUID,直接粘贴到框中</sys:String> + <sys:String x:Key="TextBlockV2RayQuicUUID">mKCP/QUIC密钥</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpExplain">启用mKCP密钥,可增强抗识别,留空则禁用,要求版本4.24.2以上,V2rayN暂不支持</sys:String> + <sys:String x:Key="TextBlockV2RayPath">路径:</sys:String> + <sys:String x:Key="TextBlockV2RayDomain">域名:</sys:String> + <sys:String x:Key="TextBlockV2RayMaskSites">伪装网站:</sys:String> + <sys:String x:Key="TextBoxV2RayMaskSitesTag">设置此项可增加代理的隐蔽(可为空)</sys:String> + <sys:String x:Key="TextBlockV2RayWebSocketTlsWebExplain">稳定性强,Caddy2做前置,隐藏代理特征,被识别为访问网站的https流量,抗封锁识别最强,需要域名,支持CDN</sys:String> + <sys:String x:Key="TextBlockV2RayHttp2TlsWebExplain">基于 HTTP/2 传输。完整按 HTTP/2 标准实现,Caddy2做前置,隐藏代理特征,H2C协议转发到V2Ray,需要域名,暂不支持CloudFlare的CDN</sys:String> + <sys:String x:Key="TextBlockV2RayTcpExplain">数据加密传输,会被识别为未知的tcp流量</sys:String> + <sys:String x:Key="RadioButtonV2RayTcpHttp">TCP+Http伪装</sys:String> + <sys:String x:Key="TextBlockV2RayTcpHttpExplain">数据加密传输,并做http伪装,会被识别为http流量,但并不是真正的http访问</sys:String> + <sys:String x:Key="TextBlockV2RayTcpTlsExplain">数据加密传输,传输协议使用TLS,会被识别为TLS流量,不等同于https流量特征 (需域名)</sys:String> + <sys:String x:Key="RadioButtonV2RayTcpTlsSelfSigned">TCP+TLS(自签证书)</sys:String> + <sys:String x:Key="TextBlockV2RayTcpTlsSelfSignedExplain">数据加密传输,传输协议使用TLS,会被识别为TLS流量,不等同于https流量特征 (无需域名)</sys:String> + <sys:String x:Key="TextBlockV2RaySelfSignedShadowrocketExplain">Shadowrocket (ios)需要手动打开“允许不安全”选项</sys:String> + <sys:String x:Key="TextBlockV2RayVlessTcpTlsWebExplain">轻量协议VLESS,占用更少主机资源,数据TLS加密传输,用Caddy2在节点上做伪装网站。适合配置低的VPS,或多人共用节点,服务端客户端版本要求4.27+ (需域名)</sys:String> + <sys:String x:Key="TextBlockV2RayWebSocketExplain">数据加密传输,传输协议使用WebSocket,未启用TLS,将被识别为WebSocket流量。</sys:String> + <sys:String x:Key="TextBlockV2RayWebSocketTlsExplain">数据加密传输,传输协议使用WebSocket,启用TLS,将被识别为TLS流量。(需要域名)</sys:String> + <sys:String x:Key="RadioButtonV2RayWebSocketTlsSelfSigned">WebSocket+TLS(自签证书)</sys:String> + <sys:String x:Key="TextBlockV2RayWebSocketTlsSelfSignedExplain">数据加密传输,传输协议使用WebSocket,启用TLS,将被识别为TLS流量。(无需域名)</sys:String> + <sys:String x:Key="TextBlockV2RayHttp2Explain">基于 HTTP/2 的传输方式。它完整按照 HTTP/2 标准实现,需要域名</sys:String> + <sys:String x:Key="RadioButtonV2RayHttp2SelfSigned">HTTP2(自签证书)</sys:String> + <sys:String x:Key="TextBlockV2RayHttp2SelfSignedExplain">基于 HTTP/2 的传输方式。它完整按照 HTTP/2 标准实现,使用自签名证书,不需要域名</sys:String> + <sys:String x:Key="RadioButtonV2RayMkcpNone">mKCP(无伪装)</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpNoneExplain">数据加密传输,以增加带宽占用,减少延迟,udp协议,无伪装,会被识别为udp流量</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpSRTPExplain">同mKCP(无伪装),增加伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpuTPExplain">同mKCP(无伪装),增加伪装成 uTP 数据包,会被识别为 BT 下载数据</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpWeChatExplain">同mKCP(无伪装),增加伪装成微信视频通话的数据包</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpDTLSExplain">同mKCP(无伪装),增加伪装成 DTLS 1.2 数据包</sys:String> + <sys:String x:Key="TextBlockV2RayMkcpWireGuardExplain">同mKCP(无伪装),增加伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)</sys:String> + <sys:String x:Key="TextBlockV2RayQuicShadowrocketExplain">提醒:Shadowrocket目前暂不支持QUIC的传输模式。</sys:String> + <sys:String x:Key="RadioButtonV2RayQuicNone">QUIC(无伪装)</sys:String> + <sys:String x:Key="TextBlockV2RayQuicNoneExplain">数据加密传输,无伪装会被识别为udp流量,谷歌出品,优点:减少延迟、多路复用、连接迁移</sys:String> + <sys:String x:Key="TextBlockV2RayQuicSRTPExplain">同QUIC(无伪装),增加伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)</sys:String> + <sys:String x:Key="TextBlockV2RayQuicuTPExplain">同QUIC(无伪装),增加伪装成 uTP 数据包,会被识别为 BT 下载数据</sys:String> + <sys:String x:Key="TextBlockV2RayQuicWeChatExplain">同QUIC(无伪装),增加伪装成微信视频通话的数据包</sys:String> + <sys:String x:Key="TextBlockV2RayQuicDTLSExplain">同QUIC(无伪装),增加伪装成 DTLS 1.2 数据包</sys:String> + <sys:String x:Key="TextBlockV2RayQuicWireGuardExplain">同QUIC(无伪装),增加伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)</sys:String> +<!--以下为程序内的--> + <sys:String x:Key="MessageBoxShow_ErrorHostPortUserNotEmpty">主机地址、主机端口、用户名为必填项,不能为空!!</sys:String> + <sys:String x:Key="MessageBoxShow_ErrorHostPasswordNotEmpty">登录密码为必填项,不能为空!!</sys:String> + <sys:String x:Key="MessageBoxShow_ErrorHostKeyNotEmpty">密钥文件为必填项,不能为空!!</sys:String> + <sys:String x:Key="MessageBoxShow_ErrorProxyAddressPortNotEmpty">如果选择了代理,则代理地址与端口不能为空!</sys:String> + <sys:String x:Key="MessageBoxShow_ErrorProxyUserPasswordNotEmpty">如果代理需要登录,则代理登录的用户名与密码不能为空!</sys:String> + + <sys:String x:Key="MessageBoxShow_ErrorHostConnection">远程主机连接信息有误,请检查!</sys:String> + <sys:String x:Key="MessageBoxShow_ChooseTemplate">请先选择配置模板!</sys:String> + <sys:String x:Key="DisplayInstallInfo_Login">正在登录远程主机......</sys:String> + <sys:String x:Key="DisplayInstallInfo_LoginSuccessful">主机登录成功!</sys:String> + <sys:String x:Key="DisplayInstallInfo_DetectionRootPermission">检测是否运行在root权限下...</sys:String> + <sys:String x:Key="MessageBoxShow_ErrorRootPermission">请使用具有root权限的账户登录主机!!</sys:String> + <sys:String x:Key="DisplayInstallInfo_DetectionRoot_OK">检测结果:OK!</sys:String> + <sys:String x:Key="DisplayInstallInfo_TestExistV2Ray">检测系统是否已经安装V2ray......</sys:String> + <sys:String x:Key="MessageBoxShow_ExistedV2Ray">远程主机已安装V2ray,是否强制重新安装?</sys:String> + <sys:String x:Key="DisplayInstallInfo_InstallationCanceledExit">安装取消,退出</sys:String> + <sys:String x:Key="DisplayInstallInfo_ForceInstallV2Ray">已选择强制安装V2Ray!</sys:String> + <sys:String x:Key="DisplayInstallInfo_NoInstalledV2Ray">检测结果:未安装V2Ray!</sys:String> + <sys:String x:Key="DisplayInstallInfo_CheckSystemRequirements">检测系统是否符合安装要求......</sys:String> + <sys:String x:Key="MessageBoxShow_CurrentKernelVersion">当前系统内核版本为</sys:String> + <sys:String x:Key="MessageBoxShow_RequiredKernelVersionExplain">,V2ray要求内核为2.6.23及以上。请升级内核再安装!</sys:String> + <sys:String x:Key="DisplayInstallInfo_KernelVersionNotMatch">系统内核版本不符合要求,安装失败!!</sys:String> + <sys:String x:Key="MessageBoxShow_MissingSystemComponents">系统缺乏必要的安装组件如:apt||dnf||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本</sys:String> + <sys:String x:Key="DisplayInstallInfo_MissingSystemComponents">系统环境不满足要求,安装失败!!</sys:String> + <sys:String x:Key="DisplayInstallInfo_SystemRequirementsOK">检测结果:OK!</sys:String> + <sys:String x:Key="DisplayInstallInfo_EnableSELinux">检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中......</sys:String> + <sys:String x:Key="DisplayInstallInfo_SELinuxModifyOK">修改完毕!</sys:String> + <sys:String x:Key="DisplayInstallInfo_ProofreadingTime">校对时间......</sys:String> + <sys:String x:Key="MessageBoxShow_TimeError">本地时间与远程主机时间相差超过限制(90秒),请先用 '系统工具-->时间校对' 校对时间后再设置</sys:String> + <sys:String x:Key="DisplayInstallInfo_TimeError">时间较对失败......</sys:String> + <sys:String x:Key="DisplayInstallInfo_TimeOK">时间差符合要求,OK!</sys:String> + + + + <sys:String x:Key="HdTel1">Tel</sys:String> + <sys:String x:Key="MsgShowTime1">Now</sys:String> +</ResourceDictionary> \ No newline at end of file diff --git a/ProxySU/TrojanGoTemplateWindow.xaml b/ProxySU/TrojanGoTemplateWindow.xaml index ed95f43..406c757 100644 --- a/ProxySU/TrojanGoTemplateWindow.xaml +++ b/ProxySU/TrojanGoTemplateWindow.xaml @@ -39,7 +39,7 @@ <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <GroupBox Header="模板库" Grid.Row="0"> + <GroupBox Header="{DynamicResource GroupBoxHeaderTrojanGoTemplates}" Grid.Row="0"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="0.6*"></ColumnDefinition> @@ -54,18 +54,18 @@ <RowDefinition></RowDefinition> </Grid.RowDefinitions> <RadioButton x:Name="RadioButtonTrojanGoTLS2Web" Content="Trojan-Go+TLS+Web" Grid.Column="0" Grid.Row="1" Checked="RadioButtonTrojanTLS2Web_Checked"></RadioButton> - <TextBlock Text="http/2传输,Caddy2伪装网站,抗识别,暂不支持CloudFlare的CDN" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockTrojanGoTLSwebPlan}" TextWrapping="Wrap" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1"></TextBlock> <RadioButton x:Name="RadioButtonTrojanGoWebSocketTLS2Web" Content="Trojan-Go+WebSocket+TLS+Web" Grid.Column="0" Grid.Row="2" Checked="RadioButtonTrojanGoWebSocketTLS2Web_Checked"></RadioButton> - <TextBlock Text="使用WebSocket传输,Caddy2伪装网站,抗识别,支持CloudFlare的CDN" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockTrojanGoWebSocketTLSwebPlan}" TextWrapping="Wrap" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2"></TextBlock> </Grid> </GroupBox> - <GroupBox Header="其他设置" Grid.Row="1"> + <GroupBox Header="{DynamicResource GroupBoxHeaderParameterTrojanGo}" Grid.Row="1"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="0.3*"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> - <ColumnDefinition Width="0.4*"></ColumnDefinition> - <ColumnDefinition Width="0.4*"></ColumnDefinition> + <ColumnDefinition Width="0.3*"></ColumnDefinition> + <ColumnDefinition Width="0.5*"></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition></RowDefinition> @@ -76,22 +76,22 @@ <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <TextBlock x:Name="TextBlockDomain" Text="域名:" Grid.Column="0" Grid.Row="0" Margin="5"></TextBlock> - <TextBox x:Name="TextBoxDomain" Style="{StaticResource TitleText}" Tag="不可为空" Grid.Column="1" Grid.Row="0" Margin="5"></TextBox> - <TextBlock Text="端口:443" Grid.Column="2" Grid.Row="0" Margin="5"></TextBlock> + <TextBlock x:Name="TextBlockDomain" Text="{DynamicResource TextBlockTrojanGoDomain}" Grid.Column="0" Grid.Row="0" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> + <TextBox x:Name="TextBoxDomain" Style="{StaticResource TitleText}" Tag="{DynamicResource TextBoxDomainPrompt}" Grid.Column="1" Grid.Row="0" Margin="5"></TextBox> + <TextBlock Text="{DynamicResource TextBlockTrojanGoPort}" Grid.Column="2" Grid.Row="0" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> <!--<Button x:Name="ButtonDomain" Content="检测" Visibility="Collapsed" Grid.Column="2" Grid.Row="0" Margin="2" Click="ButtonDomain_Click"></Button>--> <!--<TextBlock x:Name="TextBlockServerListenPort" Text="服务端口:" Grid.Column="0" Grid.Row="1"></TextBlock> <TextBox x:Name="TextBoxServerListenPort" Grid.Column="1" Grid.Row="1" Margin="3"></TextBox> <Button x:Name="ButtonServerListenPort" Content="随机选择" Grid.Column="2" Grid.Row="1" Margin="2" Click="ButtonServerListenPort_Click"></Button>--> - <TextBlock x:Name="TextBlockNewUUID" Text="密码:" Grid.Column="0" Grid.Row="1" ></TextBlock> + <TextBlock x:Name="TextBlockNewUUID" Text="{DynamicResource TextBlockTrojanGoPassword}" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center" ></TextBlock> <TextBox x:Name="TextBoxNewUUID" Grid.Column="1" Grid.Row="1" Margin="5"></TextBox> - <Button x:Name="ButtonNewUUID" Content="更新" Grid.Column="2" Grid.Row="1" Margin="3" Click="ButtonNewUUID_Click"></Button> - <TextBlock Text="使用已有密码,直接粘贴到框中" TextWrapping="Wrap" Grid.Column="3" Grid.Row="1"></TextBlock> - <TextBlock x:Name="TextBlockPath" Text="WebSocket路径:" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"></TextBlock> + <Button x:Name="ButtonNewUUID" Content="{DynamicResource ButtonTrojanChangePassword}" Grid.Column="2" Grid.Row="1" Margin="3" Click="ButtonNewUUID_Click"></Button> + <TextBlock Text="{DynamicResource TextBlockTrojanGoPasswordExplain}" TextWrapping="Wrap" Grid.Column="3" Grid.Row="1"></TextBlock> + <TextBlock x:Name="TextBlockPath" Text="{DynamicResource TextBlockTrojanGoWebSocketPath}" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="TextBoxPath" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="1" Margin="5"></TextBox> - <Button x:Name="ButtonPath" Content="随机" Grid.Column="2" Grid.Row="2" Margin="2" Click="ButtonPath_Click"></Button> + <Button x:Name="ButtonPath" Content="{DynamicResource ButtonNaiveProxyChangeUser}" Grid.Column="2" Grid.Row="2" Margin="2" Click="ButtonPath_Click"></Button> <TextBlock x:Name="TextBlockMaskSites" Text="伪装网站:" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Visibility="Hidden"></TextBlock> <TextBox x:Name="TextBoxMaskSites" Style="{StaticResource TitleText}" Tag="设置此项可增加代理的隐蔽(可为空)" Grid.Column="1" Grid.Row="3" Margin="5" Visibility="Hidden"></TextBox> @@ -103,8 +103,8 @@ <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> - <Button x:Name="ButtondDecide" Content="确定" Grid.Column="1" Grid.Row="6" Margin="3" Click="ButtondDecide_Click"></Button> - <Button x:Name="ButtondCancel" Content="取消" Grid.Column="3" Grid.Row="6" Margin="3" Click="ButtondCancel_Click"></Button> + <Button x:Name="ButtondDecide" Content="{DynamicResource ButtonTrojanGoTemplateOK}" Grid.Column="1" Grid.Row="6" Margin="3" Click="ButtondDecide_Click"></Button> + <Button x:Name="ButtondCancel" Content="{DynamicResource ButtonTrojanGoTemplateCancel}" Grid.Column="3" Grid.Row="6" Margin="3" Click="ButtondCancel_Click"></Button> </Grid> </Grid> diff --git a/ProxySU/V2RayTemplateWindow.xaml b/ProxySU/V2RayTemplateWindow.xaml index d31e552..4085009 100644 --- a/ProxySU/V2RayTemplateWindow.xaml +++ b/ProxySU/V2RayTemplateWindow.xaml @@ -39,35 +39,35 @@ <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <GroupBox Header="模板库" Grid.Row="0" Grid.RowSpan="3"> + <GroupBox Header="{DynamicResource GroupBoxHeaderV2RayTemplates}" Grid.Row="0" Grid.RowSpan="3"> <Grid> <TabControl x:Name="TabControlTemplate"> - <TabItem Header="热门方案" Width="110" Height="30"> + <TabItem Header="{DynamicResource TabItemHeaderV2RayHotPlan}" Width="110" Height="30"> <Grid> <Grid.ColumnDefinitions> + <ColumnDefinition Width="0.8*"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> - <ColumnDefinition></ColumnDefinition> - <ColumnDefinition></ColumnDefinition> + <ColumnDefinition Width="0.3*"></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition></RowDefinition> - <RowDefinition></RowDefinition> - <RowDefinition></RowDefinition> + <RowDefinition Height="1.2*"></RowDefinition> + <RowDefinition Height="1.2*"></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <RadioButton x:Name="RadioButtonWebSocketTLS2WebHot" Content="WebSocket+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonWebSocketTLS2Web_Checked"></RadioButton> - <TextBlock Text="稳定性强,Caddy2做前置,隐藏代理特征,被识别为访问网站的https流量,抗封锁识别最强,需要域名,支持CDN" TextWrapping="Wrap" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonHTTP2WebHot" Content="HTTP2+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonWebSocketTLS2Web_Checked"></RadioButton> - <TextBlock Text="基于 HTTP/2 传输。完整按 HTTP/2 标准实现,Caddy2做前置,隐藏代理特征,H2C协议转发到V2Ray,需要域名,暂不支持CloudFlare的CDN" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3"></TextBlock> + <RadioButton x:Name="RadioButtonWebSocketTLS2WebHot" Content="WebSocket+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonWebSocketTLS2Web_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayWebSocketTlsWebExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock> + <RadioButton x:Name="RadioButtonHTTP2WebHot" Content="HTTP2+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonWebSocketTLS2Web_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayHttp2TlsWebExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock> </Grid> </TabItem> - <TabItem Header="TCP传输协议" Width="110" Height="30"> + <TabItem Header="{DynamicResource TabItemHeaderV2RayTcpProtocol}" Width="110" Height="30"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> @@ -81,28 +81,28 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> - <RowDefinition></RowDefinition> - <RowDefinition></RowDefinition> + <RowDefinition Height="1.3*"></RowDefinition> + <RowDefinition Height="1.7*"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <RadioButton x:Name="RadioButtonTCP" Content="TCP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonTCP_Checked"></RadioButton> - <TextBlock Text="数据加密传输,会被识别为未知的tcp流量" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonTCPhttp" Content="TCP+Http伪装" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonTCPhttp_Checked" ></RadioButton> - <TextBlock Text="数据加密传输,并做http伪装,会被识别为http流量,但并不是真正的http访问" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonTCP2TLS" Content="TCP+TLS" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonTCP2TLS_Checked" /> - <TextBlock Text="数据加密传输,传输协议使用TLS,会被识别为TLS流量,不等同于https流量特征 (需域名)" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonTcpTLS2SelfSigned" Content="TCP+TLS((自签证书)" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="4" Checked="RadioButtonTCP2TLSnoDomain_Checked" /> - <TextBlock Text="数据加密传输,传输协议使用TLS,会被识别为TLS流量,不等同于https流量特征 (无需域名)" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3"></TextBlock> - <TextBlock Text="Shadowrocket (ios)需要手动打开“允许不安全”选项" TextWrapping="Wrap" Grid.Column="4" Grid.Row="4" ></TextBlock> - <RadioButton x:Name="RadioButtonVlessTcpTlsWeb" Content="VLESS+TCP+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="5" Checked="RadioButtonTCP2TLS_Checked" ></RadioButton> - <TextBlock Text="轻量协议VLESS,占用更少主机资源,数据TLS加密传输,用Caddy2在节点上做伪装网站。适合配置低的VPS,或多人共用节点,服务端客户端版本要求4.27+ (需域名)," TextWrapping="Wrap" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3"></TextBlock> + <RadioButton x:Name="RadioButtonTCP" Content="TCP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonTCP_Checked" VerticalAlignment="Center" HorizontalAlignment="Left"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayTcpExplain}" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonTCPhttp" Content="{DynamicResource RadioButtonV2RayTcpHttp}" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonTCPhttp_Checked" VerticalAlignment="Center" HorizontalAlignment="Left" ></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayTcpHttpExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock> + <RadioButton x:Name="RadioButtonTCP2TLS" Content="TCP+TLS" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonTCP2TLS_Checked" VerticalAlignment="Center" HorizontalAlignment="Left" /> + <TextBlock Text="{DynamicResource TextBlockV2RayTcpTlsExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock> + <RadioButton x:Name="RadioButtonTcpTLS2SelfSigned" Content="{DynamicResource RadioButtonV2RayTcpTlsSelfSigned}" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="4" Checked="RadioButtonTCP2TLSnoDomain_Checked" VerticalAlignment="Center" HorizontalAlignment="Left" /> + <TextBlock Text="{DynamicResource TextBlockV2RayTcpTlsSelfSignedExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockV2RaySelfSignedShadowrocketExplain}" TextWrapping="Wrap" Grid.Column="4" Grid.Row="4" HorizontalAlignment="Left" VerticalAlignment="Center" ></TextBlock> + <RadioButton x:Name="RadioButtonVlessTcpTlsWeb" Content="VLESS+TCP+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="5" Checked="RadioButtonTCP2TLS_Checked" VerticalAlignment="Center" HorizontalAlignment="Left" ></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayVlessTcpTlsWebExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock> </Grid> </TabItem> - <TabItem Header="WebSocket传输协议" Width="150" Height="30"> + <TabItem Header="{DynamicResource TabItemHeaderV2RayWebSocketProtocol}" Width="150" Height="30"> <Grid> <Grid.ColumnDefinitions> - <ColumnDefinition Width="1.2*"></ColumnDefinition> + <ColumnDefinition Width="1.5*"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> @@ -112,27 +112,27 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> - <RowDefinition></RowDefinition> - <RowDefinition></RowDefinition> + <RowDefinition Height="1.3*"></RowDefinition> + <RowDefinition Height="1.3*"></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <RadioButton x:Name="RadioButtonWebSocket" Content="WebSocket" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonTCP_Checked"/> - <TextBlock Text="数据加密传输,传输协议使用WebSocket,未启用TLS,将被识别为WebSocket流量。" TextWrapping="Wrap" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonWebSocketTLS" Content="WebSocket+TLS" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonHTTP2_Checked"/> - <TextBlock Text="数据加密传输,传输协议使用WebSocket,启用TLS,将被识别为TLS流量。(需要域名)" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonWebSocketTLS2Web" Content="WebSocket+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonWebSocketTLS2Web_Checked"></RadioButton> - <TextBlock Text="稳定性强,Caddy2做前置,隐藏代理特征,被识别为访问网站的https流量,抗封锁识别最强,需要域名,支持CDN" TextWrapping="Wrap" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonWebSocketTLSselfSigned" Content="WebSocket+TLS(自签证书)" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="4" Checked="RadioButtonWebSocketTLSselfSigned_Checked"></RadioButton> - <TextBlock Text="数据加密传输,传输协议使用WebSocket,启用TLS,将被识别为TLS流量。(无需域名)" TextWrapping="Wrap" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3"></TextBlock> - <TextBlock Text="Shadowrocket (ios)需要手动打开“允许不安全”选项" TextWrapping="Wrap" Grid.Column="4" Grid.Row="4" ></TextBlock> + <RadioButton x:Name="RadioButtonWebSocket" Content="WebSocket" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonTCP_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"/> + <TextBlock Text="{DynamicResource TextBlockV2RayWebSocketExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonWebSocketTLS" Content="WebSocket+TLS" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonHTTP2_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"/> + <TextBlock Text="{DynamicResource TextBlockV2RayWebSocketTlsExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonWebSocketTLS2Web" Content="WebSocket+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonWebSocketTLS2Web_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayWebSocketTlsWebExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonWebSocketTLSselfSigned" Content="{DynamicResource RadioButtonV2RayWebSocketTlsSelfSigned}" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="4" Checked="RadioButtonWebSocketTLSselfSigned_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayWebSocketTlsSelfSignedExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockV2RaySelfSignedShadowrocketExplain}" TextWrapping="Wrap" Grid.Column="4" Grid.Row="4" HorizontalAlignment="Left" VerticalAlignment="Center" ></TextBlock> </Grid> </TabItem> - <TabItem Header="Http/2传输协议" Width="110" Height="30"> + <TabItem Header="{DynamicResource TabItemHeaderV2RayHttp2Protocol}" Width="110" Height="30"> <Grid> <Grid.ColumnDefinitions> - <ColumnDefinition></ColumnDefinition> + <ColumnDefinition Width="1*"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> @@ -141,24 +141,24 @@ <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> - <RowDefinition></RowDefinition> - <RowDefinition></RowDefinition> + <RowDefinition Height="1.8*"></RowDefinition> + <RowDefinition Height="1.5*"></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <RadioButton x:Name="RadioButtonHTTP2" Content="HTTP2" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonHTTP2_Checked"></RadioButton> - <TextBlock Text="基于 HTTP/2 的传输方式。它完整按照 HTTP/2 标准实现,需要域名" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonHTTP2Web" Content="HTTP2+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonWebSocketTLS2Web_Checked"></RadioButton> - <TextBlock Text="基于 HTTP/2 传输。完整按 HTTP/2 标准实现,Caddy2做前置,隐藏代理特征,H2C协议转发到V2Ray,需要域名,暂不支持CloudFlare的CDN" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonHTTP2selfSigned" Content="HTTP2(自签证书)" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonWebSocketTLSselfSigned_Checked"></RadioButton> - <TextBlock Text="基于 HTTP/2 的传输方式。它完整按照 HTTP/2 标准实现,使用自签名证书,不需要域名" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3"></TextBlock> - <TextBlock Text="Shadowrocket (ios)需要手动打开“允许不安全”选项" TextWrapping="Wrap" Grid.Column="4" Grid.Row="3" ></TextBlock> + <RadioButton x:Name="RadioButtonHTTP2" Content="HTTP2" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonHTTP2_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayHttp2Explain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonHTTP2Web" Content="HTTP2+TLS+Web" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonWebSocketTLS2Web_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayHttp2TlsWebExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonHTTP2selfSigned" Content="{DynamicResource RadioButtonV2RayHttp2SelfSigned}" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonWebSocketTLSselfSigned_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayHttp2SelfSignedExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockV2RaySelfSignedShadowrocketExplain}" TextWrapping="Wrap" Grid.Column="4" Grid.Row="3" ></TextBlock> </Grid> </TabItem> - - <TabItem Header="mKCP传输协议" Width="110" Height="30"> + + <TabItem Header="{DynamicResource TabItemHeaderV2RayMkcpProtocol}" Width="110" Height="30"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> @@ -177,22 +177,22 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <RadioButton x:Name="RadioButtonMkcpNone" Content="mKCP(无伪装)" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="数据加密传输,以增加带宽占用,减少延迟,udp协议,无伪装,会被识别为udp流量" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButton2mKCP2SRTP" Content="mKCP+SRTP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同mKCP(无伪装),增加伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButton2mKCPuTP" Content="mKCP+uTP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同mKCP(无伪装),增加伪装成 uTP 数据包,会被识别为 BT 下载数据" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButton2mKCP2WechatVideo" Content="mKCP+WechatVideo" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="4" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同mKCP(无伪装),增加伪装成微信视频通话的数据包" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButton2mKCP2DTLS" Content="mKCP+DTLS 1.2" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="5" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同mKCP(无伪装),增加伪装成 DTLS 1.2 数据包" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButton2mKCP2WireGuard" Content="mKCP+WireGuard" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="6" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同mKCP(无伪装),增加伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)" TextWrapping="Wrap" Grid.Column="1" Grid.Row="6" Grid.ColumnSpan="3"></TextBlock> + <RadioButton x:Name="RadioButtonMkcpNone" Content="{DynamicResource RadioButtonV2RayMkcpNone}" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayMkcpNoneExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButton2mKCP2SRTP" Content="mKCP+SRTP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayMkcpSRTPExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButton2mKCPuTP" Content="mKCP+uTP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayMkcpuTPExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButton2mKCP2WechatVideo" Content="mKCP+WechatVideo" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="4" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayMkcpWeChatExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButton2mKCP2DTLS" Content="mKCP+DTLS 1.2" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="5" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayMkcpDTLSExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButton2mKCP2WireGuard" Content="mKCP+WireGuard" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="6" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayMkcpWireGuardExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="6" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> </Grid> </TabItem> - <TabItem Header="QUIC传输协议" Width="110" Height="30"> + <TabItem Header="{DynamicResource TabItemHeaderV2RayQuicProtocol}" Width="110" Height="30"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> @@ -211,26 +211,26 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <TextBlock Text="提醒:Shadowrocket目前暂不支持QUIC的传输模式。" Foreground="Red" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5"></TextBlock> - <RadioButton x:Name="RadioButtonQuicNone" Content="QUIC(无伪装)" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="数据加密传输,无伪装会被识别为udp流量,谷歌出品,优点:减少延迟、多路复用、连接迁移" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonQuicSRTP" Content="QUIC+SRTP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同QUIC(无伪装),增加伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonQuic2uTP" Content="QUIC+uTP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同QUIC(无伪装),增加伪装成 uTP 数据包,会被识别为 BT 下载数据" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonQuicWechatVideo" Content="QUIC+WechatVideo" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="4" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同QUIC(无伪装),增加伪装成微信视频通话的数据包" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonQuicDTLS" Content="QUIC+DTLS 1.2" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="5" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同QUIC(无伪装),增加伪装成 DTLS 1.2 数据包" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3"></TextBlock> - <RadioButton x:Name="RadioButtonQuicWireGuard" Content="QUIC+WireGuard" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="6" Checked="RadioButtonQuicNone_Checked"></RadioButton> - <TextBlock Text="同QUIC(无伪装),增加伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)" TextWrapping="Wrap" Grid.Column="1" Grid.Row="6" Grid.ColumnSpan="3"></TextBlock> + <TextBlock Text="{DynamicResource TextBlockV2RayQuicShadowrocketExplain}" Foreground="Red" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonQuicNone" Content="{DynamicResource RadioButtonV2RayQuicNone}" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="1" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayQuicNoneExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonQuicSRTP" Content="QUIC+SRTP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="2" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayQuicSRTPExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonQuic2uTP" Content="QUIC+uTP" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="3" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayQuicuTPExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonQuicWechatVideo" Content="QUIC+WechatVideo" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="4" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayQuicWeChatExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonQuicDTLS" Content="QUIC+DTLS 1.2" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="5" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayQuicDTLSExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> + <RadioButton x:Name="RadioButtonQuicWireGuard" Content="QUIC+WireGuard" GroupName="TemplateGroup" Grid.Column="0" Grid.Row="6" Checked="RadioButtonQuicNone_Checked" HorizontalAlignment="Left" VerticalAlignment="Center"></RadioButton> + <TextBlock Text="{DynamicResource TextBlockV2RayQuicWireGuardExplain}" TextWrapping="Wrap" Grid.Column="1" Grid.Row="6" Grid.ColumnSpan="3" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock> </Grid> </TabItem> </TabControl> </Grid> </GroupBox> - <GroupBox Header="其他设置" Grid.Row="3" Grid.RowSpan="2"> + <GroupBox Header="{DynamicResource GroupBoxHeaderParameterV2Ray}" Grid.Row="3" Grid.RowSpan="2"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> @@ -251,31 +251,31 @@ <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> - <TextBlock x:Name="TextBlockServerListenPort" Text="服务端口:" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="1"></TextBlock> + <TextBlock x:Name="TextBlockServerListenPort" Text="{DynamicResource TextBlockV2RayServerPort}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="1" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="TextBoxServerListenPort" Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="3" Margin="3"></TextBox> - <Button x:Name="ButtonServerListenPort" Content="随机选择" Grid.Column="4" Grid.Row="0" Margin="2" Click="ButtonServerListenPort_Click"></Button> - <TextBlock Text="若使用TLS加密,请保持默认的443端口" Grid.Column="5" Grid.ColumnSpan="2" Grid.Row="0" Margin="3"></TextBlock> - <TextBlock x:Name="TextBlockNewUUID" Text="UUID:" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="1"></TextBlock> + <Button x:Name="ButtonServerListenPort" Content="{DynamicResource ButtonV2RayServerPortChange}" Grid.Column="4" Grid.Row="0" Margin="2" Click="ButtonServerListenPort_Click"></Button> + <TextBlock Text="{DynamicResource TextBlockV2RayServerPortExplain}" Grid.Column="5" Grid.ColumnSpan="2" Grid.Row="0" Margin="3"></TextBlock> + <TextBlock x:Name="TextBlockNewUUID" Text="UUID:" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="1" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="TextBoxNewUUID" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" Margin="3"></TextBox> - <Button x:Name="ButtonNewUUID" Content="更新" Grid.Column="4" Grid.Row="1" Margin="2" Click="ButtonNewUUID_Click"></Button> - <TextBlock Text="使用已有UUID,直接粘贴到框中" TextWrapping="Wrap" Grid.Column="5" Grid.Row="1" Grid.ColumnSpan="2" Margin="0"></TextBlock> - <TextBlock x:Name="TextBlockQuicUUID" Text="mKCP/QUIC密钥" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="1"></TextBlock> + <Button x:Name="ButtonNewUUID" Content="{DynamicResource ButtonTrojanChangePassword}" Grid.Column="4" Grid.Row="1" Margin="2" Click="ButtonNewUUID_Click"></Button> + <TextBlock Text="{DynamicResource TextBlockV2RayUUIDExplain}" TextWrapping="Wrap" Grid.Column="5" Grid.Row="1" Grid.ColumnSpan="2" Margin="0"></TextBlock> + <TextBlock x:Name="TextBlockQuicUUID" Text="{DynamicResource TextBlockV2RayQuicUUID}" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="1" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="TextBoxQuicUUID" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" Margin="3"></TextBox> - <Button x:Name="ButtonQuicUUID" Content="更新" Grid.Column="4" Grid.Row="2" Margin="2" Click="ButtonQuicUUID_Click"></Button> - <TextBlock x:Name="TextBlockMkcpUUID" Text="启用mKCP密钥,可增强抗识别,留空则禁用,要求版本4.24.2以上,V2rayN暂不支持" TextWrapping="Wrap" Grid.Column="5" Grid.Row="2" Grid.ColumnSpan="2"></TextBlock> + <Button x:Name="ButtonQuicUUID" Content="{DynamicResource ButtonTrojanChangePassword}" Grid.Column="4" Grid.Row="2" Margin="2" Click="ButtonQuicUUID_Click"></Button> + <TextBlock x:Name="TextBlockMkcpUUID" Text="{DynamicResource TextBlockV2RayMkcpExplain}" TextWrapping="Wrap" Grid.Column="5" Grid.Row="2" Grid.ColumnSpan="2"></TextBlock> - <TextBlock x:Name="TextBlockPath" Text="路径:" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="1"></TextBlock> + <TextBlock x:Name="TextBlockPath" Text="{DynamicResource TextBlockV2RayPath}" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="1" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="TextBoxPath" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3" Margin="3"></TextBox> - <Button x:Name="ButtonPath" Content="随机" Grid.Column="4" Grid.Row="3" Margin="2" Click="ButtonPath_Click"></Button> - <TextBlock x:Name="TextBlockDomain" Text="域名:" Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="1"></TextBlock> - <TextBox x:Name="TextBoxDomain" Style="{StaticResource TitleText}" Tag="不可为空" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3" Margin="3"></TextBox> + <Button x:Name="ButtonPath" Content="{DynamicResource ButtonNaiveProxyChangeUser}" Grid.Column="4" Grid.Row="3" Margin="2" Click="ButtonPath_Click"></Button> + <TextBlock x:Name="TextBlockDomain" Text="{DynamicResource TextBlockV2RayDomain}" Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="1" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock> + <TextBox x:Name="TextBoxDomain" Style="{StaticResource TitleText}" Tag="{DynamicResource TextBoxDomainPrompt}" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3" Margin="3"></TextBox> <Button x:Name="ButtonDomain" Content="检测" Visibility="Collapsed" Grid.Column="4" Grid.Row="4" Margin="2" Click="ButtonDomain_Click"></Button> - <TextBlock x:Name="TextBlockMaskSites" Text="伪装网站:" Grid.Column="0" Grid.Row="5" Grid.ColumnSpan="1" Visibility="Hidden"></TextBlock> - <TextBox x:Name="TextBoxMaskSites" Style="{StaticResource TitleText}" Tag="设置此项可增加代理的隐蔽(可为空)" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3" Margin="3" Visibility="Hidden"></TextBox> + <TextBlock x:Name="TextBlockMaskSites" Text="{DynamicResource TextBlockV2RayMaskSites}" Grid.Column="0" Grid.Row="5" Grid.ColumnSpan="1" Visibility="Hidden"></TextBlock> + <TextBox x:Name="TextBoxMaskSites" Style="{StaticResource TitleText}" Tag="{DynamicResource TextBoxV2RayMaskSitesTag}" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3" Margin="3" Visibility="Hidden"></TextBox> - <Button x:Name="ButtondDecide" Content="确定" Grid.Column="1" Grid.Row="6" Margin="0" Click="ButtondDecide_Click"></Button> - <Button x:Name="ButtondCancel" Content="取消" Grid.Column="3" Grid.Row="6" Margin="0" Click="ButtondCancel_Click"></Button> + <Button x:Name="ButtondDecide" Content="{DynamicResource ButtonTrojanGoTemplateOK}" Grid.Column="1" Grid.Row="6" Margin="0" Click="ButtondDecide_Click"></Button> + <Button x:Name="ButtondCancel" Content="{DynamicResource ButtonTrojanGoTemplateCancel}" Grid.Column="3" Grid.Row="6" Margin="0" Click="ButtondCancel_Click"></Button> <!--<Button x:Name="ButtonTestChecked" Content="测试选中状态" Grid.Column="5" Grid.Row="6" Click="ButtonTestChecked_Click"></Button>--> </Grid> </GroupBox> diff --git a/ProxySU/bin/Beta/Beta.zip b/ProxySU/bin/Beta/Beta.zip index 167ef8d6d9c776f0e73a8226a4c43d97cdb9f008..2e0365f78547953b85f6d337b0bdc5a616928920 100644 GIT binary patch delta 57504 zcmXVWV{|6G^LA}pTVrc(x3+DYTi>;NZ*AMQZQHhO+y8xj@0%0MT*+jT4>OZ<G96Wf zJLiOm3ew;Z7$E<Z)jWJ(#6U#QKt!-cMDPh=<bQx-=f0}8`trY75s2gyVQ?Z~^<|>Y z*ioOZhkpQ>D>So^OrF6XI0y_;R8SHajX%NYHKIm>7oeWiEA4rFp4XV3(A-Pr*N~sA z_4VA%?XB$t8#Y;#jP=jQ({`-)<}Uw=+1P|KWI8d73k>j^9>x{+p;}Yo!xbZ-qRz7} zV1091eZw^M!)uTbnqWn(ivTG4EPkJqG@adSt?4BC+66y8J7#(a%|J`keBN+ZI133M zY-Z*GHOf*Hg&i=8l|JJ&_z|AE@f;{c(yv4d!@o`(yGJ+z4nGbF<6`|IuyV!rqxcIh zc@0*Ncy!VVf+YB(y!%D`Qya{|6|-a`m=ecyj=^pBm^xec4@%oD^b@ePr38Mj<0Y3C zi?9vMhv<Da$ihOek_)v`SP?%B`9>K1phMnoTi=G+Y4V02gI)&>Qi!oJbqvpVc`kA` z&E0~qFjZh|oCM?B0<}XQ&JS{r3{num#}bnPQ9Hoo8;<+$lAf|9Z`j9@wm&#TuQ6g6 zaXHjnxTS8NGFU7l<Svl3>6K)YObq;njI@U?`UqTuJ`V-D+7QqHq7S!=M&~CjR)bT; z=UK(80VePYRZI*4=JR4jJIH1VxINPHKjcsXO_pKSg5|e8-s<(e(Pnp4)TQKtE`WwM zlubXMp$w@p$tGJytpEe@4wEbcjXUKr(!j{~2lZ(lit`_55C*OQx_3|ycnB>>REag$ zFBOnxiKk46$<$$xKu1~^!4wb$9Q*hE7=A)lOPhPZFvQZ-@J1Nx5yN@TB8L_J`jaE- zyBIg&6d&j0NO5{3HMeFPZa2lFl{2MdjtxnJ-K>?z2fc<wX9($>Cd%+L`y@%E3^Ox7 z1usqV&Wdh1@f^5!&_?0PA!FL!SjTHSN;cl57<);n+P=Dv6mHvU88AE8KurMA3uRgd z<|qE7s$Z#!6L4FQ)kEyLqGXI%(TC!JF>ur@3J}yB+);R`yj@%is5jBmHn_e;@*SHB zQa~_-37|$1QY`m|R0%Ro#B2t|s=Y;RCxG1v0ViE@aR6@8tl6s~_3P=uV+V?nvym3s z56m#7YrdZqeC7s(RVc8ngA9gQ5a+=~2DvpL?Wum9G^KcQ$gRg0H10H@wn&Pe*UJAD zZxNJkJlW)-oR`%iSVNz;hF0J}zcf}YTR4wm|4C1#zH`PNa*jm~!(g2*dgVqXhcTog zw4i>D0tY0y>S-cGyj#PQw9l9OE80!J0-<;!<+r}CucUvFMF!^0kl+D;?jfo<qaL9T zjUt~d)^x%M<?GMmjytKRTa(F~u08pK=A9)v9CHFs$CV`VJMIq?I32MXb2i5;?Y7;F zg~1CAc1*2pHN+ooH6tJwc=9rb06Wq>h($Yo%op&)O=eLK3ebh1?g&7H_5>MnM}eP? zz7k==ML;*eVeCI(mBCW;hAm0j=j8Ay#7hQzu>Hy!C&yrhbx+wdOC-(N{b@n~8Id1g z7)Bk`^L0PFSpm_PZ#sAl2vhx4wuYSG#sqDm;g6<+&n^hcnwouX;*%^;gokWa&LV$c z@&!y%C|Xa7m_W^t$(B7S$|S-W`{*eht2m)Z&CHmn4V(C5l*$R~^b&%k8sF%Rb3D@s zw-M8;$uzyB%gD^|$t|jSG-f-__SEs3G2z@v&YB+Y-Ys`D-;_1dv79@$Q8JQ|q+up- zX@X|88b5z0$f#+%Yoc|bHSX=wDdSy?z6|_*SCa&PQI?b!pcS<0S!4=PT*#c86w13$ zH(O-6N}rq5L}<wwGe4KAFmB4bV6@+$ldUj5&%59dtGZYxS$vqTcUODKLElZWFsDr9 zIhtoV3OH$ah>NB_YDgge4|4=)iBbMXw2LS-UX=Yw9cy@qiVk#<@Or*@+X4n+8MlYs zoTNvP4dQVH==4w6d<Yr{k9gU_oXRr=5I_I~f}kA$n9#_BVN;-@vzd||I<Dd+Js9(% z6hw(>f>g8{oGB(?3>zK_mG~4$dkBOhy{d2#a+r%oH|2vhf+mB23@rrRh=R}B!5p(& z62;Ly16?ftG&-bN6VyfyRp2;Sndv)sD*q3X^uz&>?dkN!vC<UGxm3(0Od}EQ9pocp ztEr|YY=9OVXN!a{ZlZp!(k>|it;!$)5EeRlXk_f*rJjR>TTG2|ID4>nmANjA^9v1$ zLDk@`!U{VpFuekupMT4D+=nz(T8O_r;PAw?1%hg~cms>2u>o`M0mw|lg^S`9cQPc2 zD<;WFK5CV4KqaXuCRs=>$s$!oDcSl)9!1zj@|2@Xm8aFGXhdEC8#lwzQZk~zyZ`ed z%s=A(L6S(rUMWj)4zx#9nu#lLxXz74hXqWpJf7#n;Zwb2<xFJ!FVa!1ORrG*u26`M zFRq>wL@kuKfBW7-DG(6KQ!T2jc%l=5dAgwwY9OIS=^X=@cPVAbI|m_OTXP{(R%@fm z2$2SB+5}y@NW3sCHYs)#^AM_Dl&x0@;XZz^*|BJ`9fO&m{Y;}qyvk)BJ`80ZCgD`z z%L(!MYsLA3i9{Ha+ehVildFg66Xm~sw1b;U^ML{lU9a*&14PP7wxRphL;9wJo*q@) zUFUph%}5CnD+?{OA+f*>vgnRyt2WfC8dyu?t4t_3#3@>gVH;(t%qlp<D~cqsa1XNZ zl+Zn{PAtI0E2<>6pkTI`_$Jr^BAHG(aAc}i{FR3Ni1O3t8Wg#0?xBG119!n?d=A70 znG!u>84pF{0*+c?TIBPn9^e&9;1`O{|IGBo#r;!hvhcI<4^3HvBU~2mLq1|mTNe#T zKWLGMw<@29p8<RiF{XA%7Rd@Jj#SBt(F0g-(oI7z@9tS4{f4L(N4?N?AM0k-$yM5^ zemT6u<eCkKx<xaDS>D5?n&fP=cDsrCI(^UkVcAVG0kET3K5$#juxfH8ceCs!)SZUM z_AeZ8toOby@^E8(H~Br%!dBg|)jJ9Qr9{^@8#Bm)42+|4j>(2x62CxJ`CYBj?i-;O zan}xpaH`q7Us&KrK;x3eHlNb%WiM3M=AO)4^D`XID|=4--6cs-7w^hUvww$OHNr?2 zFGrM}KM-^C{t}Do{<0q|%nm&zbnczKfc$*@H<U^XseWMe)OD8KckDKIm$!;w-Tx$@ z_g|i3wr=(LAqsA{%?5$OP+#e~DFxq1)NFV9^l4!<j;zpx`aih=DXu%_Dd6I6&^~^g zfDqT6&X9mO9Bb+@ql&HA-V9p~7A^G>4o09aZu^!y35DjdcZ))xI9BP+A^`z|+=bJ% zJsT#)D3`&=%qV-pP6L1dI)dCu0Ny?OwRy)ylV{=hsi~v0GO=ZiMH|4yAXZ*U*@6wy zbb>%<Y4?^jMm<r;N830#5c+!KV=Lf<#n8J7pdJsu0_Rtq<pf-&gyU-8ni6(hgabDd z<+j6TUr}oF-=z}D++cckz^reCD&Rggg|^P!Yr2)OowfYmd+nTi>Q@ynpRI#}RUW-_ zrl~ki-UZ5UXa-pS%HPk?@kqQY><BXYX)(9(yI20;0r5$&Kns-Q{xeD}BL`lDnAca( ziSGs*A8tO!dyTxn-Ye605M>zVy$#eU?yws|dCMEP@xG^0d-T3Xd2tpP2~>b0LC8hz zlS3&I{1aG%(YK2d6%3#Z7$@F<*wurP7j#4H3r6Yky`g%7Ztcc{$;IlEfQcu*fHVXR z@F#W>;K1!`MX3s?0qyfg$@0I!3ZO^vshL4yLKhOoVYu09gX?Z~8E0%Ow+9aNi?h6h zs7E0T#mewegv*Z}DLcG`42V0p6B1>|4HqNqkojcM^%Ni6$AV>5#K=?ckqz=_!e%Rl zkySX2xz#!FDfNoexPyYfCJ1^-VKTO*QQ=RB`+1qbOe^;n2fRq6M2ol;3Li?KhzH%8 zG=AU(+l;(HI&9Kloi8yi3<4{#)`BXqX#AcWP+Jm{8<KZh?08V_>G~qc8#E#qpbSJI z3d}idgv~kgr2zzjJZ%{B^!<^)RSxr<`a!Z!^-hDcYeaybHi|OM1PoOtf-Tt|rjA)w zru5{m7hcV@a|=_G?s<YVS>bt~4*4~cq$JT#<8goySd5{|7lYpoh`_k$%RR=P*pm-% z_xjE*lJQ7$4*b3Pgb})KLo6`tURukEuGzp<{Qdf7jrC`e=O66x!q=pFY^5ri2IN*Z zt0_T3^z&~)-l26x2X*R#7x-ctP0`a10(Vc5muq}sL8vlTbZdA7A^Pw-rvphBF&Ve_ zA-5ql5fRgMc6US7D!_<f=G6(DB8Kq~E7Wx+nkvLtDXaI87d67vjzm}Ob{o@=IOJHm z3!LqqoC<H<3>M3m9$$)I&su>S+x~E?!7EH$hJg$JSnG?f#9P_}FYc+nlmnUre>Y5) zL<zif1JDAxQ6qKF>h#)p&Glk*ce-a;tS6z)6be*&{gs*|p#7)?^<D!)J-$V2k6Fo~ zMxLpcgBBhqJvw4z1k;j|RKrC=M$#q+y-ko7yB1>OhUuV|i=3P^Rq-K<Fg-M$)oSLS z)R>H<b544Be9Kx~tJg8VMwy6e)07I+_@!Y42t5G^IVrgvJLW4BIsh8#N?b+{0`xJb zF3d+{$5TcIFrx=e&OjR*teOO@cmNwG2{P&cLeGqjiEVzZOWI-1<*<NvGmx#Ch1}?r zDUo?GM|!-uNj_Y3Twbs6j*&2&Gr;)P6`l!e-sP_%L~>l)Ai<VCnoa&ShIvxmvS2Ey z)&S|Ql&*dlQn1JZXz~f1wGd*Vz%W=)T&eua`6%laP~8oYxz=3%D)Ph$X)D~{9B{Km zz!UFpZhvEqv=!`s47kxjvQ^#Lk;-t^Dr)Uh`(|gFD1>Z8*I7dfl6FUm_&Z+AM*}k} zd~^S+65IVMtSc@_{3^JvmP>D!KF)l1`J@>K%~a@kk956M{eE%t?n08&DOS+k`*pt7 zJ%hmo$Q|v&5dHP7(3Q}3uKf6@w&C@v*~P}xrt!F`$x%7Itbcu6-_18UUMzc~vEUhE zx%~f*Y0!eaA*^xsfU#lt=QDZqk!U*#Pk8NAcWx~p2PELe&Lm&FNm0S3qIW+^((Nkg z_644rUNI@wYIgyGiv)6OJwcQqj1bEH7U;!TiO13afOJ(Y2utHUd>zYR37Yv;800v{ z9def8P-!OTP8aY=l7X;m22(BY0x5+0vK)nSB+NnB_lUwicHaexlWK=-$PloIQWbPV z7hp&H(o=IuJmCi*4;Uxmf!$SwArb(r2>uRWfiWhL39La5$S0`?1b_xu5%WOr0_kD2 ziQNct(EEsC(23bDu8Hp_Np;k1Xyv(rZVUDSU-9LrCQxxY&0&J3P<McqpKOl-MSKjC zE&*oTQmi8>MZPm^3TZUPX<|b25*B5V7HKfD=!Lk}GWEQ<t9(@%KVT-2>}?1o|A;B2 z;TfkX2AHXA+^xpWTu4|1;mot41JjOL+QiV)X6>CLN!X0{&hVuF3@N3>Fi&y_u`)1B zx(TuV(<T>SR@}nIjh>ddKPN-XhQ2o^L(Yc&k0xb{-<xYdNlR*Bi-(;&Xkk-^nM`P5 zYez}bjrfy*4cC5mjZ*ZlxsYwND_-TEaYJNzx@LLeO?N`?ZuvU|M*>@)4_b@wH#||V zI)Azjq<BJo>zUZ;Ey(CC(2-hVVg8!XSg_9WB+Bwc+RYMfwTf&#zT2qedFJWkjdoBU z0MN3%qosLM%bFq}wl^*iOzADM#Ui(3fiUEB$(E8#uPVYnd>?c*0F@k516gu?@>uY~ zDPcbS-_d%gK6m&OVu72B{+=ZqN29!W_XiBq!ZDzQEU$o^r3pwAv;c;v$;KE-lw~z| z0Vgza>8ur$F#(B^)wM1rKJQW)e(?iJ-DH$P>$?2%+6iCX2-B~}7L!n0oxbU26zw5O z)9^-b=HGrgeZA7u6$dt2zYkt9-Dx^h{KXFyz8u^KqKac!vVeUkW%R5B^3GZdw<=g4 zTrGCJ=41P%m?%*}0Ez%a6vBWT)Brn@56E0F6E?Q~z{do52{Ii4d_#YGySA7ax&pSy zq0UnuFZCM!ZNVQs#RMa+XyG9nqAFJ~`wV8x)13jwdQvUPN>?7nSEf9!3CDVJEy>DP zyF)(~1OtwUrGWLi2#DphPdaQurQ_^{49q5?R*7Q>P5Vp0_$~*k#z?ST)!83Ac)Vb) zDl7Hsy9Iqwn0I{G2gxT6qdo?c>og1lYR)^2+Ltj=%<qO1u{hvy3CIJ;6#AbRB3!e^ zM%;>4@Ag^)TJ(D&g%&f5VZCOgr%HLbm<FxXI>n+o!a$UJm4QmFuywZSUe`acR|{b+ z+(~(6e{OzSpUzffCJ3z_?ArZm5>RaZ;V-?$u$EuWJX`xx2c<06EFRsT=)j}X<h%y{ zH}N&y7YK4yEC(Wk`G(uPhJJcQLgl<_E;Lz9GM*%-=21)<^GG*xXRJB=w>4{rnxhsS z-a;E*oe|jR^`k2zjIlWOml+AH-fMQ0U@&}=RkmP~?Q9{aw$ZXhXh{bFBO4d`@^iSG zX-12xP9*ORUB+)ff<h6u5>4K!KoJT-ISEWKn@danu>s?P;WULe_GU0SX+jf>UQ_p= ztF?{MyJW#Kcl5%7q|UVmTrhuNfA++#{LxJ&K^HK-zxwdTit~dDsXMAadu&(!@TS=D zWuEiHg5Zk{2?!O;FWg)InvIFocI9`(*>kvEeV{*>-S?k3mE(&X()Q@?vcpRwfzOX% z{o#44l@L*7A;|<0nNbP`5|pwON?K#TpL&>OKh<uF?O#|qK5*f(CS+w)KCU&U!i+i3 zflGjwUj$!&<W6Rpx4my24%q_b4*At~lbvbbR6g)BH{9zs5|X>bvWr;aem<l~N$KE< z=ts?f{q6^`KrT1Zs}_UOT<11oZe4oHH)7hgb~5C|uRB(Cx5Oa1Kxfh$dUevgQDnwQ z1tc5$T#v)NbhP3Q+*2^N_yk?NVK$KF1F->N*`bOPFew^D2+(R&WUi6y!rDd$EMTHl z{n!5Mr?;@8+;Cn-e;8YcsEQCkOb6C{gp9_#avD&<qm)BGhX&S#jtk4X<ZNs!F>70S zDcGCk3>29w(7dZm5K=%pwfpFN6N}F)c!af=4I>kahqX@4=-`I-oqF|@<CGmFfwr)O z%2AZj)V8BrE+jq-mhCXlb)#+)nYB3r$Ch9cQBC2YJ<=+*q(9ylNA7!l<bMY9q=uTr zXFM7i1c{S}G(y|97gi!5M=?;4NpkUZqO2M75eEMYJ1DblXB13mVgbs;ZD*zk&HGjb zAshFKv>37vEJ^mSyQyVbk8m@iz@2i4jxw;G<%Q`Gi`S%?l%~t7XCh}Nvd8g)y1D6y zgfrKjQV>{?>l~@UG}FYoUx>%I?<6PgS4!?3;JDL5<+Dg!n4qb}&N+Scg1f6h`=vFf z4=d2rJkSV6JU~sAtXdD==~A9Y)rez@DDy16=|WYw>1nuWO@e8u&aBZzAl$U`VuU&2 zaJ^jh@Gp&BPA{hYPymmswzEf<lDi8mOV&0-;;~PsO)~^$Rwdl@KEbq@{|ADi8^e!2 zH#zhOmq=>U*H^{ER6Vl$04>~p-M?YB*!?#Wk$o|kMhN{l{Szq0Kg|%}h2Z+>BS43? zhIeb9JwBFB9ek~0Tp(RufV8Lge$sBZM~Lt_nR8gT<{@^dgq{yH4()@{9*~)QbLuO* z{`k;dW@J^-dXe}MZVR~wrH|GvV+Z0pvwvme(3s?*DdXL(O{BXKs8;8uaXX=o_faf+ zX8>AsKfe*GmD{ld%3MS}7V^vmrWJ$9hh0O)j>%D-^G66vD49HXfpm6ysHJ(hz~2?u z;F%`fy|T|e39J-l5e0=#C3T{wibWnEZPZ4Vg>Jehiy<2sWSk5Syy0wWS{jHL$cONO z8wl{@WB$v61qH7-zOk3gY?G!`?PG1F6Mpz}HiCbsRX-d(F!B}q0}iR<r#KJ&42!r5 zUF3M?FZqdp4;1XXz)YIiUV|S7Gm`yAP0^zAg{4ki?9EPo^P~N^cS}#8tOmbBx(tFs zC?6nMGyX{GGxY~fUBR36)aM<f(1tov9P5lO;#~<u|J8Ib*6ozl!YlWR*5HACi=<U9 zRjL#JIFXwHEEu{~+~Wly4fh|7#(^t+DJhMeX-H*~3yr;S0h8*w<Kh@O$=pknC0jEJ zC9aBQ)kenVor{(jJ*uM+(b;#d?|>!JhNF44>uHIaY|A{0`qt@vEY5k^f*qE`7B!K! zAG$0qEoC7Zi2FSCcU$%xPt4x{Lr(Wkn<&&0FE=>azvsDa8^PPhx$i^f$7aK;zxl|1 z3vX`g-j!(I09|w5cBNcBUD8;D+t>Mr1&aaFG^#EH2ms?k=m(xeDc+45yK}(&8hDU5 zX9*ynMkmWfWD%!|z0z4Bo}5}d?!;uC)M+fFVL`YAJTsk8_5^nZot2gu21}G{Hs!5r z%lS&%&UU%AfR7imp=qnZf$}RmT#soLEIWa=`Xk;82=S+F5XswU%BAMamR$$Ve|g^` z&1PL;*u|n0y|wUz53Ztxjh9AqigECG`z2x2-+{}0XIxnR?+>M{Z!gyLfh0Zy|7Os2 z1%o0)B?fi%*0wf0fpg2ht%nVT$SVS8mVZl~1Euii=6r-56_jay<(8HvOl?L*Nf#2n zs^DcW14FAUXAlL_9B%w%7}KgQ_Pv>Wn1G$V73=6}Gk?;~-er_G0i+C%M1uSagDI5C z!6y?Dkd*0$dNv%h_Ohc*3AAYwb!fZ>S!d0%%Cg#H*|Gzoj?KT9MNL`5WZC;W)&v&U zi*J?&H%VRBwi@V=R(jbMDZ3BUx6j1Yaxz^Ffbn=BMKyDW(7o4|xvApHr6KoKzm8OI zZH`I_Sy|`{(@l}LK=}E(5A51ew`J}8#=}T@&fq0L8@450ci_IM>p`$Pan(n1{}#+h zLWIduLi>)0SI)#U+oB>wu}4hIR0fAfENA~zTuwwKok!!yuINPEDpPHgLshEOKEk;@ z1*$JyUWyz?N8oD83{b>xCqmlM4Bpg(nMQ_Dqfqk?<t2KAFO_29W_+b+I0G>JEj4{H za4_CKJtpxZ$MW#g#3_n3buT$uxmnUTm?5d<W6JlO&k68*VFL#6%zok}(JK6^@0KXf zdGTs{;tJhUfOG{RcP!s?8mGgTmmJ$d2gWrvbLTDLYf7*~7HbD!OF%09^&x8WwXM(v zA+pAtL2e>G3Qox$s$lO+rhq#3=K+JZV|D8I@la_HVms<EP<;-DmksEhJZe+4I7ND& zvi^q8pUAufdL~%BQst-9x|*EFV&@LK%19puALTzQm0Ha6`uE0rPnu!Utqt)k0&OO# z=`?I>R#qpriqbeorF36{%@zY$#fvGvclszw7aC5J1$X+mi<KbNQ=y~SC-v<JD!US! zBbi;Hc2jE2Fu@=9L-$jNn)9gll{6lAI>VKzfy%}dZr6wV6Et$p0n=F<!6p4B5pxlL zR}^X)uqRw1<PApw*SeRo+q;q-z_MGjM6|bAo<&z%<FvD)%n7B<n|Mq@Q36?$F|SYy zvmC^u(yuMHMa1B}<Rhbb!Im3ZSN3s)1<R~6=}G0!Jd3i^%E#l(Mb3>5SZgHg9*n2Q zI|ADR7=kLw#ITlFoqLG-G0oq|i!G?tjrvJN5!)tOL$hO{MWtN>Jd4liz+$a5leDwi z___V5_w*#u%@xiIF?s)AoKFg!YeS0-sPyEO3cu5kxMy+65xql!B2=RowUuj@<8}3= z6QJ>nR6VmG;6A?Y(|^%Ze?fZp;I*xjW#Zdug?DdR8y_V;fZoqc#?Q~==}8t6KJ=T^ zuW7yN;?jkK7pIs8nEl1j1BPi871XpWTH3f_Afp@=isN#T7kVUwT|5_Q*l8s&*unh> zV~~iZe0afl0;#pIWN*2Vx0vHLz^=DUbgaBB!tGVtFZr=Jr#q)~(~z%~sbp#inw?C^ z`?-a&FB?90C_AILnf=cz&Fdyaomqa=nj0)XoLm}n=kzrHlr|W-0FI0FyZl;Y(oafQ zeL>6$o)9v>pz+k3H{&657fdTVlAD(TiA=FfJ1hR@2yQZn)tldJuQyAnE394!Pu5k& zitE#U0-G_;c0Qb$GlnFPFQ#*Dd{T(V1=W?YqypC#6GW9z@w&7(78B52ST$r@p^2T# zw>^GJcbnbm!|Bv$16`MaE<jlFril!S7}#IW2Cyc-O`ZU-CPIk3x?rn_y_=d~sS4J2 z(!}i~V{Whq-nLB;bs98DVMa*;Sp9j!My9YPBm;032=wyG*^W?paV=<ZYjp{e_P;No zT`kNtoRqY^D3l}{K+&^1)9bRSgmrz}<8%`%7x8YUzUVIDfxPZZSG5P&4hM_vtao5R zX{geKT2p99i}QLFxj%-{vgYQy%5x{hU*}hD6pM0ERXFJbA8T;!ba>umylnpxZ$RsM zAbs#bck6+ED}GF>0`Ne+%D$VRzIUz?eD<$uU%Gd^il1|Rep}qo5`TcT49*KQ=6uly z?tpDb!PMvO0cm^nI(|FA@4(+~jSP=_l66mAMt(pAt>6CI6K#}QUF=b-qH^j?ELTvW zh0B9DUfp&4=^|-5i)XXt0iqQrm8etBMey(-AVjq0wiwNjh1FgRoB8ct7R>3%ElXi{ z2d(nKP%2BcpET&LwCG#m`LlXo`dLEScf{G1GNZ3I6}Z&W1M94rErmV<7E@&lN_$Q3 z@Gk(KIe6D%JG?4*sN}gmGmYQRXnLj<tsOiKT}pa^c$iK<EId$I%*}tpR>Y_+rdiAt zEzSU+PiR;4YDBMkw+25S^h+OpC-81o+_Bqh5sDTU*T}T8cdRwcQ2;34CUwBQTt=^o zCQAw6fQ2QFaE1cu<}l;FTZj~qK9m4o2r#(Vmfs?No|ezijJA3~`Z9@EnOT<UHO-oZ zW^KbYZ<ad#?cF^xD?*tIF($|i3fbY}6Ef1GY;=8$2t|`BZ#%y%=H7XyJ}gcZDW4y= z_bT+*(UaNQfMyp_kJCkqXp<k&!VV|LKmy%q;CD>}quU+FJwMXtM|6JpD^U`lBub6{ zyB{rU&munM+rGg4%bX)KTN5T1mavv_G%7PY6+9ObuxwU-&$`KRZ>fEmsty7_=%#lp z;;wfrYpZumkI>v*n7u5R?GIh$fsbZ#^8<{13hYMra#U5X!6WGiU_o(sr}<$rD|tHw z{6r0m1i0Ccej8N%H1&9UikL&rzl~6my8phZz>qq&ye-x|O1ke^wYCi2Xno4Cc{>R2 z#=X#B<))|E6}@RJT}WuUcY5m!W!~bmH;^&g=3pG!`aKnH{}6d^G|*+Qhme8JrCv8p zVLp`Np(V5VRLVy`v^Z$UOn=2N9aifKbXSYW53e`M_%t6ZV6OjOtv8x;?h*S=WrK}m z`b0oe-{$roh@4LRBFYqWSi1RQm55{713E&54nMF;u#h8j`;+H0W(wB1rL$!T#`R`e z#pZG^lcr}`#oAn@qG`YVMLf_6w^p8RjN#GIb$4=36h5aJ-f&o(gSIAiPBgXz>ON)* z#zj0hWeOU3J&Xu`Qbm&YFSnOPPB(FseE$qLdGXME98!@}a<q9*UM(`c&Gr80h|ITo zdxo_82%gxW4B%*W348Ul5hq*O6T>*J*G!`{4<n*}$v<A7QtP_7`H@SmO@BHR>ZtHz zXC+eh1o{{*fMNH@4X;pWU7-F2{_I``^RqjwDK=g^Z)iXU$+H$i*gbbN?(z)#{D_M4 z8j_f4);PNcoRWHf{<L;2Ppk52|0QmcT^9+KRIiOY?hFFy*UaibA^UBU;nVD%4RNeH z<Yjs2A6@P>R;-3LK#oUdh2t<##h!V+O~IENu=OhsnEbM}+;BQ@_ocfBR939{Y#%7L zNq(V{>IuBIkj;hr#mcPR2;8td8;5Uj)30BP@+p66d!?oW0&;On6S^&aZDl=eyqaNB zz40ctDt9g~cCULlcy(5+4Qws}10M0Oz9yIA_s?|~o$8%Ezs=4^Zy)Q<zHiOWT@OAP z*|ookE`(*-qo3RlC-W<T?4#>czay@;^EeT;*}nU?-2aLzih#N~wr=S5QJ6T4>N=c) z?ILi(kU)rtiYSWE{WOBcM?ndd1M!6!3d$oVHV_`H(hv}-Af^e+GrIn9(fRDxmAbl` zNiTT?){Jj@?_KYH|1{ZA>RInu|LsczUH$$Y{A+uA)c2RRR>%(o;F1@oV75tyN#u4~ z{Kc87;UC$iN|cXv{zsw4g|r}Z?6O8!=OXqSZLC*&G4u$^X^lf6)5Sl2@T!v<(mcCs zwPS&2+STAzE(ViG6|I*}>&uPcR<^;&h8+wyKWoflI4e@?P+62Y>N)XE&wtw=<PbE4 z?yuGEVIj;!v8<-V0{hwRA6&!JIRx4P5pSmXe>$g3#>M5*xj83Xj1C&=(8-D?GjT9A zy{N=cAQhup(1kw=fgz^Cbm@aPaN&GDQ_>dr9{55eWDn#EEDr(M??P;LkRE6(Lh?fN z0`f1Rr%>8t|KOFMYeOKsu$pkZyA$hWXhStWbn;9Wzf=Z*8dT8d4_416Pw7t!XGA#U zl7$A}Npk#HU>|c$D%>k0Dx*+82(3-F{H#=fu@hqM>IV58;s-&`6DiI2YX)0isWg&< z+#tgRKRBJNg+@`f*_rINYfl`O?4LTPhQ91OAngx1q{|qe7ZM3iO8tjd*U)@Eayua< z<R52qc??Q{uvXJlHBU;~qL<#XgtQenc9PGRIi8D`gr#=^tA{#BulKXLv6j&L)l-B+ z*<QOGy{4R}*V=M#(w7=J{J$OWmpiW1mO5<r)0Q{K(w1#>?%T9A?(fj&Bb$bPRj;=k zIS<zyIcv8cVR8UF4K!<4%yr_Cz&4e#TPS5?(*zlSBvx~j?y_%PHI$n&2SJlTzbtCv z5g;E}e&+mk5}~RFgLL|(BMiq+Aak0DYkrSNJE!#S=XUQVA#+&6hpLR-hF7&*_87*6 z5ZqTL>Bpy`p^p6h!RMud`rVk}M3gl`hN+9-zMl#}n+_7*#Mmno2W9O&_LHjdpE?qS z-&G_8>b>cx_cyK?dEDqLG;3;0fbZ=#68i`YmWRBMpf-D?X=^UcJAck}{@~kXe?46( z|CaPepQ75(N$=SR)SE~#u;X5qIr-z&_v)WRKqXT%K*95FEmJ@>{t~df#uK4-Ylu-f z94(`u7LiR+Xa9pI-{0KnCc+*=INJO{rU7;u=r#-jJ>9bTw$#f?xz*@zF5`yJ?Is32 zy+U#mk@<tim@W`-6OojdlfQ?{U-eHEDQmWuwW%EeDa*dy-Qgx86rc2e&|0YZ1&7rY zBKoDSV>chOFE-IG>GQit`x@@IQ=Lr}_k^qcEVbJXxsNuS5g50w-dJ$EBwCd$uz<|a z>6ctxdFHLuyUw+97)9keUNH-lo5{OIBvQewFWVQ8Boc_t9Wx}tRsn9&fH24LR{+mk z;~uuamrc(*tWw`_r-G~fC<=A%#Znh+oqsoGNWY&cz^AE_^M^z}WYxdUrVv2<Z?oD- zr}foGBm|3%RbMvSWg4y+F=*f%&b)v<abyz49uU#ugKia1BA+$QMMffjTVBtLZxOFs zS-!DcJuuff+$L~G-@6pM47<|8%_aAZCwFQAN{(w1kALdVoDg0mo-82uENg~AjS(j} zt4OCr&gnm$|1K~TWBcCbLL7N{LlUw4*-2A?YJy}zpob4$P>VSLB%KdV5=r_?!!Sph zg=&e6bITLX@LJA;gflD0M0!k$L}!}O4=&xv)88#ce#-FzjF8)QWvVA)(J0q%E+*Fn z`$k?o9TwsMchZ(=36aftp9=_wVNm?^N)^11?a6sf89^jUw@1Zp=oQ@<y#}Cur<)`+ z*zAxpG@n@hvr$dp)KE2TxWz~Puf=3fOI{KUm!YPn03ycPW)L`Rd*QJr0BSwSuPp6< zX1VK$b_(6CYo{K3k(1tandL|D@&eVWKcI}p*~E}-q^^2v{?yupo5$Hp7-IH)O#z*K zy2Fa@V@_`IlA3Su+DbX;cFjVFfj_t4nQVygeiB9?Zfg#F&VBw7P|6vWDgKB({>+*^ z!?G!a8ha!l<I{Xk-MRj{;MVLvodI_+GCgAP!G+3SY*cMQ>;p>bnMBOdnq_&XgE-zI zW~jO)_KVcy9!a#{luZ8~>4$!Oy!wHa$K*?z>%hozhw%7vfOdOeWj%A}9Hu{cX}IjO z%dnhuj&v|EQnJb$8BvA<{~jaUqqg5#-q?DAwrF)~Xrluk)Jt>zgV)mj>vV^@>*4aY zRal9|m2)%Kq$yQ2Pij|z<%g76MZ&~mBD*3Bu)_Xl>UyQ!KWI;vDk+Y0_W|N)%U+K- z+q12cF@`^W#H<O<`3%7GBkK4}FYZ8qhMrbXJP@eD5bc5^VG0FKWVQnT<D&pPp?5nw zp;zrD7fb0BM3kFFVZm2rD6Sp6v|+Rnywr&}(Uikf0_-@WpUVD)94VVT>A#rsKL(0# zv^~^IgmSy-OR2&5M$$*tL>o?(F3VOMv-rw9{apW|{89L6k;^s6rV4smVh7NKa0C=~ znW%NWVNopl`oR-`LdYrXlZjMJ>F-1pD>l6|XCj(5MgFz+LwSl>nE{Go-Ib~%F&RaE zyrp=<<^cnZMc3-cLZD1+v<vZ1_I#w!mss&jGp@bc+TPx1L8=a%pUDV63oB|Xl7bvE zBy4nmzl6^(QAO}pJd#Q7R8361ghF6Pd@5|M3|2lqH!CkaT4{8;#Uw!+ajehHSZb5* zo{L4z<YPdPNK<M5i+zaV`gHU^<0Lm)=z<Bl$rI7bg6MW#b%nfg_;;h^)nhKMarWi% zOUKT0>vbKwy6MLnRvX993h%0CyN1a}$EQ}l3%Ye3pi%bu{dCi$^9#X0X4^LV+<U5V z@)7G@XI=cbZ-1)ZjHJmw{`sRR{&_AoJN9|*$6Z!p)n)p6L`U-1H_5f;(8f7|T8byJ z;}K!-C8UDDcMj2u=L<qh92S6K8bt!~bv*hs*W|@Qgw0(g9zKo9$ItTakg6?WDc|Vr z=7R}X0RNLeq0+q|9UR#n==egWd)o|U%CQTHrMo!nxgK;0sW=mo0MitauyfpnGN~;n z1raF`Y5*?*>toc`yA+bJL&YA}#7s=#w?s-oKDDk*X!y|)OsXZPr<qE=3DL*O<-IRp z)@_iZwvD@Yzx%C}=|dM_E~wrZ9IJUtc;X7)*;COnIZ`1JS4VLML>DdcqoJ2x!@EFS zaxzIqFA^o<*v6b%mIs$*(sAWt&L7IGi-R!!EUqw@<ZRIq(<Q8KOSmJMHYS<2jWKul z<R$-&Tu9eK_8cd}yOp5evgz#v{qado#O1jqeXruib9ZreHvHUga;MlWRJ{L~1F3i# zTmUvFr&p>SxW@Ade3#ah^gK{+)BY)LdjP5xgJI{g>3>Nx>}sDtrf?c3x9@#cwVs>+ zf<3tl&XYh;p$#tNfNkb*kki&!K(g6F+Z-CS*`gC#&~9I7Vfi$yL={}p=2bMV`a2^d zng>GsEeiRPN_~@S>pPwV^(0pMbSJCAf1XEBjAruk5-yPz7^_#6gLgWgye|V^f*Sod z7Vk9vbkx+yJ|qJs5juBPqFtoN)%9i)huVUW9<PuOHz6xTx^*luzSh|*PGpWmhgJOf zOiYP$S{(d2hX>(NxYL;@5Za;my6mNs@0YBHr3r>4K%&f$tZRMTWv~5E_a-LfAc&t? z`RyIuG^=C)IBCxz9h+I0!YR${n3U(t?h&P>&%UvU9Qi!=s+tgO6_{C%9$-7e@=j?{ zE&OVd;eVw7a~hZQ-pblqL>I@&sSmd?T^+J<lZgB5Xpg@!&Da^IVvCMHBz0xp_u*vC zE@Lj=x5|WmOwRO-1eCUZ|6$)|mu$DA6??XUq<y*u99lPYaEyKXZpC*2@ks*z5b@Ek z6_1;G#JLWn5nR4NUEQaiGqkC)>fdW)r~5Z}!@Zm}ax}tKENEzI#xUp`^2U)L-aC8u z8yBb{`v)3gCMJwp&&?M)DY3^pMGquRQ8>>R^oQ^ES9~e5@Ghqx5>vYe2q|&tr(+88 zfUf}qHyZ^RHxM-yBeH{^INGEAwc9-x+9j*n#!K3wH$lS6pq<pvOsS^)yG{j{0+L6p z`l?R>Ev!&3d%v9qUn1=XB`k32y8_YcUNUKX7;Dh4*#M~Ocq^f<xG!O@R=-Hr$nz+( z)$|uI1THZVpN+^Fsv@#mT3E#P_N2h=Z|8tX*o&`;e5I`-aWs2c%ITHS<;MC%<3z*u z+iBivbdoEsJ{x*BVI^+CgRs}9TPmvPfPMQI)(wMP48il>YLQoOS5UOk3)~U^<IL&m zbh6vdWBeUY&jF-uRt3;6KTSMt7dZ(z?5qx`p<s4U#=E{>wmb--C!lV4D{&lMC=fu@ z;PzVHtm;f+4=e)*&z%eSz2MPMO(HMfUHZAd)8XT^k!LE5gqC?hGL)$$hI_h}c~9tA zqc{odP|jRcMmSG05k$47Cv%zbhH<a?i+TdGp@gb;%A!@taj7qeA2^~z6txZ(18Usz zXrDE~8m|Q&r?Fsn)lB6~N-#pBG>pL45STuFZ&YR)N^{mamVXXK4GucN$D{!M^@H2e zXpu=rxw2un@bV{)RW#2};fszRwR+tTv(Gpa0tewj_p<E*HeKZyxP@_!!etAN)g{Ms zBdwIX8CF#^c9raGxtyF-GppfT;YoMvuopCX=-e}6E7TlxE*!E}IjM;XSd2hI9dzY< z)hV0SS<B<5jX%jW$42IBA>M1&N*y)W{N^gi8fhj&HmhVVw&8|9*^dYN4HV<&_aMVM zN+ez;eu@oVyl&=}tlWT9i}?IiH}d*xuJX^a3a=~-I|!vsqYKRlr6+lkXbAU>wM#CI zqzpn_9+kepo_{%EtNQ4qI5+~KQYbs^|610`#cV5?d~9yGBsgX3E_OJ$C?8@f?oWIR zY9b)?y<ZI#<AyN5B?fET!vtyf1~OBk1+A-Z?k=Lb2Bmvbw4tv_ekcCHUVw~V*S%LZ zx|0^nF_{b0L6bKxO6zc3P|~ye=`IT8P#R|rVmy2SnOapsdzSag-e?63#CBHglHG(g z;;zNvd+A%!i}BUtQaHVZy!<m@dRu(kXBS;UwqG2t%4zIpm;e(#Ao%YQ%_k)gF<Z?e z<ugs0e3=-ZFm~lE6@d$r_-WO_Vbqpu`-Z9<G$sS|Vldf?-c)o|DLNg#nsMAr^tphl zwWSNHF0-j5x}CrLmplh#P+9+)49CF5x(@PDNIstR2AuL-29y3YdSG}S8U<hxVOWvY zj?^Df^S1DOJ-jse+86uEJ9lH-DSYIqpnZ!+7RS0(Q|^*-DI|jXtF$(g?!O7zCxffO z_%|?4kGe-%Sc>b7KdapJsb_;Zq^9jgJehDjsuVh44`%bZWQ75X(1h~88AgoLRa-;H zZaWodyS!&*ig>;pfb8!q8(wFp+a?Ia9ovAzy2xh;Tp4*%^SX|o(hNdVfW}pz9XqSy z)3)1j`McfS=~p`V(LVxC03C`^BtCmLSKDsDdPO;c;sU%IzUtTqUYka16kbp77<C7l zqy+Q#&iKcx6i~ShYhXKp8AyxzjL7lI0#&plm}fz(pcn}Dp~<QJxB-o-m)ZqgekUf% zenff%>Poo#Lc5iZ_Z-2mdU1_?x`l}rtewo-aBJG;=9I+VrG>ri+{E4`iB05E#Qs&m z&;`tA|H?o)*1j8jp%Til)5G51b!@m@59HYPq#tTN0q)Jr@(^w>8Ma35zb)#JOm4w1 zY`PKO>-X?7k$!>MLWn+`hi1-BwRnh>)6V3Q$*AR!30k=Mwr9G#8!(57yAumPaksCh zY)X<D=`o{2uQwR+iT!ypUNE!M>%lfSEFrk8(EOX&A6KrU`B#(}%aGYC8k=QB{;SmJ zBOF=l5QxlCvi?J`eX+Qqy##wrVIiy$>rv3iJ5t(QSERx2ywOy|vsjOoJ-CEOpn`Ep z+YS_xz-djZ##GghVdhk@H+$?L0PF^S%vT}WE5V<tzqP{PK%k4821TfM2Gy6?2Rw}+ z@I)N$JSJHL^E`QEcLDS~icI26$BUC%#P&eq3kbm%Lsi`0+>3kW|7e1|0DidmqmQc= z+DRLE$>vc!R_5Me*Fr~bb9UeZhXccW`3L;Bn_e`=9psFL;JNg?TZsUsQ>Sd^UmfZZ zMtBD~D%CEDnBsR;_juxWMzuq-IaSWM+_B&Acek07_c~-J#W3zsQ!0mxejU`x?SFUQ zu7Lp!KtQ@qrR<u}A|>4jFQj`8F%jtqSu71v@Pa+f5kKmMySbWxxmwLs0c*1B^lvW^ z5wSkOuV3~&j=3y{f=kz)QF$d_XzS>Y*1O_Eo=x7g%|;~MaSuYB3i6YQ1=tDg$qp2u zLUdzBb;UU5Q$+BHtl}z>^A))2B+ipKc|fZnssP?~!#1-D9g~gvA27m2X7goes(DP; zp;9Hng&dWANAqxZbMmxRzvRldN}9PU1@s7&4(D`K`J`jE;YwH#>=^nRln(hJ-#Z;u zUX@jYN=>q+@dUS1%x&wnVkV1~?6?wJHhz<@2c#g{Eo{w{bZX|$?LthNuy^QZO96wQ zZNn3G5$k;1)N^S*Z?62`8agWZw`(f9iIZ$T<FRiQ^&`s^i6%>`gU(cF^Sj`TR4;KK zpBd+(JroBmbu-!!ozK+%A{Up!ValR@!Rd^klM;QT%7%26FpeF2FJqT2C#xb)Op3W8 zmMMz=9*GW8b$|9!?GlZlg~QOqu?PNQqEUVI?k#GV+3;zk!590vT<zE3P#@~y+<^5* z+zN4_C1^1P3B06f^iN_o+$+{_w^Efx1<#%p1hc|l{lBDnej{#qp3PG2swG5c<{LB% z)rXZr9~;<t?zGy0Z@5ixzGGhHDE!Qu238w11M=1wHpVOe7U^mSu3WoR$pQ1;eZ-1u zT`4JxEw&>y5@{sm`@dP8-dOnSt8c9yiJapK_IJLwxIXDQC%(G=eLdo3b?YHyHVYQ> z)00bPhHS^EeX|S{`+oYkYkfYu(|s4zr~z?Liu=E(xITxN#=lK7yLj~Dn)<#aeAT`! zK*zt;Gkvr`J&VZ;70QA2F~Gy`Sh;K3xPs%IZ!1wPZ@ayAjku^F;;VL=;2PSKA)%0w z_o}DR2{Pqs$x}!7Z2l1?mQ}}v8xAK=Nb3dUNm4XDFjmTDKDZ(a2KfRiPpV#e*(YYA z(Ok0N3+Xcu68Jt6lp%o>2t%lVauOc6U1J!2fe;~1sFC*taiM=XoIn#8M3f}~HzJ`r z_%(PTk^l#oPvQ$iLx_M`l&K&9Yd|rH7dQz#oF4e@PndcV9f(~A7%LJU$XzR#5qe2) z5`-WCN`Nsjo6sLW0Cs>g3g6!y-!KT`gnvqKKn>Xf>PaSo0lx#piM=3pJz+QrCD$PP zYEh>A0P)aX9z9eLzyru^l(%an=wweR+=lN8&6$!z9+q_58q(p_=vdC?#rof?a1R`( zd58dmV}VX=MSj5r`99x*Yq_~>YO|%E;%~7dnhxX=q~^-M&Fd?k$TS~GH75i7jU160 zIfGXbSXTl<CR-Pdbj(;qYD)wBmBQ{th8_R-ankj6rO9AE0u@9%73rp5jrg!bVp~xZ zwRVJ<9b#7q?gu2$=_QnD5jRcNW;V=OWw$4+pMKl*zAl*Y)#Fw*8&c>HV?7(y2EY$) zX_KeXCy{we9-uK#7NRI}9kZN$u^fE~cpo#RkC#p!P8<<Crqh;8VosO^v`(T~)(5O2 zus65Ht?7(f1Cf3;w}!3h3|fn&t?S6zRGG2oPuL_Wr5ASa6oKF4)gD%1YF}}sy>TVI z;oL7Qhr`<Dz}gzXMlmtYMJ^nPnK>r3PRcGoMI8-Bp{1t}8f}w`C54K%C7L<Yj-Nr? zb8S#kwq*XR6gb9NJ4npE4rvCQ(try0KsAMQ%*rQVf2Pq7wXoQB5!doRYULVgD?H`x zgAnBwev5RyrAM$=sOTHg=o{l`8D?2Ke9XO{Y`vd!f}QSu&;t<2a}daN5Xuwj)`*Ro z{nkZk>lKCUR@#}i$cpK~DYBKVlU$bdQL8dc&F(2{JQLQGY3n>fHiU-k&PVLgO6lUM zlO~S9^v4A=-g?eKgZb>07@GwzW~DA<y@NRYN+fnUvNTe46Lq65qbH~kvG5x+jp~jV zsO;w0VhKI@{@gEI4z{@ag%Tc~ci5zcTUab_r6~*aQ41AsvIO!wx)EhALB2@&Fds3h zWnS?+?<}7`9U#SLK}|)+r(cCvQa$-?WjF4?_{e|&@`@lf6MyTNfEo<ALW%&8+86<} z92hp4I7t?>IM{j!p=RO|QIW8wMoZl@rAn*KO6kfat#UQ1#x={uC9O*7-<6ANG+)OX zuI5`4o|2S*@n5%6>o+{FI*)CS8Ln?Vmk;@4=J-HLZpN#_^OoV?gnjwZUWkbqm6geW zGyv__VbV8PVn8KWiJIbU7|aqI5!!42-yUa(oLM#?&5b!2ks;>#{@h1vhz}@?PB{pk zq@%e`S~tdP{{LS@g#JS78(kl!Yj5$TB_a<3woLO^Y;NO6@{yg$m$twT7udg48hN;n zOo3PVcgAq(dt}l#vi}tRAqP%=wXiK-z7&J{p2G;_Tkw(HX!<&=dZ(z)v^A+$v5pXb zC5M{3X-@8?6^17->Got`+-62&p(ggddSZ2N>%w%<W85G;L2(Ww@9Jc@^17|BpX3fN ztmQfFKNUT`c%wahIL(}UeNCO<^{#LpcLts+3w~^BNYzU!0kN}I-GEvBj^J7Cvix7~ zZg@9zeeu?JMI+T=$&}q^hKUT1R!M)R5FXQ|u;ujC)1;c=bh6*W<E-BtsPFaDwRsp5 zS&CV`q;9Mrx5=33ZYX!Jr|Ib@bISbc>JZ8@^wg51p5edmTahP6a<t3G#)@WxrS<d^ zq`*zf@03p&InSkv=Yhp=L?SQ9lkfc>2yNg1c3uAN3Tv*;+7H1$9I?|R=|#*L`$ig3 z9g~F_8_?m$bFrG`cgJ(@jy~zXlNlyIZS-hfkL^>I`o!UsN|`-XeV}+12GfYpTd1QA zjhBdyrt>#Vn@Op{rTF4`(zmi-DGmUaI!Rc^--bRkooyzse!$g-X9tEr{&43kIdhwP zxRm>Hf}@Shfeh|2j*n!>@3;aboxZ}Co)2uA<2mzkGvR629o&buR68lDLYHN6W!68_ zLQD0aFHTZf(-gAQUov-2Z*2)&oZqaYr5H3<beYop<9wP-nMnTpnQ~?|55|}oZ|3F> zVb3bHjltyE{6JZwFYDcI<19};rD=^s{&ZXFBc^9_*5dZNbyG)+?4ApPAZ1X)V58Dl zrKa^Lo+xJs&J6M22la_t6lwkNoa)#KOdncU{qmD53aUcl(k__E3Jzygdt_o$I(cM6 ztf?J7-o%dT_PC3fm)WUOt_c-m)p<6iZkxgE^e=M}t3apkh@!kzC*vbmr7;CEf}^j# zY4Yhpd4?BJNhn=X=UOMi^(I=YS3iU{6%L@R`3rLCurq1p^zq%6&K}g)IqB4EZUi=s z`Me_qf`1R|31W>GlrD0}M|)Qy^m(qxuZ7G<xr8baOA=!m?U!4GpzLWQiJgMENzCPm zzotsKK0wanG+fmM)hG5It1w(Wy&LwM=OX|iA8Yhw2Uqx|nt~SreK(FXS9B3PpXixW zZNu)ii4P^Ge^)5p{{crpxW7SNS8&|Zz-N=YnDg9G!B%>g;I{*!&17?|%cUK*Ei9fl zmwtm*A#XD!Gc@EchYnTUmC_iY?wfX3$`+b}Kc-quYN}9wjRgn^YMM}Y3bm99g?f`{ z=?2ZzzM{KQ?xi4IDAWf;7NU#gD;Nh#e}zxZ-c6SizZ!LP{;x`B8TZiDG!@jlkh4?t zEqV<lf$}5#7P{Z08ie`*y;i7q2=!xny-@cE^$;Bs$`I=3bX=%8Lj96X2=!W_eoZHZ z`lL|5L7Gf|RSWe8dW%rIgnEjur(8<Lt8+=TcUl$TNr54OKc7|u7@kpsPZmr|TLO4t z@p5qPD_;qC`+_xqiz^wvIho<3DeD0LoWl6t0>($?F`iMtur{0FltSizLBiad&$z#m z;WtIkuY{8`i{Z9e%=wIPN*6L*yO24570yQ_4<D6(ShEEtXELmmxL=&f_>Osu-yk8c zlQ93RVEE)zhK~vVO5y*bnBfh=&pvM*r;@o5@Kz~TONq7s@>#GMuqS6L;A<+_O8o-w zNEW*lG3-iV*qzSss#J!*D`WT`;a?=2n?(BlB!=0-IV_y~Y=-xVwy6?+ZXv^A!3(D{ zOp`Ewk4u=p3S1#!-Y8*KNtn-8a4CKx<^6s|4d*ABIY*>K;bi8_7S0OcR0yXvIo|&B zW-)((*yM`yn6vym<`mCo&a(N;xg(P~qj^y)l}d?T1!#$D&x0+ki8L#iODi(Ar_QF9 z?B&4MoyVNFXE460oMBTA!@Rl65&pS?U4Z|8Ea;Us7HzQ~naZiWn8kQWW&rT5=W%Wy z6F54P(|t}_(H9m<ZA#7lN$TrSfe%Q#y-?s2qO(QdZKB~@0;iR*bX6w9^l2>JCTW$= zl=eLH0N{6}AHBbTQ+$Ki_AgZoljbrU$zhmU#PHF13_qPGwJG*|Kw9iqrZT5dEcSeV zA>-bBhVPM(w=BE@aLakocK%dxO{BHIM&f2m+{Y#En<Q3A5_7H;=yx&P?PC7Rf<Gzv z_XPi};C&LZJ&Ey~gnv}{%Y>6FaJh^pzgxhtFoofqEQWihO1e_}-=BXtQp?-&UkCWP z?Bjre%xhCq>6b;<0S0C<+?U7jxhjT#50)@|U^>GeWH6jv%J2hdA((0BzZLLng=K)d zXE3Kv;QcdWr2o?)w-yn5xl_W0?|^-Fn$$ZA-vg>csMo#Xx{_4F@=~b7w0zDjsV-_S zR#Y#jWO})Tsoxm$DpCm^j(pPRF(Xt~LP$lZ8>nj9PMShj%vaR%oR6hWq4&;zkEWn@ z=tt>P(QVT{3%~87X2|-SFQ-nWl?$RFGihxM^<bUK%ab#iddZ|V&0?x}iK6B#WNM>H zJ(|kYfJyyGsJEEZG70%*lltsjroOd8Q743Y|0=WWLUpfE)K7)_?!}6ll0`-)J!w+k z&8)yzX4=;>b&A|214cHzajlYn{rDBPq~?&XK5D_~bW?rAf}l>UkCt{O-LziCOE3F+ z>P+fxG|N8wmeg7Fn`TAbgIbwG&zjV3*d>ofTNHJE+AXPhba1Pp?wfK;YCi4Rrl>8D z70|L)MJ<G^kTTm8bqum%dfud-098tlv@5Cr)B^g(c12|)UO7FoLs74PLe45_%1%W! zf?7z+Oe!nymegwMGpTnV*R^zqNu|Lqb#&*>s9l!QvpXYp0k!h7s9l!RrI$r5v7CO? z5ltPHw=bH)1+-&d)Jm&qpGozh3~T5%llmB_iz&w)O}(Dhx+AHBdZbfQCzdr(L6>T+ zpUA%#d*zF}bk10|Qpu)&^e?y%vWrdXO$#0XwaF54J?-gMss9W)TTgu^RaEs*>IQnV zNqsN<QJf8Y$fQOQ@|E<wNxh7gyqO;Hn3h02fa+0Hb^0yX{@&B4sAkBv(q~NSHc+jU z=~a{;R6AW^QYS&}pg)?_Wra^-XLtR8sq+=LfV#q@=7M?^&EIc-*5AUXuxWhbHx*Td zn(m}$P3onpms7iG<wJ^kCCY%eJxuBrXz|i{4=d^~^PWoWr#BWDLhXTUKmFRI9+>ws zwi}Bo6!j*^hUv?din=2Isnmn?{y{}OjTEk;mrZJK{>!POwC{37-G>%(ghD2D09sy4 z4_%?Cm!?0J`g)pwd55AtjgTj(!lX7PH^U#^WKzG+V(RrKbtkl(q?=5te#VrvQ#Ajp ziYf(l9eq@&Q?xEGC+)3Nd8eX&R+XRjcG_f8FPt}E+(h5FQ^m_i8Qw{MGpVPM!n^6F zuPbU0IlGyjH>vYeUQT@<6@5o(*_<+9+(Jjcqhue2mJiZ@mrd$=#JiQAH>sCFeS}ti zS5beTbxZ2UsMDl=2I><OHmUc4`XpUrQVS99)ASCL`U+&9rQ1wuCS;$dP2W>gW71Qp zx6_T!Dyju#_$qxAl<s3+qenoQeGJr&7o`lZczemcsdrJIP)DS%+(kn|y=BT!acSCJ zbdyP)$bQOybr-$Qq~4ZY3E4+LagWO>U!3+0`V=VL<Gw*(w50G2x<5wtkV+40qUDJ9 ztVt!gmZ#lKQ~n+e`Ay3CyOM1+n7SlJ)@I6{5ZM(mvZJQ#ZjpU8Ms|-W^NQ@*7}?)U z*#||o^d+lo^-D@tC$jDsna`BHL1Z6{k$u9HO%vIFLou>PP1$n<N>;(oPG{I!%)4C0 zGve`kQW^hM8RK`CxPU)6jqyKD6RGeAsu+GRi9@E$V*HZg@$@XtvP%D-a9xT-!zY4k zofFr^e+&OwA>)r^@%@Q!7x9kiZtzp650HJ&@x%Y;G@n~-XQSC3w;6a6LPj}Dg!41z zh-MdmG&AQF(h}xPV@_u|<G(99)0&!0+;fFb)>iiR-<PSNi<&3}Pb!`?Jn8aWS7J~u zAUt6}?3x4SP@TXF1l9{|61Yv^E`e^qS+pN;E{zE1u)tIFF3eFki_YH(d=9XJ(v9m% zYUphSbB+oBUch>)bG@sK@egNg#LnoN@@9H}8_k^AO!cmZl3M9u3RLX`{K~XF^f1D^ z0jJONVdpNTG%R68py8G>l*;wflB;m%=eDXN<aV(JuWNbP8|bi6or9ABS5o?iD3i`B z{~X}s)4v2g-<tnb!1qJ*i_rXC+zrdA_z@j;U03omI_5e)`!PD@+L7~Tz=tw&=xwfl zPnOLBo}cq~y4CgPA~J4vmFJ`)m8=CRMy_!QJe@q0E(bar%5sdiaT$UCxM;rdF!jx1 z*qT=X_`52`zgxoap6Lv~lELs>fL_<P=GPb_#?=d#8Fj|)D%65N=BF4<#_F6`8b5IT zvuqpiSL9!cFs)V1)MRAm?=v2bl)Be{c+BN08!)y>etzeAZdwjKC!FV8Q)dJW4s#Un z#)SjMi>~D4HvnEb|5~Ho^`{v(7)BE3+(>#j^Swqf@J|8WoO-)anY6O#PNOdA7lq$2 zE=YRQ!h4MRq*pDt&uB`TTl7Pt-Z+u@m}q{|*p>9c^c;H3<zM)`;Z6Erg$rMQ;3(%> zNJ?68p6hVZa7l@4zp<pE!gVa^BEYvLy*Gc6>t^9+!fs1k`(3%|D-mW*)t6ABy|dUd z1v8snUe~KL+g-<um($&@TP2^jCe>H<x;~jynO^~EM)}o<`*0fS&Nw*hTGuJ#?s@Z# zQ-)e2a?PG6@Dx)27^L^k!w!ajSm|E2B=C>TOfkMjm!{96hm9i{x4Z65dMM|suEz|i z&7}1R`B>6>XMPCy_oc>%;aTMw-vmCNYaE(`r7ydlGrm*mN?Jt2C9{*3(UOYKL7I`a z1UbC0tTO3B$-|3DHRTr|OwNpUK$eaeujF)Ht8?}z-EM@ZHdAgg_nljR5q>x+FPZaM z40uh_F+v`Y)+aM>NUBU`ZFPX}NUBS|J?FiEALNx;^3mc)lbVuuX8k6q&UHunmk_3* z=(!~BBQFR{PJYhSU6q}@A8}_V|G>2=zW^{hzYOpd`PIqX(v~Ox&h<bJx1aCiTqv9) z$+<4{TyXxF`g`CX&3Z0>`B*aQ7o2zIQ%bJu-B}qaw;I>x%%Yo<AD;e-lv|TunpTkV z$>iP)__D_9XEAJ>nkxM+2l$E1YhAY|zp~<vlzXKtBgR{b?@IZBiBGM%FJ-^0F#R!l zIQc}@k5V2^Zdv&Alw#!J@svtHq?`Qv^gpCLXS^o!`IHyQKrbkNf>+i)rC4AMO{JY_ zH8g|v0p`=yfTeT|;6l0{a4G!=aJ6t61YSZv1#A=kZh>9&C%}F>4H%@%DQiWum)-$w z#{}L<$HBQ1`~AD7JSzC33WxN{DGkP3=yibL19IFh1;M{(%KHSrOW@-IlUxi-1va=O zq`)Hr-{+F>0^gH=bX*{(b*JEWnmDIhlnM?YbJhyJ*2G!5HcdEb%-JXSJ`-o@sBlJw z^PaT#aVp?2lyaqU>NJJn;c0?r9~a2dBEgGHoV6{-%y17qNf}0=vD!Fj++;j!ykum! z>RqpNy~;J<3c3!sUg!F>>u%Q%T(3$xm4tqsydk+Yd1vx}8<I~ZzdiZp<Xe(In*5XG zUnCc&l%*_8S(&mXWm8IXii-@)V=l@d?BL6p^ScW#Oe1>pf_lJE@dm&<vNr=RFK<ob z&`Ee)l!WJEN&&u>Qh;AUX@FN!IyhH}Mw}u6PNPD|F9b}bZoo7e227_v0hZ6bjc#zg z&-G_lR#H)aQY{qEq1&bzlsrmt|L#J@k}dR$DL1AP#qwOKug+6EYq(`|`S;N@Bf^`S z`e2zot|!|bca?mWFw?@DnR=W*7bsRpjc|7r$Hy&5-9OWw#-AP1*p;nuS-qCxPQgM$ z@autRB6Jq4H4RTTo*X>6c&6i-foCS3S$JmSsWzH_lSI*l7j<=XtoH_oeD0A3pF0>_ zTGz4IfxFa+yWEkxWSJB9d`E8Ga>vvhxl7J>47<`X>;=qi^#uLlK$j=D+3)VYsI!B4 z>%yUsf3Rb-zt=ms)H_($(ctrT^~VU?J;6}@V0Yu7yVK`cx31M8$o8RbcgWKo@W0wU zsKqva^%KO~=ywRv>>l=d+B~7{Lk>a}Z(J#~YPoaTJC+38BUY*1N_Es6_W8K*`|7Bv zaWFjK37AxUSIFxh1k&L5`8=A?VM6`@sLkGB2tO)ONp3qXz_6{U-E%Os&VMkLsSEBM z_H0Gf9q<Rbt%2<VYjK@o*d^A?Y;}kFtf6CnnP&ZUxd%NyYpC`90k>)}6yJiVE#wY_ z#Om?o*&g%+tXdqIZQhV4D2y%Mu7E%2?+MlHgz6>KG#CPGb$5IHO6jKd_N_~3LwK-j z-x6IH5o9S1y94XoK@Yw#*X~DL{959+`MdgqcFuC@^@KXMw{KWU7jE%)hkc%lRK|RN zkZucmySSdrGHFuhT+>iG*zF%+G#YnHf7ehfr`dDBq70N(R~#vL+pf0u#x3nlTN)$m z*3Hy55)63;YMNTCWod8NY9*HpT+*<0Nn2~X=0@`G#9I<>x5s9l^LU^t+{Rt+386<^ z;t8PX?C=DFs1vZ`GP$IEbDKS*>%onG&s02br>B!E%o74%n}gA<0sp~~w(X`_&~i`} z2ZA+QJl$S*)b?yo-~qRe8f9#2ZSZ${*1JP)TT?@tnr9thkgO6p=WeWM<AvGb^8|zK zT|@1@AWH^<UH*X2+esTep^X9eP@lI;7ce^V1Zy^W20a0Yy8MHKir3Ulo4nnBo_b%% z69C@U=RctFmLbnztH<3<?R^3Mi5d5(zPp<`peN)R3^BvgZL>y4L!SrP?~bcd&3341 zEwWp~G=V*U-IO{^A|{Q5b$549q&w*G^|X0=2R*isx(PP>2R-AIZqTnrMW-No^u;LY z96*|Fv)@798I|us<&34E!4n97DWP)?`$C~1CsDIsRBMq8e@#J61%<L&ar<D`*h;ie zM^vMMqBdbr^u<O)1Lulr)0VflF<mK%RGZGaYW$$huD#VC2z6`?c;HDKXguiY3PXn8 zgRBPpgWf|RHU_-igb{aR7{3>yC_UUG+PwpwR!^4)b5ujLLk;%$FY51q=ve3O>c=hD z4PK8AQKG?myuIOo8zE8U0rvpLz(CLzzO5^OUfb?(97M7FoS*GY4gP@vSV#(?@wQ-} zMuWk=wmy%~r|H)4phmX`yq9>*m~9^PS%q%#`h4D?qJvC(LVf;j(k-z*9O^^g_I62T zwJ_ivhEsHjXT(WtAE<YKdIO$~VRyjRRic88{tf=X0mdSAw=RGY*%MHFm06uDC-2A6 z^N9}Snq%{WtZ|*W+JOuVdjig~js7^PMi63?KNzxSM>>L2aI1hvTR7)k9_se=xWm3s z(_k><9t16wDB~~%qiEBByVqml>%5@>_mD|!K*j5U+cZG;dQTUBhJ0!Wcu<vUHq%4^ z1V{3DwlLDz<;Aa7-{%e>co#F;{mOA_9Awf~bDR7Fo~?*NZuE&^g>J!wg<lkuwW)$A z9^!j?z34f^{(g_efd<ZN6n{`~H0TgIT>Hq7M~xIb*D<vr;2$tK>-`4?eVB~60JMEb zqn2h1QYGDtz9$HObA$-#8e&SjXebPmy3%84U1t$yNHKv+=C-#t@DM?f0X#BnAg9QV zAXsH+)H+^zLTCm3QMO)^aJ<d_F1IgUq?uedQ5;^jRj_>!wGjxKG!l{D-U0cIdT)vh zG1wXKB0=w<vK59v#_jW7ERS7T@FG@fa1Z#yJwDVl*B9-7aQngv8)EY@7IjtvTw9(X zh87uEz)(p`2k`l1Bt(A*n{15-EqK7QKkR|J?kGcb08OKAdp&5ty2ygo4-NUu(F|4# z@f!-lR}P}!x;%n!!hDGqkIpp&*Geipf;ag5fU5CAvZWobJYcv74%J+RJX|*nbW7#y z&IgCs=jmmCq}|=w0M80@K)YuE!vI)u4y9(RS+r@eo9B@M?;!IUyS-Rga!-_w(*{FI zy7fcw!UtejaLm*~W(DgZmIJoeD}S#(gx54W!(d?^8A2xsi1&!77Ey%7<A!Fl?#^&; zuP1;;z@5WMh^%RzJ<l;|@9+k_F}(U<&@<5K8)^4{h8)=ec%uXEK))8TK?5k^2A*%Z zTiN2suwbr1?84}*?I>RF33dg%L$Sj4KF@%MeSvs0vJ$w}KKDVvf_8md16Wpeg`Dy+ zG!pRk_Bn~5+dVj<1(DH``ADbJ>+^;zQZ@Y#GCF`CvmtT6giKtqpdy9^wz-ErmQ}mV zv$Vy3576ovz>i*2)p!m@$6#eO>W(2X+*ydQl?ci_Y7$*OFB+;M;>S<)Og&t*_r)>H z&T0|J3<bn-y;s9ikws`)t;TE$kVIxW_0p19rv;UOuI2+vg)ot}aA#1k=wvVULe8;j z3bFubZvgl@cOYJb(V{mDe+*0ZA;q<1Y<<9geE_6s3SOCUi(T(^`~1Dcex83&5we0a z(Wc-Qcc`n60Q=&-mYr=|!9@-5+D%YZQHqc?;Z{pDUOXU0#p{x4VKiD$p;Yc-1-6wJ zizSy<{fvukH+u$qO>~QY5ZC}iX`a#m!$a_9;WM(kY;!v_)4Goq-LrIZ9c@yTUAs7c zen-qAao!=dZ)<5u+~$yG>P;RS&v|>5*IEi2%WodL)Q%;#i?pYxdCpFr7CU%3wqit? z&J&sz+Izef*xSDrMH`<moLfh1@fz5p_GzAFCsVWRd)HQhTFu*9K^#jL%{q%%L&Oly zJKkj5>$cm_#<%Zp+Z(0Lsu<~E)mVOigU{m*v~+cahrFI{UMmN!VsmxGo7kQ~mTIB% z9y%#bWO$ICzTQ33(zDa!>8Eau#W;a_;*P60YiTscQgS;B#!yVBy|I?gR|Caz$0{Cx zKZjf>?pAIZG3|sJ8yYryhJh%5&U8|#Up6(DE~)AEMU-9Y9`IQ_J8A+ms0sdmMLL?) zZk5WlW#NT!Kut&61JO{rY~zO0)i6;YHBbZ&`o|23o(HEA{c=DmkIO+pji7+?tM(dv zvd<z6Wd(CtMZB-b>$Zq%zQsMLn+6xgp)*(<5R<{9N!t*RSGHr}I4B#IYEjVV^>qh8 zY(f8woue8LqBB~U*dRj7hoc&QFX-phyN$_%Hdc{#egM<9C!VVYh?voWLKp@W8nbPI z)Z*BxkaoVJV#b>>HxkF%Kpb=9&~d}iVW-}bOZQ-Kz#C+qbqS?+i!qu=|8fULHv6L@ zEW{eb#bXyaFrfJM&3Cc$ph#sk#qNwJfO-xnp6;jCp>@1r*IdlmWL9N=8}YWe+vh!` zm|<yw^<5SMehDvDOrC$J1AZU!sz~ifdV0)(Mf!PkoT2SajXn>r!ZgoX@aQNtB!b3+ zT^?XjbHkerj3^FV1r$?Gzg`*S5dPj?pGOtmT8);C7cC4UpMBvFEMe_*NY`-=vUEJn zvUeYctv^p!pF6Yz{)0b%e!svfGS}qX4)holx0@<mdcr+d3MLe)E0)Au2g)B95$aW* zfZsOP+Gkm(`PE#*TlU`6zLa9{=D?;-g|_)To}u{F2u>f7_7L|VtFd^G!C{-;wwA$S zHyq(&hh~3#>ky`O^+7{XTnxO+17w6jLmxoD?(EimjZH8uIBM{JZ&d_qx1iiGOtNW% z^lT(L>}5I#--73k4SpY!J?aOOJpZU|$N-sp)|d{^WL3`eNMhwh2LnEclHEU`dh=dw znKurjmuV5_OQ!Rnmn+{Y({|$wU~sL`+a2-FlI>7BZckTO+TDzpN%mJ%P!kQRO-G=1 z$BX171&HO2fK)+$gwm!$Uoq*LE(PUB&AC9DBF+o<0L4Qq+Zqb+ejoCt7W%L(^)aaL z3~EEbt?nK42eG#wv<~TJ)dVGCyC05@943G<5Iso<#x13F%Vsap+vTx|wXx&ny3$o@ zQA+PL^wtDyJp5v22zfohXmm?3weN(r1bcHqbN?CpLfw&nDaz}pOz+jg=^62H2)$_; zjA;>aEx~e}?+*5Z6%Ax#sPRLwP{Zp+fW-G~(;*BZJKh1b++hUKyOU1My*>cGt*vXp zg%>UB=m_<B5p{pq?F(93Ys6r1_1gVNajcv~e7+zt3$92cD5nd{_lAA$0A_9;UD&gB zaJKas1rFDLT80#dN6W^6q0oq8sC33ZHlyIgLDU9I#OCZyVZaDjSmtzYwr=H{1jk(Z z!06r}e$0c+&F&F@7-UyC5HNRE!*Qk)JD~@W8V;#FFd|#QjR)Z}s4FY29$>Fj3lNK+ zqZrPEeT_r^t`SVB=u)VdsNU!EAHaE?zZH940p@mpN3`M$0RGrum$wFIiA;oKtJLu@ zm3^J20Ui&$h>zcp8jIBl6}Ms8G;9fI&IWHF7>ba(Cj-^?vYuGRN)%=BT}%cqLzL%8 z$gqiR4EV!Cksjs9-00V_dO}0i5c)=wm8ZM3^mHYN`fb=z9QNX1Sa9Aw(-py$i4MoU zqbJILQ->6RfX2<09$C+ub?+rhPj<RnvdJGB@8Sc*=3Nc(*tp#dV+f0mN%2edF;?)p zXW04nQ&B5lTiPzsxMjAqilYpDsG?4AVi#jEqpeB<?6}nJe4Q)11bBR|tl|j6?yL=k zL$d#7Rw73brnS5_q3oD9gR+d5s!a$I)CjwO1A>IKyxD(%Vm8)PPAGo&OtEFvt5Dfz zB@D@)gVvK~OSg(Nc+18ND7`Ji8#4B-9LtJ8XxT0{m&UfWvgASIrg}|sD*6b+VZ~@V z)e$FMY=q+=b)KQ3%bbC&ZoY!q5)evnLPYzp!&MX_stnKo72#_*J%F|3A&frw^^qTc zzi#q@_R;|O#x5TXO30vu4C6OIwSavH7a$MtLx?p9%nR5<esH!^J2gzCITx2^KzR^u zAuWJLYFyO2c;^eA=dYjE{K(0vhgLVQ>SgM0!%y#h?TLF%ZoT3B)(X7;w3r?ksie%) zJ7@_7pkss{^*reN`(@ub^ox@p=rYoOpE>^Y-c`+WPa9K<=$W=BnuS}ts8?zG)86l2 z^?c85o>k4;u72by=2Xx>c6@I4HC-=ws+;fX`23L{w^ic%_#CEg*Mbw7r~i8VzEck# zcP%z{MRQ!u7Ln4e!56LOQw2q3B~qSUR1G-55V9h`O|%Mdi@-L7f)<giB_pMO5;V=q zZ1?nQ8x;4w;CbWj2m1}-N?xtpowc+TrT638)@Wz2_-feKkMxFAZQuz}EhvP+Uysz4 z8|i8LAK>}|?FUu^EpBk}&AJ7B2oXZOAo5v@zXS4D16~keYLE)P1DU>w8u1R=dSJTT zl(q~tvlJh#<2>Hiy{DyW*QpzS>#t(_WgTj|d}CmB>xpg5H&8R2ziQ;V4R16B_>%fm zuFY1dO-iYw^P$;|)`poE*q~V^D&7g$iCEm4`o;e3gnOQdD-y&#z%3~)L_YcDcDR*k zgvaMZvlXq&Na+zQOF}4ZNXJT{o}sM=n3sAbANYVl!4B{|kinZ$VL3&Aor@U<Z26?T zvGPvUHpzG?Pu*nZc?n9}$1qoyB4UNY2*+7R?f_jPmT1<NP3u<{nxQ325Th0Ofc4VR z=arSRwKS|GX<@}L)_lnUH1$cV*nu>=LHkkq0~UTY4M!w~CB^ls+|sJd8Z5AC_DU<> zh}3!P=@vUHUT>6_yA8O17imSxmcCzcqB31J3ulQgQ=#TKmLwV@n%jKMamZobaAcI~ zkRFOLQfh*7+of;58nQvefacM!JkwSYep7RsB&xb*tEEvCQ3ay<VHONfi&b@crSk=7 z%ISLP&QK{?O+RfcwkA+b+mPMmqQlztp$okJPUGMk+h5*|sf+@DFuZH=lfG>C+|%j3 zM~C0Ldqw9nhn{Ks$7oh_t;guHH`d};XLn$D!~n322Y|Zxf=$?I(cP>$?FAldEF;UR zlSYsIuNcb6w`4uOhG#W{>qT4lSjK8v!8wmgHewWPa!Bjw@OG4GGjUq~ybd$i;fu2< z1E17mSR~WTFrHO^jNxyQg^$78St7>j9y69-y1BCyrW#A<I5Kp<u{44|f;2s2Nc*_@ z#*8~8ow9FC%|5FIM1n8&Ck^AlaG9p8K<T=~l!6inU;Rq1Avbdf%uElM&KH%cp+UhV znEI;4f<DBlqotsiV_N5$pe)rahGYn!{ILcEe6u`vSf=KGpq_le*+bIMWCA|O>DG-M z-%8b>Nd|?cyfG!&d+7P&(|WXSW6l`iMsM!!f4%30=2gwn#BbbvyJza5lb5aSyt<_# ztcQs$rv|U)keR0$Th-jRZS5W&9x_h{&HfpLVHWRPyL0a8I_O$~WEPuG9SU6sY$cw| z(|QJbyg4<0G(mVkqdqog+pd22(A?8w`7+V4HOgy(%m~}dHnsW6lbp6)Q?HCCeW;wy zs1A!>D_+fV<tq#Hi6<76iZ(|7z=`~A_`1tB1s3&Yp57TV45VNCyH1Ou*g*pH`Lqnl z9|CuXW_PBHju&<*Ezx0N-p7v}Z=2SBf7g%OI8K*;^qCrD=^&mrwnz17o@?>6X6M#% zk*8v3W;-=MJ-i*&eE-SK*VtnR+n#B|4AE9i=lajc+D5HNr&C;Cy3*cIo5^v22iF>A zBZlCZi9x0g>jV>sPB78wMJ5CuqF?ix+lP!^t46NZZC5AWc$OfYFpn+3Eqa_9O|MgV z5=|$6K5htcow>%96Ike+m2snE*SLM6<STZ<y})0uL@c7M_(kZkvjt3rs6m`aOiKol zHQiScZir(7>y}E#^dJ+<#gh6O6(@Ey5%cw8)jV;-;XLBo+;2U6jK|M^?3lf4Rol_w zdQMaF)I{si>Hd2B_lGxMv*L}L`)|h@7hNcSJ8n7{J@ub%@maghZ@uw~WhZp2KRO(p zwb<y!_UZ|H?PUKlFgIoO-rU-^WA3#TVP4Sl^z!w#A&-&A19XMy*#uNRkV`E8XFPN0 z@wN)us%Ck`n^O^9(aEN*pfLVWYQ>-W&Kqa%0$=d=w0;v4Kz0Y?MJ;bR+0yp$<BV5- zwcLHp<yRcv2|Ty9r>vbTPCQwOr9A^l`NYu<q^!IKl|r6g$kfs{cKLvRbN2_XgQRpK z?{^OtNtQ6$H%MBG2VZyGdoj2^{Q1o>KPU^AuvlXaCde}60vj_X9u#MI4X^=(IjFcY zM<}e9Q-Wj&bScpV6X(u(UNA<F=%(3!9<O53-h=MP)0!veM;Kmv+S)%zbkG{2WsrDK zK;Dt4lflbw6cpE%)EPSxi6!YYW`1lUcOo{E2W9W)pmrA`4#FaeItZ48&&VCH$JY)4 zhIrjX5?z8NvYeZE471MKQ%=XGy%G4)VdquuYkJfg7^#fjoM@IOJ4v>KgSQiZL~l2+ zfat?zXUI|A&XcucV|e{Uwwi3#;@e;k9RN2b6~~O+_1~#x`&7k+J;Mr5Gl%Oudq^Jc zAt|t!$G*5r!eF}85+cE2l!6YnoAmfO$x*W-HZAAz(z!X*#5En%MQlh=#)w7#84r>U zsmF31o8poGPE(9oCybu>?_|P%xjz_rgL*eAeg`W*DzR@?#MctdSw*r12>fE=m;>T~ zP+=L5`cgA)=;@RCP$OHA<#mx%673V0Yx~)D*#7N16Nc9z%}M(d{b-ekAPcZ1Ku0Yw zq;+yzwIy{Hn-hs7>C|C9Igv-<peRAlA`<hA{0dua?N!v9ts{Y5)-ig2#OTS1qfU12 zY@~z0RR`{t$sAokmX~p9In_csuUoR(G07zDk$t<EU5`8zUzUw(=^BU_ggO#CCJaa_ zVL6`d0`w|L<VZJw7;d2v%X(ax{mY$M?ODzL7+uwT=nxL}vSV#QnvSel@TBZvY(`YV zwD3~6gHd{|xkjY~4>_ZMt6JDrq(08=*oT~jaVHe<=MmYl(+KTNEFac5@Xr&@%@$xR z+374_kyz?#yTV#GyXi97m%f1Z(n2yS8xS@i$0Hk%k{n;kWK)G$RcO&ym>8{weWVmY zgwplS)SlR!AoS%(;Yw?&7bhM!atLgRZ&dTKKaXq1V#at4Z!A`St$$VX-5vdxj@+1e zI@03uFUN53&E3X9CmB0zG7#8hm9N=#Q!fu*uWRNF=FHQ1t$L$*S~I5^3AvO*vW&NC zI5i!X@uR~kXVaQF50N;HTg-h3x2)pUNvSbCOU-s*BnYr2@N6>o3>w%*QkPv3i&4G4 zZeh7Tp|4cLZZ?m9HBGJ_KOYT(`DKi0k87*c6whf;X~?v!j>kJBW`KqTb~xuEK~0uX zXKYPviD;5>CGp%%QfET>+?I$=8FLcN<)kzwl*g`#HI8`+A<<l)Wf}>U!#i;r9muD? ztkI!P2SuOSGaN~@H0LBG_5genm1+BUDcP=;B%1$8YfZ?1{(HyMYFjE#w%wnx_Js1j ze{$MQ-DlGy&S{DXmC=1BDGEQ)GM!Zl36){Xcqv4#IwhLlgtaA<w{ho>$W^V$S#*** z6UwJMF`Z}8w$CbsgvyYv&rs-+anb_6e=`0_g1QpRp}q<>zE<->+BwOgsVmVO)~yF8 z7&!=S65l+3q)w28>X8$k&45_Pa*W2w#%M#1@TEm_9_*2IC2dbk%X%3jtbTASpdZv$ zvC)8N32GmCs#mViRwE4~WikJ^Yzh0`<Lcdbwz=(~7PM7rNK6mvm-(_s;1$er9d<zv zTUE+gD`nMNYekkdfKd=#Ep$qF>k5G?9o7=gAy-U)WIvrl^jm8#cP3U+E8n_4Yydte zZN?{>RXQQ89um{L0WiSvV?#u9m~frq+GwmSzN8E8?7L*(r7M1U6`ui@T|TA#*zUWp zIecuLuZE(3MsC<rPu0kqF{7<xODo5F?Y5PDyqUJD*;r$}#?CrewyK$L>YR^f2{u!| zjVtVb8O?kZU}M_{CGLrBoFaBx7Fe}qHFI8AN9Jjk^W}Af!Lfww7T^ySHhar3AodGT z!ZD=4V2`n+$ZHrpqtsb?i0{qe&%>pzbPf|l7}bgf%-cuCLg$dZs*g#2bR8R`U*)2& zy1E5R`@_eM4s(IOan%dWui3TAEZ7zJQ-uJ3rZUW!HFH9@fmR6&AbjR&-gIEyAL`nA zg!hl<o^CLQ)E0y-q7~>aD`}B*eRLnrEVwJdy#Nn(i6Pq#NtojR7J-MV1b>-Xm0Vdy zF{kl~;E_wSnjahd^a+P*%jIVF!>exUoqL*xl44YbluQh>AAd!1NU!hT8|6{yh$W1F z*V>dp8^y{hDnyZ(yI+Pdb(s;G7U&RKld~SN>9~3%#6)^#S!x7yK#sj>ft9N@*yB1i z4w}(uq1D+bwXii8OZTg7uL!qcfY~fET!BEX&uo5T@1B;5oeP>T?Bi2`sW>N~w_bp^ zM82~7s$S+8r=M=Q0B?wx-8(<%ka7`!{ucA~WC+a`>;){BU0#)B6E&lGTuN&YB0iJ$ zFhg;3)397jD!0B`qx>mdl(@YhV=6K&FN~l;6*~4Wgg37;r)!L675BZkn_oAH8PPf> z_j=A>k8j#m5iTJ%`4f8&Y^z3k7ZJx`?IonsnAUz`+a1RTuQu|SI&$*G-P{F#Vp5*N zlBf4Z#y8y|mUs16?Bt5&U1%PSA3t_&@8VV-XLrz6So7#`6Mi$yO4C)R%gGj4Ce3OH z{2+D0UPG!bz$FjMySM}6xdKnGG|nN3=ch*b9S~^=RnYFpUhC!HEyBosCGCOUO3=U^ z<t0dw^W4=xcn~#I$K|N%{l_SO(_@vTm@LD@fka|(UEJCCM6YrBiPvx#wl;@ne$(Zz z?I;Xy@^CHiYfh}&wV3xjSu+oSuWN3=VApKcXmHz8*N@$neBx#Hpe<>Pigg|FuIfHq z+rN9?XSc=F$Hh9V_%;H!M*7YwK6Hz>zw{A&+8lMzjH|!n##cv@<7>Eogwv=sLvlVZ zX(m{0c4yzVC$Ig;HJt0r)2Vw_b)4V2XKQCa)A2Em4)dAZ#TXXb<O(6uP&@L{H@hsJ z4i$5FtyR}$j71i(&Axr=B2RoOF`)|Wb7&E0ojNUWkfW}=;@fqaS0*X99~>D@rF9me zf5fMXoaixRR&-LT>Q!Zb0C%~b%vj1HGf!LnqD4d<-`SOPS>Wo}{Nr@0eaQ{|LvOp3 zj~8v_t95Q;J?2X`2h=pceN?7yW52UR#jMt^DaxpdlQ~r{N@niQRqJ;k5JuTR?dqv8 zdMtKF&RmS(xlB>)J#m^VMt}v)_B?+2>J-s0X&GD2WnPWq3G<165Mjg`Bg8nKXIL(B z7<uZq$a1%_NNR=hog~V7RBW}54rjFk&2oxO>1KI=>3mZm_d;&NQQtqNeU9E|ok;wE zP{PY}IRf^}l+p)o{P8fH{rGz_c+^IKn!H2GL~(Bx^vKI4wfOBr=;}CcsM>lUBt{MD z3t90Y<BpeAK8-qmtLZvL);DIEs(FwvSH{t)@-S8**AwO*UewDc^nc%$$CJgZXc&%> z)A{aJaI2k$CzLxnI9ZpaqbCNWb)4;)*x75~>mXE`(OlFLEtbAq61xIqvv<l}TC{J( zrd;JThLn%NoNVi!4d^u!uhX@uy7XzT^e==&k79EMq+;=Z*}3?%=5V~Aou4O~gwqq5 zt2`{3b-*#aZqW7=uvg~9&$3?mp>$Y5y@r~n_pWR)(s(H`0z2zI=$6q+H`W+CPYo(d z$#wX9%|3aK`khV|iAo>uQ6|EpDkdgdvHi{_EmD1p-FtC8>S;6nT0kk6zYzm#9fwl= zu`qTM0^FE?Z8ge^(QfToOXDTlU3_=jqdTg4pE$s-Ty8sc{Gcsm^!~1=ua`{%8G^4u zu4`<iqI%AQSISltCtc$lCyu7PrQyFGXP5G8$9rPCi3c^KHq8>yQ>2=^xgZLIuQ_5V z>1fC+*QS<9xr{u0`N3w#Y|atq&a_^orYE#nF<X{@LoaTP4h1n~YryugxLj%tJ2a`` z2f5>A+4eKDkG1XS4sNl>;VaFcTBzTtJcBG+c^!(!UC1&zNpC*qDJZSca=4=@oU=4^ zDQq5<_MT+*=QNcetf~T~!J-|jzR|nAvS8Vbr#SK@j*@efX)%m^VPY?>282muWGgb? zX!lEhT8r^ODn-I57$>b0sd6#ZxTObiz09h^w;M1O7H|*Xo?z_-nWxR(w8BX$-_@}6 zEdEMIT;FmdCora8(mS8syK`2hVjYWn*Pt9+yL)Fbhs<4_TwyZ9h9f)RYe>0Gd+igB zxe-|-Cm;cY)0d&6_W^39P$kO1qEYP@yQ4dQJX((w$}gJK&{ZQta!^v}j?r4JQ?!IJ z8byn36HRZeDQPtxeS1rL`_-0m8Fh(mGDh-(bk$~}Jxn<%Nj1f;11gx7tE80(qf#<1 z)>^bI-c?*{wQ3aC@oN*=(zN7yjoP}jhf(}$S=Wcn^R8;0t4MAo)LG;<k&RPJZpS`< zA=057Pl&83)2!I8VD2x?GC7lW-7T6g=8m?iIsV+5H&yvWBbtI5BWvVYOqUEiczja; zsg2$}<~l2yjJ{udj{LspO=frtpj#0lru*4^y=XC(IOfZ!#4<qP6O@1otYhCoIv8ut zw(+)otRYvE^(#-~R6e@3TFOT}4Xf0DF|JwwMat~F0K#Xohb;q{Rj1WnJ?cu-Btqii zvz#_i|JhtU8Sm)5%a$hXP3(HZ8EW4-p7yx6hIH&i^j0QnQ(EYBXi<v4Zs`;1iZW<$ zjWjugK${*bj&{UUc)Y;6daRH^^GbYBC~MCvl1t%8rPSWexb^X1w1~{30GZ8yYui86 zI>u~Xn}~~M>1E|ZYOTYED)F1g)^L^ql2bPa$T+S!n3me}IOX)B%iq{s++VQg!Q<(t zdG%qBSwSic-U2#J*Zy4}{?^8awE9$rWwrA3^}jlf@Y+J!4?80Znf}y-7P5rXyFYOj z(p+Z?X{nQiOj!aJGB@rLwa}b@b+iuQdE$w&Oqa5Zwu$;YOpT1y!}0+RwRNa_W3Sju zZ})4i>cc*pr8@B!AWAcT^OXfE!YVH@`M6T=%ISlta;wL#^QFHwB5t96h1e%oQueFu ze}q^A{(f;hFT$U7<h7QyCNjR1!yi7CSn_9PmNm){lgrW!i$pE3!Bd8R<InuD8DH0o ziY@2!33bpOHSN)1cQ3yV#vHTx<rju?I-{?P#Tb8vpFc+zyPr38m`klb#E@<I0)fc1 zivfIrZirDYY7y-n+1GMw@aS;5`wty*;Gf0cHQ;70xoONGb!w;Ihxm3IpOEk=r#idi zGrGCg-g8pDzo5c0u0pJTyo?XDjnZy$ZM^2-Tfqaf<nI7C68ZW8&B-8sdm-=oXO7SA zRPQq|Zq#7|3N@*=eh?dR1Hgv$hYt1nJ356FX3*Ns^lSBd7fNHw=!JdR9a+sU?lu<0 z=f-;0ptK=Bl^Mk6j;uw!Z=v<sayaAZ;k3S+kH7VDyeBepxc7m7&Yxdptj-{9F%F~b z#QOA`9v#j6EwkDlwl;H)4zpcFU-}Q)3d4eBu?|jM>Y_lOcXOP_TKxOcd!bpMsupmU z<*+)GwcSKD$-r02CuCehyggpAQ@dLYy<2aXs;?GQ{`ENL_rSLFUaS1*aM_6!ovev9 zI$aUrmd+fVkLW;u$yZKd&%kw<s@~X5d>#hld6_b(8rA9w1?TOz9u9$RetaKpjMI@z zCJMcX*bWEVt~~i$59e?AG7fuNB<y{s6kdq8%J}!kZPyH#Igvp!8Z&m;{`vphsZ87| zK{R`Kc_xEWK!(Cl{7S(xH(GOKteM>Ti)=>8Dq&c@rW!SWN2Y2FbJ%FN*$tHYwUaN6 zyt_?%Qg~moL;Unf9fC||FNS9PX)k|Gb#W{8s{A0$@WcllDn81pyl8znbIjc+#pl`& zMfN#M<WXy&CD`?R+}b!ciLhR621`|~8uQe?Hd6EwOWf^d1F43VUTGdm#}<UdVou$0 zMBL@PqLmSU?^3G6-)i8|>qkX+R?_*@foGY>uyBB$6`&ALK0LTl=GuPQKUxA_9Uee_ z)cbtu;*>PUS{>8OYmoEmxI5)VD95)|m3sm_7(INP#AnTF^)g0%!%y$f#=PZL9r+Zk z->kAahnpVd?0kami0o;UJ5=<ZNF^^r!`EXQ--O|R=Effb9ws9@gLDIw&jZiNkP(RY zAXYVNNg*6e9$lCl9RZ_FH*SkC+D|V;<ysrpW@Y+wG}8S0&wt@N7jU6X|NL|Y#hTA5 zWyzoR*7j(lAbcH5wTJC|Vv>3KiRPDfuk-QuH2539ItK7;#;pUquEO|~P;FTm_}(+U zm17`(W`R|jd0I<MJuQi@s`ZDBl!ZFR`lM0QIHR8PCwj)xR9GdipYkYN{OYTFXLkY$ zN8AsT>(C)SEz?fM--d(R_;XisQ4S}3)+@;D>hf4`|Eft$W33)@lhEmFMs?$k&rUIF zb)EfbZ+vdlRL|F^ER%ZapZ0QjnJeM#8gapY*?Qe*%uwarVV$M1-SwU^T!Z)m{f{^b zW97-X*uhmuurzXUqt>~(sHHT^;x2F$*uq+OgO^Xd8|=_r!s2wCQRg|cSbT58SZyx} z-`nHTsC#SH4W{b2`y2rZ%gQzKUDzz^CLhg;c9f3D_vk2FJ|d!@xKNQV(9Y4$9IR-6 zjXlHmDU#T*Rvo$VYdcC)M_!b!&v<Fe<OeW2PoIh!=SZ7c`5ER%(}UKJre|B*5lU1U zJ#wF5xI6sXGd<u=G}~u>z@2CcXLG=vXd374fZL}1%n!N~&HR7tpnE~|7~3|<L=U?! z9w*el>Ck&}mNI78550|Yz3DnZk6LkmW{tq89do1DIedZ5cGit!yVSaYyik|L7RtVn zTsuhzr_QExq7CR3wit<RL}yuV1yZ$5%XqtpwbmUVdyU%GFr~3OLG~EXSvZ!=bhAfK zMLU%G-%uv&J=$0K_#aWuW~Cpw2&k7~XR-cG^lO}Ir5d!aVG~}v+6!EVcBj{Wqc;1G zwJy!KgpB{TQNl~21m8`bguaB{Pi{zjyc_eoH`Nm@k7BG<p4h_3SeSUDrh+jSH`1T1 z%Nn~p?%h%R8d=sIA}asu@rs>R4wtpM*`}$0`D4BpI{KA~-l42kFJJy|zCoFL5IL!q zj-<ZJZOE%e<5u<Pi;1oP_08me{^;y>PFI8zf4tHm4->8t$Ii9UG`Th7IGQTsOg#3* z|2dXW))iyz<W`LM$ax}{{}UM+&V>$Hge|ueE%7B}spIk`Zs8I<7Ymmd>YUulO+@>- zTCl`W|CZah7X7kJ`P$hoQ(~z9#$DV($Hhl<akBU978m1}kBTjhw{yFHuA6MNP-UVE z2eJ+{*2RLAZ(SxVaLBEFfw0gboygU<E)EiN^2;qT#&hT^$8hNFu6%(G<>*x8*}2+% zKX&HsyMAkL3GQr^QQcX&?aR;)pR!KSJ@Wd|=Cg9%C!T00IKGN+dA0*7C6C^3Yt;AK z_+y&#-*i<72Gj7b+=r`w11yJ2>EPOr<<u`o+w~9Y_oAKeT#jD<zcp2w7d01j?#tRW zVdh&R7go<n>gUiHW<k!0uJP}BHphQWIq?q^o`K$kmSokAcSy$yoo&7FQj9hpzZe_m zor_)8GbC%MMYN$Mt9kI?+jp}TK0#EU&NyKHKZ`|{Qe~cYIBhC_=Z_a`zJ_l}M77TD zyzkWA*Qk#rAcu0E7{4@&hGxfg?1h)pr@D>EJ0|aJ*>U3Nu>WLSgRhT_c2W<Wa!wnR z&lSY2ZlWJo02aMTZscme)6iFd^6VG+)l8)}`kcR+&SMb&2RqO3N1R6={C~c1kJ}OQ zsQ(!5{OASzV*9m!`kI)Sgl`oMF?ZtY@40L+ard>^)AfHBMcLNQ3OYR~)MBEnfRqR& zP;bSmH(u1;xfyVC#9AHNR#sl*-X2X=U*hJnP;KN3qxSCyOB}zt$AU*vOjG~&56x0~ z{V`wlrd(V2+@RFmtCe2KbM(c_0P^Ay4QQa2`;Kd|KQZ=yh3(j#7e3C8hW-8F+IHtj z?e(_X<4$+j#~hRNCv#LEtBqM8bjQ+hO<Y%{SABM>*7=hfZlRG<{6`lmxqzyfjDJ5} zT_Su%%j`D(pPu=oKSsKL+^e_ZC)Gr(P|cMh&3g@=<y5D-!{n~kjvh(uwr}*Zae$p6 zJRLE~pHC}))PJ2IgXXe-cP9SD-jM)CRb1b0Hk*5s%^h<69AJPX<m6JSkRYTWR|0CQ zwVUK8Y}xF_J%HFNP^qBh5RZxl6>n=rZM_kX-uANgzAxDTy=?8Jwek1On?JjM_y0{c z5yV<P?C$(I-n@D5&6_uGCNrB(0TSCLibRMKQ5&#-1v0JpuNh{aYBV;T5;S&C6b*_Y z6gCRB;4ea9-X-cP{VGZ=$f9`@MQFmC;(Zt*EQHp4E42@AiLZLyrg#GBW}xuj2Ci^b zL>ecCLYxH9VSvAz@EeK32b{^(K6wI!s>k;s{I~=P6INAm_6$7=-0^>zZX+T?qItq- z#Mv`{^k{6r6q!bN7dOlVN`fMjRN=Qy6d@;}W3)l#GWE}b`!y&v@PDc<X_y3plm3em z>c65BolI>qc_tD{Ladp=D>ku+emzMV?VBt@Viby?1}(JAfoA+}c*_Ihq*2>sgqn6t zddsNAX*d|L5kmp|rTK_z@ApqmHRfr}xzHbfDyD^JIxx#<DkfZk6?#`7&LsM1rUi8( z^zYRV`Iv)|Z5yoxW@R($nVgU4a%3m^VL9X6bc2yW?nH8)CbC#lBHNT}O61eWI8VS! z6X(SV=cV?PT5)Es?z~)Ie77h?%@d<;WukXBoEpv`7gEkH8ggCu4wo9aCL{>&`<9r0 z`onLn=SsvG@lMmCvHmI_L!zu{?30-_IpNYs=g8!-G~AARc6@8fvjoI2JZ$M0Ck%^4 zWXz>`k9~~o98IpcPMT0pFRhF3%mk4;p5tZJ+!Mx0b=1U(lbSnDoI<&0PT=gnnUSY4 zMjpo&wM5w*N{xS6^W1p<6exzvupsh(Pkuu_l?rxl<d_Tk(?yPPd*krSF`Qc3PWCn| z{7-HxczhU|mKZGZPokx!x>zLTD_~K}{B^pVQNlCvzcUZx$%P|SLs&TGO{`Of4vCBN zcol8_csiygf06L|>drc|i#6J?h-*dr+t<$Ox^2xzce7lf9Lr*#Xh$s%`>TY1lnDvf zrJFVgnb4<6ynSkybZF~CxRKuWLCsLIp3h))zA`vVfA*QtI)bUnDBnh^35Rp~XIe7W z%0@HsqA{M+Ff#aY!s_W2i({Qh!KvgV2m#GG7W#OEk{|&LZ_yI6E|L_6XD&I^1x1;? z3B)IG1PUt^_P!z-bz@+l>tH5->Qn-%M&ss$|2{rsvF2&xX7rP7iV%#+4vog~mxRZG z=n@?hEfMot*yf2tf_`yXXgJRbFg0l3mOu?eUbj0P;<;`&;?Ca>pSpVVmzZwkhgRZ0 ze!(xZ&ud^6pUh*4DGImSO_>L7%D=b++A)T$m6&pFTk}=i$CZiKS*vS*1eix!dEM@n zorkWOqM(h9d1kEq%JvU`<QlyB)J?RMQ5u*<$u|4ZZc~ItD-&3DHQi|12I}S6F*y|b zVr*D8@iH+bq;)c|AWfViUKLxu!$Vfw@;%{ekDDhB35ut|An)huTy_DqHGp}cD)PJw zp#>!EUcF8cPFL`32l_*QM3$G$X>BV$wc_s|GvQeje1IC=^XjF)TzS#^Yc6ExdE-UB zbdAE3gKw-Zk=W90sbuTw?1sxsMX}lei{rcNR2)YX<3`na5il@?zYmIYZu$9n1~Wu_ zo@#$&)rD)GU-HQJfBnXj_Gf<$7Rh8vMkQ}b#DLw-UTy5loFtilO-y|QaAi%?a5naC zHnuj|*tTukww>JAwr$(CtsC1Ln}42qtG@cHPS@!()7{l)rUqTz)AOj}X-V`+no?_< zF*SY*Z!0cYZ!%HlVp{G^kc2v+69EI%l(2>#G5MiL;p6AsOZ3AeHePD%49uisfkzL& z*9wyg+q+0(&Tdt~v_ZfhA?LlYk?ZY{v;oKyOKphCLgl+H{#(w8$eZ{8hmY*&j~-@S z`5(nc(FBa>M{2lAfF4Vd5g;*7OCdCs&;m{|f$H%Gc0bORK1Ae6Er~>ImoYQT((syP zGYL`XZWfCe)4CN<lcw3WjVWSh4ZAkqXwrInPi*i^iNY$*S}bU{!)mPgV)yNu*Wb7X zeAAp*i_X^_Xi22UE`r4fXOLtr9+np$rdOY2z_k}3mLY)*ppT>v3!DQ>i)Z$nV6j?3 zv^q=98mn}PB<N+On?_Bq3JUW*!6o<w#n|gV1PezGy6yJ(7T;@NC@T;@CPl_$)j%qb z5>MwjQNWVHO-}FmJa(}wdio~zczq|7NBkT`uO<uA)ia2Z4L0^HT`4BR;OIkWR9FT~ z&YbMFhTgIQ;D1Um>;>{-1ig<y>SHjH{v{##V;CD(zo?QP8=t7RFZYYXfq|RW^SLPS zViycJz}r}~Ga)+#9C!;A8le59F7u0_rwA=aOtQZda0n6}M@h{>b^CMjf#Y*zrxdI3 zmNP+^$iMeWDY5c`8YPYjlpG^uNR3n2eos#v_Q-7$5Lt7yL6y)3?`X}Ob`52CGnJV- zzMDSD9-EUG*M;UDnYd}tuiNBD1~$ghk?1c^l*i<0X}~ZJ2WLblo*e<It{{-Po-R7y z+~nk<kVdU3!cM;s&^2Qs;%<T?1e;$<l7Bz<^+q=dMs`sdrCCxeadc6&(9p7+l&l8w z#u*L`aA6;`vMlhnw50eG%KAG>2)o9EpJB}5aXCmUTryrQrXM8b#t3qJ_?jCE6_hBX zR4<BZuQN?N2%}G)q>T}d>VeF`%tWP{o0&Wgq|VIfY~IMfhl_qJvum7%xQqbYi7Qpy zgj83GuDQ_2cI?-Z(W+HEL`L(fiO8~Z>bycPAhK@t9*&_9JOM$`jZ4uF69%O6Q$fJM znnPk)LkRKwfL<F%lW`zf-z{z`fhlFd&-k}jzUn;6Y6<;lD_U3^kMGwAKv+Ywp@l;s zmhw4Z<Iu{H6wK%6YKxA{<j+`&e%)}q{x7u1PqW*7RjvB!(nD6xc<h|4j!QovrAC4z z;M41zxkux=mbq=$FNrv(=WRA89-rf>K4u+|%E9|XGdd^Y#<2`&!J=ucc6W_%VTu37 z(c6t^U_l7Sm8nPFWUSWY&9+3rL7((a^7cyj=8@?Af!5Q!s&4kTzm!?C>RHjcZ>yaJ z$;^$g&+!laLxcvVy7_cHt6n;$ZtWa20LtCC|F=|3daR+AQb@qrRZi{HDmDovsG__8 zZX^zRjW|j(u$DG;5ne4re2F6zcX@0WDp-kHWz5N!1XF(xeK~Eieus6!Z@X!XR1ESl zF|8L|`{*66E4mLA?`dy}`!;v`)ZVq~$%ExZDs@KcWnMbAar_*}wb+KX!%dnBXsI4M z$M85jm34OK#&>9?ukGL6AZwu7U2P}HE|7)KY5kPDo{ipjwSwdEQMFs&2MHsEtm_2_ zT4(nW)-(XRbYJ(p;};ia7x|d$Mo`L|^RhpGP|^1#zM@8SOh0iz9!TR|1+O{RuY`=! ztgb3-`%cv!2FI^ub@Qhfnn82}OzIdE$b>EG=vI|UM|BUAyzAGm^bmAV?Akp#aJmt? z3(@2Wo3jh-vtiOXL%e+4bA6&N?!Y^_>ub6v_U&KJI6rh^I<}b?nVHC*!i7LdJqKcG zSo-SWGP!kPW)_ZXbdT>LaK7`r<*uBT>293gdv-#LJ-%gK`sj9CI6ig&jBUyCk$bdm zUu04`g@)arj$~}CP-1Vs_wUGF$JjMo19n|#yfnDwM2#XY1R72AzBMEJ&g>nQB>eoS z3mRqAJGW4sx1cRJ*Pgi58s^Hm>xUQWq(7bASw=4*HXV=HG(0s-S*I;+;;@gVE9O<v z?B24#>O*@?=#V6Sd{$}zR;NE}zGkadn%7jkZ!Ul>#>}MOH{Eo%J0CTwraZpCdH4L& z_Bc)Kqx|}u<Nw2JHA0j#xNZDAHgK)=?j;Pt?3*)!<dWR#*`ukJD^(j6r4&~L_GSpi zt}vQ&uIwrq;jFtaASey;f`lg|<rE*L<;1cl(%{uSCD_rFpce-R5bfBP1bd2)G03^a z*4?PNQxA`L1A9h;yqUr#1>b{JllA#YjRw^XPp8R=bUqTxJAP*<m3sFD`YT&<M4gNc zR&FlZOAN{vE*BZCPvBiU+7=()TPk-4j3lDgz5Ejf&RVcj;2g14YY5eyo5nT^d&$>! zc8+*PwJ&H%qYU>NAg;K5j*f^(y5l((M0&Dl5zZ2$nk_V9ZgX*InZ3@jKDW-*A#7tq zt!@~Miq5gwRceaP?)4YqfCR=a4s9uRo)f0mab17QqX%I3S*hNg{c!6$pvwDe-i$lj zPdy{^vU{o_9Sh53X6*vQZVGFWARfeuK-@Q;8BHzEA~J#wu<++PT!pXgPCCQ#uRlh5 zkRG9x!;FNJy9W-9VITA{<qYU^2PioqZpsfio$skFM&J>mzD4)a+V!#4gridisG6;B zLcT0Bp5fcagj}0*R%SwWb<45AgN`)h8uqJ+a(Shxs?>Bei_-#=v*My!bDg}tSQY{# zlU;ohmC>{d5Wt~8C`hT9>*Y6adgSj@%-hxRw%}g8RZJf-o}o^O;os1%UEh(ypH}hX zTIY`M`$peiTmki-cfJ)f`?z+`H%sfhmc6^1zc4BVLj%O3ZAvCi@reRS=UNuzbwmm4 zCQe<)mR>;AEzrtj)>hScTYMh7=gtyS5(9w<2(I1gfUH|)lDsBN!9#UYvWQt2QnHq` z-B)=rgT0lGd2Jh6y_zy@L?t9269NfL5OO8Olun>-wz>Z4n6??{6Y=`^zc9PgjM%j! z`zMaFl@wErT{MVzq#}OcIX;D~tie^-IZm~&R(2XZFUAsS@lMBg2wPB90SuZ6NJ>dD zy%KUe0O#ZIJG>^fxppK5?IdVg=gUKh^{9*=B$ZT(Db;X|A>B81ig{ns7}N?=x`7Wg zKRFp1My-c=43<+bMZsDcbTtGkVhBio+4&S*?DRbSbPpa2q9RoVRa>|+qwxC|y`=&} z@@rdsA}GuXrCg7Q_;WPqlK9s!?{<gRV)|<^z+uA*3lC4FJV8fE3LzzCS-1F)m9Tbd z0xYIf2wgh0K(Wm#t45P*TYn~`vhF~RQ*E&hIz`5(^UzxGrqCmeT)ARTg<A52_a{X7 zkb!u!+B`Ly=0}BuKW0Tv*&i)V*oR|s7*7#?ih(xal!6X0&Upofc>8<X6e#WNydU5y z0B0d~P*Q?RRu%?!F&}YyMtZrtBy^MSi1>A`>R#Ut?MugYcBlmgf?XRc<J)bNyA4P= zstbf3C;8JucNWP0=HUi$%`He6+8BeQ^*Wy97pKlSRW=`%2w723hD$MbliCorhQ<9m z#yG)GoF9xzCElvyS_7nRa765aR5o2+fJTl}$<ec#PW7yNt`7~i(Ll1;3LG6?KdDe; zqXe{rWcgCYAAIf_q*n58LQUMr^QDM0CMsYq4(Buwa`ifLTegs~;Z(6D;-<#61qkr3 z74tjLY6SW1!zX9IK+P)D4sYry;$6v)ib>(k;8@Sob1;_Pn|OedQ?ii_FaG&a0E*Fe z@L*Z~a>z@HkeLu-^{a0AvQb!fq=zu3@&zo@Ea`k1elWNSMp|SBWvp5iItGI~MOSjP znvsA%a|!akYPY0|B)?bc^~N$NRwNp7`SeO0NH=0{r8xD<jF1$qo4_!TG?n7~mDS3^ zt;CR&6O9FTv7n|W(IMV_Vl+WC0hgz)?RC+WIK2kslAYPT1n7l0VwQp*>$@Flk5$)t z-oP4)(>^F(_lsugkw;uaytW?&^C2kb3Z}NS(Jd0-A?e_F;*lDP^@OU5tY8((*d6J} zo>#ES3G9W1xv&oGkn&&U%*+;+9{hgoMi%xoow=pd+3|2~o&8B{iwvTIfR2UT+j~ae z8VYjam`fg?na9^x4{r#ewKjRs*+1X}LCj@j$PP+B^iCL0DsVm@=02+0SrCeEmLoUZ zmgWXxAn;qw55Ao=yq|j4X_S`HJavq%Z+!)_T+SEWCB@jeaqsyCHdeo=miPRyn8UZ8 z--L%2{d?r)l$5P8?;`H;0Q6KzP1SVR^~~^^yM+6G^nan|$t!OqXKxo;aJjuk>bP?T zU9-*%<rYd8j0B4z&lDO%BKeEE%hkw~Yl5LQIGo?CYAth}4gNkgVGT$El<UHsrWedY zG3yALBN31m9@e7INwJX_Q0oObLch=DST*^mm5tnAbV+cOXxV)U0{XxPpsBf9Ro8Wt z;x#R?u`RGIh?R2*3*4L1hL`e-mz6TQRqOCNzWR19Ir~vzsar<_qVVY!{fCznN=6Nq zj!XrTF);6~r#6ZTnOLR>!Mf#3h(`QuSNc|%!_BvcgWC{-%jYndZg?{MXr_We5w2j~ zVPj?$r2guga@PUa0EG#+4g`*|hXzD-3Py|drOYZp>>$6EM>g{XK#Qu7DmZ<flG!Y* za0*0zhie(;=?SV9QsH%cZpHnJfqJ^|Iy}wTM?sj|0M=2=7$&6@3iucu8i3D3kLr*F z{iM5D*<up;_lNC;3B*{STE%WK6}LR2u{lo)E1+1v)Au<Q0uYp*x87<VEcoc=MEU2s zOb#O-`!#a~(Ex$ls`~U&6uaaPxeG%YySM>b9tZ(u4`n4z)|eqzs@iYZ+B{*V#v^_| zI?_U}RDaZm2JtJR5Y-UXHfsF%?Z85~*)4o%c%{FG0cHA43O1BGbJ0^MSqdO9Q3zCo zUB8eQ*>#*12mv!$y5MS_CLuKgo0P=qU@|QOw3=1IzJEwGro-a<Oc0I+Kgc74lhWk! z9lk(gGN>gR-60`yY?`b6bincVG8iG~JUJ$Yk|QDOP?yRSd;4|J$PU|v=(u1p;XGFv z;%%cMv!Pm+G^C!URFi8P_ngfj*z66qfcwHCMDljbLV&D()skdiWBuN%uzbge-sBIS zkq+DC2nh>D#pmatU>~@QDdEI)bY<A}NmEa=Sv>jQE6i2)J7QDEP6&{W99`V8(G7KV zM}kH=sEiUS2Lkk}vD&x2xo~ZM39me+fL_T<Y?RS6qgXdYfk8UWr3$jtv0vQH5nFvz zZNK#>$N}i{?2Qv*+w@_wege`El$#9gUf-*C&%hy3FZnNXR%RjW@FJ$=WB;rGb<WiY z==pYh{~1Z<(7&x^`mMu|X6h)z+=wj~0<r4maq{5Q(tM1y4Af|QCPzplB#k?6uxuJK z9_;A1><*pfBzS!cgI*FIl|mMRuWVF_qjJ+hnE)}2Lh4^0{K5LLe$yB+VW`j<R9@5# z;5gtqW{fgKC(So%>X<OvC^n9*o<`^a+2)x-vy3CA)~`rI<C57%-QAC*VyNnJ5_fEi zt{bNTK9D0I3%Q*#4sS;MjYTpVMQM$&f-Jw`m})+Y)v(SqO`vCFlnNnPKU7z%7^V=D z@&G>~3W$v?ZcN_o6M}Q|CaRHZR`=1L=n_o@?NP2}fF1IW&7P1rGKkFB`Pwi@zKt?J z2&cTr%7_^0kzp6}0tZY<X+rQG>rf5?kAk_x_w~p8%u+y><|CWrkYQ^(gqZ!*+X6jk zggpNUkjB%q-#Q)4w(;LO-HoQ&Ajt$<hya53q(&nM1V{JgoXO_6w(5$poT;K_imC96 z%@Wp@IX6D)NBK4>b>#@_!%1cMGmS5m8De-o)HhP?FGib2F1JUl#Iut0tSDuO8QGER ziPx4-?<cxTF}bJLer}_7ekAWKoee&%PN`<My3gF4$1Db#-pdb~AtDQ^b_FFIQvv9i z%*_ezjdlF^x#9}>W`y$m*fy{%)M$*(m5D&7X_+JlMuP;j4EeM1VA9YLPRHJf3c&rf z{;ZaUR9cL+V;Z?6_v7tuP?14&oJ}FxPViHh;>s%sBK=)|=1=nAKs|~ir=wmB8;FW5 zVk(hRGRLAAvTy2@s>fv@)cr>um<sTti4;AS7HP3>xe;<!t+FFBt21%zyIK79$JICx zCcrti;#gD~<kj_05>^RgiY-QrEUSrlw7PFJFN#iCy8j!tXk~BbZXlv=D6JQ<Xm;PT zU@4|8@oUr~U2Q7Op`u=A=uWo&Lq8fsHTN1NqfQ3g`0dR!R{&nyp~$?iRt%692(dK7 zRtR-3g1iCmVFCweoySSTf3G9Nt)`qdf=u%+9PP4vZ*fO`lf!G(!Ug|KM9exGd&t8O z9;&KD&Z3EAO{#yb?Vrt@iAsAWK}mU)kV+p}yvQkGUsm^hJP{EFbl_{Wl;52o|J>o3 ziG#X?-*P`3jgpPV+3>l)W&tEN?&N98cs(i-4?N{U8wBqpZ~m=b!|Z(8Es(wJ6N_Yj zO#3T>*U8g*2MInDlw|CAOYelecR5=iyN%NMsvfED@HXkUuj<Y6{5;Ty{RDNz!Qik{ z9hZRzf7$jnc#Y`P)5X<^s&4V^7W)HyrfJu^)EQzSZvCfE<^29Vk^s>->4XwkmKrD% zUEx`r>6ZR2Tj4g{r)xG9sy>U_8N#knwdNUFmm-@MqV8BI&Xrg|AL5W|%^f<WdQkRT z-grf<I16)gwC>lF_kGLUBQ<IBFf0(UQ;cSCsA>gjyC(kj<;KB&8q=D1`T+3hRMx3E z2!=-ramy8#Mr^YA6M#vh$f-|xaMGbP{c?!F(@gZ@hrF@5vEcz@OytJ19Lk4g<Vg*U zQC$%&n7l=lh*vbyUS;i%y{fs;nI&SHao9oGjZROaFGWy$TmtK!T@8YG)~VsnIrm~= z6T{0%uw`V1yivR0LUVITDzvG;Gq%-sPNyIkw`IzFjEO??E`YeIEb9%8f*_E%?bbe1 zxN4CM<@Dz1u%%^3r{YjD%gLoSP&qEHbX>__=)Zy(^JYgq<_oIOho53u3D9BTslE?% zp8LTh9BApsn{{P@htNWpe{Jb)n`I`Cx`UQ3zm@XSw7w0;jWl0jN3C4PhF{B86S*Mo zqH(`E{zxZC>H`QJX&a{D2Y&R6_4UTBEgTPNbl4&D+~Fl-7spa7Bl;5zM~?}|eN;@5 zaCTC9dVmJVw57OfdQHwy4apQs6xw&@Sj%531CMo2F10UQb`bl7BbMo&EQBkC%5w$O zc3xpmcCkAt3Rv92qCEAxmBJBpZtjA*_l#Em^ayy_!~l$jgB+fS9$7i+UCT^CI+S`Q zQ{_=P)6A5a5l7G?F0l{}y<%Jw0<>g@mgp7B!p~MOaw(?KtE<ciB5=5|Q)k@D?SKEs z;RvRS)3i$;rVc#>HtM=DmE@UsYRadSKlkRhtWg&+lZyFDI4f4Q=e6Rk7{BX0KJn;h z{+0r9mIRDGC_s|RY15(_%i&BTui=IZNctDEa+U45OO<hjNI;CF-bOlr|9y;6&C#5G zf_bx(wCY*t;hB}@G&lEKM^9}EBM$As&TMd6+QqYv`pez=4^A{^jf7Mn>P9wjkzANj zhI}~QWzw}{lr@@<*s7~$KjIIwnrWss8Ix;Ty((ag+vSS6ufzp^z0TX{>)1}uP}4O7 z!3B6dqIHvY;5zH`0^3`n=3NsryI{&Podab1;;pssh9(%{vsvo8qpmWz;`*1rV%1mN zwNQ-VSt89rE9IUIG)rg%iphsoc^KT;3b@6Xih~|lw)`9OA<fv(qnN4ZyCU1+d2D`g zm;pexwQwwfCezsRbw5v?^{Xab?BF?hZVZ`pggnJ~z1AV;_z2aQj0#x6uoHBLbSK%S z`v3I4eQtP@m&Ntoqr>Xxyco5H62)r;J092Yoou)b@)WJ!hzf^a!ZhJ=`6w8v=|uCU z;1awBTK`4F<9R)(B4*v?@=R%_5{>cHodu}>-sqNv^CJx)eskS<e}DcPjRSa0j?;F9 zsPQ-(e0Wn(6m{A3^g70?jAz$xw&wLXP|w`R4GC#;?Y09W!t%NnpVONXE61PBhND$v zqR0A$JjrzNSIEjvdm20{L0eEG+7{d#+c5sIMr;jvxbSc`wh{VQ7CSN#^&OM;!x+F2 z>ZiRxwB-Iy^GGyaH@(}5OD252t;j<(=0X~B@_=ADk=O<rmazW22nZn>PKW8=WB=^i zsC|WO7JwuSov`3bQ^3Dgvft7G9$A)LfTGl^Zk_54@k3ML0SSV5uncD+BmbA&oeYi_ zgWE%u7?~Ag3GZt|3@*oLv!{;d!VRG0lGg*ny!H6GPgbAXD|ZDs-<(Py_RyS=I~HT> zB{KuM`Fc=5GL$n|6t64T(C57mDj)`b-m?hW%@Nv-i29mDz-7@W;?aF>Bk@jER27%4 zUUqBXNJp<9aGW*bLsHt8>J?eh_fw>gPL9h*aZuA^c9DEw2I|_8+9!K(CI)bG_xHWC zy7Ob^++veg#lB5ts0v<YFW}nh8FO$ZV*G3RE<d~hf%HXBozjP8?-=zE@Z>IR9e_%D zt@kPM?xpGe#8pY1^lK#GCH?vi>TvU^mW6q!@5$A0y@{zba%p?pn1NSBclI1?9{G!R zX845u5}-9Bd+#pH$uh6@@&$N;4}Z+DSU;L#-7cItIVrtG^w5C^HkMqwe>|+9wyale zxF2VQZ(pg}bo^sE-02IrZ~J&$2Zr>=@Vu7ZuJn8=hdp6pV#;5(9ph0%(4F30G|W)c zbUmgs_=T+Bl|1ur2<(2nAM=i@cHg4rkKnp)<Z<243XWIQbYoe}NCQ|m3p?L$C+ava zDQn1bKJQDCW&ode<Gi0YG0>QAz!@L3{Gsj7M^=*PkQrl{n*c7N_wKjND~gs4hltyS zoX^B9bH2|3{KOfrBgS#o?i&OTz<v~KV#j5><ja|APkF#yO3%A6u+6dLwg&JKu_f#i zII|N^h0A8g2kZg#030@*SIBu^#$<;@q$c-eZU(MjpL)KkE`SXo4^V<1zFfvVdszqj zt96F$T>t%tb3H0NB=MflQ^z*>+v7jt^!L}5p6IC5)Pd~1;|bkQhMN=4?U(3TzhI{R z?z|=J%1E~&7N1=>-B2>ey+N46&$la9P|@4FDO;a}G5$#ahv41Q!aE(X^=23w;tQgO zcnz@a{S@{|gICP!bel^q`>|7$qNC9L*i?gg#2(ch5z6EJuW5yWJ9psg`#PGX@sMa9 zvTeiu;oCva3*z9@l7@e!IbkKEhJtuL=bGC@n9H|V>y-sFYBP$m+(W~^%lEUc=`sN~ z5xR7^(y#vj->vOfS*Lw6kos?gKH>FKZRWp{JWrX9e?ialY$04o9@DWrGu%%&W6aT( zB8H`IMRf>o53SzkeNg!DN!;2$&(}SlE|*Se|6xQs5w1g7gL7AVd@649aT-i|#7+M( zHIt2v=GLBhSkbjr<Bh%=w7mFPsT&Ei-;ncR1rGSgc0a;onT}cCPTlf4h!aixujj{4 z-Rw3@n!8xSUy0V*E5C-VYlwTA9&v!LJs<yUht5-*k6U^^tPkI|zq%bb@ER?hof*^K zznhd1Z5!TsFF`g~dI?>}jsImX#>YrW%M}0f^Qq_W`l%CF<rO}MlNc+_2o^Guu1Uiw zz|8j}WRCj&^SkR5UiQ#?*i5#2p0+%buDq{2!Ot%{u1HtO9Bn&jgw|;cB71g&vDNTr zZ@ku<t%blckr{l>=jEZoRnJ&gNd<xY-lB#GYoF~*i^NPcomoFKR<72XBu^+w-wKg` z;`2y({5*yj)bv8PHsp{W0W4x7S+~6ajxv()Kd(bLI-p0eR6=&4j=_btTi*KUqtAph zGVcj*Q?B{n0*z3PIgKjxb4Wd`H(KM4+MWqDcD<s3j2u4scz@Q2aQmaP&~=TxiI0v| zdtQ?qICAz!Vkl*~ZotPHuD5sCNcP04<xS;v5`Ui2mVOz2r}+7F&p+?D>7&m9JV)cl zM@7(fr@r`@QN2Hp@K#f)*9Y?Ge!Z?FeT9e`axT2*RaQ#Xt^bp-wY^%eUSaluKI<si zzj5PQ{Os)HI#d0-ug?=ulH<cc<H5jLSXd|otkn--0RGMPFyLl0k$bxlG~60<dwqLL zs;sQE|A4zVJwGpKH=RtSFJnIf9P>P}8=ozfNkPekBTiP6QBV+lpHI_dCC8YXSyI)N zzNTqA_-)*I{M{Y+hr%91#)c71zpAEM^!h;k{kpX!7S<3nTWpkRdfpxOAi9yG@I5c+ z>wnt87rj%eRu|qD6&3w8&JJ;5>8q%$G}?bmb$7kmqCSWTGBhU6(pFOglqRO6P$Gs1 zu9_G`7PtlSKbGYpkE6|@zOfDMa|O?Z?g@F~`#kF#e~)#4C?m<vC8!7JzW$$gg7O<` zkKcy$*@*q9*e99I>3k799*_tBxfd$2VVXno{I0--06yNhG9l`eqbs`8m@DsDI)jDW za-~|?!O<}(FORSftR5e*bvAI8!RboV*Kt-}F+3H)7XF&X!!*h0`DjJL$e3{SZnhrV zEz)Bul-<|I4;f(AU^Yh-4}+sAgqD5<yQOPCgjxv?41RfeLAv?7|1v7dBXB*<{j_24 z4BN0S^ftqOjI&(g{7<*bgLxqC0)s!scp~}K%L4%cflzHl%P|Uo2LFILC$q>2$^zui zmohayZhaoUqvOr=eaU|66a{v=Gv3K#zEaMLl+eo^0Ioc@Cte$8otd`VZ^tRg5gxdQ zrgC_5crccyqUdvC?Il*KKf)eqwOZv0k-91>D#*L*>TU`f@z=#)g?IdJ`MiIg6JiSL z2vw?n=gVVMC(H)G;+RgQ3)e?>n%+6jBTuBzntEjH@jlkYoSr>+bSXV{-c1*5kKlis zWvm8|+4`Kk@4G+YI8O>Ae?Vsp^9G84D2yKe<+*_=%FXpXg8>I+3K87Knp&~*&H$De zCG60jCq_G})E$j@(FqM?X5!>SL~Cl`(=2SFY;SBxc^ClJ8qFn?l~IAope4=CEc}|* zZ@^VPCv=V@BQCQ9Iqj;ds<n2rYWGK=sbYFASTz5}2ojX`5R`G~wFuUHr_<~Gsf4w) zwHZ98!vXXhtg*;-;uzl2`qox;##6y$?fc)U9{c+f`8o6<HPkuu<Ef01`O)oL6+9fq z(P@6|X)C~Y6n4N;o#6<g$A~-r1OI&rMwRQV*Rv6KWjDLyk=zFxK3$_Z-9KvJrvwgL zE`CfDTqBDeZ1zf!wV!u}(~>Z{wvacbwUoXl!&gK#!K=C&R+VPv*|E{dJ^f=W95%xd zlyR05)~&x0yfYY33>O#I{^8B_g!pkr5x@Jo9}bY_gSNk-hCjZru)vtdEqT=|`u@*1 zmOlOJeFut{z}>Y?YdoFV(rl7{Q=-SrF##txnn#)8#f3+9xZz72w`L3B-_k#T2j^o? zS3u6s%(IV}tLu`Bf2&`wh~7F}4PP&lpHGZ{FT0~F-Rbv_g|r?3=iO6`>F4Le<Th`N zWCXx<bGwJKrtZqY>A7JWTv)!~YXC4aWHf$_{+aQD{h9H{rw#)ZrDx!M1?2<IG#iGy z?gT^n%FG9v2c{c_2euoQ2d-PytMnSzX>dtNK*GD`7#+5$Ez^xgF(e~LF0d(^{pf6x zUiIq4uv+2=tifn?E9u&GX~iv9!d#m&sSm&=>FA`hjgfEn%Dknap$j|1B=Ac0*I)It zU1s}u<v2`-6GUu#F}e}BxH7hUl!Yl-g%hQG<aL+5y5_!3O;H;+Xh$P>a`B5>>cV?a zVVo=CUo=vo_GGI5pJq-AMltP$E@8y+OLxt<U0qV(*BfR72^82vV~r+6K_p%Uws`=E zdS=!~nghFQK3Y$r4mYZ%ffmS^ef3ip1of&gxu2v134ey#KAax*Z=moo+ssow;R{b3 zTP-2EbpTAmQF9mz>{2e0i$%R6qu-zKNANjIlQTq@W;HP2nO$=yOu_|*VFDpp*4B|S ziW?_8v=f9jmrec4zg#QRB~jItF#wMowXN1Q@m_n6V11mngJ;emRKodIMFAevd4^+x zcHmnC*DRe8e!BIV#z6|)r0H+`zao-6lcJGBY&m>RriXz}7~I;mcGo^!B_Gd*>(RWP zOBZNdACzqGOp+*@mIrrGH-oe;nM>D*TywB+`Yu!`Z>8lXRb;z|2yRr2cz`=pFOQZ> zy*o02KMV4A$+Plz5u4mwdHlhh^iZ1l?5Rzv;)e)M;O}^wFh^L8(LCPkH>TBammA*i zvxNJG6A&7E!@6(>fim|lt=?cVIkcn(RrV1omVXqS_TC3V0$Q|?gBCB$3KcLFhIY?8 z*KxqI`EuZ72aQ#4u?v_vZ2*lXaAC5<$!Y_tR<6`n_pPemF@VnEJvS3@&uONqXhDye zW{nG&om6mzuo?zPf?CHylJ1a{>Lx(~xTI(1t!hp3p5RPVO`Ys2qoJ)>nPay)L;e2p z2&veczLR7h{o@!ddNxjQ^=fnEDx*=QoQN04uowS0E?%k@{&24iJOc_e=xN(gf$~*) zL6MsOq3rD{wf**upoHet1yd~oD$xCBAZaG$VhB{0n#`8p{sa~u$L3<{v6%+s@dE6G zk)1=0-eMLJzJ;a`^cWjC9!edHAb&HbVVeYBk&%KP(#rs9dcp2mt-(WI!hPd2q@qmG z<p)m#Ou9Hzv~wu{Mx)YwO7Te)nthzIBN!R77u-5+kmt>0?+0gqDn9&WM+!EBQ|l+V zZA5;C)dck#Hc}|fy93XbA3Q=3T9UBGI$!4V3<9cvg?|b^YE&2st3l)>gkfQNqnLdi zNg=6Q#R3Y}7`2>5=px$+C(I!Hh=GrvWfSVSfC7#0e%lrx>zU%M?KeSn$X=_$TuYJh zMsuPNf?VDihdXyLahsW-cG>JBhtoQa5z+~i>)g)?G5$0{)_VM45B)==qCnA)FQ-0- zdHdwjbxK)Fs6=>qj;hTX|2!pqzdh*0EsbNvp!)a&AbgMj8S}~zOkbvpP+b4q6~S&~ z{MdV!gi0bnYC5M@NM+8<JgigTni|$<aEdu0Zp?xQIpQt2w>1!{rZ6p%?zTgL8o7Pf z){0zc;U@Ike_1Ar%lQsX#BBL5{SZ2Y3?t>aG_FCt@K<oVdErr2EP8WxC$t(OP=<G? zpi-A1$O7T=1BEoF^%9ed1M4_`l%}(j(3#lrwz3o;U*nycU9KTs(V;P5UqP<;+~wE> z2Bw2mY>|l<xht2vNagh8!F@t0hQRaeWVf!3;{ASBHPXyO9&Mi8GaaOZ!t=pd2Y7zo z)D&^iLhgLk$wW5zVI4A1W`}Zlp>~eld|uLXz|S7+{Xup6`%fSJ?)12<e`WNK%yhzW z9rp)7I-YC|&JlsBtMuYvXsTj%f|VV;H-perdt6tftH5g@Bjs6igdJ2jg1SQj%<-pa zPHTEgd<Q5S!u4l!9PU%h#nx09l7gTZ%yiXGUdF1I&S1d=AIYkY3j&_b2))C;vgl7< zG_Uu&5yUG*9=nCnhZ%xQ!yI-LF8`H%?EpJKEOK83qNLj|_v_iI`Oy-W$O|_Rc?_Vv z_Vwv5#?v-)Fpcn>f{vEp1X=cP9?%W~VXem2-yfw}(NPW^3l&?QgO)?+Sp^sD($sr{ zXSORn))NS(s#qS@=VRMD4zUFcD`dZOjf!BB5uQD`bW$4L{<IE6V3!E*^>_U<EqILs zK(%WN!U<`sWb5@qAl{K{?1-_wz~Lk-w)D!^linEBNQ)W&a-LY|@9T4MpFPCH>LnF3 zF0P~Ti@%-Ji@9d2#Unx`38ZpF8o44*xuueSQDyJM$iP6I2o^3At9Wi|iI5}_$6C+2 zlo!6{E_IR*5*Hq$xA~n=uE@8Co6`9X*vsB$iRqXD;$Q#nD2!JkTQt%*O^$QHwaMAu zbr5$q*IUssl|F}3P~j-Fyy8zNHsbR+!2QgpDeHw~j}s5%)qbl9qEaa8r-~!Uf1avV z2=dPCcrG#r-e`r=CLKq*H+ffj?icxU4Ro9o-Fo46LSH7KMmi&PB&wR(p|fiPo~lY> z5_yMC(Co}b>^oUCC5=f8wd<)4lh0`XCEbq0SFc4mTW_SUbVb?AXDBIPzL_wTwNe}< z87SyC-8kzh^eGKgbQhMJ%i)nr%sHGVjL*#5qb8)d+QfILw#6bdGt1$6zSfMXG2@Pp zBx<6(?qSO1f)$4w&Pk0f6vgoYl9vVIc!WolopHtJ6(L9{&PN;##7G))XImX>v`EDf z<P1{D0);FB<42b*oss6-8ezf%UtvpVAD+Y9P^aX|W&fS&!_Hov-n14rXyi)d5O09T z)s&--Bb@aG?G?*qj|1h3XB_(=rJa);BkSq@nvz8@p=Vf4+I6pKFvu1FrpYO|6jR2J z1?fx7lwhw46_$W<conrf7N_iTC}|<o24Rcja0I-W6tkx6h4W8laN)xd{x8P@E=CkE zV!Q6K*qBukHa7xfq5enL)+bI3%>_|^Y2c%zP95$gnXS{iQO9OzQe+q6D%P19@J!5% zisOgo4lZF^%AUQ*X0<#3#POII;u@eN?fz84C^WjTL+$Wt?$BL`u};0@q9qq+=T46u zhdSo3p8Dlzp*#^Ftd^LQk&~Fy1zF#jpG>Jk%17Us6a}y2z{@*9#_tcJL71H(lm?GN zN0|*tq!zwosALz;)GKPKhd~h5b(*n?G3+${s8;#io}`lp6pyC^WTKQX520bC&`~V> z!hCA`_mhjlo6?(hL;uKk8f3{wPcv&*2qB&dkj))K2Qn&YgCD-aqmP$@z2{lbu#^|$ zisHo?uD#{XgM=?o(!#Ly8}{Bm4JdW-(ETormvjou>&&D}5h%lx0@vr!OC<KEOW_aW z2}!2I4|MPjChKPdM3#pUNU<uNIi5f>RzXqF_96y6LY0?IKV(a%P(ONbA1DeEuTek6 z3M<dS70CnFmOZ(6*p0wbM&(v7?{_0=D}mJn?P(a6rvc+?VOf57CPz;YS_<C0lXRoY zG;i!!mRxK`<2v1m(Q+%;`*=zJsQxNNK|L_w9GCb&Q^4N>@(@CdTwmY4^eDGMhUAkJ z$~Pt!OxyH|f1of+J(9CxtLZwu7N!3vWf_fe(T%ATvFkN$L&&J>FX%3V{`2mQvb9&t z-n=^jny|WS5-g<Cn0!SMF~IvHRx@V@`*!G*2PE}1Pr=umobM-G8i6W8TAm65NiWc1 z6f~tgPspweKuGDOhCtFs!<+~ovM2|OBQIEXP0XAK2~ZF`)uX?WgFGlD#AYhZlTs@V zuFsW4021Z~*Xws+jr(~n$<c6?1mEtwS&-rDC<;QvnjGZ`kf{g?&sGK(_cAam!C$Eg zl3d#}E5UXw$zg8P1ds35V#R;cmx6xg2U8Hz`-K3?2}BW;1)H$aVWln1u(Yazr~N$_ z<q(wA+{`#Glmr=fSeTiR@l*txu8o<Mpm<dTALP<U1sn95u`GOrElQD=OY=xqbA!`& z3oJ?@s#OH5?D!C-f}s{?ao8$@kNV*(%<$d?5T-(SOY<6b5tyA2l{DPVe%zPmJ@tkx z&9(vT1Q4>IYRdA0d<}&1gyo8Y*Lw4U*YeoYLeK_)<XlcX-zp{dZd#a;Cl=qzLA{G1 zbfJG%2PgLlnsYVcOrCN%{g9g4$wR&F#L|Glw&H4peJsseswGGWS?*O`lKb0P8Qi`z zOogWb_p>6;xpsA05WRn8aaP#QhUKR=JS(6g@2L-earP~bGbDt@PjqRv=vtfk{s+eR zVcx_J0`on;-SJH<n2wy_CLKvmh=*PZ)>#mKIU(jeoLlM7qq01oRw0C{kc_2RWE~Yj ze1Cc7#vey0x3O^5@`7O3u~-fR&_TZ+W7030m3GMuEv?YPCz@e?rU~i%MaqdE4ITr$ z>@^kE8YUgwNSrO^ngor|?p~kZr{mG|7Sr7g)J)<dc}$5RDXz#ZCceYr%J4e+JrL^Q znm`kR=4DFpsD#S1C+f}ox}<Ti4JueceDt(`C6#ZZTVy%9`&|RUes(+lI|k1oTbmEj z81^sB$=V-pghdB>Z}^r>>FDDMVbgqoF=GP)>kwj)yMUtrzcm6<*r0->WJ4$gtqObp zFgnbpyN!`l%cMIa<c(sL7Y|l7Lw(uq^Qeo(_<|Vi)<m&f0+VHPyUFR<<P4f~u;l43 z9G8F$MVNb8|GQ?u5#(z>NxJupb!rizjERP7?|Jg9jKEi7sMK(k_3o{?csV+NB6Ctp zcF%e${Lz={g?pY9cv!x^^JwKDsZ)t4`lK;-Xn)Ue<NW$3XQDye;kgJ8cy79JO&p$T z7%OM^uGg_B-|TF#VoTui*;k~kU17p3?lW~Xt`TMi4CF$~z(y*w$ytb*06}coRzJQ- zx+$3f1}N9Pcj0B0Fxp>3Ktcg9?bo!j`L14Qv|JL_)>OsJ0`(dP&Yglvzf)AA%^^%3 zY!QJDKVUt=^+n!5Z1E+}aE9pr(~VJ>sZ<`0=V$&&v^=3R8!GDAxN<7ou*&?0ebeVB z>dB)O;(3Z)N1E;*@GT3SHYyFO5oL+fG0C{wO4-oV!occg<z1CP3b+7($pTPaTA$y@ z^Q+(13OSel-~E~D_6mhW9j8S7s!-$xkYFO<_kK)r`|;#bTs(U+DW8a^h}lGbASDu! zN7oryvKqxQcVHImocc`ZSP_)I$Lpp{^ajzN4aiA<=NGlQEse6GZkVr`!An<n5TsrV zg(u2JB0SRIo!mODLlb8}wd;7b4vO<{JzX+m8%d~nF_%)MlN$mbM09Fu_gAv<xfvY` zxg~?1Xe_WE<Ja=Cg{ubwpj_Qej|9?3a9J3S)a}XxyGLwo)4Yc%?IVVHtV`?t7@`)m zV38k+iMq0b7GVMW+aDIyo4U)@kWI<8ll!?|@#jz;F<PE-98+gNX7Q$#|0ILRuNGBC z1378`+*Qs3^0uXSd}K|F3uBE%KI$b&YdjS1L?P0jRD)(gz&cP-*`F@_d)K5T0B*uj zeu8W=`BG;~a$z}W>~MFsBsn$@!+0}uMeO0S&o!Rv-Y`5op4FH+kxEt#B#tJF-}bEY zk+=~rkY34==j_n{Xd*pgEt<q&vSNr0uion?c-ZBj5FRB+M)i=IK6hI{?`eXdfYS?K zD}^;RnXeMFB`6HI3!=_qtIs$wMRig;n2$v<`eE8%_EC1i@(=&h9}5`Pe_p~vVH^o| z2I3$e;Kr)yX;QHSf@byLfhTr(wFE2q2OXx|7A<&6Hc}9Phvz~pYE}qJ!F!5H<HkW) zi&V<m>5y(d=`+LPkgd8Y2hT!!&1SE%<%qv?!+2xV6J0!zUcI}Bxi^97iP-Fm@#8@> zCgHjIBu{#}Wr<vcmk@(sN3t0y4c00dMvu5Q=k13PoOOA48W#g51qGN8qx*vHy9;0! zE}0%o(HO7*GH05oX2DmaIGpm_y^2{CP;J)B&$1K_Fd5#3TP7sF`*RPX<kpocfk`@J zkSAC+DEjr>3w>Um!oQCmpnHlB_$?WpX4rXw{J|*%l`&C-jwaE>GOX#3scUt4tDw@H zNDX9NE6l|kfl;L%Wd$*z!%Oh}g+Hi^<;=rj$I8$Ft()fUB#0ZsNvCoUgY>9vY`+%7 zJiC+@c+gNMA_S8rjfUXgj<|~ht}>4*F-jPH`tR##s1eP)tDf#9Hsb<_9WsJ#onB-t z_>8EbCn|^|<6XuF#+fh^?td(B7q|SF(kSHGJ%-!oOTf4JocOklAc?SyHnO=m8(_jd z=LB~FGz%^?1jDc)=KLjeEA4f|($hMFti3p^6oj5&tKmApAuE5rD?KrX)aK<$BMU=> z-LCe$H{uLVBzLKUVk>Fz%+u9t9R^_>Gg?J_v?wAstGYiT%Gma=gM9i}r$8*-TvKjI zHvFt%wnGHPq4VfLU-~iR>+{*rN-R}<3_U-<3dV<lJbJx(LWZ<$SzxK_zq3}2>as!f zFi_p&xke@<FDlJ^uqd9F39$N<;#K{fHMQifEa$!9?|EK-H8ea%grcIe9{-<o;@?8Z z?vUhorP@Ng*<#Xt@dS!O^1*aCj^$CXR{o#dx(b7<Q2}-6oT-*#ywoLS@x1vn_44$9 z4Q@5aflK?4)85o(1eNdfIe%klcbY2MD|>RAG2)ZmxISpo=FEs?NMd!mU(^!gg#o|! zZ%ops?gLd9Au~U`PL>}qEiO(^7{R7ne1EuPwJd6@C6$zR(9QnM>uBXIgkZCAom(K= zAm6*BghS7T32KAn@=24Du7YMC7@?^J*jpfHEC;`vw;G_k%rP%l<*Tuv=<8Rq&3oKO zC~xqTtQ^<;8k#QeM_u!A*q&qCiy17+#*1rfG$S9*GY^Lt-9*<|se<N2T*FYAFMeR~ zzYSOS>iuWp48GBY5rQXW;=swuq0QhzCJkYId@G`dsu37U!34?qT#I9O_hcpqK-HfS zNtuj#^o7GUrA!G@(7+->`s0|EOjPtR%3GplerSVgeXiP>l24}DLe;_S9@i}&XsBpw zK8mboqV>}eU0;(<o7%x<m1nUUt042ncwghl^)^BZp$Xj+RPCRL5qp0!rnb<bSN@D8 zAtmYJY`O(Cj2n->R|wt6hLz|WAd7M4!i=|}z#Fvpf5^vV^y62vE6%Ju%3RKYn60S5 z$ygjX`EaZNvT!eKcz*6`Ew}>#mY^7aEh!Nw#cvehU+}9Sl6*yw0*j`$dRN@427))h zp@*5Atgf#0&2<DA;mO`36IWAHpA6owna?cq2s7LNdjS83{eQ@INT`eGBvUAcdg!H& zdo^)0IFTq?b|A5`d^NELM_>#U*LoOmP$87N%L+CiJFTHD#2drQ3LWH&?ipqLC8Y0X zk|Rs2(sWb6sRIqp(P$fVtLC(De}V%ItWLb++;vc9gkR5r7S$gL{c8Xs3A|70Z%9Dh zHzfUr<W+?U&?P*MPuzJjGE?f``T7P$fo~n|75aCe$n~%H6X~AIBrx8ozWIuNL-y#v z1Z)=t_5lcwajq+VLvHg#9?$2Md<)`(3E&m~22q#*fW-fZ@bd!uwsXJXo1sR&f5(+f zA8>8^t;N4@p?DG)Ue(`x0x$tR-@LTn^~aR@*OuQ^$KNpX4ckd{&(C(**r48r8}xKq z)3|V|-xM+5TFrdF-I2Ihab)5hiFdfZb!-0(`4##<abNP&S@7)NI*Wam7i3~X{D)(Z zz<)ZkvjVUb4BRfAo>iu^e(W2%+rW1c98U+@9&V`H>Ep~q1x-2F;B*onPX{mTxnJUt zB|7f!g0Z{OWG44I9`|XmyYjpf9n<*wg%O1G)g(G1_Yxn|fYt`!K=Nu%YlHTTw@L0^ zJaVamP#$gwJu6I0`!B@1RsXVyb(C?Fo0bk<IRI>+n8iD$@Rt~6XTa_sZXC+d99R1; zIaEV)Ib2FWU-dc;*(GLXKpu~`{k9u#JN>Sf$P0I1ip#_}FV~Em=xlACd|c!eUzl)O z>bN0w)o!x96Rc*>@Fon7(rj)^SwXnzV!&`Ft;X9gFY9|q@z`gmYgDt!GPTym-)8h0 z0?-|%J)0R1kt$yh>9UBo#m;ZtJ$tQ0vsbUZwDMUHSY?+qyEiXA4=nR!4`V&0D_^1_ zRJU__+oG92R@zG%FYIaPWYIdTHR)BC*f4XSM36gEcdmDtXR}>x@P~OHQy#lny6()g za<n|8i%INAlLa+SK^HPLA$ud?Yl)(#01_Br3uOQOu4PcQosQypj;wJoUSfd_KxH~2 zS+ZI%h3-4=b`5yDeCQ5g=ff&2V`rWh!FW2U-a+Ha?luPsB(iUtLUhlk4?Dx0>$HtG z*;IIr6&I6Wd+o4JbwQ+%@8#WRa&)&EsxoU9!~PxdO3L41ty(L!F!}_w9q1~*1DvgA zP*4uNxSM*S@%q92Wwz1X%ho;BXdG6&`=x32@`$z4MG4fHm{@7GEXO{-6fV_Dk_0Ac zs(75AbFW`H&9vdmcAc|$QdVdqG`O?!3EAV4bhUa!b>^_YGKAM2o#PrRb16ydn78`G z9m_9gz9o}vIkR>gagX0l*a#un0cdrOyQ{|0nZkF<_f|)ucHurLwhS1{S87((F2f+S zn52y{;NmmOVNIS6bN4KiS|giUqu`XSdm%=-WViM=Yx|gOyF8bsqBQYT2l;J3B>Ob$ zd=k5T!%p0&|Nhzo#;{VW2S}Q>sg{Ks5|n%yED9u$(V5vGhjKaST<JIv0V2L;dj@oz zEiW;C^9;2-7810CgLVGhtKYfQTzTDU^|198Q%6Xr{hWemt<#5K$gY`=l3KZMsNAv; zsSBfHWFawEg*{>|mfF)!-aK-Bwm7bSyK=OyQIsq=t}ZG)(z;9bz^m?us$UhblifH; z<DKbxr^oY}Q5B!qvwu442J9xVM@5<)qUtL@!7N3+`(z$i`8_CWvd4-w4_p6qE4MX~ zte~!Vq^Z8D!WBmk+Q8aVze5Sn?{HwwFLL5hU1CrYRU^^Sm!(xFQ)K~ESc;+=4u8Zr zfa*nUtpyj8G~rNKMftmKVppUe(Hwj%H+7er+oRH6>ga_1GrD=W1+WFHXQGwkb+R1z z{Zf_2wcteJ9U1y}K8~&3)Y5jf=3CJf#(A0KsO@O$vb1&F=H2CdP5&!<qPpdiex+ZS z3~h1$IvR^1BHe0~55?ojUxTJB9LsW}TS}Vb=~lFLe7M#{1~(^*(0`2`;7wGjSz~!l zI(WrU)Y?q$BCF452>6(K1{d7RcFsOzz8t}ibsq$hVpXJ8ucx->P--iz6X_^n4HmEd zQuM~Yl_i18e2m@_(*tH+mysidUS_?89^c?@IV(qL;;Y!qQ1SA`?&e2o?8smgN0F%3 zJdUnlzn43-S;{1}xWKXa4F_0Gr`J%ZUQZzk33CeSAl@w70tO!0Cb=9on)FBnqJv{C zKZtB#94RsL4%LX?e}o#k(;TuL+@X@ox8(|zCV@RBl3q|P-I*y17tZ_}bwc|&Ep-l+ z!o0lHcEsg}dUIT-P+gG5f-1@205P0|IRrSbn^xD0V;$!cvgY=0Pr?WWR|7PpYfG?C zV+{&2Ilmlu1I)&2aXSkeXEisEABgIj>fJ$n=aYtS3_l)-9FkgwSVssT*fr<kve_#T z77MZVeV@&|g-UdR90-mU*QB-9Td-H@8mWWVlV*KI9Wk`mGAY+=^S5;~O^5ob*4$Ux zkq3_G22hUH>j&1QeTtD=2a{v@=?_h0Xtyg1sxrb$03?u~JR%6=$CvI)T$c*Lmn>Nx zT@|)A?ErbjLx!t%R3&)PGWY5bTP1&5SKFMchF5B4b)-&VG>fod9uKh2*wT-K{i?;w zHTm_`S_uSZ23>RMMdwKZO6M0)a%NN%9g8whW1DSNuyg7)LK)@wI}KF6QysNUr#oCT z{xWAy01ZuqNPtJLsY;&g>{!!avseAt<@xB5bAywyBDvWg)5%JW9^eO?gk{$GG{xRN zcWHJ=Y0=a9IEB*Aq?VW6k8zf459~|9x8-%YL-npHStU$2C^e<246Crx^yMvhdFCq0 z(o&7`TvQ?Ej+z$zHq)u94W^w;5%^8z^VyyoK(*$`CeagE(q(#x7Z|#Z!&KTx7KIIn zovg!?%h0}<>`?KX?={tCFeOC=_E_-&Hp;WIPITOJays6gNltd<VN}cQhi50k(w4Fn zp8wElyXvHkhDKDT(h_qkFX%87NT#tMxEDkm^cKR;g5AFLU2CFNicn6HyJ4>NOQ-D? z0M6TG>VlGM%-O)ztveUuFI}$mnZxTHEeW0m?I;#Bm88jd%hhO~&En!VIJ@-l%lyIR z=Sh|SSJzp9MbWi=oL&%ELO?<mknTol>68WqL_$(pDXAf(JC`m=B}7uBl@g_60qF)w z>HG$Gp67aB-{*sCuAANY-T!mXIcH{<<@_1%kkidhthADrjP=y;Ru(}#H~xCQV=|Uz zUP@%kZ0B4<o`Jx!&sv!;2C+GZAA`4+=pq{|o%5~ho`XKgDh0i^$v({5_3O970p7XU zVp|G>YFnq*^7c++xYRO+PK#a~r>v(>p*<~6^-M5x74hj?qq^rLsoBMdNVWnn^=OQg z9aBWZ(`7Ra)P&k}dk&tx`id;A?!i_^!`{-qDVJd&<ou1u6gE+_lLLTn74O_So{F== znsvxTi^22=si^eS(X&Alw!hz)1r)X>C*osm{nDNeZ++#+%b+(F%Ec}e=t~|Lqi?nG zTvx#SYwm8SU(TzsL*Jtlk;(#WB+s%WNWcs%4s&cqO+*3D|6K#O0H#!*$+qqNYAP53 z^!Ka_Gp`5=5;37c#eCIl!Da-xw##m%0<pZ0Lwzc)&8ui{4N?>m7(s}t7r-VXErBq> z`q-gpZ2uu0>mv8OuJ!F@Y<)IOLP7#z$;V7yFZ%;}PgTEM%V1&3dC~ab=sXYJ&FE5S zgm3tr9Y&JYw_8NLCmV?|WDQCmBV1HCI({J8RLiHbkC=zST`M}pG^P%CdyFP}AIzNQ z<T?kBPIU3Xv{I9xgsDj^6aZX^M^ahp3GZ5-JEm{5f!-XogB&gjox@hd6EvD5vA62q zE{d@5=>^gp=pNqD4vuDV5Wq{<jo**-p!>W_7&`TF#(4wAQJEY}%g$$s&+)McCQ0KU z9R75?rUihL_$7Afn`feRs!0{%P7-GwAZVTUecusrAqlA>O$vY4GX=OLsLXGPPMi7j zPMVV|Dl6CcHtWMzkM;6@hyA#XvOglSYhFy5Ln9%PF6YZJxxO;q!&R4T*$1thu-lH{ zQWkhu9<xV(QeFH=@y&xKe6L^MIF)Q<q~tmrCRfhGNehD<X5vRtngz!NTdC1fo1<n_ zmsfqLJ}dbY`x@G;r6dD{CF7CXILq3e6Hnw0JE>bHhwSM1Ud_{vZ}1DMkCmwL<&SO4 zH}}>&2%%<~@X}AC8>5MIg;CWOskex|>_qr)%VG%~*TiuarjgmgKBxrCS)V9-`^;sX zKUFWcu72;7+mVD`uX&rh@B4YGWr2=|Npp4Lcu8u;FkzB?VTvUXWU2CyY+wjsMD+q+ z<~h2|el;<PexXaKj*Km<@rdUar62EUHgwb_iQ9T&Tjd5$9-=HhiJg)*>t->W%o#L; z2Kz2GnGS4nwuKNQp}gbYSo+jE;O%MRFnlq4E36O(L1IyFFKkxO#7>t#vU6;w62Tvv zf9PsI;n~uA<df0{+%t#Dd2W}{7aq9b-zzCfFX)3w;r(=tU)t2AYL2J*$!j;b=KW%1 z>21}qWl&NS!$cVq_y_)#TYVCb-5r%G5%>vG%b30#?U~x&R3@A6wiQu4R57sh(YzC? zVvy9NX~FBbHje(ld6v9@<6d)7n3k}!I<ksE<#<t;x}bBp7*N1bDyTxazO*W^G*mUO zVo>{QNTyT8Aop8QSl<KZ7?34$UCT*bA8K0>b}s)}6gI(FpfdfK*Ev3EbrZAy5~{LZ z96~v3iK+HFF3h15H(|0wM)IjJ{mjfWE`m>n&xA_khpL_I4;+|_$!*_lW=k}dz7>%2 zUEsYBS9r0I3TRl0nWHtP6XMp7N>_<<BYHFY+)2n){eJ4D(RNUz{Lb1mC%rG@wP~JD zsiEETH0yRy@HdWv$iu`$1nk2AlL_{Hn+d73EE<F1lRQb0N*!v~^J1^seCP8@hNB8P zq`;2~dmoS|z70W{S;+g=pP(P+ifY_7*qOBrHP0Xe=bymu-c3xIRGQG&Bx>NA`9P0K z-eZjTg<1oAL0L!sYDmQAvgmG4KoB=6l18?YcJv!`hefszr7~F^6J?1lT68p+$nV!= zYlOHd-OC{VMpE=yMhPkvZ$HZMQ>orSlch#EQtx{T7}jV>If)j5DYQIC1&KdrZDaTd z@(E6omH^}Bhtcx~@&qr{V$i)8Q)v=N%+6jHHZy<2FYtW-Af_zUF3650?E{Up<i0KK zE;sM^nYEUQWu>6hY3l40WBc6WlAn_Txsm{@mJ#kjnC(bM`H)R<{@6v1ZUu+bg?9?2 z(0k^07j-({oi&<AVwkjls5PU0kKQ1*SnYl$$<qTwSEI7^>5Q~A%&~i!sir)5Hu4oU zoS$14;}c&8;%;7XS=8#&UcIc>2^=o+BNg}vmnDx}rp2Eq`pQ9<duSDSMIp3Ui5M4I zb8@`GlN){g%||hE-ixs^3Fbn(hsu@Pln-c<EfsVjGO-Lv?ucw_d~D9XdTUwE?)wsn z6jq7A-YYde%bX%Or8{YsdcMwp*M^RGHlwy}P5wLo-Acn#bFWZUQ!9G~<5UgTX`&Cs zaXhigkN2p(;!W+y%w;dw0+#efWk1f56>CUKW|Ez7?C=@92>SX^pYoWvLJsr{VVhXL z3($zeg)8F!QnLGmp=h+?R4o-7xn7=m7HM7!5J^a=nq~?A>Z8YZYRX9JZ*fw<TJxj) z{@JLJtlPcdiGGS7Q}h5&g6Y)Zwqt+CfN)Alu#`dZ+t+t05EV8{TWK3Yv5aLc5`%~7 z;g7ed1D$y+lB}rK`^QX)@$We<C%RS~;Ea{JtYk?tN40%kDrZt23pQSsoBKq}$=gd* z1#mEQ!|`7j=uP3qReCNIYUAJA@yL~zEN&%yX3n$a;Dp<_aw~hd%FHV)JAv&dH*QCd z^IQhn;`|s&1*YdW7<0_Fra`q&!Ky<>{|~1PQpqa)?m&mY7Z9mgk$ww*!pN6e#R)sM zK4gBPb)d6RYQ?!`;Q&pBQzrbjo=Rw^KJZ5LbrezWF%yU0!<SiPv2wY3x}Sr%9`S#5 z$^!3tlcUP3KN?QtHSVji#}_p7p_YpvriCVd51CGZLe0;V)Tn(sQiwc+pIJ5$*4|Ck z-#PG>UpCPx&MY2tY%ej2EgdIXJA#$%NyC170*>fcl#Yb(#3<HuT>S3e5v(}nIuyWT z9{)038B4Qj&!?+7!?JG@U9^l5RVRf5gHE&Tl9d+SatWmvXPObrIA2C6H6#0O_cU`a z1}8=_Pm;bYa#<nrc{&r^%4GvC#(^iu^kVitW525|U7z#TbvuE}N`4i$(R-V3eMzT1 z&OC}uG0ns^r8YtxeROA^SFXbOn`Jg&n7?{TTGppPw1z4~8=gQ~ujTHaynwCyD+7&k z5s8JJI^~0Oj+arrI{9$&FYLbcL^hJK;THB1`#yA8E9!M@Z>X`#L!)HcdHF#Z`4D9} z4bdD|OG&!lGFd79OR^?=C^Wp!H>1bPe?>RP4DtN%=<EJO$Lbj6zVN8Pq0}@TNa|o4 z1UEo(34`$Csk$s{)h$9;-f9>s3KEGiAn2DuhBFh%{f@s~R~7EN8Ead4!paY)#6Pl3 z?o1}SOhv=uiIFK8r<V6(IizEtml7!`+;YUF+`mT|)tB}CyBUGvM6ac`zQlrepmfh~ zg5;W^uv{8h3f+|0w>3f>+L-|A1w(*Y&Ov_RK(3K`-mxs&hLn0<m#=!>r+jdm5vL%M zUvK=nO4=a5rSkej3HdhhZu9iQ2ju|TkOhVI?8)Pk?8$O9yyGlxNvEQOwsFf$Hj?T) zk4)P)V_J_3T)s18(90OJDXU9h1+rK%6r*-J5jDJs?8j?#cG|G76##e$-ZyzWSeM$- z*$EW&=2FMhM%tl<kLoi>;v&)d%i@1)GS1Nx&nD;Ru0(xgVhLI6=v%_{UI<PBpYUh< z+6N`%t{flNy@jqwvF$dWFexm#?MeWXdC8VXm{G9M9=j8}XxU~U!BZKbO;iz4+!o;2 zv#Yk9$19iCd0`)|3S5d!RrsBMyeGpJXM=jgk2Azfa5ji=WQ^4J7)X_h6+5xoODpu4 zj{eB<%(yo5zA1|Bv5-V$R9ds&Q)ZLcmrQhv-`EA)bp$g7c6PCLGiK)WToh)dpM-A* zYjy8J`yR0trOCsM9&9V{rn5QV1&^p$xEQMwOvbtUJ%3P{Hv%XM7!Aats*&}gcCaSb zYt3_}lDUxs=iNa_aS1Ww>wAZCB7CFvNJ&;|jfYrB?)zojOyc8NXAq3VOfj;{y$=#w z^Ion9OQE|*s5Fw)`b-+Jba``*+_121L}<sUn`cx9)qt-mpf-Vq+VW98keyhM+t_Qz zEq<n4^JFVG9pL%C^C1c=6Sw0z2JCa*rQJCDJU;Y?{1Y+CsL{MHjNDHLS|nRvzIO9u zrSuM&jkoaK3ZmV7L7q#ofA~dt3HQ`5LyTH<=Td<erK9$;HpAX-yaYyJReW}tN9cQb zQEhv1yi6r@usO*}DQQ(;GPv2X2QH?TZ)<BC@W&HlN&w(+C2*m9yiSRpOvm}*bT9Oq z{m)wUlhuMuy7yfhE=unom*rcOs|b;kljlwYmj*9n=MK)iRd57iE-p^(SC5x78Qn#; zn^6Z&_Sf@7Jr0<Te!l7z9T+tPY=1hsZY3tN>E07PUWgmuY&x4`d`{)H7b6*#30&xY zjIQOZ$OLZh2G2}XS;L(`*NXzU(w-)L(C2KUW}xA4inRe;WA1bTN-5xp?nUplVsl!q z9q)8d<)LGf$TyuIP^5?LJ`sNpH??XDB_7ya?9LP3s@FW3@yGK+WjL!nPa}N_TpSl@ z85le|myi?3SKWD>7U$_E0(+Ef2%Kxv>T|$>?yd31hF<jS26ge4yWr7KpfY$O&eJkH zHU;PUDeUVdg!+PI5%-7O{WD^2&mIkFsve6D4h_+Xo~*oeAC5VzKUsTE2a&a9xj2<j zQ5M*2Jhf{9TI|KoMoSG?Pd>}%ilZz@oQv%H-=Fr>bl+*a<J^7s>nH3cu?BD<e?A1@ z+a4VnDqN(E7NeV%AQX+NFA&RtLm4)2Ogsj##)ENdx-TrxZujV&kQUU{2?->sQ3Oev zZ~?nrjLLFx-lwxcRN?I|*?71+R|X#M4|`w_VNbs5v*mmPZx>v^S{0-{5jo!*q#J!u zx*C~%Zx+#hQe`!*S7VpH`wM7MEViF^?4Tq+&x3u5;V?bTipcWS?gj?7Oy$s&<Sk-( zD;ecGV8xYgJ0_C{j-HIqo&#Cl1Z<+aowVM26Xnk#6w8lJDF#z11Z<)kPd9~Ejp**y zbX7lQ{1s-pZgN>=16p^6udF+U-p6@k&*@Ifnl9@04kqlCAhg*A00lyzYvGQeCqcM< zosi?YPG-@`Za1gWR>NV&)I9m=cB*|N%><}9a%gRB%|HLKB}sle=SO}v@&Q#&s(hyR zNzoqYIK$XDwH_&snQ~uef42^HNPeCA60{aH?ey4(H?5a`22DHLo;_)T(x`h_A=Ai* z3Xsq@=Yb9baRB9zE8j@gM%kwz_c!eUsL4r&!0AQ}wpW{Jrqf)t?S%YRw&BD2wpYFs zt6z~W;(FBPKiZ7(tWLU44<lqAjHpq#Lry@;4r;nX_*<8L21c*oGkUi^F&Z)%AjpRQ z*PwJ68LxSCW*DUZ*16zE3zQ=TcYG@)Cw!~rp7f#n;Xq`s*r~EmQrG&vqJFgv&1;h1 z_aCT)SSyz*SQy_sZoZH_nO<>QO120t4SL?nop}@q>1qe3Y3~wf*Qp2XNV%FSf&r26 zXYL9o;&cfc$`?{EUc57{naFExZAC2|)&7k?<ccSoB4A5CJDn{BS$kX(gGg&R*qC7N zj~k<z1nQjQN^9qCSsBJ9xP%i%lD!d!@hw%!rtp}B#wR6N3N<wkEOf;cZ8UnFZpK9& zBc4YofM>a>kVEE5^RLjJbm7}LpxJ1;KnP`!z2>Ln{-Y!=2_B_8PaTlK#lgBC%iBKV zSN*u}w4(M7b=hS#W8Ch_=$5xSSa6$jJI%5luo`5zw(IOZZx7F2{tUWvSiE85V_Jsp z?m`h0Ed#9q*a2tiQ`9j%n?pr$@rj8H#6(1x6UyO^PL%7^r&@hjW??I#UTLLoslHfB zkD@h#wx>6I_ERFDyM|sbMJ-Crz^zY&i2nI$#&+w0)!l&@@j8K*3-UTtV`AX61ImZq zKjz#|qnh<~j%ItF%9jsWah_w}eN$@aJghw+xSU2y&&a4$Vg7?qg!(i)FQn?e+qTg= z`^}%9^34cj`^8qJ8hB74(0D>Z!p>#6iNHPn9*>g*W@ct%XM9`m-_p1-+~%w93^_As zIR!0`DWX!<#)^ue)B7Xxqt86phk^Sx2rkX^)?Wg?m*pKW&|HIY3EGFkTI5~AvpTE_ z(({uCySuv7*Xs61^oNJlG6~#rrU;zlDCsiD?%Sm?*Xt0b2Hkdsx&Cw<_@2yb6{%?7 zh+^wRjw*8u`u!62t+LlUr|VYpQ&(VX9(4kyo%ljrWjhh&Y0-{#W!{I3z%~`P$(vfa zy`JyibJst8`c&d4J_nk0ny<||6IW)PqlU7S2afmRi06uY$_<;m>AE{TmdfHXNJZWG z1}B`(Pu9yuEA{pC6nmjmVrky@?Wc+}?%(rJ#p|^${UnQ!DB-~{n&i7MP9Ne7@a)MD z)n7xD(^hG!t4oO8?Ey++ngX|KlD!lKuuAzA5Bn{Mx6TlEar(KKnL{jn=M&wb@Kw9I zjLb|`_qkx&$Y>rOp3Z6_u5^c1EWhd(XE$b@e15`lx}gytWYi(sn6lU3xjXtqB_MbG zkM0Jc*M*{*1<%Nm#~O|os8TVrvMP~%SzBKZ(P85CD^Law3MX%?im1<Dxpj6+1e*F0 z2&R)9()VX4bNzBuKQ{Y4m6X8K!gM){gOP&KDAIpCNgNPMe>*Mb6}{A2xh335Wmocb zoC5strz+~gr}UBkp`Pif5{XgsYY_pCzR$kr(HHpD=m)j~+RN##uzj;i?f_eb-<<b~ zmUXvb4L}WIx`^M&J(~2Tu@pIsX+3u^`VQUmLW)jVa{d?bdEP)U1A(}z*VU^k{W)8E z88sv!na@h2!Xy#eLf1%%&m()$1HS4>?LO1eqKlvuPHewBRI(Q)aK8(AZRMOk4#Hzw zMR-XU^*9K%G3BTLmEh6^vmory^=zIdLjzA5I9sPlaj9+-uW4(l@w)6gI9HlDRJEOM zs`9!-9GqKE9QNi{KKRuLz`ZSiL5J4N^FW1I&tv-wVH|r+<kvs^-*6t;zd35_SdrM# z?*gPyfNXYtR<eHX=qcYbd{08p+nz+8#GWLcR3cp%T`5%zfp`{8P(Af~XbeWltz7s3 z*6;J3EjLmKd}cb%h;2!>h4cYxuiWf(9CxoqgYBWXdofjh@we;-k9!6bc<5@O`^o|L z98A*NxXAMR&z0TRZ0hxW9(QM90^Q|5`9$We8a6(u>2y4(e|AfA=Y%LdMMop~?xG=( z6bvA9_)oc=qp`iBzj!6dJ)$9tSW-^~DyVf@M|Lh2aZp5rQGtS195xRIgUll4S43&8 z<07=DrN?)~#Cx6lwJngViHj;VCG*UYN2F~{G=}-X&u4$PXg!;8yazMm3fX2QI9eBj z&maDDbC^5lQP0@4IEB7oB#{hOS=6c~HD)1<wp#0Lx8_|vk++QMjc7k3IzTf9bim&u zTbUimMlgg%?|vY`gA51+L46wWb4ulwoM<u(6?h!cB{>Hi{G7v|PHU0r_*$1Uf0w2> zwxiLa7VY-m&1$Ny56mHVAK<0^AWb&QMG*QyENJ!BXNHLx3hiY?L&+?{xK=Rtd0;)M zrn{YsO5GP-5i7mfp*d!$!Ct{rVBsxBf$+C)*rC|iq4~tZLHWHe6Z7zdIXHwkP7r<{ zd6pAyhnWk02%Y<wy-J+dCbeM87^NXlYC53|WoG)!;~{HTH~-CVt|%_uY;k^g!`KWO zq%l?~Y2henC%+20eIZrrK&6N_v!_d|sOVtKG|s^DIV+d0fvPOKzA~rS6VTdOup*i5 znrEMnGwV?x&O<Py4<=|V@7;PcsOx6FIz*-!mZq6zMq>SAxe8<C)qt{%zl6xR;1}Hm zCKDhi|4w`aONQ@z{e*mBmi)*hzAoKBTxAX>mRE!tFX_*nvIw#cHNQj_+#=XMLwNfY zc1Y;Ih={j*YwMr6iD$bCBw<{jt0|$P!OQ(1q(QxBsNjYMZs;|=XBZorsAD-4HBD-e z?_5_u!6SVkyd+Z2uiI@rN09%H5j!a)BA)P3Ux*>AK2-T!1l(u6W`Fl8swp9(h$9gp zAt7NRfdc9c^V<54N5O~EXmDdc2oK5gU-s8xe@Dg=2QU#{<Og9xeN2G{?>j>!g8%Y^ z5J8{z8(&Ln5L^>be+U~&*)UwhAHqTP-~0ZvS){9G;UWGI3KSiCxMK{26yE3$!6C65 z^|)^L@AwkS^{U;OE7j1yKyq~mF<c}Lq$`*?Sb2FzkpHG{BHZ8&NXIzb$bQg*pu<x% zA=vPzVGtMzB*Q3EgLVYDR?z#pp_>R_22+sH;SMnnGWg#alyKDm@BsfH9Romd>R11W zQ^1WvAUN=;00`!v=pKk72f}y$62*d3=|Jw>R1P&UvxsmUL0(Mtxh~@-!aV~)@lNM| z#IIAJ@aa$pJ_+t%yx+g1TwbLty4<An>OwH!N<k0?=pVvB5J-u;{X>yn9UBhG=w45< z<o}j&c}4razM-R@f*q(B3~K6K_+1x!6XD*$Aa&{f4|V58lLHfqIV?Vc{0Du0MbmlS z(3J)d%By}O`cu;{1f(kdqB=t$+<yX)P_R#(;1Y@8Ks^eDutK$r0<Md?iSR&hKgtwv z(~O-l*xy$N3f~F^hvyFzJq$##eXme5xN;ao;7=g>3V7vr1EiTi@ZpGfa0*GJ?HpZA zp+Dp(!a>^K|Ar<q1Lx?~#2|V2CHv<U?b8}`UFS`NCtuO+Z*J(Ba0mzV58!SD2$%-_ z17O0>Eg^(AUCj45ap7MyGp|yxL;kAw1z5rLAPabLt^5m3841#ezi2CKun(^5J;QSH zm3cjayg?s&UGGhVXI{~~VK>@Kkq~z19{^1h2v~>T07mwZ+i*NPu-<FU<n7Utf6*+v zO6iUGCx!l|-h*jt*uT)C(IEXK>WYTJHyywRCIi9#MXj{#$$K?|tREbHUGGhVH(t@S z(N{Dz947|CO!D8r-xnh|_e%&Vln%V~U42o5TmN;E4D`Qw_}3UvusHTgkP0s4^w&_p zIb$K1|DUwF%OBD^@mJ}j@EKQdE~UnTrxfRE<aO0I5#AdMHlhaJX8A9Q@#<<p^e6Q! z4y1D7|4^{&3k2+J(1%$QoN529`Okq8xPvWY#zSyW%9CzVo8!S}uCI#8&wFA2n+kW2 z2ODBd`G*#R+AGCe*LxG;I0+!2oO%QN^n~2K8SepP9>OcRKj`QyIw9>J`WAd90qlc6 zD56A=@=U*>z@EZ_69eFBd_9q(B?3tQML6v$Wg_E0Qq~h8tPFuAao5HE9o3Z3F|J0L Q75pwBMna;^f`E_y4_T?5Q2+n{ delta 49464 zcmYhAb8sMC^Y3HZb~a8nwryJ*+vdc{#x^!KHnuj{*tTu^?(_csxl^B>neNlys;M(` zPIdKcpAmJ|5Fskbf<s_{{C9}|zzswUMFb5+1ZzSB9~VUy{(-A(JjEl>(E4w*3Owyt z6r31vxU#R^SK+|EoQ03Cqri?Ji5HtDDG*Xph9HX!2ts`Lfo7W!5xEhtJh<s2dfpX< z=!3o1@OIwy3ov(gw{YO}NK5aC$?P28%oFU9-&o1W=~<f+P<Mn2+77y2G7NGo75d5y z834veO;a{<D68)Hb)8C0P8%>g&N~ckUW@^Z4d@BMI^WtCXhIA-x-AzYZXIu>7k}s! zhlaiTTkt}7ETpmVdt?nWxh!fJRYC=$kCi55mbNQc@K6NF9Fp^$5V1%fd)(dwt#Wi- zNh8#?n6JOJNI##kzt{-rV7T`UzXk<gw@^tuBm+nN923RAZMndKK6`z@lqxZ~?jZx` zch1U8170_OR<Vdyp?a96NM8!PFy+Y(5k;#lnF5Hjiw^zZ-Y0_%FKb~x!}CL-#R9(z z*=m^S+Z3$vERJWTDQ8L-b*}dZr4jT$;6wI--Z%x398_V3Qsto~e$t(TC}_Hsw`RY` zVx@ovZDV7?nyQO>E9Yo>s*v28K{5g=HZZdvDr^XXXkg>JmI49lXcar#Cb$F)y=fw? z)Z&gKN|8Hwt_SVOXdt6Y-Vme&NPUJjG$k~_vLu>nqfSL&j2SAfB=66B9kjvQEw+!J z<Sa8QB>K3~>~;i!n}IO0NbN2gGL#_4=yEEM@iIqgWQiDrVApF4u>^YVxc$KD8${2q z!y75+axiUM4`FUG%<K_IiJD&skbfISK$X~qT*%j`4X8r{mQ1}7^{nao9${i31E|r2 zwro;03Wbpn7iC%IBxPoYQ;Oo~q<?SVZe_nT3h}q)GQz1b*msEq+p|H@8$mX$=3}WT z-HxCwL{2WsRcFZG+Au6-ogD!Cucn3+B4%&KW^aD=hADo*-_|56+zYp`6MU@~VD_S{ zG_}C`V9jQs`f8gOe&kRi40)<3{)ngBEyMaV_C16M^!H13Q|m7=X<VqDg+88A$CA-A zge#sI2Bno1lt@y9&^rE*%(7$a;890<bSL5;s8qyG<q6+oTS>{9lg_>YBcYYfT=oZU zjx&}NBIL?=ErDSx<FA@jgpg)x6e2UWP#AV|LSmG7$T!C@5t?BI<jhZpTy_?Ti_vou zJB*lwF>4TwFvOPSiD39GllKWk;pRUwnL)%^W(brkX9JjYY9FHY0xNYPml&i_I+r=Z zd9D?5>23K@3i^0jlwh0y&gKW|_@z~$NPIUi`p|3{axo)n<>ua=qVB)^l3=fT)NW?< z+fVwB5c{cO!wJVp^zD>CYb<7}rS564?8s(HwO#ps3j8V1O*(F%=Lr<cBUh#brzg?) z&GDP!*QUd?^>^P4?7z!(nqZBDcCGw5v12y)LL4C<LaUeHrqn#BfNE13Xm)MCI)UCq zpMQW8QBgnpj2-N^V55En^dITIVI%z&OkfMve9*(S(|atjwTpXgaw4cn@!>S~vo!t8 z1fkJ|0Zz%^<(LOixEi5024zTC4AkGTO0_f#EBy?k=(tHl)l6F#1)(6vP5sRiU+lm# zy!A#F%@}t~KQom|fT@h=aWn<<X&TqL$tMQ0nx|tHI&bMi6@^0x`NOIK78kT*m>{{} z5(I@gUkeZ2U^kjA(i4_6cij><__e5{wu&@Ua~GB?))Bp{^Pl5B>+R!+nd2uv&B7k~ zD1N8nW~V;+j5tG6&Fw@s@g1{_u^}@$tw|6qI_JtRsU$0n0gjqejnTV}Y!ve>ZQ(i` zTy6}!l=HKzq6}|NIy~ssZAIZa+1aUQXx7?Wq72v(?WrDeI^CDW92{YDw>BaS{B|Zx zT&@hb_DQJ*)+SM043w}<_l+@a+zfkY)+bi@9a7Ux=VewILyh+e_?5U>&x|V%UGNP3 z?wC8;92rb9z=CUqCp~M+j!&RG=3QI4F?FAs)AwE@Orn9l6aqd3Iv#us@fPwM=Q+ZB zFxBzoMqh;J488jP4e%tn{!m^#wJh`CVD4aOC&yx_LRHEx91(BksuV3|f>LZzY}Uj0 z-#GX50@PO81jeHUXi0<l%-UiTL>u*W_A3HJi@C8%z=Vu38S(Cf&f&~>1#<=_Gp4cK z`GCR5@M1P)Gq$4+9Cxc!Fs`~(;p`3>f{ofB0RRh~hG%N#{H{%qZ5N+1a%17-*etBU zJZ#wCSBxi@XQkhd>6rAeeKfG<xT5&YM&g*Nwhre53fm0MKhy4;tW*|>0&!Y_Drg^- zv_N(;V3d+9nh2&LO`4c&mZBz;Xj)lBo0x2)uzPHTV~jjcPN62rB~ul`E`qiS#mG}{ z&bCK=9vM7-H!gh@#YHnkYh}1yK#8-FJ6!Kcs>jj~IwMNt+;&r0qILf(H~?v}(!E!t za$6*#b0-yqCrB%}a5R?74NuQHFGgHd`IsOYNIAwc1pOhUQ?hIT?JBU!<R;<D5Fn;| zreJC%1C^Nrx{4F8j~aJg054n+ho>76zTv|>=BjsU25~s(H#k7kF+hF$iWs?GkADCj zNe$i_8*I3{4T{U-%K}Y|H@#!Q^(>EMKQg}q&8;;uyF<tA>EGP+?!)yyN6;x5i&VP@ zY+E=Z=tro5$iAf)nQ4`LNX&wzTD7s9i61tqB&M2VXvoi+jy29uFf6gy*(9b~WHd*u zyL}!eG>VKhawKXPOPRz>AjV9{<Kq)G3^^z)LD7k|Z)$<}xMoD`DhA17g}CU^8W0{$ zf@h~yNv5K+yXI>oTZZ$h@A71e@n(|)C4ap78E`F&Z5MWoXVlcJjxajGa71iKA7)3t zub*a|%F^A<>_O;)K%Fd$++*}%^|1*LV-+63G>4R`oA<H{`P8P}8<>Z-J(<6D&g7V+ zI*K#xXFjY;)hxQej*DgZFy`$(3?rd>PeFQK=@EVg1zSM4J<AgwddI+f*C6Eq>7{?x z5T<t&x&E7(?0++}8_zz$L#W|n*(OfsR?gqp&tj*BQ;OIqhc7t`g+DhgYSpyZ3<PZl zUt>cEE;W0E!+yfR(21L@38>htiPEpSH&Bf<^V8WbG=t`-tr1zTG>2<7+l4x;$^Nlk zBSI^+3&z~AS(_kQY(|E+u>-Pt<&xX%L}lvj-oomTH22T0m0$ji_Z&SbtQi=@+x|~N z=d}7by=m1$3PWA;!C`gLGF0$kj{R-LKO9S^X-kU@Q~l5c(bG78HGtd~+&_|iTc;aT za1zfEaVx+A6_ygpmL}4;s*N<5d&BatrF#CNC+zt0L=3h{q8-qQjCp$9N=Dcn8B9L- z6Mv(FKwezB9<gqyKB1bS&nkfnv5vzC+%=wmqz58zX{XfAUUN8$TzqyO$(febi8*r8 z+6)V1(h?r4iEhK@7RJRYD@E60Z@_oi1RrGsF>U+Ok!CDvGB9uSn8@)WJqq_|XUx}k zCF#7n2^spX=om0Samx3RZLIJ_5i$ei@FdlMyx0(aJbZ8Mn)`N&n$oq?LVLb-Tm$#Q z*$-aUU5bqWXWw2*1;-@H2mWl#(M=X?LiO%{&sUa`?Du!Ev7YJOQkDcy^}L8O_`4T< z`l8Ig`wbGI^iIB{6K#JbTkLTPIRWq_rzy{nW{YUjd%)}GLGF!YLAM1ThW`eNGikDL zgpg%G9Ye?o%Aqh9O8*W@Y`7y-h%CuE%nlKZqKGGCKQu~r*fq30@~I~~j0j<f6H19t zI;0V32qg*+NjAa`0gR@Q7W@t<%#@HPc>gd;x5qT-cXSay2*$c6y`N9Hey8Scn6b|< zQc%ROWk3QcSK>&i=?%?_uM84#!iyB+6#BmE?Q=4yFU3Go=u5J%fJ$!?<}Ho5Z&5lG z-Hxh^Q%H&euA;`IB<=HGA%k8L0kiLUDkD)fyCY%OsG)HP2VNB~$#?>2JLFBBvqsip zeF-~!+Js-Z{pS0G5Y8JEm|2^`I7Xg(7Ob~JiU8_;8vHM9NGV{2ATH+3DEGsOs$82w z92<061Adm3Z_=p4s{nf26JvJ<oOwgI^=?tkn`XnY*WxubY@3Q~ZcE7qV~!y#inARe zPL;`S{Eo3Yxae0Du{&kvY8$g6OVR0+t*f3r3dfq^-@?6mdID##P$xlwWoW<PeG|F& zG{DldokPaGl&N~^c4uMi^_iZMcC0o%v{$@tB6@|>li5eq_tE^fA5z;@ojRU3Hta8& z;#FCZim+cvR@BjE?T!A51y#&#=jteLVd$w0yA9`Aoqp);&2a@rP^?oCSSiAuBVTaH z&8D`_LsL{k<ozs+0%N%&_&sW@M2Dsgh=81a>Wd~?v(Z>9$2=0on&e>1?ce?CPTBM3 zlpERZFjJ$-XDHf=M|G#svQIzG)cJWEOlL!6T2rLoM!x-UxEnT@_4#iaL$&ejjM<^p zNtN+Wd+LAL$gD(y(s0zJk<tXbH$w0;mIadjnzT8%)=k_Rr;0WDUJmFqODo8tmI7w2 zV=`l23bG7z5ve~%tgN;h<(lVNMs;LqX6o&nb=-Fw8+EK#NOY{*RR3vY6=bPO571;8 z-n4C2GAuKa|CI(@3}*~YT-8m!C%rn~hL>3M7H$=6@f%P)iBP#HxdVIfGLxEmX~cfG zID@gS>y4d=Y}cB~x>!4d$#Ml&1NtzXnK0`D-MtaCjs#TKXf}cD4TFz_iAl}mRCa#Y zvtX;q5ygL0hS;J=84PXn?8Pb-4T?{ha--TpF`v&t#|Mp}d#QtDM<T=t1k}*%ir+#T zWEU*DR^?zXrpOWkOMYVzBK<4_XPn`%6=5$Hq5}~fxu<%U9bw%}d*=UP3``-|x43+R zp4#2ULfT9Tws5(&C+Osbp4!>w=kjEPo|^k%Ml;F7FsEmvYRQ^@I2*Kz#aIpfr<f1g zy!T*^2sPxG^!X)oF{<5Nyd`TP<1OE|CU$E!^>4#9-92BZT*fqa>)+;!1z)!oJ|7h% zeN!brN#8E!IM!nOBj$kvX5gN9G)=?9ucCW1BC8f<OcNoRaenR6o~wFl$?)o^p-13i ztW@=y_uePMen}1~cd(BE=Mwx0C6$L2(gR25%gp*?xTSD4(cL_)Q9&3r0OhmV_P&w> zu03YKbCVgec7r8XiL{t<l*O4aJJZnuKOiN)eignTTv$&B{g=9E34mo_CMjQm(NNNv z)?5-z>gra0ka?>mZKzrkrLCF^Vnhr>CE5zxFN@+IrUY?eLkHs{%th4ihQd*H)@_uY z;Q(sH7-B-A2f1SfV<-v}WMo2e4z(i%lP2s5)<1@_8NTfvXb)qC@=Yim$_Oc>kfbWa zktn2+ln;Cd5r$aw8t4$F3h6`nCS0~PEWemV*~*At&d4KiU9flf{<~b+6f#kdQ#!I4 z%!^BpEpsNs+*L1=Im8^H7}r)_RnhX4M!uL`9z5Ub7n}MbTTDnv!Ysn?l9ixoTU5<S zEfH3Znu$G_2`(8`JNX96{1q1a7h7@5<^nd+YO72bc~w3AJpgv%xwXCd8=LO%0(;=J z+%GovMYc7ROuOA#ISMxPy;)mX%jOu_2EzOmM#c#W5mp+;2~!bPZpH}=5mrh@dDeWZ zSXtJTX}Nzn{P`;aj1x#9=FoI_cA`d-{>VmnJ>hleJDWe9k>{RJJTG&+E>HNL7(;xp zM+tu)=JvTv0sCzhsF&Kw9gCSAp<CE1DcI~;*iHDTP57AX>pJt7d`|?qKFIxD&<8aQ zhq+@eQ+sVk=$9|a9sRx4Gw0Hlk40?Yh-~MJDt=sR6;>gxzx_bB`(N#4*u5rWd49Z8 zJr(;U>WtB=!A`)ZD3fQBj3Zw{g9w~JKM7}^*AT7S0Fj7_m&$*VI@*zhza_8k{_+29 z&PWnPazD7F2dxcpWA6+ihAmt_ABvcd5Hip9^8$WvF0JC;M{2#`3{;Fp_x#wJvB41A zB?I7N;_hW*+F8<#U_ei-7q>MWm>@yk-Ug?sI<WKR+z(~*;_>}~K$If-Qh8vMtw?Go z5K5}137B)|ow^?1mD4}Fxg51wRNj?yz(@+Wg7xdbAPYUC^mC$ohA4ruoMvtJON>Gm zp)>x<soV5s)0eWuQptomn{jpUr(O;x{`GjE`nU)E^W*3GNBO$)qUbnT?i)z%n^3<W z$pMkwgdfTj;XxZV`sHA<kINaTHEh1Nh}95|C7`9Ru82A#Q{A5Ip3PS5Ci|;8IyThi z9)|C7JFFdn3e&x@qK4`(lV1tif;Z+JhctX$D$+aS;*L-NGd%O5R5a+$YW_v=h@)q+ z6Bou>T#UHu5ShX>9=G3>k`-AZBU$|sSQW>qjWMbw>Hr_1lMDUeYC6@b+i!@L;mFoG zDL|QDPCJ%?ACA#_C0V3xe}@&5Q-rjID5fJs)>%BR&y?=^KueBy4wD}V`|HLL_rxib z2J4O!^b3UVFdHOY##Qh#kV?gYh{}!oQ#ejf*g%*^8{f(i_(<&nmi)<1R!Zafvj4`A zP`NxOalcCwd{Q6*aN&ZXe>|L@6_9!ofj_nT*OgrFv`9Ufe`*h}OP!xpx!<h_KG_hb z7P(dl?l-_PkG`jU#is&<086;w&p&wsJBmBkrH=pPTO&J~&d(`)eqiCG%#_Ju(l|1V zPOyPW6Kv|Z=wdhRO7g#B1ylay4eclvdM<vtFRX4cXJZaKE>>?}({cGiUuNV1sa8jA zsV*|9_>;^x-fG>-M&O20dvgcGg(IqVbLTTRbaLK@mEI}_yv(o0v~)jZnAMDTN6B8D zL(E&-!leN2{<=XeUM*Wg^MU=y3rW213AXq0xLM7I>aUgTq~{UnOod6^cs@meWayX3 zRfZ6({e43AP$#&~Ang)itL(IZrMQHqbENE;*I;zOPsDzPn`6`cnurOdLSaVo>HT(5 z;Z{__G^NH466%HVAYN_b(eFx&kr%^MCF9UCRLt92Ib5dld}vUdst-A6S!)^0ZTu_g zy2y3MI2u2N9ax|mdymt;%l<g9PD&{qTzt62q0_{#zGucl+<Wruvq(G#61wUY!^&TG zOe-#v^s6hc8-&lwJuwtYLZj=jFfRFmK<Yc(*ik(*88r%Q3KmW?E&m!OiRLO$?4BQ} z(5&yK!5AO-lMC82{F#fKb6T8l6NA1V{+<g@ACA#O!MGOSa9hBFSumD6?8w`_2sO=9 ztyWQfZpI`O1lKLqi#-Mk_(}_6%fdH?3>ovD73Uww;#yfE`Y=vZPB*6e4XS~_D;KF* zo+^h{bbso7iuGh18RSq|knCww>%4fE!&LIYLs|2+*zjdJ@nI??5nYkQ90dqRA1Q`U zvi4OSdF7Nkec#ibx*6v@YxAuey2~1J`8M1zUuB_FJmg|RxtB2o+*Glg!KzvD5voU* zrtY=LvYot09Ibf4?7gT@dtI`wHQPrFk<&&WF~?d2i~D259685WH2pYuDoQ>$!p^aH zR7xo|Co*ZpR+?dk3L6f$Mrd1zHfnW`?#^V!U=8!DWDj$T7G9+w3?<f??De6ufE!3z z(r%^8j&X>c|I)++_<Z*Fyt<Ug=^r}^j^cf&{SRr55fVXrA*rO-9sR}H*}NGq$!Bjx z|L)<ynC@RZW7Q@mL5$A@j;Ik)-EgMukbWNW&9E=u`zc$|s;2^xTdh3ELKvX@{P6)L zM%}?ld%RjlckvOIfpyRou+i?d%3YN6Vbi(nw$ZmJQ*KuPeHetR46=*6QKrl%jgRd2 zZSk%7GW}wX;i!5t>!KZAP?=hyf_)7YEsdJ&xHJsO=7KJAD;m5etlAB%b1p7^TAN3q z(qa|#cJ7qfHjM}Cfkh3>4*JX!`0BpWoT8zFR&_tPMNp^@RAx_5@tCF)njEjD=G0i0 zB)+U)vE4s_F#Mb??D6>N4Zl7F<ke;D@oTcHI)NWhe6%B%ZS`!LkK-v_cVvW?F5hJ@ zssxc_Wi8aNz|uJTT2YB|MN;bF4^c#g|J;h+j2rVJ5QZHktD12Zi8UoJ=#0W>2PN}1 zCUZ6>`>v>Fg@4YfK+Tua)Ym$7!f3A)OfJ5P^Dg`b-rjY5*?f%j;bgHk%yrFY;2+C3 z{TeV*%b_peciq6H!|kqj3d>vj)E8yczdJP0T@i-waJYkMNx2JMFoWf!j>2tAlre6U zLx0SFc(~iU6FhC<w&AvC*{{_4s9XtYI+P%`Y@(iwAQ0M1+JOf5_o`K#_aYx4f`9xf zWlr%1TCKKrQJWv25ujbBX?_H@!-P-vIi}ck1!q!>ao5Xf8b3;A&8i}^6aE!sVaS|b zPGFV=bJ=bJMb_c0uSL#bifi;ZUQaK9L*r<v&X#_g5|`)DMM-v95O?R63K+`L|Ne~# z(LDcXTcu3z7h{KSgO|>!*aZ!_WFTf+;cP)7aPV&Yj+^wW*;7dY8#&0UjOaZ6PQ>Q? z9F4)RHw?*GG%$zbZ=0U}LFTD7NOdLXW2&kwab14!@(&yReAT%*z-Z<ERn1xixm1P6 zgZGs(#d|(33Id!cS#XsN)M~u%N)u{YZbJU9@43%+*0RH1@!0-N4H@4g?erDhsr(8N zc+F>AjQQ;rIXUjRV9t78iHQ7aCRfi-spgQDQZ^~DplYWo?=vd=Q1r8=tfl2=g?Uxu z3c{N;c#djbzb>{%ROehbJ<-;WEbA<flLxz(RSs88aNT*3@1ZF*0x%lLf%c#Nw3trS zXBKZ2t@Se;3ukz9D(%{g2O`g~Vf#vFfcUe$H?!Vq7?{m>`tX^vm{Si}k<vyGMsL`f z_$g57d_fpfxo=xuN<Brwg1(OBKW;+XSFz^CjGNHquQnE9k4IsCTEW(m*5=Zt4OZwB z!<MsjfotKj^|&`zLPIuxAE*DempF1Y8bqU8XS}Q#oa$gijl#Y4V@9PxywWv_9uU|~ z(|W)|tT2I8`JsINl)>&$M;m2t+0D&8@md+6+CknhV?izD7O02q;0;@6gxD#bsP#t` z?>-Ppo%t=w7!#v5zm|wfnV@~!0Ys(E&8fr#1z$mWbaN}QsfD-Tc1TA{>Rm*YX$I0c zkf1~of~mAS1->`N0@Q5}_BYCa2*CD@2i7pP=p6PIrb^Ff<$5U7r%!3_t+R=A4rMw( zurEAvxWtU>oVW5r-sD36B9CXW=DqNmYfUY#Uh#o+Z+5nS=G4iyXJ*mtZ{A$;Mi7Ht z<qWs(DQ`!Mz15ZKam2TdNa4K2y5W@k*L9FW<1jyWz?U07?1MFPc2>qz6WD9<JTT6& zD-Mapb;vr+|6`}xwb`t<^hMqOKDHsX2n)1KAh7w{tf>*3Wu3l?-YDeHw?bflGBjrd zb~h_NT*Ee(=h|dhgB6-k9m8v;$^U@Y1SxT>(!{Pw-4_n-pi7BtEgyzj8(q1--lzlZ z`SEU%$s%Bn-@y{Ahi<3J4~+lc3*e*0AzW~b*Kz9-pfvrXiX3(VJ7*KrN2v+7*! zd9N0-RZp{J#d=QnUO3|M5PV4yCDIt{rW}tu|9;3CYnda~&V|OghClbQ^vcmzorbQ; zH<(<UzBo*I{+r1q&0brCoF3ksot(Q_XF>b$tB`7CVQG3*%{-c}7oeIeI#PX$WC5JL z>$&LVy<eASv^{@1p(611$u(Y>>LS9Mk7OVk?pd_ayIz<+7|gYz3NBR3t1j?a=)(Rg zSG86BsIjX!%R`M`Aj}Bw&P(iX55tz`pP)%r%tM&DRy&<uqkEAM_*k}p3Vj-a(6(<! zG^EBJvj2lUB3{<U4P0`(ubW5NJ&Omh*=0Q{rFu1d5X0FzTwX?jZ*1`nr>-=3<SMx! zKTdX#HiY{e!Lr}GUUlLJb^I5$z4bZTKr!p`@UM-#$iW^PbWSk3>cnv$i)!k+6N$i_ z#o-Z<H<>)~Wa>an)M;QVHNHAW^srJCyH(N+qI8ySBti$armMW9jmvzlmFf!*lL|kr zsQpt9)2+#Bv#luv^T>%y6R^Ll%}W_Hq*GS0%xz+cb|A`nF3G+5A=nAvb@S`ms##e= zu-oSKdoM>2cE<<?`#-(2hd!HP2?TC|Jn`R`_QvCJ?LC+v2yp$JMb0!GxPmC`_fhJ} z8r;SfNk;@)p-G-0KOB%@qCi^w(LNq|K4KeHEunltA89-qPgO6?CQH}paO{D>b5;8! zS2+S`ZE?3mlEC1Oe*Z76FM%(ux%#g_pz1<pCGNEZsFHYx#9?}3w1<wgE=1tr=7%g; z+`!%5NN24!3WPqrtyjwoFj(GnH~fJOMUqCzTLg$xS}*t2q=t7lC^k)e#N0`=FjcHE z^RsukW!~TC<)F+~@Eo3t?J<A%e>#2^V_GhV{o%0Z<n2zohR^duvSV~@((KqmMY}|g z*ng^dmeTQCCijE}co5^tLE%O@0bFsJ3!IUV?m0a@ls9oQTc*M`7%l`xL6@Ug1}H+< zh$!GRC;ZGF`j|7PYNvT_t69FXX{_bPP7oE|(|oe+lQbWHu7Y(uHCQUIC@VgH6~~ES zpIZ~tM_eS$<Ye)t?wwq2^1;bfnN_lvC=uF$qn|_DQ8bsB{y^Mv&Qbf-x>xnpI&mg= z$#o`ZfA<>K5%oZvS~n_YWAJ4Jdv)6=T?Kr#&UJn^v~>&2!Ne_Nn`JFoWP*CgH~;fv z93Z2kKQwv=do@Fr+%(G0cxs*hnNjNpdz1sDEj)wc%31ucAP1CddW3GPPmo@pjsf5F ze@!Lx>nQPI_b#oFrO3-rMQ6;XTFj5P#mJ&ppiV=Lhn%0X=MKR~*6{@)`0gHPVzo8= zzT(8Td?V}~NzCC;oIx|6%yD$$*T?VqOVJa0>KuQvPv7qkcWZ|O7j)Wdn2Y1{w^_Xv z_B1Y-mIe0bf(exiy!EwEi)(YkwAem<eI6(ej~$%#xhovLn2e7p9w@~$&I5nweb|_~ zjh)7pEAH&a9f#wOI06Mh&5bL-kq4IilM|`*qnS5*GX7(H$5q16nal4bo{cAaayuKx zBK@DKQVp#<@}StCfOEK_;M=+x)4#Q~-)5cChA*neb{)*mLfamba4hR+ejt@5CFC-O z&n^0wq}_L<D1_B|sO$2w7|dR^aN%|vXb?&tkg+edcw|`VV#%7XlmP8h=Y0Wx61W?d z=WqgOs$AWm-h`Q5k0#Y<cXgKB9@TH&9?NqV5>sc*a-GezWBCix=#C2J`ruq4^^VJb znYV&GYDDW3NBM!H96W7b)f)~O^$a!U>YG?bfhaE;lMu93?o=h-{3W2w_$xL22$HYu zctXbSK;MjCfOS+&;SRjp%KmsUFu57W!U|8J!);477nm}4XTVF|*^>y{Q~uY2#+;9p z96?F4ithA?CwDtAYTTl<6oKus5$lni4)N`(dIb*A*!Xz)R}Ma$WAp6Jz_`4fIoEVF zA1<wE>>YY+Cib7bwVPsU*nt3f8^a!p|9nmMhpLm)r>YEqz>ul(lh|kRo&65j(Y^z= zUE@9B5TMi)0}E7<?xn8+K0cpkx8oF-?tts@7Bg@20n4imJGxQ$x#U6rDc|Oo;<Kmm zrK^nEEmp%sp4Lb2iXyMW!t2fS0D_P)Cst@bFK2`E(=QM&5dDuH4-fwfqPiBHs$=9| zm0u5x^{+s!Nss-^p$61xf&PRKBsiKqs20NxazsOjAjuAzKLs|^PGufkGW4<R^UzhG zFg>!d7h71a%-qGHmWMI2#Wla^9qf{0HhPWG|9{1%($nszMX!Ddp_BDYE0y03vEj<0 z(#rrE;>OB)>hngU{YPpTi;r~lfdh$mb`$CkeUs>Cx}9hp$Z0|5q4TYC{N9N&&b&M~ z5PSQsl^$(a0cf9WZ=^?tOM>&Yf4kw@XwS+G?0eS7C3?v0Cu`+bH)|z&*Vp#=DU%i6 z#Ovf68lhB1Ap^O5PEzW5CA(WL1iM==fvzlBz-RqZK+g&<+A(#ct=p6wFqJSe({{yc z<SdM4FV+@B4`B?mqb4N+g93|t9Kwp$#>WMrjfr_Jq=tejrYy|Y3#q5&3c8`b2#=wu zrsT2lpws*D(Bac=(GClniO_-6`TFv;Bv|3E{-pM#_Homq<4F7DsYF#9DW0M^xN54C z(r}NllJ8{4;@dOBudta5l+TKtbZaRb8~2qPJxB;(mwMc`NpZ&B*k)O{z35Dy8h6zv zw&Qpex{uh{8jsk_GkV3y(|g6NQr6y($r`j77i(yA?6X^^bq<;T3){8ryN#X9f~I16 z=r-ESZua_27Z@aE{)OvBKhC^&w~~Jiw3dG*9mE%yuaf@rQ3L^eH)jTo<~B~wTS);4 zv-6DSAfjKs?vtDR!$Q5uFDl#WXiq>*PIOUDQNOnw_Hb#d7^Vt>l4e-A8$Qf^wjH-Y z7X34gweU?h1mBE|SKLH59X>^b9K?eEArX@<5+*9JI5D^{H4BS0dV7CSvK|q+jWY?I zY>Y&4LNdMHoJAZ^Bxz47prY{()SVruCt7-7dUc+8cc?jw>7l@$Xsd7j>1*ERL9V6Z zUwlx2E8;T4mfG@D)>FT&hMm7jn=v!3lP_j7xl~yp=i0x`CdH!4GVAh9<>vW+)G^2n zCh6@ItMPFjzN*~3TbrE84$i&S_?3I=@DFvX@pY>Ke41jkxtuJ%<(`={Fov|b95#I^ znUNNv?M#?)|6|Imr7tb=Nb_$0pVnJ-AT4tEA6ey|HQDS>BXCzWZ9R5{PbWruU6>Z6 zWwSOlwdq&8+hvF8GB3X|rZos$t!Ta&eGM7u?d2saR+=XN{ZLu<sTup$DD9dxDh<p> ziwUQtr46UW{~x977SAb(@khDMZBcEM`z!2ym9>3-+D@yzO-yvLOFBDak$Yp2F4A3w zD-RA_bdzd^8rg<TQQcKs|Cq?6{&()t!Cq6e#TOhz@4^}lwVM|=)F7xm2)QvE{6DNp zkQaOz*yyyKK+=GQT{%V@361P;&Z`mc5$v(N0Sg859R1l5V<Tb>B{B9lQ;ywoY@6d^ zq7m6qhj~AZ?QuCq_`}ENdYPz{j{3Hi)sunzN?t*1%WLt+v;Be>IL|+>|6U=&`){5$ z%U*WF7B!xyx8JAhS5z1d{|X4~iF(=n0_o<re>sY|+CcU1k092{+NPP0^U;^wPGv6E znTOjUj&k{SrkHsfHXEf=idu<&M%z1kaJ@Fm$1Hzo#!RJYETZi7Z-1x=tmOs!Ig`5B zNqT1Fc{jTu4k&o9W~qkODs)}!`PDC~Yv7K$j#kHhMpbkrwU(_3MlhKrFqtXq^5K^| zW5om<90B%Ok1J+q-yheKEz*RID+m{rC5SC+2ak|4hb<xIsb-Ec4rcGhX>8~A(o-b` zVH4gP?`Q-rd@KA`Q7^ku>mS~8G~g|$UvUc{RYCX>%bq!e-FHV3Fa|knleuf&g%n97 zbC!>#u_cF^xMNJav*-R!RZUu%E{<8<o3gs#@dGEhb1*~~mzF%l2^oA#=tI4-Q||rA z8m=#2pSDjfafa8nEp;(uz@RTP(;@jP&*0fhg#QxZs!_QWdYbk|$a>~j7D>;boTxZ^ zx14Ai+l)^2wHe;68J@L$Nxs5GSF)9*wxnT6zM-A1Uq+bDmfM**p0(|S*?5Wz%uyfS z6+qO_J(Fo<U+Jpctta)5;0D+m%2%rfEWPrd{;w7W%s>6X2KJdjH|5t^PT?#?$(#Es zM@-hyKb{j=^hcyKe1H09nrx&U56jm0{q+Cm&4zaPwCu7U@mgK{j}3w@!=<LHqW?H7 zdJxpT!_2r}ZYMizahhEf0GjODm#r$6+AZ%lNgaB0YTJm;y9|yzYnRAvbe(uwv~|GR zZRGi2u?L{NazpmK49aR!0R0VX5L^DiQ)@HZ1o#fof&D)YWG>Z2cRzJ<46Ph66`96z z$$<P)n3S19?_6)Kjr83X(6pm_@D#sl)xND2FhweDZH93g6Kw@T;7zk7a^XyG!2}e& zBImNL&voua_)##|gBKS!+wL$}pNc#<01l02T@QCapRIBW!D3BM6uGg4*r;dDrlqyO z%D`oVtD4>9bZ{LzOQ*@?O=qs%dK5VC%24Lnu&IgjnR?*rv#Ak$$UV#CscjRu;$K31 zFmUnf^Qm#j++kk=1pj4JvvwWw7^g1jUESxN^{*JXd~`qQO=a$}FZH=}9j^Mc`Goi! zHBX3~bLOUvT|RW`eRk@Pj~!f%jV+|sba~iCd9}TN0k_Ug+7dOrmYNcby$8{H&a^cs z0t0uD6sAXLxk0>ERoM-Nf|h}PCl92Ja$Ezd3d#4GafiSaS3ow-iF{J}h^X`~WmR;l zA-iw^lfe9ix++em9$b<kdpRH}BBS428FP7>G@hm~h&dT<6PFdv>9o$L=d;e&`E&1Z zXZ4?9bK5g&R?Yvlj>{UuBrZ40`j^mY7njxH>~z3Au&(1raLL`sQHpwtL$c&`z4U-` z&~onx99e*Np?!8Qi)KZgxol(V7xPbjqF+nuAGqg!z+QN{hlQZskMNp<jA6+!h8zX5 zO`gknZ+4N-mkRl9$Zdy6@>(b}V?4r}tM%vR)vssDIkutdr_wP>BP<iZbEx)}<lB=s z4eh|%7Mh^5k7mfD=1)>NT3ni2L)Yda+v#xt!_u0X75dKvjNjm2)e+mT85}{~V!+X5 z_e{T8t;l$`yOEc(5iz$7MKzMo-cWE1m?F8^w^g}Qu(S0LlD5%jFvgY7a0fICwblsd zZli`d9;pW4sE8%Zbmiz;k;L>nYJa0zrPjM5dyf$bt!aK%oaYcD;dNmg<AI*@9_9!D zJRd=Zf4T`U!~qP{eXa-EOCT-S(91)iQC<k-cgqoS*fW8Mnh~)%2d3e_sVUG&ickoH zTcuFtBYt6`X6&G_;bB8RhjH8(e?s6N<#Oatg2+wwwO=}CxZ11t`Z_@K^cO+JF&xO1 z*bZN83+9$-3e0B-Y)=Ndt&2Kv>S7QAK&1(UI`waB4jBB2T_mHzMqcdXGIpb6q6X9q zW$O|lo$YZ7Zq}3k(Z;L0vc0*5Y&RM{6#jXuua>)1(}_2tG)uw)j`Q@Ugph3Ciw`xJ z*LnouI_)zGM-x7DRFNHEsMNUw-<2Ie$CQ8`&yJS3Gm4Mu9hfDAiFfh?i1Ki3cr>V; zgfwc|POgh+BjNe$^?A?Uq<fjknMA)Uhlgn0zZ#ax{cO{`E95iw&>|DZ!A;q36%V1Z zytSQsP$H=i#TRMk7a7`&)Lkx~dF@ziUuiwKW>^NTs^XK{GG4Kq%e9(2!7zuhnY@-{ zA83IL`SmxHbLKF&->7&3DAnEPt_<&;a5<UGUP99^@8Nd*(5mN-V$w#b+GHdYY{?ef z$ghIjw_E(!Ohz_?zZM8d+#S`lCi}zm;)PxP*%_q)Y>InCrwA^fRlSfDE1jI|JpYDz zq6r)LoA-oRJJWRF9zVUVpFyHLw3YWf*L-r!KgY+PTGVy|+wzA1sPajjye0I;iWrj+ zgSbh%TDcK|7SbD7AgBuM>p)fga*RFOcLUeIy-?D~U^%m5IP-EcDl@;hk0(oau;PwJ z{N=lmGix!J)=Is#8tp4<ah<du{g?!ycs0ojkBRo0669Y!+R~_=Bx{xRZEJQeGh1$| z)rE|N;xZfOxSN*>!1BJ@{cF&uo!Q*PCp*_{Zf><&GBVqEx=Y;5+=f+8hMFs@lUyjx zw53vdcr=@G8OdN!pQAt`#>H7XXb>W*eVUS%jk&mGtIkC#VI)VM0R_*rS+wiiUu z&6lca;exo$ZRB6*`$dPz!D*fNb#Lu|OFTg{<l>mZAt)aU$b6vDMWL`dg!!zCwKwAg z*}%)dAJy|?W2f!B6gxLrsNZH81RWfvQuQcjF}7;EoKg-LhZQmEG%wJ1mi>VuCqAv) z>2GLUs=v5Dcg1y}+xr-8fQB8xWKe`Hz@3feYW;i8oiiSfCwiegqLx5tH6(|2+y7Yx zkL|y;t_FV!lx>L2`wxV#;jHollJp<w*aSxr;1oBwtRE3D;egwX8g<|z6a+LE8chmB zz!UL>RDK>{Vn0qyVLR$F_-A%K_#o3$Oc*~ik637<cEl?ab&T<Vfjhx*uTvX#D~B<= zWwsrghuRHLJGE`Rv{2vhpv9lNWhb2%JRwH2JOl?85@+pYZWuR<U!bqm&nAQ?1m(8o z`<_el8O)6&hs_}w+&%|`-T%BtLEDvA*1T9;FPO;iSY=_`VR_rE@DrKdPi8z>e{#D_ zsOh0DB(m;B@^COwY>p3C3b3L*L)^6a<K+GFs#8oRI!A9pe$+81XW`!@Yn(Sp+-H_P zQyv3s#Y)CZ#wK@Zoo4u%Gn1@`?h5K_vDKdyydM8j5j0ioY+xklVG1mV!j~QzO2~Rt z*lsN9_aU2E)xHPVzK~b9)Kzx)W`M5B^~}1;Mg*K-HU7$wsW^F*=dpETAMMG^8K?5` zS5NFOg}Hj{WoW<5a_j*qiO5M}c5{nYw}=Do2W=7CWty9YLJvlv3hseC-W0_H)%9*O z>Ch{675%Mx3h)$qhhzQe`7nb9$5)RUR6}1}VZ9}1Le_mcO>+sQ;vkDu8}pym3CnNw z{&<F&l!9TiYmY{*i}l22nr<BRa{MN<&umk;Nt2~#pQiF5pIps*Yd0tMd&@`?H93F{ z!CZh0I*pNqw(1^rr!)7Sqjw<M8z&a+bGpO?7xma(woPcA_$6^<uVsmc6<di=^>l5U z%;`5p!+pHI2Zkkw&)Qi!p6haZPWTQze=oY?9(7CnVpXh4`vQJUzFlj`t7y+Le_p)> zj|t>J+2$~YZUo&`!xaq#g)V~NL3BVrr=#uQbwco~`mxOb^S*)B_nrZ+8{{UH5JaWv zj9CeprQQFSwU=7oJ2MHJwDbBB<fZxIaW9j!&v9AAHfU`sIJZk&ap0lr9k5sKPK)ci zI(S>J@MR)~&$hf4;bsOU@TIKf*!!Hz<EF{n`j~%}=QB=yTPJ?M=DU}{iU-nOda<2$ zI&^i3M$H{It!}`%{MsBIJ!J{e5_6`)|6Wx%Efjh$*=cm0aa3-)*;JR=^(IO7+A&;; zX;6{29q3F5dTcv|3Gr{ply=Mw^B+3}@qUy;>#H6q<UReuKixQiC%TtsT|dd=Ki0Kq zpF?d}Kgl6--Lds}^+WbvBmg{kJZpFn!5QWl)>NnmTg7{tN@q{pv+8A`9bY`|WLC=o z&Z$1$f0Z$=Z<vzS@;+Q+m68P{4`g~KxJ8;(RPbQg_aN}#-P*ek5f{YJ2?J(T=pM^K zy(&1L-)N7aEhF%Caso+Hj=BM6{fTsQO&~5H2PiZ<+^je_)E~Y1*FX+r!7Vz789s(1 zla`*7=AAmTn#)3$#@(Otd(o<JSH6SpqY?Sib-P?WH?H}2A~o-n(tGJ2AlKUpP};v` zcTvh-dgHf7L&QTu?u<xLwV8d>mEhg_c4EoAmc*nWh>4hKDfGAyNRP;`$;AocO{`P7 z7-JKTg$QDm)p%7};{Xn_S!Nx7aAGvd6WFYLD8C5uj6sVV<w-Orl!hP6^#ewg_@Xfq z;{9u_-;W;D-l0HX^Cy2_OEx!ADHwpLm$zbNWrf=c;4iHmLtN`&ex|}9->F`k(fT(3 zTcnka&K*H<x0;TU0YQQ_{d8atc9$AARF$@|@G94YwC|4bZvdFYVV=s#C&idp`<R~6 z2n4<IwJBz9ZGWx$PH|^Y+TAUmTZ<sl{z2b(Sl>7nG<vO`muGh(RX`y|z&(DE$OYOG zC35SL|6c-u;XACgTn8W_@0%TPBH1RH`qv{7$rrl2Yb~b;ys;zrOd%0mEmlf8H`D9D zw@J+9piCQm16Yinx*pAB23v}TR`cO5bec$SSL;Y)rNE0m)z@hAWh7>Z6Jxw5)%4RA zKQq**XIL<!bZJUcC(0|;(+Cj6%-@zyfa?|t{bCU7Gx8qe($j$ZBu?=aP7eY~wjF6s z)>f)_r{ZSQR`UBFn2Py2lTABaLMYHlNB;^>1phkx2?!6KKp4$tZCcn5oaA)Ovv+|$ zWpBRtb|2ke{`Kg5cHhF8aNk-!w0$D%QOkYEc~<b1Y|-9=ZJ!%qKf4PY?a9{eF)KG; ztkg2DMX&1lrD*lLUur(m#c4MbeOsiR#JD$a6LKcwYJB*w$r5h+lJ+@K#M#6pqc66Z zJ9syz4$xN{t9%_p%g3wHXEZdzH7*1BB}JKpQOeXK+Q-hSb|?tmZoItyJZc-`mRGI+ zYgm7PXpb$x{%l<1q<Xron8A>SiqWNOw-TC-LW2uTe&2*JiTWzo_X%-L|D|S?K~O(y z`F2jd<Dk?AUDv<ey5-%q>u)OYzrK-#M#q6<4e%_*uonF<jmhRubL*7_bnu)1(8@s9 zd=tkL|J;-oEH?z;aJyZ)CjP?c?(s<@c;k@-&-aY~N9+Z=fBhwA`{Rrjr}Km8{RB1S zS-A)G^1UUXgnJE2qV4Vrm2%ahVB_Tp4B&W2yx;y})@l4og%(8bZtnsC2!CI`PZ^5? zZ(Bas7DJIf6Y@@%?|V)KAF4#Y@V*ak-`+oLI(Y@-Uc($hY84%~JW^l}Xt&jcomwCD ze^X#SJ33w4{vrMm(U2j>VN5g_g6Zfcws;VLi9g1@8ugYKQ?y97$|@FpDHza<E%QAY zjoM7f`qy~iEl6^gl0fLKA~pARLwKVm(1alanXE&NsN^pC0uvb+x-9fFI1#p(E*Xqk zG(S4H9%Xb-2}$?`PUbsXCwwxq5?(%iurqOT+Ao3-XDm1eiXztJZl#)FXYk|~rOSYN z!cjUUfv|pINs(U^A|rt;7^7U&@cC6CxAe*UN(#a+(8=Fp<1dwlM6^K;n5m(;fos@M z&R|9AjT)$4yt6sd#XI|;U*@9&eCu-JMtd&zukF2<Lg=Tt(CaT?Ait58Kd61E%&x$M z9@dmUB$|F_Q5Miq9?FVwQDXhdf-ETCQdT7_D{lkQV}VyT&!=WpB1acC!^$5gQ!eR| z{e~S-i5ayJ>mVGeD;8?A5#7EF4(Od@FI=>#+Z}PRJMp5_z|bqB%P#C_m3&Jz5l!Vp zJw9j;O!eCgeD#Q63BD(91vAr#U<tisafa8d$nq&|53QUpeDY~p)<>JkK=Y_{y9DiL z=c=6fu%7uqdFo3ryA;px5zip=%Xm{d6i_bFGCcH8ZZk|isbp$^GFyyb0VrQtY?RHb zsafR=%?U@V(9Ocm#`pqQkdK=skrsnb|MC~buKy|fs4Mg9>VEWY>L)L|jwt)C(j$$p zWFAb-s$+PloD5pFbxuHgm)^b-SNSvM^qZZCYL=KP=BuBlNOc`9CPx(9-aTfn8lA0h zC__O%;wzyyoLR25GeL938&D@N&sXi<LMU&CEib>s`4FwMqpjwtq2_o>cdkUo7Y;Y| z6K?LGT9d9b0FEgFE~vX-p{buyZJCmG{v`ZdJlRV*xqK;YC5ELVt8?8zBqL2ML;974 zsc?L(VBFL%LsRJxQ@P~dW2z^6sVA2&q^$(A_=shczq0r!o7YkUs)Y$B5@rU$I$q3) zUe%7+bcD4Cd4j>tyV}F*YQ8pm0wgZGp)E#T&JY@WRVJKG4`>1HX`th!57f!H8?A<F zIX#9H$Wo~W`Kc1q=ych8>b++ly_4_Y)`Et0h`^8rF(~yeq6f|KMg)<#C&G>{$cadn zOGW_Ukb}vBAqW`2m<6K7v4aB#XPpNOzIuRwG17rlJo{qrIE4U(-(>iGyTjG5z#;TF zK+DFCV36~Oe|&_4fTm%BsQdbdTtoCH%@0uji<&G@{fo+joZfN|{V9F6>COX#(9-}> zyLs^l$s-*gJ|aBZxpS#{1tZz6hZWKnaJavwxwI4n2T&ZfL6ruNv_lL@2M|wL%V1|c zmVb347{Pp4gtIiLzO6qJy6_&ll@g%W1V$O<<jlg@C_k^!pkEt3#K$_Q5T-msrD_Y0 z1#<f0&~JlM1t8-H)CGVb-Sfat``KjgrMU64vg{^6RDwq2rN>fa|9bMt4-tOB8>O}C zvJ1MU1^%tx`d>JdxsYFx-cav!Soo`Hd6)%3g9c7Tf?p<RlDWcM6vw$mLMkb8FLXf) zgU%GurPsUzSCXA@M&$j&@q(Pk4$>UX9Of1kG5dGCs@%>5FFrw^ShnO=xV)<1QsT3} zAY$L+y#*r4vB3a2xNoexV{^8qGV7ff_}U=ff$T=vl?*&N`jZ1I0-D&8#Fkf8&+Po~ z*sECb1wpA)66mD&zG`e<w2m&OY~?Vk1S1LWT(sy|UntM|IF16N5|J!r2ftxh$!YY= z^U}~1KXY}E7+xrTr!i;yUOlliPNRt1D1z=wsmz{DCuW>9Vo$A<PyE)fzA!~N@Wqwl z1_q%<GZKUjph-3{yE?O^d}i3i9mSG5qvZprK#&qie}?_2=fQo2Y$!@&PS*?e^X0Ed zOCZ<&sXQ{XuO=jI`<**aBNt0<Qpd_pg7@@n2F1F^5Gv*(gKag87W^P9UXbxpcN+0` zP8=MS33~bX4ag|>jJ>B0n-{T>DM@HP2#~)7tM=4vidSr(pmv6!6-!lEXeH-7a~qD^ zsJ=y^V)<C=D0yuYYwE17qGZg%M+!+fX}lT4#Bafzb8&ydGE0=4uJDOzNYtNzD}7YR zGV)f=tNLeTOT_>QiE23L0(NI#wg<JuH9|0@jjlV5IrCn&3;IwFMB=kU3vYz#9H<2+ z3eMiqfP305%h<K7X3l){P@8QTA<)he(*3MacMM6Am&PE1T$eZ$%C<9Qmhh>Mk*G)R zzjKEh2Axc3b(ak$4I>DB15bmpNUT*^0y|HU+F}1~6DY_W|C)&@x!2aKuy^M!qD&yU z8Tvbl3L5nbJ$8d8J7eY1Kmz~81pu*Idv~p{fqm!T&KCPN+uW6=P{>ShV+F!pPa9x; zF}U(@6s`JuX5R+KPh`MCr&Z?$KzW%|Ha)#6umu$_AsqnwqG_5nEP9Wx9|)pQ0+nJA zsUVj|d0?St2ep(brohNRO5~YEFQ?Ff#^}rgr)6#v@Pb)^R(!Y*Q1O)U1L{+_g$_{# zf3Za0Pu}rlC?W_wfWMILPocTNt2iWuO4&)C)|xV_AgEj==q5x8oq{{_swfl*e3MPk ziJGUWCnzT<5}=}s$BUUy+gIpMx>*dDgQ_0_z<d9|w2((5EyFl!TuY#fTDMYx`e)T) za)HmafYZzQ5pAcsV+`Ta0NKW?h;=h!Hv?LcPtk?X_{<oK5K7ObT%%XvEMtW<pJu#p zZ#>jT%=_;IB1TtAqZy&u;Vjg?G{MdWVhX&r!Qf5)adtRYl18S~)qZ3lyUNFOIF!Lk z&Wth!QHdrAU*yj26e`b5_@Tqop9_!tAiPFBtrRq10ZczPkf(7y0hH}fSG?jW6eKp4 zW%j`SS`=VHBtNCFP9UbA9z7Hq^)sYN9|5CAcvA8&E@l7<LzTp{FhMB7=y-#&Rsc(r zR>yS2qS7}ovrEwozUWiWbA2OTo>)VCYAO&PvFPLmBJNsT>LYFN1K%Il(LDh5LEcdM zeZSK?X{K|od`UJqFp_N2s5<#9MJc2En=%hf?ZkTR*Nq#^7+>4)YY9y@J@PVKD@~ZQ zf1Qf2AzmnDAVxQF8|J>p01<dA=Oe@<qgjp4N7)DCCq~}Y6J;+mb7M{%nQNF*9F^lI zg_(*%2ShYq>^w$@IFhvyl|*ZQU;`e*Qhulz%oEk@>f7`Z&~$8r{|Yz!=??P(wawKT z^leZjPSlt>J6CuoPznwkO2zYgZa<<E#%A!lJI;t+_8(^d<U6FHQ^@4;SPA`Pgz<OI zoEPR%1c1${@c#inK)}Cio}aMc96;U2QFj_@?O-V<5N8F0_*sVXS0Fx@rFc2w0}%fS z@xLS99`SI*53tyBgo1xRg$=0`ZpLvRizB-m+b|Euy&~l&*C>ZZ{|xZe03*kfBYswn zBdZhq0ak=k*f)~GsTmY5PonTWp27|`3g19ZaY_)t#qkfBV7(E%72u5sUkw4Ms=bmW zixUa_TW#qUAIdRgq(qI2j{>R;saqopVT}oocStQDso@D6OG<x}L}~<3MshBhQh#UG zq;mv5SyL!=lKD9`8K@&jttONFN5W^_O{pSvO<+1_A&;ag9>f*ye6lL>tbcpXMz%<j zg91BqexzHPB55bR-KdxI#J0Q>La9$As%t2vtob5!R|cgzNK`RLso@e;fK-D-J&lr& zO4RHqN-ggy=^=kLxraz)BIUSRq#i)(&R!x_WG9TBY>}v7yMy?X$le5>1R|5BGJ&MH zw^+9`B7qAcxqXxf29xqWt_T7(v_R=?C@C)x_130d#f1__f2r?b30xT2TqIJ@!>B}% z9TGJN;u1v)t`n)dxdbkX^eh&sEK33xLlTFI)RRybM}B{hs3qnEE`b~=5vk9hE{W_M zCQ|*NE`>Z?DpCzlmqu<ME>csWt{r)Jgh&m9mSvE`64eQ)Eb@ayeGPrjA=x8EYALk3 z16e3h-vO0J7LQco(vj>K>52<b=f)~==}cnBDUs+*?kiKgcP0DE6c61=bh#3xt4OLu z9e_SuP3nIo$`AU`i@aT~c<)1u6)x{UJun`<6I$1gJUw2VtwMBPcvt<0@p8*(-Jird z%lVXRq3)POC8ibv^}b57fP7IYdOrj$D<D5e)H=sdcuAi;L8P*+qv5-PZW84L$w6eX zL|qG`IhZW25~*cC6%pekk=g=1Dke1&6##W5<ZXY6dIRc8Nx@{1It$bYvO}Vh;w!jO z#9kv(u@MPC6-bm7s4?V-Q=}GUOoSJZ_q`}m_Q(WoJo!eVW@XHPv?JXPi&S@L^&~P) zqHYH()g<-}>3WEp$W0-$%?wi4K;3k5M56AAn*s0Z?7<>64eDl+O(7!HD|#X~n;45k z>H~l9&`55OsKn?Q+<dZUj7Yr%b7B#BTcSpTm0L)+8$`+&JdwMN+<Cu9Jpz(<kVhrz zn4t*11KcN3?ffZaSR+Y-m6aq?qWT3dfP>->OH>+Acf<GF3|{@IkxRIH$zu{VGUIM; z4cRAAyJDs?>qzf)qMi-<@Bpcos3YLvArgQ2ph%5{maQk#Bx<j52DgFicto`Fj&UmU zIEmaK)~y9A8%eQ5Ee5?O$n6sKB~VY2!xHs*Xae^X`A(t^0kw@-9~G(J1GSyRN>nuH zJxe-B)E20Fjuc3g0qR~L?>{C|@30fOT_pRDjO#jjmD~W7bR7Zp*CW{K$e~GnxxIhn zG*XN3de}?8LFz6`yTo-+7kgBsHU>NbREk7B8?XteETHIBwKi=V_ZrCuO1`RIBR!6~ zJV0HsTiqz67Ljy@Qg^x4t(EF_W8FTty2Dc4TC6i4Q`ZF^6YF|mT{pM7-csE>tZQ(q zTO`$)v2Kf7-43a)9P7SztNUK6J4JsemH3vr&heI5_d2b^r_>*L3ayFsy;4fBC*GB# z_|!Ct-;~4x9vndN41^`f|J*_0Xakk}R|v(~#HQ@bw5x0XmvFfk&6RHsF5A5HSa=Ix z98d8mfBGhJK>~e8ITrXPaw9;xYHV7*?JWPg)_#d)t!^>k29Q)Zose^ga?pP=i<aS8 zC6#inN6v>hD;`d`+>vUD?yrS6Csyuro+Sf`2?__r48@A2Fo_{NKv=5+w2=&eK_m}h zcZ7Wq4n#N<;b?>v0K>?1fYD?Qauy(5MKaQo$$GT;Il_McbPy|3nAD!!&rr@1<R1js zheWX%X%x5E29P9nS6UIdpBR5aibw`qX(%Db$ybh%0Dtno0bpTL1;D?=){vv*rKA}s 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 a{a58AVPIcR-qhfqJPZg3;7<Vf)Bgv)4Kus|