PSScriptAnalyzer/Measure-ADTCompatibility.psm1

<#
    .SYNOPSIS
    PSSCriptAnalyzer rules to check for usage of legacy PSAppDeployToolkit v3 commands or variables.
    .DESCRIPTION
    Can be used directly with PSSCriptAnalyzer or via Test-ADTCompatibility and Convert-ADTDeployment functions.
    .EXAMPLE
    Measure-ADTCompatibility -ScriptBlockAst $ScriptBlockAst
    .INPUTS
    [System.Management.Automation.Language.ScriptBlockAst]
    .OUTPUTS
    [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
    .NOTES
    None
#>

function Measure-ADTCompatibility
{
    [CmdletBinding()]
    [OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord])]
    Param
    (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [System.Management.Automation.Language.ScriptBlockAst]
        $ScriptBlockAst
    )

    Begin
    {
        $variableMappings = @{
            AllowRebootPassThru = '$adtSession.AllowRebootPassThru'
            appArch = '$adtSession.AppArch'
            appLang = '$adtSession.AppLang'
            appName = '$adtSession.AppName'
            appRevision = '$adtSession.AppRevision'
            appScriptAuthor = '$adtSession.AppScriptAuthor'
            appScriptDate = '$adtSession.AppScriptDate'
            appScriptVersion = '$adtSession.AppScriptVersion'
            appVendor = '$adtSession.AppVendor'
            appVersion = '$adtSession.AppVersion'
            currentDate = '$adtSession.CurrentDate'
            currentDateTime = '$adtSession.CurrentDateTime'
            defaultMsiFile = '$adtSession.DefaultMsiFile'
            deployAppScriptDate = '$adtSession.DeployAppScriptDate'
            deployAppScriptFriendlyName = '$adtSession.DeployAppScriptFriendlyName'
            deployAppScriptParameters = '$adtSession.DeployAppScriptParameters'
            deployAppScriptVersion = '$adtSession.DeployAppScriptVersion'
            DeploymentType = '$adtSession.DeploymentType'
            deploymentTypeName = '$adtSession.DeploymentTypeName'
            DeployMode = '$adtSession.DeployMode'
            dirFiles = '$adtSession.DirFiles'
            dirSupportFiles = '$adtSession.DirSupportFiles'
            DisableScriptLogging = '$adtSession.DisableLogging'
            installName = '$adtSession.InstallName'
            installPhase = '$adtSession.InstallPhase'
            installTitle = '$adtSession.InstallTitle'
            logName = '$adtSession.LogName'
            logTempFolder = '$adtSession.LogTempFolder'
            scriptDirectory = '$adtSession.ScriptDirectory'
            TerminalServerMode = '$adtSession.TerminalServerMode'
            useDefaultMsi = '$adtSession.UseDefaultMsi'
            appDeployConfigFile = $null
            appDeployCustomTypesSourceCode = $null
            appDeployExtScriptDate = $null
            appDeployExtScriptFriendlyName = $null
            appDeployExtScriptParameters = $null
            appDeployExtScriptVersion = $null
            appDeployLogoBanner = $null
            appDeployLogoBannerHeight = $null
            appDeployLogoBannerMaxHeight = $null
            appDeployLogoBannerObject = $null
            appDeployLogoIcon = $null
            appDeployLogoImage = $null
            appDeployMainScriptAsyncParameters = $null
            appDeployMainScriptDate = $null
            appDeployMainScriptFriendlyName = $null
            appDeployMainScriptMinimumConfigVersion = $null
            appDeployMainScriptParameters = $null
            appDeployRunHiddenVbsFile = $null
            appDeployToolkitDotSourceExtensions = $null
            appDeployToolkitExtName = $null
            AsyncToolkitLaunch = $null
            BlockExecution = $null
            ButtonLeftText = $null
            ButtonMiddleText = $null
            ButtonRightText = $null
            CleanupBlockedApps = $null
            closeAppsCountdownGlobal = $null
            configBalloonTextComplete = '(Get-ADTStringTable).BalloonText.Complete'
            configBalloonTextError = '(Get-ADTStringTable).BalloonText.Error'
            configBalloonTextFastRetry = '(Get-ADTStringTable).BalloonText.FastRetry'
            configBalloonTextRestartRequired = '(Get-ADTStringTable).BalloonText.RestartRequired'
            configBalloonTextStart = '(Get-ADTStringTable).BalloonText.Start'
            configBannerIconBannerName = '(Get-ADTConfig).Assets.Banner'
            configBannerIconFileName = $null
            configBannerLogoImageFileName = '(Get-ADTConfig).Assets.Logo'
            configBlockExecutionMessage = '(Get-ADTStringTable).BlockExecution.Message'
            configClosePromptButtonClose = '(Get-ADTStringTable).ClosePrompt.ButtonClose'
            configClosePromptButtonContinue = '(Get-ADTStringTable).ClosePrompt.ButtonContinue'
            configClosePromptButtonContinueTooltip = '(Get-ADTStringTable).ClosePrompt.ButtonContinueTooltip'
            configClosePromptButtonDefer = '(Get-ADTStringTable).ClosePrompt.ButtonDefer'
            configClosePromptCountdownMessage = '(Get-ADTStringTable).ClosePrompt.CountdownMessage'
            configClosePromptMessage = '(Get-ADTStringTable).ClosePrompt.Message'
            configConfigDate = $null
            configConfigDetails = $null
            configConfigVersion = $null
            configDeferPromptDeadline = '(Get-ADTStringTable).DeferPrompt.Deadline'
            configDeferPromptExpiryMessage = '(Get-ADTStringTable).DeferPrompt.ExpiryMessage'
            configDeferPromptRemainingDeferrals = '(Get-ADTStringTable).DeferPrompt.RemainingDeferrals'
            configDeferPromptWarningMessage = '(Get-ADTStringTable).DeferPrompt.WarningMessage'
            configDeferPromptWelcomeMessage = '(Get-ADTStringTable).DeferPrompt.WelcomeMessage'
            configDeploymentTypeInstall = '(Get-ADTStringTable).DeploymentType.Install'
            configDeploymentTypeRepair = '(Get-ADTStringTable).DeploymentType.Repair'
            configDeploymentTypeUnInstall = '(Get-ADTStringTable).DeploymentType.Uninstall'
            configDiskSpaceMessage = '(Get-ADTStringTable).DiskSpace.Message'
            configInstallationDeferExitCode = '(Get-ADTConfig).UI.DeferExitCode'
            configInstallationPersistInterval = '(Get-ADTConfig).UI.DefaultPromptPersistInterval'
            configInstallationPromptToSave = '(Get-ADTConfig).UI.PromptToSaveTimeout'
            configInstallationRestartPersistInterval = '(Get-ADTConfig).UI.RestartPromptPersistInterval'
            configInstallationUIExitCode = '(Get-ADTConfig).UI.DefaultExitCode'
            configInstallationUILanguageOverride = '(Get-ADTConfig).UI.LanguageOverride'
            configInstallationUITimeout = '(Get-ADTConfig).UI.DefaultTimeout'
            configInstallationWelcomePromptDynamicRunningProcessEvaluation = '(Get-ADTConfig).UI.DynamicProcessEvaluation'
            configInstallationWelcomePromptDynamicRunningProcessEvaluationInterval = '(Get-ADTConfig).UI.DynamicProcessEvaluationInterval'
            configMSIInstallParams = '(Get-ADTConfig).MSI.InstallParams'
            configMSILogDir = 'if ($isAdmin) { (Get-ADTConfig).MSI.LogPath } else { (Get-ADTConfig).MSI.LogPathNoAdminRights }'
            configMSILoggingOptions = '(Get-ADTConfig).MSI.LoggingOptions'
            configMSIMutexWaitTime = '(Get-ADTConfig).MSI.MutexWaitTime'
            configMSISilentParams = '(Get-ADTConfig).MSI.SilentParams'
            configMSIUninstallParams = '(Get-ADTConfig).MSI.UninstallParams'
            configProgressMessageInstall = '(Get-ADTStringTable).Progress.MessageInstall'
            configProgressMessageRepair = '(Get-ADTStringTable).Progress.MessageRepair'
            configProgressMessageUninstall = '(Get-ADTStringTable).Progress.MessageUninstall'
            configRestartPromptButtonRestartLater = '(Get-ADTStringTable).RestartPrompt.ButtonRestartLater'
            configRestartPromptButtonRestartNow = '(Get-ADTStringTable).RestartPrompt.ButtonRestartNow'
            configRestartPromptMessage = '(Get-ADTStringTable).RestartPrompt.Message'
            configRestartPromptMessageRestart = '(Get-ADTStringTable).RestartPrompt.MessageRestart'
            configRestartPromptMessageTime = '(Get-ADTStringTable).RestartPrompt.MessageTime'
            configRestartPromptTimeRemaining = '(Get-ADTStringTable).RestartPrompt.TimeRemaining'
            configRestartPromptTitle = '(Get-ADTStringTable).RestartPrompt.Title'
            configShowBalloonNotifications = '(Get-ADTConfig).UI.BalloonNotifications'
            configToastAppName = '(Get-ADTConfig).UI.BalloonTitle'
            configToastDisable = '(Get-ADTConfig).UI.BalloonNotifications'
            configToolkitCachePath = '(Get-ADTConfig).Toolkit.CachePath'
            configToolkitCompressLogs = '(Get-ADTConfig).Toolkit.CompressLogs'
            configToolkitLogAppend = '(Get-ADTConfig).Toolkit.LogAppend'
            configToolkitLogDebugMessage = '(Get-ADTConfig).Toolkit.LogDebugMessage'
            configToolkitLogDir = 'if ($isAdmin) { (Get-ADTConfig).Toolkit.LogPath } else { (Get-ADTConfig).Toolkit.LogPathNoAdminRights }'
            configToolkitLogMaxHistory = '(Get-ADTConfig).Toolkit.LogMaxHistory'
            configToolkitLogMaxSize = '(Get-ADTConfig).Toolkit.LogMaxSize'
            configToolkitLogStyle = '(Get-ADTConfig).Toolkit.LogStyle'
            configToolkitLogWriteToHost = '(Get-ADTConfig).Toolkit.LogWriteToHost'
            configToolkitRegPath = '(Get-ADTConfig).Toolkit.RegPath'
            configToolkitRequireAdmin = '(Get-ADTConfig).Toolkit.RequireAdmin'
            configToolkitTempPath = 'if ($isAdmin) { (Get-ADTConfig).Toolkit.TempPath } else { (Get-ADTConfig).Toolkit.TempPathNoAdminRights }'
            configToolkitUseRobocopy = '(Get-ADTConfig).Toolkit.FileCopyMode -eq ''Robocopy'''
            configWelcomePromptCountdownMessage = '(Get-ADTStringTable).WelcomePrompt.Classic.CountdownMessage'
            configWelcomePromptCustomMessage = '(Get-ADTStringTable).WelcomePrompt.Classic.CustomMessage'
            CountdownNoHideSeconds = $null
            CountdownSeconds = $null
            currentTime = $null
            currentTimeZoneBias = $null
            defaultFont = $null
            deployModeNonInteractive = $null
            deployModeSilent = $null
            DeviceContextHandle = $null
            dirAppDeployTemp = $null
            dpiPixels = $null
            dpiScale = $null
            envOfficeChannelProperty = $null
            envShellFolders = $null
            exeMsiexec = $null
            exeSchTasks = $null
            exeWusa = $null
            ExitOnTimeout = $null
            formattedOSArch = $null
            formWelcomeStartPosition = $null
            GetAccountNameUsingSid = $null
            GetDisplayScaleFactor = $null
            GetLoggedOnUserDetails = $null
            GetLoggedOnUserTempPath = $null
            GraphicsObject = $null
            HKULanguages = $null
            HKUPrimaryLanguageShort = $null
            hr = $null
            Icon = $null
            installationStarted = $null
            InvocationInfo = $null
            invokingScript = $null
            IsOOBEComplete = 'Test-ADTOobeCompleted'
            IsTaskSchedulerHealthy = $null
            LocalPowerUsersGroup = $null
            LogFileInitialized = $null
            loggedOnUserTempPath = $null
            LogicalScreenHeight = $null
            LogTimeZoneBias = $null
            mainExitCode = $null
            Message = $null
            MessageAlignment = $null
            MinimizeWindows = $null
            moduleAppDeployToolkitMain = $null
            msiRebootDetected = $null
            NoCountdown = $null
            notifyIcon = $null
            OldDisableLoggingValue = $null
            oldPSWindowTitle = $null
            PersistPrompt = $null
            PhysicalScreenHeight = $null
            PrimaryWindowsUILanguage = $null
            ProgressRunspace = $null
            ProgressSyncHash = $null
            ReferencedAssemblies = $null
            ReferredInstallName = $null
            ReferredInstallTitle = $null
            ReferredLogName = $null
            regKeyAppExecution = $null
            regKeyApplications = $null
            regKeyDeferHistory = $null
            regKeyLotusNotes = $null
            RevertScriptLogging = $null
            runningProcessDescriptions = $null
            scriptFileName = $null
            scriptName = $null
            scriptParentPath = $null
            scriptPath = $null
            scriptRoot = $null
            scriptSeparator = $null
            ShowBlockedAppDialog = $null
            ShowInstallationPrompt = $null
            ShowInstallationRestartPrompt = $null
            switch = $null
            Timeout = $null
            Title = $null
            TopMost = $null
            TypeDef = $null
            UserDisplayScaleFactor = $null
            welcomeTimer = $null
            xmlBannerIconOptions = $null
            xmlConfig = $null
            xmlConfigFile = $null
            xmlConfigMSIOptions = $null
            xmlConfigUIOptions = $null
            xmlLoadLocalizedUIMessages = $null
            xmlToastOptions = $null
            xmlToolkitOptions = $null
            xmlUIMessageLanguage = $null
            xmlUIMessages = $null
        }

        $functionMappings = @{
            'Write-Log' = @{
                'NewFunction' = 'Write-ADTLogEntry'
                'TransformParameters' = @{
                    'Text' = { "-Message $_" }
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
                'RemoveParameters' = @(
                    'AppendToLogFile'
                    'LogDebugMessage'
                    'MaxLogHistory'
                    'MaxLogFileSizeMB'
                    'WriteHost'
                )
            }
            'Exit-Script' = @{
                'NewFunction' = 'Exit-ADTScript'
            }
            'Invoke-HKCURegistrySettingsForAllUsers' = @{
                'NewFunction' = 'Invoke-ADTAllUsersRegistryAction'
                'TransformParameters' = @{
                    'RegistrySettings' = { "-ScriptBlock $($_.Replace('$UserProfile', '$_'))" }
                }
            }
            'Get-HardwarePlatform' = @{
                'NewFunction' = '$envHardwareType'
                'RemoveParameters' = @(
                    'ContinueOnError'
                )
            }
            'Get-FreeDiskSpace' = @{
                'NewFunction' = 'Get-ADTFreeDiskSpace'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Remove-InvalidFileNameChars' = @{
                'NewFunction' = 'Remove-ADTInvalidFileNameChars'
            }
            'Get-InstalledApplication' = @{
                'NewFunction' = 'Get-ADTApplication'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'Exact' = '-NameMatch Exact' # Should inspect switch values here in case of -Switch:$false
                    'WildCard' = '-NameMatch WildCard' # Should inspect switch values here in case of -Switch:$false
                    'RegEx' = '-NameMatch RegEx' # Should inspect switch values here in case of -Switch:$false
                }
            }
            'Remove-MSIApplications' = @{
                'NewFunction' = 'Uninstall-ADTApplication'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'Exact' = '-NameMatch Exact' # Should inspect switch values here in case of -Switch:$false
                    'WildCard' = '-NameMatch WildCard' # Should inspect switch values here in case of -Switch:$false
                    'Arguments' = { "-ArgumentList $_" }
                    'Parameters' = { "-ArgumentList $_" }
                    'AddParameters' = { "-AdditionalArgumentList $_" }
                    'LogName' = { "-LogFileName $_" }
                    'FilterApplication' = {
                        $filterApplication = @(if ($null -eq $boundParameters.FilterApplication.Value.Extent) { $null } else { $boundParameters.FilterApplication.Value.SafeGetValue() })
                        $excludeFromUninstall = @(if ($null -eq $boundParameters.ExcludeFromUninstall.Value.Extent) { $null } else { $boundParameters.ExcludeFromUninstall.Value.SafeGetValue() })

                        $filterArray = $(
                            foreach ($item in $filterApplication)
                            {
                                if ($null -ne $item)
                                {
                                    if ($item.Count -eq 1 -and $item[0].Count -eq 3) { $item = $item[0] } # Handle the case where input is of the form @(, @('Prop', 'Value', 'Exact'), @('Prop', 'Value', 'Exact'))
                                    if ($item[2] -eq 'RegEx')
                                    {
                                        "`$_.$($item[0]) -match '$($item[1] -replace "'","''")'"
                                    }
                                    elseif ($item[2] -eq 'Contains')
                                    {
                                        $regEx = [System.Text.RegularExpressions.Regex]::Escape(($item[1] -replace "'", "''")) -replace '(?<!\\)\\ ', ' '
                                        "`$_.$($item[0]) -match '$regEx'"
                                    }
                                    elseif ($item[2] -eq 'WildCard')
                                    {
                                        "`$_.$($item[0]) -like '$($item[1] -replace "'","''")'"
                                    }
                                    elseif ($item[2] -eq 'Exact')
                                    {
                                        if ($item[1] -is [System.Boolean])
                                        {
                                            "`$_.$($item[0]) -eq `$$($item[1].ToString().ToLower())"
                                        }
                                        else
                                        {
                                            "`$_.$($item[0]) -eq '$($item[1] -replace "'","''")'"
                                        }
                                    }
                                }
                            }
                            foreach ($item in $excludeFromUninstall)
                            {
                                if ($null -ne $item)
                                {
                                    if ($item.Count -eq 1 -and $item[0].Count -eq 3) { $item = $item[0] } # Handle the case where input is of the form @(, @('Prop', 'Value', 'Exact'), @('Prop', 'Value', 'Exact'))
                                    if ($item[2] -eq 'RegEx')
                                    {
                                        "`$_.$($item[0]) -notmatch '$($item[1] -replace "'","''")'"
                                    }
                                    elseif ($item[2] -eq 'Contains')
                                    {
                                        $regEx = [System.Text.RegularExpressions.Regex]::Escape(($item[1] -replace "'", "''")) -replace '(?<!\\)\\ ', ' '
                                        "`$_.$($item[0]) -notmatch '$regEx'"

                                    }
                                    elseif ($item[2] -eq 'WildCard')
                                    {
                                        "`$_.$($item[0]) -notlike '$($item[1] -replace "'","''")'"
                                    }
                                    elseif ($item[2] -eq 'Exact')
                                    {
                                        if ($item[1] -is [System.Boolean])
                                        {
                                            "`$_.$($item[0]) -ne `$$($item[1].ToString().ToLower())"
                                        }
                                        else
                                        {
                                            "`$_.$($item[0]) -ne '$($item[1] -replace "'","''")'"
                                        }
                                    }
                                }
                            }
                        )

                        $filterScript = $filterArray -join ' -and '

                        if ($filterScript)
                        {
                            "-FilterScript { $filterScript }"
                        }
                    }
                    'ExcludeFromUninstall' = {
                        $filterApplication = @(if ($null -eq $boundParameters.FilterApplication.Value.Extent) { $null } else { $boundParameters.FilterApplication.Value.SafeGetValue() })
                        $excludeFromUninstall = @(if ($null -eq $boundParameters.ExcludeFromUninstall.Value.Extent) { $null } else { $boundParameters.ExcludeFromUninstall.Value.SafeGetValue() })

                        $filterArray = $(
                            foreach ($item in $filterApplication)
                            {
                                if ($null -ne $item)
                                {
                                    if ($item.Count -eq 1 -and $item[0].Count -eq 3) { $item = $item[0] } # Handle the case where input is of the form @(, @('Prop', 'Value', 'Exact'), @('Prop', 'Value', 'Exact'))
                                    if ($item[2] -eq 'RegEx')
                                    {
                                        "`$_.$($item[0]) -match '$($item[1] -replace "'","''")'"
                                    }
                                    elseif ($item[2] -eq 'Contains')
                                    {
                                        $regEx = [System.Text.RegularExpressions.Regex]::Escape(($item[1] -replace "'", "''")) -replace '(?<!\\)\\ ', ' '
                                        "`$_.$($item[0]) -match '$regEx'"
                                    }
                                    elseif ($item[2] -eq 'WildCard')
                                    {
                                        "`$_.$($item[0]) -like '$($item[1] -replace "'","''")'"
                                    }
                                    elseif ($item[2] -eq 'Exact')
                                    {
                                        if ($item[1] -is [System.Boolean])
                                        {
                                            "`$_.$($item[0]) -eq `$$($item[1].ToString().ToLower())"
                                        }
                                        else
                                        {
                                            "`$_.$($item[0]) -eq '$($item[1] -replace "'","''")'"
                                        }
                                    }
                                }
                            }
                            foreach ($item in $excludeFromUninstall)
                            {
                                if ($null -ne $item)
                                {
                                    if ($item.Count -eq 1 -and $item[0].Count -eq 3) { $item = $item[0] } # Handle the case where input is of the form @(, @('Prop', 'Value', 'Exact'), @('Prop', 'Value', 'Exact'))
                                    if ($item[2] -eq 'RegEx')
                                    {
                                        "`$_.$($item[0]) -notmatch '$($item[1] -replace "'","''")'"
                                    }
                                    elseif ($item[2] -eq 'Contains')
                                    {
                                        $regEx = [System.Text.RegularExpressions.Regex]::Escape(($item[1] -replace "'", "''")) -replace '(?<!\\)\\ ', ' '
                                        "`$_.$($item[0]) -notmatch '$regEx'"

                                    }
                                    elseif ($item[2] -eq 'WildCard')
                                    {
                                        "`$_.$($item[0]) -notlike '$($item[1] -replace "'","''")'"
                                    }
                                    elseif ($item[2] -eq 'Exact')
                                    {
                                        if ($item[1] -is [System.Boolean])
                                        {
                                            "`$_.$($item[0]) -ne `$$($item[1].ToString().ToLower())"
                                        }
                                        else
                                        {
                                            "`$_.$($item[0]) -ne '$($item[1] -replace "'","''")'"
                                        }
                                    }
                                }
                            }
                        )

                        $filterScript = $filterArray -join ' -and '

                        if ($filterScript)
                        {
                            "-FilterScript { $filterScript }"
                        }
                    }
                }
                'AddParameters' = @{
                    'ApplicationType' = '-ApplicationType MSI'
                }
            }
            'Get-FileVersion' = @{
                'NewFunction' = 'Get-ADTFileVersion'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Get-UserProfiles' = @{
                'NewFunction' = 'Get-ADTUserProfiles'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'ExcludeSystemProfiles' = { if ($_ -eq '$false') { '-IncludeSystemProfiles' } }
                    'ExcludeServiceProfiles' = { if ($_ -eq '$false') { '-IncludeServiceProfiles' } }
                }
            }
            'Update-Desktop' = @{
                'NewFunction' = 'Update-ADTDesktop'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Refresh-Desktop' = @{
                'NewFunction' = 'Update-ADTDesktop'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Update-SessionEnvironmentVariables' = @{
                'NewFunction' = 'Update-ADTEnvironmentPsProvider'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Refresh-SessionEnvironmentVariables' = @{
                'NewFunction' = 'Update-ADTEnvironmentPsProvider'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Copy-File' = @{
                'NewFunction' = 'Copy-ADTFile'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'ContinueFileCopyOnError' = { if ($_ -eq '$true') { '-ContinueFileCopyOnError' } else { $null } }
                    'UseRobocopy' = { if ($_ -eq '$true' -or $boundParameters.ContainsKey('RobocopyParams') -or $boundParameters.ContainsKey('RobocopyAdditionalParams')) { '-FileCopyMode Robocopy' } else { '-FileCopyMode Native' } }
                }
            }
            'Remove-File' = @{
                'NewFunction' = 'Remove-ADTFile'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Copy-FileToUserProfiles' = @{
                'NewFunction' = 'Copy-ADTFileToUserProfiles'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'ContinueFileCopyOnError' = { if ($_ -eq '$true') { '-ContinueFileCopyOnError' } else { $null } }
                    'UseRobocopy' = { if ($_ -eq '$true' -or $boundParameters.ContainsKey('RobocopyParams') -or $boundParameters.ContainsKey('RobocopyAdditionalParams')) { '-FileCopyMode Robocopy' } else { '-FileCopyMode Native' } }
                    'ExcludeSystemProfiles' = { if ($_ -eq '$false') { '-IncludeSystemProfiles' } }
                    'ExcludeServiceProfiles' = { if ($_ -eq '$false') { '-IncludeServiceProfiles' } }
                }
            }
            'Show-InstallationPrompt' = @{
                'NewFunction' = 'Show-ADTInstallationPrompt'
                'TransformParameters' = @{
                    'Icon' = { if ($_ -ne 'None') { "-Icon $_" } }
                    'ExitOnTimeout' = { if ($_ -eq '$false') { '-NoExitOnTimeout' } }
                    'TopMost' = { if ($_ -eq '$false') { '-NotTopMost' } }
                }
            }
            'Show-InstallationProgress' = @{
                'NewFunction' = 'Show-ADTInstallationProgress'
                'TransformParameters' = @{
                    'TopMost' = { if ($_ -eq '$false') { '-NotTopMost' } }
                    'Quiet' = '-InformationAction SilentlyContinue' # Should inspect switch values here in case of -Switch:$false
                }
            }
            'Show-DialogBox' = @{
                'NewFunction' = 'Show-ADTDialogBox'
                'TransformParameters' = @{
                    'TopMost' = { if ($_ -eq '$false') { '-NotTopMost' } }
                }
            }
            'Show-InstallationWelcome' = @{
                'NewFunction' = 'Show-ADTInstallationWelcome'
                'TransformParameters' = @{
                    'MinimizeWindows' = { if ($_ -eq '$false') { '-NoMinimizeWindows' } }
                    'TopMost' = { if ($_ -eq '$false') { '-NotTopMost' } }
                    'CloseAppsCountdown' = { "-CloseProcessesCountdown $_" }
                    'ForceCloseAppsCountdown' = { "-ForceCloseProcessesCountdown $_" }
                    'AllowDeferCloseApps' = '-AllowDeferCloseProcesses' # Should inspect switch values here in case of -Switch:$false
                    'CloseApps' = {
                        $quoteChar = if ($boundParameters.CloseApps.Value.StringConstantType -eq 'DoubleQuoted') { '"' } else { "'" }
                        $closeProcesses = $boundParameters.CloseApps.Value.Value.Split(',').ForEach({
                                $name, $description = $_.Split('=')
                                if ($description)
                                {
                                    "@{ Name = $quoteChar$($name)$quoteChar; Description = $quoteChar$($description)$quoteChar }"
                                }
                                else
                                {
                                    "$quoteChar$($name)$quoteChar"
                                }
                            }) -join ', '
                        "-CloseProcesses $closeProcesses"
                    }
                }
            }
            'Get-WindowTitle' = @{
                'NewFunction' = 'Get-ADTWindowTitle'
                'TransformParameters' = @{
                    'DisableFunctionLogging' = '-InformationAction SilentlyContinue' # Should inspect switch values here in case of -Switch:$false
                }
            }
            'Show-InstallationRestartPrompt' = @{
                'NewFunction' = 'Show-ADTInstallationRestartPrompt'
                'TransformParameters' = @{
                    'NoSilentRestart' = { if ($_ -eq '$false') { '-SilentRestart' } }
                    'TopMost' = { if ($_ -eq '$false') { '-NotTopMost' } }
                }
            }
            'Show-BalloonTip' = @{
                'NewFunction' = 'Show-ADTBalloonTip'
                'RemoveParameters' = @(
                    'NoWait'
                )
            }
            'Copy-ContentToCache' = @{
                'NewFunction' = 'Copy-ADTContentToCache'
            }
            'Remove-ContentFromCache' = @{
                'NewFunction' = 'Remove-ADTContentFromCache'
            }
            'Test-NetworkConnection' = @{
                'NewFunction' = 'Test-ADTNetworkConnection'
            }
            'Get-LoggedOnUser' = @{
                'NewFunction' = 'Get-ADTLoggedOnUser'
            }
            'Get-IniValue' = @{
                'NewFunction' = 'Get-ADTIniValue'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Set-IniValue' = @{
                'NewFunction' = 'Set-ADTIniValue'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'New-Folder' = @{
                'NewFunction' = 'New-ADTFolder'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Test-PowerPoint' = @{
                'NewFunction' = 'Test-ADTPowerPoint'
            }
            'Update-GroupPolicy' = @{
                'NewFunction' = 'Update-ADTGroupPolicy'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Get-UniversalDate' = @{
                'NewFunction' = 'Get-ADTUniversalDate'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Test-ServiceExists' = @{
                'NewFunction' = 'Test-ADTServiceExists'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
                'RemoveParameters' = @(
                    'ComputerName'
                )
            }
            'Disable-TerminalServerInstallMode' = @{
                'NewFunction' = 'Disable-ADTTerminalServerInstallMode'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Enable-TerminalServerInstallMode' = @{
                'NewFunction' = 'Enable-ADTTerminalServerInstallMode'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Configure-EdgeExtension' = @{
                'NewFunction' = { if ($boundParameters.ContainsKey('Add')) { 'Add-ADTEdgeExtension' } else { 'Remove-ADTEdgeExtension' } }  # Should inspect switch values here in case of -Switch:$false
                'RemoveParameters' = @(
                    'Add'
                    'Remove'
                )
            }
            'Resolve-Error' = @{
                'NewFunction' = 'Resolve-ADTErrorRecord'
                'AddParameters' = @{
                    'ExcludeErrorRecord' = {
                        if (!$boundParameters.ContainsKey('GetErrorRecord') -or $boundParameters.GetErrorRecord.ConstantValue -eq $false -or $boundParameters.GetErrorRecord.Value.Extent.Text -eq '$false') { '-ExcludeErrorRecord' }
                    }
                    'ExcludeErrorInvocation' = {
                        if (!$boundParameters.ContainsKey('GetErrorInvocation') -or $boundParameters.GetErrorInvocation.ConstantValue -eq $false -or $boundParameters.GetErrorInvocation.Value.Extent.Text -eq '$false') { '-ExcludeErrorInvocation' }
                    }
                    'ExcludeErrorException' = {
                        if (!$boundParameters.ContainsKey('GetErrorException') -or $boundParameters.GetErrorException.ConstantValue -eq $false -or $boundParameters.GetErrorException.Value.Extent.Text -eq '$false') { '-ExcludeErrorException' }
                    }
                    'ExcludeErrorInnerException' = {
                        if (!$boundParameters.ContainsKey('GetErrorInnerException') -or $boundParameters.GetErrorInnerException.ConstantValue -eq $false -or $boundParameters.GetErrorInnerException.Value.Extent.Text -eq '$false') { '-ExcludeErrorInnerException' }
                    }
                }
            }
            'Get-ServiceStartMode' = @{
                'NewFunction' = 'Get-ADTServiceStartMode'
                'TransformParameters' = @{
                    'Name' = { "-Service $_" }
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
                'RemoveParameters' = @(
                    'ComputerName'
                )
            }
            'Set-ServiceStartMode' = @{
                'NewFunction' = 'Set-ADTServiceStartMode'
                'TransformParameters' = @{
                    'Name' = { "-Service $_" }
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
                'RemoveParameters' = @(
                    'ComputerName'
                )
            }
            'Execute-Process' = @{
                'NewFunction' = 'Start-ADTProcess'
                'TransformParameters' = @{
                    'Path' = { "-FilePath $_" }
                    'Arguments' = { "-ArgumentList $_" }
                    'Parameters' = { "-ArgumentList $_" }
                    'SecureParameters' = '-SecureArgumentList' # Should inspect switch values here in case of -Switch:$false
                    'IgnoreExitCodes' = { "-IgnoreExitCodes $($_.Trim('"').Trim("'") -split ',' -join ',')" }
                    'ExitOnProcessFailure' = {
                        $ContinueOnError = if ($null -eq $boundParameters.ContinueOnError.Value.Extent) { $false } else { $boundParameters.ContinueOnError.Value.SafeGetValue() }
                        $ExitOnProcessFailure = if ($null -eq $boundParameters.ExitOnProcessFailure.Value.Extent) { $true } else { $boundParameters.ExitOnProcessFailure.Value.SafeGetValue() }
                        @('-ErrorAction Stop', '-ErrorAction SilentlyContinue')[$ContinueOnError -or !$ExitOnProcessFailure]
                    }
                    'ContinueOnError' = {
                        $ContinueOnError = if ($null -eq $boundParameters.ContinueOnError.Value.Extent) { $false } else { $boundParameters.ContinueOnError.Value.SafeGetValue() }
                        $ExitOnProcessFailure = if ($null -eq $boundParameters.ExitOnProcessFailure.Value.Extent) { $true } else { $boundParameters.ExitOnProcessFailure.Value.SafeGetValue() }
                        @('-ErrorAction Stop', '-ErrorAction SilentlyContinue')[$ContinueOnError -or !$ExitOnProcessFailure]
                    }
                }
            }
            'Execute-MSI' = @{
                'NewFunction' = 'Start-ADTMsiProcess'
                'TransformParameters' = @{
                    'Path' = { if ($_ -match '^[''"]?\{?([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}?[''"]?$') { "-ProductCode $_" } else { "-FilePath $_" } }
                    'Arguments' = { "-ArgumentList $_" }
                    'Parameters' = { "-ArgumentList $_" }
                    'AddParameters' = { "-AdditionalArgumentList $_" }
                    'SecureParameters' = '-SecureArgumentList' # Should inspect switch values here in case of -Switch:$false
                    'Transform' = { "-Transforms $(if ($_ -match "^'") { $_ -replace ';', "','" } elseif ($_ -match '^"') { $_ -replace ';', '","' } else { $_ })" }
                    'LogName' = { "-LogFileName $_" }
                    'IgnoreExitCodes' = { "-IgnoreExitCodes $($_.Trim('"').Trim("'") -split ',' -join ',')" }
                    'ExitOnProcessFailure' = {
                        $ContinueOnError = if ($null -eq $boundParameters.ContinueOnError.Value.Extent) { $false } else { $boundParameters.ContinueOnError.Value.SafeGetValue() }
                        $ExitOnProcessFailure = if ($null -eq $boundParameters.ExitOnProcessFailure.Value.Extent) { $true } else { $boundParameters.ExitOnProcessFailure.Value.SafeGetValue() }
                        @('-ErrorAction Stop', '-ErrorAction SilentlyContinue')[$ContinueOnError -or !$ExitOnProcessFailure]
                    }
                    'ContinueOnError' = {
                        $ContinueOnError = if ($null -eq $boundParameters.ContinueOnError.Value.Extent) { $false } else { $boundParameters.ContinueOnError.Value.SafeGetValue() }
                        $ExitOnProcessFailure = if ($null -eq $boundParameters.ExitOnProcessFailure.Value.Extent) { $true } else { $boundParameters.ExitOnProcessFailure.Value.SafeGetValue() }
                        @('-ErrorAction Stop', '-ErrorAction SilentlyContinue')[$ContinueOnError -or !$ExitOnProcessFailure]
                    }
                }
            }
            'Execute-MSP' = @{
                'NewFunction' = 'Start-ADTMspProcess'
                'TransformParameters' = @{
                    'Path' = { "-FilePath $_" }
                }
            }
            'Block-AppExecution' = @{
                'NewFunction' = 'Block-ADTAppExecution'
            }
            'Unblock-AppExecution' = @{
                'NewFunction' = 'Unblock-ADTAppExecution'
            }
            'Test-RegistryValue' = @{
                'NewFunction' = 'Test-ADTRegistryValue'
                'TransformParameters' = @{
                    'Value' = { "-Name $_" }
                }
            }
            'Convert-RegistryPath' = @{
                'NewFunction' = 'Convert-ADTRegistryPath'
                'TransformParameters' = @{
                    'DisableFunctionLogging' = { if ($_ -eq '$false') { '-InformationAction Continue' } }
                }
            }
            'Test-MSUpdates' = @{
                'NewFunction' = 'Test-ADTMSUpdates'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Test-Battery' = @{
                'NewFunction' = 'Test-ADTBattery'
            }
            'Start-ServiceAndDependencies' = @{
                'NewFunction' = 'Start-ADTServiceAndDependencies'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
                'RemoveParameters' = @(
                    'ComputerName'
                    'SkipServiceExistsTest'
                )
            }
            'Stop-ServiceAndDependencies' = @{
                'NewFunction' = 'Stop-ADTServiceAndDependencies'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
                'RemoveParameters' = @(
                    'ComputerName'
                    'SkipServiceExistsTest'
                )
            }
            'Set-RegistryKey' = @{
                'NewFunction' = 'Set-ADTRegistryKey'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Remove-RegistryKey' = @{
                'NewFunction' = 'Remove-ADTRegistryKey'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Remove-FileFromUserProfiles' = @{
                'NewFunction' = 'Remove-ADTFileFromUserProfiles'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'ExcludeSystemProfiles' = { if ($_ -eq '$false') { '-IncludeSystemProfiles' } }
                    'ExcludeServiceProfiles' = { if ($_ -eq '$false') { '-IncludeServiceProfiles' } }
                }
            }
            'Get-RegistryKey' = @{
                'NewFunction' = 'Get-ADTRegistryKey'
                'TransformParameters' = @{
                    'Value' = { "-Name $_" }
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Install-MSUpdates' = @{
                'NewFunction' = 'Install-ADTMSUpdates'
            }
            'Get-SchedulerTask' = @{
                'NewFunction' = 'Get-ADTSchedulerTask'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Get-PendingReboot' = @{
                'NewFunction' = 'Get-ADTPendingReboot'
            }
            'Invoke-RegisterOrUnregisterDLL' = @{
                'NewFunction' = 'Invoke-ADTRegSvr32'
                'TransformParameters' = @{
                    'DLLAction' = { "-Action $_" }
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Register-DLL' = @{
                'NewFunction' = 'Register-ADTDll'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Unregister-DLL' = @{
                'NewFunction' = 'Unregister-ADTDll'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Remove-Folder' = @{
                'NewFunction' = 'Remove-ADTFolder'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Set-ActiveSetup' = @{
                'NewFunction' = 'Set-ADTActiveSetup'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'ExecuteForCurrentUser' = { if ($_ -eq '$false') { '-NoExecuteForCurrentUser' } }
                }
            }
            'Set-ItemPermission' = @{
                'NewFunction' = 'Set-ADTItemPermission'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'File' = { "-Path $_" }
                    'Folder' = { "-Path $_" }
                    'Username' = { "-User $_" }
                    'Users' = { "-User $_" }
                    'SID' = { "-User $_" }
                    'Usernames' = { "-User $_" }
                    'Acl' = { "-Permission $_" }
                    'Grant' = { "-Permission $_" }
                    'Permissions' = { "-Permission $_" }
                    'Deny' = { "-Permission $_" }
                    'AccessControlType' = { "-PermissionType $_" }
                    'Add' = { "-Method $($_ -replace '^(Add|Set|Reset|Remove)(Specific|All)?$', '$1AccessRule$2')" }
                    'ApplyMethod' = { "-Method $($_ -replace '^(Add|Set|Reset|Remove)(Specific|All)?$', '$1AccessRule$2')" }
                    'ApplicationMethod' = { "-Method $($_ -replace '^(Add|Set|Reset|Remove)(Specific|All)?$', '$1AccessRule$2')" }
                    'Method' = { "-Method $($_ -replace '^(Add|Set|Reset|Remove)(Specific|All)?$', '$1AccessRule$2')" }
                }
            }
            'New-MsiTransform' = @{
                'NewFunction' = 'New-ADTMsiTransform'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Invoke-SCCMTask' = @{
                'NewFunction' = 'Invoke-ADTSCCMTask'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Install-SCCMSoftwareUpdates' = @{
                'NewFunction' = 'Install-ADTSCCMSoftwareUpdates'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Send-Keys' = @{
                'NewFunction' = 'Send-ADTKeys'
            }
            'Get-Shortcut' = @{
                'NewFunction' = 'Get-ADTShortcut'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Set-Shortcut' = @{
                'NewFunction' = 'Set-ADTShortcut'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'New-Shortcut' = @{
                'NewFunction' = 'New-ADTShortcut'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Execute-ProcessAsUser' = @{
                'NewFunction' = 'Start-ADTProcessAsUser'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
                'RemoveParameters' = @(
                    'TempPath'
                    'RunLevel'
                )
            }
            'Close-InstallationProgress' = @{
                'NewFunction' = 'Close-ADTInstallationProgress'
                'RemoveParameters' = @(
                    'WaitingTime'
                )
            }
            'ConvertTo-NTAccountOrSID' = @{
                'NewFunction' = 'ConvertTo-ADTNTAccountOrSID'
            }
            'Get-DeferHistory' = @{
                'NewFunction' = 'Get-ADTDeferHistory'
            }
            'Set-DeferHistory' = @{
                'NewFunction' = 'Set-ADTDeferHistory'
            }
            'Get-MsiTableProperty' = @{
                'NewFunction' = 'Get-ADTMsiTableProperty'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Set-MsiProperty' = @{
                'NewFunction' = 'Set-ADTMsiProperty'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Get-MsiExitCodeMessage' = @{
                'NewFunction' = 'Get-ADTMsiExitCodeMessage'
            }
            'Get-ObjectProperty' = @{
                'NewFunction' = 'Get-ADTObjectProperty'
            }
            'Invoke-ObjectMethod' = @{
                'NewFunction' = 'Invoke-ADTObjectMethod'
            }
            'Get-PEFileArchitecture' = @{
                'NewFunction' = 'Get-ADTPEFileArchitecture'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                }
            }
            'Test-IsMutexAvailable' = @{
                'NewFunction' = 'Test-ADTMutexAvailability'
            }
            'New-ZipFile' = @{
                'NewFunction' = 'New-ADTZipFile'
                'TransformParameters' = @{
                    'ContinueOnError' = { if ($_ -eq '$true') { '-ErrorAction SilentlyContinue' } else { '-ErrorAction Stop' } }
                    'DestinationArchiveDirectoryPath' = {
                        $destinationArchiveDirectoryPath = $boundParameters.DestinationArchiveDirectoryPath.Value.Value
                        $destinationArchiveFileName = $boundParameters.DestinationArchiveFileName.Value.Value
                        $quoteChar = if ($boundParameters.DestinationArchiveDirectoryPath.Value.StringConstantType -eq 'DoubleQuoted' -or $boundParameters.DestinationArchiveFileName.Value.StringConstantType -eq 'DoubleQuoted') { '"' } else { "'" }
                        "-DestinationPath $quoteChar$([System.IO.Path]::Combine($destinationArchiveDirectoryPath, $destinationArchiveFileName))$quoteChar"
                    }
                    'DestinationArchiveFileName' = {
                        $destinationArchiveDirectoryPath = $boundParameters.DestinationArchiveDirectoryPath.Value.Value
                        $destinationArchiveFileName = $boundParameters.DestinationArchiveFileName.Value.Value
                        $quoteChar = if ($boundParameters.DestinationArchiveDirectoryPath.Value.StringConstantType -eq 'DoubleQuoted' -or $boundParameters.DestinationArchiveFileName.Value.StringConstantType -eq 'DoubleQuoted') { '"' } else { "'" }
                        "-DestinationPath $quoteChar$([System.IO.Path]::Combine($destinationArchiveDirectoryPath, $destinationArchiveFileName))$quoteChar"
                    }
                    'SourceDirectoryPath' = { "-LiteralPath $_" }
                    'SourceFilePath' = { "-LiteralPath $_" }
                    'OverWriteArchive' = '-Force' # Should inspect switch values here in case of -Switch:$false
                }
            }
            'Set-PinnedApplication' = @{
                'NewFunction' = '# The function [Set-PinnedApplication] has been removed from PSAppDeployToolkit as its functionality no longer works with Windows 10 1809 or higher targets.'
            }
        }

        $spBinder = [System.Management.Automation.Language.StaticParameterBinder]
    }

    Process
    {
        try
        {
            # Get legacy variables
            [ScriptBlock]$variablePredicate = {
                param ([System.Management.Automation.Language.Ast]$Ast)
                $Ast -is [System.Management.Automation.Language.VariableExpressionAst] -and $Ast.Parent -isnot [System.Management.Automation.Language.ParameterAst] -and $Ast.VariablePath.UserPath -in $variableMappings.Keys
            }
            [System.Management.Automation.Language.Ast[]]$variableAsts = $ScriptBlockAst.FindAll($variablePredicate, $true)

            # Get legacy functions
            [ScriptBlock]$commandPredicate = {
                param ([System.Management.Automation.Language.Ast]$Ast)
                $Ast -is [System.Management.Automation.Language.CommandAst] -and $Ast.GetCommandName() -in $functionMappings.Keys
            }
            [System.Management.Automation.Language.Ast[]]$commandAsts = $ScriptBlockAst.FindAll($commandPredicate, $true)

            # Process all hashtable definitions that splat to legacy functions first
            foreach ($commandAst in $commandAsts)
            {
                $functionName = $commandAst.GetCommandName()
                $boundParameters = ($spBinder::BindCommand($commandAst, $true)).BoundParameters

                foreach ($boundParameter in $boundParameters.GetEnumerator())
                {
                    if ($boundParameter.Value.Value.Splatted)
                    {
                        $splatVariableName = $boundParameter.Value.Value.VariablePath.UserPath

                        # Find the last assignment of the splat variable before the current command
                        [ScriptBlock]$splatPredicate = {
                            param ([System.Management.Automation.Language.Ast]$Ast)
                            $Ast -is [System.Management.Automation.Language.AssignmentStatementAst] -and $Ast.Left.Extent.Text -match "\`$$splatVariableName$" -and ($Ast.Extent.StartLineNumber -lt $commandAst.Extent.StartLineNumber -or ($Ast.Extent.StartLineNumber -eq $commandAst.Extent.StartLineNumber -and $Ast.Extent.StartColumnNumber -lt $commandAst.Extent.StartColumnNumber))
                        }
                        [System.Management.Automation.Language.Ast]$splatAst = $ScriptBlockAst.FindAll($splatPredicate, $true) | Select-Object -Last 1

                        if ($splatAst)
                        {
                            $splatModified = $false
                            $outputMessage = New-Object System.Text.StringBuilder
                            $outputMessage.AppendLine("Modify splat `$$splatVariableName`:") | Out-Null

                            # Construct a hashtable in text form
                            $replacementHashText = New-Object System.Text.StringBuilder
                            if ($splatAst.Extent.StartLineNumber -eq $splatAst.Extent.EndLineNumber)
                            {
                                $splatHashLineSeparator = ' '
                                $splatHashItemSeparator = '; '
                                $splatHashIndent = 0
                            }
                            else
                            {
                                $splatHashLineSeparator = "`n"
                                $splatHashItemSeparator = "`n"
                                $splatHashIndent = $splatAst.Extent.StartColumnNumber + 3
                            }
                            $replacementHashText.Append("$($splatAst.Left.Extent.Text) = @{$splatHashLineSeparator") | Out-Null

                            $replacementHashItems = foreach ($keyValuePair in $splatAst.Right.Expression.KeyValuePairs)
                            {
                                if ($keyValuePair.Item1.Value -in $functionMappings[$functionName].RemoveParameters)
                                {
                                    $splatModified = $true
                                    continue
                                }
                                if ($keyValuePair.Item1.Value -in $functionMappings[$functionName].TransformParameters.Keys)
                                {
                                    $splatModified = $true

                                    if ($functionMappings[$functionName].TransformParameters[$keyValuePair.Item1.Value] -is [ScriptBlock])
                                    {
                                        # If parameter is remapped to a script block, invoke it to get the new parameter
                                        $splatNewParam = ForEach-Object -InputObject $keyValuePair.Item2 -Process $functionMappings[$functionName].TransformParameters[$keyValuePair.Item1.Value]
                                    }
                                    else
                                    {
                                        # Otherwise, use the new parameter name as-is
                                        $splatNewParam = $functionMappings[$functionName].TransformParameters[$keyValuePair.Item1.Value]
                                    }

                                    # Split splatNewParam into parameter name and value
                                    if ($splatNewParam -match "-([a-zA-Z0-9_-]+)\s*(.*)?")
                                    {
                                        $paramName = $matches[1]
                                        $paramValue = $matches[2]
                                        if ([string]::IsNullOrWhiteSpace($paramValue))
                                        {
                                            # Assume if no value is provided it's a switch parameter, which in a hashtable for splatting, needs to be set to $true
                                            $paramValue = '$true'
                                        }
                                        "$(' ' * $splatHashIndent)$paramName = $paramValue"

                                        $outputMessage.AppendLine("$($keyValuePair.Item1.Value) = $($keyValuePair.Item2.Extent.Text) → $paramName = $paramValue") | Out-Null
                                    }
                                }
                                else
                                {
                                    # Write the key-value pair as-is
                                    "$(' ' * $splatHashIndent)$($keyValuePair.Item1.Value) = $($keyValuePair.Item2.Extent.Text)"
                                }
                            }

                            if ($splatModified)
                            {
                                $replacementHashText.Append($replacementHashItems -join $splatHashItemSeparator) | Out-Null
                                $replacementHashText.Append("$splatHashLineSeparator$(' ' * ([math]::Max(0, $splatHashIndent - 4)))}") | Out-Null

                                # Create a CorrectionExtent object for the suggested correction
                                $objParams = @{
                                    TypeName = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent'
                                    ArgumentList = @(
                                        $splatAst.Extent.StartLineNumber
                                        $splatAst.Extent.EndLineNumber
                                        $splatAst.Extent.StartColumnNumber
                                        $splatAst.Extent.EndColumnNumber
                                        $replacementHashText.ToString()
                                        $MyInvocation.MyCommand.Definition
                                        "More information: https://psappdeploytoolkit.com/docs/reference/functions"
                                    )
                                }
                                $correctionExtent = New-Object @objParams
                                $suggestedCorrections = New-Object System.Collections.ObjectModel.Collection[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent]
                                $suggestedCorrections.Add($correctionExtent) | Out-Null

                                # Output the diagnostic record in the format expected by the ScriptAnalyzer
                                [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord]@{
                                    Message = $outputMessage.ToString().Trim()
                                    Extent = $splatAst.Extent
                                    RuleName = 'Measure-ADTCompatibility'
                                    Severity = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticSeverity]::Warning
                                    RuleSuppressionID = 'ADTCompatibilitySuppression'
                                    SuggestedCorrections = $suggestedCorrections
                                }
                            }
                        }
                    }
                }
            }

            # Process all legacy variables second
            foreach ($variableAst in $variableAsts)
            {
                $variableName = $variableAst.VariablePath.UserPath
                $newVariable = $variableMappings[$variableName]

                if ([string]::IsNullOrWhiteSpace($newVariable))
                {
                    $outputMessage = "The variable [`$$variableName] is deprecated and no longer available."
                    $suggestedCorrections = $null
                }
                else
                {
                    if ($newVariable -match 'ADTSession')
                    {
                        $outputMessage = "The variable [`$$variableName] is now a session variable and no longer directly available. Use [$newVariable] instead."
                    }
                    elseif ($newVariable -match 'ADTConfig')
                    {
                        $outputMessage = "The variable [`$$variableName] is now a config variable and no longer directly available. Use [$newVariable] instead."
                    }
                    elseif ($newVariable -match 'ADTString')
                    {
                        $outputMessage = "The variable [`$$variableName] is now a localization string variable and no longer directly available. Use [$newVariable] instead."
                    }
                    else
                    {
                        $outputMessage = "The variable [`$$variableName] is deprecated. Use [$newVariable] instead."
                    }

                    if ($newVariable -like '*.*' -and $variableAst.Parent.StringConstantType -in [System.Management.Automation.Language.StringConstantType]'DoubleQuoted', [System.Management.Automation.Language.StringConstantType]'DoubleQuotedHereString')
                    {
                        # Wrap variable in $() if it is contains a . and is used in a double-quoted string
                        $newVariable = "`$($newVariable)"
                    }

                    # Create a CorrectionExtent object for the suggested correction
                    $objParams = @{
                        TypeName = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent'
                        ArgumentList = @(
                            $variableAst.Extent.StartLineNumber
                            $variableAst.Extent.EndLineNumber
                            $variableAst.Extent.StartColumnNumber
                            $variableAst.Extent.EndColumnNumber
                            $newVariable
                            $MyInvocation.MyCommand.Definition
                            'More information: https://psappdeploytoolkit.com/docs/reference/variables'
                        )
                    }
                    $correctionExtent = New-Object @objParams
                    $suggestedCorrections = New-Object System.Collections.ObjectModel.Collection[$($objParams.TypeName)]
                    $suggestedCorrections.Add($correctionExtent) | Out-Null
                }

                # Output the diagnostic record in the format expected by the ScriptAnalyzer
                [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord]@{
                    Message = $outputMessage
                    Extent = $variableAst.Extent
                    RuleName = 'Measure-ADTCompatibility'
                    Severity = 'Warning'
                    RuleSuppressionID = 'ADTCompatibilitySuppression'
                    SuggestedCorrections = $suggestedCorrections
                }
            }

            # Redefine legacy functions last
            foreach ($commandAst in $commandAsts)
            {
                $functionName = $commandAst.GetCommandName()

                # Use a StringBuilder for the output message, but a collection for newParams, since we want to search it as we go to avoid duplicate insertions, which are possible when multiple v3 parameters are combined into one
                $outputMessage = New-Object System.Text.StringBuilder
                $newParams = New-Object System.Collections.Generic.List[System.String]

                if ($functionMappings[$functionName].NewFunction -match '^#')
                {
                    # If function is remapped to a comment, use the comment as the message and skip parameter processing
                    $newFunction = $functionMappings[$functionName].NewFunction
                    $outputMessage.AppendLine($newFunction.TrimStart('#').Trim()) | Out-Null
                }
                else
                {
                    # Define these parameters first since scriptblocks may reference them
                    $boundParameters = ($spBinder::BindCommand($commandAst, $true)).BoundParameters

                    if ($functionMappings[$functionName].NewFunction -is [ScriptBlock])
                    {
                        # If function is remapped to a script block, invoke it to get the new function name
                        $newFunction = Invoke-Command -ScriptBlock $functionMappings[$functionName].NewFunction
                    }
                    else
                    {
                        # Otherwise, use the new function name as-is
                        $newFunction = $functionMappings[$functionName].NewFunction
                    }

                    $outputMessage.AppendLine("The function [$functionName] is deprecated, use [$newFunction] instead.") | Out-Null

                    foreach ($boundParameter in $boundParameters.GetEnumerator())
                    {
                        if ($boundParameter.Key -in $functionMappings[$functionName].RemoveParameters)
                        {
                            $outputMessage.AppendLine("-$($boundParameter.Key) is deprecated.") | Out-Null
                            continue
                        }
                        if ($boundParameter.Key -in $functionMappings[$functionName].TransformParameters.Keys)
                        {
                            if ($functionMappings[$functionName].TransformParameters[$boundParameter.Key] -is [ScriptBlock])
                            {
                                # If parameter is remapped to a script block, invoke it to get the new parameter
                                $newParam = ForEach-Object -InputObject $boundParameter.Value.Value.Extent.Text -Process $functionMappings[$functionName].TransformParameters[$boundParameter.Key]
                            }
                            else
                            {
                                # Otherwise, use the new parameter name as-is
                                $newParam = $functionMappings[$functionName].TransformParameters[$boundParameter.Key]
                            }

                            if ([string]::IsNullOrWhiteSpace($newParam))
                            {
                                # If newParam is empty, assume parameter should be removed (RemoveParameters definition is preferred, but it is not suitable for conditional removals)
                                $outputMessage.AppendLine("Removed parameter: -$($boundParameter.Key)") | Out-Null
                                continue
                            }
                            if ($newParams.Contains($newParam))
                            {
                                # If the new param value is already present in the new command, skip it. This can happen when 2 parameters are combined into one in the new syntax (e.g. Remove-MSIApplications -FilterApplication -ExcludeFromUninstall)
                                continue
                            }

                            if ($boundParameter.Value.ConstantValue -and $boundParameter.Value.Value.ParameterName -eq $boundParameter.Key)
                            {
                                # This is a simple switch
                                $outputMessage.AppendLine("-$($boundParameter.Key) → $newParam") | Out-Null
                            }
                            elseif ($boundParameter.Key -eq $boundParameter.Value.Value.Parent.ParameterName)
                            {
                                # This is a switch bound with a value, e.g. -Switch:$true
                                $outputMessage.AppendLine("-$($boundParameter.Key) → $newParam") | Out-Null
                            }
                            else
                            {
                                # This is a regular parameter, e.g. -Path 'xxx'
                                $outputMessage.AppendLine("-$($boundParameter.Key) $($boundParameter.Value.Value.Extent.Text) → $newParam") | Out-Null
                            }
                        }
                        else
                        {
                            # If not removed or transformed, pass through original parameter as-is, making some assumptions about the parsed input to do so
                            if ($boundParameter.Value.ConstantValue -and $boundParameter.Value.Value.ParameterName -eq $boundParameter.Key)
                            {
                                # This is a simple switch
                                $newParam = "-$($boundParameter.Key)"
                            }
                            elseif ($boundParameter.Key -eq $boundParameter.Value.Value.Parent.ParameterName)
                            {
                                # This is a switch bound with a value, e.g. -Switch:$true
                                $newParam = $boundParameters.Value.Value.Parent.Extent.Text
                            }
                            elseif ($boundParameter.Value.Value.Splatted)
                            {
                                # This is a splatted parameter, e.g. @params, retain the original value
                                $NewParam = $boundParameter.Value.Value.Extent.Text
                            }
                            else
                            {
                                # This is a regular parameter, e.g. -Path 'xxx'
                                $newParam = "-$($boundParameter.Key) $($boundParameter.Value.Value.Extent.Text)"
                            }
                        }

                        if (![string]::IsNullOrWhiteSpace($newParam))
                        {
                            $newParams.Add($newParam) | Out-Null
                        }
                    }

                    foreach ($addParameter in $functionMappings[$functionName].AddParameters.Keys)
                    {
                        if ($functionMappings[$functionName].AddParameters[$addParameter] -is [ScriptBlock])
                        {
                            # If parameter is remapped to a script block, invoke it to get the new parameter
                            $newParam = ForEach-Object -InputObject $addParameter -Process $functionMappings[$functionName].AddParameters[$addParameter]
                        }
                        else
                        {
                            # Otherwise, use the new parameter name as-is
                            $newParam = $functionMappings[$functionName].AddParameters[$addParameter]
                        }

                        if (![string]::IsNullOrWhiteSpace($newParam))
                        {
                            $newParams.Add($newParam) | Out-Null
                            $outputMessage.AppendLine("Add Parameter: $newParam") | Out-Null
                        }
                    }
                }

                # Construct the new command
                $newCommand = $newFunction + ' ' + ($newParams -join ' ')

                # Create a CorrectionExtent object for the suggested correction
                $objParams = @{
                    TypeName = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent'
                    ArgumentList = @(
                        $commandAst.Extent.StartLineNumber
                        $commandAst.Extent.EndLineNumber
                        $commandAst.Extent.StartColumnNumber
                        $commandAst.Extent.EndColumnNumber
                        $newCommand
                        $MyInvocation.MyCommand.Definition
                        "More information: https://psappdeploytoolkit.com/docs/reference/functions"
                    )
                }
                $correctionExtent = New-Object @objParams
                $suggestedCorrections = New-Object System.Collections.ObjectModel.Collection[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent]
                $suggestedCorrections.Add($correctionExtent) | Out-Null

                # Output the diagnostic record in the format expected by the ScriptAnalyzer
                [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord]@{
                    Message = $outputMessage.ToString().Trim()
                    Extent = $commandAst.Extent
                    RuleName = 'Measure-ADTCompatibility'
                    Severity = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticSeverity]::Warning
                    RuleSuppressionID = 'ADTCompatibilitySuppression'
                    SuggestedCorrections = $suggestedCorrections
                }
            }


        }
        catch
        {
            $PSCmdlet.ThrowTerminatingError($PSItem)
        }
    }
}

Export-ModuleMember Measure-ADTCompatibility

# SIG # Begin signature block
# MIIuKwYJKoZIhvcNAQcCoIIuHDCCLhgCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDEGdbnlwDZuKbo
# +zHGm8A+Qv6c0KThiPPdyGQw582U/aCCE5UwggWQMIIDeKADAgECAhAFmxtXno4h
# MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z
# ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
# IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z
# G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ
# anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s
# Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL
# 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb
# BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3
# JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c
# AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx
# YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0
# viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL
# T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud
# EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf
# Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk
# aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS
# PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK
# 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB
# cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp
# 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg
# dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri
# RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7
# 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5
# nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3
# i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H
# EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G
# CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
# IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
# ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C
# 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce
# 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da
# E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T
# SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA
# FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh
# D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM
# 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z
# 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05
# huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY
# mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP
# /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T
# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD
# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG
# A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY
# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj
# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV
# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU
# cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN
# BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry
# sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL
# IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf
# Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh
# OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh
# dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV
# 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j
# wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH
# Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC
# XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l
# /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW
# eE4wggdJMIIFMaADAgECAhAK+Vu2vqIMhQ6YxvuOrAj5MA0GCSqGSIb3DQEBCwUA
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
# ODQgMjAyMSBDQTEwHhcNMjQwOTA1MDAwMDAwWhcNMjcwOTA3MjM1OTU5WjCB0TET
# MBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQBgjc8AgECEwhDb2xvcmFkbzEd
# MBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xFDASBgNVBAUTCzIwMTMxNjM4
# MzI3MQswCQYDVQQGEwJVUzERMA8GA1UECBMIQ29sb3JhZG8xFDASBgNVBAcTC0Nh
# c3RsZSBSb2NrMRkwFwYDVQQKExBQYXRjaCBNeSBQQywgTExDMRkwFwYDVQQDExBQ
# YXRjaCBNeSBQQywgTExDMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA
# uydxko2Hrl6sANJUjfdypKP60qBH5EkhfaRQAnn+e3vg2eVcbiEWIjlrMYzvK2sg
# OMBbwGebqAURkFmUCKDdGxcxKeuXdaXPHWPKwc2WjYCFajrX6HofiiwNzOCdL6VE
# 4PDQhPRR7SIdNNFSrx5C4ZDN1T6OH+ydX7EQF8+NBUNHRbEVdl+h9H5Aexx63afa
# 8zu3g/GXluyXKbb+JHtgNJaUgFuFORTxw1TO6qH+S6Hrppf9QcAFmu4xGtkc2FSh
# gv0NgWMNGDZqJr/o9sqJ2tdaZHDyr6H8PvY8egoUshF7ccgEYtEEdB9SRR8mVQik
# 1w5oGTjDWjHj+8jgTpzletRywptk/m8PehVBN8ntqoSdvLLcuQVzmuPLzN/iuKh5
# sZeWvqPONApcEnZcONpXebyiUPnEePr5rZAU7hMjMw2ZPnQlMcbGvtgP2qi7m2f3
# mXFYxWjlKCxaApYHeqSFeWC8zM7OYL2HlZ+GuK4XG8jKVE6sWSW9Wk/dm0vJbasv
# AgMBAAGjggICMIIB/jAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAd
# BgNVHQ4EFgQU5GCU3SEqeIbhhY9eyU0LcTI75X8wPQYDVR0gBDYwNDAyBgVngQwB
# AzApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDgYD
# VR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaow
# U6BRoE+GTWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRH
# NENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRw
# Oi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmlu
# Z1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDCBlAYIKwYBBQUHAQEEgYcwgYQwJAYI
# KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBcBggrBgEFBQcwAoZQ
# aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29k
# ZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcnQwCQYDVR0TBAIwADANBgkq
# hkiG9w0BAQsFAAOCAgEAqA0ub/ilMgdIvMiBeWBoiMxe5OIblObGI7lemcP2WEqa
# EASW11/wVwJU63ZwhtkQaNU4rXjf6fqy5pOUzpQXgYjSaO4D/AOMJKHlypxslFqZ
# /dYpcue2xE3H7lmO4KPf8VxXuFIUqjLetU+kkh7o/Q52RabVAuOrPFKnObixy1HI
# x0/5F+RuP9xhqmDbfM7l5zUAcuOCCkY7buuInEsip9BZXUiVb8K5bPR9Rk7Doat4
# FQmN72xjakcEZOMU/vg0ZgVa8nxkBXtVsjxbsr+bODn0cddHK1QHWil/PmpANkxN
# 7H8tdCAZ8bTzIvvudxSLnt7ssbbQDkAyNw0btDH+MKv/l+VcYyQH51Z5xT9DvHCm
# Ed774boZkP2GfTFvn7/gISEjTdOuUGstdrgSwg1zJPqgK7zWxK48xC7awpa3gwOs
# 9pnyiqHG3rx84/SHUiAL2lkljsD3epmRxsWeZhZNY93xEpQHe9LBvo/t4VRjZzqU
# z+pfEMPqeX/g5+mpb4ap6ZmNJuAYJFmU0LIkCLQN9mKXi1Il9WU6ifn3vYutGMSL
# /BdeWP+7fM7MZLiO+1BIsBdSmV6pZVS3LRBAy3wIlbWL69mvyLCPIQ7z4dtfuzwC
# 36E9k2vhzeiDQ+k1dFJDSdxTDetsck0FuD1ovhiu2caL4BdFsCWsXPLMyvu6OlYx
# ghnsMIIZ6AIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg
# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTECEAr5W7a+ogyFDpjG+46sCPkwDQYJYIZI
# AWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0B
# CQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAv
# BgkqhkiG9w0BCQQxIgQgkKf8xoozG+UoLDlDTlfMBU7QY8VaEUXPBCFMhP1Q4ngw
# DQYJKoZIhvcNAQEBBQAEggGAAaeM5y8x5YupAwiV4TzcuOdcLXpxYT/nKBfzo821
# N4copjJ2ot6vxdch8b8GQpLWhNikWOH6x2zgwTPEjDr/CtLMQv0lHjrlV1v1hiEd
# FCkc9VKlO8e+CmPvWRg7orqw7AYm6/DS6J2TJ8rRlzAv/BUGcahZ2su19hBISmW3
# rKCaArudj0LaJ0voJa3c2raIDVzADtOkkqyuoWXQ/jo0ZgXq+dqqOskpVYuwz/TO
# uxKoimdd3XXusqQFPjlQ4t3UtiMfrF8jLeEinZHY7V0eZ1Wsoad8hCZ4nP97ePkT
# 7vfKYxp4/ZwX0aj3V6l/e6IxkSOzGNnlUYGy7BFo/pvCq7jVJwIOkI3Za/hdH1sY
# tBw3Yl4tdfoxALemvxrQTorQBgyegCKprSiscL/MqYZJj/Tmfed8krWyumtllH9l
# LvNChJT9EQCe6TQsfv8h4H/KAD+fpH4NudNC+4OV8q42eRh0cRrxvhWAjn1CFMJG
# HtHt4QcRpRZcXemVsPWItK7ioYIXOTCCFzUGCisGAQQBgjcDAwExghclMIIXIQYJ
# KoZIhvcNAQcCoIIXEjCCFw4CAQMxDzANBglghkgBZQMEAgEFADB3BgsqhkiG9w0B
# CRABBKBoBGYwZAIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIGonjc2h
# szFI5mGq+uMhzqZguuipZiH/QKGhoj/8/sIeAhABAUsPEHpHtZGMYsqJAhv+GA8y
# MDI0MTIwOTE4MTMyM1qgghMDMIIGvDCCBKSgAwIBAgIQC65mvFq6f5WHxvnpBOMz
# BDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl
# cnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBT
# SEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTI0MDkyNjAwMDAwMFoXDTM1MTEyNTIz
# NTk1OVowQjELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERpZ2lDZXJ0MSAwHgYDVQQD
# ExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIP
# ADCCAgoCggIBAL5qc5/2lSGrljC6W23mWaO16P2RHxjEiDtqmeOlwf0KMCBDEr4I
# xHRGd7+L660x5XltSVhhK64zi9CeC9B6lUdXM0s71EOcRe8+CEJp+3R2O8oo76EO
# 7o5tLuslxdr9Qq82aKcpA9O//X6QE+AcaU/byaCagLD/GLoUb35SfWHh43rOH3bp
# LEx7pZ7avVnpUVmPvkxT8c2a2yC0WMp8hMu60tZR0ChaV76Nhnj37DEYTX9ReNZ8
# hIOYe4jl7/r419CvEYVIrH6sN00yx49boUuumF9i2T8UuKGn9966fR5X6kgXj3o5
# WHhHVO+NBikDO0mlUh902wS/Eeh8F/UFaRp1z5SnROHwSJ+QQRZ1fisD8UTVDSup
# WJNstVkiqLq+ISTdEjJKGjVfIcsgA4l9cbk8Smlzddh4EfvFrpVNnes4c16Jidj5
# XiPVdsn5n10jxmGpxoMc6iPkoaDhi6JjHd5ibfdp5uzIXp4P0wXkgNs+CO/CacBq
# U0R4k+8h6gYldp4FCMgrXdKWfM4N0u25OEAuEa3JyidxW48jwBqIJqImd93NRxvd
# 1aepSeNeREXAu2xUDEW8aqzFQDYmr9ZONuc2MhTMizchNULpUEoA6Vva7b1XCB+1
# rxvbKmLqfY/M/SdV6mwWTyeVy5Z/JkvMFpnQy5wR14GJcv6dQ4aEKOX5AgMBAAGj
# ggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8E
# DDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEw
# HwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFJ9XLAN3
# DigVkGalY17uT5IfdqBbMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRp
# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3Rh
# bXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRw
# Oi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRz
# LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1l
# U3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAD2tHh92mVvjOIQSR9lD
# kfYR25tOCB3RKE/P09x7gUsmXqt40ouRl3lj+8QioVYq3igpwrPvBmZdrlWBb0Hv
# qT00nFSXgmUrDKNSQqGTdpjHsPy+LaalTW0qVjvUBhcHzBMutB6HzeledbDCzFzU
# y34VarPnvIWrqVogK0qM8gJhh/+qDEAIdO/KkYesLyTVOoJ4eTq7gj9UFAL1UruJ
# KlTnCVaM2UeUUW/8z3fvjxhN6hdT98Vr2FYlCS7Mbb4Hv5swO+aAXxWUm3WpByXt
# gVQxiBlTVYzqfLDbe9PpBKDBfk+rabTFDZXoUke7zPgtd7/fvWTlCs30VAGEsshJ
# mLbJ6ZbQ/xll/HjO9JbNVekBv2Tgem+mLptR7yIrpaidRJXrI+UzB6vAlk/8a1u7
# cIqV0yef4uaZFORNekUgQHTqddmsPCEIYQP7xGxZBIhdmm4bhYsVA6G2WgNFYagL
# DBzpmk9104WQzYuVNsxyoVLObhx3RugaEGru+SojW4dHPoWrUhftNpFC5H7QEY7M
# hKRyrBe7ucykW7eaCuWBsBb4HOKRFVDcrZgdwaSIqMDiCLg4D+TPVgKx2EgEdeoH
# NHT9l3ZDBD+XgbF+23/zBjeCtxz+dL/9NWR6P2eZRi7zcEO1xwcdcqJsyz/JceEN
# c2Sg8h3KeFUCS7tpFk7CrDqkMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipe
# WzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl
# cnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdp
# Q2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1
# OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5
# BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0
# YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1Bkmz
# wT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkL
# f50fng8zH1ATCyZzlm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C
# 3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5
# n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUd
# zTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWH
# po9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/
# oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPV
# A+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg
# 0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mM
# DDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6E
# VO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB
# /wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1Ud
# IwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNV
# HSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0
# dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2Vy
# dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0f
# BDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1
# c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcB
# MA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBT
# zr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/E
# UExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fm
# niye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szw
# cqMj+sAngkSumScbqyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8TH
# wcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/
# JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9
# Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm
# 228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVB
# tzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnw
# ZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv2
# 7dZ8/DCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcNAQEM
# BQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UE
# CxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJ
# RCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjELMAkG
# A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
# Z2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MIIC
# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zC
# pyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR0uRf
# 1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x
# 4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53yEio
# ZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4x7ax
# xLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3VdeGbZ
# OjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJ
# l2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJhbesz
# 2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz0YkH
# 4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb
# 5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+CiaZ
# 9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYD
# VR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0ksuC
# MS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGswJAYI
# KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3
# aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
# dENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0g
# ADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs
# 7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq
# 3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/
# Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9
# /HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+cWoj
# ayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA3YwggNyAgEB
# MHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYD
# VQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFt
# cGluZyBDQQIQC65mvFq6f5WHxvnpBOMzBDANBglghkgBZQMEAgEFAKCB0TAaBgkq
# hkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI0MTIwOTE4
# MTMyM1owKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQU29OF7mLb0j575PZxSFCHJNWG
# W0UwLwYJKoZIhvcNAQkEMSIEIBlsGu1W2iaTIxBj/pzo4IC8tODjUGX4ly6rax6F
# eYwaMDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIEIHZ2n6jyYy8fQws6IzCu1lZ1/tdz
# 2wXWZbkFk5hDj5rbMA0GCSqGSIb3DQEBAQUABIICAFab/9k1WLuIbwH/LBXHTQ5m
# 2mNPHvK+qITMR43SrXlGsocf+ox976PgcGGS41MS5Cl58LPqbuUmiJOELGb1ZW1Y
# vtDVh88ExGKshz2Jzkld9dhTrAZdMJrNeUS+Q+Vc8yZQiuEpZi1Za2aPeybOYR13
# Kdt18W+0eXowd15uYB7tAFHrkAUbFwskgnE1WDF1bySycTQpIsn1fPRw5/TUIHGh
# tkmBevtOd5RJDtgasKSVkNiPGfn/DpeL41Bw+x6rpceFp+wVLNfVhcf9/J+Pw11O
# MGypfuFYsvUPnTTnsejXnYroLKWZ3YctdBCNbtXHUX0C8LWuov1Na33HUiSud8fU
# CI4fF593on6t5kowmNCTFCcqDzO6r+mBCU1bUb9GmfSkV8ggEPeba5FnkQOzl4Cc
# nMVdeL+oX2cOLZmJfemtYZWLjAWua4nwqC6QF4yWPFyGc1BRp6JSKuAplc3KshyI
# TrNSucj3Ulej/E2CaDcAMqJFm460btNk92Vn5EsCU77bhZ/hnZqwEErFzLs8C6Ur
# 5EU3iyLvNgtGlATsKIwi7gss5jY5tJ6cgDlMjcZ7XcIRafCKtoyTdmh5Wy3yrAPn
# 3jdCcedID5IWrn4ihbhEHalbt6lq9/4En7oJshny5kFhSQmHJYA2jiCKDApgFq77
# aYaIDDD36x/Uh3vRAOZU
# SIG # End signature block