Upload-eSIMActivationCodesInBulk.ps1

<#PSScriptInfo
 
.VERSION 1.0
 
.GUID a37da805-ba72-498e-bc33-d97bd9044f0a
 
.AUTHOR kris.titeca@proximus.com
 
.COMPANYNAME Proximus
 
.COPYRIGHT
 
.TAGS eSIM Intune Bulk ActivationCodePool
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI https://www.proximus.be/favicon.ico
 
.EXTERNALMODULEDEPENDENCIES Microsoft.Graph
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
 
#>


<#
 .SYNOPSIS
    This script will import eSIM cellular activation codes into Intune using a csv input file.
.DESCRIPTION
    This script will import eSIM cellular activation codes into Intune using a csv input file.
    By default the script will split up the upload in chunks of maximum 1000 activation codes to overcome the Intune limit.
    The script will also create a log file in the %temp% folder named like the script with the extension .log
    Make sure Microsoft Graph PowerShell SDK is installed
.NOTES
     
.PARAMETER csvfile
    The full path towards a csv file containing the Activation codes. The csv file should be formatted as required for Intune.
    The first line should contain the SM-DP+ Server FQDN
    The remaining lines should contain esim number and the activation code, separated by a comma
    This parameter is mandatory
.PARAMETER subscriptionName
    The name you want the cellular subscription to be named.By default the cellular subscription will be named 'Proximus'.
    In case it's split up into chunks, the Name will be appended by an underscore and the number of the chunk (e.g.: Proximus_1, Proximus_2, ...)
    This parameter is optional
.PARAMETER ProxyServer
    If you need to specify a proxy server, this can be achieved by this parameter.
    This is for usage of a proxy server that doesn't require authentication
    This parameter is optional
.PARAMETER ChunkSize
    The default ChunkSize is 1000, which is based on the Intune limit. You can specify a lower ChunkSize if needed.
    Do note that setting a ChunkSize are greater than 1000 will probably result in an error.
    This parameter is optional
.PARAMETER WhatIf
    If you just want to run the script without doing any uploads, you can add the parameter WhatIf.
.LINK
     
.EXAMPLE
    eSIM_Bulk_Upload_ActivationCodes.ps1 -csvfile 'c:\temp\esim_codes.csv'
.EXAMPLE
    eSIM_Bulk_Upload_ActivationCodes.ps1 -csvfile 'c:\temp\esim_codes.csv' -WhatIf
.EXAMPLE
    eSIM_Bulk_Upload_ActivationCodes.ps1 -csvfile 'c:\temp\esim_codes.csv' -subscriptionName 'Contoso'
.EXAMPLE
    eSIM_Bulk_Upload_ActivationCodes.ps1 -csvfile 'c:\temp\esim_codes.csv' -ProxyServer 'http://proxyserver.contoso.com:8080'
.EXAMPLE
    eSIM_Bulk_Upload_ActivationCodes.ps1 -csvfile 'c:\temp\esim_codes.csv' -ChunkSize 200
#>



 Param(
[Parameter(Mandatory=$True)]
[string]$csvfile,
[Parameter(Mandatory=$False)]
[string]$subscriptionName = 'Proximus',
[Parameter(Mandatory=$False)]
[string]$ProxyServer,
[Parameter(Mandatory=$False)]
[int]$ChunkSize=1000,
[Parameter(Mandatory=$False)]
[switch]$WhatIf
)

$scriptName = $MyInvocation.MyCommand.Name
if ($scriptName)
{
    $LogFile = $env:temp + "\$scriptName.log"
}
else
{
    $LogFile = $env:temp + "\Upload-eSIMActivationCodesInBulk.log"
}

$LogMaxSize = 1024


function WriteLog {
    param(
    [Parameter(Mandatory)]
    [string]$LogText,
    [Parameter(Mandatory)]
    [ValidateNotNullOrEmpty()]
    [ValidateSet('Info','Warning','Error')]
    [string]$Type,
    [string]$LogFileName,
    [switch]$TrimLogFile
    )
   
    switch ($Type)
    {
        'Info' {write-host $LogText}
        'Warning' {write-host $LogText -ForegroundColor:Yellow}
        'Error' {write-host $LogText -ForegroundColor:red}
        Unknown {write-host $LogText}
    }

    
    $time = Get-Date -f "dd/MM/yyyy HH:mm:ss"
    if ($Type -eq 'Info')
    {
        $ParsedLog = "$time $LogText"
    }
    else
    {
        $ParsedLog = "$time $Type : $LogText"
    }

    if ($TrimLogFile)
    {
        $ParsedLog | Out-File -FilePath "$LogFileName"
    }
    else
    {
        $ParsedLog | Out-File -FilePath "$LogFileName" -Append
    }
    
}


if (Test-Path $LogFile)
{
    if ((Get-Item "$LogFile").length / 1KB -gt $LogMaxSize) 
    {
        writelog -LogText '**** START eSIM Bulk Upload Activation Codes ****' -Type Info -LogFileName $LogFile -TrimLogFile
    }
    else
    {
        writelog -LogText '**** START eSIM Bulk Upload Activation Codes ****' -Type Info -LogFileName $LogFile
    }
}
else
{
    writelog -LogText '**** START eSIM Bulk Upload Activation Codes ****' -Type Info -LogFileName $LogFile
}


writelog -LogText "Input csv file: $csvfile" -Type Info -LogFileName $LogFile

WriteLog -LogText "Subscription Name: $subscriptionName" -Type Info -LogFileName $LogFile

writelog -LogText "Proxy Server: $ProxyServer" -Type Info -LogFileName $LogFile

writelog -LogText "WhatIf: $WhatIf" -Type:Info -LogFileName $LogFile

writelog -LogText "Chunk Size: $ChunkSize" -Type:Info -LogFileName $LogFile


if (!(Test-Path $csvfile))
{
    writelog -LogText "file $csvfile not found" -Type:Error -LogFileName $LogFile
    break;
}

$MsGraph = Get-InstalledModule Microsoft.Graph -ErrorAction:SilentlyContinue

if ($MsGraph)
{
    writelog -LogText "Microsoft Graph PowerShell Module version $($MsGraph.Version) installed" -Type:Info -LogFileName $LogFile
}
else
{
    writelog -LogText "Microsoft Graph PowerShell SDK is not installed. Navigate to https://learn.microsoft.com/en-us/powershell/microsoftgraph/installation?view=graph-powershell-1.0 on how to install." -Type:Error -LogFileName $LogFile
    break;
}

$SMDPServer = ''
$arrayOfeSIMs = @()
writelog -LogText "csv file found" -Type Info -LogFileName $LogFile
$i = 0
foreach($line in Get-Content $csvfile) 
{
    $i++
    if ($i -eq 1)
    {
        $SMDPServer = $line.Trim()
        writelog -LogText "SM-DP+ Server: $SMDPServer" -Type Info -LogFileName $LogFile
    }
    else
    {
        
        $siminfo = $line.Split(",")
        writelog -LogText "Processing line $i, ICCD = $($siminfo.Item(0)) Activation Code: $($siminfo.Item(1))" -Type Info -LogFileName $LogFile
        $eSim = [ordered]@{
            IntegratedCircuitCardIdentifier = $siminfo.Item(0)
            MatchingIdentifier   = $siminfo.Item(1)
            SmdpPlusServerAddress  = 'thales1.prod.ondemandconnectivity.com'
        }

        $arrayOfeSIMs += $eSim

    }
      
}
writelog -LogText "Found $($arrayOfeSIMs.Count) eSIM activation codes" -Type Info -LogFileName $LogFile

if ($arrayOfeSIMs)
{
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    if ($ProxyServer)
    {
        writelog -LogText "Setting Proxy Server ($ProxyServer) for powershell to use" -Type Info -LogFileName $LogFile
        [system.net.webrequest]::DefaultWebProxy = new-object system.net.webproxy($ProxyServer)
        [system.net.webrequest]::DefaultWebProxy.BypassProxyOnLocal = $true  
    }
    
    import-module Microsoft.Graph.DeviceManagement
    import-Module Microsoft.Graph.Authentication

    Select-MgProfile -Name beta

    writelog -LogText "Connecting to Microsoft Graph" -Type Info -LogFileName $LogFile

    $Token = Connect-MgGraph -ContextScope Process -ForceRefresh -Scopes "DeviceManagementConfiguration.Read.All", "DeviceManagementConfiguration.ReadWrite.All"

    if ($Token)
    {
        writelog -LogText "Connected to Microsoft Graph" -Type Info -LogFileName $LogFile

        $chunkcount = 0
        writelog -LogText "Chunk Size: $ChunkSize , splitting up if needed" -Type Info -LogFileName $LogFile
        for ($i = 0; $i -lt $arrayOfeSIMs.Count; $i += $ChunkSize)
        {
            $temparray = $arrayOfeSIMs | select -Skip $i -First $ChunkSize
            $chunkcount += 1
            if ($arrayOfeSIMs.Count -gt $ChunkSize)
            {
                $NewsubscriptionName = $subscriptionName + "_" + $chunkcount
            }
            else
            {
                $NewsubscriptionName = $subscriptionName
            }
            writelog -LogText "Chunk #$chunkcount ,number of activationcodes: $($temparray.Count)" -Type Info -LogFileName $LogFile

            writelog -LogText "Create new eSIM ActivationCodePool with Display Name $NewsubscriptionName" -Type Info -LogFileName $LogFile
            $error.Clear()
            if (!$WhatIf)
            {
                $Result = New-MgDeviceManagementEmbeddedSimActivationCodePool -ActivationCodeCount $temparray.Count -DisplayName $NewsubscriptionName -ActivationCodes $temparray
                if ($error)
                {
                    writelog -LogText "Failed: $error" -Type Error -LogFileName $LogFile
                    $error.clear() 
                }
                if ($Result)
                {
                    writelog -LogText "Success: Cellular subscription id: $($result.Id), Name: $($Result.DisplayName) , Created: $($Result.CreatedDateTime)" -Type info -LogFileName $LogFile
                }
            }
            else
            {
                writelog -LogText "Not making any changes as WhatIf Parameter was specified" -Type Warning -LogFileName $LogFile
            }
        }

        Disconnect-MgGraph
    }
    
}


Write-Host "See Logfile for more information: $LogFile"
writelog -LogText '**** STOP eSIM Bulk Upload Activation Codes ****' -Type Info -LogFileName $LogFile


# SIG # Begin signature block
# MIIu2gYJKoZIhvcNAQcCoIIuyzCCLscCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCL/8DLY1OO/HJI
# Fga2KR79QLk/w9HJjOhR2KsoEc9w9KCCFGYwggWiMIIEiqADAgECAhB4AxhCRXCK
# Qc9vAbjutKlUMA0GCSqGSIb3DQEBDAUAMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24g
# Um9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9i
# YWxTaWduMB4XDTIwMDcyODAwMDAwMFoXDTI5MDMxODAwMDAwMFowUzELMAkGA1UE
# BhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExKTAnBgNVBAMTIEdsb2Jh
# bFNpZ24gQ29kZSBTaWduaW5nIFJvb3QgUjQ1MIICIjANBgkqhkiG9w0BAQEFAAOC
# Ag8AMIICCgKCAgEAti3FMN166KuQPQNysDpLmRZhsuX/pWcdNxzlfuyTg6qE9aND
# m5hFirhjV12bAIgEJen4aJJLgthLyUoD86h/ao+KYSe9oUTQ/fU/IsKjT5GNswWy
# KIKRXftZiAULlwbCmPgspzMk7lA6QczwoLB7HU3SqFg4lunf+RuRu4sQLNLHQx2i
# CXShgK975jMKDFlrjrz0q1qXe3+uVfuE8ID+hEzX4rq9xHWhb71hEHREspgH4nSr
# /2jcbCY+6R/l4ASHrTDTDI0DfFW4FnBcJHggJetnZ4iruk40mGtwEd44ytS+ocCc
# 4d8eAgHYO+FnQ4S2z/x0ty+Eo7+6CTc9Z2yxRVwZYatBg/WsHet3DUZHc86/vZWV
# 7Z0riBD++ljop1fhs8+oWukHJZsSxJ6Acj2T3IyU3ztE5iaA/NLDA/CMDNJF1i7n
# j5ie5gTuQm5nfkIWcWLnBPlgxmShtpyBIU4rxm1olIbGmXRzZzF6kfLUjHlufKa7
# fkZvTcWFEivPmiJECKiFN84HYVcGFxIkwMQxc6GYNVdHfhA6RdktpFGQmKmgBzfE
# ZRqqHGsWd/enl+w/GTCZbzH76kCy59LE+snQ8FB2dFn6jW0XMr746X4D9OeHdZrU
# SpEshQMTAitCgPKJajbPyEygzp74y42tFqfT3tWbGKfGkjrxgmPxLg4kZN8CAwEA
# AaOCAXcwggFzMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzAP
# BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQfAL9GgAr8eDm3pbRD2VZQu86WOzAf
# BgNVHSMEGDAWgBSP8Et/qC5FJK5NUPpjmove4t0bvDB6BggrBgEFBQcBAQRuMGww
# LQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMzA7
# BggrBgEFBQcwAoYvaHR0cDovL3NlY3VyZS5nbG9iYWxzaWduLmNvbS9jYWNlcnQv
# cm9vdC1yMy5jcnQwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9iYWxz
# aWduLmNvbS9yb290LXIzLmNybDBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEF
# BQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wDQYJ
# KoZIhvcNAQEMBQADggEBAKz3zBWLMHmoHQsoiBkJ1xx//oa9e1ozbg1nDnti2eEY
# XLC9E10dI645UHY3qkT9XwEjWYZWTMytvGQTFDCkIKjgP+icctx+89gMI7qoLao8
# 9uyfhzEHZfU5p1GCdeHyL5f20eFlloNk/qEdUfu1JJv10ndpvIUsXPpYd9Gup7EL
# 4tZ3u6m0NEqpbz308w2VXeb5ekWwJRcxLtv3D2jmgx+p9+XUnZiM02FLL8Mofnre
# kw60faAKbZLEtGY/fadY7qz37MMIAas4/AocqcWXsojICQIZ9lyaGvFNbDDUswar
# AGBIDXirzxetkpNiIHd1bL3IMrTcTevZ38GQlim9wX8wggboMIIE0KADAgECAhB3
# vQ4Ft1kLth1HYVMeP3XtMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAkJFMRkw
# FwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENv
# ZGUgU2lnbmluZyBSb290IFI0NTAeFw0yMDA3MjgwMDAwMDBaFw0zMDA3MjgwMDAw
# MDBaMFwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTIw
# MAYDVQQDEylHbG9iYWxTaWduIEdDQyBSNDUgRVYgQ29kZVNpZ25pbmcgQ0EgMjAy
# MDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMsg75ceuQEyQ6BbqYoj
# /SBerjgSi8os1P9B2BpV1BlTt/2jF+d6OVzA984Ro/ml7QH6tbqT76+T3PjisxlM
# g7BKRFAEeIQQaqTWlpCOgfh8qy+1o1cz0lh7lA5tD6WRJiqzg09ysYp7ZJLQ8LRV
# X5YLEeWatSyyEc8lG31RK5gfSaNf+BOeNbgDAtqkEy+FSu/EL3AOwdTMMxLsvUCV
# 0xHK5s2zBZzIU+tS13hMUQGSgt4T8weOdLqEgJ/SpBUO6K/r94n233Hw0b6nskEz
# IHXMsdXtHQcZxOsmd/KrbReTSam35sOQnMa47MzJe5pexcUkk2NvfhCLYc+YVaMk
# oog28vmfvpMusgafJsAMAVYS4bKKnw4e3JiLLs/a4ok0ph8moKiueG3soYgVPMLq
# 7rfYrWGlr3A2onmO3A1zwPHkLKuU7FgGOTZI1jta6CLOdA6vLPEV2tG0leis1Ult
# 5a/dm2tjIF2OfjuyQ9hiOpTlzbSYszcZJBJyc6sEsAnchebUIgTvQCodLm3HadNu
# twFsDeCXpxbmJouI9wNEhl9iZ0y1pzeoVdwDNoxuz202JvEOj7A9ccDhMqeC5LYy
# AjIwfLWTyCH9PIjmaWP47nXJi8Kr77o6/elev7YR8b7wPcoyPm593g9+m5XEEofn
# GrhO7izB36Fl6CSDySrC/blTAgMBAAGjggGtMIIBqTAOBgNVHQ8BAf8EBAMCAYYw
# EwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E
# FgQUJZ3Q/FkJhmPF7POxEztXHAOSNhEwHwYDVR0jBBgwFoAUHwC/RoAK/Hg5t6W0
# Q9lWULvOljswgZMGCCsGAQUFBwEBBIGGMIGDMDkGCCsGAQUFBzABhi1odHRwOi8v
# b2NzcC5nbG9iYWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUwRgYIKwYBBQUH
# MAKGOmh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2NvZGVzaWdu
# aW5ncm9vdHI0NS5jcnQwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL2NybC5nbG9i
# YWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUuY3JsMFUGA1UdIAROMEwwQQYJ
# KwYBBAGgMgECMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24u
# Y29tL3JlcG9zaXRvcnkvMAcGBWeBDAEDMA0GCSqGSIb3DQEBCwUAA4ICAQAldaAJ
# yTm6t6E5iS8Yn6vW6x1L6JR8DQdomxyd73G2F2prAk+zP4ZFh8xlm0zjWAYCImbV
# YQLFY4/UovG2XiULd5bpzXFAM4gp7O7zom28TbU+BkvJczPKCBQtPUzosLp1pnQt
# pFg6bBNJ+KUVChSWhbFqaDQlQq+WVvQQ+iR98StywRbha+vmqZjHPlr00Bid/XSX
# hndGKj0jfShziq7vKxuav2xTpxSePIdxwF6OyPvTKpIz6ldNXgdeysEYrIEtGiH6
# bs+XYXvfcXo6ymP31TBENzL+u0OF3Lr8psozGSt3bdvLBfB+X3Uuora/Nao2Y8nO
# ZNm9/Lws80lWAMgSK8YnuzevV+/Ezx4pxPTiLc4qYc9X7fUKQOL1GNYe6ZAvytOH
# X5OKSBoRHeU3hZ8uZmKaXoFOlaxVV0PcU4slfjxhD4oLuvU/pteO9wRWXiG7n9dq
# cYC/lt5yA9jYIivzJxZPOOhRQAyuku++PX33gMZMNleElaeEFUgwDlInCI2Oor0i
# xxnJpsoOqHo222q6YV8RJJWk4o5o7hmpSZle0LQ0vdb5QMcQlzFSOTUpEYck08T7
# qWPLd0jV+mL8JOAEek7Q5G7ezp44UCb0IXFl1wkl1MkHAHq4x/N36MXU4lXQ0x72
# f1LiSY25EXIMiEQmM2YBRN/kMw4h3mKJSAfa9TCCB9AwggW4oAMCAQICDD829Qfj
# mzJ8C5K35zANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQ
# R2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFsU2lnbiBHQ0MgUjQ1IEVW
# IENvZGVTaWduaW5nIENBIDIwMjAwHhcNMjMwMzI5MTYxOTAyWhcNMjQwMzI5MTYx
# OTAyWjCCAQ8xHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRUwEwYDVQQF
# EwwwMjAyLjIzOS45NTExEzARBgsrBgEEAYI3PAIBAxMCQkUxCzAJBgNVBAYTAkJF
# MScwJQYDVQQIEx5CcnVzc2VscyBIb29mZHN0ZWRlbGlqayBHZXdlc3QxEzARBgNV
# BAcTClNjaGFhcmJlZWsxIDAeBgNVBAkTF0tvbmluZyBBbGJlcnRJSSBsYWFuIDI3
# MRUwEwYDVQQKEwxQcm94aW11cyBQTEMxFTATBgNVBAMTDFByb3hpbXVzIFBMQzEn
# MCUGCSqGSIb3DQEJARYYa3Jpcy50aXRlY2FAcHJveGltdXMuY29tMIICIjANBgkq
# hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtcCmuHWB2Kpi0po5+F06iiRkDx+xTj25
# ObDH1wNo5UH8r2kCpk2Gbaxa95w4hAk2fEwUFgAEXhqOkUcEUrYgg5dD+FHnf+x8
# hEzaqQ5ehSm56IMR/++idvOUiINl+Dbofav5imS1cekc9YxBzKRuhUjokB49Ufm3
# SRPg38t3npmQ1sQlnxiSptf91g2yke5+nF8Gbt3zZ/kcRjlDylTuzvvWCrXopysx
# xcuRqv05GpBj5MLfv7EpeZ24x+RZ60iQNtXMTk52fjNe79y4uoCpwTysogTA9Yex
# bqtNmaqmBkXxKCLD43VTlSCitdsqz0gOcPmqmQMvYbvKPaWbCXX85HWuadTiktEg
# eAg+xzHi6951U9C6ip1D9MhnFbqH/jjhnShCF5xEXXxKVK5SaFpyLwjnRjHkWxB/
# MoAphU2o5KW2SXQfM5sjYEWhlLgHyR9TfD1zvOnu9oitsJsXvPVkiSNSum1gE2lH
# na5yDUKPrnqloxxor8CIjJdMf9ke4KK5VSJm5kMFdzW3LepPUfDZpGOwto6XZPrD
# Dmx6WqlRDv0LfZUCup0Fas5MmGO36dvg/2XofWk3imaUix5eIjpAJg7egMuFdt5w
# CgCzR9C8WDsHKe1IxMi6FUojtDrmNLaAmDLAedqEFmCxEgzJUI7L/NuodnAP+dD4
# wAdG7RPdKKUCAwEAAaOCAdswggHXMA4GA1UdDwEB/wQEAwIHgDCBnwYIKwYBBQUH
# AQEEgZIwgY8wTAYIKwYBBQUHMAKGQGh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5j
# b20vY2FjZXJ0L2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNhMjAyMC5jcnQwPwYIKwYBBQUH
# MAGGM2h0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjQ1ZXZjb2Rlc2ln
# bmNhMjAyMDBVBgNVHSAETjBMMEEGCSsGAQQBoDIBAjA0MDIGCCsGAQUFBwIBFiZo
# dHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBAzAJ
# BgNVHRMEAjAAMEcGA1UdHwRAMD4wPKA6oDiGNmh0dHA6Ly9jcmwuZ2xvYmFsc2ln
# bi5jb20vZ3NnY2NyNDVldmNvZGVzaWduY2EyMDIwLmNybDAjBgNVHREEHDAagRhr
# cmlzLnRpdGVjYUBwcm94aW11cy5jb20wEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYD
# VR0jBBgwFoAUJZ3Q/FkJhmPF7POxEztXHAOSNhEwHQYDVR0OBBYEFHWv+SOXjfx4
# 2/m1mR/QC+EQvlWZMA0GCSqGSIb3DQEBCwUAA4ICAQCHGEE8urtXJsM2WYEk0l03
# /IV14m+BgRs9ydOzycFzfu/OLSXV4haIuzDN3XQMJUbf+mx/38Y5OiqW/50pQ1GD
# CXXual41UKc4KGUytpZzGA32K+1fAiRZvQq8zc4GZshfq5IUSWhi9Hlq7RRRsGfu
# YbOJfsTnH2OM+QE/c4HSI2/2KqEd3peNsb6X4xHQKxtRVy43Sh4AMHU4FFU+R6b7
# OYH+Tv4jHfpdcby11aQqRzjO0NIJ5Y3nTuWPrYoZiauByBMR7SGllhbci5F0GkSR
# qll7ucLnITifjjwQEM59Hq4tvnMvPKheQ9J87GrP0z4v/h7QtZpF8O/M1LXGucif
# i6kwWuyawUu1XD2CNFlVy81/elUZfrg7Zq5sG+EV24WI4EiHfczUbyWBr0JvEJKf
# qXAiVLIP6yZubISwuT5pmPOlrMYn5GSBiIuQEJnqwSRimcQVPo/Mozrt+QcDpKVX
# /VIwAvrKoKlrulbD3n8+bw5b/xnhvT8y96aEC3NIreJeobCVP80Q/hP91Lyo6LOl
# e5CksUS01ElwOmYQjqeM0R0FpfL7epWL50DkQ86ftXNuuSIxMkE3MCiJ5RFsEKZQ
# 4fSj4Sn3kx7jdtu/MAL3lQZhn2Jl7DFEy1DRdMqPcYGctRsPAXq0G66MW7xDF0Yh
# ca345ek2bVfFFfmhinsCSTGCGcowghnGAgEBMGwwXDELMAkGA1UEBhMCQkUxGTAX
# BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExMjAwBgNVBAMTKUdsb2JhbFNpZ24gR0ND
# IFI0NSBFViBDb2RlU2lnbmluZyBDQSAyMDIwAgw/NvUH45syfAuSt+cwDQYJYIZI
# AWUDBAIBBQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYKKwYB
# BAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0B
# CQQxIgQgkxtJ1q4FRqBM64haBe9IiiDlGkvSD9cB7sLL77KfacYwDQYJKoZIhvcN
# AQEBBQAEggIAHr2AYFIgc/OfQlpneqRR9WqU2i+r2EAwcYs5u3EUqxRjbaIC6zPG
# ZgcItEi27L5zrerd4G20E++9i+DrQkYdfxwjAttAb+7yroBu7KhAjNHFyklnQFVk
# hyahqoeK703nEhJaQELd00FYBu5q9kb33ZRsbikB+E+KzIt7zdpXdfyh4/2I+BFT
# ZKxs7E9N2izsW+x+i5SoGZ+lChjKGnmj/ajOY6iqUhqbLgqm2oLvn0kfcjKrJlZE
# xdJ3wUO5NPzzeRAO67ei4+IVOVYmRUmHyxg1fburxJt3iddoAS7nZHORB9J5MLxy
# LykgZ99TSOsP1V3bA/+XcICCX6ikkL9/LpGo1LrgvWMuxmFD1m69AzPB02X4iLbu
# XpjDTwKVOhd27UTbDTIQxactK18efVB1bJt0Vqs5GLOp6b22TOCracI7CSX+FEBh
# SooFa/ljH8HkGSGN7UAvkycv2tyCZbairiqQC8lm7vV6kdfkDEPGFXBC1/CCat7Q
# z0bx0sVEGmpVbK4WHA6GG8QS+ElnujXJDn7QQUdaTymGah9X9uMbVR3e+NWnpcPq
# OmkkRcb/mcrrH5PO35+AoLNcN9ew7y5hMq0QoL4sY10zhIWbNGd3/4WUZARgMBNV
# 8eNDiDwq8HIyZmGmH87Va1p51rTW9KUow5HP4f43My7SrQY1uzKmee+hghaxMIIW
# rQYKKwYBBAGCNwMDATGCFp0wghaZBgkqhkiG9w0BBwKgghaKMIIWhgIBAzENMAsG
# CWCGSAFlAwQCATCB3wYLKoZIhvcNAQkQAQSggc8EgcwwgckCAQEGCysGAQQBoDIC
# AwECMDEwDQYJYIZIAWUDBAIBBQAEIJqAwx4g1oKpQWrQZ9VTHWS3sxpkAg56RIwS
# PjH7StulAhR4hRr6/O3epFeOQbhyg8y7uJE4aBgPMjAyMzA2MjEwNjU4NTlaMAMC
# AQGgWKRWMFQxCzAJBgNVBAYTAkJFMRkwFwYDVQQKDBBHbG9iYWxTaWduIG52LXNh
# MSowKAYDVQQDDCFHbG9iYWxzaWduIFRTQSBmb3IgQ29kZVNpZ24xIC0gUjagghJB
# MIIGWTCCBEGgAwIBAgIQAbKL1M/u7g2+0LMNm/hDajANBgkqhkiG9w0BAQsFADBb
# MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTExMC8GA1UE
# AxMoR2xvYmFsU2lnbiBUaW1lc3RhbXBpbmcgQ0EgLSBTSEEzODQgLSBHNDAeFw0y
# MjA0MDYwNzQ1MzhaFw0zMzA1MDgwNzQ1MzhaMFQxCzAJBgNVBAYTAkJFMRkwFwYD
# VQQKDBBHbG9iYWxTaWduIG52LXNhMSowKAYDVQQDDCFHbG9iYWxzaWduIFRTQSBm
# b3IgQ29kZVNpZ24xIC0gUjYwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB
# gQCwrUjgWeVpERIzjrRfuweFQuDJSaVk8AaY/czwyPqKnBl9ZqozINe6fmmjX+J/
# SpRRz8XL16o3pIEBCvrXkOoZdh1a3NYiQrypP94PG0ireGZasaH0QI/HpKFfocL8
# 4nyPe1elgXqQK4vrpCjcPi1yZSswtGg85AqYnSsdtnFRm4C3oHqg3YlOXZoWKRMY
# fS6Ha0v69GSUQus9lMKrBJtl2ExxzzYj+C6ZINlfd6XqjRfFTyCXbDMkSJwzjEyd
# CI7lKLbCWiiModW+CpNhYpbhdXH6kBwJXWCtHQjy6MKywwAikvvc0LkZQUK9isu9
# bMbtKGpKjzS0aZobWodeODi8Uiw6Dry6EE/SALMcutKBFT6vr1yw5dhfoGp+jPyD
# Q7l3YYpHcz+jMtE6qydVm/IbUV2E4yTSVjie3EpvmV9RITLEvVjw8SFoGe8YNTI/
# jHQNLWzyIvm4IQGfmrApN/Q6Sdroaled2QKh8By5XbYZ/QGVekOHC/3FS+NqtgXn
# hfMCAwEAAaOCAZ4wggGaMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggr
# BgEFBQcDCDAdBgNVHQ4EFgQU7vCDytaxCcuwDiYdxp4bnvVlffkwTAYDVR0gBEUw
# QzBBBgkrBgEEAaAyAR4wNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFs
# c2lnbi5jb20vcmVwb3NpdG9yeS8wDAYDVR0TAQH/BAIwADCBkAYIKwYBBQUHAQEE
# gYMwgYAwOQYIKwYBBQUHMAGGLWh0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2Nh
# L2dzdHNhY2FzaGEzODRnNDBDBggrBgEFBQcwAoY3aHR0cDovL3NlY3VyZS5nbG9i
# YWxzaWduLmNvbS9jYWNlcnQvZ3N0c2FjYXNoYTM4NGc0LmNydDAfBgNVHSMEGDAW
# gBTqFsZp5+PLV0U5M6TwQL7Qw71lljBBBgNVHR8EOjA4MDagNKAyhjBodHRwOi8v
# Y3JsLmdsb2JhbHNpZ24uY29tL2NhL2dzdHNhY2FzaGEzODRnNC5jcmwwDQYJKoZI
# hvcNAQELBQADggIBADv0XDv/NST+Pqqy5xrHgGxKVri5ZHV23M6Lb8AebLytGYsn
# bGpuDbCxL1Od2Vfh8VlnwiLVwZGOSSxFMBh5TmoIjtAZWF2CaPu8JrmMTOU3zbbG
# FjrCKfXnzLJKgIJAIR32hMZusL7fCtzYwLvoJnKXt8fNUEppA6+N77eKDf13HLa+
# pq/aF5wOsZOcBR5Fc7PO6LOz/sWXsMly7O7LCbDLH72v3Zc4pi7xNZk+9GOqE54Z
# rzA/Uqd8bf/3DPA1CS8RsX3Rg4g8YmbYuW/ISZi4b8JsEqhYudmJiLwSs+/P8rJp
# GVCTeB/PAk4A1lirKX4JNN947AbErcIMkOCWROgQ6GIkYXD7VU4w2zj9QQAYpWgH
# g3d69zCPs7veHPEs3NeVj+IgJ3YvaR8pfhxnFr0BZXBAMbeO+xSM00/y3SsCGXrY
# vF+Mebrn7Ooaa2x0+NJkAsTmKfiYOdmt5dQyToOuLQSQg2r5P3zrqQAXldkqsmDA
# EjNCI5Hpsmsec2dDowkTL3hqs7ONCTvTO4jMlEtjQLJzExDqbDRePtuRWFdUW5YT
# ypnfhGZQTagMymJq0YvDke/qDd2V9OoqMJKKZKxK31ecT8RTvfQmBr+HNCStcapM
# orW7Yb5Je+nyDgxuCYIZMUIElUFeTgiZEHHEH85ahHJI27L7EngiF0fWQjVKMIIG
# WTCCBEGgAwIBAgINAewckkDe/S5AXXxHdDANBgkqhkiG9w0BAQwFADBMMSAwHgYD
# VQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2ln
# bjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xODA2MjAwMDAwMDBaFw0zNDEyMTAw
# MDAwMDBaMFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNh
# MTEwLwYDVQQDEyhHbG9iYWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIFNIQTM4NCAt
# IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA8ALiMCP64BvhmnSz
# r3WDX6lHUsdhOmN8OSN5bXT8MeR0EhmW+s4nYluuB4on7lejxDXtszTHrMMM64Bm
# bdEoSsEsu7lw8nKujPeZWl12rr9EqHxBJI6PusVP/zZBq6ct/XhOQ4j+kxkX2e4x
# z7yKO25qxIjw7pf23PMYoEuZHA6HpybhiMmg5ZninvScTD9dW+y279Jlz0ULVD2x
# VFMHi5luuFSZiqgxkjvyen38DljfgWrhsGweZYIq1CHHlP5CljvxC7F/f0aYDoc9
# emXr0VapLr37WD21hfpTmU1bdO1yS6INgjcZDNCr6lrB7w/Vmbk/9E818ZwP0zcT
# UtklNO2W7/hn6gi+j0l6/5Cx1PcpFdf5DV3Wh0MedMRwKLSAe70qm7uE4Q6sbw25
# tfZtVv6KHQk+JA5nJsf8sg2glLCylMx75mf+pliy1NhBEsFV/W6RxbuxTAhLntRC
# Bm8bGNU26mSuzv31BebiZtAOBSGssREGIxnk+wU0ROoIrp1JZxGLguWtWoanZv0z
# AwHemSX5cW7pnF0CTGA8zwKPAf1y7pLxpxLeQhJN7Kkm5XcCrA5XDAnRYZ4miPzI
# sk3bZPBFn7rBP1Sj2HYClWxqjcoiXPYMBOMp+kuwHNM3dITZHWarNHOPHn18XpbW
# PRmwl+qMUJFtr1eGfhA3HWsaFN8CAwEAAaOCASkwggElMA4GA1UdDwEB/wQEAwIB
# hjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTqFsZp5+PLV0U5M6TwQL7Q
# w71lljAfBgNVHSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDA+BggrBgEFBQcB
# AQQyMDAwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwMi5nbG9iYWxzaWduLmNvbS9y
# b290cjYwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9iYWxzaWduLmNv
# bS9yb290LXI2LmNybDBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYm
# aHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wDQYJKoZIhvcN
# AQEMBQADggIBAH/iiNlXZytCX4GnCQu6xLsoGFbWTL/bGwdwxvsLCa0AOmAzHznG
# FmsZQEklCB7km/fWpA2PHpbyhqIX3kG/T+G8q83uwCOMxoX+SxUk+RhE7B/CpKzQ
# ss/swlZlHb1/9t6CyLefYdO1RkiYlwJnehaVSttixtCzAsw0SEVV3ezpSp9eFO1y
# EHF2cNIPlvPqN1eUkRiv3I2ZOBlYwqmhfqJuFSbqtPl/KufnSGRpL9KaoXL29yRL
# dFp9coY1swJXH4uc/LusTN763lNMg/0SsbZJVU91naxvSsguarnKiMMSME6yCHOf
# XqHWmc7pfUuWLMwWaxjN5Fk3hgks4kXWss1ugnWl2o0et1sviC49ffHykTAFnM57
# fKDFrK9RBvARxx0wxVFWYOh8lT0i49UKJFMnl4D6SIknLHniPOWbHuOqhIKJPsBK
# 9SH+YhDtHTD89szqSCd8i3VCf2vL86VrlR8EWDQKie2CUOTRe6jJ5r5IqitV2Y23
# JSAOG1Gg1GOqg+pscmFKyfpDxMZXxZ22PLCLsLkcMe+97xTYFEBsIB3CLegLxo1t
# jLZx7VIh/j72n585Gq6s0i96ILH0rKod4i0UnfqWah3GPMrz2Ry/U02kR1l8lcRD
# Qfkl4iwQfoH5DZSnffK1CfXYYHJAUJUg1ENEvvqglecgWbZ4xqRqqiKbMIIFgzCC
# A2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UE
# CxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24x
# EzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAw
# MDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UE
# ChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJKoZIhvcN
# AQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRIxutbPK6D
# uEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE
# 3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrF
# smbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7
# bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106
# yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNXk7besvji
# hbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2SXcwvHE3
# 5absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguyCLNh
# ZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq
# +aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXlu
# DocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8
# KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G
# A1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSubAWjkxPi
# oufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLNnsAEoJFp
# 5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFy
# RJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxD
# KZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0C
# uiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5C
# Ru3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpzoHdpx7Zc
# f4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZpnOZ7BN9u
# Bmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T
# uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgD
# u+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+L
# LUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo
# 8YLoRT5s1gLXCmeDBVrJpBAxggNJMIIDRQIBATBvMFsxCzAJBgNVBAYTAkJFMRkw
# FwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWduIFRp
# bWVzdGFtcGluZyBDQSAtIFNIQTM4NCAtIEc0AhABsovUz+7uDb7Qsw2b+ENqMAsG
# CWCGSAFlAwQCAaCCAS0wGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMCsGCSqG
# SIb3DQEJNDEeMBwwCwYJYIZIAWUDBAIBoQ0GCSqGSIb3DQEBCwUAMC8GCSqGSIb3
# DQEJBDEiBCDArJYBEnPWV3DneoS+qNuymVZPeGC/yIr6NT8/brlYkTCBsAYLKoZI
# hvcNAQkQAi8xgaAwgZ0wgZowgZcEIP8gGaCkc+jpkodlu9RmAcZYWY2qExgIaTYD
# mnzwIcqZMHMwX6RdMFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWdu
# IG52LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIFNI
# QTM4NCAtIEc0AhABsovUz+7uDb7Qsw2b+ENqMA0GCSqGSIb3DQEBCwUABIIBgBVb
# e3VALPAgf7mJcsbiLyma3JrXhqz0YfQ1IfsGbCICPeBMmgD+7mq6T9yHqV4qD4cX
# zBYZpGA+7nOSlULScM4aVBGKUHC1VNj+tI9zNepPpV36/zL+kKQYd6BO/yvqKUiH
# fh5Y6LaIkL16P7ynSpB++dB+E5hMjbofjTDSwycSdXOGB8hg5pZcVgRNVwRGL0DW
# Zulx/OSXpRNfND/g8D6D6ixpPak/0DnUdsPjWZh5zYa+qzzqGyyACLNZjklXPeCB
# SM+jqE1Hih6AzI8aZo/UixK2UR/YnGarKSDNelIimnyUKZtyVbgVUFP/9sHAB1k0
# zm/8lp5F3fEqwhtU1VhgTiJGjFVWP1jcmoiXssxwd2/x16dwbA60eXdw81VqXzUN
# fPUUNTe10n1fp9x7bRnX5Kq22GZXvyNM8hUmcpzWNqw2VIqKe8j6QdTNwBAj/qgZ
# pKLZ0JH7iVwmk6QBm10qtmZgyjieVpnFMm0pAoKd5fbox4QXeHZcvCHRKxVb/g==
# SIG # End signature block