Src/Plugins/Word/Out-WordDocument.ps1

function Out-WordDocument
{
<#
    .SYNOPSIS
        Microsoft Word output plugin for PScribo.

    .DESCRIPTION
        Outputs a Word document representation of a PScribo document object.
  #>

    [CmdletBinding()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', 'pluginName')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter','Options')]
    [OutputType([System.IO.FileInfo])]
    param
    (
        ## ThePScribo document object to convert to a text document
        [Parameter(Mandatory, ValueFromPipeline)]
        [System.Management.Automation.PSObject] $Document,

        ## Output directory path for the .txt file
        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [ValidateNotNull()]
        [System.String] $Path,

        ### Hashtable of all plugin supported options
        [Parameter()]
        [AllowNull()]
        [System.Collections.Hashtable] $Options
    )
    process
    {
        $pluginName = 'Word'
        $stopwatch = [Diagnostics.Stopwatch]::StartNew()
        Write-PScriboMessage -Message ($localized.DocumentProcessingStarted -f $Document.Name)

        ## Generate the Word 'document.xml' document part
        $documentXml = Get-WordDocument -Document $Document

        ## Generate the Word 'styles.xml' document part
        $stylesXml = Get-WordStylesDocument -Styles $Document.Styles -TableStyles $Document.TableStyles

        ## Generate the Word 'settings.xml' document part
        $updateFields = (($Document.Properties['TOCs']) -and ($Document.Properties['TOCs'] -gt 0))
        $settingsXml = Get-WordSettingsDocument -UpdateFields:$updateFields

        #Convert relative or PSDrive based path to the absolute filesystem path
        $absolutePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
        $destinationPath = Join-Path -Path $absolutePath ('{0}.docx' -f $Document.Name)
        if ($PSVersionTable['PSEdition'] -ne 'Core')
        {
            ## "Unable to determine the identity of the domain" fix (https://github.com/AsBuiltReport/AsBuiltReport.Core/issues/17)
            $currentAppDomain = [System.Threading.Thread]::GetDomain()
            $securityIdentityField = $currentAppDomain.GetType().GetField("_SecurityIdentity", ([System.Reflection.BindingFlags]::Instance -bOr [System.Reflection.BindingFlags]::NonPublic))
            $replacementEvidence = New-Object -TypeName 'System.Security.Policy.Evidence'
            $securityZoneMyComputer = New-Object -TypeName 'System.Security.Policy.Zone' -ArgumentList @([System.Security.SecurityZone]::MyComputer)
            $replacementEvidence.AddHost($securityZoneMyComputer)
            $securityIdentityField.SetValue($currentAppDomain, $replacementEvidence)
            ## WindowsBase.dll is not included in Core PowerShell
            Add-Type -AssemblyName WindowsBase
        }
        try
        {
            $package = [System.IO.Packaging.Package]::Open($destinationPath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::ReadWrite)
        }
        catch
        {
            Write-PScriboMessage -Message ($localized.OpenPackageError -f $destinationPath) -IsWarning
            throw $_
        }

        ## Create document.xml part
        $documentUri = New-Object -TypeName System.Uri -ArgumentList ('/word/document.xml', [System.UriKind]::Relative)
        Write-PScriboMessage -Message ($localized.ProcessingDocumentPart -f $documentUri)
        $documentPart = $package.CreatePart($documentUri, 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml')
        $streamWriter = New-Object -TypeName System.IO.StreamWriter -ArgumentList ($documentPart.GetStream([System.IO.FileMode]::Create, [System.IO.FileAccess]::ReadWrite))
        $xmlWriter = [System.Xml.XmlWriter]::Create($streamWriter)
        Write-PScriboMessage -Message ($localized.WritingDocumentPart -f $documentUri)
        $documentXml.Save($xmlWriter)
        $xmlWriter.Dispose()
        $streamWriter.Close()

        ## Create styles.xml part
        $stylesUri = New-Object -TypeName System.Uri -ArgumentList ('/word/styles.xml', [System.UriKind]::Relative)
        Write-PScriboMessage -Message ($localized.ProcessingDocumentPart -f $stylesUri)
        $stylesPart = $package.CreatePart($stylesUri, 'application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml')
        $streamWriter = New-Object -TypeName System.IO.StreamWriter -ArgumentList ($stylesPart.GetStream([System.IO.FileMode]::Create, [System.IO.FileAccess]::ReadWrite))
        $xmlWriter = [System.Xml.XmlWriter]::Create($streamWriter)
        Write-PScriboMessage -Message ($localized.WritingDocumentPart -f $stylesUri)
        $stylesXml.Save($xmlWriter)
        $xmlWriter.Dispose()
        $streamWriter.Close()

        ## Create settings.xml part
        $settingsUri = New-Object -TypeName System.Uri -ArgumentList ('/word/settings.xml', [System.UriKind]::Relative)
        Write-PScriboMessage -Message ($localized.ProcessingDocumentPart -f $settingsUri)
        $settingsPart = $package.CreatePart($settingsUri, 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml')
        $streamWriter = New-Object -TypeName System.IO.StreamWriter -ArgumentList ($settingsPart.GetStream([System.IO.FileMode]::Create, [System.IO.FileAccess]::ReadWrite))
        $xmlWriter = [System.Xml.XmlWriter]::Create($streamWriter)
        Write-PScriboMessage -Message ($localized.WritingDocumentPart -f $settingsUri)
        $settingsXml.Save($xmlWriter)
        $xmlWriter.Dispose()
        $streamWriter.Close()

        Out-WordHeaderFooterDocument -Document $Document -Package $package

        ## Create the Package relationships
        Write-PScriboMessage -Message $localized.GeneratingPackageRelationships
        $officeDocumentUri = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument'
        $stylesDocumentUri = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles'
        $settingsDocumentUri = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings'

        [ref] $null = $package.CreateRelationship($documentUri, [System.IO.Packaging.TargetMode]::Internal, $officeDocumentUri, 'rId1')
        [ref] $null = $documentPart.CreateRelationship($stylesUri, [System.IO.Packaging.TargetMode]::Internal, $stylesDocumentUri, 'rId1')
        [ref] $null = $documentPart.CreateRelationship($settingsUri, [System.IO.Packaging.TargetMode]::Internal, $settingsDocumentUri, 'rId2')

        $headerDocumentUri = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/header'
        if ($Document.Header.HasFirstPageHeader)
        {
            $firstPageHeaderUri = New-Object -TypeName System.Uri -ArgumentList ('/word/firstPageHeader.xml', [System.UriKind]::Relative)
            [ref] $null = $documentPart.CreateRelationship($firstPageHeaderUri, [System.IO.Packaging.TargetMode]::Internal, $headerDocumentUri, 'rId3')
        }
        if ($Document.Header.HasDefaultHeader)
        {
            $defaultHeaderUri = New-Object -TypeName System.Uri -ArgumentList ('/word/defaultHeader.xml', [System.UriKind]::Relative)
            [ref] $null = $documentPart.CreateRelationship($defaultHeaderUri, [System.IO.Packaging.TargetMode]::Internal, $headerDocumentUri, 'rId4')
        }

        $footerDocumentUri = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer'
        if ($Document.Footer.HasFirstPageFooter)
        {
            $firstPageFooterUri = New-Object -TypeName System.Uri -ArgumentList ('/word/firstPageFooter.xml', [System.UriKind]::Relative)
            [ref] $null = $documentPart.CreateRelationship($firstPageFooterUri, [System.IO.Packaging.TargetMode]::Internal, $footerDocumentUri, 'rId5')
        }
        if ($Document.Footer.HasDefaultFooter)
        {
            $defaultFooterUri = New-Object -TypeName System.Uri -ArgumentList ('/word/defaultFooter.xml', [System.UriKind]::Relative)
            [ref] $null = $documentPart.CreateRelationship($defaultFooterUri, [System.IO.Packaging.TargetMode]::Internal, $footerDocumentUri, 'rId6')
        }

        ## Process images (assuming we have a section, e.g. example03.ps1)
        if ($Document.Sections.Count -gt 0)
        {
            $imageDocumentUri = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'
            foreach ($image in (Get-PScriboImage -Section $Document.Sections))
            {
                try
                {
                    $uri = ('/word/media/{0}' -f $image.Name)
                    $partName = New-Object -TypeName 'System.Uri' -ArgumentList ($uri, [System.UriKind]'Relative')
                    $part = $package.CreatePart($partName, $image.MimeType)
                    $stream = $part.GetStream()
                    $stream.Write($image.Bytes, 0, $image.Bytes.Length)
                    $stream.Close()
                    [ref] $null = $documentPart.CreateRelationship($partName, [System.IO.Packaging.TargetMode]::Internal, $imageDocumentUri, $image.Name)
                }
                catch
                {
                    throw $_
                }
                finally
                {
                    if ($null -ne $stream) { $stream.Close() }
                }
            }
        }

        $package.Flush()
        $package.Close()
        $stopwatch.Stop()
        Write-PScriboMessage -Message ($localized.DocumentProcessingCompleted -f $Document.Name)

        if ($stopwatch.Elapsed.TotalSeconds -gt 90)
        {
            Write-PScriboMessage -Message ($localized.TotalProcessingTimeMinutes -f $stopwatch.Elapsed.TotalMinutes)
        }
        else
        {
            Write-PScriboMessage -Message ($localized.TotalProcessingTimeSeconds -f $stopwatch.Elapsed.TotalSeconds)
        }

        Write-Output -InputObject (Get-Item -Path $destinationPath)
    }
}

# SIG # Begin signature block
# MIIhZwYJKoZIhvcNAQcCoIIhWDCCIVQCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUnYJApmBhAJvZPEywAVYdM6mH
# ZaegghsPMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0B
# AQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVk
# IFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYD
# VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lD
# ZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIIC
# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKR
# N6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZz
# lm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1Oco
# LevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH
# 92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRA
# p8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+g
# GkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU
# 8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/
# FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwj
# jVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQ
# EgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUae
# tdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAw
# HQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LS
# cV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEF
# BQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
# Z2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYy
# aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5j
# cmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEB
# CwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftw
# ig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalW
# zxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQm
# h2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScb
# qyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLaf
# zYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbD
# Qc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0K
# XzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm
# 8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9
# gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8a
# pIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBrAwggSY
# oAMCAQICEAitQLJg0pxMn17Nqb2TrtkwDQYJKoZIhvcNAQEMBQAwYjELMAkGA1UE
# BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj
# ZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTIx
# MDQyOTAwMDAwMFoXDTM2MDQyODIzNTk1OVowaTELMAkGA1UEBhMCVVMxFzAVBgNV
# BAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0
# IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMTCCAiIwDQYJKoZI
# hvcNAQEBBQADggIPADCCAgoCggIBANW0L0LQKK14t13VOVkbsYhC9TOM6z2Bl3DF
# u8SFJjCfpI5o2Fz16zQkB+FLT9N4Q/QX1x7a+dLVZxpSTw6hV/yImcGRzIEDPk1w
# JGSzjeIIfTR9TIBXEmtDmpnyxTsf8u/LR1oTpkyzASAl8xDTi7L7CPCK4J0JwGWn
# +piASTWHPVEZ6JAheEUuoZ8s4RjCGszF7pNJcEIyj/vG6hzzZWiRok1MghFIUmje
# EL0UV13oGBNlxX+yT4UsSKRWhDXW+S6cqgAV0Tf+GgaUwnzI6hsy5srC9KejAw50
# pa85tqtgEuPo1rn3MeHcreQYoNjBI0dHs6EPbqOrbZgGgxu3amct0r1EGpIQgY+w
# OwnXx5syWsL/amBUi0nBk+3htFzgb+sm+YzVsvk4EObqzpH1vtP7b5NhNFy8k0Uo
# gzYqZihfsHPOiyYlBrKD1Fz2FRlM7WLgXjPy6OjsCqewAyuRsjZ5vvetCB51pmXM
# u+NIUPN3kRr+21CiRshhWJj1fAIWPIMorTmG7NS3DVPQ+EfmdTCN7DCTdhSmW0td
# dGFNPxKRdt6/WMtyEClB8NXFbSZ2aBFBE1ia3CYrAfSJTVnbeM+BSj5AR1/JgVBz
# hRAjIVlgimRUwcwhGug4GXxmHM14OEUwmU//Y09Mu6oNCFNBfFg9R7P6tuyMMgkC
# zGw8DFYRAgMBAAGjggFZMIIBVTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW
# BBRoN+Drtjv4XxGG+/5hewiIZfROQjAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/
# 57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYI
# KwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
# b20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9j
# cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3JsMBwGA1Ud
# IAQVMBMwBwYFZ4EMAQMwCAYGZ4EMAQQBMA0GCSqGSIb3DQEBDAUAA4ICAQA6I0Q9
# jQh27o+8OpnTVuACGqX4SDTzLLbmdGb3lHKxAMqvbDAnExKekESfS/2eo3wm1Te8
# Ol1IbZXVP0n0J7sWgUVQ/Zy9toXgdn43ccsi91qqkM/1k2rj6yDR1VB5iJqKisG2
# vaFIGH7c2IAaERkYzWGZgVb2yeN258TkG19D+D6U/3Y5PZ7Umc9K3SjrXyahlVhI
# 1Rr+1yc//ZDRdobdHLBgXPMNqO7giaG9OeE4Ttpuuzad++UhU1rDyulq8aI+20O4
# M8hPOBSSmfXdzlRt2V0CFB9AM3wD4pWywiF1c1LLRtjENByipUuNzW92NyyFPxrO
# JukYvpAHsEN/lYgggnDwzMrv/Sk1XB+JOFX3N4qLCaHLC+kxGv8uGVw5ceG+nKcK
# BtYmZ7eS5k5f3nqsSc8upHSSrds8pJyGH+PBVhsrI/+PteqIe3Br5qC6/To/RabE
# 6BaRUotBwEiES5ZNq0RA443wFSjO7fEYVgcqLxDEDAhkPDOPriiMPMuPiAsNvzv0
# zh57ju+168u38HcT5ucoP6wSrqUvImxB+YJcFWbMbA7KxYbD9iYzDAdLoNMHAmpq
# QDBISzSoUSC7rRuFCOJZDW3KBVAr6kocnqX9oKcfBnTn8tZSkP2vhUgh+Vc7tJwD
# 7YZF9LRhbr9o4iZghurIr6n+lB3nYxs6hlZ4TjCCBsYwggSuoAMCAQICEAp6Soie
# yZlCkAZjOE2Gl50wDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNV
# BAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0
# IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yMjAzMjkwMDAwMDBa
# Fw0zMzAzMTQyMzU5NTlaMEwxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2Vy
# dCwgSW5jLjEkMCIGA1UEAxMbRGlnaUNlcnQgVGltZXN0YW1wIDIwMjIgLSAyMIIC
# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuSqWI6ZcvF/WSfAVghj0M+7M
# XGzj4CUu0jHkPECu+6vE43hdflw26vUljUOjges4Y/k8iGnePNIwUQ0xB7pGbumj
# S0joiUF/DbLW+YTxmD4LvwqEEnFsoWImAdPOw2z9rDt+3Cocqb0wxhbY2rzrsvGD
# 0Z/NCcW5QWpFQiNBWvhg02UsPn5evZan8Pyx9PQoz0J5HzvHkwdoaOVENFJfD1De
# 1FksRHTAMkcZW+KYLo/Qyj//xmfPPJOVToTpdhiYmREUxSsMoDPbTSSF6IKU4S8D
# 7n+FAsmG4dUYFLcERfPgOL2ivXpxmOwV5/0u7NKbAIqsHY07gGj+0FmYJs7g7a5/
# KC7CnuALS8gI0TK7g/ojPNn/0oy790Mj3+fDWgVifnAs5SuyPWPqyK6BIGtDich+
# X7Aa3Rm9n3RBCq+5jgnTdKEvsFR2wZBPlOyGYf/bES+SAzDOMLeLD11Es0MdI1DN
# kdcvnfv8zbHBp8QOxO9APhk6AtQxqWmgSfl14ZvoaORqDI/r5LEhe4ZnWH5/H+gr
# 5BSyFtaBocraMJBr7m91wLA2JrIIO/+9vn9sExjfxm2keUmti39hhwVo99Rw40KV
# 6J67m0uy4rZBPeevpxooya1hsKBBGBlO7UebYZXtPgthWuo+epiSUc0/yUTngIsp
# QnL3ebLdhOon7v59emsCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNV
# HRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYG
# Z4EMAQQCMAsGCWCGSAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGog
# j57IbzAdBgNVHQ4EFgQUjWS3iSH+VlhEhGGn6m8cNo/drw0wWgYDVR0fBFMwUTBP
# oE2gS4ZJaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0
# UlNBNDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMw
# gYAwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEF
# BQcwAoZMaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3Rl
# ZEc0UlNBNDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsF
# AAOCAgEADS0jdKbR9fjqS5k/AeT2DOSvFp3Zs4yXgimcQ28BLas4tXARv4QZiz9d
# 5YZPvpM63io5WjlO2IRZpbwbmKrobO/RSGkZOFvPiTkdcHDZTt8jImzV3/ZZy6HC
# 6kx2yqHcoSuWuJtVqRprfdH1AglPgtalc4jEmIDf7kmVt7PMxafuDuHvHjiKn+8R
# yTFKWLbfOHzL+lz35FO/bgp8ftfemNUpZYkPopzAZfQBImXH6l50pls1klB89Bem
# h2RPPkaJFmMga8vye9A140pwSKm25x1gvQQiFSVwBnKpRDtpRxHT7unHoD5PELkw
# NuTzqmkJqIt+ZKJllBH7bjLx9bs4rc3AkxHVMnhKSzcqTPNc3LaFwLtwMFV41pj+
# VG1/calIGnjdRncuG3rAM4r4SiiMEqhzzy350yPynhngDZQooOvbGlGglYKOKGuk
# zp123qlzqkhqWUOuX+r4DwZCnd8GaJb+KqB0W2Nm3mssuHiqTXBt8CzxBxV+NbTm
# tQyimaXXFWs1DoXW4CzM4AwkuHxSCx6ZfO/IyMWMWGmvqz3hz8x9Fa4Uv4px38qX
# sdhH6hyF4EVOEhwUKVjMb9N/y77BDkpvIJyu2XMyWQjnLZKhGhH+MpimXSuX4IvT
# nMxttQ2uR2M4RxdbbxPaahBuH0m3RFu0CAqHWlkEdhGhp3cCExwwggbbMIIEw6AD
# AgECAhAEyswKPFRr9qgYCxGuzc8mMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYT
# AlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQg
# VHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTEw
# HhcNMjExMDE5MDAwMDAwWhcNMjMxMTA0MjM1OTU5WjBgMQswCQYDVQQGEwJHQjEP
# MA0GA1UEBxMGTG9uZG9uMR8wHQYDVQQKExZWaXJ0dWFsIEVuZ2luZSBMaW1pdGVk
# MR8wHQYDVQQDExZWaXJ0dWFsIEVuZ2luZSBMaW1pdGVkMIIBojANBgkqhkiG9w0B
# AQEFAAOCAY8AMIIBigKCAYEAtbm3o57mQYxu0idSifhlyZaDVO0Zu0BnGTFZOtZL
# ibBotgpKp7Be3k9WDyIbOiUHVaFY7DG8aL8krpArj+3KJR49U5pLXcevNUQFLL18
# pi9lZ+e2w+dcBAfuJ30J760VtPDwAA7nmAff3f9o+tEB1ZnIeXzlPRyMz7YZS43s
# DeAft8p8jFzmM0jRtt9SXNxKcC0gnX6Cx0vw4AkxmMtreX/Igvj5VVq4M81E84Ce
# fWsU/IpqIL24xpxl3OOwZ53wzn+rPA3T9bj0PUyI/6VvONUIRD/EfODxurVdSDdu
# LHsRag4+Q3xFvZm/WNqsr2qGv7LHT3uKPsjuPBo1Mz9fM/AfPwdEfM3xJ+Y1rBqU
# xnDhwYS97Fw3LM63lTKl3bN4TOFEJX8YPgC02J4vzYSIP0fwBBPyd7MtbiXzFvSo
# Xnl0EQmjH+k4fjOCwn1tgWnI77NET05Jd06F3Od52In9qIJ5Bhu4zlMFEQgE7JON
# OI4/Hl/dBzfNkyItMMRcNiPJAgMBAAGjggIGMIICAjAfBgNVHSMEGDAWgBRoN+Dr
# tjv4XxGG+/5hewiIZfROQjAdBgNVHQ4EFgQUEr+p1bWwrT+zl6+TXhHWz9ewYuAw
# DgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0w
# gaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0
# ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1o
# dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2ln
# bmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDA+BgNVHSAENzA1MDMGBmeBDAEE
# ATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQG
# CCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
# dC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E
# aWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEu
# Y3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAB35Ee2voPHjrdDl
# B80kocW2ZrVcKO5/POchPOvxL1evXPdoaexNDCwXzM/6GXa4U1VhV+GqbeQ+JCZF
# XWbiycxqXEfi5fxj2sRzdF3CDootFiqxK1eqz2W82KR5FX45LTsQMrg6O8kA2nb2
# eBxk6TWYUtS+3jtdS/nwDp/B/A+ol0CaD51hlzq9QY0NNkwsbZ+fKmIxinqEFF6n
# taOmQNWS0EOtNQBYdlf0pNThBuPxENsDtWRS56pg3qfl3+khteed8sFoyY/9g1So
# fbc7DAQiYtTikmekA+s5WkHY1ewiSF/NcXSNNMNgbuAsizoMQ9NkJ/vMhs89+hNU
# e6Tlk9bFffOP9oh5z6Df/XHJslhNY3DxWYQQxtqzZpAk/4GCJ8L9qdeEDvtulPp3
# p6VqNBxQPu98C46pfXgCX0vIieVy3RZOhHD2JCytWNFWXJFvoo03akcyTumiq2+m
# ew6ALwXKKtFeoDHfnzDkVsZRPqY49gECVKifY7Z7Usuf3SBOB6txOlzK15eMR2EI
# RsBSCPVZCevU9z51DP/GLZ6/kCDG6hcu6isenIWAxWw1wiGv6HJpca73ummRYoUe
# KtNV8hg7ItlPimtrjjoT+0ciE8Ohuv5GDBqK0GE4ikCIUZyFg74ppkHV4q+YghXv
# ubkwMSV7ymFRKhgcGQLlDXP+OaVQMYIFwjCCBb4CAQEwfTBpMQswCQYDVQQGEwJV
# UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRy
# dXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAE
# yswKPFRr9qgYCxGuzc8mMAkGBSsOAwIaBQCgeDAYBgorBgEEAYI3AgEMMQowCKAC
# gAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsx
# DjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBTiz3zzR26Mnl6JmTa+hTV9
# zobzzDANBgkqhkiG9w0BAQEFAASCAYAGTGlnxK3lE36JLDCP2ErirruxjZGrFI5y
# 4E9ACv8Ipfx+Hp7iiV9JKvFIxyNaVVbFyak4Ke9dTOnmq+pwPbtT7+6Om9GZWBkC
# FXS7k0T5JPe5BGIZORqORSSKYSvn4mYwmqc+T9sBV7LlIoGBQPkgMtWgmbm4Ap9Q
# MZJcpMF48pCwTIugbl79whUrmggN81K+i4zYo1mp7u+1O/q8s8/bNzZMGyd8ZHty
# D44NsB17SRZPm7CQNwQSBJdvhPaNVFwOAMameoJT3qSMLh6+gLYpUSv9NT0ZHbtK
# lzmyBnuXdaBb42L0qqf5n2OSw+7Q4AFOd0AW7LMHbOqYGAOWSzKrgVUCOkzFTSUG
# YrlARIuLSajKNb12LXh8gDlhQfBDOyIe4NqO2O1bvjwQLChn1oVW4SJKWtFQemtA
# kCoeMkJgY/8hs8cbyvg1MSJpGKxR2PKH4ZHvl8oP4e+MnvmkWHrTm48HkSHFAwLr
# b/eDLRd9bwv1jvCEuPhjVkJ5LXn85JihggMgMIIDHAYJKoZIhvcNAQkGMYIDDTCC
# AwkCAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x
# OzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGlt
# ZVN0YW1waW5nIENBAhAKekqInsmZQpAGYzhNhpedMA0GCWCGSAFlAwQCAQUAoGkw
# GAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjIwNDIw
# MTUwNDM2WjAvBgkqhkiG9w0BCQQxIgQgI1MTDicLyMZDlYBe9fv3/n6/dY2Xu61y
# /3suJ2gJMLEwDQYJKoZIhvcNAQEBBQAEggIAGd377wwThBLTV/M7LxxLP4IhsRdb
# h/ogGZpc7cT3EmuxnGjnqW6p2WynDn6HxlFMvZLkO7O21yIOpw8REpnCF/HfkNXo
# g7vIdutdneD5LvapCGJ0sp000jM2ZaPTK99+N+eo2xJoYyESZe+4Y/MBSzKmjF4O
# zj6b9Vx8GBJFrJUXosOZfctbuCLZrGA94Zm15hFzZKXkpr0+bh3OxdM+P6/DuD6w
# 5VP47/HS4qa5ENOcGGg67kmLHg4a3FyPnmY0W1bAo+ylBctG0aozG4gV6Ovrb3tt
# okFdDCk48CWj54ueAZGuymUQchizYS8soLj5HarYouNl0Lho90P8xEN7U4kIegz8
# was6V3h+glkUwM+z4b/pVqjyjEsRMJA8+HGH3LHs7utz9wnnNVZrxM4afBqs419O
# FDFTJHXyt6hDkwuSrHf8ms3hXdQmNsu+LaXMoQxEh6ygY2BUzxh+R2GzEPTf4oQi
# U/itSMYwVmlKusUdf5EW/+SzF0bWoSX9D3Za2q5CiEKSLtamXynJOKCOShYGzc4o
# 75VCLafvYsCUtpMqAnifyjFPr8AA5M1i9WyjMdfA4ykgMz94n0XHadIbW5DLKQGy
# l7h720NffthrmO/IVxZT+9BU1weLVxp1LrIhCshqy8OBSd1URo96TT3ovOY3br+P
# ZjucmLk7kO0XFJs=
# SIG # End signature block