Migrate.Autorest/custom/Set-AzMigrateLocalServerReplication.ps1
# ---------------------------------------------------------------------------------- # # Copyright Microsoft Corporation # 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. # ---------------------------------------------------------------------------------- <# .Synopsis Updates the target properties for the replicating server. .Description The Set-AzMigrateLocalServerReplication cmdlet updates the target properties for the replicating server. .Link https://learn.microsoft.com/powershell/module/az.migrate/set-azmigratelocalserverreplication #> function Set-AzMigrateLocalServerReplication { [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Runtime.PreviewMessageAttribute("This cmdlet is using a preview API version and is subject to breaking change in a future release.")] [OutputType([Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.IJobModel])] [CmdletBinding(DefaultParameterSetName = 'ById', PositionalBinding = $false, SupportsShouldProcess, ConfirmImpact='Medium')] param( [Parameter(Mandatory)] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Path')] [System.String] # Specifies the replicating server for which the properties need to be updated. The ID should be retrieved using the Get-AzMigrateLocalServerReplication cmdlet. ${TargetObjectID}, [Parameter()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Path')] [System.Int32] # Specifies the number of CPU cores. ${TargetVMCPUCore}, [Parameter()] [ValidateSet("true" , "false")] [ArgumentCompleter( { "true" , "false" })] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Path')] [System.String] # Specifies if RAM is dynamic or not. ${IsDynamicMemoryEnabled}, [Parameter()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Path')] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.ProtectedItemDynamicMemoryConfig] # Specifies the dynamic memory configration of RAM. ${DynamicMemoryConfig}, [Parameter()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Path')] [System.Int64] # Specifies the target RAM size in MB. ${TargetVMRam}, [Parameter()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Path')] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.AzLocalNicInput[]] # Specifies the nics on the source server to be included for replication. ${NicToInclude}, [Parameter()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Path')] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Runtime.DefaultInfo(Script = '(Get-AzContext).Subscription.Id')] [System.String] # The subscription Id. ${SubscriptionId}, [Parameter()] [Alias('AzureRMContext', 'AzureCredential')] [ValidateNotNull()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Azure')] [System.Management.Automation.PSObject] # The credentials, account, tenant, and subscription used for communication with Azure. ${DefaultProfile}, [Parameter(DontShow)] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Runtime')] [System.Management.Automation.SwitchParameter] # Wait for .NET debugger to attach ${Break}, [Parameter(DontShow)] [ValidateNotNull()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Runtime')] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Runtime.SendAsyncStep[]] # SendAsync Pipeline Steps to be appended to the front of the pipeline ${HttpPipelineAppend}, [Parameter(DontShow)] [ValidateNotNull()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Runtime')] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Runtime.SendAsyncStep[]] # SendAsync Pipeline Steps to be prepended to the front of the pipeline ${HttpPipelinePrepend}, [Parameter(DontShow)] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Runtime')] [System.Uri] # The URI for the proxy server to use ${Proxy}, [Parameter(DontShow)] [ValidateNotNull()] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Runtime')] [System.Management.Automation.PSCredential] # Credentials for a proxy server to use for the remote call ${ProxyCredential}, [Parameter(DontShow)] [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Category('Runtime')] [System.Management.Automation.SwitchParameter] # Use the default credentials for the proxy ${ProxyUseDefaultCredentials} ) process { Import-Module $PSScriptRoot\Helper\AzLocalCommonSettings.ps1 Import-Module $PSScriptRoot\Helper\CommonHelper.ps1 CheckResourcesModuleDependency $HasTargetVMCPUCore = $PSBoundParameters.ContainsKey('TargetVMCPUCore') $HasTargetVMRam = $PSBoundParameters.ContainsKey('TargetVMRam') $HasDynamicMemoryConfig = $PSBoundParameters.ContainsKey('DynamicMemoryConfig') $HasNicToInclude = $PSBoundParameters.ContainsKey('NicToInclude') $HasIsDynamicMemoryEnabled = $PSBoundParameters.ContainsKey('IsDynamicMemoryEnabled') if ($HasIsDynamicMemoryEnabled) { $isDynamicRamEnabled = [System.Convert]::ToBoolean($IsDynamicMemoryEnabled) } $null = $PSBoundParameters.Remove('TargetVMCPUCore') $null = $PSBoundParameters.Remove('IsDynamicMemoryEnabled') $null = $PSBoundParameters.Remove('DynamicMemoryConfig') $null = $PSBoundParameters.Remove('TargetVMRam') $null = $PSBoundParameters.Remove('NicToInclude') $null = $PSBoundParameters.Remove('TargetObjectID') $null = $PSBoundParameters.Remove('WhatIf') $null = $PSBoundParameters.Remove('Confirm') $ProtectedItemIdArray = $TargetObjectID.Split("/") $ResourceGroupName = $ProtectedItemIdArray[4] $VaultName = $ProtectedItemIdArray[8] $MachineName = $ProtectedItemIdArray[10] # Get existing Protected Item $null = $PSBoundParameters.Add("ResourceGroupName", $ResourceGroupName) $null = $PSBoundParameters.Add("VaultName", $VaultName) $null = $PSBoundParameters.Add("Name", $MachineName) $ProtectedItem = InvokeAzMigrateGetCommandWithRetries ` -CommandName 'Az.Migrate.Internal\Get-AzMigrateProtectedItem' ` -Parameters $PSBoundParameters ` -ErrorMessage "Replication item is not found with Id '$TargetObjectID'." $null = $PSBoundParameters.Remove("ResourceGroupName") $null = $PSBoundParameters.Remove("VaultName") $null = $PSBoundParameters.Remove("Name") $protectedItemProperties = $ProtectedItem.Property $customProperties = $protectedItemProperties.CustomProperty $MachineIdArray = $customProperties.FabricDiscoveryMachineId.Split("/") $SiteType = $MachineIdArray[7] $SiteName = $MachineIdArray[8] # No "DisableProtection" means IR has not been initiated # "CommitFailover" means migration has been completed if (!$protectedItemProperties.AllowedJob.Contains('DisableProtection') -or $protectedItemProperties.AllowedJob.Contains('CommitFailover')) { throw "Set server replication is not allowed for this item '$TargetObjectID' at the moment. Please check its status and try again later." } if ($SiteType -eq $SiteTypes.HyperVSites) { $customPropertiesUpdate = [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.HyperVToAzStackHCIProtectedItemModelCustomPropertiesUpdate]::new() $customPropertiesUpdate.InstanceType = $AzLocalInstanceTypes.HyperVToAzLocal } elseif ($SiteType -eq $SiteTypes.VMwareSites) { $customPropertiesUpdate = [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.VMwareToAzStackHCIProtectedItemModelCustomPropertiesUpdate]::new() $customPropertiesUpdate.InstanceType = $AzLocalInstanceTypes.VMwareToAzLocal } # Update target CPU core if ($HasTargetVMCPUCore) { if ($TargetVMCPUCore -le 0) { throw "Specify target CPU core greater than 0" } $customPropertiesUpdate.TargetCpuCore = $TargetVMCPUCore } # Update VM Ram if ($HasTargetVMRam) { if ($TargetVMRam -le 0) { throw "Specify target RAM greater than 0" } $customPropertiesUpdate.TargetMemoryInMegaByte = $TargetVMRam } $targetMemory = $customPropertiesUpdate.TargetMemoryInMegaByte -or $customProperties.TargetMemoryInMegaByte # Update IsDynamicRam if ($HasIsDynamicMemoryEnabled) { $customPropertiesUpdate.IsDynamicRam = $isDynamicRamEnabled } elseif ($HasDynamicMemoryConfig) { $customPropertiesUpdate.IsDynamicRam = $customProperties.IsDynamicRam } # Dynamic memory is enabled - set provided configuration if ($customPropertiesUpdate.IsDynamicRam -and $HasDynamicMemoryConfig) { if ($targetMemory -lt $DynamicMemoryConfig.MinimumMemoryInMegaByte) { throw "DynamicMemoryConfig - Specify minimum memory less than $($targetMemory)" } if ($targetMemory -gt $DynamicMemoryConfig.MaximumMemoryInMegaByte) { throw "DynamicMemoryConfig - Specify maximum memory greater than $($targetMemory)" } if ($DynamicMemoryConfig.TargetMemoryBufferPercentage -NotIn $RAMConfig.MinTargetMemoryBufferPercentage..$RAMConfig.MaxTargetMemoryBufferPercentage) { throw "DynamicMemoryConfig - Specify target memory buffer percentage between $($RAMConfig.MinTargetMemoryBufferPercentage) % and $($RAMConfig.MaxTargetMemoryBufferPercentage) %." } $customPropertiesUpdate.DynamicMemoryConfig = $DynamicMemoryConfig } # Dynamic memory is enabled - set default configuration if ($customPropertiesUpdate.IsDynamicRam -and !$HasDynamicMemoryConfig) { if ($null -eq $customProperties.DynamicMemoryConfig) { $memoryConfig = [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.ProtectedItemDynamicMemoryConfig]::new() $memoryConfig.MinimumMemoryInMegaByte = [System.Math]::Min($targetMemory, $RAMConfig.DefaultMinDynamicMemoryInMB) $memoryConfig.MaximumMemoryInMegaByte = [System.Math]::Max($targetMemory, $RAMConfig.DefaultMaxDynamicMemoryInMB) $memoryConfig.TargetMemoryBufferPercentage = $RAMConfig.DefaultTargetMemoryBufferPercentage $customPropertiesUpdate.DynamicMemoryConfig = $memoryConfig } else { $customPropertiesUpdate.DynamicMemoryConfig = $customProperties.DynamicMemoryConfig } } # Update Nics if ($HasNicToInclude -and $NicToInclude.length -gt 0) { # Get discovered machine $null = $PSBoundParameters.Add("ResourceGroupName", $ResourceGroupName) $null = $PSBoundParameters.Add("SiteName", $SiteName) $null = $PSBoundParameters.Add("MachineName", $MachineName) if ($SiteType -eq $SiteTypes.HyperVSites) { $machine = InvokeAzMigrateGetCommandWithRetries ` -CommandName 'Az.Migrate.Internal\Get-AzMigrateHyperVMachine' ` -Parameters $PSBoundParameters ` -ErrorMessage "Machine '$MachineName' not found in resource group '$ResourceGroupName' and site '$SiteName'." } elseif ($SiteType -eq $SiteTypes.VMwareSites) { $machine = InvokeAzMigrateGetCommandWithRetries ` -CommandName 'Az.Migrate.Internal\Get-AzMigrateMachine' ` -Parameters $PSBoundParameters ` -ErrorMessage "Machine '$MachineName' not found in resource group '$ResourceGroupName' and site '$SiteName'." } $null = $PSBoundParameters.Remove("ResourceGroupName") $null = $PSBoundParameters.Remove("SiteName") $null = $PSBoundParameters.Remove("MachineName") # Nics [PSCustomObject[]]$nics = @() [PSCustomObject[]]$uniqueNics = @() foreach ($nic in $NicToInclude) { $discoveredNic = $machine.NetworkAdapter | Where-Object { $_.NicId -eq $nic.NicId } if ($null -eq $discoveredNic) { throw "The Nic id '$($nic.NicId)' is not found." } if ($uniqueNics.Contains($nic.NicId)) { throw "The Nic id '$($nic.NicId)' is already included. Please remove the duplicate entry and try again." } $uniqueNics += $nic.NicId $htNic = @{} $nic.PSObject.Properties | ForEach-Object { $htNic[$_.Name] = $_.Value } if ($htNic.SelectionTypeForFailover -eq $VMNicSelection.SelectedByUser -and [string]::IsNullOrEmpty($htNic.TargetNetworkId)) { throw "The TargetVirtualSwitchId parameter is required when the CreateAtTarget flag is set to 'true'. NIC '$($htNic.NicId)'. Please utilize the New-AzMigrateLocalNicMappingObject command to properly create a Nic mapping object." } $nics += [PSCustomObject]$htNic } if ($SiteType -eq $SiteTypes.HyperVSites) { $customPropertiesUpdate.NicsToInclude = [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.HyperVToAzStackHCINicInput[]]$nics } elseif ($SiteType -eq $SiteTypes.VMwareSites) { $customPropertiesUpdate.NicsToInclude = [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.VMwareToAzStackHCINicInput[]]$nics } } $protectedItemPropertiesUpdate = [Microsoft.Azure.PowerShell.Cmdlets.Migrate.Models.Api20240901.ProtectedItemModelPropertiesUpdate]::new() $protectedItemPropertiesUpdate.CustomProperty = $customPropertiesUpdate $null = $PSBoundParameters.Add('ResourceGroupName', $ResourceGroupName) $null = $PSBoundParameters.Add('VaultName', $vaultName) $null = $PSBoundParameters.Add('Name', $MachineName) $null = $PSBoundParameters.Add('Property', $protectedItemPropertiesUpdate) $null = $PSBoundParameters.Add('NoWait', $true) if ($PSCmdlet.ShouldProcess($TargetObjectID, "Updates VM replication.")) { $operation = Az.Migrate.Internal\Update-AzMigrateProtectedItem @PSBoundParameters $jobName = $operation.Target.Split("/")[-1].Split("?")[0].Split("_")[0] $null = $PSBoundParameters.Remove('Name') $null = $PSBoundParameters.Remove('Property') $null = $PSBoundParameters.Remove('NoWait') $null = $PSBoundParameters.Add('JobName', $jobName) return Az.Migrate.Internal\Get-AzMigrateLocalReplicationJob @PSBoundParameters } } } # SIG # Begin signature block # MIIoUQYJKoZIhvcNAQcCoIIoQjCCKD4CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAamq+nBxJGSgzz # WX/o5LEX5fCg4jItLyVyxb8TorOchqCCDYUwggYDMIID66ADAgECAhMzAAAEA73V # lV0POxitAAAAAAQDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTEzWhcNMjUwOTExMjAxMTEzWjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQCfdGddwIOnbRYUyg03O3iz19XXZPmuhEmW/5uyEN+8mgxl+HJGeLGBR8YButGV # LVK38RxcVcPYyFGQXcKcxgih4w4y4zJi3GvawLYHlsNExQwz+v0jgY/aejBS2EJY # oUhLVE+UzRihV8ooxoftsmKLb2xb7BoFS6UAo3Zz4afnOdqI7FGoi7g4vx/0MIdi # kwTn5N56TdIv3mwfkZCFmrsKpN0zR8HD8WYsvH3xKkG7u/xdqmhPPqMmnI2jOFw/ # /n2aL8W7i1Pasja8PnRXH/QaVH0M1nanL+LI9TsMb/enWfXOW65Gne5cqMN9Uofv # ENtdwwEmJ3bZrcI9u4LZAkujAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU6m4qAkpz4641iK2irF8eWsSBcBkw # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMjkyNjAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AFFo/6E4LX51IqFuoKvUsi80QytGI5ASQ9zsPpBa0z78hutiJd6w154JkcIx/f7r # EBK4NhD4DIFNfRiVdI7EacEs7OAS6QHF7Nt+eFRNOTtgHb9PExRy4EI/jnMwzQJV # NokTxu2WgHr/fBsWs6G9AcIgvHjWNN3qRSrhsgEdqHc0bRDUf8UILAdEZOMBvKLC # rmf+kJPEvPldgK7hFO/L9kmcVe67BnKejDKO73Sa56AJOhM7CkeATrJFxO9GLXos # oKvrwBvynxAg18W+pagTAkJefzneuWSmniTurPCUE2JnvW7DalvONDOtG01sIVAB # +ahO2wcUPa2Zm9AiDVBWTMz9XUoKMcvngi2oqbsDLhbK+pYrRUgRpNt0y1sxZsXO # raGRF8lM2cWvtEkV5UL+TQM1ppv5unDHkW8JS+QnfPbB8dZVRyRmMQ4aY/tx5x5+ # sX6semJ//FbiclSMxSI+zINu1jYerdUwuCi+P6p7SmQmClhDM+6Q+btE2FtpsU0W # +r6RdYFf/P+nK6j2otl9Nvr3tWLu+WXmz8MGM+18ynJ+lYbSmFWcAj7SYziAfT0s # IwlQRFkyC71tsIZUhBHtxPliGUu362lIO0Lpe0DOrg8lspnEWOkHnCT5JEnWCbzu # iVt8RX1IV07uIveNZuOBWLVCzWJjEGa+HhaEtavjy6i7MIIHejCCBWKgAwIBAgIK # 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/Xmfwb1tbWrJUnMTDXpQzTGCGiIwghoeAgEBMIGVMH4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAQDvdWVXQ87GK0AAAAA # BAMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICGW # 3j1y4Nur/G32asq5Rr+ZPokTE1kiepRJtSJDiToKMEIGCisGAQQBgjcCAQwxNDAy # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20wDQYJKoZIhvcNAQEBBQAEggEAHNY3yebXEW2EtkNlc4smnnhUC5gwkR4HshKm # WQkKsBH1QjTNBXDHekoneAQgWuIeOmd0YARY57SgBBKJUO+oH5eyGhIkaujpwox4 # +WcsVzbrZg+/gbvdpNvsnv5P0AVhTEsV++d6J1ZYaBq9hL2cj9RtljsR5WmWNXY2 # RJ3468Z9ihiAs7q0fPUdw7mrPO+2VR7CVeDnsQoKrPIPXCXoB4l3sE3AJlQcWiqR # DFOE1Ei5kBs/vdZjnfOuf3BdH/RsSsIybX/ogVkGKNtdivr6/TjJEPb/VOVmI6v0 # sdGbtEE5FKE4BtqtoJlqcAikbr9NTdCIKkv5XRmaifxy+r4XpKGCF6wwgheoBgor # BgEEAYI3AwMBMYIXmDCCF5QGCSqGSIb3DQEHAqCCF4UwgheBAgEDMQ8wDQYJYIZI # AWUDBAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGE # WQoDATAxMA0GCWCGSAFlAwQCAQUABCCesR4aPMwgI/Hb1zVXXeHjQwxNtxR7izx8 # V7odIVeFqAIGZ7Y2znl+GBIyMDI1MDIyNTA3MDMzMC41OFowBIACAfSggdmkgdYw # gdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsT # JE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMe # blNoaWVsZCBUU1MgRVNOOjY1MUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3Nv # ZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIR+zCCBygwggUQoAMCAQICEzMAAAH1mQmU # vPHGUIwAAQAAAfUwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg # UENBIDIwMTAwHhcNMjQwNzI1MTgzMTAxWhcNMjUxMDIyMTgzMTAxWjCB0zELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9z # b2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMScwJQYDVQQLEx5uU2hpZWxk # IFRTUyBFU046NjUxQS0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1l # LVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM # 73RwVBNZ39Y/zghPskwhbV9AvrWx1+CaGV9PSe9gRvaS+Q0XTvdnCO965Jai3fzs # uMTRMKIb3d7ojQfMgVAGdvEY/9Y8FSKsWrtYTlECy6E19hQv48hv2MmrcLBbEgJ/ # Dm3+lPIg4eMq+jWVA5NZnKmKv+mxnAQTvLa5YA9tklMWsp6flHvfHYdvHLh5bUNy # ZePKbbAVa/XSwEfjRqMl9746TBxN2hitjcqSk39FBKN7JwrRuGOjQIZghhr5kwBq # jRI1H9HUnVjqwuSIIk7dpCttLVLPuX7+omDLx/IRkw0PkyzsLSwRo6+gEeJZKlMz # i9zTEMsKZzo8a/TcK1a7YqLKqsvwEAHURjI5KEjchPv1qsMgOsv5173UV+OZJsFj # mP4e9LSXd1eSM/ceifxvviVbCKQXSvMSsXSfeSFUC6zHtKbWgYb7TqHP1cDLdai7 # 5PpJ7qhrksOJCA9N9ZH+P0U2Twm7TqhJ9OHpzTdXS6WVrQjDL4fNSX5aZjEUtTQ+ # JpeyaC503BWqfnXOv4GLdc8nznBa7LoYZPucEOZc3NM2TMr3wMFCNM5ptBdRnzzh # hv0MU1yKCZ5VNiTJRdnqGxx3w3KrjkDcPduT6deeyiArVnvNmPpdsZ+3vGA5i+95 # TqnT5+u2FsXsxe/6LmpwP0d8WY6rhVgd69V6xhvo/QIDAQABo4IBSTCCAUUwHQYD # VR0OBBYEFFXgfFv1SjSgcPAlkl7baLF7YHUBMB8GA1UdIwQYMBaAFJ+nFV0AXmJd # g/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9z # b2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0El # MjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6 # Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGlt # ZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0l # AQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUA # A4ICAQBzDGZU9oD3Ed9+6ibRM5KnaGym5/UbRwdb8pccC6Gelbz9K+WrmP1ooj/z # 8bp8YhAyvTOWlq7yPLzcjjNyUZ0mOXlLTZLEOVQprC1a+B/uJ1rTo+CN5AzV5fgu # 63hts99PQUSnvsbvqGHKxfFMk0e/nL5/BOFR6KJyWKFnCpxkylrjqb6hXqKBNToj # QSed6i0yoWzRDfMeBVWvhZeOcbYFyeSKnjZ53KD/2JdzOpMGsSS9PPRSWW2kUZpC # cvOr42jxUSCrRQbtbUQtkaGabEWYcAHBNPqw8kVXrwN8ugLSIH1Btv1Vnya9tNXk # m0hIGSVO5UCUSTNeL0siM2bH6Sd0F8o/x3Eb/FtFem1ANANoKxLqiAuTAuAfrNKz # 66X1abMjQXzMiZuGdmFTOIgeF4Wjgf5miiM9hyBMrr/duRJs5puZAV/3kHwHp7la # pdtLmz050x1SVbWBMjWvm75YDAfYobt3Gd6hNt/+NiXdNS0/sAenJyTZzSe6f9DQ # LJylr1BQf8PLTWTq1CiY1caOK+Db8EZyBknQfDwLopV6UQnfXEugTbWb340SBIoJ # GgUTUuSZrfVLIhrKdt1gRvyw6VnKcx2bzI+V0PC4Xni8mIQCuOtwM1d7oGhtlSJN # ZIq+/UMlp1HVJQI7853bUaBT6Fmq750qCMoBh15Mi+L1Hau0tjCCB3EwggVZoAMC # AQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29m # dCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTIxMDkzMDE4MjIy # NVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw # b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM57RyIQt5osvXJHm9 # DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm95VTcVrifkpa/rg2 # Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N # 7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBbfowQHJ1S/rboYiXc # ag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJ # j361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYwXE8s4mKyzbnijYjk # lqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW/aUgfX782Z5F37Zy # L9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M # 269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLX # pyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLU # HMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode # 2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEA # ATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYE # FJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYMKwYBBAGCN0yDfQEB # MEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv # RG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEE # AYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB # /zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEug # SaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9N # aWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsG # AQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jv # b0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt # 4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518JxNj/aZGx80HU5bbsP # MeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+iehp4LoJ7nvfam++ # Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2pFaq95W2KFUn0CS9 # QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefwC2qBwoEZQhlSdYo2 # wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aR # AfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFORy3BFARxv2T5JL5z # bcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhLmm77IVRrakURR6nx # t67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3 # Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5m/8K6TT4JDVnK+AN # uOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/Z # cGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNWMIICPgIBATCCAQGhgdmkgdYw # gdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsT # JE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMe # blNoaWVsZCBUU1MgRVNOOjY1MUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3Nv # ZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQAmwAq7jw1tHlhG # DdZIFALKPN2S9qCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw # MA0GCSqGSIb3DQEBCwUAAgUA62dMZTAiGA8yMDI1MDIyNDE5NTIwNVoYDzIwMjUw # MjI1MTk1MjA1WjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDrZ0xlAgEAMAcCAQAC # AjccMAcCAQACAhP8MAoCBQDraJ3lAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisG # AQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQAD # ggEBACsXV1pNBxpeqssxGD9naKFRtYWjVMcslYqe/9jnKlHsL1YzkAChGJ4Up4wV # 8+q3+3ByHNIZiAxVOCZeBI/FEZm6Sns81OQmReMuwcfGqboOTpXgKjyTAzF0YqR3 # Ssgg49wiuI5qeRAZmWRPBHGwMasjGD7iHN29LEGA77dJcd16w5gjUX+yJJHTH13c # mxQtBIrhkLPtRjNyN/NhgpWVJQ0thU5RIRLNwRhNzqSS9V3WDqEhCkpRfuX8co9Y # G4SCUFDuqdH4tsX3cKPsgVaLnth7FmYK4/eVHtTN99ZHsjqATWDELPyQZqspyqdw # 5AIf/BZUpg1SRVs9cJuB0yLKGKIxggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt # ZS1TdGFtcCBQQ0EgMjAxMAITMwAAAfWZCZS88cZQjAABAAAB9TANBglghkgBZQME # AgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJ # BDEiBCDzJYEkJbozjP37v1E1c8Ob6BK6RTMjKSyEYK8uDMa4vzCB+gYLKoZIhvcN # AQkQAi8xgeowgecwgeQwgb0EIMHW8tIXCHT0hK7iR0S/j+2D15HViTzDnHuPkZOG # po81MIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAH1 # mQmUvPHGUIwAAQAAAfUwIgQgtIAd98Uq6K2RjJ1N1bNUFwsqqUymQCTpYUt5gtWs # vecwDQYJKoZIhvcNAQELBQAEggIAc56KdfA3aw0UA2wWXLSn6MqKjKoPxv0komO8 # LI3rb3rwrlcmolITCizU3sSjwEd9+mMZ8m+OBrX+ePohecgseah1yCcRiz3NbQLj # KH5SMoPWHFinU1SMzNptD3OaiFGEPf0FY755FLRc72XNkP0r/OZcslGGNoQGWWdp # MwAbB2OtSKr84Cm7sAgcphos/WzDVE2o39Qsc0Fdaqh5WqoIZWd29h/iBZilGsZN # eh1XANLSsW4Zx1kwlUCdg+J2BooV54FCNRqfLy38F2AbsBvL9o+t4p+4eHPhTm99 # y2NV6uVrrsYoUs1QXoCXa2QowEJA7nRHZmnxkFettCIUrntix+H+kx/jGsd1Yllz # 7ET3CCbkWn6+GrRay9C00p5y5UJh88YRtb4pLkFczY9l4MFRKoY4Njg6AhivO+Rt # NNVUY/McgIUo4eCM9kgVCRshGtqC4ENf7CKnLsZTZNVY2sXJSOBgjpLFygEHzu9K # akbfknH751uYnwlH4VBMwhTH9psvCXJ7IEFGzfqg/Znsh74WbwI1siIKVBsTMFIo # ykf0HN8wggfpmBC6VAHLOqWM/iZBAU0wEB1pix6U85bUjAiSrghM34u9TOi6YmWt # 4zUlZVkbgny71zWF/MomtVIT0xU27d79Mu0Rxa4nIkHEY3QsVuFADuXdGmcLSlAo # rUlSKpE= # SIG # End signature block |