WSAPI/VirtualLUNs.psm1

####################################################################################
## © 2020,2021 Hewlett Packard Enterprise Development LP
##
## Permission is hereby granted, free of charge, to any person obtaining a
## copy of this software and associated documentation files (the "Software"),
## to deal in the Software without restriction, including without limitation
## the rights to use, copy, modify, merge, publish, distribute, sublicense,
## and/or sell copies of the Software, and to permit persons to whom the
## Software is furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included
## in all copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
## OTHER DEALINGS IN THE SOFTWARE.
##
## File Name: VirtualLUNs.psm1
## Description: Virtual LUNs cmdlets
##
## Created: February 2020
## Last Modified: February 2020
## History: v3.0 - Created
#####################################################################################

$Info = "INFO:"
$Debug = "DEBUG:"
$global:VSLibraries = Split-Path $MyInvocation.MyCommand.Path
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

############################################################################################################################################
## FUNCTION New-vLun_WSAPI
############################################################################################################################################
Function New-vLun_WSAPI 
{
  <#
  
  .SYNOPSIS
    Creating a VLUN
    
  .DESCRIPTION
    Creating a VLUN
    Any user with Super or Edit role, or any role granted vlun_create permission, can perform this operation.
    
  .EXAMPLE
    New-vLun_WSAPI -VolumeName xxx -LUNID x -HostName xxx

  .EXAMPLE
    New-vLun_WSAPI -VolumeName xxx -LUNID x -HostName xxx -NSP 1:1:1
    
  .PARAMETER VolumeName
    Name of the volume or VV set to export.

  .PARAMETER LUNID
    LUN ID.
    
  .PARAMETER HostName
    Name of the host or host set to which the volume or VV set is to be exported.
    The host set should be in set:hostset_name format.
    
  .PARAMETER NSP
    System port of VLUN exported to. It includes node number, slot number, and card port number.

  .PARAMETER NoVcn
    Specifies that a VCN not be issued after export (-novcn). Default: false.
    
  .PARAMETER WsapiConnection
    WSAPI Connection object created with Connection command
    
  .Notes
    NAME : New-vLun_WSAPI
    LASTEDIT: February 2020
    KEYWORDS: New-vLun_WSAPI
   
  .Link
     http://www.hpe.com
 
  #Requires PS -Version 3.0
  
  #>

  [CmdletBinding()]
  Param(
      [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
      [System.String]
      $VolumeName,
      
      [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$true)]
      [int]
      $LUNID,
      
      [Parameter(Position=2, Mandatory=$true, ValueFromPipeline=$true)]
      [System.String]
      $HostName,
      
      [Parameter(Position=3, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $NSP,
      
      [Parameter(Position=4, Mandatory=$false, ValueFromPipeline=$true)]
      [Boolean]
      $NoVcn = $false,
      
      [Parameter(Position=5, Mandatory=$false, ValueFromPipeline=$true)]
      $WsapiConnection = $global:WsapiConnection
  )

  Begin 
  {
    # Test if connection exist
    Test-WSAPIConnection -WsapiConnection $WsapiConnection
  }

  Process 
  {
    # Creation of the body hash
    Write-DebugLog "Running: Creation of the body hash" $Debug
    $body = @{}    
    
    If ($VolumeName) 
    { 
        $body["volumeName"] ="$($VolumeName)" 
    }  
    If ($LUNID) 
    { 
        $body["lun"] =$LUNID
    }
    If ($HostName) 
    { 
        $body["hostname"] ="$($HostName)" 
    }
    If ($NSP) 
    {
        $NSPbody = @{} 
        
        $list = $NSP.split(":")
        
        $NSPbody["node"] = [int]$list[0]        
        $NSPbody["slot"] = [int]$list[1]
        $NSPbody["cardPort"] = [int]$list[2]        
        
        $body["portPos"] = $NSPbody        
    }
    If ($NoVcn) 
    { 
        $body["noVcn"] = $NoVcn
    }
    
    
    $Result = $null
    
    #Request
    $Result = Invoke-WSAPI -uri '/vluns' -type 'POST' -body $body -WsapiConnection $WsapiConnection
    $status = $Result.StatusCode    
    if($status -eq 201)
    {
        write-host ""
        write-host "Cmdlet executed successfully" -foreground green
        #write-host "SUCCESS: Status Code : $Result.StatusCode ." -foreground green
        #write-host "SUCCESS: Status Description : $Result.StatusDescription." -foreground green
        write-host ""
        Write-DebugLog "SUCCESS: Successfully Created a VLUN" $Info    
        Get-vLun_WSAPI -VolumeName $VolumeName -LUNID $LUNID -HostName $HostName
        
        Write-DebugLog "End: New-vLun_WSAPI" $Debug
    }
    else
    {
        write-host ""
        write-host "FAILURE : While Creating a VLUN" -foreground red
        write-host ""
        Write-DebugLog "FAILURE : Creating a VLUN" $Info
        Write-DebugLog "End: New-vLun_WSAPI" $Debug
        
        return $Result.StatusDescription
    }    
  }
  End 
  {
  }  
}
#ENG New-vLun_WSAPI

############################################################################################################################################
## FUNCTION Remove-vLun_WSAPI
############################################################################################################################################
Function Remove-vLun_WSAPI
 {
  <#
    
  .SYNOPSIS
    Removing a VLUN.
  
  .DESCRIPTION
    Removing a VLUN
    Any user with the Super or Edit role, or any role granted with the vlun_remove right, can perform this operation.
    
  .EXAMPLE
    Remove-vLun_WSAPI -VolumeName xxx -LUNID xx -HostName xxx

  .EXAMPLE
    Remove-vLun_WSAPI -VolumeName xxx -LUNID xx -HostName xxx -NSP x:x:x
    
  .PARAMETER VolumeName
    Name of the volume or VV set to be exported.
    The VV set should be in set:<volumeset_name> format.
  
  .PARAMETER LUNID
   Lun Id
   
  .PARAMETER HostName
    Name of the host or host set to which the volume or VV set is to be exported. For VLUN of port type, the value is empty.
    The host set should be in set:<hostset_name> format.required if volume is exported to host or host set,or to both the host or host set and port
  
  .PARAMETER NSP
    Specifies the system port of the VLUN export. It includes the system node number, PCI bus slot number, and card port number on the FC card in the format:<node>:<slot>:<port>
    required if volume is exported to port, or to both host and port .Notes NAME : Remove-vLun_WSAPI
 
  .PARAMETER WsapiConnection
    WSAPI Connection object created with Connection command
 
  .Notes
    NAME : Remove-vLun_WSAPI
    LASTEDIT: February 2020
    KEYWORDS: Remove-vLun_WSAPI
   
  .Link
     http://www.hpe.com
 
  #Requires PS -Version 3.0
    
  #>

  [CmdletBinding(SupportsShouldProcess = $True,ConfirmImpact = 'High')]
  Param(
      [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
      [System.String]
      $VolumeName,
      
      [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$true)]
      [int]
      $LUNID,
      
      [Parameter(Position=2, Mandatory=$true, ValueFromPipeline=$true)]
      [System.String]
      $HostName,
      
      [Parameter(Position=3, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $NSP,

      [Parameter(Position=4, Mandatory=$false, ValueFromPipeline=$true)]
      $WsapiConnection = $global:WsapiConnection      
    )
    
  Begin 
  {
    # Test if connection exist
    Test-WSAPIConnection -WsapiConnection $WsapiConnection
  }

  Process 
  {    
    #Build uri
    Write-DebugLog "Running: Building uri to Remove-vLun_WSAPI ." $Debug
    $uri = "/vluns/"+$VolumeName+","+$LUNID+","+$HostName
    
    if($NSP)
    {
        $uri = $uri+","+$NSP
    }    

    #init the response var
    $Result = $null

    #Request
    Write-DebugLog "Request: Request to Remove-vLun_WSAPI : $CPGName (Invoke-WSAPI)." $Debug
    $Result = Invoke-WSAPI -uri $uri -type 'DELETE' -WsapiConnection $WsapiConnection
    
    $status = $Result.StatusCode
    if($status -eq 200)
    {
        write-host ""
        write-host "Cmdlet executed successfully" -foreground green
        write-host ""
        Write-DebugLog "SUCCESS: VLUN Successfully removed with Given Values [ VolumeName : $VolumeName | LUNID : $LUNID | HostName : $HostName | NSP : $NSP ]." $Info
        Write-DebugLog "End: Remove-vLun_WSAPI" $Debug
        return $Result        
    }
    else
    {
        write-host ""
        write-host "FAILURE : While Removing VLUN with Given Values [ VolumeName : $VolumeName | LUNID : $LUNID | HostName : $HostName | NSP : $NSP ]. " -foreground red
        write-host ""
        Write-DebugLog "FAILURE : While Removing VLUN with Given Values [ VolumeName : $VolumeName | LUNID : $LUNID | HostName : $HostName | NSP : $NSP ]." $Info
        Write-DebugLog "End: Remove-vLun_WSAPI" $Debug
        
        return $Result.StatusDescription
    }    
    
  }
  End {}  
}
#END Remove-vLun_WSAPI

############################################################################################################################################
## FUNCTION Get-vLun_WSAPI
############################################################################################################################################
Function Get-vLun_WSAPI 
{
  <#
  .SYNOPSIS
    Get Single or list of VLun.
  
  .DESCRIPTION
    Get Single or list of VLun
        
  .EXAMPLE
    Get-vLun_WSAPI
    Display a list of VLun.
    
  .EXAMPLE
    Get-vLun_WSAPI -VolumeName xxx -LUNID x -HostName xxx
    Display a list of VLun.

  .PARAMETER VolumeName
    Name of the volume to be exported.
  
  .PARAMETER LUNID
   Lun
   
  .PARAMETER HostName
    Name of the host to which the volume is to be exported. For VLUN of port type, the value is empty.
        
  .PARAMETER NSP
    The <n:s:p> variable identifies the node, slot, and port of the device.

  .PARAMETER WsapiConnection
    WSAPI Connection object created with Connection command
    
  .Notes
    NAME : Get-vLun_WSAPI
    LASTEDIT: February 2020
    KEYWORDS: Get-vLun_WSAPI
   
  .Link
     http://www.hpe.com
 
  #Requires PS -Version 3.0
  #>


  [CmdletBinding()]
  Param(
      [Parameter(Position=0, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $Vlun_id,
      
      [Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $VolumeName,
      
      [Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$true)]
      [int]
      $LUNID,
      
      [Parameter(Position=3, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $HostName,
      
      [Parameter(Position=4, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $NSP,
      
      [Parameter(Position=5, Mandatory=$false, ValueFromPipeline=$true)]
      $WsapiConnection = $global:WsapiConnection
  )

  Begin 
  {
    # Test if connection exist
    Test-WSAPIConnection -WsapiConnection $WsapiConnection     
  }

  Process 
  {
    Write-DebugLog "Request: Request to Get-vLun_WSAPI [ VolumeName : $VolumeName | LUNID : $LUNID | HostName : $HostName | NSP : $NSP] (Invoke-WSAPI)." $Debug
    #Request
    
    $Result = $null
    $dataPS = $null        
    $uri = "/vluns/"+$Vlun_id+"/"
    # Results
    if($VolumeName)
    {
        #Build uri
        $uri = $uri+$VolumeName            
    }
    if($LUNID)
    {
        if($VolumeName)
        {
            #Build uri
            $uri = $uri+","+$LUNID            
        }
        else
        {
            $uri = $uri+$LUNID
        }
        
    }
    if($HostName)
    {
        if($VolumeName -Or $LUNID)
        {
            #Build uri
            $uri = $uri+","+$HostName            
        }
        else
        {
            $uri = $uri+$HostName
        }
    }
    if($NSP)
    {
        if($VolumeName -Or $LUNID -Or $HostName)
        {
            #Build uri
            $uri = $uri+","+$NSP            
        }
        else
        {
            $uri = $uri+$NSP
        }
    }
    if($Vlun_id -Or $VolumeName -Or $LUNID -Or $HostName -Or $NSP)
    {
        #Request
        $Result = Invoke-WSAPI -uri $uri -type 'GET' -WsapiConnection $WsapiConnection
        If($Result.StatusCode -eq 200)
        {
            $dataPS = ($Result.content | ConvertFrom-Json).members
        }
    }
    else
    {
        #Request
        $Result = Invoke-WSAPI -uri '/vluns' -type 'GET' -WsapiConnection $WsapiConnection
        If($Result.StatusCode -eq 200)
        {            
            $dataPS = ($Result.content | ConvertFrom-Json).members            
        }        
    }

    If($Result.StatusCode -eq 200)
    {
        if($dataPS.Count -gt 0)
            {
                write-host ""
                write-host "Cmdlet executed successfully" -foreground green
                write-host ""
                Write-DebugLog "SUCCESS: Get-vLun_WSAPI successfully Executed." $Info
                
                return $dataPS
            }
            else
            {
                write-host ""
                write-host "FAILURE : While Executing Get-vLun_WSAPI. Expected Result Not Found [ VolumeName : $VolumeName | LUNID : $LUNID | HostName : $HostName | NSP : $NSP]." -foreground red
                write-host ""
                Write-DebugLog "FAILURE : While Executing Get-vLun_WSAPI. Expected Result Not Found [ VolumeName : $VolumeName | LUNID : $LUNID | HostName : $HostName | NSP : $NSP]" $Info
                
                return 
            }
    }
    else
    {
        write-host ""
        write-host "FAILURE : While Executing Get-vLun_WSAPI." -foreground red
        write-host ""
        Write-DebugLog "FAILURE : While Executing Get-vLun_WSAPI. " $Info
        
        return $Result.StatusDescription
    }
  }
    End {}
}#END Get-vLun_WSAPI


############################################################################################################################################
## FUNCTION Get-vLunUsingFilters_WSAPI
############################################################################################################################################
Function Get-vLunUsingFilters_WSAPI 
{
  <#
  .SYNOPSIS
    Get VLUNs using filters.
  
  .DESCRIPTION
    Get VLUNs using filters.
    Available filters for VLUN queries
    Use the following filters to query VLUNs:
    • volumeWWN
    • remoteName
    • volumeName
    • hostname
    • serial
        
  .EXAMPLE
    Get-vLunUsingFilters_WSAPI -VolumeWWN "xxx"

  .EXAMPLE
    Get-vLunUsingFilters_WSAPI -VolumeWWN "xxx,yyy,zzz"
    
  .EXAMPLE
    Get-vLunUsingFilters_WSAPI -RemoteName "xxx"
    
  .EXAMPLE
    Get-vLunUsingFilters_WSAPI -RemoteName "xxx,yyy,zzz"
    
  .EXAMPLE
    Get-vLunUsingFilters_WSAPI -RemoteName "xxx" -VolumeWWN "xxx"
    Supporting single or multipule values using ","

  .EXAMPLE
    Get-vLunUsingFilters_WSAPI -RemoteName "xxx" -VolumeWWN "xxx" -VolumeName "xxx"
    Supporting single or multipule values using ","
    
  .EXAMPLE
    Get-vLunUsingFilters_WSAPI -RemoteName "xxx" -VolumeWWN "xxx" -VolumeName "xxx" -HostName "xxx"
    Supporting single or multipule values using ","
    
  .EXAMPLE
    Get-vLunUsingFilters_WSAPI -RemoteName "xxx" -VolumeWWN "xxx" -VolumeName "xxx" -HostName "xxx" -Serial "xxx"
    Supporting single or multipule values using ","
    
  .PARAMETER VolumeWWN
    The value of <VolumeWWN> is the WWN of the exported volume
    
  .PARAMETER RemoteName
    the <RemoteName> value is the host WWN or an iSCSI pathname.
    
  .PARAMETER VolumeName
    Volume Name
    
  .PARAMETER HostName
    Host Name
    
  .PARAMETER Serial
    To Get volumes using a serial number
 
  .PARAMETER WsapiConnection
    WSAPI Connection object created with Connection command
 
  .Notes
    NAME : Get-vLunUsingFilters_WSAPI
    LASTEDIT: February 2020
    KEYWORDS: Get-vLunUsingFilters_WSAPI
   
  .Link
     http://www.hpe.com
 
  #Requires PS -Version 3.0
  #>


  [CmdletBinding()]
  Param(
      [Parameter(Position=0, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $VolumeWWN,
      
      [Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $RemoteName,
      
      [Parameter(Position=3, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $VolumeName,
      
      [Parameter(Position=4, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $HostName,
      
      [Parameter(Position=5, Mandatory=$false, ValueFromPipeline=$true)]
      [System.String]
      $Serial,
      
      [Parameter(Position=6, Mandatory=$false, ValueFromPipeline=$true)]
      $WsapiConnection = $global:WsapiConnection
  )

  Begin 
  {
    # Test if connection exist
    Test-WSAPIConnection -WsapiConnection $WsapiConnection     
  }

  Process 
  {
    Write-DebugLog "Request: Request to Get-vLunUsingFilters_WSAPI VVSetName : $VVSetName (Invoke-WSAPI)." $Debug
    #Request
    
    $Result = $null
    $dataPS = $null        
    $Query="?query="" """
    
    # Results
    if($VolumeWWN)
    {        
        $Query = LoopingFunction -Value $VolumeWWN -condition "volumeWWN" -flg $false -Query $Query        
    }
    if($RemoteName)
    {
        if($VolumeWWN)
        {
            $Query = LoopingFunction -Value $RemoteName -condition "remoteName" -flg $true -Query $Query
        }
        else
        {
            $Query = LoopingFunction -Value $RemoteName -condition "remoteName" -flg $false -Query $Query
        }
    }
    if($VolumeName)
    {
        if($VolumeWWN -or $RemoteName)
        {
            $Query = LoopingFunction -Value $VolumeName -condition "volumeName" -flg $true -Query $Query
        }
        else
        {
            $Query = LoopingFunction -Value $VolumeName -condition "volumeName" -flg $false -Query $Query
        }
    }
    if($HostName)
    {
        if($VolumeWWN -or $RemoteName -or $VolumeName)
        {
            $Query = LoopingFunction -Value $HostName -condition "hostname" -flg $true -Query $Query
        }
        else
        {
            $Query = LoopingFunction -Value $HostName -condition "hostname" -flg $false -Query $Query
        }
    }
    if($Serial)
    {
        if($VolumeWWN -or $RemoteName -or $VolumeName -or $HostName)
        {
            $Query = LoopingFunction -Value $Serial -condition "serial" -flg $true -Query $Query
        }
        else
        {
            $Query = LoopingFunction -Value $Serial -condition "serial" -flg $false -Query $Query
        }
    }
    
    if($VolumeWWN -or $RemoteName -or $VolumeName -or $HostName -or $Serial)
    {
        #Build uri
        $uri = '/vluns/'+$Query
        
        #write-host "uri = $uri"
        
        #Request
        $Result = Invoke-WSAPI -uri $uri -type 'GET' -WsapiConnection $WsapiConnection        
        If($Result.StatusCode -eq 200)
        {            
            $dataPS = ($Result.content | ConvertFrom-Json).members            
        }
    }    

    If($Result.StatusCode -eq 200)
    {
        if($dataPS.Count -gt 0)
        {
            write-host ""
            write-host "Cmdlet executed successfully" -foreground green
            write-host ""
            Write-DebugLog "SUCCESS: Get-vLunUsingFilters_WSAPI successfully Executed." $Info
            
            return $dataPS
        }
        else
        {
            write-host ""
            write-host "FAILURE : While Executing Get-vLunUsingFilters_WSAPI. Expected Result Not Found with Given Filter Option : VolumeWWN/$VolumeWWN RemoteName/$RemoteName VolumeName/$VolumeName HostName/$HostName Serial/$Serial." -foreground red
            write-host ""
            Write-DebugLog "FAILURE : While Executing Get-vLunUsingFilters_WSAPI. Expected Result Not Found with Given Filter Option : VolumeWWN/$VolumeWWN RemoteName/$RemoteName VolumeName/$VolumeName HostName/$HostName Serial/$Serial." $Info
            
            return 
        }
    }
    else
    {
        write-host ""
        write-host "FAILURE : While Executing Get-vLunUsingFilters_WSAPI." -foreground red
        write-host ""
        Write-DebugLog "FAILURE : While Executing Get-vLunUsingFilters_WSAPI. " $Info
        
        return $Result.StatusDescription
    }
  }
    End {}
}#END Get-vLunUsingFilters_WSAPI


Export-ModuleMember New-vLun_WSAPI , Remove-vLun_WSAPI , Get-vLun_WSAPI , Get-vLunUsingFilters_WSAPI
# SIG # Begin signature block
# MIIhEAYJKoZIhvcNAQcCoIIhATCCIP0CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCv65TELQmvu5E8
# Z9ciadBWsICPpaqxOsA7HtNUVeaiE6CCEKswggUpMIIEEaADAgECAhB4Lu4fcD9z
# xUgD+jf1OoqlMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoT
# D1NlY3RpZ28gTGltaXRlZDEkMCIGA1UEAxMbU2VjdGlnbyBSU0EgQ29kZSBTaWdu
# aW5nIENBMB4XDTIxMDUyODAwMDAwMFoXDTIyMDUyODIzNTk1OVowgZAxCzAJBgNV
# BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlQYWxvIEFsdG8x
# KzApBgNVBAoMIkhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIENvbXBhbnkxKzAp
# BgNVBAMMIkhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIENvbXBhbnkwggEiMA0G
# CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDmclZSXJBXA55ijwwFymuq+Y4F/quF
# mm2vRdEmjFhzRvTpnGjIYtVcG11ka4JGCROmNVDZGAelnqcXn5DKO710j5SICTBC
# 5gXOLwga7usifs21W+lVT0BsZTiUnFu4hEhuFTlahJIEvPGVgO1GBcuItD2QqB4q
# 9j15GDI5nGBSzIyJKMctcIalxsTSPG1kiDbLkdfsIivhe9u9m8q6NRqDUaYYQTN+
# /qGCqVNannMapH8tNHqFb6VdzUFI04t7kFtSk00AkdD6qUvA4u8mL2bUXAYz8K5m
# nrFs+ckx5Yqdxfx68EO26Bt2qbz/oTHxE6FiVzsDl90bcUAah2l976ebAgMBAAGj
# ggGQMIIBjDAfBgNVHSMEGDAWgBQO4TqoUzox1Yq+wbutZxoDha00DjAdBgNVHQ4E
# FgQUlC56g+JaYFsl5QWK2WDVOsG+pCEwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB
# /wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEQYJYIZIAYb4QgEBBAQDAgQQMEoG
# A1UdIARDMEEwNQYMKwYBBAGyMQECAQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8v
# c2VjdGlnby5jb20vQ1BTMAgGBmeBDAEEATBDBgNVHR8EPDA6MDigNqA0hjJodHRw
# Oi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29SU0FDb2RlU2lnbmluZ0NBLmNybDBz
# BggrBgEFBQcBAQRnMGUwPgYIKwYBBQUHMAKGMmh0dHA6Ly9jcnQuc2VjdGlnby5j
# b20vU2VjdGlnb1JTQUNvZGVTaWduaW5nQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRw
# Oi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAY+1n2UUlQU6Z
# VoEVaZKqZf/zrM/d7Kbx+S/t8mR2E+uNXStAnwztElqrm3fSr+5LMRzBhrYiSmea
# w9c/0c7qFO9mt8RR2q2uj0Huf+oAMh7TMuMKZU/XbT6tS1e15B8ZhtqOAhmCug6s
# DuNvoxbMpokYevpa24pYn18ELGXOUKlqNUY2qOs61GVvhG2+V8Hl/pajE7yQ4diz
# iP7QjMySms6BtZV5qmjIFEWKY+UTktUcvN4NVA2J0TV9uunDbHRt4xdY8TF/Clgz
# Z/MQHJ/X5yX6kupgDeN2t3o+TrColetBnwk/SkJEsUit0JapAiFUx44j4w61Qanb
# Zmi0tr8YGDCCBYEwggRpoAMCAQICEDlyRDr5IrdR19NsEN0xNZUwDQYJKoZIhvcN
# AQEMBQAwezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3Rl
# cjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQx
# ITAfBgNVBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0xOTAzMTIwMDAw
# MDBaFw0yODEyMzEyMzU5NTlaMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3
# IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VS
# VFJVU1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0
# aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIAS
# ZRc2DsPbCLPQrFcNdu3NJ9NMrVCDYeKqIE0JLWQJ3M6Jn8w9qez2z8Hc8dOx1ns3
# KBErR9o5xrw6GbRfpr19naNjQrZ28qk7K5H44m/Q7BYgkAk+4uh0yRi0kdRiZNt/
# owbxiBhqkCI8vP4T8IcUe/bkH47U5FHGEWdGCFHLhhRUP7wz/n5snP8WnRi9UY41
# pqdmyHJn2yFmsdSbeAPAUDrozPDcvJ5M/q8FljUfV1q3/875PbcstvZU3cjnEjpN
# rkyKt1yatLcgPcp/IjSufjtoZgFE5wFORlObM2D3lL5TN5BzQ/Myw1Pv26r+dE5p
# x2uMYJPexMcM3+EyrsyTO1F4lWeL7j1W/gzQaQ8bD/MlJmszbfduR/pzQ+V+DqVm
# sSl8MoRjVYnEDcGTVDAZE6zTfTen6106bDVc20HXEtqpSQvf2ICKCZNijrVmzyWI
# zYS4sT+kOQ/ZAp7rEkyVfPNrBaleFoPMuGfi6BOdzFuC00yz7Vv/3uVzrCM7LQC/
# NVV0CUnYSVgaf5I25lGSDvMmfRxNF7zJ7EMm0L9BX0CpRET0medXh55QH1dUqD79
# dGMvsVBlCeZYQi5DGky08CVHWfoEHpPUJkZKUIGy3r54t/xnFeHJV4QeD2PW6WK6
# 1l9VLupcxigIBCU5uA4rqfJMlxwHPw1S9e3vL4IPAgMBAAGjgfIwge8wHwYDVR0j
# BBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYDVR0OBBYEFFN5v1qqK0rPVIDh
# 2JvAnfKyA2bLMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MBEGA1Ud
# IAQKMAgwBgYEVR0gADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLmNvbW9k
# b2NhLmNvbS9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDA0BggrBgEFBQcBAQQo
# MCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTANBgkqhkiG
# 9w0BAQwFAAOCAQEAGIdR3HQhPZyK4Ce3M9AuzOzw5steEd4ib5t1jp5y/uTW/qof
# nJYt7wNKfq70jW9yPEM7wD/ruN9cqqnGrvL82O6je0P2hjZ8FODN9Pc//t64tIrw
# kZb+/UNkfv3M0gGhfX34GRnJQisTv1iLuqSiZgR2iJFODIkUzqJNyTKzuugUGrxx
# 8VvwQQuYAAoiAxDlDLH5zZI3Ge078eQ6tvlFEyZ1r7uq7z97dzvSxAKRPRkA0xdc
# Ods/exgNRc2ThZYvXd9ZFk8/Ub3VRRg/7UqO6AZhdCMWtQ1QcydER38QXYkqa4Ux
# FMToqWpMgLxqeM+4f452cpkMnf7XkQgWoaNflTCCBfUwggPdoAMCAQICEB2iSDBv
# myYY0ILgln0z02owDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMV
# VGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENl
# cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEwMjAwMDAwMFoXDTMwMTIzMTIz
# NTk1OVowfDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3Rl
# cjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQw
# IgYDVQQDExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3
# DQEBAQUAA4IBDwAwggEKAoIBAQCGIo0yhXoYn0nwli9jCB4t3HyfFM/jJrYlZilA
# hlRGdDFixRDtsocnppnLlTDAVvWkdcapDlBipVGREGrgS2Ku/fD4GKyn/+4uMyD6
# DBmJqGx7rQDDYaHcaWVtH24nlteXUYam9CflfGqLlR5bYNV+1xaSnAAvaPeX7Wpy
# vjg7Y96Pv25MQV0SIAhZ6DnNj9LWzwa0VwW2TqE+V2sfmLzEYtYbC43HZhtKn52B
# xHJAteJf7wtF/6POF6YtVbC3sLxUap28jVZTxvC6eVBJLPcDuf4vZTXyIuosB69G
# 2flGHNyMfHEo8/6nxhTdVZFuihEN3wYklX0Pp6F8OtqGNWHTAgMBAAGjggFkMIIB
# YDAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUDuE6
# qFM6MdWKvsG7rWcaA4WtNA4wDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYB
# Af8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwMGCCsGAQUFBwMIMBEGA1UdIAQKMAgw
# BgYEVR0gADBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVzdC5j
# b20vVVNFUlRydXN0UlNBQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYIKwYB
# BQUHAQEEajBoMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20v
# VVNFUlRydXN0UlNBQWRkVHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9v
# Y3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggIBAE1jUO1HNEphpNve
# aiqMm/EAAB4dYns61zLC9rPgY7P7YQCImhttEAcET7646ol4IusPRuzzRl5ARokS
# 9At3WpwqQTr81vTr5/cVlTPDoYMot94v5JT3hTODLUpASL+awk9KsY8k9LOBN9O3
# ZLCmI2pZaFJCX/8E6+F0ZXkI9amT3mtxQJmWunjxucjiwwgWsatjWsgVgG10Xkp1
# fqW4w2y1z99KeYdcx0BNYzX2MNPPtQoOCwR/oEuuu6Ol0IQAkz5TXTSlADVpbL6f
# ICUQDRn7UJBhvjmPeo5N9p8OHv4HURJmgyYZSJXOSsnBf/M6BZv5b9+If8AjntIe
# Q3pFMcGcTanwWbJZGehqjSkEAnd8S0vNcL46slVaeD68u28DECV3FTSK+TbMQ5Lk
# uk/xYpMoJVcp+1EZx6ElQGqEV8aynbG8HArafGd+fS7pKEwYfsR7MUFxmksp7As9
# V1DSyt39ngVR5UR43QHesXWYDVQk/fBO4+L4g71yuss9Ou7wXheSaG3IYfmm8SoK
# C6W59J7umDIFhZ7r+YMp08Ysfb06dy6LN0KgaoLtO0qqlBCk4Q34F8W2WnkzGJLj
# tXX4oemOCiUe5B7xn1qHI/+fpFGe+zmAEc3btcSnqIBv5VPU4OOiwtJbGvoyJi1q
# V3AcPKRYLqPzW0sH3DJZ84enGm1YMYIPuzCCD7cCAQEwgZAwfDELMAkGA1UEBhMC
# R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9y
# ZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdvIFJT
# QSBDb2RlIFNpZ25pbmcgQ0ECEHgu7h9wP3PFSAP6N/U6iqUwDQYJYIZIAWUDBAIB
# BQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
# BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg
# 4kbRY17dgQgOV3Yp4KCnXyB3VCaAIwXpncxbNsof61swDQYJKoZIhvcNAQEBBQAE
# ggEAdPAm+z9RMSt19rGwIkXNqxQmgi/l8LMG0znSIQfRaHrYOwozaaY7Rtwz1GwP
# 0tEkJ1qXtyYO5rkno1GceiLDQmVXIz9PYUA1cjzeDIrpygX0s7pOZLqAL4kf4znD
# U7MfsdGeTOnOtTdiXi+vAdBYmJa8JQ98f7KwabO2lRv/cfpLrcm71ZFmdwB1+Mlx
# joZi1bW0sSJ7SDbeKS95ucEwpGZvVBRYjIaQSJQ8E1lqdf0U812zODId9PbZabu8
# utZp827321o6sYvwuW7jBJ35y08GYkzVqzVUC0fGq7jaMdHdcWMmay+ySGCvfFQk
# 98ZxwtLyKYI7uxlgzfIE40wM7qGCDX0wgg15BgorBgEEAYI3AwMBMYINaTCCDWUG
# CSqGSIb3DQEHAqCCDVYwgg1SAgEDMQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcN
# AQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQCAQUABCBrUgwd
# Pzqd1cOe6Jib/rFMozMUVh+KRiUbhhywGPouAAIQKnyDGSaU6qmgkIkHBuRjwRgP
# MjAyMTA2MTkwNTI5MzFaoIIKNzCCBP4wggPmoAMCAQICEA1CSuC+Ooj/YEAhzhQA
# 8N0wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln
# aUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQTAeFw0yMTAxMDEw
# MDAwMDBaFw0zMTAxMDYwMDAwMDBaMEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5E
# aWdpQ2VydCwgSW5jLjEgMB4GA1UEAxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjEw
# ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC5mGEZ8WK9Q0IpEXKY2tR
# 1zoRQr0KdXVNlLQMULUmEP4dyG+RawyW5xpcSO9E5b+bYc0VkWJauP9nC5xj/TZq
# gfop+N0rcIXeAhjzeG28ffnHbQk9vmp2h+mKvfiEXR52yeTGdnY6U9HR01o2j8aj
# 4S8bOrdh1nPsTm0zinxdRS1LsVDmQTo3VobckyON91Al6GTm3dOPL1e1hyDrDo4s
# 1SPa9E14RuMDgzEpSlwMMYpKjIjF9zBa+RSvFV9sQ0kJ/SYjU/aNY+gaq1uxHTDC
# m2mCtNv8VlS8H6GHq756WwogL0sJyZWnjbL61mOLTqVyHO6fegFz+BnW/g1JhL0B
# AgMBAAGjggG4MIIBtDAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNV
# HSUBAf8EDDAKBggrBgEFBQcDCDBBBgNVHSAEOjA4MDYGCWCGSAGG/WwHATApMCcG
# CCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHwYDVR0jBBgw
# FoAU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHQYDVR0OBBYEFDZEho6kurBmvrwoLR1E
# Nt3janq8MHEGA1UdHwRqMGgwMqAwoC6GLGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv
# bS9zaGEyLWFzc3VyZWQtdHMuY3JsMDKgMKAuhixodHRwOi8vY3JsNC5kaWdpY2Vy
# dC5jb20vc2hhMi1hc3N1cmVkLXRzLmNybDCBhQYIKwYBBQUHAQEEeTB3MCQGCCsG
# AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTwYIKwYBBQUHMAKGQ2h0
# dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1cmVkSURU
# aW1lc3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggEBAEgc3LXpmiO85xrn
# IA6OZ0b9QnJRdAojR6OrktIlxHBZvhSg5SeBpU0UFRkHefDRBMOG2Tu9/kQCZk3t
# aaQP9rhwz2Lo9VFKeHk2eie38+dSn5On7UOee+e03UEiifuHokYDTvz0/rdkd2Nf
# I1Jpg4L6GlPtkMyNoRdzDfTzZTlwS/Oc1np72gy8PTLQG8v1Yfx1CAB2vIEO+MDh
# XM/EEXLnG2RJ2CKadRVC9S0yOIHa9GCiurRS+1zgYSQlT7LfySmoc0NR2r1j1h9b
# m/cuG08THfdKDXF+l7f0P4TrweOjSaH6zqe/Vs+6WXZhiV9+p7SOZ3j5Npjhyyja
# W4emii8wggUxMIIEGaADAgECAhAKoSXW1jIbfkHkBdo2l8IVMA0GCSqGSIb3DQEB
# CwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNV
# BAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQg
# SUQgUm9vdCBDQTAeFw0xNjAxMDcxMjAwMDBaFw0zMTAxMDcxMjAwMDBaMHIxCzAJ
# BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
# aWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBU
# aW1lc3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9
# 0DLuS82Pf92puoKZxTlUKFe2I0rEDgdFM1EQfdD5fU1ofue2oPSNs4jkl79jIZCY
# vxO8V9PD4X4I1moUADj3Lh477sym9jJZ/l9lP+Cb6+NGRwYaVX4LJ37AovWg4N4i
# Pw7/fpX786O6Ij4YrBHk8JkDbTuFfAnT7l3ImgtU46gJcWvgzyIQD3XPcXJOCq3f
# QDpct1HhoXkUxk0kIzBdvOw8YGqsLwfM/fDqR9mIUF79Zm5WYScpiYRR5oLnRlD9
# lCosp+R1PrqYD4R/nzEU1q3V8mTLex4F0IQZchfxFwbvPc3WTe8GQv2iUypPhR3E
# HTyvz9qsEPXdrKzpVv+TAgMBAAGjggHOMIIByjAdBgNVHQ4EFgQU9LbhIB3+Ka7S
# 5GGlsqIlssgXNW4wHwYDVR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wEgYD
# VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYB
# BQUHAwgweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k
# aWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0
# LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4
# oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJv
# b3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy
# dEFzc3VyZWRJRFJvb3RDQS5jcmwwUAYDVR0gBEkwRzA4BgpghkgBhv1sAAIEMCow
# KAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCwYJYIZI
# AYb9bAcBMA0GCSqGSIb3DQEBCwUAA4IBAQBxlRLpUYdWac3v3dp8qmN6s3jPBjdA
# hO9LhL/KzwMC/cWnww4gQiyvd/MrHwwhWiq3BTQdaq6Z+CeiZr8JqmDfdqQ6kw/4
# stHYfBli6F6CJR7Euhx7LCHi1lssFDVDBGiy23UC4HLHmNY8ZOUfSBAYX4k4YU1i
# RiSHY4yRUiyvKYnleB/WCxSlgNcSR3CzddWThZN+tpJn+1Nhiaj1a5bA9FhpDXzI
# AbG5KHW3mWOFIoxhynmUfln8jA/jb7UBJrZspe6HUSHkWGCbugwtK22ixH67xCUr
# RwIIfEmuE7bhfEJCKMYYVs9BNLZmXbZ0e/VWMyIvIjayS6JKldj1po5SMYIChjCC
# AoICAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
# MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hB
# MiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQQIQDUJK4L46iP9gQCHOFADw3TAN
# BglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJ
# KoZIhvcNAQkFMQ8XDTIxMDYxOTA1MjkzMVowKwYLKoZIhvcNAQkQAgwxHDAaMBgw
# FgQU4deCqOGRvu9ryhaRtaq0lKYkm/MwLwYJKoZIhvcNAQkEMSIEID33gKFhnnSf
# IjdRK2MYqKKPDvJIekHYrBG/hn8aacxXMDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIE
# ILMQkAa8CtmDB5FXKeBEA0Fcg+MpK2FPJpZMjTVx7PWpMA0GCSqGSIb3DQEBAQUA
# BIIBACvDTAsZ9W6PC0yiiOkNEZnugGgUnm0TAOUulSr4DMFO3GcjKPE8A9T4MrGF
# eltXOBZ+59ENljqDvpn8XenhT0wzaov2BJh4hhGJBwP9WcmoKl93X6ocQeE07rJ0
# M7aZ695lwopf4nOHceYbzbgQXm9Z4MirlJvU3r6q1kBhQ1wECC3q9zQZVgxRXsRx
# L0B49ebaiiIwzXsTDXh3DLzsvDZbnvPM/FwvSYR9o5I7fCmopoNpW/J/gP9cftMD
# tudspni/0GxUpoTB58BS405SExwPiZADNHwLPU5StNVkOmScIfeIm71tw+udpOac
# TABlWaMnjHW17cpZXuTHhDqnm+Y=
# SIG # End signature block