AzurePSDriveStorageAccount.psm1

using namespace Microsoft.PowerShell.SHiPS

$script:Azure_Storage = if($IsCoreCLR){'Azure.Storage.NetCore'}else{'Azure.Storage'}
$script:AzureRM_Storage = if($IsCoreCLR){'AzureRM.Storage.NetCore'}else{'AzureRM.Storage'}


[SHiPSProvider(UseCache=$true)]
class StorageAccounts : SHiPSDirectory
{
    StorageAccounts() : base ($this.GetType())
    {
    }

    StorageAccounts([string]$name): base($name)
    {
    }

    [object[]] GetChildItem()
    {
        $obj =  @()                     
        @(& "$script:AzureRM_Storage\Get-AzureRmStorageAccount").Foreach{
             $obj += [StorageAccount]::new($($_.StorageAccountName), $_) 
        }          
        return $obj 
    }
 }

[SHiPSProvider(UseCache=$true)]
class StorageAccount : SHiPSDirectory
{ 
    Hidden [object]$data = $null

    StorageAccount ([string]$name, [object]$data) : base ($name) 
    {
        $this.data = $data
    }

    [object[]] GetChildItem()
    {        
        $obj =  @()

        $ev = $null
        try{
                $result=& "$script:Azure_Storage\Get-AzureStorageContainer" -Context $this.data.Context -ErrorAction SilentlyContinue -ErrorVariable ev
                if($ev) {
                    Write-Verbose $ev.Exception
                }else{
                    $obj+=[Blobs]::new($this.data, $result);
                }
            } catch {
                Write-Verbose $_.Exception
            }
        try{
                $result=& "$script:Azure_Storage\Get-AzureStorageShare" -Context $this.data.Context -ErrorAction SilentlyContinue -ErrorVariable ev
                if($ev) {
                    Write-Verbose $ev.Exception
                } else {
                    $obj+=[Files]::new($this.data, $result)
        
                }
         } catch {
                Write-Verbose $_.Exception
         }
            
        try {
                $result=& "$script:Azure_Storage\Get-AzureStorageTable" -Context $this.data.Context  -ErrorAction SilentlyContinue -ErrorVariable ev
                if($ev){
                    Write-Verbose $ev.Exception 
                } else {
                    $obj+=[Tables]::new($this.data, $result);
                }
        } catch {
                Write-Verbose $_.Exception
        }

        try {
            $result=& "$script:Azure_Storage\Get-AzureStorageQueue" -Context $this.data.Context -ErrorAction SilentlyContinue -ErrorVariable ev
            if($ev){
                Write-Verbose $ev.Exception
            } else {                    
                $obj+=[Queues]::new($this.data, $result);
            }    
        }
         catch {
                Write-Verbose $_.Exception
         }

        return $obj;
    }
}

[SHiPSProvider(UseCache=$true)]
class Blobs : SHiPSDirectory
{
    Hidden [object]$data = $null
    Hidden [object]$result = $null

    Blobs ([object]$data, [object]$result) : base ($this.GetType()) 
    {
        $this.data = $data
        $this.result = $result
    }

    [object[]] GetChildItem()
    {     
        if(-not $this.result)
        {
            Write-Debug "AzurePSDrive: No Blobs."
            return $null
        }

        $obj =  @()
        $this.result | ForEach-Object{     
            $obj+= [Blob]::new($_.Name, $_);                  
        }         
        return $obj     
    }
}

[SHiPSProvider(UseCache=$true)]
class Files : SHiPSDirectory
{
    Hidden [object]$data = $null
    Hidden [object]$result = $null

    Files ([object]$data, [object]$result) : base ($this.GetType()) 
    {
        $this.data = $data
        $this.result = $result        
    }

    [object[]] GetChildItem()
    {      
        if(-not $this.result)
        {
            Write-Debug "AzurePSDrive: No Files found."
            return $null
        }

        <# ConnectionString from cmdlet returns something like below:
            BlobEndpoint=https://<accountname>.blob.core.windows.net/;QueueEndpoint=https://<accountname>.queue.core.windows.net/;
            TableEndpoint=https://<accountname>.table.core.windows.net/;FileEndpoint=https://<accountname>.file.core.windows.net/;AccountName=<accountname>;AccountKey=<token>
        #>

        # Parse the orginal connection string, extract FileEndpoint, and make it net use-able.
        $conectstring = $this.data.Context.ConnectionString -split ';'
        $accountInfo=$conectstring | Where-Object { $_ -match 'AccountName' -or $_ -match 'AccountKey'}
        $fileEndPoint = $conectstring  | Where-Object {$_ -match 'FileEndpoint'}
        $fileshare = $fileEndPoint

        if($fileEndPoint) {
            $index = $fileEndPoint.IndexOf('//')
            if ($index -gt 0) {
                $temp = $fileEndPoint.Substring($index)
                if($temp) {
                    $fileshare = $temp.Replace('/', '\') 
                }   
            }
        }

        return  $this.result | ForEach-Object {           
             [FileShare]::new($_.Name, $this.data.Context, "$fileshare$($_.Name);$($accountInfo)");
            }
    }
}

[SHiPSProvider(UseCache=$true)]
class Tables : SHiPSDirectory
{
    Hidden [object]$data = $null
    Hidden [object]$result = $null

    Tables ([object]$data, [object]$result) : base ($this.GetType()) 
    {
        $this.data = $data
        $this.result = $result        
    }

    [object[]] GetChildItem()
    {     
        return @($this.result | Sort-Object Name)    
    }
}

[SHiPSProvider(UseCache=$true)]
class Queues : SHiPSDirectory
{
    Hidden [object]$data = $null
    Hidden [object]$result = $null

    Queues ([object]$data, [object]$result) : base ($this.GetType()) 
    {
        $this.data = $data
        $this.result = $result                
    }

    [object[]] GetChildItem()
    {     
        return @($this.result | Sort-Object Name)  
    }
}

[SHiPSProvider(UseCache=$true)]
class FileShare : SHiPSDirectory
{ 
    Hidden [string]$shareName = $null
    [object]$Context = $null
    [string]$ConnectionString = $null

    FileShare ([string]$name, [object]$context, [string]$connectionString) : base ($name) 
    {
        $this.shareName = $name        
        $this.context = $context
        $this.ConnectionString = $connectionString
    }

    [object[]] GetChildItem()
    {
        $obj =  @()

        & "$script:Azure_Storage\Get-AzureStorageFile" -Context $this.context -ShareName $this.shareName | ForEach-Object {
            if($_.GetType().Name -eq "CloudFileDirectory") {
                $obj+=[FileFolder]::new($_.Name, $_)
            } else {
                $obj+=[FileShareLeaf]::new($_.Name)
            }
        }

        return $obj
    }
}

class FileShareLeaf : SHiPSLeaf
{
    FileShareLeaf([string]$name): base($name)
    {
    }
}

[SHiPSProvider(UseCache=$true)]
class FileFolder : SHiPSDirectory
{
    Hidden [string]$DirectoryName = $null
    Hidden [object]$CloudFileDirectory = $null

    FileFolder ([string]$name, [object]$cloudFileDirectory) : base ($name) 
    {
        $this.DirectoryName = $name
        $this.CloudFileDirectory = $cloudFileDirectory
    }


    [object[]] GetChildItem()
    { 
        $obj =  @()

        & "$script:Azure_Storage\Get-AzureStorageFile" -Directory $this.CloudFileDirectory | ForEach-Object {
            if($_.GetType().Name -eq "CloudFileDirectory") {
                $obj+=[FileFolder]::new($_.Name, $_)
            } else {
                $obj+=[FileShareLeaf]::new($_.Name)
            }
        }
        return $obj
    }
}

[SHiPSProvider(UseCache=$true)]
class Blob : SHiPSDirectory
{ 
    Hidden [object]$data = $null

    Blob ([string]$name, [object]$data) : base ($name) 
    {
        $this.data = $data
    }

    [object[]] GetChildItem()
    {      
        return @(& "$script:Azure_Storage\Get-AzureStorageBlob" -Context $this.data.Context -Container $this.data.Name | Sort-Object Name)
    }
}


# SIG # Begin signature block
# MIIdhwYJKoZIhvcNAQcCoIIdeDCCHXQCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUu+/3kN3LHuMVr7GL2jSM3XTy
# KMygghhVMIIEwzCCA6ugAwIBAgITMwAAAMzLuBPrXXItRQAAAAAAzDANBgkqhkiG
# 9w0BAQUFADB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G
# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEw
# HwYDVQQDExhNaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EwHhcNMTYwOTA3MTc1ODU2
# WhcNMTgwOTA3MTc1ODU2WjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNO
# OjE0OEMtQzRCOS0yMDY2MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBT
# ZXJ2aWNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwe5bp0PH7Nar
# LeUDfq1E+Jd4WNpGm2kgEVzLGmOAjML+w5RXEzQOQuqTl8SfMUcrg1+to2Ihbu3h
# fPFFRQJq0cPH/i14X1w0cWP6jRqyAqv/T3lSM4O3dDSNZK+QUsUq0yXeF+FmvW0i
# gBHUpOpXEyxHha0QNzbJm9iyCXSu/WaUstgcq8wHA2gvuLdvSA6pDt+AgAUf0o/f
# 2Nwl25HtlDNRiI1PgfSRdw+W0gnSalk3xycrDVFDlVLavPccwXNc0YsNrKFr9T17
# baz3xYPTb/+90NtpUoBgSdpV2Rr7ev7l806lz4mlxEEqFv/xwk7Yws4BowtU9pE1
# zaPyNiV2GQIDAQABo4IBCTCCAQUwHQYDVR0OBBYEFPWhmmbVkedPZa+s2RQAnZdC
# m8+qMB8GA1UdIwQYMBaAFCM0+NlSRnAK7UD7dvuzK7DDNbMPMFQGA1UdHwRNMEsw
# SaBHoEWGQ2h0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3Rz
# L01pY3Jvc29mdFRpbWVTdGFtcFBDQS5jcmwwWAYIKwYBBQUHAQEETDBKMEgGCCsG
# AQUFBzAChjxodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY3Jv
# c29mdFRpbWVTdGFtcFBDQS5jcnQwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI
# hvcNAQEFBQADggEBAJaBLYob96ccjvtcRqUl/51+iQ6TX4WoJCYb+jf3sMtgQLd4
# kLPpCB/2f8uuZePf9wSdjCu2SPFt1Px6vJysXk2B7rReYR3A8G0SsoUv/nCdFjp3
# dtr3lm2xkMU2wv5Ox4BO4Jf+0vT9+s3PbLnPZK/GjUJ1idWSG0sKpXgq7mpSw9SV
# 7jIjjdM0bupBd2xLCKfocxjYir5UYJWiC8C0kb//6F8/JL/n1Gr1Ty7mZdiFjW4F
# BEIxTU3r0EnAqtOv/O0cApLuC9AV1pFixlGgQRqlA/xRQLLaui3j5qGKeJeijYSz
# RJgTY5L21IbbuV6arIrZhpJkL059QogKBFgjmiIwggYBMIID6aADAgECAhMzAAAA
# xOmJ+HqBUOn/AAAAAADEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
# Z25pbmcgUENBIDIwMTEwHhcNMTcwODExMjAyMDI0WhcNMTgwODExMjAyMDI0WjB0
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
# AoIBAQCIirgkwwePmoB5FfwmYPxyiCz69KOXiJZGt6PLX4kvOjMuHpF4+nypH4IB
# tXrLGrwDykbrxZn3+wQd8oUK/yJuofJnPcUnGOUoH/UElEFj7OO6FYztE5o13jhw
# VG877K1FCTBJwb6PMJkMy3bJ93OVFnfRi7uUxwiFIO0eqDXxccLgdABLitLckevW
# eP6N+q1giD29uR+uYpe/xYSxkK7WryvTVPs12s1xkuYe/+xxa8t/CHZ04BBRSNTx
# AMhITKMHNeVZDf18nMjmWuOF9daaDx+OpuSEF8HWyp8dAcf9SKcTkjOXIUgy+MIk
# ogCyvlPKg24pW4HvOG6A87vsEwvrAgMBAAGjggGAMIIBfDAfBgNVHSUEGDAWBgor
# BgEEAYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUy9ZihM9gOer/Z8Jc0si7q7fD
# E5gwUgYDVR0RBEswSaRHMEUxDTALBgNVBAsTBE1PUFIxNDAyBgNVBAUTKzIzMDAx
# MitjODA0YjVlYS00OWI0LTQyMzgtODM2Mi1kODUxZmEyMjU0ZmMwHwYDVR0jBBgw
# FoAUSG5k5VAF04KqFzc3IrVtqMp1ApUwVAYDVR0fBE0wSzBJoEegRYZDaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljQ29kU2lnUENBMjAxMV8y
# MDExLTA3LTA4LmNybDBhBggrBgEFBQcBAQRVMFMwUQYIKwYBBQUHMAKGRWh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljQ29kU2lnUENBMjAx
# MV8yMDExLTA3LTA4LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC
# AQAGFh/bV8JQyCNPolF41+34/c291cDx+RtW7VPIaUcF1cTL7OL8mVuVXxE4KMAF
# RRPgmnmIvGar27vrAlUjtz0jeEFtrvjxAFqUmYoczAmV0JocRDCppRbHukdb9Ss0
# i5+PWDfDThyvIsoQzdiCEKk18K4iyI8kpoGL3ycc5GYdiT4u/1cDTcFug6Ay67Sz
# L1BWXQaxFYzIHWO3cwzj1nomDyqWRacygz6WPldJdyOJ/rEQx4rlCBVRxStaMVs5
# apaopIhrlihv8cSu6r1FF8xiToG1VBpHjpilbcBuJ8b4Jx/I7SCpC7HxzgualOJq
# nWmDoTbXbSD+hdX/w7iXNgn+PRTBmBSpwIbM74LBq1UkQxi1SIV4htD50p0/GdkU
# ieeNn2gkiGg7qceATibnCCFMY/2ckxVNM7VWYE/XSrk4jv8u3bFfpENryXjPsbtr
# j4Nsh3Kq6qX7n90a1jn8ZMltPgjlfIOxrbyjunvPllakeljLEkdi0iHv/DzEMQv3
# Lz5kpTdvYFA/t0SQT6ALi75+WPbHZ4dh256YxMiMy29H4cAulO2x9rAwbexqSajp
# lnbIvQjE/jv1rnM3BrJWzxnUu/WUyocc8oBqAU+2G4Fzs9NbIj86WBjfiO5nxEmn
# L9wliz1e0Ow0RJEdvJEMdoI+78TYLaEEAo5I+e/dAs8DojCCBgcwggPvoAMCAQIC
# CmEWaDQAAAAAABwwDQYJKoZIhvcNAQEFBQAwXzETMBEGCgmSJomT8ixkARkWA2Nv
# bTEZMBcGCgmSJomT8ixkARkWCW1pY3Jvc29mdDEtMCsGA1UEAxMkTWljcm9zb2Z0
# IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA3MDQwMzEyNTMwOVoXDTIx
# MDQwMzEzMDMwOVowdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBMIIBIjANBgkqhkiG
# 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn6Fssd/bSJIqfGsuGeG94uPFmVEjUK3O3RhO
# JA/u0afRTK10MCAR6wfVVJUVSZQbQpKumFwwJtoAa+h7veyJBw/3DgSY8InMH8sz
# JIed8vRnHCz8e+eIHernTqOhwSNTyo36Rc8J0F6v0LBCBKL5pmyTZ9co3EZTsIbQ
# 5ShGLieshk9VUgzkAyz7apCQMG6H81kwnfp+1pez6CGXfvjSE/MIt1NtUrRFkJ9I
# AEpHZhEnKWaol+TTBoFKovmEpxFHFAmCn4TtVXj+AZodUAiFABAwRu233iNGu8Qt
# VJ+vHnhBMXfMm987g5OhYQK1HQ2x/PebsgHOIktU//kFw8IgCwIDAQABo4IBqzCC
# AacwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUIzT42VJGcArtQPt2+7MrsMM1
# sw8wCwYDVR0PBAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMIGYBgNVHSMEgZAwgY2A
# FA6sgmBAVieX5SUT/CrhClOVWeSkoWOkYTBfMRMwEQYKCZImiZPyLGQBGRYDY29t
# MRkwFwYKCZImiZPyLGQBGRYJbWljcm9zb2Z0MS0wKwYDVQQDEyRNaWNyb3NvZnQg
# Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCEHmtFqFKoKWtTHNY9AcTLmUwUAYD
# VR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwv
# cHJvZHVjdHMvbWljcm9zb2Z0cm9vdGNlcnQuY3JsMFQGCCsGAQUFBwEBBEgwRjBE
# BggrBgEFBQcwAoY4aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9N
# aWNyb3NvZnRSb290Q2VydC5jcnQwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI
# hvcNAQEFBQADggIBABCXisNcA0Q23em0rXfbznlRTQGxLnRxW20ME6vOvnuPuC7U
# EqKMbWK4VwLLTiATUJndekDiV7uvWJoc4R0Bhqy7ePKL0Ow7Ae7ivo8KBciNSOLw
# UxXdT6uS5OeNatWAweaU8gYvhQPpkSokInD79vzkeJkuDfcH4nC8GE6djmsKcpW4
# oTmcZy3FUQ7qYlw/FpiLID/iBxoy+cwxSnYxPStyC8jqcD3/hQoT38IKYY7w17gX
# 606Lf8U1K16jv+u8fQtCe9RTciHuMMq7eGVcWwEXChQO0toUmPU8uWZYsy0v5/mF
# hsxRVuidcJRsrDlM1PZ5v6oYemIp76KbKTQGdxpiyT0ebR+C8AvHLLvPQ7Pl+ex9
# teOkqHQ1uE7FcSMSJnYLPFKMcVpGQxS8s7OwTWfIn0L/gHkhgJ4VMGboQhJeGsie
# IiHQQ+kr6bv0SMws1NgygEwmKkgkX1rqVu+m3pmdyjpvvYEndAYR7nYhv5uCwSdU
# trFqPYmhdmG0bqETpr+qR/ASb/2KMmyy/t9RyIwjyWa9nR2HEmQCPS2vWY+45CHl
# tbDKY7R4VAXUQS5QrJSwpXirs6CWdRrZkocTdSIvMqgIbqBbjCW/oO+EyiHW6x5P
# yZruSeD3AWVviQt9yGnI5m7qp5fOMSn/DsVbXNhNG6HY+i+ePy5VFmvJE6P9MIIH
# ejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0
# IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5
# WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDEx
# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00
# uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kN
# eWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/n
# qwhQz7NEt13YxC4Ddato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3V
# XHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6x
# jF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5k
# f1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4c
# I6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bys
# AoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexN
# STCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93
# KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX
# 3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEA
# MB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4K
# AFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME
# GDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRw
# Oi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJB
# dXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcw
# AoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJB
# dXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcu
# AzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEA
# bABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3
# DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74
# w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQ
# sP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6Sp
# BQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd
# 8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJx
# Jxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9
# Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEG
# sXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AA
# KcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/
# 1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EK
# sT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCBJww
# ggSYAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAADE
# 6Yn4eoFQ6f8AAAAAAMQwCQYFKw4DAhoFAKCBsDAZBgkqhkiG9w0BCQMxDAYKKwYB
# BAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0B
# CQQxFgQUCkXrTGPAlXSMcD/uh9JQ9UL+flwwUAYKKwYBBAGCNwIBDDFCMECgFoAU
# AFAAbwB3AGUAcgBTAGgAZQBsAGyhJoAkaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
# L1Bvd2VyU2hlbGwgMA0GCSqGSIb3DQEBAQUABIIBAAV3ZoO/vsM5X6b+U18nQ6zM
# eX507Jq8W55UK0/rSN2OjuZ6En5Al+Tde6MaYX0691SCHRs0BY6ypa6eLBicgXNr
# 7R5EVG2JvgeEXRxyB2uYZYxbA+J87wzIc/Am+4fAZRLE4j0Rp2y3U/Y4V4JcWgDX
# oHwPEU/lOi3gtmmANUHxWs2GSkadHA0ETxWilYm6OkVuT+v/Zdf3aoTlJhG89ovr
# X1TO608m/crx1B01+TbqJuU+Eu7Oj7kZDWQhaPlVFBJ+HOWqnqof1xD1Cbme7O9X
# 7iaHLCwOuNAK1bCdiGF7U3sGYJu15PuuElxmsFHIh/0bkH3zBbW72Oswzl0Thxeh
# ggIoMIICJAYJKoZIhvcNAQkGMYICFTCCAhECAQEwgY4wdzELMAkGA1UEBhMCVVMx
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgUENBAhMzAAAAzMu4E+tdci1FAAAAAADMMAkGBSsOAwIaBQCgXTAYBgkq
# hkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xODA2MDUxOTI0
# NThaMCMGCSqGSIb3DQEJBDEWBBTVeWjcEY8qHGKq79G1EC98oewk4zANBgkqhkiG
# 9w0BAQUFAASCAQC9XMVLgiDYzdu9xECI9IqZdxV69jUYqc5eSlcx4WDH40J4iRqt
# 4mY7yKlZVG1bSoOjnwn3vXUp6TnCNe2AqH6rgfISbEyDqL6C5WCfDPRxFvDmEGK9
# N5p29E5uUjJ3JewPk+t1yyY6/7EMj9t/szXTcDke41RIx20w/dlhcDXE1wgj7OiS
# gvRK8KOfXCONayq69r/k2xZKLeyXmK0hrymw9Ioz5OYiontXLCTlya2aiBjkHhrH
# J8ROJ2Zc+ij/nM56tRjaCy5r72LGXFqZ8vyk6XKvQ7Jub8nQUPE+wtt1Ot6PXMNs
# lUA02Vt5MrnZ83QSLflrc07nRoQaCyKPB18o
# SIG # End signature block