internal/ConvertTo-PsString.ps1
<# .SYNOPSIS Convert PowerShell data types to PowerShell string syntax. .DESCRIPTION .EXAMPLE PS C:\>ConvertTo-PsString @{ key1='value1'; key2='value2' } Convert hashtable to PowerShell string. .INPUTS System.String .LINK https://github.com/jasoth/Utility.PS #> function ConvertTo-PsString { [CmdletBinding()] [OutputType([string])] param ( # [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [AllowNull()] [object] $InputObjects, # [Parameter(Mandatory = $false)] [switch] $Compact, # [Parameter(Mandatory = $false, Position = 1)] [type[]] $RemoveTypes = ([string], [bool], [int], [long]), # [Parameter(Mandatory = $false)] [switch] $NoEnumerate ) begin { if ($Compact) { [System.Collections.Generic.Dictionary[string, type]] $TypeAccelerators = [psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')::get [System.Collections.Generic.Dictionary[type, string]] $TypeAcceleratorsLookup = New-Object 'System.Collections.Generic.Dictionary[type,string]' foreach ($TypeAcceleratorKey in $TypeAccelerators.Keys) { if (!$TypeAcceleratorsLookup.ContainsKey($TypeAccelerators[$TypeAcceleratorKey])) { $TypeAcceleratorsLookup.Add($TypeAccelerators[$TypeAcceleratorKey], $TypeAcceleratorKey) } } } function Resolve-Type { param ( # [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [type] $ObjectType, # [Parameter(Mandatory = $false, Position = 1)] [switch] $Compact, # [Parameter(Mandatory = $false, Position = 1)] [type[]] $RemoveTypes ) [string] $OutputString = '' if ($ObjectType.IsGenericType -or ($ObjectType.BaseType -and $ObjectType.BaseType.IsGenericType)) { if (!$ObjectType.IsGenericType) { $ObjectType = $ObjectType.BaseType } if ($ObjectType.FullName.StartsWith('System.Collections.Generic.Dictionary')) { #$OutputString += '[hashtable]' if ($Compact) { $OutputString += '(Invoke-Command { $D = New-Object ''Collections.Generic.Dictionary[' } else { $OutputString += '(Invoke-Command { $D = New-Object ''System.Collections.Generic.Dictionary[' } $iInput = 0 foreach ($GenericTypeArgument in $ObjectType.GenericTypeArguments) { if ($iInput -gt 0) { $OutputString += ',' } $OutputString += Resolve-Type $GenericTypeArgument -Compact:$Compact -RemoveTypes @() $iInput++ } $OutputString += ']''' } elseif ($InputObject.GetType().FullName -match '^(System.(Collections.Generic.[a-zA-Z]+))`[0-9]\[(?:\[(.+?), .+?, Version=.+?, Culture=.+?, PublicKeyToken=.+?\],?)+?\]$') { if ($Compact) { $OutputString += '[{0}[' -f $Matches[2] } else { $OutputString += '[{0}[' -f $Matches[1] } $iInput = 0 foreach ($GenericTypeArgument in $ObjectType.GenericTypeArguments) { if ($iInput -gt 0) { $OutputString += ',' } $OutputString += Resolve-Type $GenericTypeArgument -Compact:$Compact -RemoveTypes @() $iInput++ } $OutputString += ']]' } } elseif ($ObjectType -eq [System.Collections.Specialized.OrderedDictionary]) { $OutputString += '[ordered]' # Explicit cast does not work with full name. Only [ordered] works. } elseif ($Compact) { if ($ObjectType -notin $RemoveTypes) { if ($TypeAcceleratorsLookup.ContainsKey($ObjectType)) { $OutputString += '[{0}]' -f $TypeAcceleratorsLookup[$ObjectType] } elseif ($ObjectType.FullName.StartsWith('System.')) { $OutputString += '[{0}]' -f $ObjectType.FullName.Substring(7) } else { $OutputString += '[{0}]' -f $ObjectType.FullName } } } else { $OutputString += '[{0}]' -f $ObjectType.FullName } return $OutputString } function GetPSString ($InputObject) { $OutputString = New-Object System.Text.StringBuilder if ($null -eq $InputObject) { [void]$OutputString.Append('$null') } else { ## Add Casting [void]$OutputString.Append((Resolve-Type $InputObject.GetType() -Compact:$Compact -RemoveTypes $RemoveTypes)) ## Add Value switch ($InputObject.GetType()) { { $_.Equals([String]) } { [void]$OutputString.AppendFormat("'{0}'", $InputObject.Replace("'", "''")) #.Replace('"','`"') break } { $_.Equals([Char]) } { [void]$OutputString.AppendFormat("'{0}'", ([string]$InputObject).Replace("'", "''")) break } { $_.Equals([Boolean]) -or $_.Equals([switch]) } { [void]$OutputString.AppendFormat('${0}', $InputObject) break } { $_.Equals([DateTime]) } { [void]$OutputString.AppendFormat("'{0}'", $InputObject.ToString('O')) break } { $_.Equals([guid]) } { [void]$OutputString.AppendFormat("'{0}'", $InputObject) break } { $_.BaseType -and $_.BaseType.Equals([Enum]) } { [void]$OutputString.AppendFormat('::{0}', $InputObject) break } { $_.BaseType -and $_.BaseType.Equals([ValueType]) } { [void]$OutputString.AppendFormat('{0}', $InputObject) break } { $_.BaseType.Equals([System.IO.FileSystemInfo]) -or $_.Equals([System.Uri]) } { [void]$OutputString.AppendFormat("'{0}'", $InputObject.ToString().Replace("'", "''")) #.Replace('"','`"') break } { $_.Equals([System.Xml.XmlDocument]) } { [void]$OutputString.AppendFormat("'{0}'", $InputObject.OuterXml.Replace("'", "''")) #.Replace('"','""') break } { $_.Equals([Hashtable]) -or $_.Equals([System.Collections.Specialized.OrderedDictionary]) } { [void]$OutputString.Append('@{') $iInput = 0 foreach ($enumHashtable in $InputObject.GetEnumerator()) { if ($iInput -gt 0) { [void]$OutputString.Append(';') } [void]$OutputString.AppendFormat('{0}={1}', (ConvertTo-PsString $enumHashtable.Key -Compact:$Compact -NoEnumerate), (ConvertTo-PsString $enumHashtable.Value -Compact:$Compact -NoEnumerate)) $iInput++ } [void]$OutputString.Append('}') break } { $_.FullName.StartsWith('System.Collections.Generic.Dictionary') -or ($_.BaseType -and $_.BaseType.FullName.StartsWith('System.Collections.Generic.Dictionary')) } { $iInput = 0 foreach ($enumHashtable in $InputObject.GetEnumerator()) { [void]$OutputString.AppendFormat('; $D.Add({0},{1})', (ConvertTo-PsString $enumHashtable.Key -Compact:$Compact -NoEnumerate), (ConvertTo-PsString $enumHashtable.Value -Compact:$Compact -NoEnumerate)) $iInput++ } [void]$OutputString.Append('; $D })') break } { $_.BaseType -and $_.BaseType.Equals([Array]) } { [void]$OutputString.Append('(Write-Output @(') $iInput = 0 for ($iInput = 0; $iInput -lt $InputObject.Count; $iInput++) { if ($iInput -gt 0) { [void]$OutputString.Append(',') } [void]$OutputString.Append((ConvertTo-PsString $InputObject[$iInput] -Compact:$Compact -RemoveTypes $InputObject.GetType().DeclaredMembers.Where( { $_.Name -eq 'Set' })[0].GetParameters()[1].ParameterType -NoEnumerate)) } [void]$OutputString.Append(') -NoEnumerate)') break } { $_.Equals([System.Collections.ArrayList]) } { [void]$OutputString.Append('@(') $iInput = 0 for ($iInput = 0; $iInput -lt $InputObject.Count; $iInput++) { if ($iInput -gt 0) { [void]$OutputString.Append(',') } [void]$OutputString.Append((ConvertTo-PsString $InputObject[$iInput] -Compact:$Compact -NoEnumerate)) } [void]$OutputString.Append(')') break } { $_.FullName.StartsWith('System.Collections.Generic.List') } { [void]$OutputString.Append('@(') $iInput = 0 for ($iInput = 0; $iInput -lt $InputObject.Count; $iInput++) { if ($iInput -gt 0) { [void]$OutputString.Append(',') } [void]$OutputString.Append((ConvertTo-PsString $InputObject[$iInput] -Compact:$Compact -RemoveTypes $_.GenericTypeArguments -NoEnumerate)) } [void]$OutputString.Append(')') break } ## Convert objects with object initializers { $_ -is [object] -and ($_.GetConstructors() | ForEach-Object { if ($_.IsPublic -and !$_.GetParameters()) { $true } }) } { [void]$OutputString.Append('@{') $iInput = 0 foreach ($Item in ($InputObject | Get-Member -MemberType Property, NoteProperty)) { if ($iInput -gt 0) { [void]$OutputString.Append(';') } $PropertyName = $Item.Name [void]$OutputString.AppendFormat('{0}={1}', (ConvertTo-PsString $PropertyName -Compact:$Compact -NoEnumerate), (ConvertTo-PsString $InputObject.$PropertyName -Compact:$Compact -NoEnumerate)) $iInput++ } [void]$OutputString.Append('}') break } Default { $Exception = New-Object ArgumentException -ArgumentList ('Cannot convert input of type {0} to PowerShell string.' -f $InputObject.GetType()) Write-Error -Exception $Exception -Category ([System.Management.Automation.ErrorCategory]::ParserError) -CategoryActivity $MyInvocation.MyCommand -ErrorId 'ConvertPowerShellStringFailureTypeNotSupported' -TargetObject $InputObject } } } if ($NoEnumerate) { $listOutputString.Add($OutputString.ToString()) } else { Write-Output $OutputString.ToString() } } if ($NoEnumerate) { $listOutputString = New-Object System.Collections.Generic.List[string] } } process { if ($PSCmdlet.MyInvocation.ExpectingInput -or $NoEnumerate -or $null -eq $InputObjects) { GetPSString $InputObjects } else { foreach ($InputObject in $InputObjects) { GetPSString $InputObject } } } end { if ($NoEnumerate) { if (($null -eq $InputObjects -and $listOutputString.Count -eq 0) -or $listOutputString.Count -gt 1) { Write-Warning ('To avoid losing strong type on outermost enumerable type when piping, use "Write-Output $Array -NoEnumerate | {0}".' -f $MyInvocation.MyCommand) $OutputArray = New-Object System.Text.StringBuilder [void]$OutputArray.Append('(Write-Output @(') if ($PSVersionTable.PSVersion -ge [version]'6.0') { [void]$OutputArray.AppendJoin(',', $listOutputString) } else { [void]$OutputArray.Append(($listOutputString -join ',')) } [void]$OutputArray.Append(') -NoEnumerate)') Write-Output $OutputArray.ToString() } else { Write-Output $listOutputString[0] } } } } # SIG # Begin signature block # MIInsQYJKoZIhvcNAQcCoIInojCCJ54CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBxU9l7McIp2jsc # hQKpt/mambJXJuFblwFfU71mjZIeHaCCDYUwggYDMIID66ADAgECAhMzAAACU+OD # 3pbexW7MAAAAAAJTMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMzAwWhcNMjIwOTAxMTgzMzAwWjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDLhxHwq3OhH+4J+SX4qS/VQG8HybccH7tnG+BUqrXubfGuDFYPZ29uCuHfQlO1 # lygLgMpJ4Geh6/6poQ5VkDKfVssn6aA1PCzIh8iOPMQ9Mju3sLF9Sn+Pzuaie4BN # rp0MuZLDEXgVYx2WNjmzqcxC7dY9SC3znOh5qUy2vnmWygC7b9kj0d3JrGtjc5q5 # 0WfV3WLXAQHkeRROsJFBZfXFGoSvRljFFUAjU/zdhP92P+1JiRRRikVy/sqIhMDY # +7tVdzlE2fwnKOv9LShgKeyEevgMl0B1Fq7E2YeBZKF6KlhmYi9CE1350cnTUoU4 # YpQSnZo0YAnaenREDLfFGKTdAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUlZpLWIccXoxessA/DRbe26glhEMw # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ2NzU5ODAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AKVY+yKcJVVxf9W2vNkL5ufjOpqcvVOOOdVyjy1dmsO4O8khWhqrecdVZp09adOZ # 8kcMtQ0U+oKx484Jg11cc4Ck0FyOBnp+YIFbOxYCqzaqMcaRAgy48n1tbz/EFYiF # zJmMiGnlgWFCStONPvQOBD2y/Ej3qBRnGy9EZS1EDlRN/8l5Rs3HX2lZhd9WuukR # bUk83U99TPJyo12cU0Mb3n1HJv/JZpwSyqb3O0o4HExVJSkwN1m42fSVIVtXVVSa # YZiVpv32GoD/dyAS/gyplfR6FI3RnCOomzlycSqoz0zBCPFiCMhVhQ6qn+J0GhgR # BJvGKizw+5lTfnBFoqKZJDROz+uGDl9tw6JvnVqAZKGrWv/CsYaegaPePFrAVSxA # yUwOFTkAqtNC8uAee+rv2V5xLw8FfpKJ5yKiMKnCKrIaFQDr5AZ7f2ejGGDf+8Tz # OiK1AgBvOW3iTEEa/at8Z4+s1CmnEAkAi0cLjB72CJedU1LAswdOCWM2MDIZVo9j # 0T74OkJLTjPd3WNEyw0rBXTyhlbYQsYt7ElT2l2TTlF5EmpVixGtj4ChNjWoKr9y # TAqtadd2Ym5FNB792GzwNwa631BPCgBJmcRpFKXt0VEQq7UXVNYBiBRd+x4yvjqq # 5aF7XC5nXCgjbCk7IXwmOphNuNDNiRq83Ejjnc7mxrJGMIIHejCCBWKgAwIBAgIK # 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/Xmfwb1tbWrJUnMTDXpQzTGCGYIwghl+AgEBMIGVMH4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAJT44Pelt7FbswAAAAA # AlMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIIOb # fRz8LI36bQo3AN1dmW/h3cYJJn/yMdm9VP0v7hYGMEIGCisGAQQBgjcCAQwxNDAy # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20wDQYJKoZIhvcNAQEBBQAEggEArQzwIDkTxg9fuKpBV/NjRxya0FlG6D8CkcQP # /DI8qCxeNc09wN1FZiDLf81eli3yDoTU9/cN0415CthMomkUNWRq2Q7AQR1fkg/q # M76xgvkuoOUb6OVrauU8BAXNq8OVe8UDT/Bisoe2Am3O0Gv5cZOwxOcPfeYvSNJ5 # 8UCcoiXNmwAoDBPK/oX0IvGUAIC5sQ/Fpp1S5+911dmcDRy7fVDJqFaBx8D1oJt9 # n5PN3tUUKfhapL5TF2ap6xOa2TcGKkGPZ5ZswCzcojPFeIccPAjh8LiqDYh7IFtx # o1RWTyHFNLNV0NuTMJzucej2ilx6MOcuZ2OPn9b0rXYmu4vdnKGCFwwwghcIBgor # BgEEAYI3AwMBMYIW+DCCFvQGCSqGSIb3DQEHAqCCFuUwghbhAgEDMQ8wDQYJYIZI # AWUDBAIBBQAwggFVBgsqhkiG9w0BCRABBKCCAUQEggFAMIIBPAIBAQYKKwYBBAGE # WQoDATAxMA0GCWCGSAFlAwQCAQUABCAj0Lenj9e1VtWHZZb6dCPwfSEnKWXNFlUD # c/jcC8eVsgIGYi/ZMxAcGBMyMDIyMDQyMTAwMjk0NC4yOTlaMASAAgH0oIHUpIHR # MIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQL # EyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhh # bGVzIFRTUyBFU046RDlERS1FMzlBLTQzRkUxJTAjBgNVBAMTHE1pY3Jvc29mdCBU # aW1lLVN0YW1wIFNlcnZpY2WgghFfMIIHEDCCBPigAwIBAgITMwAAAaxmvIciXd49 # ewABAAABrDANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg # MjAxMDAeFw0yMjAzMDIxODUxMjlaFw0yMzA1MTExODUxMjlaMIHOMQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQg # T3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046 # RDlERS1FMzlBLTQzRkUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNl # cnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDHeAtQxRdi7sdx # zCvABJTHUxeIhvUTsikFhXoU13vhF9UDq0wRZ4TACjRyEFqMZCtVutv6EEEJrSB6 # PLKYTLdVqZCzbwpty2vLHVS97fwQMe1FpJn77oydyg2koLd3JXObjT1I+3t9lOJ/ # xKfaDnPj7/xB3O1xh9Xxkby0WM8KMT9cZCpXrrGyM0/2ip+lgtgYID84x14p/ShO # 5K4grqgPiTYbJJHnUxyUCKLW5Ufq2XLHsU0pozvme0dJn3h4lPA57b2b2f/WnfV1 # IQ8FCRSmfGWb8Z6p2V8BWJAyjWoGPINOgRdbw7pW5QLOgOIbj9Xu6bShaaQdVWZC # 1AJiFtccSRrN5HonQE1iFcdtrBlcnpmk9vTX7Q6f40bA8P2ocL9TZL+lr8pKLytJ # AzyGPUwlvXEW71HhJZPvglTO3CKq5fEGN5oBEPKIuOVcxAV7mNOGNSoo2xi2ERTV # MqVzEQwKVfpHIxvLkk9d5kgn9ojIVkUS8/f48iMHu5Zl8+M1MmHJK/tjZvBq0quX # 1QD7ISDvAG/2jqOv6Htxt2PnIpfIskSSyTcWzGMYkCSmb28ZQiKfqRiJ2g9d+9zO # yjzxf8l3k+IRtC6lyr3pZILZac3nz65lFbqY2E4Hhn7qVMBc8pkpOCUTTtbYUQdG # wygyMjTFahLr1dVMXXK4nFdKI4HiRwIDAQABo4IBNjCCATIwHQYDVR0OBBYEFFgR # n3cEyx9AZ0o8fElamFrAQI5NMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1 # GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w # a2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEp # LmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWlj # cm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUy # MFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYB # BQUHAwgwDQYJKoZIhvcNAQELBQADggIBAHnQtQJYVVxwpXZPLaCMwFvUMiE3EXso # VKbNbg+u8wgt9PH0c2BREv9rzF+6NDmyYMwsU9Z4tL5HLPFhtjFCLJPdUQjyHg80 # 0CLSKY/WU8/YdLbn3Chpt2oZJ0bNYaFddo0RZHGqlyaNX7MrqCoA/hU09pTr6xLD # YyYecBLIvjwf5lZofyWtFbvI4VCXNYawVEOWIrEODdNLJ2cITqAnj123Q+hxrNXJ # rF2W65E/LzT2FfC5yOJcbif2GmEttKkK+mPQyBxQzWMWW05bEHl7Pyo54UTXRYgh # qAHCx1sHlnkbM4dolITH2Nf+/Xe7KJn48emciT2Tq+HxNFE9pf6wWgU66D6Qzr6W # jrGOhP7XiyzH8p6+lDkHhOJUYsOfbIlRsgBqqUwU23cwBSwRR+NLm6+1RJXZo4h2 # teBJGcWL3IMysSqrm+Mqymn6P4/WlG8C6y9lTB1nKWtfCYb+syI3dNSBpFHY91Cf # iSkDQM+Xsj8kEmT7fcLPG8p6HRpTOZ2JBwcu6z74+Ocvmc+46y4I4L2SIsRrM8Ki # siieOwDx8ax/BowkLrG71vTReCwGCqGWRo+z8JkAPl5sA+bX1ENCrszERZjKTlM7 # YkwICY0H/UzLnN6WJqRVhK/JLGHcK463VmACwlwPyEFxHQIrEMI+WM07IeEMU1Kv # r0UsbPd8gd5yMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg # VGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+ # F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU # 88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqY # O7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzp # cGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0Xn # Rm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1 # zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZN # N3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLR # vWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTY # uVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUX # k8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB # 2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKR # PEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0g # BFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5t # aWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQM # MAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQE # AwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQ # W9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNv # bS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBa # BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqG # SIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOX # PTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6c # qYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/z # jj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz # /AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyR # gNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdU # bZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo # 3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4K # u+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10Cga # iQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9 # vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGC # AtIwggI7AgEBMIH8oYHUpIHRMIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8g # UmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046RDlERS1FMzlBLTQzRkUxJTAj # BgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMC # GgMVALEa0hOwuLBJ/egDIYzZF2dGNYqgoIGDMIGApH4wfDELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt # U3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQEFBQACBQDmCx61MCIYDzIwMjIwNDIx # MDQwNzE3WhgPMjAyMjA0MjIwNDA3MTdaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIF # AOYLHrUCAQAwCgIBAAICD94CAf8wBwIBAAICEuQwCgIFAOYMcDUCAQAwNgYKKwYB # BAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGG # oDANBgkqhkiG9w0BAQUFAAOBgQBy/5/7nQNDLVPjAmYSkG1Hq4eRteIxKzvwfwcE # YxX7YEyuiEmNyKGZoTmCSbwrQL6efXnAEMhxydOZhOgyvsw0yYZy2+HKVUzK/35w # 6qk0z7FHQZV5DPCG+zG203lS1cu0E8eQ414u1pfxM0MY351fs87u/WgyxFKv11Rq # DvzYAjGCBA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw # AhMzAAABrGa8hyJd3j17AAEAAAGsMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG # 9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIK5VTlRXKRRqcazv # iYQpOjK3r/xUXhllv6NVJlfjAleBMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCB # vQQg+bcBkoM4LwlxAHK1c+epu/T6fm0CX/tPi4Nn2gQswvUwgZgwgYCkfjB8MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy # b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAaxmvIciXd49ewABAAABrDAi # BCDpi5SwpegfRkjqZop8Xuj/gQ1loWa2aR1BLvoYy1LjKzANBgkqhkiG9w0BAQsF # AASCAgBSTXmDB1dWqk+HaraLbj/NuTjuIwwHBlQKhue+h2XTVYe7czyEOTNyRB64 # dqs5BDtnuYUQRrrtHC2D2noSyJ/OWhWGkvN8vhMV7FensRu474brtTfkU5kNJbQv # oJifObfpldzsP5ncaTVyR7m4CZlny6KO2a7qpR0K6ORHhKAuTYK6zRYeSNBgGQTG # 4x0US3eIk0/oWLGY0fzpdaQkqC7iNYCCtLH3rm3wnGeJhqDp74iuL2TEkpWjgF2w # kKUFC3f7j52ajd5iFSA/mo2sml6kwvFpq0r+m47FlK0eQNAxBa1zThO/Z5RZV+jN # v5FHUOZe5fTMqBPsXL1KuIQ2vKgmZdoyQalppidI8/DYq0DkVhMKriwetDMeeIpu # hCpP8MBxp8Y2FbWBFuCHWDg5ZwQo1u5Oty0W4cpWiJoeIC9S0RZTM+Mf59uGmIDX # X1+x3xwg5NQJf2dffih6ButzggoZG+BGdBmeTr3lScuRcH9yqN98RCRrxMFMlsU/ # lVYBCKayO5CfG/dQ4f/mu2SlNSWfIminiULRF2zXQr1i6mnQvOkbnf0RNIx6Cc0D # Q6oB/Sp9h2uj1IvhQqryFwOCM1VCb6KIEW9qdtdLJbWSUY56aYcJDAfhFozfghXv # jseClm58XYXPFDYNlnSGcqeW4SGwcbPR3Ov4zK7ufB/l6gkGlQ== # SIG # End signature block |