IP.Tools.psm1
## Running A Build Will Compile This To A Single PSM1 File Containing All Module Code ## ## If Importing Module Source Directly, This Will Dynamically Build Root Module ## # Get list of private functions and public functions to import, in order. $Private = @(Get-ChildItem -Path $PSScriptRoot\private -Recurse -Filter "*.ps1") | Sort-Object Name $Public = @(Get-ChildItem -Path $PSScriptRoot\public -Recurse -Filter "*.ps1") | Sort-Object Name $AllMask = [Math]::Pow(2, 32) New-Variable -Name AllMask -Value $AllMask -Scope Script -Force Class IpNetwork { [ipaddress]$IpAddress [ipaddress]$IpNetmask IpNetwork([string]$CIDR) { ($IP, $MaskLen) = $CIDR.Split('/') $IP = Get-IpNetworkBase -CIDR $CIDR Write-Verbose "IP: $($IP); Mask: $($MaskLen)" $this.IpAddress = [ipaddress]($IP) $this.IpNetmask = [ipaddress](Convert-MaskLenToIp($MaskLen)) } IpNetwork([IpAddress]$IP, [IpAddress] $Mask) { Write-Verbose "IP: $($IP); Mask: $($Mask)" $IP = Get-IpNetworkBase -IP $IP -Mask $Mask $this.IpAddress = $IP $this.IpNetmask = $Mask } [system.net.ipaddress]GetStartAddress() { return Get-IpNetworkStartIp -Network $this } [system.net.ipaddress]GetEndAddress() { return Get-IpNetworkEndIP -Network $this } } # Dot source the private function files. foreach ($ImportItem in $Private) { try { . $ImportItem.FullName Write-Verbose -Message ("Imported private function {0}" -f $ImportItem.FullName) } catch { Write-Error -Message ("Failed to import private function {0}: {1}" -f $ImportItem.FullName, $_) } } # Dot source the public function files. foreach ($ImportItem in $Public) { try { . $ImportItem.FullName Write-Verbose -Message ("Imported public function {0}" -f $ImportItem.FullName) } catch { Write-Error -Message ("Failed to import public function {0}: {1}" -f $ImportItem.FullName, $_) } } # Export the public functions. Export-ModuleMember -Function $Public.BaseName # Private Function Example - Replace With Your Function function Add-PrivateFunction { [CmdletBinding()] Param ( # Your parameters go here... ) # Your function code goes here... Write-Output "Your private function ran!" } function Get-IpBogon { <# .SYNOPSIS Return a list of IP Bogons with [ipaddress] objects representing the IP and Mask .DESCRIPTION Return a list of IP Bogons (Internet non-routable addresses) with [ipaddress] objects representing both IP and Mask. IP Bogons are Internet non-routable addresses that are either reserved for Private use (RFC1918), or are otherwise not available. .INPUTS None .OUTPUTS Array of [ipaddress] objects representing IP Bogons. .EXAMPLE PS> $Bogons = Get-IpBogon.ps1 .LINK https://github.com/IPSecMSSP/ip.tools #> [CmdletBinding()] $Bogons = @() $Bogons += '0.0.0.0/8' # RFC1122 "This" network $Bogons += '10.0.0.0/8' # RFC1918 Private-use networks $Bogons += '100.64.0.0/10' # RFC6598 Carrier-grade NAT $Bogons += '127.0.0.0/8' # RFC1122 IPv4 Loopback $Bogons += '169.254.0.0/16' # RFC3927 IPv4 Link local $Bogons += '172.16.0.0/12' # RFC1918 Private-use networks $Bogons += '192.0.0.0/24' # RFC5736 IETF protocol assignments $Bogons += '192.0.2.0/24' # RFC5737 TEST-NET-1 $Bogons += '192.168.0.0/16' # RFC1918 Private-use networks $Bogons += '198.18.0.0/15' # RFC2544 Network interconnect device benchmark testing $Bogons += '198.51.100.0/24' # RFC5737 TEST-NET-2 $Bogons += '203.0.113.0/24' # RFC5737 TEST-NET-3 $Bogons += '224.0.0.0/4' # RFC1112 Multicast $Bogons += '240.0.0.0/4' # Reserved for future use $BogonIps = @() foreach ($Bogon in $Bogons) { $BogonIp = [IpNetwork]::new($Bogon) $BogonIPs += $BogonIp } Write-Output $BogonIps } function Remove-IpBogon { # <# .SYNOPSIS Remove any Bogon IPs from the list of provided IPs. .DESCRIPTION Remove any Bogon IPs from the list of provided IPs. Each IP is expected to be either a dotted quad notation string representation of the address, or an [ipaddress] object. .INPUTS [IpAddress] or [string] values to filter .OUTPUTS Array of [ipaddress] objects that have had IP Bogons removed. .EXAMPLE PS> $IPs = Get-IpFromSomeSource PS> $IPs | Remove-IpBogon Obtain a list of IPs from some source (like a SIEM), and filter out the Bogon addresses .LINK https://github.com/IPSecMSSP/ip.tools #> [cmdletbinding(SupportsShouldProcess)] param ( [Parameter(Mandatory=$true, ValueFromPipeLine=$true)] [ipaddress] $Address ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { if ($PSCmdlet.ShouldProcess($Address, "Remove IP if Bogon")) { if (!(Test-IpBogon -Address $Address)) { Write-Output $Address } } } End { } } function Test-IpBogon { [cmdletbinding()] param ( [Parameter(Mandatory=$true, ValueFromPipeLine=$true)] [ipaddress] $Address ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me $IpBogons = Get-IpBogon } Process { $IsBogon = $false foreach ($Bogon in $IpBogons) { if (Test-IpInNetwork -Address $Address -Network $Bogon) { $IsBogon = $true } } Write-Output $IsBogon } End { Clear-Variable 'IpBogons' } } function Convert-IpToMaskLen { <# .SYNOPSIS Convert a Subnet Mask to PrefixLength .DESCRIPTION Convert a Subnet Mask to a Prefix Length .EXAMPLE PS C:\> Convert-IpToMaskLen 255.255.0.0 16 This example counts the relevant network bits of the dotted SubnetMask 255.255.0.0. .INPUTS [string] .OUTPUTS [string] #> [CmdletBinding()] param ( # SubnetMask to convert [Parameter(Mandatory)] [System.Net.IpAddress]$SubnetMask ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose "$($Me): $($SubnetMask)" } Process { $Octets = $SubnetMask.IPAddressToString.Split('.') Write-Verbose "$($Me): Octets: $($Octets)" foreach($Octet in $Octets) { while(0 -ne $Octet){ $Octet = ($Octet -shl 1) -band [byte]::MaxValue $result++ } } $TestMask = Convert-MaskLenToIp -MaskLen $result if ($TestMask -ne $SubnetMask) { throw "Invalid Netmask Supplied" } else { $result -as [string] } } End { } } function Convert-MaskLenToIp { <# .SYNOPSIS Convert MaskLen from CIDR Notation (IP/MaskLen) to an IP Address object .DESCRIPTION Convert MaskLen from CIDR Notation (IP/MaskLen) to an IP Address object .PARAMETER MaskLen Integer value representing the mask length .INPUTS Integer Mask Lenth .OUTPUTS [ipaddress] object representing the Netmask .EXAMPLE Pass a single MaskLen as a parameter PS> Convert-MaskLenToIp -MaskLen 24 AddressFamily : InterNetwork ScopeId : IsIPv6Multicast : False IsIPv6LinkLocal : False IsIPv6SiteLocal : False IsIPv6Teredo : False IsIPv6UniqueLocal : False IsIPv4MappedToIPv6 : False Address : 16777215 IPAddressToString : 255.255.255.0 .EXAMPLE Use Pipeline to convert MaskLen to IP Address PS> 27 | Convert-MaskLenToIp AddressFamily : InterNetwork ScopeId : IsIPv6Multicast : False IsIPv6LinkLocal : False IsIPv6SiteLocal : False IsIPv6Teredo : False IsIPv6UniqueLocal : False IsIPv4MappedToIPv6 : False Address : 3774873599 IPAddressToString : 255.255.255.224 .LINK https://github.com/IPSecMSSP/ip.tools #> [CmdletBinding()] [OutputType([ipaddress])] param( [Parameter(Mandatory=$true, ValueFromPipeLine=$true)] [ValidateRange([int]0, [int]32)] [int]$MaskLen ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { [ipaddress]($AllMask - ($AllMask -shr $MaskLen)) } End { } } function Get-IpNetworkBase { <# .SYNOPSIS Get the Base Network address for the supplied IP/Mask .DESCRIPTION Get the Base Network address for the supplied IP/Mask .PARAMETER CIDR [string] containing CIDR notation for network address .PARAMETER IP [IPAddress] object or Dotted Quad notation string representing the IP address .PARAMETER Mask [IpNetwork] Object or Dotted Quad notation string representing the Netmask .INPUTS CIDR Strings .OUTPUTS [IpAddress] Object .EXAMPLE PS> (Get-IpNetworkBase -CIDR 192.168.100.20/24).IPAddressToString 192.168.100.0 .EXAMPLE Use Pipeline to convert MaskLen to IP Address PS> 27 | Convert-MaskLenToIp .LINK https://github.com/IPSecMSSP/ip.tools #> [CmdletBinding(DefaultParameterSetName = 'CIDR')] [OutputType([IpAddress])] param( [Parameter(ParameterSetName='CIDR', Mandatory=$true, Position = 0, ValueFromPipeline=$true)] [string] $CIDR, [Parameter(ParameterSetName='IpMask', Mandatory=$true, Position = 0)] [IpAddress] $IP, [Parameter(ParameterSetName='IpMask', Mandatory=$true, Position = 1)] [IpAddress] $Mask ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { If ($PSCmdlet.ParameterSetName -eq "CIDR") { ([IpAddress]$IP, $MaskLen) = $CIDR -split '/' [IpAddress]$Mask = Convert-MaskLenToIp $MaskLen } Write-Verbose "IP: $($IP); Mask: $($Mask);" [IpAddress]$Net = ($IP.Address -band $Mask.Address) return $Net } End { } } function Get-IpNetworkEndIP { [CmdletBinding(DefaultParameterSetName = 'CIDR')] [OutputType([ipaddress])] param ( [Parameter(ParameterSetName='CIDR', Mandatory=$true, ValueFromPipeline=$true)] [string]$CIDR, [Parameter(ParameterSetName='IpMask', Mandatory=$true, Position = 0)] [string] $IP, [Parameter(ParameterSetName='IpMask', Mandatory=$true, Position = 1)] [string] $Mask, [Parameter(ParameterSetName='Network', Mandatory=$true, Position = 1)] [IpNetwork] $Network ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { Switch ($PSCmdlet.ParameterSetName) { "CIDR" { Write-Verbose "$($Me): Invoked with CIDR" $Network = [IpNetwork]::new($CIDR) } "IpMask" { Write-Verbose "$($Me): Invoked with IP/Mask" $Network = [IpNetwork]::new($IP, $Mask) } "Network" { Write-Verbose "$($Me): Invoked with IpNetwork Object" } } $NetworkIP = $Network.IPAddress.GetAddressBytes() Write-Verbose "$($Me): NetworkIP: $($NetworkIP)" [Array]::Reverse($NetworkIP) Write-Verbose "$($Me): NetworkIP (reversed): $($NetworkIP)" $NetworkIP = ([ipaddress]($NetworkIP -join ".")).Address $MaskLen = Convert-IpToMaskLen -SubnetMask $Network.IpNetmask $NumIPs = ([System.Math]::Pow(2,(32 -$MaskLen))) $EndIP = $NetworkIP + $NumIPs - 1 # Convert to Double If (($EndIP.GetType()).Name -ine "double") { $EndIP = [Convert]::ToDouble($EndIP) } $EndIP = [ipaddress]$EndIP Return $EndIP } End { } } function Get-IpNetworkStartIP { [CmdletBinding(DefaultParameterSetName = 'CIDR')] [OutputType([ipaddress])] param ( [Parameter(ParameterSetName='CIDR', Mandatory=$true, ValueFromPipeline=$true, Position = 1)] [String]$CIDR, [Parameter(ParameterSetName='IpMask', Mandatory=$true, Position = 0)] [string] $IP, [Parameter(ParameterSetName='IpMask', Mandatory=$true, Position = 1)] [string] $Mask, [Parameter(ParameterSetName='Network', Mandatory=$true, ValueFromPipeline=$true, Position = 1)] [IpNetwork] $Network, [Parameter(Mandatory=$false)] [switch]$ExcludeNetwork ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { Switch ($PSCmdlet.ParameterSetName) { "CIDR" { Write-Verbose "$($Me): Invoked with CIDR" $Network = [IpNetwork]::new($CIDR) } "IpMask" { Write-Verbose "$($Me): Invoked with IP/Mask" $Network = [IpNetwork]::new($IP, $Mask) } "Network" { Write-Verbose "$($Me): Invoked with IpNetwork Object" } } $NetworkIP = $Network.IPAddress.GetAddressBytes() [Array]::Reverse($NetworkIP) $NetworkIP = ([ipaddress]($NetworkIP -join ".")).Address if($ExcludeNetwork) { $StartIP = $NetworkIP + 1 } else { $StartIP = $NetworkIP } # Convert to Double If (($StartIP.GetType()).Name -ine "double") { $StartIP = [Convert]::ToDouble($StartIP) } $StartIP = [ipaddress]$StartIP Return $StartIP } End { } } function New-IpNetwork { <# .SYNOPSIS Create a new IpNetwork object with the specified CIDR or IP and Mask parameters .DESCRIPTION Create a new IpNetwork object with the specified CIDR or IP and Mask parameters .PARAMETER CIDR [string] containing CIDR notation for network .PARAMETER IP [IPAddress] object or Dotted Quad notation string representing the IP address .PARAMETER Mask [IpNetwork] Object or Dotted Quad notation string representing the Netmask .INPUTS CIDR Strings .OUTPUTS [IpNetwork] Object .EXAMPLE PS> $Network = PS> Test-IpInNetwork -Address 192.168.100.20 -Network .EXAMPLE Use Pipeline to convert MaskLen to IP Address PS> 27 | Convert-MaskLenToIp .LINK https://github.com/IPSecMSSP/ip.tools #> [CmdletBinding(DefaultParameterSetName = 'CIDR', SupportsShouldProcess)] param( [Parameter(ParameterSetName='CIDR', Mandatory=$true, Position = 0, ValueFromPipeline=$true)] [string] $CIDR, [Parameter(ParameterSetName='IpMask', Mandatory=$true, Position = 0)] [string] $IP, [Parameter(ParameterSetName='IpMask', Mandatory=$true, Position = 1)] [string] $Mask ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { if ($PSCmdlet.ShouldProcess("IpNetwork", "Return new IP Network from CIDR or IP and Mask")) { Switch ($PSCmdlet.ParameterSetName) { "CIDR" { return [IpNetwork]::new($CIDR) } "IpMask" { return [IpNetwork]::new($IP, $Mask) } } } } End { } } function Test-IpInNetwork { <# .SYNOPSIS Test if an IP address exists in the specified network .DESCRIPTION Test if an IP address exists in the specified network .PARAMETER Address [IPAddress] object or Dotted Quad notation string representing the IP address to test .PARAMETER Network [IpNetwork] Object consisting of IpAddress and IpNetmask to check if IP belongs. If supplied as string, will be converted to IpNetwork before testing. .INPUTS IP Addresses and networks. .OUTPUTS [bool] result of test .EXAMPLE PS> $Network = New-IpNetwork "192.168.100.0/24" PS> Test-IpInNetwork -Address 192.168.100.20 -Network $Network .EXAMPLE Use Pipeline to convert MaskLen to IP Address PS> 27 | Convert-MaskLenToIp .LINK https://github.com/IPSecMSSP/ip.tools #> [cmdletbinding()] param ( [Parameter(Mandatory=$true, ValueFromPipeLine=$true)] [ipaddress] $Address, [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [ValidateScript({ $TypeName = $_ | Get-Member | Select-Object -ExpandProperty TypeName -Unique if ($TypeName -eq 'System.String' -and $_ -match "(\d{1,3}\.){3}\d{1,3}\/\d{1,2}") { Write-Verbose "Convert From String: $_" New-IpNetwork $_ } elseif ($TypeName -eq 'IpNetwork') { Write-Verbose "Taken as IpNetwork Object $_" $_ } })] $Network ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { Write-Verbose "Network To Test: $Network" if ($Network.GetType().Name -eq 'String') { $Network = New-IpNetwork -CIDR $Network } if ($Network.IpAddress.Address -eq ($Address.Address -band $Network.IpNetmask.Address)) { Write-Output $true } else { Write-Output $false } } End { } } function Test-IpRangeIsSubnet { <# .SYNOPSIS Test if supplied IP Range is a valid Subnet .DESCRIPTION Test if supplied IP Range is a valid Subnet .PARAMETER StartAddress [IPAddress] object or Dotted Quad notation string representing the Start IP address of the range to test .PARAMETER EndAddress [IPAddress] object or Dotted Quad notation string representing the End IP address of the range to test .INPUTS IP Addresses .OUTPUTS [bool] False if the IP Range does not represent a valid subnet [ipaddress] representation of the Subnet Mask .EXAMPLE PS> $StartAddress = 192.168.1.0 PS> $EndAddress = 192.168.1.15 PS> Test-IpRangeIsSubnet -StartAddress $StartAddress -EndAddress $EndAddress AddressFamily : InterNetwork ScopeId : IsIPv6Multicast : False IsIPv6LinkLocal : False IsIPv6SiteLocal : False IsIPv6Teredo : False IsIPv6UniqueLocal : False IsIPv4MappedToIPv6 : False Address : 3774873599 IPAddressToString : 255.255.255.224 .LINK https://github.com/IPSecMSSP/ip.tools #> [cmdletbinding()] param ( [Parameter(Mandatory=$true, ValueFromPipeLine=$true)] [ipaddress] $StartAddress, [Parameter(Mandatory=$true, ValueFromPipeLine=$true)] [ipaddress] $EndAddress ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { Write-Verbose "Address Range To Test: $StartAddress - $EndAddress" $StartAddressBytes = $StartAddress.GetAddressBytes() $EndAddressBytes = $EndAddress.GetAddressBytes() $AddressDiffBytes = @() for (($octet = 0); ($octet -lt $StartAddressBytes.Count); $octet++) { Write-verbose "Octet $octet" $AddressDiffBytes += $StartAddressBytes[$octet] -bxor $EndAddressBytes[$octet] } Write-Verbose "$($AddressDiffBytes -join '.')" [ipaddress]$AddressDiff = $AddressDiffBytes -join '.' Write-Verbose $AddressDiff [ipaddress]$MaskDiff = ($AllMask - 1) - $AddressDiff.Address Write-Verbose $MaskDiff # Reverse the bytes $Octets = $MaskDiff.IPAddressToString.Split('.') [Array]::Reverse($Octets) $Mask = [IpAddress]($Octets -join '.') if (Test-ValidMask ($Mask)) { Write-Output $Mask } else { Write-Output $false } } End { } } function Test-ValidMask { <# .SYNOPSIS Test if an IP address represents a valid network mask .DESCRIPTION Test if an IP address represents a valid network mask. I.E. the binary representation contains all 1's followed by all 0' .PARAMETER Address [IPAddress] object or Dotted Quad notation string representing the IP address to test .INPUTS IP Address .OUTPUTS [bool] result of test .EXAMPLE PS> $Mask = "255.255.192.0" PS> Test-ValidMask -Address $Mask .EXAMPLE Use Pipeline to convert MaskLen to IP Address PS> 27 | Convert-MaskLenToIp .LINK https://github.com/IPSecMSSP/ip.tools #> [cmdletbinding()] param ( [Parameter(Mandatory=$true, ValueFromPipeLine=$true)] [ipaddress] $Address ) Begin { $Me = $MyInvocation.MyCommand.Name Write-Verbose $Me } Process { Write-Verbose "Mask To Test: $Address" # Convert Address to binary representation $binAddress = ($Address.GetAddressBytes() | ForEach-Object {[System.Convert]::ToString($_,2).PadLeft(8,'0')}) -join '' $AddressBits = $binAddress.ToCharArray() $Last = 1 $ValidMask = $true Foreach ($bit in $AddressBits) { if ($bit -eq '1') { if ($Last -ne '1') { $ValidMask = $false } } $Last = $bit } Write-Output $ValidMask } End { } } Export-ModuleMember -Function Get-IpBogon, Remove-IpBogon, Test-IpBogon, Convert-IpToMaskLen, Convert-MaskLenToIp, Get-IpNetworkBase, Get-IpNetworkEndIP, Get-IpNetworkStartIP, New-IpNetwork, Test-IpInNetwork, Test-IpRangeIsSubnet, Test-ValidMask # SIG # Begin signature block # MIIoHgYJKoZIhvcNAQcCoIIoDzCCKAsCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCClTqrbd8x/ZwIH # H3BfdSYW8FsHfhgU3KJi886fOpSgJaCCISEwggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqG # SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy # RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg # Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXH # JQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMf # UBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w # 1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRk # tFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYb # qMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUm # cJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP6 # 5x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzK # QtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo # 80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjB # Jgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXche # MBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB # /wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU # 7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG # CCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDig # NqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v # dEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZI # hvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd # 4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiC # qBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl # /Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeC # RK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYT # gAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/ # a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37 # xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmL # NriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0 # YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJ # RyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIG # sDCCBJigAwIBAgIQCK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0BAQwFADBiMQsw # CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu # ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw # HhcNMjEwNDI5MDAwMDAwWhcNMzYwNDI4MjM1OTU5WjBpMQswCQYDVQQGEwJVUzEX # MBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0 # ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMIICIjAN # BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1bQvQtAorXi3XdU5WRuxiEL1M4zr # PYGXcMW7xIUmMJ+kjmjYXPXrNCQH4UtP03hD9BfXHtr50tVnGlJPDqFX/IiZwZHM # gQM+TXAkZLON4gh9NH1MgFcSa0OamfLFOx/y78tHWhOmTLMBICXzENOLsvsI8Irg # nQnAZaf6mIBJNYc9URnokCF4RS6hnyzhGMIazMXuk0lwQjKP+8bqHPNlaJGiTUyC # EUhSaN4QvRRXXegYE2XFf7JPhSxIpFaENdb5LpyqABXRN/4aBpTCfMjqGzLmysL0 # p6MDDnSlrzm2q2AS4+jWufcx4dyt5Big2MEjR0ezoQ9uo6ttmAaDG7dqZy3SvUQa # khCBj7A7CdfHmzJawv9qYFSLScGT7eG0XOBv6yb5jNWy+TgQ5urOkfW+0/tvk2E0 # XLyTRSiDNipmKF+wc86LJiUGsoPUXPYVGUztYuBeM/Lo6OwKp7ADK5GyNnm+960I # HnWmZcy740hQ83eRGv7bUKJGyGFYmPV8AhY8gyitOYbs1LcNU9D4R+Z1MI3sMJN2 # FKZbS110YU0/EpF23r9Yy3IQKUHw1cVtJnZoEUETWJrcJisB9IlNWdt4z4FKPkBH # X8mBUHOFECMhWWCKZFTBzCEa6DgZfGYczXg4RTCZT/9jT0y7qg0IU0F8WD1Hs/q2 # 7IwyCQLMbDwMVhECAwEAAaOCAVkwggFVMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYD # VR0OBBYEFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB8GA1UdIwQYMBaAFOzX44LScV1k # TN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcD # AzB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj # ZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t # L0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0 # cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmww # HAYDVR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcNAQEMBQADggIB # ADojRD2NCHbuj7w6mdNW4AIapfhINPMstuZ0ZveUcrEAyq9sMCcTEp6QRJ9L/Z6j # fCbVN7w6XUhtldU/SfQnuxaBRVD9nL22heB2fjdxyyL3WqqQz/WTauPrINHVUHmI # moqKwba9oUgYftzYgBoRGRjNYZmBVvbJ43bnxOQbX0P4PpT/djk9ntSZz0rdKOtf # JqGVWEjVGv7XJz/9kNF2ht0csGBc8w2o7uCJob054ThO2m67Np375SFTWsPK6Wrx # oj7bQ7gzyE84FJKZ9d3OVG3ZXQIUH0AzfAPilbLCIXVzUstG2MQ0HKKlS43Nb3Y3 # LIU/Gs4m6Ri+kAewQ3+ViCCCcPDMyu/9KTVcH4k4Vfc3iosJocsL6TEa/y4ZXDlx # 4b6cpwoG1iZnt5LmTl/eeqxJzy6kdJKt2zyknIYf48FWGysj/4+16oh7cGvmoLr9 # Oj9FpsToFpFSi0HASIRLlk2rREDjjfAVKM7t8RhWByovEMQMCGQ8M4+uKIw8y4+I # Cw2/O/TOHnuO77Xry7fwdxPm5yg/rBKupS8ibEH5glwVZsxsDsrFhsP2JjMMB0ug # 0wcCampAMEhLNKhRILutG4UI4lkNbcoFUCvqShyepf2gpx8GdOfy1lKQ/a+FSCH5 # Vzu0nAPthkX0tGFuv2jiJmCG6sivqf6UHedjGzqGVnhOMIIGwDCCBKigAwIBAgIQ # DE1pckuU+jwqSj0pB4A9WjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEX # MBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0 # ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTIyMDkyMTAw # MDAwMFoXDTMzMTEyMTIzNTk1OVowRjELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERp # Z2lDZXJ0MSQwIgYDVQQDExtEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMiAtIDIwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDP7KUmOsap8mu7jcENmtuh6BSF # dDMaJqzQHFUeHjZtvJJVDGH0nQl3PRWWCC9rZKT9BoMW15GSOBwxApb7crGXOlWv # M+xhiummKNuQY1y9iVPgOi2Mh0KuJqTku3h4uXoW4VbGwLpkU7sqFudQSLuIaQyI # xvG+4C99O7HKU41Agx7ny3JJKB5MgB6FVueF7fJhvKo6B332q27lZt3iXPUv7Y3U # TZWEaOOAy2p50dIQkUYp6z4m8rSMzUy5Zsi7qlA4DeWMlF0ZWr/1e0BubxaompyV # R4aFeT4MXmaMGgokvpyq0py2909ueMQoP6McD1AGN7oI2TWmtR7aeFgdOej4TJEQ # ln5N4d3CraV++C0bH+wrRhijGfY59/XBT3EuiQMRoku7mL/6T+R7Nu8GRORV/zbq # 5Xwx5/PCUsTmFntafqUlc9vAapkhLWPlWfVNL5AfJ7fSqxTlOGaHUQhr+1NDOdBk # +lbP4PQK5hRtZHi7mP2Uw3Mh8y/CLiDXgazT8QfU4b3ZXUtuMZQpi+ZBpGWUwFjl # 5S4pkKa3YWT62SBsGFFguqaBDwklU/G/O+mrBw5qBzliGcnWhX8T2Y15z2LF7OF7 # ucxnEweawXjtxojIsG4yeccLWYONxu71LHx7jstkifGxxLjnU15fVdJ9GSlZA076 # XepFcxyEftfO4tQ6dwIDAQABo4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1Ud # EwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZn # gQwBBAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCP # nshvMB0GA1UdDgQWBBRiit7QYfyPMRTtlwvNPSqUFN9SnDBaBgNVHR8EUzBRME+g # TaBLhklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRS # U0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCB # gDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUF # BzAChkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVk # RzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUA # A4ICAQBVqioa80bzeFc3MPx140/WhSPx/PmVOZsl5vdyipjDd9Rk/BX7NsJJUSx4 # iGNVCUY5APxp1MqbKfujP8DJAJsTHbCYidx48s18hc1Tna9i4mFmoxQqRYdKmEIr # UPwbtZ4IMAn65C3XCYl5+QnmiM59G7hqopvBU2AJ6KO4ndetHxy47JhB8PYOgPvk # /9+dEKfrALpfSo8aOlK06r8JSRU1NlmaD1TSsht/fl4JrXZUinRtytIFZyt26/+Y # siaVOBmIRBTlClmia+ciPkQh0j8cwJvtfEiy2JIMkU88ZpSvXQJT657inuTTH4YB # ZJwAwuladHUNPeF5iL8cAZfJGSOA1zZaX5YWsWMMxkZAO85dNdRZPkOaGK7DycvD # +5sTX2q1x+DzBcNZ3ydiK95ByVO5/zQQZ/YmMph7/lxClIGUgp2sCovGSxVK05iQ # RWAzgOAj3vgDpPZFR+XOuANCR+hBNnF3rf2i6Jd0Ti7aHh2MWsgemtXC8MYiqE+b # vdgcmlHEL5r2X6cnl7qWLoVXwGDneFZ/au/ClZpLEQLIgpzJGgV8unG1TnqZbPTo # ntRamMifv427GFxD9dAq6OJi7ngE273R+1sKqHB+8JeEeOMIA11HLGOoJTiXAdI/ # Otrl5fbmm9x+LMz/F0xNAKLY1gEOuIvu5uByVYksJxlh9ncBjDCCB2IwggVKoAMC # AQICEA6ZYkUs3x6FUkpZyx3fNW8wDQYJKoZIhvcNAQELBQAwaTELMAkGA1UEBhMC # VVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBU # cnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMTAe # Fw0yMjExMTEwMDAwMDBaFw0yMzExMTAyMzU5NTlaMGcxCzAJBgNVBAYTAkFVMREw # DwYDVQQIEwhWaWN0b3JpYTEVMBMGA1UEBxMMTm90dGluZyBIaWxsMRYwFAYDVQQK # Ew1JUFNlYyBQdHkgTHRkMRYwFAYDVQQDEw1JUFNlYyBQdHkgTHRkMIICIjANBgkq # hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuJ4EsEL1x5o2E2m4pFTCeVzGv5URXuSd # Q25eyXUbMGb7VsTbft4MYM6ySZe7I1Yk7Jm/rsSsjDuud9XbvLJB3qX/kdVCFMLn # y2On85sFUQ67ZWHGh5ub9tIJzkJN7BlJ0u2Rw09AeLAArF3yqeQffu/YegMSH8rY # eb8DLvFr9lxKjoWXg5khH3yXWaI0N0g/FHKWL9URn6HSStY90y4ilQCcjwjwA8Vp # gIU9eCDj4kagwdU5ZvOazbzQXJqvzMB09ccLegf2MrPoMseRSksL0BBo5kkq5jiw # Fc4HIf2/RYrjfVWtFLq33tvMDifpI/ZuhiBooaAEe3OA10s8+A4Ps3OkSP2hd/Hq # UXGQZY1FN3fDRworMkEaaqQioeaaSePAIwdGTz2Z2aCY4b5taHWiOM/5+jhCr6Gq # S8TXI1ODtZl2V11/KfKJDjiTes2lQ4zShHNAg40/aTOQxmsvv1zwlM9Dqf8GRDC1 # OThWrPc40s6RztXa9CnC3EQgxIUQs/qQwkToS3dJGcr/bsCmVCHPQKDjHYIHbU8n # CMjSaG1YDIfdRW9MyyAFghtzjDDEyyN+LJCOdEnq4WgiaNIHNDsYABTAy9Nc2u4u # VmQE387ZqbAww2Doo/eiEnPU5y1JgXvxhqgdL2Fg20gXagfBqysTuuExuh/AoSuM # TEO02MRZ+78CAwEAAaOCAgYwggICMB8GA1UdIwQYMBaAFGg34Ou2O/hfEYb7/mF7 # CIhl9E5CMB0GA1UdDgQWBBTZSP/AY1Bcm0dUbWSS+LJDbsyIHzAOBgNVHQ8BAf8E # BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCBqjBToFGgT4ZN # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNp # Z25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0dHA6Ly9jcmw0 # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5 # NlNIQTM4NDIwMjFDQTEuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYB # BQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBlAYIKwYBBQUHAQEE # gYcwgYQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBcBggr # BgEFBQcwAoZQaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcnQwDAYDVR0T # AQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFQZrq6Y5WS74dGqSjbSXHqiQeQhc # emYWRNkPOnA4duyDdKNerNSkYDhqunW3igVhLkjYzV3rxPceL67+mUdy4ppf9g1Q # e8f6cM/wELnKmXH/aCGBVvBEjVJnt3LTQLGUGNu28Np1Hdfg7H0SqRlSuvLCaibr # C87bRHgzCLGixw/Bo2d/SuKze2EXTtt85DLvx7TCOE894bUuhaHUnz207+SUhRnm # W4pvHel8wJWfDN7QXANFvaV667cOlPZ9Kz2Jrxgf389Pj2XPrfIL/oH3U5OY6Q0/ # dHpFrT8s30MpG5iFQKbYn8W4790Gt/tjJVAFhMxYfnylT+ppemmvrltG/0qah903 # /IxMgSVI9I/23Gs83i7ppeCNnncF/5JRfD2qkQqKRHaJx/6rMjV0MDmV+m16bllZ # jEfnXIxPyB1P4tJEwiGtbKhuEX9WbdE5msxy64FFU/4Ucxa8dIjllcr1MMfwJttX # QDLtBYXDFrtb4r26FGRe3M+mjmZ0skzWPEuZpnjR0wK8Ep8HzEdB5WzLB/7lf70n # YEWfuE1CjviDRz9hesjHZZ7nvPNXuraIRqPdNWnI8eJ7sT+jnL9nP3/h/uDvuHZx # LAUBvRo6iNOOmO34/TZNCV0fBpZEBUBLJTBmFZoBTMV8z156RL7QXjCK1cLgXuCU # OfJLfjrNc5RZvtAxggZTMIIGTwIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQK # Ew5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBD # b2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTECEA6ZYkUs3x6FUkpZ # yx3fNW8wDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKA # ADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYK # KwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgOTGJaBgsVbuyDI+D0RGQXcKPuK4O # Gj9RtCpPY+b559MwDQYJKoZIhvcNAQEBBQAEggIAArkP1iKiUzvdQIYcbp/J37WL # gMwNPEG8vXsYM29VvQPzd98pDuWll53IowSwjgkIntX6+MAvpA6lLX8oO9Eh/Cyk # AKLXrPnetDgHI0b1bi1s5ZH/ORb/pd2YXBo9LKHdwMhDY2FAn0J+C6vKS7Whk2Ak # 2yvOBse+/rU+uTwlicf6KmV+8TVpnzLFNYALQg1zvPUPQS5CbKDoH0N5hlqEAlJ9 # EBJpKsS/9lwKf3zmwW0OC3iE0kmWjMoqT1gdkcvJDfXfUMDB21rWWfUGH+jll1ot # NVwPuMPVFOAnd4Cmtplg6IUiv0uVsXkTCBFeTuPUOM1H1PHfXXsIyFQbPKJkTDov # GHQZF0jyBqltDNTFM8nViNBsTpWoIJ+CX4dKkY5c8wy6mAgCocGh5dWPXslEuSE3 # MiZ+RKUTqR1Pl8oIaWF6iUC4X1K3H7K4Ve4YoOd85xbkzCOduOjYxwKi80b9BGzp # 8RoVjVhB8SiFPC8lZFqCbTt5fQOBkbF+bKruVQcdDkr3mNFG5S9KIeutMJ1P1O9q # K5vzhieI9+WxyJtnp8tRM/B/G9K5gSptTqEZDuIkn8LmxiDRmfMuaiwQbCighazj # m75gZQYOqr3S3jhnCUUugDdH+8RB5yLzuQQAcqQM2belJYkB3K0a1AFduB8upGTR # 7iiYtv8I8tFDspMGacGhggMgMIIDHAYJKoZIhvcNAQkGMYIDDTCCAwkCAQEwdzBj # MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMT # MkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5n # IENBAhAMTWlyS5T6PCpKPSkHgD1aMA0GCWCGSAFlAwQCAQUAoGkwGAYJKoZIhvcN # AQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjIxMTE0MjMwMTU1WjAv # BgkqhkiG9w0BCQQxIgQgFYWiOsH6+x5ZvjudSj3LnfWOXbBJl6m/3uW71AiaZNgw # DQYJKoZIhvcNAQEBBQAEggIAkC1z+4Pmbf6wQ88SWF/iS6ZLYlOAB7lbicrXKyZ1 # bnAmoBFerQlZa0XEyISU/Oy8KxoX40U3ZAR0HqfJ3QqfQSsuHFU8cE8CeFCK5ZUT # MJmEhLGkPeXMdm5kQ2sY1emyYw3WSoD9bAyxgAY8jFJ32Pgbke2kAnydcaRn6KDm # MC8V52M+mb2H5XrP3Nxjks37yTRMruQ7RzHWp+JWpKisSjpxsKXyriXC/hTtdQ/4 # tQ/ntRwevkXW1bF62/dyWek/MHAUJAZ7sD2FKRKJsS6jX000RQVYILcp8goVRTSF # PnvNQtid+8y3ofmcDm4SdJ1cXVV98H5OVFTm4WPgBf+g3pIFLhyfQ3IV70U27mTA # hcC5XMgGusokaCsR7RG5dgq4HgILtovLx7cz42MDcbK8uXMovrQCwJVGV0W3QV37 # 9YzOirauXjgXdFlU8ynnvHpALi0BjPWY3t2OQ6JQm0gQEG/cjKTydtNwyyaijig1 # PLNshKIHKdEO/1pJWWbVGpcHVnSvzVmUKzJ246W8hdW6Cq+kFInO4mumOmKwtzJZ # PlJPeqMGqMp3siR6fVfEJhR1zHBSiNociv68Gt+++IcbsGORsPEhuYfbEzcb6abO # P2OuVHj1z9fBie+I5rhwZ/riBZutp3XnpcoowND2EUo4gXrxAlGxIFaKSU3wBJOY # d4k= # SIG # End signature block |