AMPowerShellTemplate.psm1

<#
.Synopsis
   This function creates a new PowerShell Module, PowerShell Manifest file and default Pester tests including default PSScriptAnalyser tests for all files.
.DESCRIPTION
   Long description
.EXAMPLE
   New-AMPowerShellModule -Name MyModule -Path C:\MyPath\ -Author 'Flemming Rohde' -CompanyName Automize -Copyright 2018 -ModuleVersion 1.0.0.0 -Description testing -Verbose
.EXAMPLE
   Another example of how to use this cmdlet
.INPUTS
   Inputs to this cmdlet (if any)
.OUTPUTS
   Output from this cmdlet (if any)
.NOTES
   General notes
.COMPONENT
   The component this cmdlet belongs to
.ROLE
   The role this cmdlet belongs to
.FUNCTIONALITY
   The functionality that best describes this cmdlet
#>

Function New-AMPowerShellModule {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Name,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Path,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Author,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$CompanyName,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Copyright,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$ModuleVersion,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Description
    )

    Begin {
    }
    Process {
        if ($pscmdlet.ShouldProcess("PowerShell Module name: $Name", "New")) {

            $ModuleFolderPath = New-Item -Path $Path -Name $Name -ItemType Directory -Verbose

            New-Item -Path $ModuleFolderPath -Name 'Tests' -ItemType Directory -Verbose

            Out-File -FilePath "$ModuleFolderPath\Temp.psm1" -Encoding utf8 -Verbose

            $TemplateContent = @'
 
    Function New-Function
    {
    <#
    .Synopsis
    Short description
    .DESCRIPTION
    Long description
    .EXAMPLE
    Example of how to use this cmdlet
    .EXAMPLE
    Another example of how to use this cmdlet
    .INPUTS
    Inputs to this cmdlet (if any)
    .OUTPUTS
    Output from this cmdlet (if any)
    .NOTES
    General notes
    .COMPONENT
    The component this cmdlet belongs to
    .ROLE
    The role this cmdlet belongs to
    .FUNCTIONALITY
    The functionality that best describes this cmdlet
    #>
        [CmdletBinding(SupportsShouldProcess=$true)]
 
                param (
                    #Not mandatory parameter example
                    [Parameter(
                        Mandatory = $false,
                        ValueFromPipeline = $true,
                        ValueFromPipelineByPropertyName = $true)]
                    [AllowNull()]
                    [String]$param1,
 
                    #Mandatory parameter example
                    [Parameter(
                        Mandatory = $true,
                        ValueFromPipeline = $true,
                        ValueFromPipelineByPropertyName = $true)]
                    [ValidateNotNullOrEmpty()]
                    [String]$Param2
                )
 
                    Begin {
                    }
                    Process {
 
                        try {
                            if ($pscmdlet.ShouldProcess("Target", "Operation")) {
 
                            }
                        }
                        catch {
 
                            throw
                        }
                    }
                    End {
                    }
    }
'@


            $TemplateContent | Set-Content -Path "$ModuleFolderPath\Temp.psm1" -Encoding UTF8

            Get-Content -Path "$ModuleFolderPath\Temp.psm1" | ForEach-Object {$PSItem.TrimEnd()} | Set-Content "$ModuleFolderPath\$Name.psm1" -Encoding UTF8
            Remove-Item -Path "$ModuleFolderPath\Temp.psm1" -Force

            $ModulePath = (Get-Module -Name AMPowerShellTemplate).path

            $CurrentLocation = Get-Location

            Push-Location -Path $ModulePath.Substring(0, $ModulePath.LastIndexOf("\"))

            $Parameters = Get-Content -Path .\DefaultTests.json | ConvertFrom-Json

            $newTestScriptFileInfoSplat = @{
                Copyright   = $Copyright
                Description = $Description
                Version     = $ModuleVersion
                CompanyName = $CompanyName
                Guid        = [Guid]::NewGuid().Guid
                Author      = $Author
                Path        = "$ModuleFolderPath\Tests\Temp.tests.ps1"
            }

            New-ScriptFileInfo @newTestScriptFileInfoSplat

            (Get-Content -Path "$ModuleFolderPath\Tests\Temp.tests.ps1").Replace("Param()",$Parameters.DefaultTests.Module.Content) | Set-Content "$ModuleFolderPath\Tests\Temp.tests.ps1" -Encoding UTF8
            Get-Content -Path "$ModuleFolderPath\Tests\Temp.tests.ps1" | ForEach-Object {$PSItem.TrimEnd()} | Set-Content "$ModuleFolderPath\Tests\$Name.tests.ps1" -Encoding UTF8
            Remove-Item -Path "$ModuleFolderPath\Tests\temp.tests.ps1" -Force

            $ModuleManifestParams = @{
                RootModule        = "$Name.psm1"
                Path              = "$ModuleFolderPath\$Name.psd1"
                GUID              = [System.Guid]::NewGuid()
                Author            = $Author
                CompanyName       = $CompanyName
                Copyright         = $Copyright
                ModuleVersion     = $ModuleVersion
                Description       = $Description
                FunctionsToExport = @()
                CmdletsToExport   = @()
                AliasesToExport   = @()
                Verbose           = $true
            }

            New-ModuleManifest @ModuleManifestParams

            Push-Location $ModuleFolderPath
            Invoke-Pester ".\Tests\$Name.tests.ps1"
            Set-Location $CurrentLocation

        }
    }
    End {
    }
}

<#
.Synopsis
   This function creates a new PowerShell Script and default Pester tests including default PSScriptAnalyser tests for all files.
.DESCRIPTION
   Long description
.EXAMPLE
  New-AMPowerShellScript -Name MyScript -Path C:\MyPath -Verbose
.EXAMPLE
   Another example of how to use this cmdlet
.INPUTS
   Inputs to this cmdlet (if any)
.OUTPUTS
   Output from this cmdlet (if any)
.NOTES
   General notes
.COMPONENT
   The component this cmdlet belongs to
.ROLE
   The role this cmdlet belongs to
.FUNCTIONALITY
   The functionality that best describes this cmdlet
#>

Function New-AMPowerShellScript {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Name,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Path,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Author,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$CompanyName,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Copyright,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$ScriptVersion,
        [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Description
    )

    Begin {
    }
    Process {
        if ($pscmdlet.ShouldProcess("PowerShell Script name: $Name", "New")) {

            $ScriptFolderPath = New-Item -Path $Path -Name $Name -ItemType Directory -Verbose

            $newScriptFileInfoSplat = @{
                Copyright   = $Copyright
                Description = $Description
                Version     = $ScriptVersion
                CompanyName = $CompanyName
                Guid        = [Guid]::NewGuid().Guid
                Author      = $Author
                Path        = "$ScriptFolderPath\Temp.ps1"
            }

            New-ScriptFileInfo @newScriptFileInfoSplat

            $TemplateContent = @'
            [CmdletBinding(SupportsShouldProcess=$true)]
 
            param (
                #Not mandatory parameter example
                [Parameter(
                    Mandatory = $false,
                    ValueFromPipeline = $true,
                    ValueFromPipelineByPropertyName = $true)]
                [AllowNull()]
                [String]$param1,
 
                #Mandatory parameter example
                [Parameter(
                    Mandatory = $true,
                    ValueFromPipeline = $true,
                    ValueFromPipelineByPropertyName = $true)]
                [ValidateNotNullOrEmpty()]
                [String]$Param2
            )
 
                Begin {
                }
                Process {
 
                    try {
                        if ($pscmdlet.ShouldProcess("Target", "Operation")) {
 
                        }
                    }
                    catch {
 
                        throw
                    }
                }
                End {
                }
'@


            (Get-Content -Path "$ScriptFolderPath\Temp.ps1").Replace("Param()",$TemplateContent) | Set-Content "$ScriptFolderPath\Temp.ps1"

            Get-Content -Path "$ScriptFolderPath\Temp.ps1" | ForEach-Object {$PSItem.TrimEnd()} | Set-Content "$ScriptFolderPath\$Name.ps1"
            Remove-Item -Path "$ScriptFolderPath\Temp.ps1" -Force
            $ModulePath = (Get-Module -Name AMPowerShellTemplate).path

            $CurrentLocation = Get-Location

            Push-Location -Path $ModulePath.Substring(0, $ModulePath.LastIndexOf("\"))

            $Parameters = Get-Content -Path .\DefaultTests.json | ConvertFrom-Json

            Push-Location $ScriptFolderPath

            $newTestScriptFileInfoSplat = @{
                Copyright   = $Copyright
                Description = $Description
                Version     = $ScriptVersion
                CompanyName = $CompanyName
                Guid        = [Guid]::NewGuid().Guid
                Author      = $Author
                Path        = "$ScriptFolderPath\Temp.tests.ps1"
            }

            New-ScriptFileInfo @newTestScriptFileInfoSplat

            (Get-Content -Path "$ScriptFolderPath\Temp.tests.ps1").Replace("Param()",$Parameters.DefaultTests.Script.Content) | Set-Content "$ScriptFolderPath\Temp.tests.ps1"
            Get-Content -Path "$ScriptFolderPath\Temp.tests.ps1" | ForEach-Object {$PSItem.TrimEnd()} | Set-Content "$ScriptFolderPath\$Name.tests.ps1"
            Remove-Item -Path "$ScriptFolderPath\temp.tests.ps1" -Force

            Invoke-Pester
            Set-Location $CurrentLocation

        }
    }
    End {
    }

}

Export-ModuleMember -Function New-AMPowerShellModule

Export-ModuleMember -Function New-AMPowerShellScript
# SIG # Begin signature block
# MIIXwwYJKoZIhvcNAQcCoIIXtDCCF7ACAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUuF7lSpF4YpgDPdk4I4yytILi
# VPKgghL2MIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B
# AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG
# A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh
# d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg
# Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV
# UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu
# dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN
# AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q
# WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC
# i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4
# ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3
# +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI
# fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd
# BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG
# CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB
# Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro
# YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV
# HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y
# MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf
# plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y
# 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq
# IhKjURmDfrYwggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqGSIb3
# DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh
# dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD
# QSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkGA1UE
# BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQDEytT
# eW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIBIjAN
# BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEKU5Ow
# mNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf2Gi0
# jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQDhfu
# ltthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6Anqh
# d5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrFxeoz
# C9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQIDAQAB
# o4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAO
# BgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5odHRw
# Oi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly90
# cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUwMzAx
# oC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcyLmNy
# bDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAdBgNV
# HQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzMzHSa
# 1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ijhCcH
# bxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebDZw73
# BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmRDoDR
# EfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2bW+IW
# yhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5Mysu
# e7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzYBHUw
# ggUlMIIEDaADAgECAhAG+v2wvXnjGcvHbHMjoqQyMA0GCSqGSIb3DQEBCwUAMHIx
# CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
# dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
# RCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTYxMDE0MDAwMDAwWhcNMTkxMDIzMTIwMDAw
# WjBiMQswCQYDVQQGEwJESzETMBEGA1UECBMKU3lkZGFubWFyazEQMA4GA1UEBxMH
# S29sZGluZzEVMBMGA1UEChMMQXV0b21pemUgUC9TMRUwEwYDVQQDEwxBdXRvbWl6
# ZSBQL1MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDD2i1LjPMTWQ/Z
# IUu9hVd4zXoU0k4xoRI1hdS4T2uvNdQPIGksD0SIK86+cBqKLVe8V+Do4mkKmmc3
# OskJnetN0ebst/8/ssJBSTc9zrEjmMdwspRog0Wjnb37bJWo0/Oown86BPafFCJT
# oFoTBq4rnERtHAX8W7eNky8Lv7VMzcyM7poaeh7LSRhoetd1j6WpOWlAnbzu+tis
# kixhl+uViQRBMl7nAzHxAvoq+Qx9fF4WhRXP1IhL0I+xiEdFiUQBaEOGBX7H/yXc
# qmK7yWux+mpCd1L+t9LjqwiG2YjamlzaRaq9xd8C/HNUX/c/mnQltsWE8GuMoTpX
# oL+eEq8fAgMBAAGjggHFMIIBwTAfBgNVHSMEGDAWgBRaxLl7KgqjpepxA8Bg+S32
# ZXUOWDAdBgNVHQ4EFgQUtkZqp/lfcNEd55nXFliTnGvgwoMwDgYDVR0PAQH/BAQD
# AgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHcGA1UdHwRwMG4wNaAzoDGGL2h0dHA6
# Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMDWgM6Ax
# hi9odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNy
# bDBMBgNVHSAERTBDMDcGCWCGSAGG/WwDATAqMCgGCCsGAQUFBwIBFhxodHRwczov
# L3d3dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAEEATCBhAYIKwYBBQUHAQEEeDB2
# MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTgYIKwYBBQUH
# MAKGQmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1
# cmVkSURDb2RlU2lnbmluZ0NBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEB
# CwUAA4IBAQA0zGCo40Bv+7KNre6TTDWf/2k0Tzauzwy3oesHg3pd7ZgQcPTU5er3
# vLXCKQwb8bmsPw3XpL0u1CkjdiqaO6S4qv3pGbyg9qnDXeFPJhg+i5VaTGb+PMSa
# +nquQtdHhxfj5VEdt6nJlG/cBPMf/cH3O7/AzngCY1KGClKhtgLphHVF15oMj2Rt
# Bu/jHSqWQAZOIXg7lvNfcRDI6DHwtMXVa4pVDJJM26SsLfpdoJnVOAbWUbkzf8BX
# QDDp/pG/M9mrADKmPb+dy5EnX0SWwyZd3t/cIw7+AkpXbKGv3TJLSKQMdvW+bqZ0
# /VCcF796baLjQYXi28I4pkAabr5gt2u4MIIFMDCCBBigAwIBAgIQBAkYG1/Vu2Z1
# U0O1b5VQCDANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM
# RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQD
# ExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMTMxMDIyMTIwMDAwWhcN
# MjgxMDIyMTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQg
# SW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2Vy
# dCBTSEEyIEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0B
# AQEFAAOCAQ8AMIIBCgKCAQEA+NOzHH8OEa9ndwfTCzFJGc/Q+0WZsTrbRPV/5aid
# 2zLXcep2nQUut4/6kkPApfmJ1DcZ17aq8JyGpdglrA55KDp+6dFn08b7KSfH03sj
# lOSRI5aQd4L5oYQjZhJUM1B0sSgmuyRpwsJS8hRniolF1C2ho+mILCCVrhxKhwjf
# DPXiTWAYvqrEsq5wMWYzcT6scKKrzn/pfMuSoeU7MRzP6vIK5Fe7SrXpdOYr/mzL
# fnQ5Ng2Q7+S1TqSp6moKq4TzrGdOtcT3jNEgJSPrCGQ+UpbB8g8S9MWOD8Gi6CxR
# 93O8vYWxYoNzQYIH5DiLanMg0A9kczyen6Yzqf0Z3yWT0QIDAQABo4IBzTCCAckw
# EgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYI
# KwYBBQUHAwMweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
# cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
# ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
# OqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
# RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwTwYDVR0gBEgwRjA4BgpghkgBhv1sAAIE
# MCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYI
# YIZIAYb9bAMwHQYDVR0OBBYEFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB8GA1UdIwQY
# MBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3DQEBCwUAA4IBAQA+7A1a
# JLPzItEVyCx8JSl2qB1dHC06GsTvMGHXfgtg/cM9D8Svi/3vKt8gVTew4fbRknUP
# UbRupY5a4l4kgU4QpO4/cY5jDhNLrddfRHnzNhQGivecRk5c/5CxGwcOkRX7uq+1
# UcKNJK4kxscnKqEpKBo6cSgCPC6Ro8AlEeKcFEehemhor5unXCBc2XGxDI+7qPjF
# Emifz0DLQESlE/DmZAwlCEIysjaKJAL+L3J+HNdJRZboWR3p+nRka7LrZkPas7CM
# 1ekN3fYBIM6ZMWM9CBoYs4GbT8aTEAb8B4H6i9r5gkn3Ym6hU/oSlBiFLpKR6mhs
# RDKyZqHnGKSaZFHvMYIENzCCBDMCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNV
# BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G
# A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQQIQ
# Bvr9sL154xnLx2xzI6KkMjAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAig
# AoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgEL
# MQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU1gr+9uRYTZ0BT2NVDUXV
# cJDIa98wDQYJKoZIhvcNAQEBBQAEggEARIIDpLWyizf5bHt54Pzq2Kl2yiYMtC8x
# 8kwyZ2XlBYPTw4VmVkUnq5oSMgDDFs1Q8kt8iEV3njU7OYPAOMsR7KYFZKDOk0MA
# ltMOlhFMMu/OrmcFBDpVVKh0TkPB9InJPGcDQaWa+3vR6KSL+ifoHn8rLhiW7KQb
# YatTys2bw0yHV2AtHH+UqFEuDjfzQrtRT4+8rHUWUx34t7hvHXg46771UQC1jRNW
# D3PNmEAN0Z1exot1B5Ot9Ju486hywPa/u1OxIz+IP4g/QTnh0ijD1WO5k0JkmLGM
# 3JCA21Yk+GCKYTaJ5RK6HbJvOV/Nt4u01ScgqtIkYleQ1XShvGhYI6GCAgswggIH
# BgkqhkiG9w0BCQYxggH4MIIB9AIBATByMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQK
# ExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBT
# dGFtcGluZyBTZXJ2aWNlcyBDQSAtIEcyAhAOz/Q4yP6/NW4E2GqYGxpQMAkGBSsO
# AwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEP
# Fw0xODEwMjkxNzU2MDFaMCMGCSqGSIb3DQEJBDEWBBQ1bGnGWdI4SdE+VyjeSwJ5
# fgqBVzANBgkqhkiG9w0BAQEFAASCAQA/SFyRM5CLsKUHf8dZSRq5reQh3kzUEVZW
# 3dTNBYLaUqSpYstFK1by39DyBZZAHVl5anolaS9vhMawUU/7QnBee1+xLylMSE2k
# pSQU+KBoC9E6AZLzHuBTCrVG2lU9LfX+qpeeuaWPeCR7lWp2fzKdRDjBH6/pb2Oq
# ydhGBFRT5kjKLNJZ0yyTImfdYAQw4JsGMqsMdeIjYOaVHh0nlJFlGh1w43bJv084
# RksbtmE3pQ/q/bXicnhJBSIKZxpmkddNpMQjKWcGSRsoat03znSFdm2H0+crxoqN
# NdH0cVQ6eEnsrPwH70O/ONm5WF8lhds2osZ3UkbqQhkM6kbgj7+0
# SIG # End signature block