GitHubIssues.ps1
# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. @{ GitHubIssueTypeName = 'GitHub.Issue' }.GetEnumerator() | ForEach-Object { Set-Variable -Scope Script -Option ReadOnly -Name $_.Key -Value $_.Value } filter Get-GitHubIssue { <# .SYNOPSIS Retrieve Issues from GitHub. .DESCRIPTION Retrieve Issues from GitHub. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub .PARAMETER OwnerName Owner of the repository. If not supplied here, the DefaultOwnerName configuration property value will be used. .PARAMETER RepositoryName Name of the repository. If not supplied here, the DefaultRepositoryName configuration property value will be used. .PARAMETER Uri Uri for the repository. The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER OrganizationName The organization whose issues should be retrieved. .PARAMETER RepositoryType all: Retrieve issues across owned, member and org repositories ownedAndMember: Retrieve issues across owned and member repositories .PARAMETER Issue The number of specific Issue to retrieve. If not supplied, will return back all Issues for this Repository that match the specified criteria. .PARAMETER IgnorePullRequests GitHub treats Pull Requests as Issues. Specify this switch to skip over any Issue that is actually a Pull Request. .PARAMETER Filter Indicates the type of Issues to return: assigned: Issues assigned to the authenticated user. created: Issues created by the authenticated user. mentioned: Issues mentioning the authenticated user. subscribed: Issues the authenticated user has been subscribed to updates for. all: All issues the authenticated user can see, regardless of participation or creation. .PARAMETER State Indicates the state of the issues to return. .PARAMETER Label The label (or labels) that returned Issues should have. .PARAMETER Sort The property to sort the returned Issues by. .PARAMETER Direction The direction of the sort. .PARAMETER Since If specified, returns only issues updated at or after this time. .PARAMETER MilestoneType If specified, indicates what milestone Issues must be a part of to be returned: specific: Only issues with the milestone specified via the Milestone parameter will be returned. all: All milestones will be returned. none: Only issues without milestones will be returned. .PARAMETER MilestoneNumber Only issues with this milestone will be returned. .PARAMETER AssigneeType If specified, indicates who Issues must be assigned to in order to be returned: specific: Only issues assigned to the user specified by the Assignee parameter will be returned. all: Issues assigned to any user will be returned. none: Only issues without an assigned user will be returned. .PARAMETER Assignee Only issues assigned to this user will be returned. .PARAMETER Creator Only issues created by this specified user will be returned. .PARAMETER Mentioned Only issues that mention this specified user will be returned. .PARAMETER MediaType The format in which the API will return the body of the issue. Raw - Return the raw markdown body. Response will include body. This is the default if you do not pass any specific media type. Text - Return a text only representation of the markdown body. Response will include body_text. Html - Return HTML rendered from the body's markdown. Response will include body_html. Full - Return raw, text and HTML representations. Response will include body, body_text, and body_html. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .INPUTS GitHub.Branch GitHub.Content GitHub.Event GitHub.Issue GitHub.IssueComment GitHub.Label GitHub.Milestone GitHub.PullRequest GitHub.Project GitHub.ProjectCard GitHub.ProjectColumn GitHub.Reaction GitHub.Release GitHub.ReleaseAsset GitHub.Repository GitHub.User .OUTPUTS GitHub.Issue .EXAMPLE Get-GitHubIssue -OwnerName microsoft -RepositoryName PowerShellForGitHub -State Open Gets all the currently open issues in the microsoft\PowerShellForGitHub repository. .EXAMPLE Get-GitHubIssue -OwnerName microsoft -RepositoryName PowerShellForGitHub -State All -Assignee Octocat Gets every issue in the microsoft\PowerShellForGitHub repository that is assigned to Octocat. #> [CmdletBinding(DefaultParameterSetName = 'Elements')] [OutputType({$script:GitHubIssueTypeName})] param( [Parameter(ParameterSetName='Elements')] [string] $OwnerName, [Parameter(ParameterSetName='Elements')] [string] $RepositoryName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='Uri')] [Alias('RepositoryUrl')] [string] $Uri, [Parameter(ValueFromPipelineByPropertyName)] [string] $OrganizationName, [ValidateSet('All', 'OwnedAndMember')] [string] $RepositoryType = 'All', [Parameter(ValueFromPipelineByPropertyName)] [Alias('IssueNumber')] [int64] $Issue, [switch] $IgnorePullRequests, [ValidateSet('Assigned', 'Created', 'Mentioned', 'Subscribed', 'All')] [string] $Filter = 'Assigned', [ValidateSet('Open', 'Closed', 'All')] [string] $State = 'Open', [string[]] $Label, [ValidateSet('Created', 'Updated', 'Comments')] [string] $Sort = 'Created', [ValidateSet('Ascending', 'Descending')] [string] $Direction = 'Descending', [DateTime] $Since, [ValidateSet('Specific', 'All', 'None')] [string] $MilestoneType, [Parameter(ValueFromPipelineByPropertyName)] [int64] $MilestoneNumber, [ValidateSet('Specific', 'All', 'None')] [string] $AssigneeType, [string] $Assignee, [Parameter(ValueFromPipelineByPropertyName)] [Alias('UserName')] [string] $Creator, [string] $Mentioned, [ValidateSet('Raw', 'Text', 'Html', 'Full')] [string] $MediaType ='Raw', [string] $AccessToken ) Write-InvocationLog # Intentionally disabling validation here because parameter sets exist that do not require # an OwnerName and RepositoryName. Therefore, we will do futher parameter validation further # into the function. $elements = Resolve-RepositoryElements -DisableValidation $OwnerName = $elements.ownerName $RepositoryName = $elements.repositoryName $telemetryProperties = @{ 'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName) 'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName) 'OrganizationName' = (Get-PiiSafeString -PlainText $OrganizationName) 'ProvidedIssue' = $PSBoundParameters.ContainsKey('Issue') } $uriFragment = [String]::Empty $description = [String]::Empty if ($OwnerName -xor $RepositoryName) { $message = 'You must specify BOTH Owner Name and Repository Name when one is provided.' Write-Log -Message $message -Level Error throw $message } if (-not [String]::IsNullOrEmpty($RepositoryName)) { $uriFragment = "/repos/$OwnerName/$RepositoryName/issues" $description = "Getting issues for $RepositoryName" if ($PSBoundParameters.ContainsKey('Issue')) { $uriFragment = $uriFragment + "/$Issue" $description = "Getting issue $Issue for $RepositoryName" } } elseif (-not [String]::IsNullOrEmpty($OrganizationName)) { $uriFragment = "/orgs/$OrganizationName/issues" $description = "Getting issues for $OrganizationName" } elseif ($RepositoryType -eq 'All') { $uriFragment = "/issues" $description = "Getting issues across owned, member and org repositories" } elseif ($RepositoryType -eq 'OwnedAndMember') { $uriFragment = "/user/issues" $description = "Getting issues across owned and member repositories" } else { throw "Parameter set not supported." } $directionConverter = @{ 'Ascending' = 'asc' 'Descending' = 'desc' } $getParams = @( "filter=$($Filter.ToLower())", "state=$($State.ToLower())", "sort=$($Sort.ToLower())", "direction=$($directionConverter[$Direction])" ) if ($PSBoundParameters.ContainsKey('Label')) { $getParams += "labels=$($Label -join ',')" } if ($PSBoundParameters.ContainsKey('Since')) { $getParams += "since=$($Since.ToUniversalTime().ToString('o'))" } if ($PSBoundParameters.ContainsKey('Mentioned')) { $getParams += "mentioned=$Mentioned" } if ($PSBoundParameters.ContainsKey('MilestoneType')) { if ($MilestoneType -eq 'All') { $getParams += 'mentioned=*' } elseif ($MilestoneType -eq 'None') { $getParams += 'mentioned=none' } elseif ($PSBoundParameters.ContainsKey('$MilestoneNumber')) { $message = "MilestoneType was set to [$MilestoneType], but no value for MilestoneNumber was provided." Write-Log -Message $message -Level Error throw $message } } if ($PSBoundParameters.ContainsKey('MilestoneNumber')) { $getParams += "milestone=$MilestoneNumber" } if ($PSBoundParameters.ContainsKey('AssigneeType')) { if ($AssigneeType -eq 'all') { $getParams += 'assignee=*' } elseif ($AssigneeType -eq 'none') { $getParams += 'assignee=none' } elseif ([String]::IsNullOrEmpty($Assignee)) { $message = "AssigneeType was set to [$AssigneeType], but no value for Assignee was provided." Write-Log -Message $message -Level Error throw $message } } if ($PSBoundParameters.ContainsKey('Assignee')) { $getParams += "assignee=$Assignee" } if ($PSBoundParameters.ContainsKey('Creator')) { $getParams += "creator=$Creator" } if ($PSBoundParameters.ContainsKey('Mentioned')) { $getParams += "mentioned=$Mentioned" } $params = @{ 'UriFragment' = $uriFragment + '?' + ($getParams -join '&') 'Description' = $description 'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $symmetraAcceptHeader) 'AccessToken' = $AccessToken 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties } try { $result = (Invoke-GHRestMethodMultipleResult @params | Add-GitHubIssueAdditionalProperties) if ($IgnorePullRequests) { return ($result | Where-Object { $null -eq (Get-Member -InputObject $_ -Name pull_request) }) } else { return $result } } finally {} } filter Get-GitHubIssueTimeline { <# .SYNOPSIS Retrieves various events that occur around an issue or pull request on GitHub. .DESCRIPTION Retrieves various events that occur around an issue or pull request on GitHub. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub .PARAMETER OwnerName Owner of the repository. If not supplied here, the DefaultOwnerName configuration property value will be used. .PARAMETER RepositoryName Name of the repository. If not supplied here, the DefaultRepositoryName configuration property value will be used. .PARAMETER Uri Uri for the repository. The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER Issue The Issue to get the timeline for. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .INPUTS GitHub.Branch GitHub.Content GitHub.Event GitHub.Issue GitHub.IssueComment GitHub.Label GitHub.Milestone GitHub.PullRequest GitHub.Project GitHub.ProjectCard GitHub.ProjectColumn GitHub.Reaction GitHub.Release GitHub.ReleaseAsset GitHub.Repository .OUTPUTS GitHub.Event .EXAMPLE Get-GitHubIssueTimeline -OwnerName microsoft -RepositoryName PowerShellForGitHub -Issue 24 #> [CmdletBinding(DefaultParameterSetName = 'Elements')] [OutputType({$script:GitHubEventTypeName})] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification="The Uri parameter is only referenced by Resolve-RepositoryElements which get access to it from the stack via Get-Variable -Scope 1.")] param( [Parameter(ParameterSetName='Elements')] [string] $OwnerName, [Parameter(ParameterSetName='Elements')] [string] $RepositoryName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='Uri')] [Alias('RepositoryUrl')] [string] $Uri, [Parameter( Mandatory, ValueFromPipelineByPropertyName)] [Alias('IssueNumber')] [int64] $Issue, [string] $AccessToken ) Write-InvocationLog $elements = Resolve-RepositoryElements $OwnerName = $elements.ownerName $RepositoryName = $elements.repositoryName $telemetryProperties = @{ 'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName) 'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName) } $params = @{ 'UriFragment' = "repos/$OwnerName/$RepositoryName/issues/$Issue/timeline" 'Description' = "Getting timeline for Issue #$Issue in $RepositoryName" 'AcceptHeader' = $script:mockingbirdAcceptHeader 'AccessToken' = $AccessToken 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties } return (Invoke-GHRestMethodMultipleResult @params | Add-GitHubEventAdditionalProperties) } filter New-GitHubIssue { <# .SYNOPSIS Create a new Issue on GitHub. .DESCRIPTION Create a new Issue on GitHub. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub .PARAMETER OwnerName Owner of the repository. If not supplied here, the DefaultOwnerName configuration property value will be used. .PARAMETER RepositoryName Name of the repository. If not supplied here, the DefaultRepositoryName configuration property value will be used. .PARAMETER Uri Uri for the repository. The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER Title The title of the issue .PARAMETER Body The contents of the issue .PARAMETER Assignee Login(s) for Users to assign to the issue. .PARAMETER Milestone The number of the milestone to associate this issue with. .PARAMETER Label Label(s) to associate with this issue. .PARAMETER MediaType The format in which the API will return the body of the issue. Raw - Return the raw markdown body. Response will include body. This is the default if you do not pass any specific media type. Text - Return a text only representation of the markdown body. Response will include body_text. Html - Return HTML rendered from the body's markdown. Response will include body_html. Full - Return raw, text and HTML representations. Response will include body, body_text, and body_html. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .INPUTS GitHub.Branch GitHub.Content GitHub.Event GitHub.Issue GitHub.IssueComment GitHub.Label GitHub.Milestone GitHub.PullRequest GitHub.Project GitHub.ProjectCard GitHub.ProjectColumn GitHub.Reaction GitHub.Release GitHub.ReleaseAsset GitHub.Repository .OUTPUTS GitHub.Issue .EXAMPLE New-GitHubIssue -OwnerName microsoft -RepositoryName PowerShellForGitHub -Title 'Test Issue' #> [CmdletBinding( SupportsShouldProcess, DefaultParameterSetName='Elements')] [OutputType({$script:GitHubIssueTypeName})] param( [Parameter(ParameterSetName='Elements')] [string] $OwnerName, [Parameter(ParameterSetName='Elements')] [string] $RepositoryName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='Uri')] [Alias('RepositoryUrl')] [string] $Uri, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Title, [string] $Body, [string[]] $Assignee, [Parameter(ValueFromPipelineByPropertyName)] [Alias('MilestoneNumber')] [int64] $Milestone, [string[]] $Label, [ValidateSet('Raw', 'Text', 'Html', 'Full')] [string] $MediaType ='Raw', [string] $AccessToken ) Write-InvocationLog $elements = Resolve-RepositoryElements $OwnerName = $elements.ownerName $RepositoryName = $elements.repositoryName $telemetryProperties = @{ 'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName) 'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName) } $hashBody = @{ 'title' = $Title } if ($PSBoundParameters.ContainsKey('Body')) { $hashBody['body'] = $Body } if ($PSBoundParameters.ContainsKey('Assignee')) { $hashBody['assignees'] = @($Assignee) } if ($PSBoundParameters.ContainsKey('Milestone')) { $hashBody['milestone'] = $Milestone } if ($PSBoundParameters.ContainsKey('Label')) { $hashBody['labels'] = @($Label) } if (-not $PSCmdlet.ShouldProcess($Title, 'Create GitHub Issue')) { return } $params = @{ 'UriFragment' = "/repos/$OwnerName/$RepositoryName/issues" 'Body' = (ConvertTo-Json -InputObject $hashBody) 'Method' = 'Post' 'Description' = "Creating new Issue ""$Title"" on $RepositoryName" 'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $symmetraAcceptHeader) 'AccessToken' = $AccessToken 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties } return (Invoke-GHRestMethod @params | Add-GitHubIssueAdditionalProperties) } filter Set-GitHubIssue { <# .SYNOPSIS Updates an Issue on GitHub. .DESCRIPTION Updates an Issue on GitHub. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub .PARAMETER OwnerName Owner of the repository. If not supplied here, the DefaultOwnerName configuration property value will be used. .PARAMETER RepositoryName Name of the repository. If not supplied here, the DefaultRepositoryName configuration property value will be used. .PARAMETER Uri Uri for the repository. The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER Issue The issue to be updated. .PARAMETER Title The title of the issue .PARAMETER Body The contents of the issue .PARAMETER Assignee Login(s) for Users to assign to the issue. Provide an empty array to clear all existing assignees. .PARAMETER MilestoneNumber The number of the milestone to associate this issue with. Set to 0/$null to remove current. .PARAMETER Label Label(s) to associate with this issue. Provide an empty array to clear all existing labels. .PARAMETER State Modify the current state of the issue. .PARAMETER MediaType The format in which the API will return the body of the issue. Raw - Return the raw markdown body. Response will include body. This is the default if you do not pass any specific media type. Text - Return a text only representation of the markdown body. Response will include body_text. Html - Return HTML rendered from the body's markdown. Response will include body_html. Full - Return raw, text and HTML representations. Response will include body, body_text, and body_html. .PARAMETER PassThru Returns the updated Issue. By default, this cmdlet does not generate any output. You can use "Set-GitHubConfiguration -DefaultPassThru" to control the default behavior of this switch. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .INPUTS GitHub.Branch GitHub.Content GitHub.Event GitHub.Issue GitHub.IssueComment GitHub.Label GitHub.Milestone GitHub.PullRequest GitHub.Project GitHub.ProjectCard GitHub.ProjectColumn GitHub.Reaction GitHub.Release GitHub.ReleaseAsset GitHub.Repository .OUTPUTS GitHub.Issue .EXAMPLE Set-GitHubIssue -OwnerName microsoft -RepositoryName PowerShellForGitHub -Issue 4 -Title 'Test Issue' -State Closed #> [CmdletBinding( SupportsShouldProcess, DefaultParameterSetName='Elements')] [OutputType({$script:GitHubIssueTypeName})] [Alias('Update-GitHubIssue')] # Non-standard usage of the Update verb, but done to avoid a breaking change post 0.14.0 param( [Parameter(ParameterSetName='Elements')] [string] $OwnerName, [Parameter(ParameterSetName='Elements')] [string] $RepositoryName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='Uri')] [Alias('RepositoryUrl')] [string] $Uri, [Parameter( Mandatory, ValueFromPipelineByPropertyName)] [Alias('IssueNumber')] [int64] $Issue, [string] $Title, [string] $Body, [string[]] $Assignee, [int64] $MilestoneNumber, [string[]] $Label, [ValidateSet('Open', 'Closed')] [string] $State, [ValidateSet('Raw', 'Text', 'Html', 'Full')] [string] $MediaType ='Raw', [switch] $PassThru, [string] $AccessToken ) Write-InvocationLog $elements = Resolve-RepositoryElements $OwnerName = $elements.ownerName $RepositoryName = $elements.repositoryName $telemetryProperties = @{ 'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName) 'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName) } $hashBody = @{} if ($PSBoundParameters.ContainsKey('Title')) { $hashBody['title'] = $Title } if ($PSBoundParameters.ContainsKey('Body')) { $hashBody['body'] = $Body } if ($PSBoundParameters.ContainsKey('Assignee')) { $hashBody['assignees'] = @($Assignee) } if ($PSBoundParameters.ContainsKey('Label')) { $hashBody['labels'] = @($Label) } if ($PSBoundParameters.ContainsKey('State')) { $hashBody['state'] = $State.ToLower() } if ($PSBoundParameters.ContainsKey('MilestoneNumber')) { $hashBody['milestone'] = $MilestoneNumber if ($MilestoneNumber -in (0, $null)) { $hashBody['milestone'] = $null } } if (-not $PSCmdlet.ShouldProcess($Issue, 'Update GitHub Issue')) { return } $params = @{ 'UriFragment' = "/repos/$OwnerName/$RepositoryName/issues/$Issue" 'Body' = (ConvertTo-Json -InputObject $hashBody) 'Method' = 'Patch' 'Description' = "Updating Issue #$Issue on $RepositoryName" 'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $symmetraAcceptHeader) 'AccessToken' = $AccessToken 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties } $result = (Invoke-GHRestMethod @params | Add-GitHubIssueAdditionalProperties) if (Resolve-ParameterWithDefaultConfigurationValue -Name PassThru -ConfigValueName DefaultPassThru) { return $result } } filter Lock-GitHubIssue { <# .SYNOPSIS Lock an Issue or Pull Request conversation on GitHub. .DESCRIPTION Lock an Issue or Pull Request conversation on GitHub. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub .PARAMETER OwnerName Owner of the repository. If not supplied here, the DefaultOwnerName configuration property value will be used. .PARAMETER RepositoryName Name of the repository. If not supplied here, the DefaultRepositoryName configuration property value will be used. .PARAMETER Uri Uri for the repository. The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER Issue The issue to be locked. .PARAMETER Reason The reason for locking the issue or pull request conversation. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .INPUTS GitHub.Branch GitHub.Content GitHub.Event GitHub.Issue GitHub.IssueComment GitHub.Label GitHub.Milestone GitHub.PullRequest GitHub.Project GitHub.ProjectCard GitHub.ProjectColumn GitHub.Reaction GitHub.Release GitHub.ReleaseAsset GitHub.Repository .EXAMPLE Lock-GitHubIssue -OwnerName microsoft -RepositoryName PowerShellForGitHub -Issue 4 -Title 'Test Issue' -Reason Spam #> [CmdletBinding( SupportsShouldProcess, DefaultParameterSetName='Elements')] param( [Parameter(ParameterSetName='Elements')] [string] $OwnerName, [Parameter(ParameterSetName='Elements')] [string] $RepositoryName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='Uri')] [Alias('RepositoryUrl')] [string] $Uri, [Parameter( Mandatory, ValueFromPipelineByPropertyName)] [Alias('IssueNumber')] [int64] $Issue, [ValidateSet('OffTopic', 'TooHeated', 'Resolved', 'Spam')] [string] $Reason, [string] $AccessToken ) Write-InvocationLog $elements = Resolve-RepositoryElements $OwnerName = $elements.ownerName $RepositoryName = $elements.repositoryName $telemetryProperties = @{ 'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName) 'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName) } $hashBody = @{ 'locked' = $true } if ($PSBoundParameters.ContainsKey('Reason')) { $reasonConverter = @{ 'OffTopic' = 'off-topic' 'TooHeated' = 'too heated' 'Resolved' = 'resolved' 'Spam' = 'spam' } $telemetryProperties['Reason'] = $Reason $hashBody['lock_reason'] = $reasonConverter[$Reason] } if (-not $PSCmdlet.ShouldProcess($Issue, 'Lock GitHub Issue')) { return } $params = @{ 'UriFragment' = "/repos/$OwnerName/$RepositoryName/issues/$Issue/lock" 'Body' = (ConvertTo-Json -InputObject $hashBody) 'Method' = 'Put' 'Description' = "Locking Issue #$Issue on $RepositoryName" 'AcceptHeader' = $script:sailorVAcceptHeader 'AccessToken' = $AccessToken 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties } return Invoke-GHRestMethod @params } filter Unlock-GitHubIssue { <# .SYNOPSIS Unlocks an Issue or Pull Request conversation on GitHub. .DESCRIPTION Unlocks an Issue or Pull Request conversation on GitHub. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub .PARAMETER OwnerName Owner of the repository. If not supplied here, the DefaultOwnerName configuration property value will be used. .PARAMETER RepositoryName Name of the repository. If not supplied here, the DefaultRepositoryName configuration property value will be used. .PARAMETER Uri Uri for the repository. The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER Issue The issue to be unlocked. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .INPUTS GitHub.Branch GitHub.Content GitHub.Event GitHub.Issue GitHub.IssueComment GitHub.Label GitHub.Milestone GitHub.PullRequest GitHub.Project GitHub.ProjectCard GitHub.ProjectColumn GitHub.Reaction GitHub.Release GitHub.ReleaseAsset GitHub.Repository .EXAMPLE Unlock-GitHubIssue -OwnerName microsoft -RepositoryName PowerShellForGitHub -Issue 4 #> [CmdletBinding( SupportsShouldProcess, DefaultParameterSetName='Elements')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification="The Uri parameter is only referenced by Resolve-RepositoryElements which get access to it from the stack via Get-Variable -Scope 1.")] param( [Parameter(ParameterSetName='Elements')] [string] $OwnerName, [Parameter(ParameterSetName='Elements')] [string] $RepositoryName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='Uri')] [Alias('RepositoryUrl')] [string] $Uri, [Parameter( Mandatory, ValueFromPipelineByPropertyName)] [Alias('IssueNumber')] [int64] $Issue, [string] $AccessToken ) Write-InvocationLog $elements = Resolve-RepositoryElements $OwnerName = $elements.ownerName $RepositoryName = $elements.repositoryName $telemetryProperties = @{ 'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName) 'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName) } if (-not $PSCmdlet.ShouldProcess($Issue, 'Unlock GitHub Issue')) { return } $params = @{ 'UriFragment' = "/repos/$OwnerName/$RepositoryName/issues/$Issue/lock" 'Method' = 'Delete' 'Description' = "Unlocking Issue #$Issue on $RepositoryName" 'AcceptHeader' = $script:sailorVAcceptHeader 'AccessToken' = $AccessToken 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties } return Invoke-GHRestMethod @params } filter Add-GitHubIssueAdditionalProperties { <# .SYNOPSIS Adds type name and additional properties to ease pipelining to GitHub Issue objects. .PARAMETER InputObject The GitHub object to add additional properties to. .PARAMETER TypeName The type that should be assigned to the object. .INPUTS [PSCustomObject] .OUTPUTS GitHub.Issue #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Internal helper that is definitely adding more than one property.")] param( [Parameter( Mandatory, ValueFromPipeline)] [AllowNull()] [AllowEmptyCollection()] [PSCustomObject[]] $InputObject, [ValidateNotNullOrEmpty()] [string] $TypeName = $script:GitHubIssueTypeName ) foreach ($item in $InputObject) { # Pull requests are _also_ issues. A pull request that is retrieved through the # Issue endpoint will also have a 'pull_request' property. Let's make sure that # we mark it up appropriately. if ($null -ne $item.pull_request) { $null = Add-GitHubPullRequestAdditionalProperties -InputObject $item Write-Output $item continue } $item.PSObject.TypeNames.Insert(0, $TypeName) if (-not (Get-GitHubConfiguration -Name DisablePipelineSupport)) { $elements = Split-GitHubUri -Uri $item.html_url $repositoryUrl = Join-GitHubUri @elements Add-Member -InputObject $item -Name 'RepositoryUrl' -Value $repositoryUrl -MemberType NoteProperty -Force Add-Member -InputObject $item -Name 'IssueId' -Value $item.id -MemberType NoteProperty -Force Add-Member -InputObject $item -Name 'IssueNumber' -Value $item.number -MemberType NoteProperty -Force @('assignee', 'assignees', 'user') | ForEach-Object { if ($null -ne $item.$_) { $null = Add-GitHubUserAdditionalProperties -InputObject $item.$_ } } if ($null -ne $item.labels) { $null = Add-GitHubLabelAdditionalProperties -InputObject $item.labels } if ($null -ne $item.milestone) { $null = Add-GitHubMilestoneAdditionalProperties -InputObject $item.milestone } if ($null -ne $item.closed_by) { $null = Add-GitHubUserAdditionalProperties -InputObject $item.closed_by } if ($null -ne $item.repository) { $null = Add-GitHubRepositoryAdditionalProperties -InputObject $item.repository } } Write-Output $item } } # SIG # Begin signature block # MIIjjwYJKoZIhvcNAQcCoIIjgDCCI3wCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAfeeyfyIWbRgCO # hX3kpTB4bH39KGGMlz5B9r+T/2NK9KCCDYEwggX/MIID56ADAgECAhMzAAABh3IX # chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB # znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH # sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d # weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ # itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV # Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy # S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K # NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV # BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr # qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx # zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe # yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g # yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf # AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI # 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5 # GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea # jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZDCCFWACAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgaabL6DaW # TRCGfqg9E0w0IxdcoKmJZcyWrRJXw5rsLiMwQgYKKwYBBAGCNwIBDDE0MDKgFIAS # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN # BgkqhkiG9w0BAQEFAASCAQAHMvLvh4dABOYiWP+JCxYVFt3EdHVg41QFsXRLK7D8 # XC8R0n0INqiuD2a2j9HqmtIm2h1I09za8JE4OoUp8bkEXI9AUZdj6yArdAbFFf69 # W9zgfBi4ok8ou93ya/E68nVXb4o3msbKHpxXp2IglyUfwOoNi0TN6sR7zfAOB5OH # 3kz1SdQPys0NpZ1yLzMUiR6nbMJxjmzQ7cCkVPV0Zz2+furRhaspl+r+kKezH01n # wOQ+vqT1JM6dwAGeLj07HJjmWOdkOEcK+dzDc6oJPXWOBfjAKgYmQBpSgfgxLkbh # Gy34aGSoCARUQ6N/qvOeiyLnALbToL7lLcp0ttxV6zRnoYIS7jCCEuoGCisGAQQB # gjcDAwExghLaMIIS1gYJKoZIhvcNAQcCoIISxzCCEsMCAQMxDzANBglghkgBZQME # AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB # MDEwDQYJYIZIAWUDBAIBBQAEIF/83eFceWhb7tbqll+Zx/V1LS59oak4ZEo5BnQi # IJb9AgZfO+RS8w4YEzIwMjAwOTA5MTU0MDUyLjMxMVowBIACAfSggdSkgdEwgc4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p # Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg # VFNTIEVTTjo2MEJDLUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt # U3RhbXAgU2VydmljZaCCDkEwggT1MIID3aADAgECAhMzAAABJt+6SyK5goIHAAAA # AAEmMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw # MB4XDTE5MTIxOTAxMTQ1OVoXDTIxMDMxNzAxMTQ1OVowgc4xCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy # YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo2MEJD # LUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj # ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ4wvoacTvMNlXQTtfF/ # Cx5Ol3X0fcjUNMvjLgTmO5+WHYJFbp725P3+qvFKDRQHWEI1Sz0gB24urVDIjXjB # h5NVNJVMQJI2tltv7M4/4IbhZJb3xzQW7LolEoZYUZanBTUuyly9osCg4o5joViT # 2GtmyxK+Fv5kC20l2opeaeptd/E7ceDAFRM87hiNCsK/KHyC+8+swnlg4gTOey6z # QqhzgNsG6HrjLBuDtDs9izAMwS2yWT0T52QA9h3Q+B1C9ps2fMKMe+DHpG+0c61D # 94Yh6cV2XHib4SBCnwIFZAeZE2UJ4qPANSYozI8PH+E5rCT3SVqYvHou97HsXvP2 # I3MCAwEAAaOCARswggEXMB0GA1UdDgQWBBRJq6wfF7B+mEKN0VimX8ajNA5hQTAf # BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH # hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU # aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF # BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0 # YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG # AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBAlvudaOlv9Cfzv56bnX41czF6tLtH # LB46l6XUch+qNN45ZmOTFwLot3JjwSrn4oycQ9qTET1TFDYd1QND0LiXmKz9OqBX # ai6S8XdyCQEZvfL82jIAs9pwsAQ6XvV9jNybPStRgF/sOAM/Deyfmej9Tg9FcRwX # ank2qgzdZZNb8GoEze7f1orcTF0Q89IUXWIlmwEwQFYF1wjn87N4ZxL9Z/xA2m/R # 1zizFylWP/mpamCnVfZZLkafFLNUNVmcvc+9gM7vceJs37d3ydabk4wR6ObR34sW # aLppmyPlsI1Qq5Lu6bJCWoXzYuWpkoK6oEep1gML6SRC3HKVS3UscZhtMIIGcTCC # BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv # b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN # MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw # DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0 # VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw # RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe # dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx # Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G # kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA # AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7 # fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC # AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX # zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v # cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI # KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g # AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93 # d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB # BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA # bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh # IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS # +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK # kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon # /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi # PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/ # fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII # YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0 # cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a # KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ # cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+ # NR4Iuto229Nfj950iEkSoYICzzCCAjgCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP # cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo2 # MEJDLUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy # dmljZaIjCgEBMAcGBSsOAwIaAxUACmcyOWmZxErpq06B8dy6oMZ6//yggYMwgYCk # fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF # AOMDYqswIhgPMjAyMDA5MDkxODE4MTlaGA8yMDIwMDkxMDE4MTgxOVowdDA6Bgor # BgEEAYRZCgQBMSwwKjAKAgUA4wNiqwIBADAHAgEAAgIUMTAHAgEAAgIRCTAKAgUA # 4wS0KwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID # B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAF35Dqvm4D9uEoDASQqL # 9EdBF8mYmFRo/+ArFRUzLmDW1fTV0a4JPMJg+mPSzxd3yAGwGQIfXC8qsKudyQGw # Gr+wUXDF1rLLqADJkKM0RXo9vFn+4YkQtt8SzdnMVWQuHOhKjVU2W8xC2fVRE7aD # mxrZ41ozdKVdjP+iAzmFhVT1MYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt # U3RhbXAgUENBIDIwMTACEzMAAAEm37pLIrmCggcAAAAAASYwDQYJYIZIAWUDBAIB # BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx # IgQgu2Zz2EvNBy9aFqBRxamGGOSJIIQp4WVbuXewwPpg9IwwgfoGCyqGSIb3DQEJ # EAIvMYHqMIHnMIHkMIG9BCA2/c/vnr1ecAzvapOWZ2xGfAkzrkfpGcrvMW07CQl1 # DzCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABJt+6 # SyK5goIHAAAAAAEmMCIEIFS6Rd6vQMMD2UH0fzMeQCANX+D9cQukl40weweg2gQK # MA0GCSqGSIb3DQEBCwUABIIBACA1wNIn7sNmtK4PJOAJ+WYjtvKX6o2h1hCY+gE3 # C3a+lieukdqipQfhnqSXioV4Z2sgqu27fqdRxjeMJbGFqDDmWRayHgw87aPn5qms # Gs4LUpiF7LnO9XZETDzxOyEdj2plTd26O9LN4MqX42TrUBi1XCVgFa1YHCJ0CDgj # exWNanLFA3cIwkHIajYDRRD75IRx8GGDcFVS0VJSLQzASJ5/U5rFmkNxa+D3o85v # KwkXJTend5rHa9eTQ3RDeQzDxmGsr8CMg/kdFoNX4+DsW3/vM15lTmeJBXHLIT1i # sRfRpHzk8vCliEo1K86aEd0CCyqt1f8EBK5mWD/qCTy1S1Q= # SIG # End signature block |