param
(
    [parameter(Position=0,Mandatory=$false)][boolean] $useServiceFabric=$false 
)

Import-Module "$PSScriptRoot\CommonRollbackUtilities.psm1"  -ArgumentList $useServiceFabric -DisableNameChecking

$script:EnvDllsLoaded = $false
function Get-ApplicationEnvironment
{
    $ErrorActionPreference = 'Stop'

    if (-not $script:EnvDllsLoaded)
    {        
        $webroot = Get-AosWebSitePhysicalPath
        $InstalledPlatformBuildVersion = Get-ProductPlatformBuildFullVersion
        $isKeyVault = Get-IsMSIKeyVault

        if (($isKeyVault -eq $true) -and ($InstalledPlatformBuildVersion -ne $null) -and ($InstalledPlatformBuildVersion.Build -ge 5644))
        {        
            # Get-PackageRoot comes from CommonRollbackUtilities.psm1. it resolves the root of the deployable package
            $packageRoot = Get-PackageRoot
            $packageTemp = ""

            if(![string]::IsNullOrEmpty($packageRoot) -and (Test-Path $packageRoot))
            {
                $packageTemp = Join-Path $packageRoot "RunbookWorkingFolder\KeyVaultAssemblyTemp"
            }

            if ([string]::IsNullOrEmpty($packageTemp))
            {   
                $suffix = $(Get-Date).ToString("yyyyMMdd_HHmmss")
                $dirName = "AssemblyTemp_$suffix"
                $packageTemp = Join-Path $env:Temp "dirName"
            }

            if(!(Test-Path $packageTemp -PathType Container))
            {
                New-Item $packageTemp -ItemType Container | Out-Null
            }
        
            #need to load the Microsoft.Dynamics.ApplicationPlatform.Environment.dll and all the dll it referenced
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.Environment.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Configuration.Base.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Security.Instrumentation.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Security.KeyVaultHelper.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Carbon.Flighting.Runtime.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Carbon.CertificateCommon.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Commerce.Flighting.Common.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.Flighting.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.CE.VaultSDK.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.CE.VaultSDK.ADALv2.AuthHelper.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Azure.KeyVault.Core.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Azure.KeyVault.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Azure.Common.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Azure.Common.NetFramework.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Hyak.Common.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Authentication.Instrumentation.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Threading.Tasks.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Threading.Tasks.Extensions.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Threading.Tasks.Extensions.Desktop.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Newtonsoft.Json.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Security.SharedUtility.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp            

            try
            {
                $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.Environment.dll'
                $fileTempPath =  Join-Path $packageTemp $(Get-Item $dllPath).Name
                if (Test-Path $fileTempPath)
                {
                    # Load file from temp folder
                    [System.Reflection.Assembly]::LoadFrom($fileTempPath)
                }
            }
            catch
            {    
                #write-log "Failed to load from temp folder with Exception: [$($_.Exception)]"
                throw $_
            }
        }              
        else
        {
            #need to load the Microsoft.Dynamics.ApplicationPlatform.Environment.dll and all the dll it referenced
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.Environment.dll'
            Load-DllinMemory -dllPath $dllPath
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Configuration.Base.dll'
            Load-DllinMemory -dllPath $dllPath
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Security.Instrumentation.dll'
            if (Test-Path $dllPath)
            {
                Load-DllinMemory -dllPath $dllPath
            }
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll'
            Load-DllinMemory -dllPath $dllPath
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll'
            Load-DllinMemory -dllPath $dllPath  
        }

        $script:EnvDllsLoaded = $true
    }

    $config = [Microsoft.Dynamics.ApplicationPlatform.Environment.EnvironmentFactory]::GetApplicationEnvironment()
    
    return $config
}

function Load-DllinMemory([string] $dllPath)
{
    #try catch as not all dll exist in RTM version, some dependency/dll are introduced at update 1 or later
    #powershell cannot unload dll once it's loaded, the trick is to create an in-memory copy of the dll than load it
    #after the loading of in-memory dll, the physical dll stay unlocked

    try
    {
        if (Test-Path $dllPath)
        {
            $bytes = [System.IO.File]::ReadAllBytes($dllPath)
            [System.Reflection.Assembly]::Load($bytes) | Out-Null
        }
    }
    catch
    {}
}

function CopyDllToTempFolder([string] $dllPath, [string] $packageTemp)
{
    #try catch as not all dll exist in RTM version, some dependency/dll are introduced at update 1 or later    
    $fileTempPath =  Join-Path $packageTemp $(Get-Item $dllPath).Name
    try
    {
        if ((Test-Path $dllPath) -And !$(Test-Path $fileTempPath))
        {
            $Buffer = New-Object 'byte[]' 1024
            # Open file in read mode
            $SourceFile = [System.IO.File]::Open($dllPath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::Read)
            # Create the new file
            $DestinationFile = [System.IO.File]::Open($fileTempPath, [System.IO.FileMode]::CreateNew)
            try{
                # Copy the contents of the source file to the destination
                while(($readLength = $SourceFile.Read($Buffer, 0, $Buffer.Length)) -gt 0)
                {
                    $DestinationFile.Write($Buffer, 0, $readLength)
                }
            }
            catch{
                throw $_
            }
            finally{
                $SourceFile.Close()
                $DestinationFile.Close()
            }
        }
    }
    catch
    {
        Write-Log "Failed to copy file to temp folder with Exception: [$($_.Exception)]"
        throw $_
    }    
}

function Get-IsMSIKeyVault
{
    $webroot = Get-AosWebSitePhysicalPath
    $webconfig=join-path $webroot "web.config"
    $isMSIKeyVault=$false
    
    [System.Xml.XmlDocument] $xd=new-object System.Xml.XmlDocument
    $xd.Load($webconfig)
    $ns=New-Object System.Xml.XmlNamespaceManager($xd.NameTable)
    $ns.AddNamespace("ns",$xd.DocumentElement.NamespaceURI)

    $key="CertificateHandler.IsMSIKeyVault"

    $isKeyVaultValue = $xd.SelectSingleNode("//ns:add[@key='$key']",$ns)

    if($isKeyVaultValue -ne $null)
    {        
        $isMSIKeyVault = $isKeyVaultValue.GetAttribute("value")
    }

    return $isMSIKeyVault 
}

function GenerateMetadataModuleInstallationInfo
{
    try
    {
        $ErrorActionPreference = 'Stop'

        write-output "Creating Metadata Module Installation Info."
        
        $packagePath = Get-AOSPackageDirectory
        $CommonBin = $(Get-CommonBinDir)

        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.AX.AXInstallationInfo.dll'
        Load-DllinMemory -dllPath $dllPath
        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.AX.Metadata.Storage.dll'
        Load-DllinMemory -dllPath $dllPath
        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.AX.Metadata.dll'
        Load-DllinMemory -dllPath $dllPath
        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.AX.Metadata.Core.dll'
        Load-DllinMemory -dllPath $dllPath
        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll'
        Load-DllinMemory -dllPath $dllPath

        [Microsoft.Dynamics.AX.AXInstallationInfo.AXInstallationInfo]::ScanMetadataModelInRuntimePackage($packagePath)
    }
    catch
    {}
}

function Get-IsAppFallOrLater([Parameter(Mandatory=$false)] $webroot)
{
    $version = Get-ApplicationReleaseFromAOS -webroot:$webroot

    return $($version -ne "RTW")
}

function Get-ApplicationReleaseFromPackage
{
    $packageRoot = split-Path -parent "$(split-Path -parent $PSScriptRoot)" 
    $PackageInstallationInfo = "$packageRoot\HotfixInstallationInfo.xml"
    $XPath = '/HotfixInstallationInfo/ServiceModelList/ComponentModel/Release[../ServiceModelGroup = "Application"]'
    $ApplicationRelease =  Select-Xml -Path $PackageInstallationInfo -XPath $Xpath 
    $MRXPath = '/HotfixInstallationInfo/ServiceModelList/ComponentModel[Name = "MRApplicationService"]'
    $MRApplicationServiceModel =  Select-Xml -Path $PackageInstallationInfo -XPath $MRXpath 

    if($ApplicationRelease.Count -ge 1)
    {
        return $ApplicationRelease[0].Node.InnerText
    }
    elseif ($MRApplicationServiceModel -eq $null)
    {
        return ""
    }
    else
    {
        return "RTW"
    }
}

function Get-IsModulePartOfPlatformAsBinary ([string] $packageNugetFile)
{
    [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') 

    try
    {
        $PackFiles = [IO.Compression.ZipFile]::OpenRead($packageNugetFile)
        $PackageSpec =  $PackFiles.Entries | where {($_.Name -like '*.nuspec')}

        if(!($PackageSpec))
        {
            Throw "Unable to get package information"
        }

        [System.Xml.XmlDocument] $xmlDoc = New-Object System.Xml.XmlDocument
        $XmlDoc.Load($PackageSpec.Open())

        $PackFiles.Dispose()

        $Description = $xmlDoc.GetElementsByTagName('description').Item(0).InnerText

        if($Description.Contains("[Platform Package]"))
        {
            return $true
        }
        else
        {
            return $false
        }        
    }
    catch
    {
        return $false
    }
}

function Get-IsModulePartOfApplicationAsBinary ([string] $PackageNugetFilePath)
{
    [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') 

    try
    {
        $PackFiles = [IO.Compression.ZipFile]::OpenRead($PackageNugetFilePath)
        $PackageSpec =  $PackFiles.Entries | Where-Object {($_.Name -like '*.nuspec')}

        if(!($PackageSpec))
        {
            Throw "Unable to get package information"
        }

        [System.Xml.XmlDocument] $xmlDoc=new-object System.Xml.XmlDocument
        $XmlDoc.Load($PackageSpec.Open())

        $PackFiles.Dispose()

        $Description = $xmlDoc.GetElementsByTagName('description').Item(0).InnerText

        if($Description.Contains("[Application Package]"))
        {
            return $true
        }
        else
        {
            return $false
        }
    }
    catch
    {
        return $false
    }
}

function Get-IsPlatformUpdate3OrLater([Parameter(Mandatory=$false)] $webroot)
{
    if (!$webroot) {
    $webroot = Get-AosWebSitePhysicalPath
    }

    #must use job or process to load the production information provider dll or it'll lock it self
    #in memory copy is not usable as this dll have some special hard coded reference dll which won't resolve when loaded in memory.
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock)
        $VersionDLLPath = Join-Path $webrootBlock 'bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll'
        Add-Type -Path $VersionDLLPath
        $provider = [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider();
        $version = $provider.get_PlatformVersion();
        $version
    } -ArgumentList $webroot
    Wait-Job -Job $job | Out-Null
    $version = Receive-Job -Job $job

    return $(($version -ne '7.0') -and ($version -ne '7.0.0.0') -and (![string]::IsNullOrEmpty($version)))    
}

function Get-IsPackageContainUpgradeBinaryForUpdate3
{
    $sourcePath = [IO.Path]::Combine($(split-Path -parent $PSScriptRoot), "Packages")
    #using a framework package from platform which customer cannot generate to identify if it's from platform update 3
    $files=get-childitem -Path:$sourcePath dynamicsax-framework-bin.*.nupkg
    foreach ($packageFile in $files) 
    {
        if(Get-IsModulePartOfPlatformAsBinary -packageNugetFile $packageFile.FullName)
        {
            return $true
        }
    }

    return $false
}

function Get-ProductPlatformBuildVersion([Parameter(Mandatory=$false)] $webroot)
{
    if (!$webroot) {
       $webroot = Get-AosWebSitePhysicalPath
    }

    #must use job or process to load the production information provider dll or it'll lock it self
    #in memory copy is not usable as this dll have some special hard coded reference dll which won't resolve when loaded in memory.
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock)
        $VersionDLLPath = Join-Path $webrootBlock 'bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll'
        Add-Type -Path $VersionDLLPath
        $provider = [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider();
        $version = $provider.get_PlatformBuildVersion();
        $version
    } -ArgumentList $webroot
    Wait-Job -Job $job | Out-Null
    $version = Receive-Job -Job $job
   
    $build = [System.Version]::new()
    $releaseBuild
    if([System.Version]::TryParse($Version, [ref]$build))
    {
        $releaseBuild = $build.Build
    }
    else
    {
        #default to 0 from 7.0.0.0 
        $releaseBuild = 0
    }   

    return  $releaseBuild
}

function Get-ProductPlatformBuildFullVersion
{
    $webroot = Get-AosWebSitePhysicalPath

    #must use job or process to load the production information provider dll or it'll lock it self
    #in memory copy is not usable as this dll have some special hard coded reference dll which won't resolve when loaded in memory.
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock)
        $VersionDLLPath = Join-Path $webrootBlock 'bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll'
        Add-Type -Path $VersionDLLPath
        $provider = [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider();
        $version = $provider.get_PlatformBuildVersion();
        $version
    } -ArgumentList $webroot
    Wait-Job -Job $job | Out-Null
    $version = Receive-Job -Job $job
   
    $build = [System.Version]::new()
    
    if([System.Version]::TryParse($Version, [ref]$build))
    {
        return $build
    }
    
    return $null
}

function Get-ProductApplicationVersion ([Parameter(Mandatory=$false)] $webroot)
{
    if($webroot -eq $null)
    {
        $webroot = Get-AosWebSitePhysicalPath
    }

    #must use job or process to load the production information provider dll or it'll lock it self
    #in memory copy is not usable as this dll have some special hard coded reference dll which won't resolve when loaded in memory.
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock)
        $VersionDLLPath = Join-Path $webrootBlock 'bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll'
        Add-Type -Path $VersionDLLPath
        $provider = [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider();
        $version = $provider.get_ApplicationBuildVersion();
        $version
    } -ArgumentList $webroot
    Wait-Job -Job $job | Out-Null
    $version = Receive-Job -Job $job    
    
    return  $version
}

function Get-DataAccessSqlPwd
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.SqlPwd
}

function Get-DataAccessDatabase
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.Database
}

function Get-DataAccessSqlUsr
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.SqlUser
}

function Get-DataAccessDbServer
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.DbServer
}


function Get-AOSPackageDirectory
{
    $Config = Get-ApplicationEnvironment
    return $Config.Aos.PackageDirectory
}

function Get-CommonBinDir
{
    $Config = Get-ApplicationEnvironment
    return $Config.Common.BinDir
}

function Get-BiReportingPersistentVirtualMachineIPAddressSSRS
{
    $Config = Get-ApplicationEnvironment
    return $Config.BiReporting.PersistentVirtualMachineIPAddressSSRS
}

function Get-BiReportingReportingServers
{
    $Config = Get-ApplicationEnvironment
    $reportingServers = $Config.BiReporting.ReportingServers
    if ([System.String]::IsNullOrWhiteSpace($reportingServers))
    {
        $reportingServers = $Config.BiReporting.PersistentVirtualMachineIPAddressSSRS
    }

    return $reportingServers
}

function Get-UseReportingCluster
{
    $webRoot = Get-AosWebSitePhysicalPath
    $webConfigPath = join-path $webRoot "web.config"
    
    if(Test-Path $webConfigPath){
        [System.Xml.XmlDocument] $webConfig = new-object System.Xml.XmlDocument
        $webConfig.Load($webConfigPath)

        $ns = New-Object System.Xml.XmlNamespaceManager($webConfig.NameTable)
        $ns.AddNamespace("ns",$webConfig.DocumentElement.NamespaceURI)
        $key = "UseReportingCluster"
        $userClusterKey = $webConfig.SelectSingleNode("//ns:add[@key='$key']",$ns)

        if($null -ne $userClusterKey){
            if($userClusterKey.Value -eq $true){
                return $true
            }
        }
    }

    return $false
}

function Get-InfrastructureClickonceAppsDirectory
{
    $Config = Get-ApplicationEnvironment
    return $Config.Infrastructure.ClickonceAppsDirectory
}

function Get-DevToolsInstalled
{
    $webroot = Get-AosWebSitePhysicalPath
    $webconfig=join-path $webroot "web.config"
    $DevInstall=$false
    
    [System.Xml.XmlDocument] $xd=new-object System.Xml.XmlDocument
    $xd.Load($webconfig)
    $ns=New-Object System.Xml.XmlNamespaceManager($xd.NameTable)
    $ns.AddNamespace("ns",$xd.DocumentElement.NamespaceURI)

    $key="Infrastructure.VSToolsCount"

    $VScount = $xd.SelectSingleNode("//ns:add[@key='$key']",$ns)

    if($VScount -ne $null){
        
        if($VScount.GetAttribute("value") -gt 0)
        {
            $DevInstall=$true
        }
    }
    return $DevInstall 
}

function Get-ProductVersionMajorMinor
{
    [string]  $productVersionMajorMinorString = '7.0'
    return $productVersionMajorMinorString
}

function Get-IsRetailProductSku
{
    $productVersion = Get-ProductVersionMajorMinor    
    $retailHQConfigurationLocationRegistryPath = "HKLM:\SOFTWARE\Microsoft\Dynamics\$productVersion\Setup\Metadata"
    if(Test-Path $retailHQConfigurationLocationRegistryPath)
    {
        $retailProductSku = Get-ItemProperty -Path $retailHQConfigurationLocationRegistryPath -Name 'ProductSku' -ErrorAction SilentlyContinue
        
        if($retailProductSku -and $retailProductSku.ProductSku -and ($retailProductSku.ProductSku -eq 'Dynamics365ForRetail'))
        {
            return $true
        }
    }

    return $false
}

function Get-IsOverlayeringDisabled
{
    $productVersion = Get-ProductVersionMajorMinor    
    $retailHQConfigurationLocationRegistryPath = "HKLM:\SOFTWARE\Microsoft\Dynamics\$productVersion\Setup\Metadata"
    if(Test-Path $retailHQConfigurationLocationRegistryPath)
    {
        $isOverlayeringDisabled = Get-ItemProperty -Path $retailHQConfigurationLocationRegistryPath -Name 'DisableOverlayering' -ErrorAction SilentlyContinue
        
        if($isOverlayeringDisabled -and $isOverlayeringDisabled.DisableOverlayering -and ($isOverlayeringDisabled.DisableOverlayering -like 'true'))
        {
            return $true
        }
    }

    return $false
}

function Get-IsAppSealed ([Parameter(Mandatory=$false)] $webroot)
{
    if($webroot -eq $null)
    {
        $webroot = Get-AosWebSitePhysicalPath
    }

    $Version = (Get-ProductApplicationVersion -webroot:$webroot)
    $build = [System.Version]::new()
    $minSealedVersion = new-object System.Version "8.1"

    if([System.Version]::TryParse($Version, [ref]$build))
    {
        # Any build major/minor 8.1+ is considered sealed.
        if($build.CompareTo($minSealedVersion) -ge 0)
        {
           return $true
        }

        # Sealing logic for 8.0 and earlier
        if($build.Major -ge "8")
        {
            ##Bug 240512: Receipt designer bits are not updated with the uptake of latest binary hotfix
            ##The appseal have a different meaning during package deployment than development
            ##if the appSeal == true we expect full binary hotfix, other wise we expect seperate x++ hotfix and special handle the remaining mofule (ie, clickonce... package)
            ##the app8.0, even though it's sealed from dev point of view, it's still releasing seperate x++ hotfix and the special handling code path for none sealed need to be used during package deployment
            if($build.Minor -ge "1") 
            {
                return $true
            }
        }
        elseif($build.Minor -ge "2")
        {
            if($build.Build.ToString().StartsWith("2"))
            {
                return $true
            }
        }
    }
    
    return $false
    
}

function Get-DependencyAXModelList([string] $sourcePath, [string] $metaPackageName)
{
    $microsoftPackages = @()
    [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
    $zipFile = Get-Item $sourcePath\$metaPackageName*.nupkg
    if($zipFile -ne $null)
    {
        $PackFiles = [IO.Compression.ZipFile]::OpenRead($zipFile).Entries
        $PackageSpec =  $PackFiles | where {($_.Name -like "*.nuspec")}

        if(!($PackageSpec))
        {
            Throw "Unable to get package information for $metaPackageName"
        }

        [System.Xml.XmlDocument] $xmlDoc=new-object System.Xml.XmlDocument
        $XmlDoc.Load($PackageSpec.Open())

        $Dependencies = $xmlDoc.GetElementsByTagName('dependency').id
        
        foreach($d in $Dependencies)
        {
            $microsoftPackages += $d
        }
    }
    
    return $microsoftPackages
}

function Get-ALMPackageCopyPath
{
    [string]$ALMBackupPath = ""

    # Is the ALM Service registered (environment variable "DynamicsSDK" would be set)
    if ($env:DynamicsSDK)
    {
        $RegPath = "HKLM:\SOFTWARE\Microsoft\Dynamics\AX\7.0\SDK"

        [string]$ALMBackupPath = $null
        
        # Do not fail when registry key is not found
        try
        {
            # Get the Dynamics SDK (ALM Service) registry key (throws if not found).
            $RegKey = Get-ItemProperty -Path $RegPath
            if ($RegKey -ne $null)
            {
                # Check if backup path set in registry
                $ALMBackupPath = $RegKey.BackupPath
            }
        }
        catch
        {
        }
        
        # If path not found in registry, check default paths
        if (-not $ALMBackupPath)
        {
            if (Test-Path "I:\DynamicsBackup")
            {
                $ALMBackupPath = "I:\DynamicsBackup"
            }
            elseif (Test-Path "$($env:SystemDrive)\DynamicsBackup")
            {
                $ALMBackupPath = "$($env:SystemDrive)\DynamicsBackup"
            }
        }
    }

    return $ALMBackupPath
}

function Get-EnvironmentId
{
    $Config = Get-ApplicationEnvironment
    return $Config.LCS.LCSEnvironmentId
}

function Get-DataAccessFlightingCachePath
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.FlightingCachePath
}

function Get-DataAccessFlightingEnvironment
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.FlightingEnvironment
}

function Get-DataAccessFlightingCertificateThumbprint
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.FlightingCertificateThumbprint
}

function Get-DataAccessFlightingServiceCatalogID
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.FlightingServiceCatalogID
}

function Get-TenantDomainGUID
{
    $Config = Get-ApplicationEnvironment
    return $Config.Aad.TenantDomainGUID
}

function Get-AADTenantId
{
    $Config = Get-ApplicationEnvironment
    return $Config.Aad.AADTenantId
}

function Get-S2SCertificate
{
    try
    {
        $config = Get-ApplicationEnvironment
        $certHandlerSetttings = $config.CertificateHandler.GetCertificateHandlerSettings()

        $certificateHandler = [Microsoft.Dynamics.AX.Configuration.CertificateHandler.CertificateHandlerFactory]::CreateCertificateHandler($certHandlerSetttings)
    
        $s2sCertificate = $certificateHandler.GetSingleCertificateForId($config.Infrastructure.S2SCertThumbprint)

        return $s2sCertificate
    }
    catch
    {
        return $null
    }
}

function Load-FlightingDlls
{
    $webroot = Get-AosWebSitePhysicalPath

    Load-DllinMemory "$webroot\bin\Microsoft.Carbon.CertificateCommon.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Carbon.Flighting.Runtime.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Commerce.Flighting.Common.dll"

    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.Services.Instrumentation.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.AX.Data.Sql.Shared.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.Flighting.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.AOSFlighting.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.PerformanceCounters.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll"
    Load-DllinMemory "$webroot\bin\Newtonsoft.Json.dll"

    # Contained in XppServices.Instrumentation in earlier releases
    $dbSyncInstrumentationPath = "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.DatabaseSynchronize.Instrumentation.dll"
    if (Test-Path $dbSyncInstrumentationPath)
    {
        Load-DllinMemory $dbSyncInstrumentationPath
    }
}

$script:FlightingProvider = $null
function Get-IsFlightEnabled([string] $flightName)
{
    $ErrorActionPreference = 'Stop'

    if ([String]::IsNullOrWhiteSpace($flightName))
    {
        return $false
    }

    if ($script:FlightingProvider -eq $null)
    {
        $sqlPwd    = Get-DataAccessSqlPwd
        $sqlUser   = Get-DataAccessSqlUsr
        $sqlServer = Get-DataAccessDbServer
        $sqlDB     = Get-DataAccessDatabase
        $connectionString = "Data Source=$sqlServer; " +
            "Integrated Security=False; " +
            "User Id=$sqlUser; " +
            "Password=`"$sqlPwd`"; " +
            "Initial Catalog=$sqlDB"

        $flightingCacheFolder = Get-DataAccessFlightingCachePath
        if ([String]::IsNullOrWhiteSpace($flightingCacheFolder))
        {
            $flightingCacheFolder = Get-AosWebSitePhysicalPath # webroot
        }

        Load-FlightingDlls

        $flightingConfiguration = New-Object -TypeName Microsoft.Dynamics.ApplicationPlatform.AOSFlighting.StaticFlightingServiceConfiguration -ArgumentList `
            (Get-DataAccessFlightingEnvironment), `
            (Get-DataAccessFlightingCertificateThumbprint), `
            (Get-DataAccessFlightingServiceCatalogID), `
            $flightingCacheFolder, `
            $null, # object extraInformation `
            $connectionString, `
            (60 * 60) # int refreshDataIntervalInSec

        $script:FlightingProvider = [Microsoft.Dynamics.ApplicationPlatform.AOSFlighting.AOSFlightingSystem]::InitializeFlightService($flightingConfiguration)
        $script:FlightingProvider.AddInformationToCommonContext("TenantID", (Get-TenantDomainGUID))
        $script:FlightingProvider.AddInformationToCommonContext("EnvironmentId", (Get-EnvironmentId))

        Write-Log "Flighting provider is a $($script:FlightingProvider.GetType().Name)."
    }

    return $script:FlightingProvider.IsFeatureEnabled($flightName)
}

function IsLocalServer([string] $serverName)
{
    if ($serverName -eq $null) { return $false }
    
    if ("." -eq $serverName) { return $true }
    if ("(local)" -eq $serverName) { return $true }
    if ("localhost" -eq $serverName) { return $true }
    if ("127.0.0.1" -eq $serverName) { return $true }
    if ([System.Environment]::MachineName -eq $serverName.Split('.')[0]) { return $true }

    return $false
}

function Invoke-XppStaticMethod()
{
    Param(
        [Parameter(Mandatory=$true)]
        [ValidatePattern('^[a-zA-Z0-9_]+$')]
        [String]
        $ClassName,

        [Parameter(Mandatory=$true)]
        [ValidatePattern('^[a-zA-Z0-9_]+$')]
        [String]
        $MethodName,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]
        $RedirectStandardError
    )

    $commandParameter = "-bindir `"$(Get-CommonBinDir)`""
    $commandParameter += " -metadatadir `"$(Get-AOSPackageDirectory)`""
    $commandParameter += " -sqluser `"$(Get-DataAccessSqlUsr)`""
    $commandParameter += " -sqlserver `"$(Get-DataAccessDbServer)`""
    $commandParameter += " -sqldatabase `"$(Get-DataAccessDatabase)`""
    $commandParameter += " -sqlpwd `"$(Get-DataAccessSqlPwd)`""
    $commandParameter += " -setupmode runstaticxppmethod"
    $commandParameter += " -classname $ClassName"
    $commandParameter += " -methodname $MethodName"

    $webroot = Get-AosWebSitePhysicalPath
    $startProcessArgs = @{
        FilePath = "$webroot\bin\Microsoft.Dynamics.AX.Deployment.Setup.exe"
        ArgumentList = $commandParameter
        PassThru = $true
        Wait = $true
        RedirectStandardError = $RedirectStandardError
    }

    $process = Start-Process @startProcessArgs
    
    if ($process.ExitCode -ne 0)
    {
        $errorContent = Get-Content "$RedirectStandardError"
        if ($errorContent -eq $null)
        {
            $errorContent = "Process terminated with exit code $($process.ExitCode) (error stream is empty)."
        }
        throw $errorContent
    }
}

if(!$useServiceFabric)
{
    if (Test-Path "$($PSScriptRoot)\NonAdminDevToolsInterject.ps1")
    {
        & "$($PSScriptRoot)\NonAdminDevToolsInterject.ps1"
    }
}

function Get-HotfixInstallationInfo
{
    $packageRoot = split-Path -parent "$(split-Path -parent $PSScriptRoot)"

    # Using job to load the AXInstallationInfo dll to avoid file locks
    $job = Start-Job -ScriptBlock  {
        param($packageRootBlock)
        $axInstallationInfoDLLPath = Join-Path $packageRootBlock "Microsoft.Dynamics.AX.AXInstallationInfo.dll"
        $hotfixInstallationInfoFilePath = Join-Path $packageRootBlock "HotfixInstallationInfo.xml"
        try
        {
            if (Test-Path $axInstallationInfoDLLPath)
            {
                # Load AXInstallationInfo.dll
                [void][System.Reflection.Assembly]::LoadFrom($axInstallationInfoDLLPath)
                $hotfixInstallationInfo = New-Object Microsoft.Dynamics.AX.AXInstallationInfo.HotfixInstallationInfo

                if (Test-Path $hotfixInstallationInfoFilePath)
                {
                    # Initialize HotfixInstallationInfo from HotfixInstallationInfo.xml
                    $hotfixInstallationInfo.InitFromFile($hotfixInstallationInfoFilePath)
                    # Get HotfixInstallationInfo
                    $hotfixInstallationInfo
                }
            }
        }
        catch
        {
            Write-Warning "Failed to get HotfixInstallationInfo instance from deployable package"
            return $null
        }
    } -ArgumentList $packageRoot
    Wait-Job -Job $job | Out-Null
    $hotfixInstallationInfo  = Receive-Job -Job $job

    return $hotfixInstallationInfo
}

function Get-IsBinaryPackageTypeFromPackage
{
    $hotfixInstallationInfo = Get-HotfixInstallationInfo
    # Get Package Type from HotfixInstallationInfo for the package being deployed
    $packageType = $hotfixInstallationInfo.Type
    if(![string]::IsNullOrEmpty($packageType))
    {
        return ($packageType -eq 'PlatAppBinaryHotfixPackage' -or $packageType -eq 'MergedPackage')
    }

    Write-Warning "Failed to get package type from deployable package"
    return $false
}

function Get-MetadataModuleListFromPackage
{
    $hotfixInstallationInfo = Get-HotfixInstallationInfo
    # Get Metadata Module List from HotfixInstallationInfo of the package being deployed
    $metadataModuleList = $hotfixInstallationInfo.MetadataModuleList
    if(![string]::IsNullOrEmpty($metadataModuleList))
    {
        return $metadataModuleList
    }

    Write-Warning "Failed to get metadata module list from HotfixInstallationInfo.xml."
    return ""
}

function Get-PackageNamesFromDLL([Parameter(Mandatory=$false)] $webroot, [Parameter(Mandatory=$true)][string] $productInfoDLL)
{
    if (!$webroot) {
    $webroot = Get-AosWebSitePhysicalPath
    }

    # Using job to load the Product Information dll to avoid file locks
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock, $productInfoDLLBlock)
        $metadataCoreDLLPath = Join-Path $webrootBlock "bin\Microsoft.Dynamics.AX.Metadata.Core.dll"
        $productInfoDLLPath = Join-Path $webrootBlock $productInfoDLLBlock
        try
        {
            if (Test-Path $metadataCoreDLLPath)
            {
                # Load Metadata.Core.dll
                [void][System.Reflection.Assembly]::LoadFrom($metadataCoreDLLPath)
                if (Test-Path $productInfoDLLPath)
                {
                    # Get package names from Product Information dll
                    $packageNames = [Microsoft.Dynamics.AX.Metadata.Core.CoreHelper]::GetPackagesNames($productInfoDLLPath, $null)
                    $packageNames
                }
            }
        }
        catch
        {
            Write-Warning "Failed to get package names from product information dll."
            return $null
        }
    } -ArgumentList $webroot,$productInfoDLL
    Wait-Job -Job $job | Out-Null
    $packageNames  = Receive-Job -Job $job
    return $packageNames
}

Export-ModuleMember -Function Get-DataAccessSqlPwd
Export-ModuleMember -Function Get-DataAccessDatabase
Export-ModuleMember -Function Get-DataAccessSqlUsr
Export-ModuleMember -Function Get-DataAccessDbServer
Export-ModuleMember -Function Get-AOSPackageDirectory
Export-ModuleMember -Function Get-CommonBinDir
Export-ModuleMember -Function Get-BiReportingPersistentVirtualMachineIPAddressSSRS
Export-ModuleMember -Function Get-BiReportingReportingServers
Export-ModuleMember -Function Get-UseReportingCluster
Export-ModuleMember -Function Get-InfrastructureClickonceAppsDirectory
Export-ModuleMember -Function Get-DevToolsInstalled
Export-ModuleMember -Function Get-IsModulePartOfPlatformAsBinary
Export-ModuleMember -Function Get-IsAppFallOrLater
Export-ModuleMember -Function Get-IsPlatformUpdate3OrLater
Export-ModuleMember -Function Get-IsPackageContainUpgradeBinaryForUpdate3
Export-ModuleMember -Function Get-ProductPlatformBuildVersion
Export-ModuleMember -Function Get-ProductApplicationVersion
Export-ModuleMember -Function Get-ProductPlatformBuildFullVersion
Export-ModuleMember -Function Get-ApplicationReleaseFromPackage
Export-ModuleMember -Function Get-ProductVersionMajorMinor
Export-ModuleMember -Function Get-IsRetailProductSku
Export-ModuleMember -Function Get-IsOverlayeringDisabled
Export-ModuleMember -Function Get-DependencyAXModelList
Export-ModuleMember -Function Get-IsAppSealed
Export-ModuleMember -Function Get-IsModulePartOfApplicationAsBinary
Export-ModuleMember -Function Get-ALMPackageCopyPath
Export-ModuleMember -Function Get-IsFlightEnabled
Export-ModuleMember -Function GenerateMetadataModuleInstallationInfo
Export-ModuleMember -Function Get-EnvironmentId
Export-ModuleMember -Function Get-AADTenantId
Export-ModuleMember -Function Get-TenantDomainGUID
Export-ModuleMember -Function Get-S2SCertificate
Export-ModuleMember -Function IsLocalServer
Export-ModuleMember -Function Invoke-XppStaticMethod
Export-ModuleMember -Function Get-IsBinaryPackageTypeFromPackage
Export-ModuleMember -Function Get-MetadataModuleListFromPackage
Export-ModuleMember -Function Get-PackageNamesFromDLL

# SIG # Begin signature block
# MIInzgYJKoZIhvcNAQcCoIInvzCCJ7sCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCl/ccGLqnEnnJv
# 1HCBSSXueHFuMCYkbfotpy0/Dx7f8KCCDYUwggYDMIID66ADAgECAhMzAAACzfNk
# v/jUTF1RAAAAAALNMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjIwNTEyMjA0NjAyWhcNMjMwNTExMjA0NjAyWjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDrIzsY62MmKrzergm7Ucnu+DuSHdgzRZVCIGi9CalFrhwtiK+3FIDzlOYbs/zz
# HwuLC3hir55wVgHoaC4liQwQ60wVyR17EZPa4BQ28C5ARlxqftdp3H8RrXWbVyvQ
# aUnBQVZM73XDyGV1oUPZGHGWtgdqtBUd60VjnFPICSf8pnFiit6hvSxH5IVWI0iO
# nfqdXYoPWUtVUMmVqW1yBX0NtbQlSHIU6hlPvo9/uqKvkjFUFA2LbC9AWQbJmH+1
# uM0l4nDSKfCqccvdI5l3zjEk9yUSUmh1IQhDFn+5SL2JmnCF0jZEZ4f5HE7ykDP+
# oiA3Q+fhKCseg+0aEHi+DRPZAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU0WymH4CP7s1+yQktEwbcLQuR9Zww
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ3MDUzMDAfBgNVHSMEGDAW
# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
# AE7LSuuNObCBWYuttxJAgilXJ92GpyV/fTiyXHZ/9LbzXs/MfKnPwRydlmA2ak0r
# GWLDFh89zAWHFI8t9JLwpd/VRoVE3+WyzTIskdbBnHbf1yjo/+0tpHlnroFJdcDS
# MIsH+T7z3ClY+6WnjSTetpg1Y/pLOLXZpZjYeXQiFwo9G5lzUcSd8YVQNPQAGICl
# 2JRSaCNlzAdIFCF5PNKoXbJtEqDcPZ8oDrM9KdO7TqUE5VqeBe6DggY1sZYnQD+/
# LWlz5D0wCriNgGQ/TWWexMwwnEqlIwfkIcNFxo0QND/6Ya9DTAUykk2SKGSPt0kL
# tHxNEn2GJvcNtfohVY/b0tuyF05eXE3cdtYZbeGoU1xQixPZAlTdtLmeFNly82uB
# VbybAZ4Ut18F//UrugVQ9UUdK1uYmc+2SdRQQCccKwXGOuYgZ1ULW2u5PyfWxzo4
# BR++53OB/tZXQpz4OkgBZeqs9YaYLFfKRlQHVtmQghFHzB5v/WFonxDVlvPxy2go
# a0u9Z+ZlIpvooZRvm6OtXxdAjMBcWBAsnBRr/Oj5s356EDdf2l/sLwLFYE61t+ME
# iNYdy0pXL6gN3DxTVf2qjJxXFkFfjjTisndudHsguEMk8mEtnvwo9fOSKT6oRHhM
# 9sZ4HTg/TTMjUljmN3mBYWAWI5ExdC1inuog0xrKmOWVMIIHejCCBWKgAwIBAgIK
# 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/Xmfwb1tbWrJUnMTDXpQzTGCGZ8wghmbAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAALN82S/+NRMXVEAAAAA
# As0wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIAmI
# PQbnwYBhhzUCEiue6gjyU6V4ndeRZ/uW8lLlpo+OMEIGCisGAQQBgjcCAQwxNDAy
# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20wDQYJKoZIhvcNAQEBBQAEggEADAdubKQD5ney3iicuemmrHwC0hLriucofQs8
# rJ8oa0bPtdkVt9MiCVHXx+W178FEMidYeWDJdStkkaFuqORNbXEF6sx+GqJlrgZG
# km6U096vl605vziUtAMV8kap22JCe6U/s2KvnD6yrt7wlSlyA8tFLjn90BWXfCoU
# GnbIa3y8ZQ2ejkyiNlvDEvaFetrSRkBfSDFBL+cW9SSdfIB00EuYTwzm+HfXeIZh
# 0aXr1y4CFg+iXxNp4l/TXPgux7rvzlFpMIcuMF8h0e0wT2xJX6zogpNh3BldFytj
# iHFYq5gLz0N+fQOQZj9uDgaIAq/sHMlBxnrij3yZ56c6AnaJCKGCFykwghclBgor
# BgEEAYI3AwMBMYIXFTCCFxEGCSqGSIb3DQEHAqCCFwIwghb+AgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCAlnUmKTAmDKT2mQKDnGgzy1bqjKJ5cI5S8
# +9e0IP2vngIGZD/S7NeTGBMyMDIzMDQyNzE5NDYwMS40MzVaMASAAgH0oIHYpIHV
# MIHSMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsT
# HVRoYWxlcyBUU1MgRVNOOkZDNDEtNEJENC1EMjIwMSUwIwYDVQQDExxNaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIReDCCBycwggUPoAMCAQICEzMAAAG59gAN
# ZVRPvAMAAQAAAbkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# UENBIDIwMTAwHhcNMjIwOTIwMjAyMjE3WhcNMjMxMjE0MjAyMjE3WjCB0jELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9z
# b2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMg
# VFNTIEVTTjpGQzQxLTRCRDQtRDIyMDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAONJ
# Pslh9RbHyQECbUIINxMF5uQkyN07VIShITXubLpWnANgBCLvCcJl7o/2HHORnsRc
# mSINJ/qclAmLIrOjnYnrbocAnixiMEXC+a1sZ84qxYWtEVY7VYw0LCczY+86U/8s
# hgxqsaezKpWriPOcpV1Sh8SsOxf30yO7jvld/IBA3T6lHM2pT/HRjWk/r9uyx0Q4
# atx0mkLVYS9y55/oTlKLE00h792S+maadAdy3VgTweiwoEOXD785wv3h+fwH/wTQ
# tC9lhAxhMO4p+OP9888Wxkbl6BqRWXud54RTzqp2Vr+yen1Q1A6umyMB7Xq0snIY
# G5B1Acc4UgJlPQ/ZiMkqgxQNFCWQvz0G9oLgSPD8Ky0AkX22PcDOboPuNT4RceWP
# X0UVZUsX9IUgs7QF41HiQSwEeOOHGyrfQdmSslATrbmH/18M5QrsTM5JINjct9G4
# 2xqN8VF9Z8WOiGMjNbvlpcEmmysYl5QyhrEDoFnQTU7bFrD3JX0fIfu1sbLWeBqX
# wbp4Z8yACTtphK2VbzOvi4vc0RCmRNzvYQQ2PjZ7NaTXE4Gu3vggAJ+rtzUTAfJo
# tvOSqcMgNwLZa1Y+ET/lb0VyjrYwFuHtg0QWyQjP5350LTpv086pyVUh4A3w/Os5
# hTGFZgFe5bCyMnpY09M0yPdHaQ/56oYUsSIcyKyVAgMBAAGjggFJMIIBRTAdBgNV
# HQ4EFgQUt7A4cdtYQ5oJjE1ZqrSonp41RFIwHwYDVR0jBBgwFoAUn6cVXQBeYl2D
# 9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3Nv
# ZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUy
# MDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1l
# LVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUB
# Af8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQAD
# ggIBAM3cZ7NFUHRMsLKzjl7rJPIkv7oJ+s9kkut0hZif9WSt60SzYGULp1zmdPqc
# +w8eHTkhqX0GKCp2TTqSzBXBhwHOm8+p6hUxNlDewGMZUos952aTXblAT3OKBnfV
# BLQyUavrSjuJGZAW30cNY3rjVDUlGD+VygQHySaDaviJQbK6/6fQvUUFoqIk3ldG
# fjnAtnebsVlqh6WWamVc5AZdpWR1jSzN/oxKYqc1BG4SxxlPtcfrAdBz/cU4bxVX
# qAAf02NZscvJNpRnOALf5kVo2HupJXCsk9TzP5PNW2sTS3TmwhIQmPxr0E0UqOoj
# UrBJUOhbITAxcnSa/IMluL1HXRtLQZI+xs2eRtuPOUsKUW71/1YeqsYCLHLvu82c
# eDVQQvP7GHEEkp2kEjiofbjYErBo2iCEaxxeX4Z9HvAgA4MsQkbn6e4EFQf13sP+
# Kn3XgMIvJbqLJeFcQja+SUeOXu5cfkxe0GzTNojdyIwzaHlhOflVRZNrxee3B+yZ
# wd3JHDIvv71uSI/SIzzt9cU2GyHQVqxBSrRtKW6W8Vw7zpVvoVsIv3ljxg+7NiGS
# lXX1s7zbBNDMUj9OnzOlHK/3mrOU8YEuRf6RwakW5UCeGamy5MiKu2YuyKiGBCv4
# OGhPstNe7ALkEOh8BX12t4ntuYu+gw9L6yCPY0jWYaQtzAP9MIIHcTCCBVmgAwIB
# AgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0
# IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1
# WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O
# 1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZn
# hUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t
# 1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxq
# D89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmP
# frVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSW
# rAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv
# 231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zb
# r17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYcten
# IPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQc
# xWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17a
# j54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQAB
# MCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQU
# n6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEw
# QTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9E
# b2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQB
# gjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/
# MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJ
# oEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01p
# Y1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYB
# BQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9v
# Q2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3h
# LB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x
# 5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74p
# y27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1A
# oL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbC
# HcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB
# 9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNt
# yo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3
# rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcV
# v7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A24
# 5oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lw
# Y1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB
# 0jELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMk
# TWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1U
# aGFsZXMgVFNTIEVTTjpGQzQxLTRCRDQtRDIyMDElMCMGA1UEAxMcTWljcm9zb2Z0
# IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAx2IeGHhk58MQkzzS
# WknGcLjfgTqggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN
# BgkqhkiG9w0BAQUFAAIFAOf03LMwIhgPMjAyMzA0MjcxOTM2MTlaGA8yMDIzMDQy
# ODE5MzYxOVowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA5/TcswIBADAHAgEAAgId
# 9DAHAgEAAgIRXDAKAgUA5/YuMwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEE
# AYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GB
# AKFEMQnC/+FTjldFaxQffMe7X5Mb8SG2ud0ISTKprUUD2v1aPv7WUjI3fQUwmMmM
# omwWBgTEEe4HsmSJZZ5+7L3zJD/F/cfvk+x4E9ju2TovfEwWXJqSaJTY5MLX69lI
# mpcRTdEQwWYUJSt6qrZW7VT5Q8mNOUoDzxpXxcuJ1D2+MYIEDTCCBAkCAQEwgZMw
# fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd
# TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAG59gANZVRPvAMAAQAA
# AbkwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB
# BDAvBgkqhkiG9w0BCQQxIgQg5rNlnFEb4OzK/hBERC8zaTohMe7k9nu17JQ7DVy6
# 6FowgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBk60bO8W85uTAfJVEO3vX2
# aLaQFcgcGpdwsOoi+foP9DCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD
# QSAyMDEwAhMzAAABufYADWVUT7wDAAEAAAG5MCIEIM+wsiXu1+CId3dKOFixhcno
# m6sg3406NS5z3LoNU+6VMA0GCSqGSIb3DQEBCwUABIICACYzNILaku86T4FL3qQw
# RsYYtHmCg/44H92s5wHNeoDmz404qhNxBV9h+bPNgXMrahUqyeh7Ig4R4ZS/V6vz
# zs/62zXFYnfjqsm056CEd061rsS+ZRMWfXVYA57tuXRFm3xJtGF7twlnbB6UbN6E
# NVDMOk9nbCNOsQNtSs592OfnyoCOGIF1L1sTehDUmRtbrWbyAAb5eeCj6a54KDdq
# RocYQtG+rlB4Oy34iAouaFhT8w3ZEw2g1rOtT90aVGfa7IVOQ/tWO2lORqMjKnz+
# xD5nCmsFY1d/q+0AfSfaHqUSYRMiBxQ5lqS4InGew0NHlDkTOPMnrwHBqeegkc8y
# 2qjDxmiICfgqi0T72LxGC8uNzO88gDMbiplvSmGvq9KVkT2E8EXikRtsc/QOyZYQ
# LgWf41oDsYCeQLJIHnoNx1+pYHpl6YYnVR0+AKPSxZxkmlZQXbmlhHOlqvBkRPND
# op+3mHlZHU34UtxSVB2tp9UEijo0vDHrkTECt31w2YZcsVZdzMJdodLG3bRRYr6c
# lNanh1Y2CAWSOXiSL49826Pj9A1JKMziY9jQzTOONLz/cTZHMG7mo0v1ZDmnahiA
# 3FpjGaNv1LVvSH2ES1PjseD6+Oo8DzB6YRtGaB2hfMeSeANRBigAIP62nix1RPSN
# tQWfE8PgqTiDMwAIWLkYX6QK
# SIG # End signature block
