Get-MsIdAzureIpRange.ps1

<#
.SYNOPSIS
    Get list of IP ranges for Azure

.EXAMPLE
    PS > Get-MsIdAzureIpRange -AllServiceTagsAndRegions

    Get list of IP ranges for Azure Public cloud catagorized by Service Tag and Region.

.EXAMPLE
    PS > Get-MsIdAzureIpRange -ServiceTag AzureActiveDirectory

    Get list of IP ranges for Azure Active Directory in Azure Public Cloud.

.EXAMPLE
    PS > Get-MsIdAzureIpRange -Region WestUS

    Get list of IP ranges for West US region of Azure Public Cloud.

.EXAMPLE
    PS > Get-MsIdAzureIpRange -Cloud China -Region ChinaEast -ServiceTag Storage

    Get list of IP ranges for Storage in ChinaEast region of Azure China Cloud.

.INPUTS
    System.String
    
#>

function Get-MsIdAzureIpRange {
    [CmdletBinding(DefaultParameterSetName = 'ById')]
    [OutputType([PSCustomObject], [string[]])]
    param(
        # Name of Azure Cloud. Valid values are: Public, Government, Germany, China
        [Parameter(Mandatory = $false, Position = 1)]
        [ValidateSet('Public', 'Government', 'Germany', 'China')]
        [string] $Cloud = 'Public',

        # Name of Region. Use AllServiceTagsAndRegions parameter to see valid regions.
        [Parameter(Mandatory = $false, Position = 2, ParameterSetName = 'ById')]
        [ValidateNotNullOrEmpty()]
        [ArgumentCompleter({
                param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters )
                [string] $Cloud = 'Public'  # Default Cloud parameter value
                if ($fakeBoundParameters.ContainsKey('Cloud')) { $Cloud = $fakeBoundParameters.Cloud }
                [string] $ServiceTag = ''  # Default ServiceTag parameter value
                if ($fakeBoundParameters.ContainsKey('ServiceTag')) { $ServiceTag = $fakeBoundParameters.ServiceTag }

                [array] $AllServiceTagsAndRegions = Get-MSIDAzureIpRange -Cloud $Cloud -AllServiceTagsAndRegions -Verbose:$false
                #$AllServiceTagsAndRegions.values.properties.region | Select-Object -Unique | Where-Object { $_ }

                $listRegions = New-Object System.Collections.Generic.List[string]
                foreach ($Item in $AllServiceTagsAndRegions.values.name) {
                    if ($Item -like "$ServiceTag*.$wordToComplete*") {
                        $Region = $Item.Split('.')[1]
                        if (!$listRegions.Contains($Region)) { $listRegions.Add($Region) }
                    }
                }

                if ($listRegions) {
                    $listRegions #| ForEach-Object {$_}
                }
            })]
        [string] $Region,

        # Name of Service Tag. Use AllServiceTagsAndRegions parameter to see valid service tags.
        [Parameter(Mandatory = $false, Position = 3, ParameterSetName = 'ById')]
        [ValidateNotNullOrEmpty()]
        [ArgumentCompleter({
                param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters )
                [string] $Cloud = 'Public'  # Default Cloud parameter value
                if ($fakeBoundParameters.ContainsKey('Cloud')) { $Cloud = $fakeBoundParameters.Cloud }
                [string] $Region = ''  # Default Region parameter value
                if ($fakeBoundParameters.ContainsKey('Region')) { $Region = $fakeBoundParameters.Region }

                [array] $AllServiceTagsAndRegions = Get-MSIDAzureIpRange -Cloud $Cloud -AllServiceTagsAndRegions -Verbose:$false
                #$AllServiceTagsAndRegions.values.properties.region | Select-Object -Unique | Where-Object { $_ }

                $listServiceTags = New-Object System.Collections.Generic.List[string]
                foreach ($Item in $AllServiceTagsAndRegions.values.name) {
                    if ($Item -like "$wordToComplete*?$Region*") {
                        $ServiceTag = $Item.Split('.')[0]
                        if (!$listServiceTags.Contains($ServiceTag)) { $listServiceTags.Add($ServiceTag) }
                    }
                }

                if ($listServiceTags) {
                    $listServiceTags #| ForEach-Object {$_}
                }
            })]
        [string] $ServiceTag,

        # List all IP ranges catagorized by Service Tag and Region.
        [Parameter(Mandatory = $false, ParameterSetName = 'AllServiceTagsAndRegions')]
        [switch] $AllServiceTagsAndRegions
    )

    [hashtable] $MdcIdCloudMapping = @{
        Public     = 56519
        Government = 57063
        Germany    = 57064
        China      = 57062
    }

    [uri] $MdcUri = 'https://www.microsoft.com/en-us/download/confirmation.aspx?id={0}' -f $MdcIdCloudMapping[$Cloud]
    [uri] $MdcDirectUri = $null  # Example: https://download.microsoft.com/download/7/1/D/71D86715-5596-4529-9B13-DA13A5DE5B63/ServiceTags_Public_20191111.json

    $MdcResponse = Invoke-WebRequest -UseBasicParsing -Uri $MdcUri
    if ($MdcResponse -match 'https://download\.microsoft\.com/download/.+?/ServiceTags_.+?_[0-9]{6,8}\.json') {
        $MdcDirectUri = $Matches[0]
    }

    if ($MdcDirectUri) {
        $AzureIPs = Invoke-RestMethod -UseBasicParsing -Uri $MdcDirectUri -ErrorAction Stop
    }

    if ($AllServiceTagsAndRegions) {
        return $AzureIPs
    }
    else {
        [string] $Id = 'AzureCloud'
        if ($ServiceTag) {
            $Id = $ServiceTag
        }
        if ($Region) {
            $Id += '.{0}' -f $Region
        }

        $OutputIPs = $AzureIPs.values | Where-Object id -EQ $Id
        if ($OutputIPs) {
            return $OutputIPs.properties.addressPrefixes
        }
    }
}

# SIG # Begin signature block
# MIInuwYJKoZIhvcNAQcCoIInrDCCJ6gCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCWiJ4MTju21MSW
# CCGZof2W/EC0cZrwr0bAqLb4+duWtqCCDYUwggYDMIID66ADAgECAhMzAAACzfNk
# v/jUTF1RAAAAAALNMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjIwNTEyMjA0NjAyWhcNMjMwNTExMjA0NjAyWjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDrIzsY62MmKrzergm7Ucnu+DuSHdgzRZVCIGi9CalFrhwtiK+3FIDzlOYbs/zz
# HwuLC3hir55wVgHoaC4liQwQ60wVyR17EZPa4BQ28C5ARlxqftdp3H8RrXWbVyvQ
# aUnBQVZM73XDyGV1oUPZGHGWtgdqtBUd60VjnFPICSf8pnFiit6hvSxH5IVWI0iO
# nfqdXYoPWUtVUMmVqW1yBX0NtbQlSHIU6hlPvo9/uqKvkjFUFA2LbC9AWQbJmH+1
# uM0l4nDSKfCqccvdI5l3zjEk9yUSUmh1IQhDFn+5SL2JmnCF0jZEZ4f5HE7ykDP+
# oiA3Q+fhKCseg+0aEHi+DRPZAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU0WymH4CP7s1+yQktEwbcLQuR9Zww
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ3MDUzMDAfBgNVHSMEGDAW
# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
# AE7LSuuNObCBWYuttxJAgilXJ92GpyV/fTiyXHZ/9LbzXs/MfKnPwRydlmA2ak0r
# GWLDFh89zAWHFI8t9JLwpd/VRoVE3+WyzTIskdbBnHbf1yjo/+0tpHlnroFJdcDS
# MIsH+T7z3ClY+6WnjSTetpg1Y/pLOLXZpZjYeXQiFwo9G5lzUcSd8YVQNPQAGICl
# 2JRSaCNlzAdIFCF5PNKoXbJtEqDcPZ8oDrM9KdO7TqUE5VqeBe6DggY1sZYnQD+/
# LWlz5D0wCriNgGQ/TWWexMwwnEqlIwfkIcNFxo0QND/6Ya9DTAUykk2SKGSPt0kL
# tHxNEn2GJvcNtfohVY/b0tuyF05eXE3cdtYZbeGoU1xQixPZAlTdtLmeFNly82uB
# VbybAZ4Ut18F//UrugVQ9UUdK1uYmc+2SdRQQCccKwXGOuYgZ1ULW2u5PyfWxzo4
# BR++53OB/tZXQpz4OkgBZeqs9YaYLFfKRlQHVtmQghFHzB5v/WFonxDVlvPxy2go
# a0u9Z+ZlIpvooZRvm6OtXxdAjMBcWBAsnBRr/Oj5s356EDdf2l/sLwLFYE61t+ME
# iNYdy0pXL6gN3DxTVf2qjJxXFkFfjjTisndudHsguEMk8mEtnvwo9fOSKT6oRHhM
# 9sZ4HTg/TTMjUljmN3mBYWAWI5ExdC1inuog0xrKmOWVMIIHejCCBWKgAwIBAgIK
# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGYwwghmIAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAALN82S/+NRMXVEAAAAA
# As0wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIBHd
# FDgEQzOB+AVTMmX15QYSXnsCWVv4B2P99CYKTxiuMEIGCisGAQQBgjcCAQwxNDAy
# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20wDQYJKoZIhvcNAQEBBQAEggEAP9A2Mle6zDFooahmH4jGFhRe6JK7kAu+P9MP
# pURit8Y0eLSqWdABVlMQnkFYkt7lBJJh+Eh5p6nOMHI/SffBzqsX+JWohFo2cJW1
# z1xskh5VCTyJ5kio0g5u9P8W48hr+7LVKMGlDXQX3I5VN/MuLDFs9ZSYAjAGpMeM
# Ao55FZBSYnPPOxlMbq+7Tugpn28WFQkD5SFslx1noU1HP/5+iOPA51vDzcxa4rrX
# OtwtqZ/QM/6hZD324IgkVtHkCtOE18NOxYjuw+QpiHOiIjBCS5GLUMh2PytAslgg
# oGY8vpzJ5w+R3RyiHeah/D4m5Y86irfOYQbNVHJPJSd0gP/HHKGCFxYwghcSBgor
# BgEEAYI3AwMBMYIXAjCCFv4GCSqGSIb3DQEHAqCCFu8wghbrAgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCA+xA6eZYBh6sesnFBzT9orL9PD1oQ6Ml24
# f8G3zMmtPwIGYt5kFmWIGBMyMDIyMDcyOTE3MTE0OS40MzNaMASAAgH0oIHYpIHV
# MIHSMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsT
# HVRoYWxlcyBUU1MgRVNOOjg2REYtNEJCQy05MzM1MSUwIwYDVQQDExxNaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIRZTCCBxQwggT8oAMCAQICEzMAAAGMAZdi
# RzZ2ZjsAAQAAAYwwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# UENBIDIwMTAwHhcNMjExMDI4MTkyNzQ0WhcNMjMwMTI2MTkyNzQ0WjCB0jELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9z
# b2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMg
# VFNTIEVTTjo4NkRGLTRCQkMtOTMzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNI
# aEyhE/khrGssPvQRXZvrmfpLxDxi3ebBfF5U91MuGBqk/Ovg6/Bt5Oqv5UWoIsUS
# r5/oNgBUS/Vbmagtbk72u3WTfQoYqLRxxZsskGT2pV3SUwvJyiK24EzFwMIf5m4Z
# 5qGsbCPYxpYr2IIuRjThO7uk1eFDrZ1T/IqIU1HzTCoWWiXc5lg44Vguy4z1yIWp
# vUIUZFc65MXySnOfQLGhg9z74kZIB6BsX6XVhzz2lvIohB43ODw5gipbltyfiHVN
# /B/jJCj5npAuxrUUy1ygQrlil0vE42WP8JDXM1jRKPpeSdzmXR3lYoMacwp3rJGX
# 3B18awl9obnu6ib1q5LBUrZGWzhuyGJmn2DEK2RrpZe9j50taCHUHWJ0ef54HL0k
# G9dRkNJDTA84irEnfuYn1GmGyS2dFxMTVeKi1wkuuQ4/vBcoAo7Tb5A4geR7PSOy
# vc8WbFG+3yikhhGfcgNCYE1m3ADwmD7bgB1SfFCmk/eu6SZu/q94YHHt/FVN/bKX
# nhx4GgkuL163pUy4lDAJdDrZOZ3CkCnNpBp77sD9kQkt5BBBQMaJ8C5/Kcnncq3m
# U2wTEAan9aN5I9IpTie/3/z93Na52mDtNRgyaJr+6LaW+c/tYa0qCLPLvunq7iSg
# k4oXdIv/G3OuwChe+sKVrr1vQYW1DE7FpMMOK+NnAgMBAAGjggE2MIIBMjAdBgNV
# HQ4EFgQUls5ThqmCIWCIeVadPojK3UCLUiMwHwYDVR0jBBgwFoAUn6cVXQBeYl2D
# 9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3Nv
# ZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUy
# MDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1l
# LVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUE
# DDAKBggrBgEFBQcDCDANBgkqhkiG9w0BAQsFAAOCAgEA12jFRVjCCanW5UGSuqJL
# O3HQlMHjwJphCHnbMrrIFDCEJUKmo3wj/YhufMjhUkcdpOfY9oQAUmQcRZm5FY8I
# WBAtciT0JveOuIFM+RvrjludYvLnnngd4dovg5qFjSjUrpSDcn0hoFujwgwokajt
# 6p/CmFcy86Hpnz4q/1FceQgIFXBAwDLcW0a0x1wQAV8gmumkN/o7pFgeWkMy8Oqo
# R4c+xyDlPav0PWNjZ1QSj38yJcD429ja0Bn0J107LHxQ/fDqUR6tO2VMdtYOKbPF
# d94UkpCdrg8IbaeVbRRpxfgMcxQZQr3N9yz05l7HM5cuvskIAEcJjR3jQNutlqiy
# yTPOCM/DktVXxNTesmApC44PNfsxl7I7zBpowZYssWcF1hliZrKLwek+odRq35rz
# CrnThPdg+u0kd809w3QOScC/UwM1/FIYtGhmLZ+bjVAxW8SKMyETKS1aT/2Di54P
# q9r/LPJclr9Gn48GWBwSeuDFlTcR3GjbY85GLUI3WeW4cpGunV/g7UA/W4d844tE
# pa31QyC8RG+jo8qrXxo+4lmbya2+AKiFYB0Gg84LosREvYnrRYpB33+qfewuaqG0
# 02ysDdABD96ubXsiPTSDlZSZdIIuSG3efB4n9ySzur6fuch146Ei/zJYRZrxrWmJ
# kMA+ys05vbgAxeAcz/5sdr8wggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAA
# AAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBB
# dXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwx
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1p
# Y3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOC
# Ag8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YB
# f2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKD
# RLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus
# 9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTj
# kY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56
# KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39
# IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHo
# vwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJo
# LhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMh
# XV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREd
# cu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEA
# AaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqn
# Uv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnp
# cjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0w
# EwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEw
# CwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/o
# olxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNy
# b3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYt
# MjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5t
# aWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5j
# cnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+
# TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2Y
# urYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4
# U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJ
# w7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb
# 30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ
# /gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGO
# WhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFE
# fnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJ
# jXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rR
# nj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUz
# WLOhcGbyoYIC1DCCAj0CAQEwggEAoYHYpIHVMIHSMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBP
# cGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjg2REYt
# NEJCQy05MzM1MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl
# oiMKAQEwBwYFKw4DAhoDFQA0ovIU66v0PKKacHhsrmSzRCav1aCBgzCBgKR+MHwx
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1p
# Y3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA5o4o
# ZzAiGA8yMDIyMDcyOTE3MzUzNVoYDzIwMjIwNzMwMTczNTM1WjB0MDoGCisGAQQB
# hFkKBAExLDAqMAoCBQDmjihnAgEAMAcCAQACAhsXMAcCAQACAhF5MAoCBQDmj3nn
# AgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSCh
# CjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEA1SjdZgenNbluy0IExf2lb7sF
# oN0HA/KW7fU7vMA1QRQ9jinLSIdCykIlo+XzVhjtATkw0C0KGukvgmgFK8zR0c8h
# wCfnLB4Hq8EYp1HCgPXFdfeii4xPZl4FLST53ZkMUR1YEhf5Nw9TETYZqLnmJ442
# 15ZNwtGrOeZXYf+nERIxggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFt
# cCBQQ0EgMjAxMAITMwAAAYwBl2JHNnZmOwABAAABjDANBglghkgBZQMEAgEFAKCC
# AUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCBY
# 5FbDOGU2tnowqYKC8vmHfNywPeqhAJJrHeHnhzcNbTCB+gYLKoZIhvcNAQkQAi8x
# geowgecwgeQwgb0EINWti/gVKpDPBn/E5iEFnYHik062FyMDqHzriYgYmGmeMIGY
# MIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG
# A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGMAZdiRzZ2
# ZjsAAQAAAYwwIgQgiAUvwIj+LAs5DHOiHFLX0HwqnKyMc3DPnfDBB3dp0KAwDQYJ
# KoZIhvcNAQELBQAEggIAdtCLQk0coKl2dzFHGQNKXw+0qaSAP/6GQTBHOqPc8SUz
# jw6MYKk8TzexkngvF+QS+GDaoB8ymG0FMyHAmyV7VyloCxhsV3qZYWStzhn+MRdH
# yYj7MfmZ62Ojz4BUP7CzZ4/MLxrm+pC/GpnyzAb14OaH7+ACUCG9PrGFUJ3YS7oJ
# Dbk1LHsFu16/6uxxc5EPRJAOVNFBEQ8pgI//3o7rQ+BF9GXQsjo8TcllJULKsVjO
# cDvdBQpS91zUq3AwM7M1whL035ul3JDIVv4FDelNgf/qrNfJPjn1SBgGsAUNhIYn
# ErHZuYp7LavJwxh0VmOtQxE54568nHnJ4gcVgeyKG0hn+vZitl+EzaWff7pBovH1
# wYZ63AiOyRVFK3rZnvUMWFM/kgOAFnhbss+1q6mwLHT6jdvtF6HN/Dxh2Cd6KKnx
# j0N/sjS2EZahThw2jAWSdHh7MBzHvS/aj5/jlSF8bOLps3QQQR5M+4bhVpg5zNxb
# gE07pOmjfsRuMXohWwFzx6D8heefCJRExoKNUDkTUOvVRiA9ote38T/MvudF5vEY
# iL6+NOo9ubcwCljbEiArej08hKIKt/C8VLolBKwVy7WY/+mRk9mT0CkELFunIQUA
# GTmxdtYr5jjDSPURWfBwMI60NzsSXudbLiHEYlvTs02s4QlmqBiEY5yIHoB6kwk=
# SIG # End signature block