Client/OktaConfiguration.ps1

#
# Okta Management
# Allows customers to easily access the Okta Management APIs
# Version: 3.0.0
# Contact: devex-public@okta.com
# Generated by OpenAPI Generator: https://openapi-generator.tech
#

<#
.SYNOPSIS
 
Get the configuration object 'OktaConfiguration'.
 
.DESCRIPTION
 
Get the configuration object 'OktaConfiguration'.
 
.OUTPUTS
 
System.Collections.Hashtable
#>

function Get-OktaConfiguration {

    $Configuration = $Script:Configuration

    if ([string]::IsNullOrEmpty($Configuration["BaseUrl"])) {
        $Configuration["BaseUrl"] = "https://subdomain.okta.com";
    }

    if (!$Configuration.containsKey("AccessToken")) {
        $Configuration["AccessToken"] = $null
    }

    if (!$Configuration.containsKey("ClientId")) {
        $Configuration["ClientId"] = $null
    }

    
    if (!$Configuration.containsKey("Scope")) {
        $Configuration["Scope"] = $null
    }
   
    if (!$Configuration.containsKey("Cookie")) {
        $Configuration["Cookie"] = $null
    }

    if (!$Configuration["DefaultHeaders"]) {
        $Configuration["DefaultHeaders"] = @{}
    }

    if (!$Configuration["ApiKey"]) {
        $Configuration["ApiKey"] = @{}
    }

    if (!$Configuration["ApiKeyPrefix"]) {
        $Configuration["ApiKeyPrefix"] = @{}
    }

    if (!$Configuration.containsKey("Proxy")) {
        $Configuration["Proxy"] = $null
    }

    if (!$Configuration.containsKey("MaxRetries")) {
        $Configuration["MaxRetries"] = $null
    }

    if (!$Configuration.containsKey("RequestTimeout")) {
        $Configuration["RequestTimeout"] = $null
    }

    Return $Configuration

}

<#
.SYNOPSIS
 
Set the configuration.
 
.DESCRIPTION
 
Set the configuration.
 
.PARAMETER BaseUrl
Base URL of the HTTP endpoints
 
.PARAMETER Username
Username in HTTP basic authentication
 
.PARAMETER Password
Password in HTTP basic authentication
 
.PARAMETER ApiKey
API Keys for authentication/authorization
 
.PARAMETER ApiKeyPrefix
Prefix in the API Keys
 
.PARAMETER Cookie
Cookie for authentication/authorization
 
.PARAMETER AccessToken
Access token for authentication/authorization
 
.PARAMETER SkipCertificateCheck
Skip certificate verification
 
.PARAMETER DefaultHeaders
Default HTTP headers to be included in the HTTP request
 
.PARAMETER Proxy
Proxy setting in the HTTP request, e.g.
 
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
 
.PARAMETER MaxRetries
Specify the number of times a request should be retried
 
.PARAMETER RequestTimeout
Specify the timeout in milliseconds for a request
 
.PARAMETER PassThru
Return an object of the Configuration
 
.OUTPUTS
 
System.Collections.Hashtable
#>

function Set-OktaConfiguration {

    [CmdletBinding()]
    Param(
        [string]$BaseUrl,
        [string]$ClientId,
        [string]$Scope,
        [hashtable]$ApiKey,
        [hashtable]$ApiKeyPrefix,
        [AllowEmptyString()]
        [string]$Cookie,
        [AllowEmptyString()]
        [string]$AccessToken,
        [hashtable]$DefaultHeaders,
        [System.Object]$Proxy,
        [int]$MaxRetries,
        [int]$RequestTimeout,
        [switch]$PassThru
    )

    Process {

        If ($BaseUrl) {
            # validate URL
            $URL = $BaseUrl -as [System.URI]
            if (!($null -ne $URL.AbsoluteURI -and $URL.Scheme -match '[http|https]')) {
                throw "Invalid URL '$($BaseUrl)' cannot be used in the base URL."
            }
            $Script:Configuration["BaseUrl"] = $BaseUrl
        }

        If ($ClientId) {
            $Script:Configuration["ClientId"] = $ClientId
        }

        If ($Scope) {
            $Script:Configuration["Scope"] = "openapi " + $Scope
        }

        If ($ApiKey) {
            $Script:Configuration['ApiKey'] = $ApiKey
        }

        If ($ApiKeyPrefix) {
            $Script:Configuration['ApiKeyPrefix'] = $ApiKeyPrefix
        }

        If ($Cookie) {
            $Script:Configuration['Cookie'] = $Cookie
        }

        If ($AccessToken) {
            $Script:Configuration['AccessToken'] = $AccessToken
        }

        If ($DefaultHeaders) {
            $Script:Configuration['DefaultHeaders'] = $DefaultHeaders
        }

        If ($null -ne $Proxy) {
            If ($Proxy.GetType().FullName -ne "System.Net.SystemWebProxy" -and $Proxy.GetType().FullName -ne "System.Net.WebRequest+WebProxyWrapperOpaque") {
                throw "Incorrect Proxy type '$($Proxy.GetType().FullName)'. Must be System.Net.SystemWebProxy or System.Net.WebRequest+WebProxyWrapperOpaque."
            }
            $Script:Configuration['Proxy'] = $Proxy
        } else {
            $Script:Configuration['Proxy'] = $null
        }

         If ($MaxRetries) {
            $Script:Configuration['MaxRetries'] = $MaxRetries
        }

        If ($RequestTimeout) {
            $Script:Configuration['RequestTimeout'] = $RequestTimeout
        }

        If ($PassThru.IsPresent) {
            $Script:Configuration
        }
    }
}

<#
.SYNOPSIS
 
Set the access token value.
 
.DESCRIPTION
 
Set the access token value.
 
.OUTPUTS
 
None
#>


function Set-OktaConfigurationAccessToken {
    [CmdletBinding()]
    [AllowNull()]
    Param(
        [string]$AccessToken        
    )
    Process {
        $Script:Configuration["AccessToken"] = $AccessToken
    }
}

<#
.SYNOPSIS
 
Set the max retries value.
 
.DESCRIPTION
 
Set the max retries value.
 
.OUTPUTS
 
None
#>


function Set-OktaConfigurationMaxRetries {
    [CmdletBinding()]
    Param(
        [int]$MaxRetries        
    )
    Process {
        $Script:Configuration["MaxRetries"] = $MaxRetries
    }
}

<#
.SYNOPSIS
 
Set the request timeout value.
 
.DESCRIPTION
 
Set the request timeout value.
 
.OUTPUTS
 
None
#>


function Set-OktaConfigurationRequestTimeout {
    [CmdletBinding()]
    Param(
        [int]$RequestTimeout        
    )
    Process {
        $Script:Configuration["RequestTimeout"] = $RequestTimeout
    }
}

<#
.SYNOPSIS
 
Set the API Key.
 
.DESCRIPTION
 
Set the API Key.
 
.PARAMETER Id
ID of the security schema
 
.PARAMETER ApiKey
API Key
 
.OUTPUTS
 
None
#>

function Set-OktaConfigurationApiKey {
    [CmdletBinding()]
    Param(
        [string]$Id,
        [AllowEmptyString()]
        [string]$ApiKey
    )
    Process {
        if (!$Script:Configuration["ApiKey"]) {
            $Script:Configuration["ApiKey"] = @{}
        }
        $Script:Configuration["ApiKey"][$Id] = $ApiKey
    }
}

<#
.SYNOPSIS
 
Set the API Key prefix.
 
.DESCRIPTION
 
Set the API Key prefix.
 
.PARAMETER Id
ID of the security schema
 
.PARAMETER ApiKey
API Key prefix
 
.OUTPUTS
 
None
#>

function Set-OktaConfigurationApiKeyPrefix {
    [CmdletBinding()]
    Param(
        [string]$Id,
        [AllowEmptyString()]
        [string]$ApiKeyPrefix
    )
    Process {
        if (!$Script:Configuration["ApiKeyPrefix"]) {
            $Script:Configuration["ApiKeyPrefix"] = @{}
        }
        $Script:Configuration["ApiKeyPrefix"][$Id] = $ApiKeyPrefix
    }
}

<#
.SYNOPSIS
 
Set the default header.
 
.DESCRIPTION
 
Set the default header.
 
.PARAMETER Key
Key of the HTTP header
 
.PARAMETER Value
Value of the HTTP header
 
.OUTPUTS
 
None
#>

function Set-OktaConfigurationDefaultHeader {
    [CmdletBinding()]
    Param(
        [string]$Key,
        [AllowEmptyString()]
        [string]$Value
    )
    Process {
        if (!$Script:Configuration["DefaultHeaders"]) {
            $Script:Configuration["DefaultHeaders"] = @{}
        }
        $Script:Configuration["DefaultHeaders"][$Key] = $Value
    }
}


<#
.SYNOPSIS
 
Get the host setting.
 
.DESCRIPTION
 
Get the host setting in the form of array of hashtables.
 
.OUTPUTS
 
System.Collections.Hashtable[]
#>

function Get-OktaHostSetting {
    return ,@(
          @{
            "Url" = "https://{yourOktaDomain}";
            "Description" = "No description provided";
            "Variables" = @{
              "yourOktaDomain" = @{
                  "Description" = "The domain of your organization. This can be a provided subdomain of an official okta domain (okta.com, oktapreview.com, etc) or one of your configured custom domains.";
                  "DefaultValue" = "subdomain.okta.com";
                }
              }
          }
    )

}

<#
.SYNOPSIS
 
Get the URL from the host settings.
 
.PARAMETER Index
Index of the host settings (array)
 
.PARAMETER Variables
Names and values of the variables (hashtable)
 
.DESCRIPTION
 
Get the URL from the host settings.
 
.OUTPUTS
 
String
#>

function Get-OktaUrlFromHostSetting {

    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline = $true)]
        [Int]$Index,
        [Hashtable]$Variables = @{}
    )

    Process {
        $Hosts = Get-OktaHostSetting

        # check array index out of bound
        if ($Index -lt 0 -or $Index -ge $Hosts.Length) {
            throw "Invalid index $index when selecting the host. Must be less than $($Hosts.Length)"
        }

        $MyHost = $Hosts[$Index];
        $Url = $MyHost["Url"];

        # go through variable and assign a value
        foreach ($h in $MyHost["Variables"].GetEnumerator()) {
            if ($Variables.containsKey($h.Name)) { # check to see if it's in the variables provided by the user
                if ($h.Value["EnumValues"] -Contains $Variables[$h.Name]) {
                   $Url = $Url.replace("{$($h.Name)}", $Variables[$h.Name])
                } else {
                   throw "The variable '$($h.Name)' in the host URL has invalid value $($Variables[$h.Name]). Must be $($h.Value["EnumValues"] -join ",")"
                }
            } else {
                $Url = $Url.replace("{$($h.Name)}", $h.Value["DefaultValue"])
            }
        }

        return $Url;

    }
}

<#
.SYNOPSIS
Sets the configuration for http signing.
.DESCRIPTION
 
Sets the configuration for the HTTP signature security scheme.
The HTTP signature security scheme is used to sign HTTP requests with a key
which is in possession of the API client.
An 'Authorization' header is calculated by creating a hash of select headers,
and optionally the body of the HTTP request, then signing the hash value using
a key. The 'Authorization' header is added to outbound HTTP requests.
 
Ref: https://openapi-generator.tech
 
.PARAMETER KeyId
KeyId for HTTP signing
 
.PARAMETER KeyFilePath
KeyFilePath for HTTP signing
 
.PARAMETER KeyPassPhrase
KeyPassPhrase, if the HTTP signing key is protected
 
.PARAMETER HttpSigningHeader
HttpSigningHeader list of HTTP headers used to calculate the signature. The two special signature headers '(request-target)' and '(created)'
SHOULD be included.
    The '(created)' header expresses when the signature was created.
    The '(request-target)' header is a concatenation of the lowercased :method, an
    ASCII space, and the :path pseudo-headers.
If no headers are specified then '(created)' sets as default.
 
.PARAMETER HashAlgorithm
HashAlgorithm to calculate the hash, Supported values are "sha256" and "sha512"
 
.PARAMETER SigningAlgorithm
SigningAlgorithm specifies the signature algorithm, supported values are "RSASSA-PKCS1-v1_5" and "RSASSA-PSS"
RSA key : Supported values "RSASSA-PKCS1-v1_5" and "RSASSA-PSS", for ECDSA key this parameter is not applicable
 
.PARAMETER SignatureValidityPeriod
SignatureValidityPeriod specifies the signature maximum validity time in seconds. It accepts integer value
 
.OUTPUTS
 
System.Collections.Hashtable
#>

function Set-OktaConfigurationHttpSigning {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$KeyId,
        [Parameter(Mandatory = $true)]
        [string]$KeyFilePath,
        [Parameter(Mandatory = $false)]
        [securestring]$KeyPassPhrase,
        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string[]] $HttpSigningHeader = @("(created)"),
        [Parameter(Mandatory = $false)]
        [ValidateSet("sha256", "sha512")]
        [string] $HashAlgorithm = "sha256",
        [Parameter(Mandatory = $false)]
        [ValidateSet("RSASSA-PKCS1-v1_5", "RSASSA-PSS")]
        [string]$SigningAlgorithm ,
        [Parameter(Mandatory = $false)]
        [int]$SignatureValidityPeriod
    )

    Process {
        $httpSignatureConfiguration = @{ }

        if (Test-Path -Path $KeyFilePath) {
            $httpSignatureConfiguration["KeyId"] = $KeyId
            $httpSignatureConfiguration["KeyFilePath"] = $KeyFilePath
        }
        else {
            throw "Private key file path does not exist"
        }

        $keyType = Get-OktaKeyTypeFromFile -KeyFilePath $KeyFilePath
        if ([String]::IsNullOrEmpty($SigningAlgorithm)) {
            if ($keyType -eq "RSA") {
                $SigningAlgorithm = "RSASSA-PKCS1-v1_5"
            }
        }

        if ($keyType -eq "RSA" -and
            ($SigningAlgorithm -ne "RSASSA-PKCS1-v1_5" -and $SigningAlgorithm -ne "RSASSA-PSS" )) {
            throw "Provided Key and SigningAlgorithm : $SigningAlgorithm is not compatible."
        }

        if ($HttpSigningHeader -contains "(expires)" -and $SignatureValidityPeriod -le 0) {
            throw "SignatureValidityPeriod must be greater than 0 seconds."
        }

        if ($HttpSigningHeader -contains "(expires)") {
            $httpSignatureConfiguration["SignatureValidityPeriod"] = $SignatureValidityPeriod
        }
        if ($null -ne $HttpSigningHeader -and $HttpSigningHeader.Length -gt 0) {
            $httpSignatureConfiguration["HttpSigningHeader"] = $HttpSigningHeader
        }

        if ($null -ne $HashAlgorithm ) {
            $httpSignatureConfiguration["HashAlgorithm"] = $HashAlgorithm
        }

        if ($null -ne $SigningAlgorithm) {
            $httpSignatureConfiguration["SigningAlgorithm"] = $SigningAlgorithm
        }

        if ($null -ne $KeyPassPhrase) {
            $httpSignatureConfiguration["KeyPassPhrase"] = $KeyPassPhrase
        }

        $Script:Configuration["HttpSigning"] = New-Object -TypeName PSCustomObject -Property $httpSignatureConfiguration
    }
}

<#
.SYNOPSIS
 
Get the configuration object 'OktaConfigurationHttpSigning'.
 
.DESCRIPTION
 
Get the configuration object 'OktaConfigurationHttpSigning'.
 
.OUTPUTS
 
[PSCustomObject]
#>

function Get-OktaConfigurationHttpSigning{

    $httpSignatureConfiguration = $Script:Configuration["HttpSigning"]
    return $httpSignatureConfiguration
}

# SIG # Begin signature block
# MIIoFwYJKoZIhvcNAQcCoIIoCDCCKAQCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBUHlLfNS4AAJiQ
# vYeYy3JjNlmO6WnmOUEPgAmdMElvIKCCIRowggWNMIIEdaADAgECAhAOmxiO+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
# Vzu0nAPthkX0tGFuv2jiJmCG6sivqf6UHedjGzqGVnhOMIIGvDCCBKSgAwIBAgIQ
# C65mvFq6f5WHxvnpBOMzBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEX
# MBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0
# ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTI0MDkyNjAw
# MDAwMFoXDTM1MTEyNTIzNTk1OVowQjELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERp
# Z2lDZXJ0MSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyNDCCAiIwDQYJ
# KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL5qc5/2lSGrljC6W23mWaO16P2RHxjE
# iDtqmeOlwf0KMCBDEr4IxHRGd7+L660x5XltSVhhK64zi9CeC9B6lUdXM0s71EOc
# Re8+CEJp+3R2O8oo76EO7o5tLuslxdr9Qq82aKcpA9O//X6QE+AcaU/byaCagLD/
# GLoUb35SfWHh43rOH3bpLEx7pZ7avVnpUVmPvkxT8c2a2yC0WMp8hMu60tZR0Cha
# V76Nhnj37DEYTX9ReNZ8hIOYe4jl7/r419CvEYVIrH6sN00yx49boUuumF9i2T8U
# uKGn9966fR5X6kgXj3o5WHhHVO+NBikDO0mlUh902wS/Eeh8F/UFaRp1z5SnROHw
# SJ+QQRZ1fisD8UTVDSupWJNstVkiqLq+ISTdEjJKGjVfIcsgA4l9cbk8Smlzddh4
# EfvFrpVNnes4c16Jidj5XiPVdsn5n10jxmGpxoMc6iPkoaDhi6JjHd5ibfdp5uzI
# Xp4P0wXkgNs+CO/CacBqU0R4k+8h6gYldp4FCMgrXdKWfM4N0u25OEAuEa3Jyidx
# W48jwBqIJqImd93NRxvd1aepSeNeREXAu2xUDEW8aqzFQDYmr9ZONuc2MhTMizch
# NULpUEoA6Vva7b1XCB+1rxvbKmLqfY/M/SdV6mwWTyeVy5Z/JkvMFpnQy5wR14GJ
# cv6dQ4aEKOX5AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/
# BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEE
# AjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8w
# HQYDVR0OBBYEFJ9XLAN3DigVkGalY17uT5IfdqBbMFoGA1UdHwRTMFEwT6BNoEuG
# SWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQw
# OTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQG
# CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKG
# TGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJT
# QTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIB
# AD2tHh92mVvjOIQSR9lDkfYR25tOCB3RKE/P09x7gUsmXqt40ouRl3lj+8QioVYq
# 3igpwrPvBmZdrlWBb0HvqT00nFSXgmUrDKNSQqGTdpjHsPy+LaalTW0qVjvUBhcH
# zBMutB6HzeledbDCzFzUy34VarPnvIWrqVogK0qM8gJhh/+qDEAIdO/KkYesLyTV
# OoJ4eTq7gj9UFAL1UruJKlTnCVaM2UeUUW/8z3fvjxhN6hdT98Vr2FYlCS7Mbb4H
# v5swO+aAXxWUm3WpByXtgVQxiBlTVYzqfLDbe9PpBKDBfk+rabTFDZXoUke7zPgt
# d7/fvWTlCs30VAGEsshJmLbJ6ZbQ/xll/HjO9JbNVekBv2Tgem+mLptR7yIrpaid
# RJXrI+UzB6vAlk/8a1u7cIqV0yef4uaZFORNekUgQHTqddmsPCEIYQP7xGxZBIhd
# mm4bhYsVA6G2WgNFYagLDBzpmk9104WQzYuVNsxyoVLObhx3RugaEGru+SojW4dH
# PoWrUhftNpFC5H7QEY7MhKRyrBe7ucykW7eaCuWBsBb4HOKRFVDcrZgdwaSIqMDi
# CLg4D+TPVgKx2EgEdeoHNHT9l3ZDBD+XgbF+23/zBjeCtxz+dL/9NWR6P2eZRi7z
# cEO1xwcdcqJsyz/JceENc2Sg8h3KeFUCS7tpFk7CrDqkMIIHXzCCBUegAwIBAgIQ
# DqgNBeeiJHzhtzSGhFvtMzANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEX
# MBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0
# ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIy
# MDMxMDAwMDAwMFoXDTI1MDYwNjIzNTk1OVowZDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEzARBgNVBAoT
# Ck9rdGEsIEluYy4xEzARBgNVBAMTCk9rdGEsIEluYy4wggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQC4DJYrxv2fEdmd1f+rsCQdBo2hQ5R2qvbGJLLgqgMB
# cfKbM3mZafhtPhYM0qtPSvc6i5UNiLwwBYwzHcfi5ce1wj6YZsgV4G+ywRpITALn
# 05DOyoW1ZJyam8snJkf7FwhWgsyECJT2Y3tE2guCIpFW7gwHZMZuh3cKsHRDUSNw
# 67V9DZ0chP5IHlJsl48+6a8nPbil90tmaL7WhxwhZxEoJbbOvWZWkztjSxg8P1JA
# Ch6o4ORBPiNudXavKjWg/iBPWwHYstZQhvhIFBvkEf58FHDdZSkm1CEmyxBoA96p
# As0v5l7f+0BIuU/3EcXDwB4na0obm3q+/p2PzLUrhWONvoMxEMp1qRKkKsQtavqD
# 9AX4FTexQQlLPu/KkNklQfZaMOYrmQ3HOWMxLQW/YvuaT+Wp3Vhwmi0OL4WlmPZt
# /eeOW2NM9zK9rn+CycW48AcVwGwfKDmOcx5qe0dHwGllpy1pU049W+NeZMpAny5n
# s3RE/nggYYtxlWM23UUC+R1z2oOqnuwdl4JjeMwXBTK1shr22oD2eXk6ZH3sJSBO
# vf9c6arPm+vjkjbltJqaJ+eu3oAAUTXA5uD4QnezT5UMtMRmw8wZX5pPZ9SO+fkh
# oJKq/FGq9bPgnlf7H/XMSP0mehd56Hom8paB86TsinyTu/SC+xJrSnXas7fZXQG0
# bwIDAQABo4ICBjCCAgIwHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIw
# HQYDVR0OBBYEFBxHuEbYWCgQ74B6P4bgvcmuhSvtMA4GA1UdDwEB/wQEAwIHgDAT
# BgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8v
# Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JT
# QTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNl
# cnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0
# MjAyMUNBMS5jcmwwPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYb
# aHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGUBggrBgEFBQcBAQSBhzCBhDAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAC
# hlBodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRD
# b2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAMBgNVHRMBAf8EAjAA
# MA0GCSqGSIb3DQEBCwUAA4ICAQAnXIG8EflhKts6IYViBy/o4p5yEMQJosTJ1nxX
# 8EA/Vvf353BSFN14Vlm71TnQElbUdxMSjOmq8WXnPUeYID+Oac5tHrVXsCzeENuz
# K4YPhPLpSj9w57Fnnzh8LbojJetsCTdDnBgjcWWFq9nJ+c5IwZJLP1v6/XPEyRsD
# 2VOc7pS/FTeXrP9a5dcn7b0g5Tyd5DTt1xNx1YVreGoGb44JAPwHBH4l7nWwFIDI
# UP4llJFYsgkQytb76hVhXQoaGHrhodSMLJzekglGgrGLSN9eN/6KoncPIMuTUlAI
# mDv7N3lQFKk6X2Bp3GbpR8lPFHKTIoDcs65d/mRIZorR+tPJj7uMinJ7BlNNfDYe
# sfUL3YGgBeEh/HfVhm/OGO1VH+/nZNbkMNQq1O/YwSiAB8hdskV+X3zJszKC6D5T
# ctBefTGjObJZHeMg189EhBDscxa/x4AELVtuOVoBMfJfKIebTDW8xBWwzMdu+rOA
# G3S8/BC+i9Cxp3bikdP+goL7YLKAbZ3nFFrrQekwP2EpAOm1MCAioJ5a5pgh7yZF
# nyP2Ty3F8//sjxGINKuxnXmAz4fHSrEn6qkkdEJ6o00A/q15NCl8Bt2IMzuCE3NV
# r2M47b/vh0z6ShPHJQusFAJSKVlGqdTmF+ZampU6KS5KfVVtpYhp9D6txn7yJEHS
# i67F2TGCBlMwggZPAgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD
# ZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2ln
# bmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMQIQDqgNBeeiJHzhtzSGhFvtMzAN
# BglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqG
# SIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3
# AgEVMC8GCSqGSIb3DQEJBDEiBCBNtBTAyXDAwOWEDBzj/oPSVgUmrPtXJvChtk+x
# dph6FDANBgkqhkiG9w0BAQEFAASCAgCDE7OlxtotPeMzVZOU0ETi9cZukAXUaB06
# gIW9TPcn+98E6uwKk4FZuN6izVC3DhVb3Px1Gq8CE3J8OvxSrXZQ6HS5lzf7daTL
# bMX5uhW9xHTKQBXYuFgKlCIbMMFt6AsXrbz9P/0Ko4JKYBEVUJQ3GWMCHR/1JVQi
# jXknSEBXytd6iWwAI07hp0JcZqJ+Kb4wLK3uUG4gdl+bz3Uk2dsFhTN9hzxhdtiO
# on/b5zYGVAA29VlajdPhtb2JNq1Ghfq87qJj0FZjgqP+4vdz2DKRRwPRul2CbHM2
# ZeV7vS3Mv1qk7yf2N2o1Qge9nHJx+n7h8FbdxEFDuGeC932I5o5fCBEejj5PQyCP
# BnDdbD+DuzetlcNMC57nLIvHtIpyE2CMcntvQWOQKcpXjtWmPtwmkZeYXrPXvtUh
# SQD2LsddAu1WGWiKY7FwOIMxG96pr1cvG6z26cagezYczkZYyJT5PgMJA2BFr9Y3
# Sbt9mrch7tdEnrIy1QCiuDgOfQ5GpNZuYcr7Cyp7R8ReFwLYwSN23TLCK9isFT1f
# wGdLRXFTQBi+fphfMOb9VPxYGxjO7Fdouk935Nr2nSzTxM5h7d+TA27phzVSJFYa
# dhnAOVkrGJwNzaBNC0GXEOiOhKx0fdcHHtwabF4gg/R50eSNyCBZnmHTyDImydP1
# skRlPNPr8qGCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNV
# BAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNl
# cnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAuu
# Zrxaun+Vh8b56QTjMwQwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJ
# KoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yNDEwMzAyMDU5NTRaMC8GCSqGSIb3
# DQEJBDEiBCBHzYzBk2l/g1QR9C0i2AKS+Xo7aRkWYKYpQlDWHGizczANBgkqhkiG
# 9w0BAQEFAASCAgCH2OpSIOoyu7W672QDHLzqfAu3CgwIsdG5hkVA/t6nbY0W/xx1
# Tfzcplsp2RmMfJeJEccF+yMrLMsyNM48LIVcb2MIzay0fwsEpV03e1tzHT3+Fpck
# ul6SbYuJD5NfLQI8B8D4ayEKLDhAYW10FyfjcGmBvhdUvRTdA+ygx+rPFqr81jNI
# /tyy3jYkO6RlJUDSp77oE7Ay9X1GEUu+CmhhQBn9aw7wLPrtFSzOmXPl2qDXamne
# +pREI9kwkSfzthsgTTdjR2Bt+4Ia3vuul0FYBZPXMbkUY7ieSrWHanLcvoVUODWa
# foCZt9HlxamI6EWMHANQ4UK7HMmonFHQzoGRxSzFO9tbjUKYRcUfUvjEFEINmXZP
# BmMSBfGzZLDAVz0oEcCBm17EqvIaIIb+gNJq9b6ywhtKa6MGKft1Y0hM9s42FTfh
# PJgktskBF0vczszOxsNFoNuI0XP1DlSt9FkFNe4brlFteoRSIktED4i/dDrwaQpb
# sa1l8qZLETnNYgKd9dOAvfgedhM6foQPb4t4pnwEQum+KQqiMm7i97jphkCrVnjx
# 4vh4XaqYNJpPKmwIsC2ogm85c8SCIqWq4Ga/gUunsUiLn3ZSIczztTg7MyFN0qAT
# i2u2j54hi2QdblXaz/DCJ1qaKfcsWPoEQ+A37YvEB7GiIjBQB471R17s4g==
# SIG # End signature block