Private/_BlueprintFunctions.ps1
$_blueprintsOnlinePath = '/LambdaSampleFunctions/powershell/v3/' $_modulePath = Split-Path -Path $PSScriptRoot -Parent $_blueprintsModulePath = Join-Path -Path $_modulePath -ChildPath 'Templates' -AdditionalChildPath 'Blueprints' $_manifestFilename = 'ps-lambda-blueprint-manifest.json' <# .DESCRIPTION Probes the default or custom location to find the requested blueprint content #> function _getHostedBlueprintsContent { param ( # the relative path and filename to the content to load [Parameter(Mandatory = $true)] [string]$Contentpath ) $_defaultOrigins = @( 'https://d3rrggjwfhwld2.cloudfront.net' 'https://aws-vs-toolkit.s3.amazonaws.com' ) $_altOrigin = $env:PSLAMBDA_BLUEPRINTS_ORIGIN if ($_altOrigin) { $_contentOrigins = @($_altOrigin) } else { $_contentOrigins = $_defaultOrigins } foreach ($_origin in $_contentOrigins) { try { $_contentLocation = $_origin + $_blueprintsOnlinePath + $ContentPath Write-Debug "Attempting to load blueprints content at $_contentLocation" if ($_contentLocation.StartsWith('http')) { # Preventing "-Verbose" from displaying Invoke-WebRequest verbose output $response = Invoke-WebRequest -Uri $_contentLocation -Verbose:$false $_content = [System.Text.Encoding]::UTF8.GetString($response.Content) return $_content } else { $_content = [System.IO.File]::ReadAllText($_contentLocation) return $_content } } catch { } } } <# .DESCRIPTION Reads blueprint content from that installed with the module #> function _getLocalBlueprintsContent { param ( # The relative path and filename to the content to load [Parameter(Mandatory = $true)] [string]$ContentPath ) $_localContentPath = Join-Path -Path $_blueprintsModulePath -ChildPath $ContentPath Write-Debug "Attempting load of blueprint content from $_localContentPath" if (Test-Path -Path $_localContentPath -PathType Leaf) { return [System.IO.File]::ReadAllText($_localContentPath) } else { throw "$_localContentPath does not exist!" } } <# .DESCRIPTION Composite helper to obtain content from blueprints; if not available online it attempts to try from the local module install #> function _getBlueprintsContent { param ( # the relative path and filename to the content to load [Parameter(Mandatory = $true)] [string]$ContentPath, # Defines whether to load Blueprints from online data sources [switch]$Online ) if ($Online) { $private:_content = _getHostedBlueprintsContent -Contentpath $ContentPath } if (!($private:_content)) { $private:_content = _getLocalBlueprintsContent -ContentPath $ContentPath } return $private:_content } <# .DESCRIPTION Loads the manifest and returns a PSObject of the content. Default behavior is to download from one of the online sources detailed in $_defaultOrigins. An alternative origin can be used by setting the PSLAMBDA_BLUEPRINTS_ORIGIN environment variable to a web or file-based location. #> function _loadBlueprintManifest { param ( # Defines whether to load Blueprints from online data sources [switch]$Online ) $_getBlueprintsContent = @{ ContentPath = $_manifestFilename } if ($Online) { $_getBlueprintsContent.Add('Online', $true) } return ConvertFrom-Json -InputObject (_getBlueprintsContent @_getBlueprintsContent) } <# .DESCRIPTION Unpacks one or more content files for a blueprint into the user-specified location. Returns the name of the script file containing the actual Lambda function to be run. #> function _unpackBlueprintContents { param ( # The name of the template containing the content to be unpacked. [Parameter(Mandatory = $true)] [string]$Template, # The output folder to hold the content. It is created if necessary. [Parameter(Mandatory = $true)] [string]$Directory, # Basename to use for files in the blueprint that can be customized. # If not specified, the template name is used. [Parameter()] [string]$BaseName, # Optional script block that the unpacked script content will be passed to # prior to output to disk, allowing for template substitution etc. [Parameter()] [scriptblock]$ContentProcessor ) $_manifest = _loadBlueprintManifest $_template = $_manifest.blueprints | Where-Object -Property name -EQ -Value $Template if (!($_template)) { throw "Failed to find blueprint details for blueprint named $Template" } if (!(Test-Path $Directory)) { New-Item -ItemType Directory -Path $Directory -Force | Out-Null } $_lambdaFunctionFile = '' # unpack the contents; for each file 'source' is the name of the content in the online or installed # payload, 'output' is the name we want the content to have on disk foreach ($_contentFile in $_template.content) { $_sourcePath = Join-Path -Path $Template -ChildPath $_contentFile.source $_outputFilename = $_contentFile.output.Replace('{basename}', $BaseName) $_outputPath = Join-Path -Path $Directory -ChildPath $_outputFilename Write-Debug "Loading blueprint content at $_sourcePath" $_content = _getBlueprintsContent -ContentPath $_sourcePath if ($ContentProcessor) { $fileExt = [System.IO.Path]::GetExtension($_outputFilename) $_content = Invoke-Command -ScriptBlock $ContentProcessor -ArgumentList $fileExt, $_content } Write-Debug "Writing output file $_outputPath" New-Item -ItemType File -Path $_outputPath -Force | Out-Null Out-File -FilePath $_outputPath -InputObject $_content -Encoding utf8NoBOM -Force | Out-Null if ($_contentFile.fileType -eq "lambdaFunction") { $_lambdaFunctionFile = $_outputFilename } } return $_lambdaFunctionFile } # SIG # Begin signature block # MIIekAYJKoZIhvcNAQcCoIIegTCCHn0CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBk2Smuf+lchl0p # PLGNJL/OUyKOqXjUPfAE35mT+leEO6CCDb4wggawMIIEmKADAgECAhAIrUCyYNKc # TJ9ezam9k67ZMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0z # NjA0MjgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg # SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg # UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw # ggIKAoICAQDVtC9C0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0 # JAfhS0/TeEP0F9ce2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJr # Q5qZ8sU7H/Lvy0daE6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhF # LqGfLOEYwhrMxe6TSXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+F # LEikVoQ11vkunKoAFdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh # 3K3kGKDYwSNHR7OhD26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJ # wZPt4bRc4G/rJvmM1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQay # g9Rc9hUZTO1i4F4z8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbI # YViY9XwCFjyDKK05huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchAp # QfDVxW0mdmgRQRNYmtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRro # OBl8ZhzNeDhFMJlP/2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IB # WTCCAVUwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+ # YXsIiGX0TkIwHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P # AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC # hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v # dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAED # MAgGBmeBDAEEATANBgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql # +Eg08yy25nRm95RysQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFF # UP2cvbaF4HZ+N3HLIvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1h # mYFW9snjdufE5BtfQ/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3Ryw # YFzzDaju4ImhvTnhOE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5Ubdld # AhQfQDN8A+KVssIhdXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw # 8MzK7/0pNVwfiThV9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnP # LqR0kq3bPKSchh/jwVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatE # QOON8BUozu3xGFYHKi8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bn # KD+sEq6lLyJsQfmCXBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQji # WQ1tygVQK+pKHJ6l/aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbq # yK+p/pQd52MbOoZWeE4wggcGMIIE7qADAgECAhALQezlGADXm0QkMIMME0DNMA0G # CSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg # SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg # UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjEwNjIxMDAwMDAwWhcNMjIwNjI5 # MjM1OTU5WjCBijELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO # BgNVBAcTB1NlYXR0bGUxIjAgBgNVBAoTGUFtYXpvbiBXZWIgU2VydmljZXMsIElu # Yy4xDDAKBgNVBAsTA0FXUzEiMCAGA1UEAxMZQW1hem9uIFdlYiBTZXJ2aWNlcywg # SW5jLjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAMkg9KCA2iKT2gg1 # LZCv49o+ng0urkg5D6NjrtuvjNzzoZa/OhRaG9Lk/7oInsyP1EQHz+t3TbDC3oQL # FQlbnybnMzwA5QhCXHtgoHMKiJBTp1JXDIktrGH3viO9tJAeETndAnNIjap5ekjn # FY9mVG34XEFlhFT+5y7VplH4tX0I3Uda2dDCxnftEgJuVu3ari2RZm08AZ7msisA # 9lNL7EKBBvs8YlzXQjJUwOye0KmW9yDFI2d21io5WzdJZvUPOWRsdatCDR2T3abr # ohuO5UzqS4nlutGJ5hJ8stRV2wBAomoVaWqZJuqaMTiuigzOV79VB4Cp7LSHo4+W # FDEHFWvOd7ZhWYQKqinQfCtGJE2B4HtktyVb75fvokeDaDUr8K0qTZP+TBgcyaQQ # CSOq2Y3hlJgUUGufqnKN3ov8oT6aRwfMmNjDSFcggAdbEKkgWYI3eTMLlhz6vE7C # K4glARf+X/TXM4osMtukwEz+S6H6JcbI4jr+ko1OBAFpjc0WCQIDAQABo4ICBjCC # AgIwHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFBHT # u3xRzhBn50nr95B39HbOObU1MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggr # BgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2Vy # dC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQy # MDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lD # ZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmww # PgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5k # aWdpY2VydC5jb20vQ1BTMIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JT # QTQwOTZTSEEzODQyMDIxQ0ExLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEB # CwUAA4ICAQCI//HXDFd66gGWU+LvPhUbNZvLy4nf5iVsfdWmNCuHcYhH5mn1rzj4 # CflUA96R03Tf7SJ5C0sAuA/5iOV2x607/BWOaHsyxN/pzsNW+3gJjfPsyXHec1TE # MmTZ6A+aBaFZokdijE6eWxqjG8AmQoWUNCTso5bg6+vy/UW74Q8JRXUlmDWbQnlz # oLe4ACo6PPbHxQBGpBG+lsGhWKz3H1HUDx3kTDHGh/j6rCPW/sbG5kZxbhdLzpgr # Omu0N0+iNl2HT1Ug/lJdb/l3k8ngniMLT2Er5DcBVDo3h5aj7ODt/VNCGwL2ycAC # XDAuxLz7cRwG2GD6ibnzcMSk31bhtaXxG02V8jcIpkwn7ikAF5PORUuEMoDlf8rZ # s+p/0EVDVQ8HBEg5xvbq55Q8IWqqGniIKrAHyHO0t826Y9Rxkar2UKVMlRgT07kG # Wt5kWyVdtUIB9YTyABIMDjPdNhixlKUWBi3dr/+5dQ2HtrJyoZFP2SdW3XgQS1lR # KjE/27OzjGW1Dw0CPfvWbidhFjd+4YPZ+NQ08PMS0NpNW8vjI9BtGUVX2xlrqgT+ # ulqzWOyM0Ez877QqTmIFQQBf9JEuSgFg6BCmyqzWySco1bPjB3vmFYIeJF4PbEtr # r6Za25gE3WTkclS7ldM0feUqP4HlE2AJzgfne7QlVchP/wHbqgtd3jGCECgwghAk # AgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEw # PwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2 # IFNIQTM4NCAyMDIxIENBMQIQC0Hs5RgA15tEJDCDDBNAzTANBglghkgBZQMEAgEF # AKB8MBAGCisGAQQBgjcCAQwxAjAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEE # MBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCA4 # xGIuhm6U9LImEBV2dqUYVIKF3CRx5PG9SizXXlDjuTANBgkqhkiG9w0BAQEFAASC # AYBWKYgvJ3YxHogZDxzJxw0hkMZKJgsZTOR+b/FQih2ibvxr8JjAoJ2kWE6ZDgEj # UAImOyj+hi8/CKyKNn36uNnRu1EXaP9Llz4qccRkJgr6Hb301Y3AXH1Qu1StH5sx # BgYuOcoQdxMeT8DK2hDyDKKURi2Wqvf1pJyPPDyGloFpiuuCErpPJuC0m3N9IFwE # LKfkUWFEr7yO8LcH+gNyL1koDs2qIE9/MXoKNkG3Q3XwHWwwlc3+ZNTmKhLC0rrE # kN1OXJENl7RN/gLEaReVYyMAICtt/qFK0KKwrWqnHRNpWLi9nzgrU0CbB5MdHLKe # h4L42n+j8h8NwHZSugI7iDwZOaI/hKCJ2meXDctcUPKB2Ydfi3T1mL7sQR23dyUS # Ao3ND+BQ7fBeGGoQlgAa/xTkQXX1DBXCux0e0NiK4lZ9EABxaN2ID9zERiZ5rjve # mcPgzcbGAG2VhAJCjiEjtw+5vvJay7NThJmlNDYHI26UnTzVHifloGyqrGHGdAHQ # jzOhgg1+MIINegYKKwYBBAGCNwMDATGCDWowgg1mBgkqhkiG9w0BBwKggg1XMIIN # UwIBAzEPMA0GCWCGSAFlAwQCAQUAMHgGCyqGSIb3DQEJEAEEoGkEZzBlAgEBBglg # hkgBhv1sBwEwMTANBglghkgBZQMEAgEFAAQg/QXU4p1FHKTzV4SeCXTS7EKrnIs2 # VWHkk+1t1XReZkQCEQCaDjr/IPj/faA28WSvOzZoGA8yMDIyMDMyOTE3NTEwM1qg # ggo3MIIE/jCCA+agAwIBAgIQDUJK4L46iP9gQCHOFADw3TANBgkqhkiG9w0BAQsF # ADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL # ExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3Vy # ZWQgSUQgVGltZXN0YW1waW5nIENBMB4XDTIxMDEwMTAwMDAwMFoXDTMxMDEwNjAw # MDAwMFowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSAw # HgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMTCCASIwDQYJKoZIhvcNAQEB # BQADggEPADCCAQoCggEBAMLmYYRnxYr1DQikRcpja1HXOhFCvQp1dU2UtAxQtSYQ # /h3Ib5FrDJbnGlxI70Tlv5thzRWRYlq4/2cLnGP9NmqB+in43Stwhd4CGPN4bbx9 # +cdtCT2+anaH6Yq9+IRdHnbJ5MZ2djpT0dHTWjaPxqPhLxs6t2HWc+xObTOKfF1F # LUuxUOZBOjdWhtyTI433UCXoZObd048vV7WHIOsOjizVI9r0TXhG4wODMSlKXAwx # ikqMiMX3MFr5FK8VX2xDSQn9JiNT9o1j6BqrW7EdMMKbaYK02/xWVLwfoYervnpb # CiAvSwnJlaeNsvrWY4tOpXIc7p96AXP4Gdb+DUmEvQECAwEAAaOCAbgwggG0MA4G # A1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUF # BwMIMEEGA1UdIAQ6MDgwNgYJYIZIAYb9bAcBMCkwJwYIKwYBBQUHAgEWG2h0dHA6 # Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAfBgNVHSMEGDAWgBT0tuEgHf4prtLkYaWy # oiWyyBc1bjAdBgNVHQ4EFgQUNkSGjqS6sGa+vCgtHUQ23eNqerwwcQYDVR0fBGow # aDAyoDCgLoYsaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC10 # cy5jcmwwMqAwoC6GLGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3Vy # ZWQtdHMuY3JsMIGFBggrBgEFBQcBAQR5MHcwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v # Y3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEFBQcwAoZDaHR0cDovL2NhY2VydHMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRFRpbWVzdGFtcGluZ0NBLmNy # dDANBgkqhkiG9w0BAQsFAAOCAQEASBzctemaI7znGucgDo5nRv1CclF0CiNHo6uS # 0iXEcFm+FKDlJ4GlTRQVGQd58NEEw4bZO73+RAJmTe1ppA/2uHDPYuj1UUp4eTZ6 # J7fz51Kfk6ftQ55757TdQSKJ+4eiRgNO/PT+t2R3Y18jUmmDgvoaU+2QzI2hF3MN # 9PNlOXBL85zWenvaDLw9MtAby/Vh/HUIAHa8gQ74wOFcz8QRcucbZEnYIpp1FUL1 # LTI4gdr0YKK6tFL7XOBhJCVPst/JKahzQ1HavWPWH1ub9y4bTxMd90oNcX6Xt/Q/ # hOvB46NJofrOp79Wz7pZdmGJX36ntI5nePk2mOHLKNpbh6aKLzCCBTEwggQZoAMC # AQICEAqhJdbWMht+QeQF2jaXwhUwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMC # VVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0 # LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTE2 # MDEwNzEyMDAwMFoXDTMxMDEwNzEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTATBgNV # BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G # A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQTCC # ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3QMu5LzY9/3am6gpnFOVQo # V7YjSsQOB0UzURB90Pl9TWh+57ag9I2ziOSXv2MhkJi/E7xX08PhfgjWahQAOPcu # HjvuzKb2Mln+X2U/4Jvr40ZHBhpVfgsnfsCi9aDg3iI/Dv9+lfvzo7oiPhisEeTw # mQNtO4V8CdPuXciaC1TjqAlxa+DPIhAPdc9xck4Krd9AOly3UeGheRTGTSQjMF28 # 7DxgaqwvB8z98OpH2YhQXv1mblZhJymJhFHmgudGUP2UKiyn5HU+upgPhH+fMRTW # rdXyZMt7HgXQhBlyF/EXBu89zdZN7wZC/aJTKk+FHcQdPK/P2qwQ9d2srOlW/5MC # AwEAAaOCAc4wggHKMB0GA1UdDgQWBBT0tuEgHf4prtLkYaWyoiWyyBc1bjAfBgNV # HSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzASBgNVHRMBAf8ECDAGAQH/AgEA # MA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB5BggrBgEFBQcB # AQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggr # BgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNz # dXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2NybDQu # ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDBQBgNVHSAESTBHMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYcaHR0 # cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sBwEwDQYJKoZIhvcN # AQELBQADggEBAHGVEulRh1Zpze/d2nyqY3qzeM8GN0CE70uEv8rPAwL9xafDDiBC # LK938ysfDCFaKrcFNB1qrpn4J6JmvwmqYN92pDqTD/iy0dh8GWLoXoIlHsS6HHss # IeLWWywUNUMEaLLbdQLgcseY1jxk5R9IEBhfiThhTWJGJIdjjJFSLK8pieV4H9YL # FKWA1xJHcLN11ZOFk362kmf7U2GJqPVrlsD0WGkNfMgBsbkodbeZY4UijGHKeZR+ # WfyMD+NvtQEmtmyl7odRIeRYYJu6DC0rbaLEfrvEJStHAgh8Sa4TtuF8QkIoxhhW # z0E0tmZdtnR79VYzIi8iNrJLokqV2PWmjlIxggKGMIICggIBATCBhjByMQswCQYD # VQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGln # aWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgVGlt # ZXN0YW1waW5nIENBAhANQkrgvjqI/2BAIc4UAPDdMA0GCWCGSAFlAwQCAQUAoIHR # MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMjIw # MzI5MTc1MTAzWjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBTh14Ko4ZG+72vKFpG1 # qrSUpiSb8zAvBgkqhkiG9w0BCQQxIgQgbjCkSPu1JBk4tfYGvWd9h1bNHJeXEHWh # hhCWH0yv9vswNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQgsxCQBrwK2YMHkVcp4EQD # QVyD4ykrYU8mlkyNNXHs9akwDQYJKoZIhvcNAQEBBQAEggEAK7Wb/ZkIJw+w0yey # NKDNp0CpwWj/0zBoLf7snzLfF42m+zdAsDgg8/XTtp0yJYqgM+VtSpLtgbaszwpn # 9gGF/A2UblCckmB0/kBt8+diqBb3qFlzJ2qW1+Bal9n4cvASNn8uEMex1pH+H+Xy # TcpjUcRDpKbed04poX4zHY1GJ/bt0oI1FMPe8xKZqRFOIrl2UcvVX7UMXVshTsu7 # zJCznTY57b6K0yMfT553r58rL3bw7jqR7vyHuXKycCKEnOOOj1JnjJGukc56Kv98 # P0T/4J56p+FHZtzZy1W3DZp9qwhP5IYf1HismgA4yzfMkGXGmXOv8qZg9Pp4Ayl4 # FTPVsQ== # SIG # End signature block |