Get-KeyNameValue.ps1
function Get-KeyNameValue { <# .SYNOPSIS Retrieves keyed name/value pairs from the Appclusive server. .DESCRIPTION Retrieves keyed name/value pairs from the Appclusive server. The K/N/V store stores arbitrary data that can be selected by either key, name, value or a combination of both. Besides specifying a selection you can furthermore define the order, the selected columns and the return format. If you specify 'object' as output type then all filter options such as 'Select' are ignored. .OUTPUTS default | json | json-pretty | xml | xml-pretty .INPUTS You basically specify key, name and value to be retrieved. If one or more of these parameters are omitted all entities are returned that match these criteria. If you specify 'object' as output type then all filter options such as 'Select' are ignored. .EXAMPLE Retrieves the first 5 entities from the entity set. Not specifing Key, Name or Value is the same as you would specify the 'ListAvailable' parameter. Get-KeyNameValue | Select -First 5 Key Name Value --- ---- ----- com.acme.infrastructure.inventory ApplicationSystem Application Server com.acme.infrastructure.inventory ApplicationSystem Exchange com.acme.infrastructure.inventory ApplicationSystem Other com.acme.infrastructure.inventory ApplicationSystem Print Server com.acme.infrastructure.inventory ApplicationSystem Term Server .EXAMPLE Get-KeyNameValue biz.dfch.infrastructure.inventory Gets all entris with Key 'biz.dfch.infrastructure.inventory'. Key Name Value --- ---- ----- biz.dfch.infrastructure.inventory ServerRole DEV biz.dfch.infrastructure.inventory ServerRole INT biz.dfch.infrastructure.inventory ServerRole PROD biz.dfch.infrastructure.inventory ServerTier Tier 2 biz.dfch.infrastructure.inventory ServerTier Tier 3 biz.dfch.infrastructure.inventory ServerTier Tier 4 biz.dfch.infrastructure.inventory ServerTier Tier 5 biz.dfch.infrastructure.inventory ServerTier Unknown biz.dfch.infrastructure.inventory Status Deployed biz.dfch.infrastructure.inventory Status Disposed .EXAMPLE Get-KeyNameValue biz.dfch.infrastructure.inventory ServerRole As previous example. Gets all entris with Key 'biz.dfch.infrastructure.inventory' but now also specifies Name 'ServerRole'. Key Name Value --- ---- ----- biz.dfch.infrastructure.inventory ServerRole DEV biz.dfch.infrastructure.inventory ServerRole INT biz.dfch.infrastructure.inventory ServerRole PROD .EXAMPLE Get-KeyNameValue biz.dfch.infrastructure.inventory ServerRole -First 2 As previous example. Gets all entris with Key 'biz.dfch.infrastructure.inventory' and Name 'ServerRole' but only return first 2 entries. Key Name Value --- ---- ----- biz.dfch.infrastructure.inventory ServerRole DEV biz.dfch.infrastructure.inventory ServerRole INT .EXAMPLE Get-KeyNameValue biz.dfch.infrastructure.inventory -As json-pretty As previous example. Gets all entris with Key 'biz.dfch.infrastructure.inventory' but now also specifies Name 'ServerRole' and also specify return format as 'json-pretty'. [ { "Key": "biz.dfch.infrastructure.inventory", "Name": "ServerRole", "Value": "DEV" }, { "Key": "biz.dfch.infrastructure.inventory", "Name": "ServerRole", "Value": "INT" }, { "Key": "biz.dfch.infrastructure.inventory", "Name": "ServerRole", "Value": "PROD" } ] .EXAMPLE (Get-KeyNameValue ExistingKey NonExistingName -Select Value -DefaultValue "myDefaultValue").Value myDefaultValue .EXAMPLE (Get-KeyNameValue biz.dfch.infrastructure.inventory ServerTier -Select Value).Value Gets all entris with Key 'biz.dfch.infrastructure.inventory' and Name 'ServerTier' but only return the Value. Tier 2 Tier 3 Tier 4 .EXAMPLE Get-KeyNameValue biz.dfch.infrastructure.inventory ServerTier -ValueOnly As previous example. Gets all entris with Key 'biz.dfch.infrastructure.inventory' and Name 'ServerTier' but only return the Value. This example makes use of the new 'ValueOnly' switch that facilitates the return of values only. Tier 2 Tier 3 Tier 4 .EXAMPLE PS > Get-KeyNameValue ConvertFromJsonTest Key Name Value --- ---- ----- ConvertFromJsonTest Name1 ["arr11","arr12"] ConvertFromJsonTest Name2 ["arr21","arr22"] ConvertFromJsonTest Name3 ["arr31","arr32"] PS > Get-KeyNameValue ConvertFromJsonTest -ValueOnly ["arr11","arr12"] ["arr21","arr22"] ["arr31","arr32"] PS > Get-KeyNameValue ConvertFromJsonTest -ValueOnly -Convert json arr11 arr12 arr21 arr22 arr31 arr32 PS > Get-KeyNameValue ConvertFromJsonTest -ValueOnly -Convert json -First 1 arr11 arr12 PS > Set-KeyNameValue ConvertFromJsonTest Name20 Non-Valid-Json PS > Set-KeyNameValue ConvertFromJsonTest Name20 Non-Valid-Json -CreateIfNotExist; PS > Get-KeyNameValue ConvertFromJsonTest -ValueOnly ["arr11","arr12"] ["arr21","arr22"] Non-Valid-Json ["arr31","arr32"] PS > Get-KeyNameValue ConvertFromJsonTest -ValueOnly -Convert json -as json-pretty [ [ "arr11", "arr12" ], [ "arr21", "arr22" ], "Non-Valid-Json", [ "arr31", "arr32" ] ] This example shows how to decode JSON values while querying them from the KNV store. When the returned data is not JSON it returned unchanged .EXAMPLE $r = Get-KeyNameValue SCCM.OSDOperatingSystemType -as object ; $r.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False KeyNameValue System.Object PS > $r[0] Id : 125 Key : SCCM.OSDOperatingSystemType Name : Windows 2008 R2 STD Value : 2008STDR2x64 CreatedBy : SERVER1\Administrator Created : 8/16/2014 4:31:04 PM +00:00 ModifiedBy : SERVER1\Administrator Modified : 8/16/2014 4:31:04 PM +00:00 RowVersion : {0, 0, 0, 0...} In this example the KNV is returned as an object, so it could be piped to another Cmdlet like 'Remove-Entity'. Specifying 'object' as a return format overrides options like 'Select'. .LINK Online Version: http://dfch.biz/biz/dfch/PS/Appclusive/Client/Get-KeyNameValue/ .NOTES See module manifest for dependencies and further requirements. #> [CmdletBinding( SupportsShouldProcess = $false , ConfirmImpact = 'Low' , HelpURI='http://dfch.biz/biz/dfch/PS/Appclusive/Client/Get-KeyNameValue/' , DefaultParameterSetName = 'list' )] PARAM ( # Specifies the Key property of the entity. [Parameter(Mandatory = $false, Position = 0, ParameterSetName = 'name')] [Alias("k")] [string] $Key , # Specifies the Name property of the entity. [Parameter(Mandatory = $false, Position = 1, ParameterSetName = 'name')] [Alias('n')] [string] $Name , # Specifies the Value property of the entity. [Parameter(Mandatory = $false, Position = 2, ParameterSetName = 'name')] [Alias("v")] [string] $Value , # Specifies the order of the returned entites. You can specify more than one property (e.g. Key and Name). [ValidateSet('Key', 'Name', 'Value')] [Parameter(Mandatory = $false, Position = 3)] [string[]] $OrderBy = @('Key','Name','Value') , # Specifies what to return from the search [ValidateSet('Key', 'Name', 'Value')] [Parameter(Mandatory = $false, Position = 4)] [Alias("s")] [Alias("Return")] [string[]] $Select = @('Key','Name','Value') , # Specifies to return only values without header information. # This parameter takes precendes over the 'Select' parameter. [Parameter(Mandatory = $false, ParameterSetName = 'name')] [Alias('HideTableHeaders')] [switch] $ValueOnly , # Specifies to deserialize JSON payloads [ValidateSet('json')] [Parameter(Mandatory = $false, ParameterSetName = 'name')] [Alias('Convert')] [string] $ConvertFrom , # Limits the output to the specified number of entries [Parameter(Mandatory = $false)] [Alias('top')] [int] $First , # This value is only returned if the regular search would have returned no results [Parameter(Mandatory = $false, ParameterSetName = 'name')] [Alias('default')] $DefaultValue , # Specifies a references to the Appclusive endpoints [Parameter(Mandatory = $false)] [Alias('Services')] [hashtable] $svc = (Get-Variable -Name $MyInvocation.MyCommand.Module.PrivateData.MODULEVAR -ValueOnly).Services , # Specifies to return all existing KNV entities [Parameter(Mandatory = $false, ParameterSetName = 'list')] [switch] $ListAvailable = $false , # Specifies the return format of the search [ValidateSet('default', 'json', 'json-pretty', 'xml', 'xml-pretty', 'object')] [Parameter(Mandatory = $false)] [alias('ReturnFormat')] [string] $As = 'default' ) Begin { trap { Log-Exception $_; break; } $datBegin = [datetime]::Now; [string] $fn = $MyInvocation.MyCommand.Name; Log-Debug -fn $fn -msg ("CALL. svc '{0}'. Name '{1}'." -f ($svc -is [Object]), $Name) -fac 1; $EntitySetName = 'KeyNameValues'; # Parameter validation Contract-Requires ($svc.Core -is [biz.dfch.CS.Appclusive.Api.Core.Core]) "Connect to the server before using the Cmdlet" $OrderBy = $OrderBy | Select -Unique; $OrderByString = [string]::Join(',', $OrderBy); $Select = $Select | Select -Unique; if($ValueOnly) { if('object' -eq $As) { throw ("'ReturnFormat':'object' and 'ValueOnly' must not be specified at the same time." ); $e = New-CustomErrorRecord -m $msg -cat InvalidArgument -o $PSCmdlet; $PSCmdlet.ThrowTerminatingError($e); } $Select = 'Value'; } if($PSBoundParameters.ContainsKey('Select') -And 'object' -eq $As) { $msg = ("'ReturnFormat':'object' and 'Select' must not be specified at the same time." ); $e = New-CustomErrorRecord -m $msg -cat InvalidArgument -o $PSCmdlet; $PSCmdlet.ThrowTerminatingError($e); } } # Begin Process { # Default test variable for checking function response codes. [Boolean] $fReturn = $false; # Return values are always and only returned via OutputParameter. $OutputParameter = $null; try { # Parameter validation # N/A if($PSCmdlet.ParameterSetName -eq 'list') { if($Select -And 'object' -ne $As) { if($PSBoundParameters.ContainsKey('First')) { $Response = $svc.Core.$EntitySetName.AddQueryOption('$orderby','Name').AddQueryOption('$top', $First) | Select -Property $Select; } else { $Response = $svc.Core.$EntitySetName.AddQueryOption('$orderby','Name') | Select -Property $Select; } } else { if($PSBoundParameters.ContainsKey('First')) { $Response = $svc.Core.$EntitySetName.AddQueryOption('$orderby','Name').AddQueryOption('$top', $First) | Select; } else { $Response = $svc.Core.$EntitySetName.AddQueryOption('$orderby','Name') | Select; } } } else { $Exp = @(); if($Key) { $Key = $Key.ToLower(); $Exp += ("(tolower(Key) eq '{0}')" -f $Key); } if($Name) { $Name = $Name.ToLower(); $Exp += ("(tolower(Name) eq '{0}')" -f $Name); } if($Value) { $Value = $Value.ToLower(); $Exp += ("(tolower(Value) eq '{0}')" -f $Value); } $FilterExpression = [String]::Join(' and ', $Exp); if($Select -And 'object' -ne $As) { if($PSBoundParameters.ContainsKey('First')) { $Response = $svc.Core.$EntitySetName.AddQueryOption('$filter', $FilterExpression).AddQueryOption('$orderby', $OrderByString).AddQueryOption('$top', $First) | Select -Property $Select; } else { $Response = $svc.Core.$EntitySetName.AddQueryOption('$filter', $FilterExpression).AddQueryOption('$orderby', $OrderByString) | Select -Property $Select; } } else { if($PSBoundParameters.ContainsKey('First')) { $Response = $svc.Core.$EntitySetName.AddQueryOption('$filter', $FilterExpression).AddQueryOption('$orderby', $OrderByString).AddQueryOption('$top', $First) | Select; } else { $Response = $svc.Core.$EntitySetName.AddQueryOption('$filter', $FilterExpression).AddQueryOption('$orderby', $OrderByString) | Select; } } if('Value' -eq $Select -And $ValueOnly) { $Response = ($Response).Value; } if($PSBoundParameters.ContainsKey('DefaultValue') -And !$Response) { $Response = $DefaultValue; } if('Value' -eq $Select -And $ConvertFrom) { $ResponseTemp = New-Object System.Collections.ArrayList; foreach($item in $Response) { try { $null = $ResponseTemp.Add((ConvertFrom-Json -InputObject $item)); } catch { $null = $ResponseTemp.Add($item); } } $Response = $ResponseTemp.ToArray(); Remove-Variable ResponseTemp -Confirm:$false; } } $OutputParameter = Format-ResultAs $Response $As $fReturn = $true; } catch { if($gotoSuccess -eq $_.Exception.Message) { $fReturn = $true; } else { [string] $ErrorText = "catch [$($_.FullyQualifiedErrorId)]"; $ErrorText += (($_ | fl * -Force) | Out-String); $ErrorText += (($_.Exception | fl * -Force) | Out-String); $ErrorText += (Get-PSCallStack | Out-String); if($_.Exception -is [System.Net.WebException]) { Log-Critical $fn ("[WebException] Request FAILED with Status '{0}'. [{1}]." -f $_.Exception.Status, $_); Log-Debug $fn $ErrorText -fac 3; } else { Log-Error $fn $ErrorText -fac 3; if($gotoError -eq $_.Exception.Message) { Log-Error $fn $e.Exception.Message; $PSCmdlet.ThrowTerminatingError($e); } elseif($gotoFailure -ne $_.Exception.Message) { Write-Verbose ("$fn`n$ErrorText"); } else { # N/A } } $fReturn = $false; $OutputParameter = $null; } } finally { # Clean up # N/A } } # Process End { $datEnd = [datetime]::Now; Log-Debug -fn $fn -msg ("RET. fReturn: [{0}]. Execution time: [{1}]ms. Started: [{2}]." -f $fReturn, ($datEnd - $datBegin).TotalMilliseconds, $datBegin.ToString('yyyy-MM-dd HH:mm:ss.fffzzz')) -fac 2; # Return values are always and only returned via OutputParameter. return $OutputParameter; } # End } if($MyInvocation.ScriptName) { Export-ModuleMember -Function Get-KeyNameValue; } # # Copyright 2014-2015 d-fens GmbH # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # SIG # Begin signature block # MIIXDwYJKoZIhvcNAQcCoIIXADCCFvwCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU+LDKNbPrNmpdCMqVrSnHdIzZ # FCigghHCMIIEFDCCAvygAwIBAgILBAAAAAABL07hUtcwDQYJKoZIhvcNAQEFBQAw # VzELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNV # BAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMTA0 # MTMxMDAwMDBaFw0yODAxMjgxMjAwMDBaMFIxCzAJBgNVBAYTAkJFMRkwFwYDVQQK # ExBHbG9iYWxTaWduIG52LXNhMSgwJgYDVQQDEx9HbG9iYWxTaWduIFRpbWVzdGFt # cGluZyBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlO9l # +LVXn6BTDTQG6wkft0cYasvwW+T/J6U00feJGr+esc0SQW5m1IGghYtkWkYvmaCN # d7HivFzdItdqZ9C76Mp03otPDbBS5ZBb60cO8eefnAuQZT4XljBFcm05oRc2yrmg # jBtPCBn2gTGtYRakYua0QJ7D/PuV9vu1LpWBmODvxevYAll4d/eq41JrUJEpxfz3 # zZNl0mBhIvIG+zLdFlH6Dv2KMPAXCae78wSuq5DnbN96qfTvxGInX2+ZbTh0qhGL # 2t/HFEzphbLswn1KJo/nVrqm4M+SU4B09APsaLJgvIQgAIMboe60dAXBKY5i0Eex # +vBTzBj5Ljv5cH60JQIDAQABo4HlMIHiMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB # Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRG2D7/3OO+/4Pm9IWbsN1q1hSpwTBHBgNV # HSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFs # c2lnbi5jb20vcmVwb3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2Ny # bC5nbG9iYWxzaWduLm5ldC9yb290LmNybDAfBgNVHSMEGDAWgBRge2YaRQ2XyolQ # L30EzTSo//z9SzANBgkqhkiG9w0BAQUFAAOCAQEATl5WkB5GtNlJMfO7FzkoG8IW # 3f1B3AkFBJtvsqKa1pkuQJkAVbXqP6UgdtOGNNQXzFU6x4Lu76i6vNgGnxVQ380W # e1I6AtcZGv2v8Hhc4EvFGN86JB7arLipWAQCBzDbsBJe/jG+8ARI9PBw+DpeVoPP # PfsNvPTF7ZedudTbpSeE4zibi6c1hkQgpDttpGoLoYP9KOva7yj2zIhd+wo7AKvg # IeviLzVsD440RZfroveZMzV+y5qKu0VN5z+fwtmK+mWybsd+Zf/okuEsMaL3sCc2 # SI8mbzvuTXYfecPlf5Y1vC0OzAGwjn//UYCAp5LUs0RGZIyHTxZjBzFLY7Df8zCC # BCkwggMRoAMCAQICCwQAAAAAATGJxjfoMA0GCSqGSIb3DQEBCwUAMEwxIDAeBgNV # BAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWdu # MRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTExMDgwMjEwMDAwMFoXDTE5MDgwMjEw # MDAwMFowWjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex # MDAuBgNVBAMTJ0dsb2JhbFNpZ24gQ29kZVNpZ25pbmcgQ0EgLSBTSEEyNTYgLSBH # MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKPv0Z8p6djTgnY8YqDS # SdYWHvHP8NC6SEMDLacd8gE0SaQQ6WIT9BP0FoO11VdCSIYrlViH6igEdMtyEQ9h # JuH6HGEVxyibTQuCDyYrkDqW7aTQaymc9WGI5qRXb+70cNCNF97mZnZfdB5eDFM4 # XZD03zAtGxPReZhUGks4BPQHxCMD05LL94BdqpxWBkQtQUxItC3sNZKaxpXX9c6Q # MeJ2s2G48XVXQqw7zivIkEnotybPuwyJy9DDo2qhydXjnFMrVyb+Vpp2/WFGomDs # KUZH8s3ggmLGBFrn7U5AXEgGfZ1f53TJnoRlDVve3NMkHLQUEeurv8QfpLqZ0BdY # Nc0CAwEAAaOB/TCB+jAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIB # ADAdBgNVHQ4EFgQUGUq4WuRNMaUU5V7sL6Mc+oCMMmswRwYDVR0gBEAwPjA8BgRV # HSAAMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3Jl # cG9zaXRvcnkvMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwuZ2xvYmFsc2ln # bi5uZXQvcm9vdC1yMy5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgw # FoAUj/BLf6guRSSuTVD6Y5qL3uLdG7wwDQYJKoZIhvcNAQELBQADggEBAHmwaTTi # BYf2/tRgLC+GeTQD4LEHkwyEXPnk3GzPbrXsCly6C9BoMS4/ZL0Pgmtmd4F/ximl # F9jwiU2DJBH2bv6d4UgKKKDieySApOzCmgDXsG1szYjVFXjPE/mIpXNNwTYr3MvO # 23580ovvL72zT006rbtibiiTxAzL2ebK4BEClAOwvT+UKFaQHlPCJ9XJPM0aYx6C # WRW2QMqngarDVa8z0bV16AnqRwhIIvtdG/Mseml+xddaXlYzPK1X6JMlQsPSXnE7 # ShxU7alVrCgFx8RsXdw8k/ZpPIJRzhoVPV4Bc/9Aouq0rtOO+u5dbEfHQfXUVlfy # GDcy1tTMS/Zx4HYwggSfMIIDh6ADAgECAhIRIdaZp2SXPvH4Qn7pGcxTQRQwDQYJ # KoZIhvcNAQEFBQAwUjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24g # bnYtc2ExKDAmBgNVBAMTH0dsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0gRzIw # HhcNMTYwNTI0MDAwMDAwWhcNMjcwNjI0MDAwMDAwWjBgMQswCQYDVQQGEwJTRzEf # MB0GA1UEChMWR01PIEdsb2JhbFNpZ24gUHRlIEx0ZDEwMC4GA1UEAxMnR2xvYmFs # U2lnbiBUU0EgZm9yIE1TIEF1dGhlbnRpY29kZSAtIEcyMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEAsBeuotO2BDBWHlgPse1VpNZUy9j2czrsXV6rJf02 # pfqEw2FAxUa1WVI7QqIuXxNiEKlb5nPWkiWxfSPjBrOHOg5D8NcAiVOiETFSKG5d # QHI88gl3p0mSl9RskKB2p/243LOd8gdgLE9YmABr0xVU4Prd/4AsXximmP/Uq+yh # RVmyLm9iXeDZGayLV5yoJivZF6UQ0kcIGnAsM4t/aIAqtaFda92NAgIpA6p8N7u7 # KU49U5OzpvqP0liTFUy5LauAo6Ml+6/3CGSwekQPXBDXX2E3qk5r09JTJZ2Cc/os # +XKwqRk5KlD6qdA8OsroW+/1X1H0+QrZlzXeaoXmIwRCrwIDAQABo4IBXzCCAVsw # DgYDVR0PAQH/BAQDAgeAMEwGA1UdIARFMEMwQQYJKwYBBAGgMgEeMDQwMgYIKwYB # BQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMAkG # A1UdEwQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwQgYDVR0fBDswOTA3oDWg # M4YxaHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9ncy9nc3RpbWVzdGFtcGluZ2cy # LmNybDBUBggrBgEFBQcBAQRIMEYwRAYIKwYBBQUHMAKGOGh0dHA6Ly9zZWN1cmUu # Z2xvYmFsc2lnbi5jb20vY2FjZXJ0L2dzdGltZXN0YW1waW5nZzIuY3J0MB0GA1Ud # DgQWBBTUooRKOFoYf7pPMFC9ndV6h9YJ9zAfBgNVHSMEGDAWgBRG2D7/3OO+/4Pm # 9IWbsN1q1hSpwTANBgkqhkiG9w0BAQUFAAOCAQEAj6kakW0EpjcgDoOW3iPTa24f # bt1kPWghIrX4RzZpjuGlRcckoiK3KQnMVFquxrzNY46zPVBI5bTMrs2SjZ4oixNK # Eaq9o+/Tsjb8tKFyv22XY3mMRLxwL37zvN2CU6sa9uv6HJe8tjecpBwwvKu8LUc2 # 35IgA+hxxlj2dQWaNPALWVqCRDSqgOQvhPZHXZbJtsrKnbemuuRQ09Q3uLogDtDT # kipbxFm7oW3bPM5EncE4Kq3jjb3NCXcaEL5nCgI2ZIi5sxsm7ueeYMRGqLxhM2zP # TrmcuWrwnzf+tT1PmtNN/94gjk6Xpv2fCbxNyhh2ybBNhVDygNIdBvVYBAexGDCC # BNYwggO+oAMCAQICEhEhDRayW4wRltP+V8mGEea62TANBgkqhkiG9w0BAQsFADBa # MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEwMC4GA1UE # AxMnR2xvYmFsU2lnbiBDb2RlU2lnbmluZyBDQSAtIFNIQTI1NiAtIEcyMB4XDTE1 # MDUwNDE2NDMyMVoXDTE4MDUwNDE2NDMyMVowVTELMAkGA1UEBhMCQ0gxDDAKBgNV # BAgTA1p1ZzEMMAoGA1UEBxMDWnVnMRQwEgYDVQQKEwtkLWZlbnMgR21iSDEUMBIG # A1UEAxMLZC1mZW5zIEdtYkgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDNPSzSNPylU9jFM78Q/GjzB7N+VNqikf/use7p8mpnBZ4cf5b4qV3rqQd62rJH # RlAsxgouCSNQrl8xxfg6/t/I02kPvrzsR4xnDgMiVCqVRAeQsWebafWdTvWmONBS # lxJejPP8TSgXMKFaDa+2HleTycTBYSoErAZSWpQ0NqF9zBadjsJRVatQuPkTDrwL # eWibiyOipK9fcNoQpl5ll5H9EG668YJR3fqX9o0TQTkOmxXIL3IJ0UxdpyDpLEkt # tBG6Y5wAdpF2dQX2phrfFNVY54JOGtuBkNGMSiLFzTkBA1fOlA6ICMYjB8xIFxVv # rN1tYojCrqYkKMOjwWQz5X8zAgMBAAGjggGZMIIBlTAOBgNVHQ8BAf8EBAMCB4Aw # TAYDVR0gBEUwQzBBBgkrBgEEAaAyATIwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93 # d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCQYDVR0TBAIwADATBgNVHSUE # DDAKBggrBgEFBQcDAzBCBgNVHR8EOzA5MDegNaAzhjFodHRwOi8vY3JsLmdsb2Jh # bHNpZ24uY29tL2dzL2dzY29kZXNpZ25zaGEyZzIuY3JsMIGQBggrBgEFBQcBAQSB # gzCBgDBEBggrBgEFBQcwAoY4aHR0cDovL3NlY3VyZS5nbG9iYWxzaWduLmNvbS9j # YWNlcnQvZ3Njb2Rlc2lnbnNoYTJnMi5jcnQwOAYIKwYBBQUHMAGGLGh0dHA6Ly9v # Y3NwMi5nbG9iYWxzaWduLmNvbS9nc2NvZGVzaWduc2hhMmcyMB0GA1UdDgQWBBTN # GDddiIYZy9p3Z84iSIMd27rtUDAfBgNVHSMEGDAWgBQZSrha5E0xpRTlXuwvoxz6 # gIwyazANBgkqhkiG9w0BAQsFAAOCAQEAAApsOzSX1alF00fTeijB/aIthO3UB0ks # 1Gg3xoKQC1iEQmFG/qlFLiufs52kRPN7L0a7ClNH3iQpaH5IEaUENT9cNEXdKTBG # 8OrJS8lrDJXImgNEgtSwz0B40h7bM2Z+0DvXDvpmfyM2NwHF/nNVj7NzmczrLRqN # 9de3tV0pgRqnIYordVcmb24CZl3bzpwzbQQy14Iz+P5Z2cnw+QaYzAuweTZxEUcJ # bFwpM49c1LMPFJTuOKkUgY90JJ3gVTpyQxfkc7DNBnx74PlRzjFmeGC/hxQt0hvo # eaAiBdjo/1uuCTToigVnyRH+c0T2AezTeoFb7ne3I538hWeTdU5q9jGCBLcwggSz # AgEBMHAwWjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex # MDAuBgNVBAMTJ0dsb2JhbFNpZ24gQ29kZVNpZ25pbmcgQ0EgLSBTSEEyNTYgLSBH # MgISESENFrJbjBGW0/5XyYYR5rrZMAkGBSsOAwIaBQCgeDAYBgorBgEEAYI3AgEM # MQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQB # gjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBTJkHeLhA+efWp/ # 3x41bPhzL4dcbjANBgkqhkiG9w0BAQEFAASCAQAKBJSfiHDWxh3XRMK3zq629gtm # Clj6Dq0PnHmRL19EgWtN526F32Z6MW4zJPsiWPhi1Afr4JoKTNXkx8WllOk0lgAx # zMSPKeaMK6bC5uuCG/riSRZN26rIkwY8wqLBbKy1k7rDX1cgAd1IyPBdAaaQOo/p # yVdNhFhSa0nfjC8Szehy0MTdvcrHDjCRCxwCIrNQUg0lmXUf4SAf6QbfrwbN5s4a # acHOX+Te6+mRNzyPnggtXSj9fwnlP3Ox9HEHCqLOOF9tYpOZp6otnZNRA1uFS6uO # I5oby/ZLAgFbehzE7PtMTINGIdeXA85Wj59Z163eiB/3sxeREJcljafVvOjZoYIC # ojCCAp4GCSqGSIb3DQEJBjGCAo8wggKLAgEBMGgwUjELMAkGA1UEBhMCQkUxGTAX # BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExKDAmBgNVBAMTH0dsb2JhbFNpZ24gVGlt # ZXN0YW1waW5nIENBIC0gRzICEhEh1pmnZJc+8fhCfukZzFNBFDAJBgUrDgMCGgUA # oIH9MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE2 # MDgyNDE1NTQwOVowIwYJKoZIhvcNAQkEMRYEFDGOXobqERN7agCqh3XATVY1QN4D # MIGdBgsqhkiG9w0BCRACDDGBjTCBijCBhzCBhAQUY7gvq2H1g5CWlQULACScUCkz # 7HkwbDBWpFQwUjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt # c2ExKDAmBgNVBAMTH0dsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0gRzICEhEh # 1pmnZJc+8fhCfukZzFNBFDANBgkqhkiG9w0BAQEFAASCAQBh5jh6FRAR6391I9zY # svYjbb7Phel/7er4eo8GiytjqWPnIoltgUvC/+GXC0i91UIPQ3mgNhBs3cwVj3wK # 5rEkOLTAPFiDO3fNsGfk4H0npFNithzIHBVrktsRxciqY9tsWrPzQswTvGjeRzDC # fVQbFhW/NSb/cGGye9+lR/3KTLiMrEauNXc2dYfxFDymVMZmQqFJVlT/Bp+fKYW8 # LjseRqfUmntK2zAxeRNoIP0VGZQHLJyLZ9AwwuQmzgmobU6x74snMGrPuP7JDHoS # uOKzS5vvqIdjR7pbMkx6X8XYxRn79SXBnfgjRfxQyKfQ07hR6TqmQutveh6PeLbE # ktMB # SIG # End signature block |