Akamai.MOKS.psm1

function Expand-MOKSClientCertDetails {
    [CmdletBinding()]
    Param(
        [Parameter()]
        [string]
        $CertificateName,
        
        [Parameter()]
        $CertificateID,

        [Parameter()]
        [string]
        $Version,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey,

        [Parameter(ValueFromRemainingArguments)]
        $UnusedArgs
    )

    $CommonParams = @{
        'EdgeRCFile'       = $EdgeRCFile
        'Section'          = $Section
        'AccountSwitchKey' = $AccountSwitchKey
        'Debug'            = ($PSBoundParameters.Debug -eq $true)
    }

    if ($CertificateName -ne '') {
        # Check cache if enabled
        if ($Global:AkamaiOptions.EnableDataCache) {
            $CertificateID = $Global:AkamaiDataCache.MOKS.ClientCerts.$CertificateName.CertificateID
        }

        if (-not $CertificateID) {
            Write-Debug "Expand-MOKSClientCertDetails: '$CertificateName' - Retrieving Client Certificate details."
            $ClientCerts = Get-MOKSClientCert @CommonParams
            $ClientCert = $ClientCerts | Where-Object certificateName -eq $CertificateName
            if ($null -eq $ClientCert) {
                throw "Client certificate '$CertificateName' not found."
            }
            $CertificateID = $ClientCert.certificateId
        }

        # Add to data cache
        if ($Global:AkamaiOptions.EnableDataCache -and -not $Global:AkamaiDataCache.MOKS.ClientCerts.$CertificateName) {
            $Global:AkamaiDataCache.MOKS.ClientCerts.$CertificateName = @{
                'CertificateID' = $CertificateID
            }
        }
        Write-Debug "Expand-MOKSClientCertDetails: CertificateID = $CertificateID."
    }

    if ($Version -and $Version.ToLower() -in 'latest', 'deployed') {
        Write-Debug "Expand-MOKSClientCertDetails: '$CertificateID' - Retrieving Client Certificate versions."
        $Versions = Get-MOKSClientCertVersion -CertificateID $CertificateID @CommonParams | Sort-Object -property Version -Descending
        if ($Version.ToLower() -eq 'latest') {
            $Version = $Versions[0].version
        }
        elseif ($Version.ToLower() -eq 'deployed') {
            $DeployedVersion = $Versions | Where-Object status -eq 'DEPLOYED'
            if ($null -eq $DeployedVersion) {
                Throw "No deployed version of client certificate '$CertificateID'."
            }
            $Version = $DeployedVersion.version
        }
        Write-Debug "Expand-MOKSClientCertDetails: Version = $Version."
    }

    return $CertificateID, $Version
}

function Get-BodyObject {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        $Source
    )

    if ($Source -is 'String') {
        # Trim whitespace
        $Source = $Source.Trim()
        # Handle JSON array
        if ($Source.StartsWith('[')) {
            $BodyObject = ConvertFrom-Json -InputObject $Source -AsArray -NoEnumerate
        }
        # Handle standard JSON object
        elseif ($Source.StartsWith('{') -and $Source.EndsWith('}')) {
            $BodyObject = ConvertFrom-Json -InputObject $Source
        }
        # If none of the above, just use string as-is
        else {
            $BodyObject = $Source
        }
    }
    elseif ($Source -is 'Hashtable') {
        $BodyObject = [PScustomObject] $Source
    }
    elseif ($Source -is 'PSCustomObject' -or $Source -is 'Object' -or $Source -is 'Object[]') {
        $BodyObject = $Source
    }
    else {
        throw "Source param is of an unhandled type '$($Source.GetType().Name)'."
    }

    return $BodyObject
}


function Complete-MOKSClientCertVersion {
    [CmdletBinding(DefaultParameterSetName = 'Name & file')]
    Param(
        [Parameter(ParameterSetName = 'Name & file')]
        [Parameter(ParameterSetName = 'Name & body')]
        [string]
        $CertificateName,

        [Parameter(ParameterSetName = 'ID & file')]
        [Parameter(ParameterSetName = 'ID & body')]
        [int]
        $CertificateID,

        [Parameter(Mandatory)]
        [ValidatePattern('^(latest|deployed|[0-9]+)$')]
        [string]
        $Version,

        [Parameter()]
        [switch]
        $AcknowledgeAllWarnings,

        [Parameter(Mandatory, ParameterSetName = 'Name & file')]
        [Parameter(Mandatory, ParameterSetName = 'ID & file')]
        [string]
        $CertificateFile,

        [Parameter(ParameterSetName = 'Name & file')]
        [Parameter(ParameterSetName = 'ID & file')]
        [string]
        $TrustChainFile,

        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Name & body')]
        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ID & body')]
        $Body,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey
    )

    process {
        $CertificateID, $Version = Expand-MOKSClientCertDetails @PSBoundParameters
        $Path = "/mtls-origin-keystore/v1/client-certificates/$CertificateID/versions/$Version/certificate-block"
        $QueryParameters = @{
            'acknowledgeAllWarnings' = $PSBoundParameters.AcknowledgeAllWarnings.IsPresent
        }
        if ($PSCmdlet.ParameterSetName.Contains('file')) {
            if (-not (Test-Path $CertificateFile)) {
                throw "Certificate file '$CertificateFile' not found."
            }
            $CertData = Get-Content -Raw $CertificateFile
            $Body = @{
                'certificate' = $CertData
            }
            if ($TrustChainFile) {
                if (-not (Test-Path $TrustChainFile)) {
                    throw "Trust chain file '$TrustChainFile' not found."
                }
                $TrustData = Get-Content -Raw $TrustChainFile
                $Body.trustChain = $TrustData
            }
        }

        $RequestParams = @{
            'Path'             = $Path
            'Method'           = 'POST'
            'Body'             = $Body
            'QueryParameters'  = $QueryParameters
            'EdgeRCFile'       = $EdgeRCFile
            'Section'          = $Section
            'AccountSwitchKey' = $AccountSwitchKey
            'Debug'            = ($PSBoundParameters.Debug -eq $true)
        }
        # Make Request
        $Response = Invoke-AkamaiRequest @RequestParams
        return $Response.Body
    }
}


function Get-MOKSCACert {
    [CmdletBinding()]
    Param(
        [Parameter()]
        [string]
        $Status,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey
    )

    process {
        $Path = "/mtls-origin-keystore/v1/ca-certificates"
        $QueryParameters = @{
            'status' = $Status
        }

        $RequestParams = @{
            'Path'             = $Path
            'Method'           = 'GET'
            'QueryParameters'  = $QueryParameters
            'EdgeRCFile'       = $EdgeRCFile
            'Section'          = $Section
            'AccountSwitchKey' = $AccountSwitchKey
            'Debug'            = ($PSBoundParameters.Debug -eq $true)
        }
        # Make Request
        $Response = Invoke-AkamaiRequest @RequestParams
        return $Response.Body.certificates
    }
}


function Get-MOKSClientCert {
    [CmdletBinding(DefaultParameterSetName = '__AllParameterSets__')]
    Param(
        [Parameter(ParameterSetName = 'Name')]
        [string]
        $CertificateName,

        [Parameter(ParameterSetName = 'ID', ValueFromPipeline)]
        [int]
        $CertificateID,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey
    )

    process {
        if ($PSCmdlet.ParameterSetName -eq 'Name' -or $PSCmdlet.ParameterSetName -eq 'ID') {
            $CertificateID, $null = Expand-MOKSClientCertDetails @PSBoundParameters
            $Path = "/mtls-origin-keystore/v1/client-certificates/$CertificateID"
        }
        else {
            $Path = "/mtls-origin-keystore/v1/client-certificates"
        }

        $RequestParams = @{
            'Path'             = $Path
            'Method'           = 'GET'
            'EdgeRCFile'       = $EdgeRCFile
            'Section'          = $Section
            'AccountSwitchKey' = $AccountSwitchKey
            'Debug'            = ($PSBoundParameters.Debug -eq $true)
        }

        try {
            # Make Request
            $Response = Invoke-AkamaiRequest @RequestParams

            # Add to data cache
            if ($AkamaiOptions.EnableDataCache) {
                if ($CertificateID) {
                    Set-AkamaiDataCache -MOKSClientCertName $Response.Body.certificateName -MOKSClientCertID $Response.Body.certificateId
                }
                else {
                    foreach ($ClientCert in $Response.Body.certificates) {
                        Set-AkamaiDataCache -MOKSClientCertName $ClientCert.certificateName -MOKSClientCertID $ClientCert.certificateId
                    }
                }
            }

            if ($CertificateID) {
                return $Response.Body
            }
            else {
                return $Response.Body.certificates
            }
        }
        catch {
            throw $_
        }
    }
}


function Get-MOKSClientCertVersion {
    [CmdletBinding(DefaultParameterSetName = 'ID')]
    Param(
        [Parameter(ParameterSetName = 'name', Mandatory)]
        [string]
        $CertificateName,

        [Parameter(ParameterSetName = 'ID', Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [int]
        $CertificateID,

        [Parameter()]
        [switch]
        $IncludeAssociatedProperties,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey
    )

    process {
        $CertificateID, $null = Expand-MOKSClientCertDetails @PSBoundParameters
        $Path = "/mtls-origin-keystore/v1/client-certificates/$CertificateID/versions"
        $QueryParameters = @{
            'includeAssociatedProperties' = $PSBoundParameters.IncludeAssociatedProperties.IsPresent
        }
        $RequestParams = @{
            'Path'             = $Path
            'Method'           = 'GET'
            'QueryParameters'  = $QueryParameters
            'EdgeRCFile'       = $EdgeRCFile
            'Section'          = $Section
            'AccountSwitchKey' = $AccountSwitchKey
            'Debug'            = ($PSBoundParameters.Debug -eq $true)
        }
        # Make Request
        $Response = Invoke-AkamaiRequest @RequestParams
        return $Response.Body.versions
    }
}

function New-MOKSClientCert {
    [CmdletBinding(DefaultParameterSetName = 'Attributes')]
    Param(
        [Parameter(Mandatory, ParameterSetName = 'Attributes')]
        [string]
        $CertificateName,

        [Parameter(Mandatory, ParameterSetName = 'Attributes')]
        [string]
        $ContractID,

        [Parameter(Mandatory, ParameterSetName = 'Attributes')]
        [int]
        $GroupID,

        [Parameter(ParameterSetName = 'Attributes')]
        [ValidateSet('CORE', 'RUSSIAN_AND_CORE', 'CHINA_AND_CORE')]
        [string]
        $Geography = 'CORE',

        [Parameter(Mandatory, ParameterSetName = 'Attributes')]
        [ValidateSet('STANDARD_TLS', 'ENHANCED_TLS')]
        [string]
        $SecureNetwork,

        [Parameter(Mandatory, ParameterSetName = 'Attributes')]
        [ValidateSet('AKAMAI', 'THIRD_PARTY')]
        [string]
        $Signer,

        [Parameter(Mandatory, ParameterSetName = 'Attributes')]
        [string]
        $NotificationEmails,

        [Parameter(ParameterSetName = 'Attributes')]
        [string]
        $PreferredCA,

        [Parameter(Mandatory, ParameterSetName = 'Attributes')]
        [ValidateSet('RSA', 'ECDSA')]
        [string]
        $KeyAlgorithm,

        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Body')]
        $Body,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey
    )

    process {
        $Path = "/mtls-origin-keystore/v1/client-certificates"
        if ($PSCmdlet.ParameterSetName -eq 'Attributes') {
            $Body = @{
                'certificateName'    = $CertificateName
                'contractId'         = $ContractID
                'groupId'            = $GroupID
                'geography'          = $Geography
                'notificationEmails' = ($NotificationEmails.Replace(' ', '') -split ',')
                'secureNetwork'      = $SecureNetwork
                'signer'             = $Signer
            }
            if ($PreferredCA) { $Body.preferredCa = $PreferredCA }
            if ($KeyAlgorithm) { $Body.keyAlgorithm = $KeyAlgorithm }
            if ($Subject) { $Body.subject = $Subject }
        }

        $RequestParams = @{
            'Path'             = $Path
            'Method'           = 'POST'
            'Body'             = $Body
            'EdgeRCFile'       = $EdgeRCFile
            'Section'          = $Section
            'AccountSwitchKey' = $AccountSwitchKey
            'Debug'            = ($PSBoundParameters.Debug -eq $true)
        }

        try {
            # Make Request
            $Response = Invoke-AkamaiRequest @RequestParams

            # Add to data cache
            if ($AkamaiOptions.EnableDataCache) {
                Set-AkamaiDataCache -MOKSClientCertName $Response.Body.certificateName -MOKSClientCertID $Response.Body.certificateId
            }

            return $Response.Body
        }
        catch {
            throw $_
        }
    }
}


function New-MOKSClientCertVersion {
    [CmdletBinding(DefaultParameterSetName = 'Name')]
    Param(
        [Parameter(ParameterSetName = 'Name', Mandatory)]
        [string]
        $CertificateName,

        [Parameter(ParameterSetName = 'ID', Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [int]
        $CertificateID,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey
    )

    process {
        $CertificateID, $null = Expand-MOKSClientCertDetails @PSBoundParameters
        $Path = "/mtls-origin-keystore/v1/client-certificates/$CertificateID/versions"

        $RequestParams = @{
            'Path'             = $Path
            'Method'           = 'POST'
            'EdgeRCFile'       = $EdgeRCFile
            'Section'          = $Section
            'AccountSwitchKey' = $AccountSwitchKey
            'Debug'            = ($PSBoundParameters.Debug -eq $true)
        }
        # Make Request
        $Response = Invoke-AkamaiRequest @RequestParams
        return $Response.Body
    }
}

function Remove-MOKSClientCertVersion {
    [CmdletBinding(DefaultParameterSetName = 'ID')]
    Param(
        [Parameter(ParameterSetName = 'Name', Mandatory)]
        [string]
        $CertificateName,

        [Parameter(ParameterSetName = 'ID', Mandatory)]
        [int]
        $CertificateID,

        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [ValidatePattern('^(latest|deployed|[0-9]+)$')]
        [string]
        $Version,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey
    )

    process {
        $CertificateID, $Version = Expand-MOKSClientCertDetails @PSBoundParameters
        $Path = "/mtls-origin-keystore/v1/client-certificates/$CertificateID/versions/$Version"

        $RequestParams = @{
            'Path'             = $Path
            'Method'           = 'DELETE'
            'EdgeRCFile'       = $EdgeRCFile
            'Section'          = $Section
            'AccountSwitchKey' = $AccountSwitchKey
            'Debug'            = ($PSBoundParameters.Debug -eq $true)
        }
        # Make Request
        $Response = Invoke-AkamaiRequest @RequestParams
        return $Response.Body
    }
}


function Set-MOKSClientCert {
    [CmdletBinding(DefaultParameterSetName = 'Name & attributes')]
    Param(
        [Parameter(ParameterSetName = 'Name & attributes', Mandatory)]
        [Parameter(ParameterSetName = 'Name & body', Mandatory)]
        [string]
        $CertificateName,

        [Parameter(ParameterSetName = 'ID &attributes', Mandatory, ValueFromPipelineByPropertyName)]
        [Parameter(ParameterSetName = 'ID & body', Mandatory, ValueFromPipelineByPropertyName)]
        [int]
        $CertificateID,

        [Parameter(ParameterSetName = 'Name & attributes', Mandatory)]
        [Parameter(ParameterSetName = 'ID &attributes', Mandatory)]
        [string]
        $NewName,

        [Parameter(ParameterSetName = 'Name & attributes', Mandatory)]
        [Parameter(ParameterSetName = 'ID &attributes', Mandatory)]
        [string]
        $NotificationEmails,

        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Name & body')]
        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ID & body')]
        $Body,

        [Parameter()]
        [string]
        $EdgeRCFile,

        [Parameter()]
        [string]
        $Section,

        [Parameter()]
        [string]
        $AccountSwitchKey
    )

    process {
        $CertificateID, $null = Expand-MOKSClientCertDetails @PSBoundParameters
        $Path = "/mtls-origin-keystore/v1/client-certificates/$CertificateID"
        if ($PSCmdlet.ParameterSetName.Contains('attributes')) {
            $Body = @{
                'certificateName'    = $NewName
                'notificationEmails' = ($NotificationEmails.Replace(' ', '') -split ',')
            }
        }
        $RequestParams = @{
            'Path'             = $Path
            'Method'           = 'PATCH'
            'Body'             = $Body
            'EdgeRCFile'       = $EdgeRCFile
            'Section'          = $Section
            'AccountSwitchKey' = $AccountSwitchKey
            'Debug'            = ($PSBoundParameters.Debug -eq $true)
        }
        # Make Request
        $Response = Invoke-AkamaiRequest @RequestParams
        return $Response.Body
    }
}


# SIG # Begin signature block
# MIIKmAYJKoZIhvcNAQcCoIIKiTCCCoUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBS8IYiiG8m5CWM
# Gkx4bAc9kDmYQ2xCaAMaNQNXoR13/KCCB1owggdWMIIFPqADAgECAhAGRzH371Sh
# X6hjGl1wSSyYMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQK
# Ew5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBD
# b2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjYwMjI1MDAw
# MDAwWhcNMjcwMzEwMjM1OTU5WjCB3jETMBEGCysGAQQBgjc8AgEDEwJVUzEZMBcG
# CysGAQQBgjc8AgECEwhEZWxhd2FyZTEdMBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6
# YXRpb24xEDAOBgNVBAUTBzI5MzM2MzcxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1N
# YXNzYWNodXNldHRzMRIwEAYDVQQHEwlDYW1icmlkZ2UxIDAeBgNVBAoTF0FrYW1h
# aSBUZWNobm9sb2dpZXMgSW5jMSAwHgYDVQQDExdBa2FtYWkgVGVjaG5vbG9naWVz
# IEluYzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAJeMKuhiUI5WSRdG
# IPhNWLpaVPlXbSazhGuvzZxTi623Ht46hiPejDtWB8F8dT2pd+nOWsx5NVgkv7x/
# Tz35cZcWVMDxq/K7wYe9R2GndGgfEL02/j5rslwHr8e6qFzy1axuL/xaGXuBTVrS
# Qw25019l1KalUHwInKLIP7Hw1HLPTacyJNNTsYmOpZNqKIiQe9ivzBd7SuPU0cGi
# 1YHUk4ZQh6Ig5tBx8XZYjTmzbiQr2WWwk/CufaoIPME5zAvmW99S05rAtOqvoUr7
# eoLUQ/TcMMA6eOliAbO5m0w/pv5YDgzhzt9hQez189zZNOkMO6AcHNitJzzsEvCg
# 7fhPHxoXvasRJ0EaCEze0nuVakLPf+mGCLoZYGRctayOn4HP6LEEOGmAnQBZkwFR
# 6zxk0hzAMOkK/p7MV9V6QwOuk9q7WKnIdzS/4RjRtXNxXb2fMNyBEwrwJhdmEhWF
# 0eS0Wd6Uz3IbSr0+XH8FHLflQXFCkPcZKiGPgSCp8rTP3KHr6wIDAQABo4ICAjCC
# Af4wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFKT3
# RICOlmcsnPu7KwUf9HL4YegLMD0GA1UdIAQ2MDQwMgYFZ4EMAQMwKTAnBggrBgEF
# BQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIH
# gDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRw
# Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmlu
# Z1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hB
# Mzg0MjAyMUNBMS5jcmwwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhho
# dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNl
# cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNB
# NDA5NlNIQTM4NDIwMjFDQTEuY3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQAD
# ggIBAGSBrSnUReHUzGTy9VC6hy2oDSpu2QNu5j3o/uoaaAy2CgI0hVJRL/OfYinL
# R4hJofuNNKORp2MWXpy52L5PCGtD6/Hf92bMkDl1AP6nXuplt5HvkFPh5kVDbQ7o
# HfI1Pup2IOpKxb00UNwjtKy+38ZCX0dgkASP2vQFamBCG0eTaGUh/9ZH9rz11Nkr
# 9p83Snz/3eW3vOeKAFL3S5RDEMkTvv09540mnzA4J5lKGES2eje/FhwCCQUQBvqC
# voNFNZHyXvW9v8KqX/3CcN1LAtGCy4XnkFjQRPyn+o/OJv5M5yX2Rm5kq9dYpWnD
# U2xgxMR1BZaDf+uDoqGsLo4OqbPV4Dftp2FDs8DHMD8xP6i/k4htaWShkdyjdijr
# 9TBOi+pS9vNlcCKjwLq6aibcbkUk7ef3wxR5imhajsX22vy8Zd9ByAk07BJrccgg
# JGczCtiKcD6LZtP3VjnqhYPSQ4jk6wCruqcTCTwwO7FrIROVrWb2Ro+ph+/a5Llj
# 5ryLyp+6NAgtNwyrkp2WxZviLbh5AXnmg9Pnwrz64UE93LEjI23AWBJsLFdJTbis
# Z/tTgozdVdPZf2Dy2k8xfYZoIq6V1oWiAoQCzb5B9nETV5NGjiMPskJ4GwnlzOvz
# +4IgLQjl0V5I08Qw+3uvPQ8rHHMLbKgncTqSxqtZ73kItOztMYIClDCCApACAQEw
# fTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNV
# BAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hB
# Mzg0IDIwMjEgQ0ExAhAGRzH371ShX6hjGl1wSSyYMA0GCWCGSAFlAwQCAQUAoGow
# GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG
# AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIBfPHYr+DOloEdOEVJM9vvKYWS91EV98
# WPlnuAMZuTNZMA0GCSqGSIb3DQEBAQUABIIBgCcP0cW1bPpo8y0VWqNZndX8kG1Z
# yiu4xbtOYCN8ljobgW5E2C/8y/cFpTaa1lEcMB/V7zX5dl7QUcdgfiXa8QlmNNEJ
# ADkJ+ybe8U/jC2PaFQuebNCjovExbW+NYBbp5xDZY8RSBk2uL7vhM6byQkJZ6SnQ
# KpAVLLzA9QGACEhRUPfNjjJmVureXbEC6BAYMWhv8/NcAFsgZcb4CMQ1F0D8cp8i
# cn0DctQZg9DQy1k/fxEQ0hY4aBTSu5KfdJwUSbOXzIMJDzoHdzFeSX4s476aUYmA
# eIIenGZ0SenHLlXy2iWKINRnl9wk+GDpZ1UBa2QXBuO2DXKRk0iHsmnAHT9CmFVx
# pnWxRASalBzB6qPJryPbuKPr+HIvdu3j9nh4sxSAbXXysMq87ytneGnf5FPUwM2U
# jaUCQPly4iockHZf8XwhHWXOqxaTo8umLrAYIFeKM+DrOqArZ4ApQ89Edl7sVErO
# J5JPj8Tq4F4VzrV682MtfeV2ciCXo7NfunYqjQ==
# SIG # End signature block